diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5079bff0c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,32 +0,0 @@ -sudo: false -dist: trusty -language: c -compiler: - - gcc -env: - - CMPLR=gcc - - CMPLR=gcc EXTRA=CMD_CXXFLAGS=-std=c++11 - - CMPLR=gcc STATIC=YES - - CMPLR=clang - - CMPLR=clang STATIC=YES - - WINE=32 TEST=NO STATIC=YES - - WINE=32 TEST=NO STATIC=NO - - RTEMS=4.10 TEST=NO - - RTEMS=4.9 TEST=NO -addons: - apt: - packages: - - libreadline6-dev - - libncurses5-dev - - perl - - clang - - g++-mingw-w64-i686 - - bison - - flex - - texinfo - - install-info -cache: - directories: - - $HOME/.cache -install: sh ci/travis-prepare.sh -# Copyright (c) 2016-2017 ITER Organization - -# Version format -version: base-{branch}-{build} - -#---------------------------------# -# repository cloning # -#---------------------------------# - -# Called at very beginning, before repo cloning -init: - # Set autocrlf to make batch files work - - git config --global core.autocrlf true - -# Set clone depth (do not fetch complete history) -clone_depth: 2 - -# Skipping commits affecting only specific files -skip_commits: - files: - - 'documentation/*' - - 'templates/*' - - '**/*.html' - - '**/*.md' - -#---------------------------------# -# build matrix configuration # -#---------------------------------# - -# Build Configurations: dll/static, regular/debug -configuration: - - dynamic - - static - - dynamic-debug - - static-debug - -# Environment variables: compiler toolchain -environment: - matrix: - - TOOLCHAIN: 9.0 - - TOOLCHAIN: 10.0 - - TOOLCHAIN: 11.0 - - TOOLCHAIN: 12.0 - - TOOLCHAIN: 14.0 - - TOOLCHAIN: cygwin - - TOOLCHAIN: mingw - -# Platform: architecture -platform: - - x86 - - x64 - -# Matrix configuration: allow specific failing jobs -matrix: - exclude: - # VS Express installs don't have the 64 bit compiler - - platform: x64 - TOOLCHAIN: 9.0 - - platform: x64 - TOOLCHAIN: 10.0 - -#---------------------------------# -# building & testing # -#---------------------------------# - -install: - - cmd: ci/appveyor-prepare.bat - -build_script: - - cmd: ci/appveyor-make.bat - -test_script: - - cmd: ci/appveyor-make.bat runtests - -#---------------------------------# -# notifications # -#---------------------------------# - -notifications: - - - provider: Slack - incoming_webhook: - secure: RYOm3FIUYeZGjWKaeTVKwq+C3fzK54AKwbmAoECED45mex3lN+8HmrC845a6mg9xPUJ/ND51RopWVaKDD9/UzaM0SO195RQLKqUTIUafiuM= diff --git a/ci/appveyor-make.bat b/ci/appveyor-make.bat deleted file mode 100644 index 8ecf61dbe..000000000 --- a/ci/appveyor-make.bat +++ /dev/null @@ -1,118 +0,0 @@ -:: Universal build script for AppVeyor (https://ci.appveyor.com/) -:: Environment: -:: TOOLCHAIN - toolchain version [9.0/10.0/11.0/12.0/14.0/cygwin/mingw] -:: CONFIGURATION - determines EPICS build [dynamic/static] -:: PLATFORM - architecture [x86/x64] -:: -:: All command line args are passed to make - -Setlocal EnableDelayedExpansion - -set "ST=" -if /i "%CONFIGURATION%"=="static" set ST=-static - -set OS=64BIT -if "%PLATFORM%"=="x86" set OS=32BIT - -echo [INFO] Platform: %OS% - -:: Use parallel make, except for 3.14 -set "MAKEARGS=-j2 -Otarget" -if "%APPVEYOR_REPO_BRANCH%"=="3.14" set MAKEARGS= - -if "%TOOLCHAIN%"=="cygwin" ( - set "MAKE=make" - if "%OS%"=="64BIT" ( - set "EPICS_HOST_ARCH=cygwin-x86_64" - set "INCLUDE=C:\cygwin64\include;%INCLUDE%" - set "PATH=C:\cygwin64\bin;%PATH%" - echo [INFO] Cygwin Toolchain 64bit - ) else ( - set "EPICS_HOST_ARCH=cygwin-x86" - set "INCLUDE=C:\cygwin\include;%INCLUDE%" - set "PATH=C:\cygwin\bin;%PATH%" - echo [INFO] Cygwin Toolchain 32bit - ) - echo [INFO] Compiler Version - gcc -v - goto Finish -) - -if "%TOOLCHAIN%"=="mingw" ( - set "MAKE=mingw32-make" - if "%OS%"=="64BIT" ( - set "EPICS_HOST_ARCH=windows-x64-mingw" - set "INCLUDE=C:\tools\mingw64\include;%INCLUDE%" - set "PATH=C:\tools\mingw64\bin;%PATH%" - echo [INFO] MinGW Toolchain 64bit - ) else ( - set "EPICS_HOST_ARCH=win32-x86-mingw" - set "INCLUDE=C:\tools\mingw32\include;%INCLUDE%" - set "PATH=C:\tools\mingw32\bin;%PATH%" - echo [INFO] MinGW Toolchain 32bit - ) - echo [INFO] Compiler Version - gcc -v - goto Finish -) - -set "VSINSTALL=C:\Program Files (x86)\Microsoft Visual Studio %TOOLCHAIN%" -set "MAKE=C:\tools\make" - -if "%OS%"=="64BIT" ( - set EPICS_HOST_ARCH=windows-x64%ST% - if exist "%VSINSTALL%\VC\vcvarsall.bat" ( - call "%VSINSTALL%\VC\vcvarsall.bat" amd64 - where cl - if !ERRORLEVEL! NEQ 0 ( - call "%VSINSTALL%\VC\vcvarsall.bat" x86_amd64 - where cl - if !ERRORLEVEL! NEQ 0 goto MSMissing - ) - goto MSFound - ) - if exist "%VSINSTALL%\VC\bin\amd64\vcvars64.bat" ( - call "%VSINSTALL%\VC\bin\amd64\vcvars64.bat" - where cl - if !ERRORLEVEL! NEQ 0 goto MSMissing - goto MSFound - ) -) else ( - set EPICS_HOST_ARCH=win32-x86%ST% - if exist "%VSINSTALL%\VC\vcvarsall.bat" ( - call "%VSINSTALL%\VC\vcvarsall.bat" x86 - where cl - if !ERRORLEVEL! NEQ 0 goto MSMissing - goto MSFound - ) - if exist "%VSINSTALL%\VC\bin\vcvars32.bat" ( - call "%VSINSTALL%\VC\bin\vcvars32.bat" - where cl - if !ERRORLEVEL! NEQ 0 goto MSMissing - goto MSFound - ) - if exist "%VSINSTALL%\Common7\Tools\vsvars32.bat" ( - call "%VSINSTALL%\Common7\Tools\vsvars32.bat" - where cl - if !ERRORLEVEL! NEQ 0 goto MSMissing - goto MSFound - ) -) - -:MSMissing -echo [INFO] Installation for MSVC Toolchain %TOOLCHAIN% / %OS% seems to be missing -exit 1 - -:MSFound -echo [INFO] Microsoft Visual Studio Toolchain %TOOLCHAIN% -echo [INFO] Compiler Version -cl - -:Finish -echo [INFO] EPICS_HOST_ARCH: %EPICS_HOST_ARCH% -echo [INFO] Make version -%MAKE% --version -echo [INFO] Perl version -perl --version - -%MAKE% %MAKEARGS% %* diff --git a/ci/appveyor-prepare.bat b/ci/appveyor-prepare.bat deleted file mode 100644 index 6edb7b52f..000000000 --- a/ci/appveyor-prepare.bat +++ /dev/null @@ -1,70 +0,0 @@ -:: Build script for AppVeyor (https://ci.appveyor.com/) -:: Environment: -:: TOOLCHAIN - Toolchain Version [9.0/10.0/11.0/12.0/14.0/cygwin/mingw] -:: CONFIGURATION - determines EPICS build [dynamic/static, -debug] -:: PLATFORM - "x86" -> use 32bit architecture -:: -:: Prepares an Appveyor build by excuting the following steps -:: - Set up configure\CONFIG_SITE for static vs. dynamic build -:: - Install Cygwin / Mingw (TOOLCHAIN setting) in the in the appropriate flavor -:: - Download and install Make-4.1 from EPICS download page - -Setlocal EnableDelayedExpansion - -set OS=64BIT -if "%PLATFORM%"=="x86" set OS=32BIT - -echo [INFO] Platform: %OS% - -if "%TOOLCHAIN%"=="cygwin" ( - echo.%CONFIGURATION% | findstr /C:"static">nul && ( - echo SHARED_LIBRARIES=NO>> configure\CONFIG_SITE - echo STATIC_BUILD=YES>> configure\CONFIG_SITE - echo [INFO] EPICS set up for static build - ) || ( - echo [INFO] EPICS set up for dynamic build - ) - echo.%CONFIGURATION% | findstr /C:"debug">nul && ( - echo HOST_OPT=NO>> configure\CONFIG_SITE - echo [INFO] EPICS set up for debug build - ) || ( - echo [INFO] EPICS set up for optimized build - ) - if "%OS%"=="64BIT" ( - echo [INFO] Installing Cygwin 64bit and dependencies - @powershell -Command "(new-object net.webclient).DownloadFile('http://www.cygwin.com/setup-x86_64.exe', 'C:\cygwin64\setup-x86_64.exe')" - C:\cygwin64\setup-x86_64.exe -q -P "libreadline-devel,libncursesw-devel" - ) else ( - echo [INFO] Installing Cygwin 32bit and dependencies - @powershell -Command "(new-object net.webclient).DownloadFile('http://www.cygwin.com/setup-x86.exe', 'C:\cygwin\setup-x86.exe')" - C:\cygwin\setup-x86.exe -q -P "libreadline-devel,libncursesw-devel" - ) -) - -if "%TOOLCHAIN%"=="mingw" ( - echo.%CONFIGURATION% | findstr /C:"static">nul && ( - echo SHARED_LIBRARIES=NO>> configure\CONFIG_SITE - echo STATIC_BUILD=YES>> configure\CONFIG_SITE - echo [INFO] EPICS set up for static build - ) || ( - echo [INFO] EPICS set up for dynamic build - ) - echo.%CONFIGURATION% | findstr /C:"debug">nul && ( - echo HOST_OPT=NO>> configure\CONFIG_SITE - echo [INFO] EPICS set up for debug build - ) || ( - echo [INFO] EPICS set up for optimized build - ) - if "%OS%"=="64BIT" ( - echo [INFO] Installing MinGW 64bit - cinst mingw || cinst mingw - ) else ( - echo [INFO] Installing MinGW 32bit - cinst mingw --x86 || cinst mingw --x86 - ) -) - -echo [INFO] Installing Make 4.1 -@powershell -Command "(new-object net.webclient).DownloadFile('https://www.aps.anl.gov/epics/download/tools/make-4.1-win64.zip', 'C:\tools\make-4.1.zip')" -cd \tools -"C:\Program Files\7-Zip\7z" e make-4.1.zip diff --git a/ci/travis-build.sh b/ci/travis-build.sh deleted file mode 100644 index ba752ac4a..000000000 --- a/ci/travis-build.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/sh -set -e -x - -die() { - echo "$1" >&2 - exit 1 -} - -ticker() { - while true - do - sleep 60 - date -R - [ -r "$1" ] && tail -n10 "$1" - done -} - -CACHEKEY=1 - -EPICS_HOST_ARCH=`sh startup/EpicsHostArch` - -[ -e configure/os/CONFIG_SITE.Common.linux-x86 ] || die "Wrong location: $PWD" - -case "$CMPLR" in -clang) - echo "Host compiler is clang" - cat << EOF >> configure/os/CONFIG_SITE.Common.$EPICS_HOST_ARCH -GNU = NO -CMPLR_CLASS = clang -CC = clang -CCC = clang++ -EOF - ;; -*) echo "Host compiler is default";; -esac - -if [ "$STATIC" = "YES" ] -then - echo "Build static libraries/executables" - cat << EOF >> configure/CONFIG_SITE -SHARED_LIBRARIES=NO -STATIC_BUILD=YES -EOF -fi - -# requires wine and g++-mingw-w64-i686 -if [ "$WINE" = "32" ] -then - echo "Cross mingw32" - sed -i -e '/CMPLR_PREFIX/d' configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw - cat << EOF >> configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw -CMPLR_PREFIX=i686-w64-mingw32- -EOF - cat << EOF >> configure/CONFIG_SITE -CROSS_COMPILER_TARGET_ARCHS+=win32-x86-mingw -EOF -fi - -# set RTEMS to eg. "4.9" or "4.10" -# requires qemu, bison, flex, texinfo, install-info -if [ -n "$RTEMS" ] -then - echo "Cross RTEMS${RTEMS} for pc386" - install -d /home/travis/.cache - curl -L "https://github.com/mdavidsaver/rsb/releases/download/travis-20160306-2/rtems${RTEMS}-i386-trusty-20190306-2.tar.gz" \ - | tar -C /home/travis/.cache -xj - - sed -i -e '/^RTEMS_VERSION/d' -e '/^RTEMS_BASE/d' configure/os/CONFIG_SITE.Common.RTEMS - cat << EOF >> configure/os/CONFIG_SITE.Common.RTEMS -RTEMS_VERSION=$RTEMS -RTEMS_BASE=/home/travis/.cache/rtems${RTEMS}-i386 -EOF - cat << EOF >> configure/CONFIG_SITE -CROSS_COMPILER_TARGET_ARCHS+=RTEMS-pc386 -EOF - - # find local qemu-system-i386 - export PATH="$HOME/.cache/qemu/usr/bin:$PATH" - echo -n "Using QEMU: " - type qemu-system-i386 || echo "Missing qemu" - EXTRA=RTEMS_QEMU_FIXUPS=YES -fi - -make -j2 $EXTRA - -if [ "$TEST" != "NO" ] -then - make tapfiles - find . -name '*.tap' -print0 | xargs -0 -n1 prove -e cat -f -fi diff --git a/ci/travis-prepare.sh b/ci/travis-prepare.sh deleted file mode 100644 index fd8c6fb4b..000000000 --- a/ci/travis-prepare.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh -set -e -x - -die() { - echo "$1" >&2 - exit 1 -} - -CURDIR="$PWD" - -QDIR="$HOME/.cache/qemu" - -if [ -n "$RTEMS" -a "$TEST" = "YES" ] -then - git clone --quiet --branch vme --depth 10 https://github.com/mdavidsaver/qemu.git "$HOME/.build/qemu" - cd "$HOME/.build/qemu" - - HEAD=`git log -n1 --pretty=format:%H` - echo "HEAD revision $HEAD" - - [ -e "$HOME/.cache/qemu/built" ] && BUILT=`cat "$HOME/.cache/qemu/built"` - echo "Cached revision $BUILT" - - if [ "$HEAD" != "$BUILT" ] - then - echo "Building QEMU" - git submodule --quiet update --init - - install -d "$HOME/.build/qemu/build" - cd "$HOME/.build/qemu/build" - - "$HOME/.build/qemu/configure" --prefix="$HOME/.cache/qemu/usr" --target-list=i386-softmmu --disable-werror - make -j2 - make install - - echo "$HEAD" > "$HOME/.cache/qemu/built" - fi -fi - -cd "$CURDIR" diff --git a/configure/CONFIG b/configure/CONFIG index 580b58767..331fd7024 100644 --- a/configure/CONFIG +++ b/configure/CONFIG @@ -1,117 +1,28 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - -# -# Common build definitions +# CONFIG - Load build configuration data # +# Do not make changes to this file! -ifneq ($(wildcard $(TOP)/configure/CONFIG_BASE_VERSION),) - EPICS_BASE = $(INSTALL_LOCATION) - CONFIG = $(TOP)/configure - BASE_TOP=YES -else - CONFIG ?= $(EPICS_BASE)/configure -endif +# Allow user to override where the build rules come from +RULES = $(EPICS_BASE) -# Provide a default if the user hasn't set EPICS_HOST_ARCH -ifeq ($(origin EPICS_HOST_ARCH), undefined) - # NB: We use a simply expanded variable here for performance: - EPICS_HOST_ARCH := $(shell $(CONFIG)/../startup/EpicsHostArch.pl) -endif -# - --include $(CONFIG)/RELEASE --include $(CONFIG)/RELEASE.$(EPICS_HOST_ARCH) --include $(CONFIG)/RELEASE.$(EPICS_HOST_ARCH).Common +# RELEASE files point to other application tops +include $(TOP)/configure/RELEASE +-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common ifdef T_A - -include $(CONFIG)/RELEASE.Common.$(T_A) - -include $(CONFIG)/RELEASE.$(EPICS_HOST_ARCH).$(T_A) +-include $(TOP)/configure/RELEASE.Common.$(T_A) +-include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A) endif -include $(CONFIG)/CONFIG_COMMON -include $(CONFIG)/CONFIG_FILE_TYPE - -# Base-specific build options -# -include $(CONFIG)/CONFIG_BASE - -# Site-specific build options -# -include $(CONFIG)/CONFIG_SITE - -# Version numbering -# -include $(CONFIG)/CONFIG_BASE_VERSION - -# Host architecture specific definitions -# -include $(CONFIG)/os/CONFIG.$(EPICS_HOST_ARCH).Common --include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common - -RELEASE_TOPS := $(shell $(CONVERTRELEASE) -T $(TOP) releaseTops) +CONFIG = $(RULES)/configure +include $(CONFIG)/CONFIG +# Override the Base definition: +INSTALL_LOCATION = $(TOP) +# CONFIG_SITE files contain other build configuration settings +include $(TOP)/configure/CONFIG_SITE +-include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common ifdef T_A - - # Cross compile specific definitions - # - ifneq ($(EPICS_HOST_ARCH),$(T_A)) - include $(CONFIG)/CONFIG.CrossCommon - endif - - # Target architecture specific definitions - # - -include $(CONFIG)/os/CONFIG.Common.$(T_A) - - # Host-Target architecture specific definitions - # - -include $(CONFIG)/os/CONFIG.$(EPICS_HOST_ARCH).$(T_A) - - # Site specific target and host-target definitions and overrides - # - -include $(CONFIG)/os/CONFIG_SITE.Common.$(T_A) - -include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) - - # RELEASE file specific definitions - # - ifneq ($(CONFIG),$(TOP)/configure) - -include $(CONFIG)/CONFIG_APP_INCLUDE - endif - -endif # ifdef T_A - - -# Include /cfg/CONFIG* definitions from tops defined in RELEASE* files -# -ifneq ($(CONFIG),$(TOP)/configure) - RELEASE_TOPS_REVERSE := $(shell \ - $(PERL) -e '$$,=" ";print reverse @ARGV' $(RELEASE_TOPS)) - RELEASE_CFG_CONFIGS = $(foreach top, $(RELEASE_TOPS_REVERSE), \ - $(wildcard $($(top))/cfg/CONFIG*)) - ifneq ($(RELEASE_CFG_CONFIGS),) - include $(RELEASE_CFG_CONFIGS) - endif + -include $(TOP)/configure/CONFIG_SITE.Common.$(T_A) + -include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) endif - -# Include $(INSTALL_CFG)/CONFIG* definitions -# -TOP_CFG_CONFIGS = $(wildcard $(INSTALL_CFG)/CONFIG*) -ifneq ($(TOP_CFG_CONFIGS),) - include $(TOP_CFG_CONFIGS) -endif - -# User specific definitions -# --include $(HOME)/configure/CONFIG_USER --include $(HOME)/configure/CONFIG_USER.$(EPICS_HOST_ARCH) -ifdef T_A - -include $(HOME)/configure/CONFIG_USER.Common.$(T_A) - -include $(HOME)/configure/CONFIG_USER.$(EPICS_HOST_ARCH).$(T_A) -endif - diff --git a/configure/CONFIG.CrossCommon b/configure/CONFIG.CrossCommon deleted file mode 100644 index 2fa6460d7..000000000 --- a/configure/CONFIG.CrossCommon +++ /dev/null @@ -1,31 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# Cross compiler default definitions - -# Build class: either HOST or CROSS -# Used to determine OPT and WARN compiler flags -BUILD_CLASS = CROSS - -# Cross build: either defined or not -# Used in os/CONFIG.Common. files -# ifdef CROSS looks better than ifeq ($(BUILD_CLASS),CROSS) -CROSS = YES - -GNU_TARGET_INCLUDE_DIR = $(GNU_TARGET:%= $(GNU_DIR)/%/include) -GNU_TARGET_LIB_DIR = $(GNU_TARGET:%= $(GNU_DIR)/%/lib) - -CROSS_INCLUDES = $(addprefix -I,$(GNU_TARGET_INCLUDE_DIR)) -CROSS_LDFLAGS = $(addprefix -L,$(GNU_TARGET_LIB_DIR)) - -CMPLR_PREFIX_CROSS=$(addsuffix -,$(GNU_TARGET)) -CMPLR_PREFIX=$(CMPLR_PREFIX_$(BUILD_CLASS)) - -# Cross builds usually use the gnu compiler -include $(CONFIG)/CONFIG.gnuCommon - diff --git a/configure/CONFIG.gnuCommon b/configure/CONFIG.gnuCommon deleted file mode 100644 index 025391548..000000000 --- a/configure/CONFIG.gnuCommon +++ /dev/null @@ -1,61 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# GNU compiler defaults - -GNU = YES - -CMPLR_CLASS = gcc - -GNU_BIN = $(GNU_DIR)/bin -GNU_LIB = $(GNU_DIR)/lib - -CC = $(GNU_BIN)/$(CMPLR_PREFIX)gcc$(CMPLR_SUFFIX) -CCC = $(GNU_BIN)/$(CMPLR_PREFIX)g++$(CMPLR_SUFFIX) -AR = $(GNU_BIN)/$(CMPLR_PREFIX)ar$(CMPLR_SUFFIX) -rc -LD = $(GNU_BIN)/$(CMPLR_PREFIX)ld$(CMPLR_SUFFIX) -r -CPP = $(CC) -x c -E -RANLIB = $(GNU_BIN)/$(CMPLR_PREFIX)ranlib$(CMPLR_SUFFIX) - -PROF_CFLAGS_YES = -p -GPROF_CFLAGS_YES = -pg -CODE_CFLAGS = $(PROF_CFLAGS_$(PROFILE)) $(GPROF_CFLAGS_$(GPROF)) -WARN_CFLAGS_YES = -Wall -WARN_CFLAGS_NO = -w -OPT_CFLAGS_YES = -O3 -OPT_CFLAGS_NO = -g - -PROF_CXXFLAGS_YES = -p -GPROF_CXXFLAGS_YES = -pg -CODE_CXXFLAGS = $(PROF_CXXFLAGS_$(PROFILE)) $(GPROF_CXXFLAGS_$(GPROF)) -WARN_CXXFLAGS_YES = -Wall -WARN_CXXFLAGS_NO = -w -OPT_CXXFLAGS_YES = -O3 -OPT_CXXFLAGS_NO = -g - -CODE_LDFLAGS = $(PROF_CXXFLAGS_$(PROFILE)) $(GPROF_CXXFLAGS_$(GPROF)) - -PIPE_CFLAGS_YES_YES = -pipe -PIPE_CFLAGS = $(PIPE_CFLAGS_$(GCC_PIPE)_$(GNU)) -PIPE_CXXFLAGS = $(PIPE_CFLAGS) - -STATIC_LDFLAGS_YES = -static -STATIC_LDFLAGS_NO = - -SHRLIB_CFLAGS = -fPIC -SHRLIB_LDFLAGS = -shared -fPIC -LOADABLE_SHRLIB_LDFLAGS = -shared -fPIC - -GNU_LDLIBS_YES = -lgcc - -# Use compiler flags to generate header dependancies files -HDEPENDS_METHOD = COMP -HDEPENDS_COMPFLAGS = -MM -MF $@ - diff --git a/configure/CONFIG_ADDONS b/configure/CONFIG_ADDONS deleted file mode 100644 index 29a33c415..000000000 --- a/configure/CONFIG_ADDONS +++ /dev/null @@ -1,584 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# check for add-on CFLAGS and CXXFLAGS -# -# Rules: -# 1) USR_CFLAGS is used -# 2) if there is a special USR_CFLAGS_$(OS_CLASS), it's -# appended to 1) -# 3) if there is no special defined, but a generic USR_CFLAGS_DEFAULT, -# this one is appended -# 4) if you have the special case that your USR_CFLAGS_$(OS_CLASS) is -# empty but you don't want 3), you have to define it as '-nil-', e.g.: -# USR_CFLAGS = -# USR_CFLAGS_WIN = -nil- -# USR_CFLAGS_DEFAULT = -# -# These rules apply to these Makefile-variables: -# USR_CFLAGS C flags -# USR_CXXFLAGS C++ flags -# USR_CPPFLAGS c preprocesser flags -# SRCS source files for building libraries and prods -# USR_SRCS source files for building libraries and prods -# PROD_SRCS source files for building prods -# LIB_SRCS source files for building libraries -# LIBSRCS source files for building libraries (deprecated) -# PROD_OBJS object files for building prods -# LIB_OBJS object files for building libraries -# USR_OBJS object files for building libraries and prods -# USR_LIBS libs needed by PROD and TESTPROD and LIBRARY -# PROD_LIBS libs needed by PROD and TESTPROD -# LIB_LIBS libs needed by shared LIBRARY -# SHRLIB_LIBS libs needed by shared LIBRARY -# USR_OBJLIBS R3.13 vxWorks object libs needed building libraries and prods -# PROD_OBJLIBS R3.13 vxWorks object libs needed for building prods -# LIB_OBJLIBS R3.13 vxWorks object libs needed for building libraries -# USR_SYS_LIBS system libs needed building libraries and prods -# PROD_SYS_LIBS system libs needed for building prods -# LIB_SYS_LIBS system libs needed for building libraries -# USR_LDFLAGS ld flags for building libraries and prods -# PROD_LDFLAGS ld flags for building prods -# LIB_LDFLAGS ld flags for building libraries -# PROD products to build and install -# PROD_HOST products to build and install -# PROD_IOC products to build and install -# TESTPROD products to build -# TESTPROD_HOST products to build -# TESTPROD_IOC products to build -# LIBRARY libraries to build and install -# LIBRARY_HOST libraries to build and install -# LIBRARY_IOC libraries to build and install -# TESTLIBRARY libraries to build -# TESTLIBRARY_HOST libraries to build -# TESTLIBRARY_IOC libraries to build -# LOADABLE_LIBRARY libraries to build and install -# LOADABLE_LIBRARY_HOST libraries to build and install -# LOADABLE_LIBRARY_IOC libraries to build and install -# SCRIPTS scripts and install -# SCRIPTS_HOST host system scripts to install -# SCRIPTS_IOC ioc system scripts to install -# TESTSCRIPTS scripts -# TESTSCRIPTS_HOST host system scripts -# TESTSCRIPTS_IOC ioc system scripts -# OBJS object files to build and install -# OBJS_HOST host system object files to build and install -# OBJS_IOC ioc system object files to build and install -# USR_INCLUDES include directories -# BIN_INSTALLS binaries to install -# LIB_INSTALLS library binaries to install -# RCS win32 resource files for building libraries and prods -# PROD_RCS win32 resource files for building prods -# LIB_RCS win32 resource files for building libraries -# -# Remark: -# If you define INC, e.g. INC = getopt.h, the source -# (getopt.h) must be in the source directory (..) and/or -# in one or more ../os/ directories. -# -# Additional target architecture, T_A, Rules for USR_CFLAGS, USR_CXXFLAGS, -# and USR_CPPFLAGS which are applied before the above os_class Rules: -# 1) USR_CFLAGS_$(OS_CLASS) is used -# 2) if there is a special $(USR_CFLAGS_$(T_A)), it's -# appended to 1) -# 3) if there is no special defined, but a generic USR_CFLAGS_$(OS_CLASS)_DEFAULT, -# this one is appended -# 4) if you have the special case that your $(USR_CFLAGS_$(T_A)) is -# empty but you don't want 3), you have to define it as '-nil-', e.g.: -# USR_CFLAGS_vxWorks = -# USR_CFLAGS_vxWorks-68040 = -nil- -# USR_CFLAGS_vxWorks_DEFAULT = -# -# - -ifneq ($(strip $(USR_CFLAGS_$(T_A))),) -USR_CFLAGS_$(OS_CLASS)+=$(subst -nil-,,$(USR_CFLAGS_$(T_A))) -else -ifdef USR_CFLAGS_$(OS_CLASS)_DEFAULT -USR_CFLAGS_$(OS_CLASS)+=$(USR_CFLAGS_$(OS_CLASS)_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_CFLAGS_$(OS_CLASS))),) -USR_CFLAGS+=$(subst -nil-,,$(USR_CFLAGS_$(OS_CLASS))) -else -ifdef USR_CFLAGS_DEFAULT -USR_CFLAGS+=$(USR_CFLAGS_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_INCLUDES_$(OS_CLASS))),) -USR_INCLUDES+=$(subst -nil-,,$(USR_INCLUDES_$(OS_CLASS))) -else -ifdef USR_INCLUDES_DEFAULT -USR_INCLUDES+=$(USR_INCLUDES_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_CXXFLAGS_$(T_A))),) -USR_CXXFLAGS_$(OS_CLASS)+=$(subst -nil-,,$(USR_CXXFLAGS_$(T_A))) -else -ifdef USR_CXXFLAGS_$(OS_CLASS)_DEFAULT -USR_CXXFLAGS_$(OS_CLASS)+=$(USR_CXXFLAGS_$(OS_CLASS)_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_CXXFLAGS_$(OS_CLASS))),) -USR_CXXFLAGS+=$(subst -nil-,,$(USR_CXXFLAGS_$(OS_CLASS))) -else -ifdef USR_CXXFLAGS_DEFAULT -USR_CXXFLAGS+=$(USR_CXXFLAGS_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_CPPFLAGS_$(T_A))),) -USR_CPPFLAGS_$(OS_CLASS)+=$(subst -nil-,,$(USR_CPPFLAGS_$(T_A))) -else -ifdef USR_CPPFLAGS_$(OS_CLASS)_DEFAULT -USR_CPPFLAGS_$(OS_CLASS)+=$(USR_CPPFLAGS_$(OS_CLASS)_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_CPPFLAGS_$(OS_CLASS))),) -USR_CPPFLAGS+=$(subst -nil-,,$(USR_CPPFLAGS_$(OS_CLASS))) -else -ifdef USR_CPPFLAGS_DEFAULT -USR_CPPFLAGS+=$(USR_CPPFLAGS_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_LDFLAGS_$(OS_CLASS))),) -USR_LDFLAGS+=$(subst -nil-,,$(USR_LDFLAGS_$(OS_CLASS))) -else -ifdef USR_LDFLAGS_DEFAULT -USR_LDFLAGS+=$(USR_LDFLAGS_DEFAULT) -endif -endif - -ifneq ($(strip $(PROD_LDFLAGS_$(OS_CLASS))),) -PROD_LDFLAGS+=$(subst -nil-,,$(PROD_LDFLAGS_$(OS_CLASS))) -else -ifdef PROD_LDFLAGS_DEFAULT -PROD_LDFLAGS+=$(PROD_LDFLAGS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIB_LDFLAGS_$(OS_CLASS))),) -LIB_LDFLAGS+=$(subst -nil-,,$(LIB_LDFLAGS_$(OS_CLASS))) -else -ifdef LIB_LDFLAGS_DEFAULT -LIB_LDFLAGS+=$(LIB_LDFLAGS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIBSRCS_$(OS_CLASS))),) -LIBSRCS += $(subst -nil-,,$(LIBSRCS_$(OS_CLASS))) -else -ifdef LIBSRCS_DEFAULT -LIBSRCS+=$(LIBSRCS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIB_SRCS_$(OS_CLASS))),) -LIB_SRCS += $(subst -nil-,,$(LIB_SRCS_$(OS_CLASS))) -else -ifdef LIB_SRCS_DEFAULT -LIB_SRCS+=$(LIB_SRCS_DEFAULT) -endif -endif - -ifneq ($(strip $(SRCS_$(OS_CLASS))),) -SRCS += $(subst -nil-,,$(SRCS_$(OS_CLASS))) -else -ifdef SRCS_DEFAULT -SRCS+=$(SRCS_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_SRCS_$(OS_CLASS))),) -USR_SRCS += $(subst -nil-,,$(USR_SRCS_$(OS_CLASS))) -else -ifdef USR_SRCS_DEFAULT -USR_SRCS+=$(USR_SRCS_DEFAULT) -endif -endif - -ifneq ($(strip $(PROD_SRCS_$(OS_CLASS))),) -PROD_SRCS += $(subst -nil-,,$(PROD_SRCS_$(OS_CLASS))) -else -ifdef PROD_SRCS_DEFAULT -PROD_SRCS+=$(PROD_SRCS_DEFAULT) -endif -endif - -ifneq ($(strip $(BIN_INSTALLS_$(OS_CLASS))),) -BIN_INSTALLS+=$(subst -nil-,,$(BIN_INSTALLS_$(OS_CLASS))) -else -ifdef BIN_INSTALLS_DEFAULT -BIN_INSTALLS+=$(BIN_INSTALLS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIB_INSTALLS_$(OS_CLASS))),) -LIB_INSTALLS+=$(subst -nil-,,$(LIB_INSTALLS_$(OS_CLASS))) -else -ifdef LIB_INSTALLS_DEFAULT -LIB_INSTALLS+=$(LIB_INSTALLS_DEFAULT) -endif -endif - -ifneq ($(strip $(PROD_OBJS_$(OS_CLASS))),) -PROD_OBJS+=$(subst -nil-,,$(PROD_OBJS_$(OS_CLASS))) -else -ifneq (,$(strip $(PROD_OBJS_DEFAULT))) -PROD_OBJS+=$(PROD_OBJS_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_OBJS_$(OS_CLASS))),) -USR_OBJS+=$(subst -nil-,,$(USR_OBJS_$(OS_CLASS))) -else -ifneq (,$(strip $(USR_OBJS_DEFAULT))) -USR_OBJS+=$(USR_OBJS_DEFAULT) -endif -endif - -ifneq ($(strip $(OBJS_$(OS_CLASS))),) -OBJS+=$(subst -nil-,,$(OBJS_$(OS_CLASS))) -else -ifneq (,$(strip $(OBJS_DEFAULT))) -OBJS+=$(OBJS_DEFAULT) -endif -endif - -ifneq ($(strip $(OBJS_IOC_$(OS_CLASS))),) -OBJS_IOC+=$(subst -nil-,,$(OBJS_IOC_$(OS_CLASS))) -else -ifneq (,$(strip $(OBJS_IOC_DEFAULT))) -OBJS_IOC+=$(OBJS_IOC_DEFAULT) -endif -endif - -ifneq ($(strip $(OBJS_HOST_$(OS_CLASS))),) -OBJS_HOST+=$(subst -nil-,,$(OBJS_HOST_$(OS_CLASS))) -else -ifneq (,$(strip $(OBJS_HOST_DEFAULT))) -OBJS_HOST+=$(OBJS_HOST_DEFAULT) -endif -endif - -ifneq ($(strip $(PROD_OBJLIBS_$(OS_CLASS))),) -PROD_OBJLIBS+=$(subst -nil-,,$(PROD_OBJLIBS_$(OS_CLASS))) -else -ifdef PROD_OBJLIBS_DEFAULT -PROD_OBJLIBS+=$(PROD_OBJLIBS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIB_OBJLIBS_$(OS_CLASS))),) -LIB_OBJLIBS+=$(subst -nil-,,$(LIB_OBJLIBS_$(OS_CLASS))) -else -ifdef LIB_OBJLIBS_DEFAULT -LIB_OBJLIBS+=$(LIB_OBJLIBS_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_OBJLIBS_$(OS_CLASS))),) -USR_OBJLIBS+=$(subst -nil-,,$(USR_OBJLIBS_$(OS_CLASS))) -else -ifdef USR_OBJLIBS_DEFAULT -USR_OBJLIBS+=$(USR_OBJLIBS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIB_OBJS_$(OS_CLASS))),) -LIB_OBJS+=$(subst -nil-,,$(LIB_OBJS_$(OS_CLASS))) -else -ifneq (,$(strip $(LIB_OBJS_DEFAULT))) -LIB_OBJS+=$(LIB_OBJS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIBRARY_$(OS_CLASS))),) -LIBRARY+=$(subst -nil-,,$(LIBRARY_$(OS_CLASS))) -else -ifneq (,$(strip $(LIBRARY_DEFAULT))) -LIBRARY+=$(LIBRARY_DEFAULT) -endif -endif - -ifneq ($(strip $(LIBRARY_IOC_$(OS_CLASS))),) -LIBRARY_IOC+=$(subst -nil-,,$(LIBRARY_IOC_$(OS_CLASS))) -else -ifneq (,$(strip $(LIBRARY_IOC_DEFAULT))) -LIBRARY_IOC+=$(LIBRARY_IOC_DEFAULT) -endif -endif - -ifneq ($(strip $(LIBRARY_HOST_$(OS_CLASS))),) -LIBRARY_HOST+=$(subst -nil-,,$(LIBRARY_HOST_$(OS_CLASS))) -else -ifneq (,$(strip $(LIBRARY_HOST_DEFAULT))) -LIBRARY_HOST+=$(LIBRARY_HOST_DEFAULT) -endif -endif - -ifneq ($(strip $(TESTLIBRARY_$(OS_CLASS))),) -TESTLIBRARY+=$(subst -nil-,,$(TESTLIBRARY_$(OS_CLASS))) -else -ifneq (,$(strip $(TESTLIBRARY_DEFAULT))) -TESTLIBRARY+=$(TESTLIBRARY_DEFAULT) -endif -endif - -ifneq ($(strip $(TESTLIBRARY_IOC_$(OS_CLASS))),) -TESTLIBRARY_IOC+=$(subst -nil-,,$(TESTLIBRARY_IOC_$(OS_CLASS))) -else -ifneq (,$(strip $(TESTLIBRARY_IOC_DEFAULT))) -TESTLIBRARY_IOC+=$(TESTLIBRARY_IOC_DEFAULT) -endif -endif - -ifneq ($(strip $(TESTLIBRARY_HOST_$(OS_CLASS))),) -TESTLIBRARY_HOST+=$(subst -nil-,,$(TESTLIBRARY_HOST_$(OS_CLASS))) -else -ifneq (,$(strip $(TESTLIBRARY_HOST_DEFAULT))) -TESTLIBRARY_HOST+=$(TESTLIBRARY_HOST_DEFAULT) -endif -endif - -ifneq ($(strip $(LOADABLE_LIBRARY_$(OS_CLASS))),) -LOADABLE_LIBRARY+=$(subst -nil-,,$(LOADABLE_LIBRARY_$(OS_CLASS))) -else -ifneq (,$(strip $(LOADABLE_LIBRARY_DEFAULT))) -LOADABLE_LIBRARY+=$(LOADABLE_LIBRARY_DEFAULT) -endif -endif - -ifneq ($(strip $(LOADABLE_LIBRARY_HOST_$(OS_CLASS))),) -LOADABLE_LIBRARY_HOST+=$(subst -nil-,,$(LOADABLE_LIBRARY_HOST_$(OS_CLASS))) -else -ifneq (,$(strip $(LOADABLE_LIBRARY_HOST_DEFAULT))) -LOADABLE_LIBRARY_HOST+=$(LOADABLE_LIBRARY_HOST_DEFAULT) -endif -endif - -ifneq ($(strip $(LOADABLE_LIBRARY_IOC_$(OS_CLASS))),) -LOADABLE_LIBRARY_IOC+=$(subst -nil-,,$(LOADABLE_LIBRARY_IOC_$(OS_CLASS))) -else -ifneq (,$(strip $(LOADABLE_LIBRARY_IOC_DEFAULT))) -LOADABLE_LIBRARY_IOC+=$(LOADABLE_LIBRARY_IOC_DEFAULT) -endif -endif - -ifneq ($(strip $(PROD_LIBS_$(OS_CLASS))),) -PROD_LIBS += $(subst -nil-,,$(PROD_LIBS_$(OS_CLASS))) -else -ifdef PROD_LIBS_DEFAULT -PROD_LIBS += $(PROD_LIBS_DEFAULT) -endif -endif - -# SHRLIB_LIBS deprecated -ifneq ($(strip $(SHRLIB_LIBS_$(OS_CLASS))),) -SHRLIB_LIBS += $(subst -nil-,,$(SHRLIB_LIBS_$(OS_CLASS))) -else -ifdef SHRLIB_LIBS_DEFAULT -SHRLIB_LIBS += $(SHRLIB_LIBS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIB_LIBS_$(OS_CLASS))),) -LIB_LIBS += $(subst -nil-,,$(LIB_LIBS_$(OS_CLASS))) -else -ifdef LIB_LIBS_DEFAULT -LIB_LIBS += $(LIB_LIBS_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_LIBS_$(OS_CLASS))),) -USR_LIBS += $(subst -nil-,,$(USR_LIBS_$(OS_CLASS))) -else -ifdef USR_LIBS_DEFAULT -USR_LIBS += $(USR_LIBS_DEFAULT) -endif -endif - -# -# concat specific library contents (if defined) to SYS_PROD_LIBS -# -# SYS_PROD_LIBS deprecated -ifneq ($(strip $(SYS_PROD_LIBS_$(OS_CLASS))),) -SYS_PROD_LIBS += $(subst -nil-,,$(SYS_PROD_LIBS_$(OS_CLASS))) -else -ifdef SYS_PROD_LIBS_DEFAULT -SYS_PROD_LIBS += $(SYS_PROD_LIBS_DEFAULT) -endif -endif -PROD_SYS_LIBS+=$(SYS_PROD_LIBS) - -ifneq ($(strip $(PROD_SYS_LIBS_$(OS_CLASS))),) -PROD_SYS_LIBS += $(subst -nil-,,$(PROD_SYS_LIBS_$(OS_CLASS))) -else -ifdef PROD_SYS_LIBS_DEFAULT -PROD_SYS_LIBS += $(PROD_SYS_LIBS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIB_SYS_LIBS_$(OS_CLASS))),) -LIB_SYS_LIBS += $(subst -nil-,,$(LIB_SYS_LIBS_$(OS_CLASS))) -else -ifdef LIB_SYS_LIBS_DEFAULT -LIB_SYS_LIBS += $(LIB_SYS_LIBS_DEFAULT) -endif -endif - -ifneq ($(strip $(USR_SYS_LIBS_$(OS_CLASS))),) -USR_SYS_LIBS += $(subst -nil-,,$(USR_SYS_LIBS_$(OS_CLASS))) -else -ifdef USR_SYS_LIBS_DEFAULT -USR_SYS_LIBS += $(USR_SYS_LIBS_DEFAULT) -endif -endif - -# -# concat specific products -# -ifneq ($(strip $(PROD_$(OS_CLASS))),) -PROD+=$(subst -nil-,,$(PROD_$(OS_CLASS))) -else -ifneq (,$(strip $(PROD_DEFAULT))) -PROD+=$(PROD_DEFAULT) -endif -endif - -ifneq ($(strip $(PROD_IOC_$(OS_CLASS))),) -PROD_IOC+=$(subst -nil-,,$(PROD_IOC_$(OS_CLASS))) -else -ifneq (,$(strip $(PROD_IOC_DEFAULT))) -PROD_IOC+=$(PROD_IOC_DEFAULT) -endif -endif - -ifneq ($(strip $(PROD_HOST_$(OS_CLASS))),) -PROD_HOST+=$(subst -nil-,,$(PROD_HOST_$(OS_CLASS))) -else -ifneq (,$(strip $(PROD_HOST_DEFAULT))) -PROD_HOST+=$(PROD_HOST_DEFAULT) -endif -endif - -# -# concat specific products -# -ifneq ($(strip $(TESTPROD_$(OS_CLASS))),) -TESTPROD+=$(subst -nil-,,$(TESTPROD_$(OS_CLASS))) -else -ifneq (,$(strip $(TESTPROD_DEFAULT))) -TESTPROD+=$(TESTPROD_DEFAULT) -endif -endif - -ifneq ($(strip $(TESTPROD_IOC_$(OS_CLASS))),) -TESTPROD_IOC+=$(subst -nil-,,$(TESTPROD_IOC_$(OS_CLASS))) -else -ifneq (,$(strip $(TESTPROD_IOC_DEFAULT))) -TESTPROD_IOC+=$(TESTPROD_IOC_DEFAULT) -endif -endif - -ifneq ($(strip $(TESTPROD_HOST_$(OS_CLASS))),) -TESTPROD_HOST+=$(subst -nil-,,$(TESTPROD_HOST_$(OS_CLASS))) -else -ifneq (,$(strip $(TESTPROD_HOST_DEFAULT))) -TESTPROD_HOST+=$(TESTPROD_HOST_DEFAULT) -endif -endif - -# -# concat specific scripts -# -ifneq ($(strip $(SCRIPTS_$(OS_CLASS))),) -SCRIPTS += $(subst -nil-,,$(SCRIPTS_$(OS_CLASS))) -else -ifdef SCRIPTS_DEFAULT -SCRIPTS += $(SCRIPTS_DEFAULT) -endif -endif - -ifneq ($(strip $(SCRIPTS_IOC_$(OS_CLASS))),) -SCRIPTS_IOC+=$(subst -nil-,,$(SCRIPTS_IOC_$(OS_CLASS))) -else -ifneq (,$(strip $(SCRIPTS_IOC_DEFAULT))) -SCRIPTS_IOC+=$(SCRIPTS_IOC_DEFAULT) -endif -endif - -ifneq ($(strip $(SCRIPTS_HOST_$(OS_CLASS))),) -SCRIPTS_HOST+=$(subst -nil-,,$(SCRIPTS_HOST_$(OS_CLASS))) -else -ifneq (,$(strip $(SCRIPTS_HOST_DEFAULT))) -SCRIPTS_HOST+=$(SCRIPTS_HOST_DEFAULT) -endif -endif - -# -# concat specific scripts -# -ifneq ($(strip $(TESTSCRIPTS_$(OS_CLASS))),) -TESTSCRIPTS += $(subst -nil-,,$(TESTSCRIPTS_$(OS_CLASS))) -else -ifdef TESTSCRIPTS_DEFAULT -TESTSCRIPTS += $(TESTSCRIPTS_DEFAULT) -endif -endif - -ifneq ($(strip $(TESTSCRIPTS_IOC_$(OS_CLASS))),) -TESTSCRIPTS_IOC+=$(subst -nil-,,$(TESTSCRIPTS_IOC_$(OS_CLASS))) -else -ifneq (,$(strip $(TESTSCRIPTS_IOC_DEFAULT))) -TESTSCRIPTS_IOC+=$(TESTSCRIPTS_IOC_DEFAULT) -endif -endif - -ifneq ($(strip $(TESTSCRIPTS_HOST_$(OS_CLASS))),) -TESTSCRIPTS_HOST+=$(subst -nil-,,$(TESTSCRIPTS_HOST_$(OS_CLASS))) -else -ifneq (,$(strip $(TESTSCRIPTS_HOST_DEFAULT))) -TESTSCRIPTS_HOST+=$(TESTSCRIPTS_HOST_DEFAULT) -endif -endif - -# -# concat specific resource files -# -ifneq ($(strip $(RCS_$(OS_CLASS))),) -RCS += $(subst -nil-,,$(RCS_$(OS_CLASS))) -else -ifdef RCS_DEFAULT -RCS += $(RCS_DEFAULT) -endif -endif - -ifneq ($(strip $(PROD_RCS_$(OS_CLASS))),) -PROD_RCS += $(subst -nil-,,$(PROD_RCS_$(OS_CLASS))) -else -ifdef PROD_RCS_DEFAULT -PROD_RCS+=$(PROD_RCS_DEFAULT) -endif -endif - -ifneq ($(strip $(LIB_RCS_$(OS_CLASS))),) -LIB_RCS += $(subst -nil-,,$(LIB_RCS_$(OS_CLASS))) -else -ifdef LIB_RCS_DEFAULT -LIB_RCS+=$(LIB_RCS_DEFAULT) -endif -endif - diff --git a/configure/CONFIG_APP_INCLUDE b/configure/CONFIG_APP_INCLUDE deleted file mode 100644 index 8b4bd7d08..000000000 --- a/configure/CONFIG_APP_INCLUDE +++ /dev/null @@ -1,32 +0,0 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - -export TOP - -ifneq ($(RELEASE_TOPS),) - -define RELEASE_FLAGS_template - export $(1) - $(1)_HOST_BIN = $$(strip $$($(1)))/bin/$(EPICS_HOST_ARCH) - $(1)_HOST_LIB = $$(strip $$($(1)))/lib/$(EPICS_HOST_ARCH) - $(1)_BIN = $$(wildcard $$(strip $$($(1)))/bin/$(T_A)) - $(1)_LIB = $$(wildcard $$(strip $$($(1)))/lib/$(T_A)) - SHRLIB_SEARCH_DIRS += $$($(1)_LIB) - RELEASE_INCLUDES += $$(addprefix -I,$$(wildcard $$(strip $$($(1)))/include/compiler/$(CMPLR_CLASS))) - RELEASE_INCLUDES += $$(addprefix -I,$$(wildcard $$(strip $$($(1)))/include/os/$(OS_CLASS))) - RELEASE_INCLUDES += $$(addprefix -I,$$(wildcard $$(strip $$($(1)))/include)) - RELEASE_DBD_DIRS += $$(wildcard $$(strip $$($(1)))/dbd) - RELEASE_DB_DIRS += $$(wildcard $$(strip $$($(1)))/db) - RELEASE_PERL_MODULE_DIRS += $$(wildcard $$(strip $$($(1)))/lib/perl) -endef -$(foreach top, $(RELEASE_TOPS), \ - $(eval $(call RELEASE_FLAGS_template,$(top)))) - -endif - diff --git a/configure/CONFIG_BASE b/configure/CONFIG_BASE deleted file mode 100644 index 365042775..000000000 --- a/configure/CONFIG_BASE +++ /dev/null @@ -1,94 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -#--------------------------------------------------------------- -# EPICS Base directories - -EPICS_BASE_HOST_BIN = $(EPICS_BASE)/bin/$(EPICS_HOST_ARCH) -EPICS_BASE_HOST_LIB = $(EPICS_BASE)/lib/$(EPICS_HOST_ARCH) -ifdef T_A - EPICS_BASE_LIB = $(EPICS_BASE)/lib/$(T_A) - EPICS_BASE_BIN = $(EPICS_BASE)/bin/$(T_A) -endif - -#--------------------------------------------------------------- -# EPICS Base Ioc libraries - -EPICS_BASE_IOC_LIBS += dbRecStd dbCore ca Com - -#--------------------------------------------------------------- -# EPICS Base Host libraries - -EPICS_BASE_HOST_LIBS += cas gdd -EPICS_BASE_HOST_LIBS += ca Com - -#--------------------------------------------------------------- -# Version number for base shared libraries (and win32 products) - -ifdef BASE_TOP - # Unix lib.so. Darwin lib..dylib - SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION) - # Windows only allows 2 levels of version numbering - PROD_VERSION = $(EPICS_VERSION).$(EPICS_REVISION) - BASE_CPPFLAGS += -DUSE_TYPED_RSET -endif # BASE_TOP - -#--------------------------------------------------------------- -# Base c preprocessor flags - -# osithread default stack -OSITHREAD_USE_DEFAULT_STACK = NO -OSITHREAD_DEFAULT_STACK_FLAGS_YES = -DOSITHREAD_USE_DEFAULT_STACK - -BASE_CPPFLAGS += $(OSITHREAD_DEFAULT_STACK_FLAGS_$(OSITHREAD_USE_DEFAULT_STACK)) - -#--------------------------------------------------------------- -# Where to find the installed build tools -# Windows does not like commands with relative paths starting ../ -# but the Perl scripts in TOP/src/tools are OK - -TOOLS = $(abspath $(EPICS_BASE_HOST_BIN)) -FIND_TOOL = $(firstword $(wildcard $(TOOLS)/$(1) $(TOP)/src/tools/$(1))) - -#--------------------------------------------------------------- -# EPICS Base build tools and tool flags - -MAKEBPT = $(TOOLS)/makeBpt$(HOSTEXE) -DBEXPAND = $(PERL) $(TOOLS)/dbdExpand.pl -DBTORECORDTYPEH = $(PERL) $(TOOLS)/dbdToRecordtypeH.pl -DBTOMENUH = $(PERL) $(TOOLS)/dbdToMenuH.pl -REGISTERRECORDDEVICEDRIVER = $(PERL) $(TOOLS)/registerRecordDeviceDriver.pl -CONVERTRELEASE = $(PERL) $(call FIND_TOOL,convertRelease.pl) -FULLPATHNAME = $(PERL) $(TOOLS)/fullPathName.pl -TAPTOJUNIT = $(PERL) $(TOOLS)/tap-to-junit-xml.pl -GENVERSIONHEADER = $(PERL) $(TOOLS)/genVersionHeader.pl $(QUIET_FLAG) - -#--------------------------------------------------------------- -# tools for installing libraries and products -INSTALL = $(PERL) $(TOOLS)/installEpics.pl $(QUIET_FLAG) -INSTALL_PRODUCT = $(INSTALL) -INSTALL_LIBRARY = $(INSTALL) - -#--------------------------------------------------------------- -# tools for making header dependancies and variable replacement -MKMF = $(PERL) $(TOOLS)/mkmf.pl -REPLACEVAR = $(PERL) $(TOOLS)/replaceVAR.pl - -#--------------------------------------------------------------- -# Our versions of lex (flex) and yacc (antelope) -EYACC = $(TOOLS)/antelope$(HOSTEXE) -ELEX = $(TOOLS)/e_flex$(HOSTEXE) -S$(EPICS_BASE)/include/flex.skel.static - -YACC = $(EYACC) -LEX = $(ELEX) - -#--------------------------------------------------------------- -# The 3.15 version of msi supports new options - -MSI3_15 = $(EPICS_BASE_HOST_BIN)/msi diff --git a/configure/CONFIG_BASE_VERSION b/configure/CONFIG_BASE_VERSION deleted file mode 100644 index ac6451ad1..000000000 --- a/configure/CONFIG_BASE_VERSION +++ /dev/null @@ -1,74 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* -# -# EPICS Version information -# -# Only the person making an official EPICS release should make changes in -# this file. -# -# EPICS_SITE_VERSION is defined in CONFIG_SITE for sites that want a local -# version number to be included in the reported version string. - -# We define BASE_3_14 and BASE_3_15 as NO and BASE_3_16 as YES, so -# ifdef BASE_3_14 -# true for 3.14 or later -# ifdef BASE_3_15 -# true for 3.15 or later -# ifeq ($(BASE_3_14),YES) -# true for 3.14.x only -# ifeq ($(BASE_3_15),YES) -# true for 3.15 only -# ifeq ($(BASE_3_16),YES) -# true for 3.16 only. - -BASE_3_14 = NO -BASE_3_15 = NO -BASE_3_16 = YES - -# EPICS_VERSION must be a number >0 and <256 -EPICS_VERSION = 3 - -# EPICS_REVISION must be a number >=0 and <256 -EPICS_REVISION = 16 - -# EPICS_MODIFICATION must be a number >=0 and <256 -EPICS_MODIFICATION = 1 - -# EPICS_PATCH_LEVEL must be a number (win32 resource file requirement) -# Not included if zero -EPICS_PATCH_LEVEL = 0 - -# This will end in -DEV between official releases -EPICS_DEV_SNAPSHOT=-DEV -#EPICS_DEV_SNAPSHOT=-pre1 -#EPICS_DEV_SNAPSHOT=-pre1-DEV -#EPICS_DEV_SNAPSHOT=-pre2 -#EPICS_DEV_SNAPSHOT=-pre2-DEV -#EPICS_DEV_SNAPSHOT=-rc1 -#EPICS_DEV_SNAPSHOT=-rc1-DEV -#EPICS_DEV_SNAPSHOT=-rc2 -#EPICS_DEV_SNAPSHOT=-rc2-DEV -#EPICS_DEV_SNAPSHOT= - -# No changes should be needed below here - -ifneq ($(EPICS_PATCH_LEVEL),0) - EPICS_PATCH_VSTRING=.$(EPICS_PATCH_LEVEL) -endif - -ifneq ($(strip $(EPICS_SITE_VERSION)),) - EPICS_SITE_VSTRING=-$(EPICS_SITE_VERSION) -endif - -EPICS_SHORT_VERSION=$(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION)$(EPICS_PATCH_VSTRING) -EPICS_VERSION_NUMBER=$(EPICS_SHORT_VERSION)$(EPICS_DEV_SNAPSHOT)$(EPICS_SITE_VSTRING) -EPICS_VERSION_STRING="EPICS Version $(EPICS_VERSION_NUMBER)" - -# Provide this in case anyone is still using the old name -COMMIT_DATE="-no-date-" diff --git a/configure/CONFIG_COMMON b/configure/CONFIG_COMMON deleted file mode 100644 index 79807c2f2..000000000 --- a/configure/CONFIG_COMMON +++ /dev/null @@ -1,463 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# CONFIG_COMMON -# -# This file is to be maintained by the community. -# -# Common Configuration Information - -#------------------------------------------------------- -# POSIX is OS default -POSIX=YES - -#------------------------------------------------------- -# Divider symbol -DIVIDER = . - -#------------------------------------------------------- -# Build architectures - -# CROSS1 will be defined only when CROSS_COMPILER_HOST_ARCHS is NOT defined -CROSS1 = $(CROSS_COMPILER_TARGET_ARCHS$(word 1,$(CROSS_COMPILER_HOST_ARCHS))) - -# CROSS2 will be defined only when CROSS_COMPILER_HOST_ARCHS is defined -# and EPICS_HOST_ARCH is one of its words -CROSS2 = $(CROSS_COMPILER_TARGET_ARCHS$(filter-out 1,$(words $(filter $(EPICS_HOST_ARCH),$(CROSS_COMPILER_HOST_ARCHS))))) - -BUILD_ARCHS = $(EPICS_HOST_ARCH) $(CROSS1) $(CROSS2) - -#------------------------------------------------------- -# Default for perl if it's on the PATH, -# otherwise override this in os/CONFIG_SITE..Common -PERL = perl -CSD - -#------------------------------------------------------- -# Check configure/RELEASE file for consistency -CHECK_RELEASE_YES = checkRelease -CHECK_RELEASE_NO = noCheckRelease -CHECK_RELEASE_WARN = warnRelease - -#------------------------------------------------------- -# GNU directory -# GNU_DIR definition is here because it is used to find -# READLINE library even if GNU compiler is not used -GNU_DIR = /usr - -#------------------------------------------------------- -# Directories - -INSTALL_LOCATION = $(TOP) - -INSTALL_LOCATION_LIB = $(INSTALL_LOCATION)/lib -INSTALL_LOCATION_BIN = $(INSTALL_LOCATION)/bin - -INSTALL_HOST_BIN = $(INSTALL_LOCATION_BIN)/$(EPICS_HOST_ARCH) -INSTALL_HOST_LIB = $(INSTALL_LOCATION_LIB)/$(EPICS_HOST_ARCH) - -INSTALL_INCLUDE = $(INSTALL_LOCATION)/include -INSTALL_DOC = $(INSTALL_LOCATION)/doc -INSTALL_HTML = $(INSTALL_LOCATION)/html -INSTALL_TEMPLATES = $(INSTALL_LOCATION)/templates -INSTALL_DBD = $(INSTALL_LOCATION)/dbd -INSTALL_DB = $(INSTALL_LOCATION)/db -INSTALL_CONFIG = $(INSTALL_LOCATION)/configure - -# Directory for OS independant build created files -COMMON_DIR = ../O.Common - -# IOC's absolute path to $(TOP), may be overridden inside the application -IOCS_APPL_TOP = $(shell $(FULLPATHNAME) $(INSTALL_LOCATION)) - -#------------------------------------------------------- -# Make echo output - suppress echoing if make's '-s' flag is set -NOP = : -ECHO = @$(if $(findstring s,$(patsubst T_A=%,,$(MAKEFLAGS))),$(NOP),echo) -QUIET_FLAG := $(if $(findstring s,$(MAKEFLAGS)),-q,) - -#------------------------------------------------------- -ifdef T_A - -INSTALL_LIB = $(INSTALL_LOCATION_LIB)/$(T_A) -INSTALL_SHRLIB = $(INSTALL_LOCATION_LIB)/$(T_A) -INSTALL_TCLLIB = $(INSTALL_LOCATION_LIB)/$(T_A) -INSTALL_BIN = $(INSTALL_LOCATION_BIN)/$(T_A) - -#Directories for libraries -SHRLIB_SEARCH_DIRS = $(INSTALL_LIB) - -#------------------------------------------------------- -# Ext, app, and module configure dir targets -CONFIG_INSTALLS += ../RULES_BUILD ../RELEASE* - -#------------------------------------------------------- -# Cross compile default, HOST or CROSS, CONFIG.crossCommon will override -BUILD_CLASS = HOST - -#------------------------------------------------------- -# Build defaults, CONFIG_SITE, CONFIG, or os/CONFIG* will override -STATIC_BUILD=NO -SHARED_LIBRARIES=YES -HOST_OPT=YES -CROSS_OPT=YES -HOST_WARN=YES -CROSS_WARN=YES -GNU=NO - -#------------------------------------------------------- -# Run checkRelease in $(TOP)/configure/O.* -CONFIG_TARGETS += $(CHECK_RELEASE_$(CHECK_RELEASE)) - -#------------------------------------------------------- -# Prefix and suffix -DEP = .d -OBJ = .o -CMPLR_SUFFIX = -CMPLR_PREFIX = -LIB_PREFIX = -LIB_SUFFIX = -SHRLIB_PREFIX = $(LIB_PREFIX) -DLLSTUB_PREFIX = $(LIB_PREFIX) -DLLSTUB_SUFFIX = $(LIB_SUFFIX) - -BUILDLIB_PREFIX_YES = $(DLLSTUB_PREFIX) -BUILDLIB_PREFIX_NO = $(LIB_PREFIX) -BUILDLIB_SUFFIX_YES = $(DLLSTUB_SUFFIX) -BUILDLIB_SUFFIX_NO = $(LIB_SUFFIX) -BUILDLIB_PREFIX = $(BUILDLIB_PREFIX_$(SHARED_LIBRARIES)) -BUILDLIB_SUFFIX = $(BUILDLIB_SUFFIX_$(SHARED_LIBRARIES)) - -#-------------------------------------------------- -# vpath directories -POSIX_YES = os/posix -GENERIC_SRC_DIRS = .. $(SRC_DIRS) -OS_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \ - $(addprefix $(dir)/, os/$(OS_CLASS) $(POSIX_$(POSIX)) os/default )) -CMPLR_SRC_DIRS += . $(foreach dir, .. $(SRC_DIRS), \ - $(addprefix $(dir)/, compiler/$(CMPLR_CLASS) compiler/default )) -ALL_SRC_DIRS = $(CMPLR_SRC_DIRS) $(OS_SRC_DIRS) $(GENERIC_SRC_DIRS) - -#-------------------------------------------------- -# compile line include directories -INSTALL_INCLUDES += \ - -I$(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS) \ - -I$(INSTALL_INCLUDE)/os/$(OS_CLASS) \ - -I$(INSTALL_INCLUDE) -SRC_INCLUDES = -I$(COMMON_DIR) $(addprefix -I, $(wildcard $(ALL_SRC_DIRS))) - -#-------------------------------------------------- -# Target filename definitions -OBJSNAME = $(addsuffix $(OBJ),$(basename $(OBJS))) -PRODNAME = $(addsuffix $(EXE),$(basename $(PROD))) -TESTPRODNAME = $(addsuffix $(EXE),$(basename $(TESTPROD))) - -SHRLIBNAME = $(SHRLIBNAME_$(SHARED_LIBRARIES)) -TESTSHRLIBNAME = $(TESTSHRLIBNAME_$(SHARED_LIBRARIES)) - -#-------------------------------------------------- -# obj files - -TARGET_OBJS = $($*_OBJLIBS) $($*_LDOBJS) $(addsuffix $(OBJ),$(basename $($*_OBJS) $($*_SRCS))) - -PRODUCT_OBJS = $(addsuffix $(OBJ),$(basename $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(USR_OBJS) $(PROD_OBJS))) -PROD_LD_OBJS = $(USR_OBJLIBS) $(PROD_OBJLIBS) $(TARGET_OBJS) $(PRODUCT_OBJS) - -LIBRARY_OBJS = $(addsuffix $(OBJ),$(basename $(SRCS) $(USR_SRCS) $(LIB_SRCS) $(LIBSRCS) $(USR_OBJS) $(LIB_OBJS))) -LIBRARY_LD_OBJS = $(USR_OBJLIBS) $(LIB_OBJLIBS) $(TARGET_OBJS) $(LIBRARY_OBJS) - -#-------------------------------------------------- -# Windows resource files - -TARGET_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $($*_RCS))),) - -PROD_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $(RCS) $(PROD_RCS))),) -PROD_LD_RESS = $(TARGET_RESS) $(PROD_RESS) - -LIBRARY_RESS = $(if $(RES),$(addsuffix $(RES),$(basename $(RCS) $(LIB_RCS) $(LIBRARY_RCS))),) -LIBRARY_LD_RESS = $(TARGET_RESS) $(LIBRARY_RESS) - -#-------------------------------------------------- -# C preprocessor, compiler, and linker flag defaults - -# Target architecture specific flags -ARCH_DEP_CPPFLAGS = -ARCH_DEP_CFLAGS = -ARCH_DEP_CXXFLAGS = $(ARCH_DEP_CFLAGS) -ARCH_DEP_LDFLAGS = -ARCH_DEP_LDLIBS = - -# Target operating system specific flags -OP_SYS_CPPFLAGS = -OP_SYS_CFLAGS = -OP_SYS_CXXFLAGS = $(OP_SYS_CFLAGS) -OP_SYS_LDFLAGS = -OP_SYS_INCLUDES = - -# Makefile specific flags -USR_INCLUDES = -USR_CFLAGS = -USR_CXXFLAGS = -USR_LDFLAGS = -USR_LIBS = -USR_CPPFLAGS = -USR_DBDFLAGS = -USR_ARFLAGS = - -# Variables to be set only on the command-line: -# CMD_INCLUDES = -# CMD_CFLAGS = -# CMD_CXXFLAGS = -# CMD_LDFLAGS = -# CMD_CPPFLAGS = -# CMD_DBFLAGS = -# CMD_DBDFLAGS = -# CMD_ARFLAGS = - -# Debug specific options -DEBUG_CPPFLAGS = -DEBUG_CFLAGS = -DEBUG_CXXFLAGS = $(DEBUG_CFLAGS) -DEBUG_LDFLAGS = -DEBUG_LDLIBS = - -# Target specific options -TARGET_INCLUDES = $($(basename $@)_INCLUDES_$(T_A)) -TARGET_CFLAGS = $($(basename $@)_CFLAGS_$(T_A)) -TARGET_CXXFLAGS = $($(basename $@)_CXXFLAGS_$(T_A)) -TARGET_CPPFLAGS = $($(basename $@)_CPPFLAGS_$(T_A)) - -TARGET_INCLUDES += $($(basename $@)_INCLUDES_$(OS_CLASS)) $($(basename $@)_INCLUDES) -TARGET_CFLAGS += $($(basename $@)_CFLAGS_$(OS_CLASS)) $($(basename $@)_CFLAGS) -TARGET_CXXFLAGS += $($(basename $@)_CXXFLAGS_$(OS_CLASS)) $($(basename $@)_CXXFLAGS) -TARGET_CPPFLAGS += $($(basename $@)_CPPFLAGS_$(OS_CLASS)) $($(basename $@)_CPPFLAGS) - -TARGET_LDFLAGS = $($*_LDFLAGS) - -# Warnings flags -WARN_CPPFLAGS = $(WARN_CPPFLAGS_$($(BUILD_CLASS)_WARN)) -WARN_CFLAGS = $(WARN_CFLAGS_$($(BUILD_CLASS)_WARN)) -WARN_CXXFLAGS = $(WARN_CXXFLAGS_$($(BUILD_CLASS)_WARN)) - -# Optimization flags -OPT_CPPFLAGS = $(OPT_CPPFLAGS_$($(BUILD_CLASS)_OPT)) -OPT_CFLAGS = $(OPT_CFLAGS_$($(BUILD_CLASS)_OPT)) -OPT_CXXFLAGS = $(OPT_CXXFLAGS_$($(BUILD_CLASS)_OPT)) - -# Static build flags -STATIC_CFLAGS = $(STATIC_CFLAGS_$(STATIC_BUILD)) -STATIC_CXXCFLAGS = $(STATIC_CXXFLAGS_$(STATIC_BUILD)) -STATIC_LDFLAGS = $(STATIC_LDFLAGS_$(STATIC_BUILD)) -STATIC_LDLIBS = $(STATIC_LDLIBS_$(STATIC_BUILD)) - -#-------------------------------------------------- -# cflags for shared library src files (from SHRLIB_CFLAGS) -LIBRARY_SRCS=$(basename $(foreach lib,$(LIBRARY) $(TESTLIBRARY) $(LOADABLE_LIBRARY),$($(lib)_OBJSNAME) $(LIBRARY_OBJS))) -LIBRARY_SRC_CFLAGS=$($(patsubst $*,SHRLIB,$(findstring $*,$(LIBRARY_SRCS)))_CFLAGS) - -#-------------------------------------------------- -# prefix, suffix, and ldflags for loadable shared libraries -TARGET_LIB_LDFLAGS=$($(patsubst $*,LOADABLE_,$(findstring $*,$(LOADABLE_LIBRARY)))SHRLIB_LDFLAGS) -LOADABLE_SHRLIB_PREFIX=$(SHRLIB_PREFIX) -LOADABLE_SHRLIB_SUFFIX=$(SHRLIB_SUFFIX) - -#-------------------------------------------------- -# Command-line input support default -COMMANDLINE_LIBRARY = EPICS -OP_SYS_LDLIBS += $(LDLIBS_$(COMMANDLINE_LIBRARY)) -OP_SYS_LDFLAGS += $(LDFLAGS_$(COMMANDLINE_LIBRARY)) -RUNTIME_LDFLAGS += $(RUNTIME_LDFLAGS_$(COMMANDLINE_LIBRARY)) - -#-------------------------------------------------- -# Flags - -INCLUDES = -I. $(SRC_INCLUDES) $(INSTALL_INCLUDES) $(RELEASE_INCLUDES)\ - $(TARGET_INCLUDES) $(USR_INCLUDES) $(CMD_INCLUDES) $(OP_SYS_INCLUDES)\ - $($(BUILD_CLASS)_INCLUDES) - -CFLAGS = $($(BUILD_CLASS)_CFLAGS) $(POSIX_CFLAGS) $(OPT_CFLAGS)\ - $(DEBUG_CFLAGS) $(PIPE_CFLAGS) $(WARN_CFLAGS) $(TARGET_CFLAGS)\ - $(USR_CFLAGS) $(CMD_CFLAGS) $(ARCH_DEP_CFLAGS) $(CODE_CFLAGS)\ - $(STATIC_CFLAGS) $(OP_SYS_CFLAGS) $(LIBRARY_SRC_CFLAGS) - -CXXFLAGS = $($(BUILD_CLASS)_CXXFLAGS) $(POSIX_CXXFLAGS) $(OPT_CXXFLAGS)\ - $(DEBUG_CXXFLAGS) $(PIPE_CFLAGS) $(WARN_CXXFLAGS) $(TARGET_CXXFLAGS)\ - $(USR_CXXFLAGS) $(CMD_CXXFLAGS) $(ARCH_DEP_CXXFLAGS) $(CODE_CXXFLAGS)\ - $(STATIC_CXXCFLAGS) $(OP_SYS_CXXFLAGS) $(LIBRARY_SRC_CFLAGS) - -LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(CMD_LDFLAGS)\ - $(POSIX_LDFLAGS) $(ARCH_DEP_LDFLAGS) $(DEBUG_LDFLAGS) $(OP_SYS_LDFLAGS)\ - $($(BUILD_CLASS)_LDFLAGS) $(RUNTIME_LDFLAGS) $(CODE_LDFLAGS) - -LDLIBS = $(POSIX_LDLIBS) $(ARCH_DEP_LDLIBS) $(DEBUG_LDLIBS) $(OP_SYS_LDLIBS)\ - $(GNU_LDLIBS_$(GNU)) - -CPPFLAGS = $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS)\ - $(DEBUG_CPPFLAGS) $(WARN_CPPFLAGS) $(BASE_CPPFLAGS) $(TARGET_CPPFLAGS)\ - $(USR_CPPFLAGS) $(CMD_CPPFLAGS) $(ARCH_DEP_CPPFLAGS) $(OP_SYS_CPPFLAGS)\ - $(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS) - -#-------------------------------------------------- -# ar definition default -ARFLAGS = -ARCMD = $(AR) $(ARFLAGS) $(USR_ARFLAGS) $(CMD_ARFLAGS) $@ $(LIBRARY_LD_OBJS) - -#-------------------------------------------------- -# 'Munch' link-edit -MUNCH_CMD = $(LD) $(MUNCH_LDFLAGS) -o $@ $^ - -#-------------------------------------------------- -# LEX default options -# -# Allow 8-bit characters -LEXOPT += -8 -# Generate an "interactive" scanner, solves problems at EOF. -LEXOPT += -I - -#-------------------------------------------------- -# Build compile line here - -COMPILE.c = $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDES) -COMPILE.cpp = $(CCC) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) - -#-------------------------------------------------- -# C preprocessor command -PREPROCESS.cpp = $(CPP) $(CPPFLAGS) $(INCLUDES) $< > $@ - -#-------------------------------------------------- -# genVersion header defaults - -# C macro name -GENVERSIONMACRO = VCSVERSION -# C macro default value (empty to use date+time) -GENVERSIONDEFAULT = - -#-------------------------------------------------- -# Header dependency file generation - -HDEPENDS_METHOD = MKMF - -HDEPENDS_MKMFFLAGS = -m $@ $(INCLUDES) $*$(OBJ) -HDEPENDS_MKMF.c = $(MKMF) $(HDEPENDS_FLAGS) $(HDEPENDS_MKMFFLAGS) -HDEPENDS_MKMF.cpp = $(MKMF) $(HDEPENDS_FLAGS) $(HDEPENDS_MKMFFLAGS) - -HDEPENDS_COMP.c = $(COMPILE.c) $(HDEPENDS_COMPFLAGS) $(HDEPENDS_ARCHFLAGS) -HDEPENDS_COMP.cpp = $(COMPILE.cpp) $(HDEPENDS_COMPFLAGS) $(HDEPENDS_ARCHFLAGS) - -HDEPENDS.c = $(HDEPENDS_$(HDEPENDS_METHOD).c) -HDEPENDS.cpp = $(HDEPENDS_$(HDEPENDS_METHOD).cpp) - -#-------------------------------------------------- -# Dependency files - -TARGET_SRCS = $(foreach name, \ - $(TESTPROD) $(PROD) $(TESTLIBRARY) $(LIBRARY) $(LOADABLE_LIBRARY), \ - $($(name)_SRCS)) -SRC_FILES = $(LIB_SRCS) $(LIBSRCS) $(SRCS) $(USR_SRCS) $(PROD_SRCS) $(TARGET_SRCS) -HDEPENDS_FILES = $(addsuffix $(DEP),$(notdir $(basename $(SRC_FILES)))) - -#-------------------------------------------------- -# Deprecated and no longer used in Base - -PATH_FILTER = $(1)$(warning PATH_FILTER is deprecated; used for $(1)) - -#--------------------------------------------------------------- -# Names of installed items -# -# each list starts with the destination directory name(s) -# to make sure it's there - -INSTALL_PROD= $(PRODNAME:%= $(INSTALL_BIN)/%) -INSTALL_LIBS= $(LIBNAME:%=$(INSTALL_LIB)/%) -INSTALL_MUNCHS= $(MUNCHNAME:%=$(INSTALL_BIN)/%) -INSTALL_SHRLIBS= $(SHRLIBNAME:%=$(INSTALL_SHRLIB)/%) -INSTALL_LOADABLE_SHRLIBS= $(LOADABLE_SHRLIBNAME:%=$(INSTALL_SHRLIB)/%) -INSTALL_DLLSTUB_LIBS=$(DLLSTUB_LIBNAME:%=$(INSTALL_LIB)/%) -INSTALL_TCLLIBS=$(TCLLIBNAME:%=$(INSTALL_TCLLIB)/%) -INSTALL_TCLINDEX=$(TCLINDEX:%=$(INSTALL_TCLLIB)/%) -INSTALL_SCRIPTS = $(SCRIPTS:%= $(INSTALL_BIN)/%) -INSTALL_OBJS = $(OBJSNAME:%= $(INSTALL_BIN)/%) - -INSTALL_DOCS = $(DOCS:%= $(INSTALL_DOC)/%) -INSTALL_HTMLS = $(HTMLS:%= $(INSTALL_HTML)/$(HTMLS_DIR)/%) - -INSTALL_TEMPLATE = $(addprefix $(INSTALL_TEMPLATES_SUBDIR)/, \ - $(subst $(CONFIG),top/configure,$(TEMPLATES))) -INSTALL_CONFIGS = $(CONFIGS:%= $(INSTALL_CONFIG)/%) - -INSTALL_BIN_INSTALLS = $(addprefix $(INSTALL_BIN)/,$(notdir $(BIN_INSTALLS))) -INSTALL_LIB_INSTALLS = $(addprefix $(INSTALL_LIB)/,$(notdir $(LIB_INSTALLS))) - -#--------------------------------------------------------------- -# Installed file permissions -BIN_PERMISSIONS = 555 -LIB_PERMISSIONS = 444 -SHRLIB_PERMISSIONS = 555 -INSTALL_PERMISSIONS = 444 - -#--------------------------------------------------------------- -# -# auto determine the directory paths that things are installed to -# RULES: -# 0) found in any one of several compiler specific paths -# => install to $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS) -# 1) not found in (0) and found in any one of several OS specific paths -# => install to $(INSTALL_INCLUDE)/os/$(OS_CLASS) -# 2) not found in (1) and found in generic paths -# => install to $(INSTALL_INCLUDE) -# 3) not found in (1) or (2) then may be (not yet) computer generated -# => install into $(INSTALL_INCLUDE)/os/$(OS_CLASS) and let -# build rules work on vpath -# -# These rules guarantee that the users include from -# no more than three directories -# -INSTALL_INC += $(foreach inc, $(INC), \ - $(firstword \ - $(CMPLR_INSTALL_INC) \ - $(OS_INSTALL_INC) \ - $(GENERIC_INSTALL_INC) \ - $(GENERATED_INSTALL_INC) ) ) -INSTALL_INC += $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, $(INC_$(OS_CLASS)) ) - -# -# Rule 0 -# -CMPLR_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/compiler/$(CMPLR_CLASS)/, $(INSTALL_INC_jjj) ) -INSTALL_INC_jjj = $(foreach dir, $(CMPLR_SRC_DIRS), $(INSTALL_INC_iii) ) -INSTALL_INC_iii = $(subst $(dir)/, , $(INSTALL_INC_hhh) ) -INSTALL_INC_hhh = $(wildcard $(addsuffix /$(inc), $(dir)) ) - -# -# Rule 1 -# -OS_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/os/$(OS_CLASS)/, $(INSTALL_INC_ggg) ) -INSTALL_INC_ggg = $(foreach dir, $(OS_SRC_DIRS), $(INSTALL_INC_fff) ) -INSTALL_INC_fff = $(subst $(dir)/, , $(INSTALL_INC_eee) ) -INSTALL_INC_eee = $(wildcard $(addsuffix /$(inc), $(dir)) ) - -# -# Rule 2 -# -GENERIC_INSTALL_INC = $(addprefix $(INSTALL_INCLUDE)/, $(INSTALL_INC_ccc) ) -INSTALL_INC_ccc = $(foreach dir, .. $(SRC_DIRS), $(INSTALL_INC_bbb) ) -INSTALL_INC_bbb = $(subst $(dir)/, , $(INSTALL_INC_aaa) ) -INSTALL_INC_aaa = $(wildcard $(addsuffix /$(inc), $(dir)) ) - -# -# Rule 3 -# -GENERATED_INSTALL_INC = $(INSTALL_INCLUDE)/$(inc) - -COMMON_INC += $(filter $(COMMON_DIR)/%, $(foreach file, $(INC), \ - $(firstword $(SOURCE_INC) $(COMMON_DIR)/$(file) ) ) ) -SOURCE_INC = $(wildcard $(file) $(SOURCE_INC_bbb) ) -SOURCE_INC_bbb = $(foreach dir, $(ALL_SRC_DIRS), $(SOURCE_INC_aaa) ) -SOURCE_INC_aaa = $(addsuffix /$(file), $(dir) ) - -endif diff --git a/configure/CONFIG_ENV b/configure/CONFIG_ENV deleted file mode 100644 index 1565b2ec9..000000000 --- a/configure/CONFIG_ENV +++ /dev/null @@ -1,58 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# Author: Andrew Johnson -# Date: 20 April 1995 -# -# Experimental Physics and Industrial Control System (EPICS) -# -# CONFIG_ENV - EPICS Environment Parameter configuration file -# -# This file is read by the script base/src/libCom/env/bldEnvdata.pl -# Variable definitions must take the form -# VAR = VALUE -# or -# VAR = "Value containing spaces" -# with each one on its own line. -# Enclosing spaces and "" will be trimmed. -# - -# Default environment settings - -# Channel Access: -# Details are in the CA reference manual -# (see CAref.html in this distribution) -EPICS_CA_ADDR_LIST="" -EPICS_CA_AUTO_ADDR_LIST=YES -EPICS_CA_NAME_SERVERS="" -EPICS_CA_CONN_TMO=30.0 -EPICS_CA_REPEATER_PORT=5065 -EPICS_CA_SERVER_PORT=5064 -EPICS_CA_MAX_ARRAY_BYTES=16384 -EPICS_CA_AUTO_ARRAY_BYTES=YES -EPICS_CA_BEACON_PERIOD=15.0 -EPICS_CA_MAX_SEARCH_PERIOD=300.0 -EPICS_CA_MCAST_TTL=1 -EPICS_CAS_BEACON_PERIOD= -EPICS_CAS_BEACON_PORT= -EPICS_CAS_AUTO_BEACON_ADDR_LIST="" -EPICS_CAS_BEACON_ADDR_LIST="" -EPICS_CAS_SERVER_PORT= -EPICS_CAS_INTF_ADDR_LIST="" -EPICS_CAS_IGNORE_ADDR_LIST="" - -# Log Server: -# EPICS_IOC_LOG_PORT Log server port number etc. -EPICS_IOC_LOG_PORT=7004 - -# Other services: - -EPICS_CMD_PROTO_PORT= -EPICS_AR_PORT=7002 - diff --git a/configure/CONFIG_FILE_TYPE b/configure/CONFIG_FILE_TYPE deleted file mode 100644 index b7870d7e5..000000000 --- a/configure/CONFIG_FILE_TYPE +++ /dev/null @@ -1,67 +0,0 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* -# -# Macros and rules to create a new installation file type -# - -# -------------------------------------------------------------- -# Module developers can now define a new type of file, e.g. ABC, -# so that files of type ABC will be installed into a directory -# defined by INSTALL_ABC. This is done by creating a new CONFIG -# file, e.g. CONFIG_ABC, with the following lines: -# -# FILE_TYPE += ABC -# INSTALL_ABC = $(INSTALL_LOCATION)/abc -# -# The INSTALL_ABC directory should be be a subdirectory of -# $(INSTALL_LOCATION). The file type ABC should be target -# architecture independent (alh files, medm files, edm files). -# -# Files of type ABC are then installed into the INSTALL_ABC -# directory by adding a line like the following to a Makefile. -# -# ABC += -# -# Rules necessary to create files of type ABC should be put in -# a RULES_ABC file. Variables used by those rules should appear -# in a CONFIG_ABC file. -# -# The module developer installs new CONFIG* or RULES* files -# into the directory $(INSTALL_LOCATION)/cfg by including the -# following Makefile line: -# -# CFG += CONFIG_ABC RULES_ABC -# -# CONFIG and RULES files in the $(INSTALL_LOCATION)/cfg directory -# are included by the Base config files so their definitions and -# rules are available for use by later src directory Makefiles in -# the same module, or by other modules with a RELEASE line that -# points to the TOP of the module providing these files. - -FILE_TYPE += ADL -INSTALL_ADL = $(INSTALL_LOCATION)/adl - -FILE_TYPE += ALH -INSTALL_ALH = $(INSTALL_LOCATION)/alh - -FILE_TYPE += CFG -INSTALL_CFG = $(INSTALL_LOCATION)/cfg - -FILE_TYPE += EDL -INSTALL_EDL = $(INSTALL_LOCATION)/edl - -FILE_TYPE += PERL_MODULES -INSTALL_PERL_MODULES = $(INSTALL_LOCATION_LIB)/perl - -FILE_TYPE += PKGCONFIG -INSTALL_PKGCONFIG = $(INSTALL_LOCATION_LIB)/pkgconfig - -INSTALLS_CFG = $(CFG:%= $(INSTALL_CFG)/%) -DIRECTORY_TARGETS += $(foreach type, $(FILE_TYPE),$(INSTALL_$(type))) - diff --git a/configure/CONFIG_SITE b/configure/CONFIG_SITE index b657f5b65..d78c7f514 100644 --- a/configure/CONFIG_SITE +++ b/configure/CONFIG_SITE @@ -1,178 +1,42 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* +# CONFIG_SITE +# Make any application-specific changes to the EPICS build +# configuration variables in this file. # -# CONFIG_SITE - Global site configuration file -# +# Host/target specific settings can be specified in files named +# CONFIG_SITE.$(EPICS_HOST_ARCH).Common +# CONFIG_SITE.Common.$(T_A) +# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) -# The host architecture performing the build, in the form -# -[-] -# -# Currently Supporting: -# cygwin-x86 (cygwin compiler used for host builds) -# cygwin-x86_64 (cygwin compiler used for host builds) -# darwin-ppc (PowerPC based Apple running OSX) -# darwin-ppcx86 (Universal binaries for both CPUs) -# darwin-x86 (Intel based Apple running OSX) -# freebsd-x86 (GNU compiler used for host builds) -# freebsd-x86_64 (GNU compiler used for host builds) -# linux-arm (GNU compiler used for host builds) -# linux-ppc (GNU compiler used for host builds) -# linux-ppc64 (GNU compiler used for host builds) -# linux-x86 (GNU compiler used for host builds) -# linux-x86_64 (GNU compiler used for host builds) -# solaris-sparc (Sun compiler used for host builds) -# solaris-sparc-gnu (GNU compiler used for host builds) -# solaris-sparc64 (Sun compiler used for host builds) -# solaris-sparc64-gnu (GNU compiler used for host builds) -# solaris-x86 (Sun compiler used for host builds) -# solaris-x86-gnu (GNU compiler used for host builds) -# solaris-x86_64 (Sun compiler used for host builds) -# solaris-x86_64-gnu (GNU compiler used for host builds) -# win32-x86 (MS Visual C++ compiler used for host builds) -# win32-x86-mingw (MinGW compiler used for host builds) -# win32-x86-static (MS Visual C++ compiler used for host builds) -# windows-x64 (MS Visual C++ compiler used for host builds) -# windows-x64-mingw (MinGW compiler used for host builds) -# windows-x64-static (MS Visual C++ compiler used for host builds) +# CHECK_RELEASE controls the consistency checking of the support +# applications pointed to by the RELEASE* files. +# Normally CHECK_RELEASE should be set to YES. +# Set CHECK_RELEASE to NO to disable checking completely. +# Set CHECK_RELEASE to WARN to perform consistency checking but +# continue building even if conflicts are found. +CHECK_RELEASE = YES -# Debugging builds: -# linux-arm-debug (GNU compiler used for host builds) -# linux-x86-debug (GNU compiler with -g option for host builds) -# linux-x86_64-debug (GNU compiler with -g option for host builds) -# solaris-sparc-debug (sun compiler no optimization,-g for debugging info) -# win32-x86-debug (MS Visual C++ compiler with debug option for host builds) -# windows-x64-debug (MS Visual C++ compiler with debug option for host builds) +# Set this when you only want to compile this application +# for a subset of the cross-compiled target architectures +# that Base is built for. +#CROSS_COMPILER_TARGET_ARCHS = vxWorks-ppc32 +# To install files into a location other than $(TOP) define +# INSTALL_LOCATION here. +#INSTALL_LOCATION= -# EPICS_HOST_ARCH is a required environment variable -# Do not set EPICS_HOST_ARCH in this file. -# Use base/startup files to set EPICS_HOST_ARCH or -# provide EPICS_HOST_ARCH on the GNU make command line. +# Set this when the IOC and build host use different paths +# to the install location. This may be needed to boot from +# a Microsoft FTP server say, or on some NFS configurations. +#IOCS_APPL_TOP = -# The cross-compiler architectures to build EPICS for -# -# Currently Supporting: +# For application debugging purposes, override the HOST_OPT and/ +# or CROSS_OPT settings from base/configure/CONFIG_SITE +#HOST_OPT = NO +#CROSS_OPT = NO -# ios-arm (darwin-x86 host) -# ios-386 (darwin-x86 host) -# linux-386 (linux-x86 host) -# linux-486 (linux-x86 host) -# linux-586 (linux-x86 host) -# linux-686 (linux-x86 host) -# linux-arm (linux-x86 or -x86_64 host) -# linux-arm_eb (linux-x86 host) -# linux-arm_el (linux-x86 host) -# linux-athlon (linux-x86 host) -# linux-cris (Axis GNU crosscompiler on linux-x86 host) -# linux-cris_v10 (Axis GNU crosscompiler on linux-x86 host) -# linux-cris_v32 (Axis GNU crosscompiler on linux-x86 host) -# linux-microblaze -# linux-xscale_be -# vxWorks-486 -# vxWorks-68040 -# vxWorks-68040lc -# vxWorks-68060 -# vxWorks-pentium -# vxWorks-ppc32 (32-bit PowerPC CPUs with full FPU) -# vxWorks-ppc32sf (32-bit PowerPC CPUs without FPU) -# vxWorks-ppc603 -# vxWorks-ppc603_long -# vxWorks-ppc604 -# vxWorks-ppc604_long -# vxWorks-ppc604_altivec -# vxWorks-mpc8540 -# vxWorks-mpc8548 -# RTEMS-at91rm9200ek -# RTEMS-beatnik -# RTEMS-gen68360 -# RTEMS-mcp750 -# RTEMS-mvme167 -# RTEMS-mvme2100 -# RTEMS-mvme2700 -# RTEMS-mvme3100 -# RTEMS-mvme5500 -# RTEMS-pc386 -# RTEMS-psim -# RTEMS-uC5282 -# win32-x86-mingw (linux-x86 or -x86_64 host) -# - -# Which target architectures to cross-compile for. -# Definitions in configure/os/CONFIG_SITE..Common -# may override this setting. -CROSS_COMPILER_TARGET_ARCHS= -#CROSS_COMPILER_TARGET_ARCHS=vxWorks-ppc32 - -# If only some of your host architectures can compile the -# above CROSS_COMPILER_TARGET_ARCHS specify those host -# architectures here. If the combination is complicated, -# set CROSS_COMPILER_TARGET_ARCHS in the appropriate -# configure/os/CONFIG_SITE..Common files instead. -CROSS_COMPILER_HOST_ARCHS= - -# The 'runtests', 'tapfiles' and 'junitfiles' make targets normally only run -# self-tests for the EPICS_HOST_ARCH architecture. If the host can execute -# the self-test programs for any other cross-built architectures such as -# a -debug architecture, those architectures must be named in this variable: -CROSS_COMPILER_RUNTEST_ARCHS= - -# Build shared libraries (DLLs on Windows). -# Must be either YES or NO. Definitions in the target-specific -# os/CONFIG.Common. and os/CONFIG_SITE.Common. files may -# override this setting. On Windows only these combinations are valid: -# SHARED_LIBRARIES = YES and STATIC_BUILD = NO -# SHARED_LIBRARIES = NO and STATIC_BUILD = YES -SHARED_LIBRARIES=YES - -# Build client objects statically. -# Must be either YES or NO. -STATIC_BUILD=NO - -# Host build optimization. -# Must be either YES or NO. -HOST_OPT=YES - -# Cross build optimization. -# Must be either YES or NO. -CROSS_OPT=YES - -# Generate verbose compiler warnings for host builds. -# Must be either YES or NO. -HOST_WARN=YES - -# Generate verbose compiler warnings for cross-compiled builds. -# Must be either YES or NO. -CROSS_WARN=YES - -# Installation directory, if you want Base to be installed into a -# different location then uncomment and set this. -#INSTALL_LOCATION= - -# Use POSIX thread priority scheduling (if available). -# Must be either YES or NO -USE_POSIX_THREAD_PRIORITY_SCHEDULING = YES - -# Site version number, if set will append '-' and this string to the -# EPICS version number string that is reported by many tools. -EPICS_SITE_VERSION = - -# For GNU compiler, use pipes rather than temporary files for -# communication between the various stages of compilation. -# Must be either YES or NO -GCC_PIPE = NO - -# Set RPATH when linking executables and libraries. -# Must be either YES or NO. If you set this to NO you must also provide a -# way for Base executables to find their shared libraries when they are -# run at build-time, e.g. set the LD_LIBRARY_PATH environment variable. -LINKER_USE_RPATH = YES - -# Overrides for the settings above may appear in a CONFIG_SITE.local file --include $(CONFIG)/CONFIG_SITE.local +# These allow developers to override the CONFIG_SITE variable +# settings without having to modify the configure/CONFIG_SITE +# file itself. +-include $(TOP)/../CONFIG_SITE.local +-include $(TOP)/configure/CONFIG_SITE.local diff --git a/configure/CONFIG_SITE_ENV b/configure/CONFIG_SITE_ENV deleted file mode 100644 index 3a38d68de..000000000 --- a/configure/CONFIG_SITE_ENV +++ /dev/null @@ -1,83 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# Author: Andrew Johnson -# Date: 1 May 1995 -# -# Experimental Physics and Industrial Control System (EPICS) -# -# CONFIG_SITE_ENV - EPICS Environment Parameter Site configuration file -# -# This file is read by the script base/src/libCom/env/bldEnvdata.pl -# Variable definitions must take the form -# VAR = VALUE -# or -# VAR = "Value containing spaces" -# with each one on its own line. -# Enclosing spaces and "" will be trimmed. -# - -# Site-specific environment settings - -# Time service: -# EPICS_TIMEZONE -# local timezone info for vxWorks and RTEMS IOCs. The format is -# :::: -# where the start and end are mmddhh - that is month,day,hour -# e.g. for ANL in 2016: EPICS_TIMEZONE=CST/CDT::360:031302:110602 -# -# DST for 2016 US: Mar 13 - Nov 06 -# EU: Mar 27 - Oct 30 -# DST for 2017 US: Mar 12 - Nov 05 -# EU: Mar 26 - Oct 29 -# DST for 2018 US: Mar 11 - Nov 04 -# EU: Mar 25 - Oct 28 -# DST for 2019 US: Mar 10 - Nov 03 -# EU: Mar 31 - Oct 27 -# DST for 2020 US: Mar 08 - Nov 01 -# EU: Mar 29 - Oct 25 -# DST for 2021 US: Mar 14 - Nov 07 -# EU: Mar 28 - Oct 31 -# (see: http://www.timeanddate.com/time/dst/2016.html etc. ) -# -# These values are for 2016: -EPICS_TIMEZONE=CST/CDT::360:031302:110602 -#EPICS_TIMEZONE=CET/CEST::-60:032702:103002 - -# EPICS_TS_NTP_INET -# NTP time server ip address. Uses boot host if not set. -EPICS_TS_NTP_INET= - -# IOC Shell: -# IOCSH_PS1 -# Prompt string -# IOCSH_HISTSIZE -# Number of lines of command history to keep. -# IOCSH_HISTEDIT_DISABLE -# Prevents use of readline or equivalent if defined. -IOCSH_PS1="epics> " -IOCSH_HISTSIZE=50 -IOCSH_HISTEDIT_DISABLE= - -# Log Server: -# EPICS_IOC_LOG_INET -# Log server ip addr. -# EPICS_IOC_LOG_FILE_NAME -# pathname to the log file. -# EPICS_IOC_LOG_FILE_LIMIT -# maximum log file size. -# EPICS_IOC_LOG_FILE_COMMAND -# A shell command string used to obtain a new -# path name in response to SIGHUP - the new path name will -# replace any path name supplied in EPICS_IOC_LOG_FILE_NAME - -EPICS_IOC_LOG_INET= -EPICS_IOC_LOG_FILE_NAME= -EPICS_IOC_LOG_FILE_COMMAND= -EPICS_IOC_LOG_FILE_LIMIT=1000000 - diff --git a/configure/Makefile b/configure/Makefile index 377879766..925430940 100644 --- a/configure/Makefile +++ b/configure/Makefile @@ -1,24 +1,8 @@ -#************************************************************************* -# Copyright (c) 2002 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - TOP=.. include $(TOP)/configure/CONFIG -# Bootstrap resolution: tools not installed yet -TOOLS = $(TOP)/src/tools - -CONFIGS += $(subst ../,,$(wildcard ../CONFIG*)) -CONFIGS += $(subst ../,,$(wildcard ../os/CONFIG*)) - -CONFIGS += $(subst ../,,$(wildcard ../RELEASE*)) -CONFIGS += $(subst ../,,$(wildcard ../RULES*)) +TARGETS = $(CONFIG_TARGETS) +CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS))) include $(TOP)/configure/RULES - diff --git a/configure/RELEASE b/configure/RELEASE index 88b819034..194715368 100644 --- a/configure/RELEASE +++ b/configure/RELEASE @@ -1,22 +1,42 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - +# RELEASE - Location of external support modules # -# RELEASE: Define the location of external EPICS products +# IF YOU MAKE ANY CHANGES to this file you must subsequently +# do a "gnumake rebuild" in this application's top level +# directory. # - -# The version of this file in Base should normally be empty. +# The build process does not check dependencies against files +# that are outside this application, thus you should do a +# "gnumake rebuild" in the top level directory after EPICS_BASE +# or any other external module pointed to below is rebuilt. # -# Define INSTALL_LOCATION in CONFIG_SITE +# Host- or target-specific settings can be given in files named +# RELEASE.$(EPICS_HOST_ARCH).Common +# RELEASE.Common.$(T_A) +# RELEASE.$(EPICS_HOST_ARCH).$(T_A) +# +# This file is parsed by both GNUmake and an EPICS Perl script, +# so it can ONLY contain definititions of paths to other support +# modules, variable definitions that are used in module paths, +# and include statements that pull in other RELEASE files. +# Variables may be used before their values have been set. +# Build variables that are NOT used in paths should be set in +# the CONFIG_SITE file. -# NB: Settings in RELEASE files can be overridden in files named -# RELEASE.$(EPICS_HOST_ARCH).Common -# RELEASE.Common.$(T_A) -# RELEASE.$(EPICS_HOST_ARCH).$(T_A) +# Variables and paths to dependent modules: +#MODULES = /path/to/modules +#MYMODULE = $(MODULES)/my-module +# If using the sequencer, point SNCSEQ at its top directory: +#SNCSEQ = $(MODULES)/seq-ver + +# EPICS_BASE should appear last so earlier modules can override stuff: +EPICS_BASE = /home/ralph/work/EPICS/V3/3.16 + +# Set RULES here if you want to use build rules from somewhere +# other than EPICS_BASE: +#RULES = $(MODULES)/build-rules + +# These allow developers to override the RELEASE variable settings +# without having to modify the configure/RELEASE file itself. +-include $(TOP)/../RELEASE.local +-include $(TOP)/configure/RELEASE.local diff --git a/configure/RULES b/configure/RULES index bdc895a4d..6d56e14e8 100644 --- a/configure/RULES +++ b/configure/RULES @@ -1,20 +1,6 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* +# RULES -ifndef T_A - -include $(CONFIG)/RULES_ARCHS - -else #T_A - -include $(CONFIG)/RULES_BUILD - -endif # T_A defined +include $(CONFIG)/RULES +# Library should be rebuilt because LIBOBJS may have changed. +$(LIBNAME): ../Makefile diff --git a/configure/RULES.Db b/configure/RULES.Db deleted file mode 100644 index 7836d280e..000000000 --- a/configure/RULES.Db +++ /dev/null @@ -1,541 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -#RULES.Db - -# Set db substitutions and template file suffixes -SUBST_SUFFIX ?= .substitutions -TEMPL_SUFFIX ?= .template - -#--------------------------------------------------------------- -# vpath - -vpath %.pm $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD)) -vpath %.pod $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD)) -vpath %.dbd $(USR_VPATH) $(SRC_DIRS) $(dir $(DBD)) -vpath %.db $(USR_VPATH) $(SRC_DIRS) $(dir $(DB)) -vpath %.vdb $(USR_VPATH) $(SRC_DIRS) $(dir $(DB)) -vpath %$(SUBST_SUFFIX) $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR) -vpath %$(TEMPL_SUFFIX) $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR) -vpath bpt%.data $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR) -vpath %.acf $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR) -vpath %.acs $(USR_VPATH) $(SRC_DIRS) $(COMMON_DIR) - -#--------------------------------------------------------------- -# dbflags dbdflags - -DBD_SEARCH_DIRS = . .. $(COMMON_DIR) $(SRC_DIRS) $(INSTALL_DBD) $(RELEASE_DBD_DIRS) -DB_SEARCH_DIRS = . .. $(COMMON_DIR) $(SRC_DIRS) $(INSTALL_DB) $(RELEASE_DB_DIRS) - -DBDFLAGS = $(USR_DBDFLAGS) $(CMD_DBDFLAGS) $(addprefix -I,$(DBD_SEARCH_DIRS)) -DBFLAGS = $($*_DBFLAGS) $(USR_DBFLAGS) $(CMD_DBFLAGS) $(addprefix -I,$(DB_SEARCH_DIRS)) -REGRDDFLAGS = $(DBDFLAGS) $($*_REGRDDFLAGS) $(USR_REGRDDFLAGS) $(CMD_REGRDDFLAGS) - -#--------------------------------------------------------------- -# Targets - -# --------------------------------------------------- -# To allow os specific dbd files AND have the -j option work properly, - -CROSS_TARGET_OS_TYPES = $(sort $(foreach target, \ - $(EPICS_HOST_ARCH) $(CROSS_COMPILER_TARGET_ARCHS), \ - $(firstword $(subst -, ,$(target))))) -DBD += $(foreach type, $(CROSS_TARGET_OS_TYPES), $(DBD_$(type))) - -# Users add os specific dbd files to a Makefile as follows -# -# DBD_vxWorks += abcVx.dbd -# DBD_RTEMS += abcRTEMS.dbd -# DBD_solaris += abcSolaris.dbd -# -# --------------------------------------------------- -# DBD concatination files - -COMMON_DBDCATS += $(addprefix $(COMMON_DIR)/,$(DBDCAT)) -DBDCAT_SOURCES += $(foreach file, $($*_DBD), $(DBDCAT_SOURCE) ) -DBDCAT_SOURCE = $(firstword $(wildcard $(file) $(foreach dir, \ - $(DBD_SEARCH_DIRS),$(addsuffix /$(file),$(dir)))) \ - $(COMMON_DIR)/$(file)) - -DBDCAT_COMMAND = $(if $(DBDCAT_SOURCES),\ - $(CAT) $(DBDCAT_SOURCES) > $(notdir $@),\ - @echo "No input files for $(notdir $@)") - -INSTALL_DBDS += $(addprefix $(INSTALL_DBD)/,$(DBDCAT)) - -# --------------------------------------------------- - -DBDINC_NAME = $(patsubst %.h,%,$(patsubst %.dbd,%,$(DBDINC))) -DBD += $(addsuffix .dbd,$(DBDINC_NAME)) -INC += $(addsuffix .h,$(DBDINC_NAME)) - -INSTALL_DBDS += $(addprefix $(INSTALL_DBD)/,$(notdir $(DBD))) - -COMMON_DBDS += $(filter $(COMMON_DIR)/%, $(foreach file, $(DBD), \ - $(firstword $(SOURCE_DBD) $(COMMON_DIR)/$(file) ) ) ) -SOURCE_DBD = $(wildcard $(file) $(SOURCE_DBD_bbb) ) -SOURCE_DBD_bbb = $(foreach dir, $(GENERIC_SRC_DIRS), $(SOURCE_DBD_aaa) ) -SOURCE_DBD_aaa = $(addsuffix /$(file), $(dir) ) - -INSTALL_DBS += $(addprefix $(INSTALL_DB)/,$(notdir $(DB))) - -COMMON_DBS += $(filter $(COMMON_DIR)/%, $(foreach file, $(DB), \ - $(firstword $(SOURCE_DB) $(COMMON_DIR)/$(file) ) ) ) -SOURCE_DB = $(wildcard $(file) $(SOURCE_DB_bbb) ) -SOURCE_DB_bbb = $(foreach dir, $(GENERIC_SRC_DIRS), $(SOURCE_DB_aaa) ) -SOURCE_DB_aaa = $(addsuffix /$(file), $(dir) ) - -COMMONS = $(COMMON_DIR)/*.dbd $(COMMON_DIR)/*.db $(COMMON_DIR)/*.h \ - $(COMMON_DIR)/*$(SUBST_SUFFIX) $(COMMON_DIR)/*$(TEMPL_SUFFIX) - -# Remove trailing numbers (to 99) on stem -TEMPLATE1 = $(patsubst %0,%,$(patsubst %1,%,$(patsubst %2,%,$(patsubst %3,%, \ - $(patsubst %4,%,$(patsubst %5,%,$(patsubst %6,%,$(patsubst %7,%, \ - $(patsubst %8,%,$(patsubst %9,%,$*)))))))))) -TEMPLATE2 = $(patsubst %0,%,$(patsubst %1,%,$(patsubst %2,%,$(patsubst %3,%, \ - $(patsubst %4,%,$(patsubst %5,%,$(patsubst %6,%,$(patsubst %7,%, \ - $(patsubst %8,%,$(patsubst %9,%,$(TEMPLATE1))))))))))) -TEMPLATE3 = $(addsuffix $(TEMPL_SUFFIX),$(addprefix ../,$(TEMPLATE2))) -TEMPLATE_FILENAME = $(firstword $(wildcard $($*_TEMPLATE) \ - $(addprefix ../,$($*_TEMPLATE)) ../$*$(TEMPL_SUFFIX) $(TEMPLATE3) \ - ../template)) - -INSTALL_DB_INSTALLS = $(addprefix $(INSTALL_DB)/,$(notdir $(DB_INSTALLS))) -INSTALL_DBD_INSTALLS = $(addprefix $(INSTALL_DBD)/,$(notdir $(DBD_INSTALLS))) - -COMMONDEP_TARGET = $(COMMON_DIR)/$(basename $@) - -#--------------------------------------------------------------- -# acf files - -# An access security configuration file, *.acf, can be created from -# an *.acs file (has format of acf file plus #include "filename" lines) - -# flags for GNU compiler -ACF_CPPFLAGS_YES = -undef -nostdinc -ACF_CPPFLAGS = $(ACF_CPPFLAGS_$(GNU)) - -ACF_INCLUDES = -I. $(TARGET_INCLUDES) $(USR_INCLUDES)\ - $(SRC_INCLUDES) -I$(INSTALL_DB) -ACFDEPENDS_CMD = $(MKMF) -m $@ $(ACF_INCLUDES) $(COMMONDEP_TARGET) $< -ACF_CMD = $(CPP) $(ACF_CPPFLAGS) $(ACF_INCLUDES) $< > $@ - -#--------------------------------------------------------------- -# dependencies - -HINC += $(addsuffix .h,$(DBDINC_NAME)) -COMMON_DBDINC += $(addprefix $(COMMON_DIR)/,$(HINC)) - -DBDDEPENDS_FILES += $(addsuffix $(DEP),$(HINC) \ - $(patsubst $(COMMON_DIR)/%,%,$(COMMON_DBS)) \ - $(patsubst $(COMMON_DIR)/%,%, \ - $(filter-out $(COMMON_DIR)/bpt%.dbd,$(COMMON_DBDS)))) - -#--------------------------------------------------------------- - -ifndef T_A - -DEP = .d -TEMPLATE3 += $(addsuffix $(TEMPL_SUFFIX), $(TEMPLATE2)) - -COMMON_DIR = . -INSTALL_DBDS = -INSTALL_DBS = -COMMON_DBDS = $(DBD) -COMMON_DBS = $(DB) -COMMONS = $(DBD) $(DB) - -ACTIONS = inc -ACTIONS += build -ACTIONS += install -ACTIONS += buildInstall -ACTIONS += runtests tapfiles clean-tests test-results junitfiles - -actionArchTargets = $(foreach action, $(ACTIONS), \ - $(foreach arch, $(BUILD_ARCHS), $(action)$(DIVIDER)$(arch))) -cleanArchTargets = $(foreach arch, $(BUILD_ARCHS), clean$(DIVIDER)$(arch)) - --include $(TOP)/configure/CONFIG_APP_INCLUDE - -all: install - -install: buildInstall - -buildInstall : build - -rebuild: clean install - -.PHONY: all $(ACTIONS) - -$(actionArchTargets) $(BUILD_ARCHS): install -$(cleanArchTargets): clean - -.PHONY: $(BUILD_ARCHS) $(actionArchTargets) $(cleanArchTargets) - -else - # T_A is defined - ifeq ($(EPICS_HOST_ARCH),$(T_A)) - host: install - else - host: - endif - - .PHONY: host -endif # T_A - -ifneq (,$(strip $(DBDDEPENDS_FILES))) --include $(DBDDEPENDS_FILES) -endif - -#--------------------------------------------------------------- -# build dependancies, clean rule - -inc : $(COMMON_INC) $(INSTALL_INC) - -build : $(COMMON_DBDS) $(COMMON_DBS) $(COMMON_DBDCATS) \ - $(INSTALL_DBDS) $(INSTALL_DBS) \ - $(DBDDEPENDS_FILES) $(TARGETS) \ - $(INSTALL_DB_INSTALLS) $(INSTALL_DBD_INSTALLS) - -clean: db_clean - -db_clean : - @$(RM) $(COMMONS) $(DBDDEPENDS_FILES) - @$(RM) *_registerRecordDeviceDriver.cpp - @$(RM) $(TARGETS) - -.PHONY : db_clean - -realclean: clean - -#--------------------------------------------------------------- -# Dependency files - -%Record.h$(DEP): $(COMMON_DIR)/%Record.dbd - @$(RM) $@ - @$(DBTORECORDTYPEH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -%Record.h$(DEP): %Record.dbd - @$(RM) $@ - @$(DBTORECORDTYPEH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -%Record.h$(DEP): ../%Record.dbd - @$(RM) $@ - @$(DBTORECORDTYPEH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -menu%.h$(DEP): $(COMMON_DIR)/menu%.dbd - @$(RM) $@ - @$(DBTOMENUH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -menu%.h$(DEP): menu%.dbd - @$(RM) $@ - @$(DBTOMENUH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -menu%.h$(DEP): ../menu%.dbd - @$(RM) $@ - @$(DBTOMENUH) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -%.dbd$(DEP): %.dbd.pod - @$(RM) $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" > $@ - -%.dbd$(DEP): %Include.dbd - @$(RM) $@ - @$(DBEXPAND) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -%.dbd$(DEP): ../%Include.dbd - @$(RM) $@ - @$(DBEXPAND) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -%.dbd$(DEP): - @$(RM) $@ - @$(DBEXPAND) -D $(DBDFLAGS) -o $(COMMONDEP_TARGET) $($*_DBD) > $@ - @echo "$(COMMONDEP_TARGET): ../Makefile" >> $@ - -%.db$(DEP): %$(SUBST_SUFFIX) - @$(RM) $@ - $(MSI3_15) -D $(DBFLAGS) -o $(COMMONDEP_TARGET) -S$< $(TEMPLATE_FILENAME) > $@ - -%.db$(DEP): ../%$(SUBST_SUFFIX) - @$(RM) $@ - $(MSI3_15) -D $(DBFLAGS) -o $(COMMONDEP_TARGET) -S$< $(TEMPLATE_FILENAME) > $@ - -%.db$(DEP): %$(TEMPL_SUFFIX) - @$(RM) $@ - $(MSI3_15) -D $(DBFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - -%.db$(DEP): ../%$(TEMPL_SUFFIX) - @$(RM) $@ - $(MSI3_15) -D $(DBFLAGS) -o $(COMMONDEP_TARGET) $< > $@ - -%.acf$(DEP): %.acs - @$(RM) $@ - @$(ACFDEPENDS_CMD) - -%.acf$(DEP): ../%.acs - @$(RM) $@ - @$(ACFDEPENDS_CMD) - -.PRECIOUS: %$(DEP) - -#--------------------------------------------------------------- -# Substitution files - -# WARNING: CREATESUBSTITUTIONS script needs output dir on command line - -ifdef CREATESUBSTITUTIONS -$(COMMON_DIR)/%$(SUBST_SUFFIX): - $(ECHO) "Create substitutions" - @$(RM) $@ - $(CREATESUBSTITUTIONS) $@ -endif - -$(INSTALL_DB)/%$(SUBST_SUFFIX): %$(SUBST_SUFFIX) - $(ECHO) "Installing substitution file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(INSTALL_DB)/%$(SUBST_SUFFIX): ../%$(SUBST_SUFFIX) - $(ECHO) "Installing substitution file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -.PRECIOUS: $(COMMON_DIR)/%$(SUBST_SUFFIX) - -#--------------------------------------------------------------- -# Template files - -$(INSTALL_DB)/%$(TEMPL_SUFFIX): %$(TEMPL_SUFFIX) - $(ECHO) "Installing template file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(INSTALL_DB)/%$(TEMPL_SUFFIX): ../%$(TEMPL_SUFFIX) - $(ECHO) "Installing template file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -.PRECIOUS: $(COMMON_DIR)/%$(TEMPL_SUFFIX) - -#--------------------------------------------------------------- -# INC files - -$(COMMON_DIR)/%Record.h: $(COMMON_DIR)/%Record.dbd - @$(RM) $(notdir $@) - $(DBTORECORDTYPEH) $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%Record.h: %Record.dbd - @$(RM) $(notdir $@) - $(DBTORECORDTYPEH) $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%Record.h: ../%Record.dbd - @$(RM) $(notdir $@) - $(DBTORECORDTYPEH) $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/menu%.h: $(COMMON_DIR)/menu%.dbd - @$(RM) $(notdir $@) - $(DBTOMENUH) $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/menu%.h: menu%.dbd - @$(RM) $(notdir $@) - $(DBTOMENUH) $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/menu%.h: ../menu%.dbd - @$(RM) $(notdir $@) - $(DBTOMENUH) $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -.PRECIOUS: $(COMMON_DIR)/%.h - -#--------------------------------------------------------------- -# DBD files - -$(COMMON_DIR)/bpt%.dbd: bpt%.data - @$(RM) $(notdir $@) - $(MAKEBPT) $< $(notdir $@) - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.dbd: %.dbd.pod - @$(RM) $(notdir $@) - $(PERL) $(TOOLS)/podRemove.pl -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.dbd: %Include.dbd - $(ECHO) "Expanding dbd file $<" - @$(RM) $(notdir $@) - $(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.dbd: ../%Include.dbd - $(ECHO) "Expanding dbd file $<" - @$(RM) $(notdir $@) - $(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -# Make DBDCAT file x depend on x_DBD source files -define DBDCAT_template -$$(COMMON_DIR)/$(1).dbd : ../Makefile $$(foreach file, $$($(1)_DBD),$$(DBDCAT_SOURCE) ) -endef -$(foreach name,$(subst .dbd,,$(DBDCAT)), $(eval $(call DBDCAT_template,$(name)))) - -$(COMMON_DBDCATS):$(COMMON_DIR)/%.dbd: - $(ECHO) "Creating dbd file $(notdir $@)" - @$(RM) $(notdir $@) - $(DBDCAT_COMMAND) - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.dbd: - $(ECHO) "Creating dbd file $(notdir $@)" - @$(RM) $(notdir $@) - $(DBEXPAND) $(DBDFLAGS) -o $(notdir $@) $($*_DBD) - @$(MV) $(notdir $@) $@ - -$(INSTALL_DBD)/%: $(COMMON_DIR)/% - $(ECHO) "Installing created dbd file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(INSTALL_DBD)/%: % - $(ECHO) "Installing dbd file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(INSTALL_DBD)/%: ../% - $(ECHO) "Installing dbd file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -define DBD_INSTALLS_template -$$(INSTALL_DBD)/$$(notdir $(1)) : $(1) - $(ECHO) "Installing $$@" - @$$(INSTALL) -d -m $$(INSTALL_PERMISSIONS) $$^ $$(INSTALL_DBD) -endef -$(foreach file, $(DBD_INSTALLS), $(eval $(call DBD_INSTALLS_template, $(file)))) - -.PRECIOUS: $(COMMON_DBDS) $(COMMON_DIR)/%.dbd - -#--------------------------------------------------------------- -# HTML files - -$(COMMON_DIR)/%.html: %.dbd.pod $(TOOLS)/dbdToHtml.pl - @$(RM) $(notdir $@) - $(PERL) $(TOOLS)/dbdToHtml.pl $(DBDFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.html: %.pod $(TOOLS)/podToHtml.pl - @$(RM) $(notdir $@) - $(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.html: %.pm $(TOOLS)/podToHtml.pl - @$(RM) $(notdir $@) - $(PERL) $(TOOLS)/podToHtml.pl -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.html: ../%.pm $(TOOLS)/podToHtml.pl - @$(RM) $(notdir $@) - $(PERL) $(TOOLS)/podToHtml.pl -s -o $(notdir $@) $< - @$(MKDIR) $(dir $@) - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.html: ../%.pl $(TOOLS)/podToHtml.pl - @$(RM) $(notdir $@) - $(PERL) $(TOOLS)/podToHtml.pl -s -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -.PRECIOUS: $(COMMON_DIR)/%.html %.html - -#--------------------------------------------------------------- -# DB files - -$(COMMON_DIR)/%.db: $(COMMON_DIR)/%.edf - $(E2DB) $(E2DB_SYSFLAGS) $(E2DB_FLAGS) -n $*.VAR $< - @$(REPLACEVAR) < $*.VAR > $@ - @$(RM) $*.VAR - -$(COMMON_DIR)/%.db: %$(SUBST_SUFFIX) - $(ECHO) "Inflating database from $< $(TEMPLATE_FILENAME)" - @$(RM) $(notdir $@) - $(MSI3_15) $(DBFLAGS) -o $(notdir $@) -S$< $(TEMPLATE_FILENAME) - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.db: ../%$(SUBST_SUFFIX) - $(ECHO) "Inflating database from $< $(TEMPLATE_FILENAME)" - @$(RM) $(notdir $@) - $(MSI3_15) $(DBFLAGS) -o $(notdir $@) -S$< $(TEMPLATE_FILENAME) - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.db: %$(TEMPL_SUFFIX) - $(ECHO) "Inflating database from $<" - @$(RM) $(notdir $@) - $(MSI3_15) $(DBFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.db: ../%$(TEMPL_SUFFIX) - $(ECHO) "Inflating database from $<" - @$(RM) $(notdir $@) - $(MSI3_15) $(DBFLAGS) -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/%.acf: %.acs - $(ECHO) "Creating acf file $@" - @$(RM) $@ - $(ACF_CMD) - -$(COMMON_DIR)/%.acf: ../%.acs - $(ECHO) "Creating acf file $@" - @$(RM) $@ - $(ACF_CMD) - -.PRECIOUS: $(COMMON_DIR)/%.acf - -$(INSTALL_DB)/%: % - $(ECHO) "Installing $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(INSTALL_DB)/%: ../% - $(ECHO) "Installing $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(INSTALL_DB)/%.db: $(COMMON_DIR)/%.db - $(ECHO) "Installing created db file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -define DB_INSTALLS_template -$$(INSTALL_DB)/$$(notdir $(1)) : $(1) - $(ECHO) "Installing $$@" - @$$(INSTALL) -d -m $$(INSTALL_PERMISSIONS) $$^ $$(INSTALL_DB) -endef -$(foreach file, $(DB_INSTALLS), $(eval $(call DB_INSTALLS_template, $(file)))) - -.PRECIOUS: $(COMMON_DIR)/%.edf -.PRECIOUS: $(COMMON_DBS) - -#--------------------------------------------------------------- -# register record,device,driver support - -%_registerRecordDeviceDriver.cpp: $(COMMON_DIR)/%.dbd - @$(RM) $@ - $(REGISTERRECORDDEVICEDRIVER) $(REGRDDFLAGS) -o $@ $< $(basename $@) $(IOCS_APPL_TOP) - -%_registerRecordDeviceDriver.cpp: %.dbd - @$(RM) $@ - $(REGISTERRECORDDEVICEDRIVER) $(REGRDDFLAGS) -o $@ $< $(basename $@) $(IOCS_APPL_TOP) - -%_registerRecordDeviceDriver.cpp: ../%.dbd - @$(RM) $@ - $(REGISTERRECORDDEVICEDRIVER) $(REGRDDFLAGS) -o $@ $< $(basename $@) $(IOCS_APPL_TOP) - -.PRECIOUS: %_registerRecordDeviceDriver.cpp - diff --git a/configure/RULES.ioc b/configure/RULES.ioc index fa0482ec0..901987c6c 100644 --- a/configure/RULES.ioc +++ b/configure/RULES.ioc @@ -1,37 +1,2 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* #RULES.ioc - -include $(CONFIG)/RULES_DIRS - -build$(DIVIDER)$(ARCH) build: buildInstall -install$(DIVIDER)$(ARCH) install: buildInstall -$(ARCH): buildInstall - -ifeq ($(filter $(ARCH),$(BUILD_ARCHS)),$(strip $(ARCH))) - buildInstall$(DIVIDER)$(ARCH) buildInstall: $(TARGETS) - - clean$(DIVIDER)$(ARCH) clean: - $(RM) cdCommands envPaths dllPath.bat relPaths.sh -else - buildInstall$(DIVIDER)$(ARCH) buildInstall: - clean$(DIVIDER)$(ARCH) clean: -endif - -cdCommands dllPath.bat relPaths.sh: \ - $(wildcard $(TOP)/configure/RELEASE*) \ - $(wildcard $(TOP)/configure/CONFIG_SITE*) | $(INSTALL_BIN) - $(CONVERTRELEASE) -a $(ARCH) -t $(IOCS_APPL_TOP) $@ - -envPaths: $(wildcard $(TOP)/configure/RELEASE*) \ - $(wildcard $(TOP)/configure/CONFIG_SITE*) | $(INSTALL_BIN) - $(CONVERTRELEASE) -t $(IOCS_APPL_TOP) $@ - -realclean: - $(RM) cdCommands envPaths dllPath.bat relPaths.sh +include $(CONFIG)/RULES.ioc diff --git a/configure/RULES_ARCHS b/configure/RULES_ARCHS deleted file mode 100644 index dc3fa04fe..000000000 --- a/configure/RULES_ARCHS +++ /dev/null @@ -1,95 +0,0 @@ -#************************************************************************* -# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - -all: install -host: install$(DIVIDER)$(EPICS_HOST_ARCH) - -ACTIONS = inc -ACTIONS += build -ACTIONS += install -ACTIONS += buildInstall -ACTIONS += runtests tapfiles clean-tests test-results junitfiles - -actionArchTargets = $(foreach action, $(ACTIONS), \ - $(addprefix $(action)$(DIVIDER), $(BUILD_ARCHS))) - -cleanArchTargets = $(addprefix clean$(DIVIDER), $(BUILD_ARCHS)) - -buildDirs = $(addprefix O., $(BUILD_ARCHS)) - -# Include /cfg/DIR_RULES* files from tops defined in RELEASE* files -# Do this here so they can add ACTIONS -# -RELEASE_CFG_DIR_RULES = $(foreach top, $(RELEASE_TOPS), \ - $(wildcard $($(top))/cfg/DIR_RULES*)) -ifneq ($(RELEASE_CFG_DIR_RULES),) - include $(RELEASE_CFG_DIR_RULES) -endif - -# Create EPICS_HOST_ARCH dependancies for GNU make -j option. -# Needed in dirs where EPICS_HOST_ARCH build creates a tool used in -# cross arch builds - -CROSS_ARCHS += $(CROSS1) $(CROSS2) - -define DEP_template - $(2) : $(EPICS_HOST_ARCH) - $(1)$(DIVIDER)$(2) : $(1)$(DIVIDER)$(EPICS_HOST_ARCH) O.$(2) -endef -$(foreach action, $(ACTIONS), \ - $(foreach arch, $(CROSS_ARCHS), \ - $(eval $(call DEP_template,$(action),$(arch))))) - -# Allows rebuild to work with parallel builds option, -j. -ifeq (rebuild,$(filter rebuild,$(MAKECMDGOALS))) - $(buildDirs) O.Common : clean - rebuild : install -endif - -archPart = $(word 2, $(subst $(DIVIDER), ,$@)) -actionPart = $(word 1, $(subst $(DIVIDER), ,$@)) -$(actionArchTargets) : $(buildDirs) O.Common - $(MAKE) -C O.$(archPart) -f ../Makefile TOP=$(TOP)/.. \ - T_A=$(archPart) $(actionPart) - -$(BUILD_ARCHS) : % : O.% O.Common - $(MAKE) -C O.$@ -f ../Makefile TOP=$(TOP)/.. T_A=$@ - -$(ACTIONS) : % : $(foreach arch, $(BUILD_ARCHS), %$(DIVIDER)$(arch)) - -$(buildDirs): - $(PERL) $(TOOLS)/makeMakefile.pl $@ $(TOP)/.. - -O.Common: - $(MKDIR) O.Common - -# Clean rules -# -clean: archsCommonClean - -archsCommonClean: - $(RMDIR) $(buildDirs) O.Common - -archclean: - $(RMDIR) $(buildDirs) - -$(cleanArchTargets): - $(RMDIR) O.$(archPart) - -realclean: - $(RMDIR) O.* - -.PHONY : $(actionArchTargets) -.PHONY : $(cleanArchTargets) -.PHONY : $(BUILD_ARCHS) rebuild archsCommonClean -.PHONY : $(ACTIONS) clean realclean archclean host all - -# User specific rules -# --include $(HOME)/configure/RULES_USER diff --git a/configure/RULES_BUILD b/configure/RULES_BUILD deleted file mode 100644 index 4440b2345..000000000 --- a/configure/RULES_BUILD +++ /dev/null @@ -1,531 +0,0 @@ -#************************************************************************* -# Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* -# -# Rules for making things specified in Makefile -# -# we are in O.$(T_A), but most sources are elsewhere -# - -ifndef BASE_RULES_BUILD -BASE_RULES_BUILD=1 - -vpath %.c $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.cc $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.cpp $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.rc $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.h $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.hpp $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.html $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.skel.static $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.y $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.l $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.pl $(USR_VPATH) $(ALL_SRC_DIRS) - -#--------------------------------------------------------------- - -include $(CONFIG)/CONFIG_ADDONS - -#--------------------------------------------------------------- -# Set PROD, TESTPROD, OBJS, and LIBRARY - -SCRIPTS_HOST += $(PERL_SCRIPTS) -# PERL_SCRIPTS are installed into existing $(INSTALL_BIN) for Host systems - -ifeq ($(findstring Host,$(VALID_BUILDS)),Host) -LIBRARY += $(LIBRARY_HOST) -LOADABLE_LIBRARY += $(LOADABLE_LIBRARY_HOST) -OBJS += $(OBJS_HOST) -PROD += $(PROD_HOST) -SCRIPTS += $(SCRIPTS_HOST) -TESTLIBRARY += $(TESTLIBRARY_HOST) -TESTSCRIPTS += $(TESTSCRIPTS_HOST) -TESTPROD += $(TESTPROD_HOST) -endif - -ifeq ($(findstring Ioc,$(VALID_BUILDS)),Ioc) -LIBRARY += $(LIBRARY_IOC) -LOADABLE_LIBRARY += $(LOADABLE_LIBRARY_IOC) -OBJS += $(OBJS_IOC) -PROD += $(PROD_IOC) -SCRIPTS += $(SCRIPTS_IOC) -TESTLIBRARY += $(TESTLIBRARY_IOC) -TESTSCRIPTS += $(TESTSCRIPTS_IOC) -TESTPROD += $(TESTPROD_IOC) -endif - -#--------------------------------------------------------------- - -ifdef TEMPLATES_DIR -INSTALL_TEMPLATES_SUBDIR = $(INSTALL_TEMPLATES)/$(TEMPLATES_DIR) -else -INSTALL_TEMPLATES_SUBDIR = $(INSTALL_TEMPLATES) -endif - -HTMLS_DIR ?= . - -#--------------------------------------------------------------- -# First target - -all: install -ifeq ($(EPICS_HOST_ARCH),$T_A) -host: install -else -# Do nothing -host: -endif - --include $(CONFIG)/RULES_FILE_TYPE - --include $(CONFIG)/RULES.Db - -#--------------------------------------------------------------- -# Include defines and rules for prod, library and test* targets - -#ifneq (,$(strip $(PROD) $(TESTPROD) $(LIBRARY) $(TESTLIBRARY) $(LOADABLE_LIBRARY) )) -include $(CONFIG)/RULES_TARGET -#endif - -#--------------------------------------------------------------- -# Read dependency files - -ifneq (,$(strip $(HDEPENDS_FILES))) -$(filter-out $(wildcard *$(DEP)), $(HDEPENDS_FILES)): | $(COMMON_INC) --include $(HDEPENDS_FILES) -endif - -#--------------------------------------------------------------- -# Products and Object libraries -# -PRODTARGETS += $(PRODNAME) $(MUNCHNAME) $(CTDT_SRCS) $(CTDT_OBJS) $(NMS) - -#--------------------------------------------------------------- -# Test specifications and test result files -# -ifneq (,$(strip $(TESTS))) -TARGETS += testspec -endif - -# Enable testing if this host can run tests on the current target -ifneq (,$(findstring $(T_A),$(EPICS_HOST_ARCH) $(CROSS_COMPILER_RUNTEST_ARCHS))) -RUNTESTS_ENABLED = YES -TAPFILES += $(TESTSCRIPTS:.t=.tap) -JUNITFILES += $(TAPFILES:.tap=.xml) -endif - -#--------------------------------------------------------------- -# Libraries -# - -LIBTARGETS += $(LIBNAME) $(INSTALL_LIBS) $(TESTLIBNAME) \ - $(SHRLIBNAME) $(INSTALL_SHRLIBS) $(TESTSHRLIBNAME) \ - $(DLLSTUB_LIBNAME) $(INSTALL_DLLSTUB_LIBS) $(TESTDLLSTUB_LIBNAME) \ - $(LOADABLE_SHRLIBNAME) $(INSTALL_LOADABLE_SHRLIBS) - - -# Main targets - -install: buildInstall - -buildInstall: build - -# Allows rebuild to work with parallel builds option, -j. -install: $(patsubst rebuild,clean,$(filter rebuild,$(MAKECMDGOALS))) - -rebuild: clean install - -build: inc - -build: $(OBJSNAME) $(LIBTARGETS) $(PRODTARGETS) $(TESTPRODNAME) \ - $(TARGETS) $(TESTSCRIPTS) $(INSTALL_LIB_INSTALLS) - -inc : $(COMMON_INC) $(INSTALL_INC) $(INSTALL_CONFIGS) - -buildInstall : \ - $(INSTALL_SCRIPTS) $(INSTALL_PROD) $(INSTALL_MUNCHS) \ - $(INSTALL_TCLLIBS) $(INSTALL_TCLINDEX) \ - $(INSTALL_OBJS) \ - $(INSTALL_DOCS) \ - $(INSTALL_HTMLS) \ - $(INSTALL_TEMPLATE) \ - $(INSTALL_BIN_INSTALLS) - -clean: build_clean - -build_clean: - $(ECHO) "Cleaning" - @$(RM) *.i *$(OBJ) *.a $(TESTPRODNAME) \ - $(LIBNAME) $(TESTLIBNAME) $(SHRLIBNAME) $(TESTSHRLIBNAME) \ - $(DLLSTUB_LIBNAME) $(TESTDLLSTUB_LIBNAME) \ - $(LOADABLE_SHRLIBNAME) \ - $(INC) $(TARGETS) $(TDS) $(CLEANS) \ - *.out MakefileInclude *.manifest *.exp \ - $(COMMON_INC) $(HDEPENDS_FILES) $(PRODTARGETS) \ - $(TESTSCRIPTS) $(TAPFILES) $(JUNITFILES) -ifdef RES - @$(RM) *$(RES) -endif - -$(DIRECTORY_TARGETS) : - $(MKDIR) $@ - -# Install LIB_INSTALLS libraries before linking executables -$(TESTPRODNAME) $(PRODNAME): | $(INSTALL_LIB_INSTALLS) - -# Install built libraries too, unless Makefile says to wait -ifneq ($(DELAY_INSTALL_LIBS),YES) -$(TESTPRODNAME) $(PRODNAME): | $(INSTALL_LIBS) $(INSTALL_DLLSTUB_LIBS) -endif - -# RELEASE file consistency checking -checkRelease: - $(CONVERTRELEASE) checkRelease -warnRelease: - -$(CONVERTRELEASE) checkRelease -noCheckRelease: -ifeq ($(EPICS_HOST_ARCH),$(T_A)) - $(info Warning: RELEASE file consistency checks have been disabled) -endif - -#--------------------------------------------------------------- -# The order of the following rules is -# VERY IMPORTANT !!!! - -$(TESTPRODNAME) $(PRODNAME): $(PRODUCT_OBJS) $(PROD_RESS) $(PROD_DEPLIBS) - -$(TESTPRODNAME) $(PRODNAME): %$(EXE): - @$(RM) $@ - $(DEBUGCMD) $(LINK.cpp) - $(MT_EXE_COMMAND) - -%_ctdt$(OBJ) : %_ctdt.c - @$(RM) $@ - $(COMPILE.ctdt) $< - -%$(DEP):%.c - @$(RM) $@ - $(HDEPENDS.c) $< - -%$(DEP):%.cc - @$(RM) $@ - $(HDEPENDS.cpp) $< - -%$(DEP):%.cpp - @$(RM) $@ - $(HDEPENDS.cpp) $< - -# Cancel GNUMake's built-in rules, which don't have our _INC -# dependencies so could get used in some circumstances (gdd) -%.o : %.c -%.o : %.cc -%.o : %.cpp - -# Include files are order-only prerequisites for compilation: -%$(OBJ): %.c | $(COMMON_INC) $(INSTALL_INC) - @$(RM) $@ - $(COMPILE.c) -c $< - -%$(OBJ): %.cc | $(COMMON_INC) $(INSTALL_INC) - @$(RM) $@ - $(COMPILE.cpp) -c $< - -%$(OBJ): %.cpp | $(COMMON_INC) $(INSTALL_INC) - @$(RM) $@ - $(COMPILE.cpp) -c $< - -# Windows resource compiler -%$(RES): %.rc - @$(RM) $@ - $(RCCMD) - -YACCOPT ?= $($*_YACCOPT) -# -# rename the y.tab.h file only if we -# are creating it -# -%.c: %.y - @$(RM) $*.tab.c - @$(RM) $*.tab.h - $(YACC) -b$* $(YACCOPT) $< - $(MV) $*.tab.c $*.c - $(if $(findstring -d, $(YACCOPT)),$(MV) $*.tab.h $*.h,) - -# must be a seperate rule since when not using '-d' the -# prefix for .h will be different then .c -%.h : %.c %.y - -%.c: %.l - @$(RM) $*.yy.c - $(LEX) $(LEXOPT) -t $< > $*.yy.c - @$(RM) $@ - $(MV) $*.yy.c $@ - -#--------------------------------------------------------------- -# Libraries, shared/DLL and stubs - -$(LIBNAME) $(TESTLIBNAME): $(LIBRARY_OBJS) - -$(filter-out $(DLLSTUB_LIBNAME) $(TESTDLLSTUB_LIBNAME), $(LIBNAME) $(TESTLIBNAME)): $(LIB_PREFIX)%$(LIB_SUFFIX): - @$(RM) $@ - $(ARCMD) -ifneq ($(strip $(RANLIB)),) - $(RANLIB) $@ -endif # RANLIB - -$(SHRLIBNAME) $(DLLSTUB_LIBNAME) $(TESTSHRLIBNAME) $(TESTDLLSTUB_LIBNAME): \ - $(LIBRARY_OBJS) $(LIBRARY_RESS) $(SHRLIB_DEPLIBS) - -# Stub library timestamps may be earlier than the DLL itself. -# This order-only prerequisite resolves any related problems. -# The $(LINK.shrlib) command must build both library files if -# the target requires a separate stub library file. -$(DLLSTUB_LIBNAME): | $(SHRLIBNAME); -$(SHRLIBNAME): $(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX): - @$(RM) $@ - $(LINK.shrlib) - $(MT_DLL_COMMAND) - -$(TESTDLLSTUB_LIBNAME): | $(TESTSHRLIBNAME); -$(TESTSHRLIBNAME): $(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX): - @$(RM) $@ - $(LINK.shrlib) - $(MT_DLL_COMMAND) - -$(LOADABLE_SHRLIBNAME): $(LIBRARY_OBJS) $(LIBRARY_RESS) $(SHRLIB_DEPLIBS) - -$(LOADABLE_SHRLIBNAME): $(LOADABLE_SHRLIB_PREFIX)%$(LOADABLE_SHRLIB_SUFFIX): - @$(RM) $@ - $(LINK.shrlib) - $(MT_DLL_COMMAND) - -#--------------------------------------------------------------- -# C++ munching for VxWorks - -%.nm: %$(EXE) - @$(RM) $@ - $(NM) $< > $@ - -%.nm: %$(OBJ) - @$(RM) $@ - $(NM) $< > $@ - -%_ctdt.c: %.nm $(TOOLS)/munch.pl - @$(RM) $@ - $(PERL) $(TOOLS)/munch.pl -o $@ $< - -$(MUNCHNAME): %$(MUNCH_SUFFIX): $(MUNCH_DEPENDS) %$(EXE) - @$(RM) $@ - $(MUNCH_CMD) - -#--------------------------------------------------------------- -# GeSys modules for RTEMS -$(MODNAME): %$(MODEXT): %$(EXE) - @echo "Building module $@" - @$(RM) $@ - $(LINK.mod) - -#--------------------------------------------------------------- -# Automated testing - -runtests: $(TESTSCRIPTS) -ifdef RUNTESTS_ENABLED - -$(PERL) -MTest::Harness -e 'runtests @ARGV if @ARGV;' $^ -endif - -testspec: $(TESTSCRIPTS) - @$(RM) $@ - @echo OS-class: $(OS_CLASS) > $@ - @echo Target-arch: $(T_A) >> $@ - $(if $^, @echo Tests: $^ >> $@) - $(if $(TESTFILES), @echo Files: $(TESTFILES) >> $@) - $(if $(TESTSPEC_$(OS_CLASS)), @echo "Harness: $(TESTSPEC_$(OS_CLASS))" >> $@) - -test-results: tapfiles -ifneq ($(TAPFILES),) -ifdef RUNTESTS_ENABLED - prove --failures --ext .tap --exec cat --color $(TAPFILES) -endif -endif - -clean-tests: -ifneq ($(TAPFILES),) - $(RM) $(TAPFILES) -endif -ifneq ($(JUNITFILES),) - $(RM) $(JUNITFILES) -endif - -tapfiles: $(TESTSCRIPTS) $(TAPFILES) -junitfiles: $(JUNITFILES) - -# A .tap file is the output from running the associated test script -%.tap: %.t -ifdef RUNTESTS_ENABLED - -$(PERL) $< -tap > $@ -endif - -%.xml: %.tap - $(TAPTOJUNIT) --puretap --output $@ --input $< $* - -# If there's a perl test script (.plt) available, use it -%.t: ../%.plt - @$(RM) $@ - $(CP) $< $@ - -# Test programs (.t files) must be written in Perl. -# Generate a perl program to exec the real test binary. -%.t: %$(EXE) $(TOOLS)/makeTestfile.pl - @$(RM) $@ - $(PERL) $(TOOLS)/makeTestfile.pl $@ $< - -#--------------------------------------------------------------- -# Generate header with version number from VCS - -ifneq ($(GENVERSION),) -$(COMMON_DIR)/$(GENVERSION): FORCE - $(GENVERSIONHEADER) -t $(TOP) -N $(GENVERSIONMACRO) -V "$(GENVERSIONDEFAULT)" $@ -endif - -#--------------------------------------------------------------- -# Install rules for BIN_INSTALLS and LIB_INSTALLS - -define BIN_INSTALLS_template -$$(INSTALL_BIN)/$$(notdir $(1)) : $(1) - $(ECHO) "Installing $$(/cfg/DIR_RULES* files from tops defined in RELEASE* files -# Do this here so they can add ACTIONS -# -RELEASE_CFG_DIR_RULES = $(foreach top, $(RELEASE_TOPS), \ - $(wildcard $($(top))/cfg/DIR_RULES*)) -ifneq ($(RELEASE_CFG_DIR_RULES),) - include $(RELEASE_CFG_DIR_RULES) -endif - -# Allows rebuild to work with parallel builds option, -j. -ifeq (rebuild,$(filter rebuild,$(MAKECMDGOALS))) -$(foreach dir, $(DIRS), $(dir)$(DIVIDER)install): \ - $(foreach dir, $(DIRS), $(dir)$(DIVIDER)clean) -rebuild: $(foreach dir, $(DIRS), $(dir)$(DIVIDER)install) -endif - -# Create directory dependancies lines for GNU make -j option -# Only works with GNU make 3.81 or later (uses eval function) -define DEP_template1 -$(1): $$($(1)_DEPEND_DIRS) -endef -$(foreach dir, $(DIRS), \ - $(eval $(call DEP_template1,$(dir)))) - -define DEP_template2 -$(1)$$(DIVIDER)$(2) : $$(foreach ddir, $$($(1)_DEPEND_DIRS), \ - $$(addsuffix $$(DIVIDER)$(2),$$(ddir))) -endef -$(foreach action, $(ACTIONS), \ - $(foreach dir, $(DIRS), \ - $(eval $(call DEP_template2,$(dir),$(action))))) - -define DEP_template3 -$(1)$$(DIVIDER)$(2) : $$(foreach ddir, $$($(1)_DEPEND_DIRS), \ - $$(addsuffix $$(DIVIDER)$(2),$$(ddir))) -endef -$(foreach arch, $(ARCHS), \ - $(foreach dir, $(DIRS), \ - $(eval $(call DEP_template3,$(dir),$(arch))))) - -define DEP_template4 -$(1)$$(DIVIDER)$(2)$$(DIVIDER)$(3) : $$(foreach ddir, $$($(1)_DEPEND_DIRS), \ - $$(addsuffix $$(DIVIDER)$(2)$$(DIVIDER)$(3),$$(ddir))) -endef -$(foreach arch, $(ARCHS), \ - $(foreach action, $(ACTIONS), \ - $(foreach dir, $(DIRS), \ - $(eval $(call DEP_template4,$(dir),$(action),$(arch)))))) - -dirPart = $(join $(dir $@), $(word 1, $(subst $(DIVIDER), ,$(notdir $@)))) -actionArchPart = $(join $(word 2, $(subst $(DIVIDER), ,$(notdir $@))), \ - $(addprefix $(DIVIDER),$(word 3, $(subst $(DIVIDER), ,$(notdir $@))))) -$(DIRS) $(dirActionTargets) $(dirArchTargets) $(dirActionArchTargets) : - $(MAKE) -C $(dirPart) $(actionArchPart) - -$(ARCHS) $(ACTIONS) $(actionArchTargets) :%: \ - $(foreach dir, $(DIRS), $(dir)$(DIVIDER)%) - -.PHONY : $(DIRS) all host rebuild -.PHONY : $(ARCHS) $(ACTIONS) -.PHONY : $(dirActionTargets) $(dirArchTargets) -.PHONY : $(dirActionArchTargets) -.PHONY : $(actionArchTargets) - - -# User specific rules -# --include $(HOME)/configure/RULES_USER +#RULES_DIRS +include $(CONFIG)/RULES_DIRS diff --git a/configure/RULES_EXPAND b/configure/RULES_EXPAND deleted file mode 100644 index 51657ebd8..000000000 --- a/configure/RULES_EXPAND +++ /dev/null @@ -1,64 +0,0 @@ -# /configure/RULES_EXPAND - -vpath %@ $(USR_VPATH) $(ALL_SRC_DIRS) - -#--------------------------------------------------------------- -# Variable expansion - -# Default settings -EXPAND_TOOL ?= $(PERL) $(TOOLS)/expandVars.pl - -EXPANDFLAGS += -t $(INSTALL_LOCATION) -a $(T_A) -EXPANDFLAGS += $(addprefix -D ,$(EXPAND_VARS)) - -# The names of files to be expanded must end with '@' -EXPANDED = $(EXPAND:%@=%) - -$(EXPANDED): %: %@ - $(ECHO) "Expanding $< to $@" - @$(RM) $@ - @$(EXPAND_TOOL) $(EXPANDFLAGS) $($@_EXPANDFLAGS) $< $@ - -clean: expand_clean - -expand_clean: - @$(RM) $(EXPANDED) - -.PRECIOUS: $(EXPANDED) -.PHONY: expand_clean - -#--------------------------------------------------------------- -# Assemblies (files assembled from snippets) - -ASSEMBLE_TOOL ?= $(PERL) $(TOOLS)/assembleSnippets.pl - -define COMMON_ASSEMBLY_template -$1_SNIPPETS += $$(foreach dir, .. $$(SRC_DIRS), \ - $$(wildcard $$(dir)/$$($1_PATTERN))) -$(COMMON_DIR)/$1: $$($1_SNIPPETS) - $(ECHO) "Assembling common file $$@ from snippets" - @$(RM) $1 - $(ASSEMBLE_TOOL) -o $1 $$^ - @$(MV) $1 $$@ -endef -$(foreach asy, $(COMMON_ASSEMBLIES), \ - $(eval $(call COMMON_ASSEMBLY_template,$(strip $(asy))))) - -define ASSEMBLY_template -$1_SNIPPETS += $$(foreach dir, .. $$(SRC_DIRS), \ - $$(wildcard $$(dir)/$$($1_PATTERN))) -$1: $$($1_SNIPPETS) - $(ECHO) "Assembling file $$@ from snippets" - @$(RM) $$@ - $(ASSEMBLE_TOOL) -o $$@ $$^ -endef -$(foreach asy, $(ASSEMBLIES), \ - $(eval $(call ASSEMBLY_template,$(strip $(asy))))) - -define ASSEMBLY_DEP_template -$1$(DEP): - @echo $1: > $$@ -endef -$(foreach asy, $(sort $(COMMON_ASSEMBLIES) $(ASSEMBLIES)), \ - $(eval $(call ASSEMBLY_DEP_template,$(strip $(asy))))) - diff --git a/configure/RULES_FILE_TYPE b/configure/RULES_FILE_TYPE deleted file mode 100644 index 28cc74bd4..000000000 --- a/configure/RULES_FILE_TYPE +++ /dev/null @@ -1,73 +0,0 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - -# Include /configure/RULES_BUILD from tops defined in RELEASE* files -# -RELEASE_RULES_BUILDS = $(foreach top, $(RELEASE_TOPS), \ - $(wildcard $($(top))/configure/RULES_BUILD)) -ifneq ($(RELEASE_RULES_BUILDS),) - include $(RELEASE_RULES_BUILDS) -endif - -# Include /cfg/RULES* files from tops defined in RELEASE* files -# -RELEASE_CFG_RULES = $(foreach top, $(RELEASE_TOPS), \ - $(wildcard $($(top))/cfg/RULES*)) -ifneq ($(RELEASE_CFG_RULES),) - include $(RELEASE_CFG_RULES) -endif - -# If this is not BASE then include /configure/RULES_BUILD -# -ifeq ($(wildcard $(TOP)/configure/CONFIG_BASE_VERSION),) -TOP_RULES_BUILDS = $(wildcard $(TOP)/configure/RULES_BUILD) -ifneq ($(TOP_RULES_BUILDS),) - include $(TOP_RULES_BUILDS) -endif -endif - -# Include our own $(INSTALL_CFG)/RULES* files -# -TOP_CFG_RULES = $(wildcard $(INSTALL_CFG)/RULES*) -ifneq ($(TOP_CFG_RULES),) - include $(TOP_CFG_RULES) -endif - -# Rules to install each FILE_TYPE -# -define FILE_TYPE_template -$(1) += $$(if $$(strip $$($(1)_$(OS_CLASS))), \ - $$(subst -nil-,,$$($(1)_$(OS_CLASS))), \ - $$($(1)_DEFAULT)) -INSTALLS_$(1) = $$($(1):%=$$(INSTALL_$(1))/%) - -$$(INSTALL_$(1))/%: ../% - $(ECHO) "Installing $(1) file $$@" - @$$(INSTALL) -d -m $$(INSTALL_PERMISSIONS) $$< $$(dir $$@) -$$(INSTALL_$(1))/%: % - $(ECHO) "Installing $(1) file $$@" - @$$(INSTALL) -d -m $$(INSTALL_PERMISSIONS) $$< $$(dir $$@) - -buildInstall: $$(INSTALLS_$(1)) -endef -$(foreach type, $(FILE_TYPE), \ - $(eval $(call FILE_TYPE_template,$(strip $(type))))) - -# Cleaning FILE_TYPE files -# -clean: file_type_clean - -file_type_clean: - @$(RM) $(foreach type, $(FILE_TYPE), $($(type))) - -.PHONY : file_type_clean - -# User specific rules -# --include $(HOME)/configure/RULES_USER diff --git a/configure/RULES_OCTAVE b/configure/RULES_OCTAVE deleted file mode 100644 index a06fb075a..000000000 --- a/configure/RULES_OCTAVE +++ /dev/null @@ -1,54 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# Octave definitions and rules - -ifeq ($(findstring Host,$(VALID_BUILDS)),Host) - -FILE_TYPE += OCTAVE -INSTALL_OCTAVE = $(INSTALL_LOCATION_LIB)/octave -DIRECTORY_TARGETS += $(INSTALL_OCTAVE) - -ifdef T_A - -MKOCTFILE_FLAGS += --mex --verbose -DOCTAVE -MKOCTFILE_FLAGS += $(RELEASE_INCLUDES) $(addprefix -L,$(SHRLIB_SEARCH_DIRS)) - -vpath %.mex $(USR_VPATH) $(ALL_SRC_DIRS) -vpath %.m $(USR_VPATH) $(ALL_SRC_DIRS) - -define OCTAVES_template -$(1) : $$($(1)_SRCS) -endef -$(foreach file, $(OCTAVES),$(eval $(call OCTAVES_template,$(strip $(file))))) - -clean: octave_clean - -#This clean works from O.* dirs. -octave_clean: - @$(RM) *.mex *.m - -.PHONY: octave_clean - -.PRECIOUS: *.m *.mex - -%.mex: - mkoctfile $(MKOCTFILE_FLAGS) $($*_LIBS:%=-l%) $($*_SRCS) - -endif -endif - - -# Makefile usage: -# OCTAVES += abc.mex def.mex -# abc_SRCS = a1.c a2.c -# abc_LIBS = ca Com -# def_SRCS = a3.c a4.c -# def_LIBS = ca Com diff --git a/configure/RULES_TARGET b/configure/RULES_TARGET deleted file mode 100644 index f8e44db76..000000000 --- a/configure/RULES_TARGET +++ /dev/null @@ -1,154 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# RULES_TARGET -# -# This file is to be maintained by the community. -# -#----------------------------------------------------------------------- - -define TARGET_template -$(1)_$(2) += $$(if $$(strip $$($(1)_$(2)_$$(OS_CLASS))), \ - $$(subst -nil-,,$$($(1)_$(2)_$$(OS_CLASS))), \ - $$($(1)_$(2)_DEFAULT)) -endef - -$(foreach type, SRCS RCS OBJS LDFLAGS OBJLIBS LDOBJS SYS_LIBS , \ -$(foreach target, $(PROD) $(TESTPROD) $(LIBRARY) $(TESTLIBRARY) $(LOADABLE_LIBRARY) , \ - $(eval $(call TARGET_template,$(strip $(target)),$(type))))) - -#----------------------------------------------------------------------- - -# This define block requires GNU make 3.81 -define PROD_template -ifeq ($$(strip $$($(1)_OBJS) $$($(1)_SRCS) $$(PRODUCT_OBJS)),) -$(1)_OBJS = $(1)$$(OBJ) -endif -endef - -$(foreach target, $(PROD) $(TESTPROD), \ - $(eval $(call PROD_template,$(strip $(target))))) - -#----------------------------------------------------------------------- - -define TARGET2_template -$(1)_LDLIBS += $$($(1)_LIBS) -$(1)_LDLIBS += $$(if $$(strip $$($(1)_LIBS_$(OS_CLASS))), \ - $$(subst -nil-,,$$($(1)_LIBS_$(OS_CLASS))), \ - $$($(1)_LIBS_DEFAULT)) - -$(1)_RESS = $$(if $(RES),$$(addsuffix $(RES),$$(basename $$($(1)_RCS))),) -$(1)_OBJSNAME = $$(addsuffix $(OBJ),$$(basename $$($(1)_OBJS) $$($(1)_SRCS) )) -$(1)_DEPLIBS = $$(foreach lib, $$($(1)_LDLIBS), \ - $$(firstword $$(wildcard \ - $$(addsuffix /$(DLLSTUB_PREFIX)$$(lib)$(DLLSTUB_SUFFIX), \ - $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \ - $$(addsuffix /$(SHRLIB_PREFIX)$$(lib)*$(SHRLIB_SUFFIX_BASE)*, \ - $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \ - $$(addsuffix /$(LIB_PREFIX)$$(lib)$(LIB_SUFFIX), \ - $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \ - ) $$(addsuffix /$(BUILDLIB_PREFIX)$$(lib)$(BUILDLIB_SUFFIX), \ - $$(firstword $$($$(lib)_DIR) $(SHRLIB_SEARCH_DIRS))))) -endef - -$(foreach target, $(PROD) $(TESTPROD) $(LIBRARY) $(TESTLIBRARY) $(LOADABLE_LIBRARY) , \ - $(eval $(call TARGET2_template,$(strip $(target))))) - -#----------------------------------------------------------------------- - -define PROD2_template - -$(1)$$(EXE): $$($(1)_OBJSNAME) $$($(1)_RESS) $$($(1)_DEPLIBS) -endef - -$(foreach target, $(PROD) $(TESTPROD), \ - $(eval $(call PROD2_template,$(strip $(target))))) - -#----------------------------------------------------------------------- - -define LIBRARY_template - -$(1)_DLL_DEPLIBS=$$(foreach lib, $$($(1)_DLL_LIBS), \ - $$(firstword $$(wildcard \ - $$(addsuffix /$(DLLSTUB_PREFIX)$$(lib)$(DLLSTUB_SUFFIX), \ - $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \ - $$(addsuffix /$(SHRLIB_PREFIX)$$(lib)*$(SHRLIB_SUFFIX_BASE)*, \ - $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \ - $$(addsuffix /$(LIB_PREFIX)$$(lib)$(LIB_SUFFIX), \ - $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)) \ - ) $$(addsuffix /$(BUILDLIB_PREFIX)$$(lib)$(BUILDLIB_SUFFIX), \ - $$(firstword $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS))))) - -$$(LIB_PREFIX)$(1)$$(LIB_SUFFIX):$$($(1)_OBJSNAME) $$($(1)_RESS) -$$(LIB_PREFIX)$(1)$$(LIB_SUFFIX):$$($(1)_DEPLIBS) - -ifeq ($$(SHARED_LIBRARIES),YES) - -ifdef SHRLIB_SUFFIX -$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX):$$($(1)_OBJSNAME) $$($(1)_RESS) -$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX):$$($(1)_DEPLIBS) -$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX):$$($(1)_DLL_DEPLIBS) -endif - -endif - -endef - -$(foreach target, $(LIBRARY) $(TESTLIBRARY), \ - $(eval $(call LIBRARY_template,$(strip $(target))))) - -#----------------------------------------------------------------------- - -define LIBRARY2_template -BUILD_LIBRARY += $$(if $$(strip $$($(1)_OBJSNAME) $$(LIBRARY_OBJS)),$(1),) - -# Needed for -j parallel builds option -ifeq ($$(SHARED_LIBRARIES),YES) -ifdef SHRLIB_SUFFIX -$$(INSTALL_LIB)/$$(DLLSTUB_PREFIX)$(1)$$(DLLSTUB_SUFFIX): \ - $$(INSTALL_SHRLIB)/$$(SHRLIB_PREFIX)$(1)$$(SHRLIB_SUFFIX) -endif -endif -endef - -$(foreach target, $(LIBRARY), \ - $(eval $(call LIBRARY2_template,$(strip $(target))))) - -#----------------------------------------------------------------------- - -define LIBRARY3_template -$(1)_DIR = . -TESTBUILD_LIBRARY += $$(if $$(strip $$($(1)_OBJSNAME) $$(LIBRARY_OBJS)),$(1),) -endef - -$(foreach target, $(TESTLIBRARY), \ - $(eval $(call LIBRARY3_template,$(strip $(target))))) - -#----------------------------------------------------------------------- - -define LOADABLE_LIBRARY_template -LOADABLE_BUILD_LIBRARY += $$(if $$(strip $$($(1)_OBJSNAME) $$(LIBRARY_OBJS)),$(1),) - -$(1)_DLL_DEPLIBS=$$(foreach lib, $$($(1)_DLL_LIBS),\ - $$(firstword $$(wildcard $$(addsuffix /$$(LIB_PREFIX)$$(lib).\*,\ - $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS)))\ - $$(addsuffix /$$(LIB_PREFIX)$$(lib)$$(LIB_SUFFIX),\ - $$(firstword $$($$(lib)_DIR) $$(SHRLIB_SEARCH_DIRS))))) - -$$(LOADABLE_SHRLIB_PREFIX)$(1)$$(LOADABLE_SHRLIB_SUFFIX):$$($(1)_OBJSNAME) $$($(1)_RESS) -$$(LOADABLE_SHRLIB_PREFIX)$(1)$$(LOADABLE_SHRLIB_SUFFIX):$$($(1)_DEPLIBS) -$$(LOADABLE_SHRLIB_PREFIX)$(1)$$(LOADABLE_SHRLIB_SUFFIX):$$($(1)_DLL_DEPLIBS) -endef - -$(foreach target, $(LOADABLE_LIBRARY), \ - $(eval $(call LOADABLE_LIBRARY_template,$(strip $(target))))) - -#----------------------------------------------------------------------- - diff --git a/configure/RULES_TOP b/configure/RULES_TOP index 3d60b5af8..2b8cbc6da 100644 --- a/configure/RULES_TOP +++ b/configure/RULES_TOP @@ -1,87 +1,2 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - -include $(CONFIG)/RULES_DIRS - -distclean: realclean cvsclean realuninstall - -CVSCLEAN = $(call FIND_TOOL,cvsclean.pl) -cvsclean: - $(PERL) $(CVSCLEAN) - -realuninstall: uninstallDirs - $(RMDIR) $(INSTALL_LOCATION_BIN) - $(RMDIR) $(INSTALL_LOCATION_LIB) - -UNINSTALL_DIRS += $(INSTALL_DBD) $(INSTALL_INCLUDE) $(INSTALL_DOC) \ - $(INSTALL_HTML) $(INSTALL_TEMPLATES) $(INSTALL_DB) $(DIRECTORY_TARGETS) -uninstallDirs: - $(RMDIR) $(UNINSTALL_DIRS) - -uninstall: archuninstall uninstallDirs - -archuninstall: $(addprefix uninstall$(DIVIDER),$(BUILD_ARCHS)) | cleandirs - -archPart = $(word 2, $(subst $(DIVIDER), ,$@)) -uninstall$(DIVIDER)%: - $(RMDIR) $(INSTALL_LOCATION_BIN)/$(archPart) - $(RMDIR) $(INSTALL_LOCATION_LIB)/$(archPart) - -cleandirs: - @$(NOP) -ifeq ($(wildcard $(INSTALL_LOCATION_BIN)/*),) - $(RMDIR) $(INSTALL_LOCATION_BIN) -endif -ifeq ($(wildcard $(INSTALL_LOCATION_LIB)/*),) - $(RMDIR) $(INSTALL_LOCATION_LIB) -endif - - -help: - @echo "Usage: gnumake [options] [target] ..." - @echo "Targets supported by all Makefiles:" - @echo " all - Same as install (default rule)" - @echo " inc - Installs header files" - @echo " build - Builds and installs all targets" - @echo " install - Builds and installs all targets" - @echo " buildInstall - Same as install (deprecated)" - @echo " clean - Removes the O. dirs created by running make" - @echo " In O. dir, clean removes build created files" - @echo " realclean - Removes ALL O. dirs" - @echo " Cannot be used within an O. dir" - @echo " rebuild - Same as clean install" - @echo " archclean - Removes O. dirs but not O.Common dir" - @echo " runtests - Run self-tests, summarize results" - @echo "\"Partial\" build targets supported by Makefiles:" - @echo " host - Builds and installs $(EPICS_HOST_ARCH) only." - @echo " inc$(DIVIDER) - Installs only header files." - @echo " build$(DIVIDER) - Builds and installs only." - @echo " install$(DIVIDER) - Builds and installs only." - @echo " clean$(DIVIDER) - Cleans binaries in O. dirs only." - @echo " uninstall$(DIVIDER) - Remove bin & lib directories for only." - @echo "Targets supported by top level Makefile:" - @echo " archuninstall - Remove bin & lib directories created by this hostarch." - @echo " uninstall - Remove install directories created by this hostarch." - @echo " realuninstall - Removes ALL install dirs" - @echo " distclean - Same as realclean cvsclean realuninstall." - @echo " cvsclean - Removes cvs .#* files in all dirs of directory tree" - @echo " help - Prints this list of valid make targets " - @echo "Indiv. object targets are supported by O. level Makefile .e.g" - @echo " xxxRecord.o" - -.PHONY: cleandirs distclean cvsclean realuninstall archuninstall uninstallDirs -.PHONY: uninstall help - -# Include /cfg/TOP_RULES* files from tops defined in RELEASE* files -# -RELEASE_CFG_TOP_RULES = $(foreach top, $(RELEASE_TOPS), \ - $(wildcard $($(top))/cfg/TOP_RULES*)) -ifneq ($(RELEASE_CFG_TOP_RULES),) - include $(RELEASE_CFG_TOP_RULES) -endif +#RULES_TOP +include $(CONFIG)/RULES_TOP diff --git a/configure/Sample.Makefile b/configure/Sample.Makefile deleted file mode 100644 index a84ccbb45..000000000 --- a/configure/Sample.Makefile +++ /dev/null @@ -1,216 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# Makefile for base/src/sample -# -# -# Sample Makefile showing some possible entries -# that are allowed using RULES_BUILD. -# - -TOP = ../../.. -include $(TOP)/configure/CONFIG - -# Add-on CPPFLAGS that are needed by this Makefile. -# (If possible, all system specific flags should be -# defined in configure/os/CONFIG.. -# -# These CPPFLAGS rules also apply to these Makefile-variables: -# CPPFLAGS C preprocessor flags -# CFLAGS C flags -# CXXFLAGS C++ flags -# LDFLAGS link flags -# -# This is used on all systems: -USR_CPPFLAGS = -DVAR=value -Ddefine_for_all_systems -# ..only for WIN32: -USR_CPPFLAGS_WIN32 = -DVERSION='WIN32 port' -# -# -nil- is special: -# if USR_CPPFLAGS_WIN32 was undefined or empty, .._DEFAULT would have -# been used. -# To indicate -# "yes, there is a special USR_CPPFLAGS for WIN32, but it's empty" -# you have to set it to -nil-: -USR_CPPFLAGS_WIN32 = -nil- -# .. for all other arch classes: -USR_CPPFLAGS_DEFAULT = -DVERSION='generic Unix' - -# CPPFLAGS that are only used to compile a_file.c or a_file.cpp: -# -a_file_CPPFLAGS = -DIN_A_FILE -a_file_CPPFLAGS_WIN32 = -DVERSION='WIN32 port' - -# --------------------------------------------------------- -# general rule for all .c .cpp .h .hh files and scripts: -# -# In here you supply just the filename without '../' etc. -# While building in an O.xxx subdir, the -# sources are extracted from the -# ../os/$(OS_CLASS) directory if it exists, or -# ../os/default directory if it exists, or -# .. directory -# --------------------------------------------------------- - -# includes to install from this Makefile -# -# again: if INC_$(OS_CLASS) is defined, it is added to INC, -# otherwise INC_DEFAULT (if defined) is added: -# -INC_DEFAULT = for_all_but_WIN32_or_vxWorks.h -INC_WIN32 = only_for_WIN32.h -INC_vxWorks = -nil- # vxWorks uses no special include -INC = file.h - -# -------------------------------------------------------------------- -# defining a library -# -------------------------------------------------------------------- -# -# Contents of a library are specified via SRCS, LIB_SRCS, or .._SRCS. -# From this the platform specific object names (.o, .obj, ...) -# are derived automatically. -# -# Platform specific objects: -# use .._OBJS_$(OS_CLASS) or .._OBJS_DEFAULT -# -# Platform specific files can also be put in -# separate os/OS_CLASS directories! -# -# For almost every file the seach order is: -# ./os/OS_CLASS -# ./os/generic -# . -# So usually only LIB_SRCS should be sufficient! - -# SRCS files will be used for both LIBRARY and PROD -SRCS = file_for_lib.c another_file.cpp -SRCS_DEFAULT = posix.c -SRCS_WIN32 = win32_special.c -SRCS_Linux = -nil- -# -libname_SRCS = file_for_lib.c another_file.cpp -libname_SRCS_DEFAULT = posix.c -libname_SRCS_WIN32 = win32_special.c -libname_SRCS_Linux = -nil- -# -# SRCS that are used for all libraries -LIB_SRCS = file_for_lib.c another_file.cpp -LIB_SRCS_DEFAULT = posix.c -LIB_SRCS_WIN32 = win32_special.c -LIB_SRCS_Linux = -nil- - -# Library to build: -# lib$(LIBRARY).a or ..dll/..exp/..lib -# -LIBRARY=libname -# -# Host or Ioc platform specific library to build: -# -LIBRARY_IOC=libnameIoc -LIBRARY_HOST=libnameHost - -# Library version -SHRLIB_VERSION = -# On WIN32 results in /version:$(SHRLIB_VERSION) link option -# On Unix type hosts .$(SHRLIB_VERSION) is appended to library name - -# -------------------------------------------------------------------- -# defining products (executable programs) -# -------------------------------------------------------------------- -# -# if SRCS is undefined, it defaults to $(PROD).c -SRCS=a.c b.c c.c - -# SRCS that are used for all PRODs -# -PROD_SRCS = ppp.c qqq.c - -# SRCS that are only used for PROD a_file -# -a_file_SRCS = aa.c bb.c - -# -# EPICS libs needed to link PROD, TESTPROD and sharable library -# -# note that DLL_LIBS (the libraries needed to link a shareable -# library) is created by default from the PROD/SYS libraries specified -# below minus the name of the sharable library (LIBRARY) -# -# -# ---------- libraries for a specific product pppp -# for all systems -pppp_LIBS = Com Ca -# for most systems: -pppp_LIBS_DEFAULT = mathlib -pppp_LIBS_WIN32 = -nil- - -# ---------- libraries for all products -# for all systems -PROD_LIBS = Com Ca -# for most systems: -PROD_LIBS_DEFAULT = mathlib -PROD_LIBS_WIN32 = -nil- - -# ---------- Libraries for all products and all libraries: -# for all systems -USR_LIBS = Xm Xt X11 -Xm_DIR = $(MOTIF_LIB) -Xt_DIR = $(X11_LIB) -X11_DIR = $(X11_LIB) - -# for most systems -USR_LIBS_DEFAULT = foolib -USR_LIBS_WIN32 = -nil- -foolib_DIR = $(FOO_LIB) - -# system libs needed to link PROD, TESTPROD and sharable library -# -# ---------- system libraries for all products -# for all systems: -PROD_SYS_LIBS = m -# for most systems: -PROD_SYS_LIBS_DEFAULT = foolib -PROD_SYS_LIBS_WIN32 = -nil- - -# Product, -# may be caRepeater.o -> caRepeater -# or caRepeater.obj -> caRepeater.exe -PROD = prod -PROD_DEFAULT = product_for_rest -PROD_WIN32 = product_only_for_WIN32 -PROD_Linux = product_only_for_Linux -PROD_solaris = product_only_for_solaris - -PROD_HOST = product_only_for_host_type_systems -PROD_IOC = product_only_for_ioc_type_systems - -# Product version -PROD_VERSION = -# On WIN32 results in /version:$(SHRLIB_VERSION) link option -# On Unix type hosts PROD_VERSION) is ignored - -# Scripts to install -# -# If there is both ../$(SCRIPTS) and ../$(OS_CLASS)/$(SCRIPTS), -# the latter, system specific version will be installed! -# -SCRIPTS_DEFAULT = script_for_rest -SCRIPTS_WIN32 = script_only_for_WIN32 -SCRIPTS_Linux = script_only_for_Linux -SCRIPTS = script - -# if you want to build products locally without installing: -# TESTPROD = test - -# put all definitions before the following include line -# put all rules after the following include line - -include $(TOP)/configure/RULES - -# EOF Makefile diff --git a/configure/os/CONFIG.Common.RTEMS b/configure/os/CONFIG.Common.RTEMS deleted file mode 100644 index 9650ae255..000000000 --- a/configure/os/CONFIG.Common.RTEMS +++ /dev/null @@ -1,157 +0,0 @@ -# -# This file contains definitions for RTEMS builds -# -# Author: W. Eric Norum -# University of Saskatchewan -# eric.norum@usask.ca -# -# Contains definitions common to all RTEMS targets -# -# This file is maintained by the build community. -# Sites may override definitions in os/CONFIG_SITE.Common.RTEMS -#------------------------------------------------------- -# - -#------------------------------------------------------- -# RTEMS tools are similar to UNIX tools --include $(CONFIG)/os/CONFIG.Common.UnixCommon - -GNU_TARGET_INCLUDE_DIR = -unexport GCC_EXEC_PREFIX - -#-------------------------------------------------- -# Get RTEMS_BASE definition --include $(CONFIG)/os/CONFIG_SITE.Common.RTEMS - -ifneq ($(CONFIG),$(TOP)/configure) --include $(TOP)/configure/CONFIG_SITE.Common.RTEMS -endif - -#------------------------------------------------------- -# Pick up the RTEMS tool/path definitions from the RTEMS BSP directory. -include $(RTEMS_BASE)/$(RTEMS_TARGET_CPU)-rtems$(RTEMS_VERSION)/$(subst RTEMS-,,$(T_A))/Makefile.inc -include $(RTEMS_CUSTOM) -include $(CONFIG.CC) - -#------------------------------------------------------- -# RTEMS cross-development tools -CC = $(RTEMS_TOOLS)/bin/$(CC_FOR_TARGET) $(GCCSPECS) -fasm -CCC = $(RTEMS_TOOLS)/bin/$(CXX) -CPP = $(RTEMS_TOOLS)/bin/$(CC_FOR_TARGET) -x c -E -AR = $(RTEMS_TOOLS)/bin/$(AR_FOR_TARGET) -LD = $(RTEMS_TOOLS)/bin/$(LD_FOR_TARGET) -r - -RANLIB := $(RTEMS_TOOLS)/bin/$(RANLIB) - -#------------------------------------------------------- -# Build types -VALID_BUILDS = Ioc - -#-------------------------------------------------- -# The RTEMS Makefiles redefine several macros, so we have to -# reset them to the proper EPICS values, from CONFIG_COMMON -CFLAGS = $($(BUILD_CLASS)_CFLAGS) $(POSIX_CFLAGS) $(OPT_CFLAGS)\ - $(DEBUG_CFLAGS) $(PIPE_CFLAGS) $(WARN_CFLAGS) $(TARGET_CFLAGS)\ - $(USR_CFLAGS) $(CMD_CFLAGS) $(ARCH_DEP_CFLAGS) $(CODE_CFLAGS)\ - $(STATIC_CFLAGS) $(OP_SYS_CFLAGS) $(LIBRARY_SRC_CFLAGS) - -CXXFLAGS = $($(BUILD_CLASS)_CXXFLAGS) $(POSIX_CXXFLAGS) $(OPT_CXXFLAGS)\ - $(DEBUG_CXXFLAGS) $(PIPE_CFLAGS) $(WARN_CXXFLAGS) $(TARGET_CXXFLAGS)\ - $(USR_CXXFLAGS) $(CMD_CXXFLAGS) $(ARCH_DEP_CXXFLAGS) $(CODE_CXXFLAGS)\ - $(STATIC_CXXCFLAGS) $(OP_SYS_CXXFLAGS) $(LIBRARY_SRC_CFLAGS) - -LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(CMD_LDFLAGS)\ - $(POSIX_LDFLAGS) $(ARCH_DEP_LDFLAGS) $(DEBUG_LDFLAGS) $(OP_SYS_LDFLAGS)\ - $($(BUILD_CLASS)_LDFLAGS) $(RUNTIME_LDFLAGS) $(CODE_LDFLAGS) - -LDLIBS = $(POSIX_LDLIBS) $(ARCH_DEP_LDLIBS) $(DEBUG_LDLIBS) $(OP_SYS_LDLIBS)\ - $(GNU_LDLIBS_$(GNU)) - -CPPFLAGS += $($(BUILD_CLASS)_CPPFLAGS) $(POSIX_CPPFLAGS) $(OPT_CPPFLAGS)\ - $(DEBUG_CPPFLAGS) $(WARN_CPPFLAGS) $(BASE_CPPFLAGS) $(TARGET_CPPFLAGS)\ - $(USR_CPPFLAGS) $(CMD_CPPFLAGS) $(ARCH_DEP_CPPFLAGS) $(OP_SYS_CPPFLAGS)\ - $(OP_SYS_INCLUDE_CPPFLAGS) $(CODE_CPPFLAGS) - -ECHO = @$(if $(findstring s,$(patsubst T_A=%,,$(MAKEFLAGS))),$(NOP),echo) - -#-------------------------------------------------- -# Although RTEMS uses gcc, it wants to use gcc its own way -CROSS_CPPFLAGS = -CROSS_LDFLAGS = -SHRLIB_CFLAGS = -OPT_CFLAGS_YES = $(CFLAGS_OPTIMIZE_V) -OPT_CXXFLAGS_YES = $(CFLAGS_OPTIMIZE_V) -OPT_CFLAGS_NO = $(CFLAGS_DEBUG_V) -OPT_CXXFLAGS_NO = $(CFLAGS_DEBUG_V) - -MODEXT=.obj - -#-------------------------------------------------- -# operating system class (include/os/) -OS_CLASS = RTEMS - -#-------------------------------------------------- -# Operating system flags -OP_SYS_LDLIBS += -lrtemsCom -lc -lrtemscpu -lCom -lnfs -lm -OP_SYS_LDFLAGS += $(CPU_CFLAGS) -u Init \ - $(PROJECT_RELEASE)/lib/no-dpmem.rel \ - $(PROJECT_RELEASE)/lib/no-mp.rel \ - $(PROJECT_RELEASE)/lib/no-part.rel \ - $(PROJECT_RELEASE)/lib/no-signal.rel \ - $(PROJECT_RELEASE)/lib/no-rtmon.rel - -MOD_SYS_LDFLAGS += $(CPU_CFLAGS) -Wl,-r -nostdlib - -# Do not link against libraries which are part of the Generic Image -GESYS_LIBS += -lgcc -GESYS_LIBS += -lc -lm -lrtemscpu -lrtemsbsp -lrtems++ -lbspExt -GESYS_LIBS += -lcexp -ltecla_r -lspencer_regexp -lpmelf -lpmbfd -GESYS_LIBS += -lnfs -ltelnetd -lrtems-gdb-stub - -# While not part of the Generic Image it provides symbols which -# would conflict. -GESYS_LIBS += -lrtemsCom - -#-------------------------------------------------- -# Options for building GeSys loadable objects - -MODNAME_YES = $(PRODNAME:%$(EXE)=%$(MODEXT)) -MODNAME += $(MODNAME_$(USE_GESYS)) -PRODTARGETS += $(MODNAME) -BIN_INSTALLS += $(MODNAME) - -# changes to LDFLAGS in CONFIG_COMMON and LINK.cpp in CONFIG.Common.UnixCommon -# should be reflected here with the following exceptions -# -# replace OP_SYS_LDFLAGS with MOD_SYS_LDFLAGS -# replace PROD_LDLIBS with MOD_LDLIBS -# remove STATIC_LDFLAGS - -MOD_LDLIBS = $(filter-out $(GESYS_LIBS),$(PROD_LDLIBS)) - -MOD_LDFLAGS = $(OPT_LDFLAGS) $(TARGET_LDFLAGS) $(USR_LDFLAGS) $(POSIX_LDFLAGS) \ - $(ARCH_DEP_LDFLAGS) $(DEBUG_LDFLAGS) $(MOD_SYS_LDFLAGS) $($(BUILD_CLASS)_LDFLAGS)\ - $(RUNTIME_LDFLAGS) $(CODE_LDFLAGS) - -LINK.mod = $(CCC) -o $@ $(PRODDIR_LDFLAGS) $(MOD_LDFLAGS) -LINK.mod += $(PROD_LDFLAGS) $(PROD_LD_OBJS) $(PROD_LD_RESS) $(MOD_LDLIBS) - -#-------------------------------------------------- -# RTEMS has neither shared libraries nor dynamic loading -STATIC_BUILD=YES -SHARED_LIBRARIES=NO -CODE_CFLAGS = -CODE_CXXFLAGS = - -#-------------------------------------------------- -# Override the usual RTEMS verbosity from ar -ARFLAGS = rc - -#-------------------------------------------------- -# Command-line input support -LDLIBS_LIBTECLA = -ltecla_r -lncurses -LDLIBS_READLINE = -lreadline -lncurses - -#-------------------------------------------------- -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-at91rm9200ek b/configure/os/CONFIG.Common.RTEMS-at91rm9200ek deleted file mode 100644 index 6f5f97732..000000000 --- a/configure/os/CONFIG.Common.RTEMS-at91rm9200ek +++ /dev/null @@ -1,13 +0,0 @@ -# -# CONFIG.Common.RTEMS-at91rm9200ek -# Author: Ralf Hartmann -# BESSY -# Ralf.Hartmann@bessy.de -# -# Atmel AT91RM9200-EK evaluation kit -# using the AT91RM9200 ARM9-based 32-bit RISC microcontroller -# -# All RTEMS targets use the same Makefile fragment -# -RTEMS_TARGET_CPU=arm -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-beatnik b/configure/os/CONFIG.Common.RTEMS-beatnik deleted file mode 100644 index 00080e7fd..000000000 --- a/configure/os/CONFIG.Common.RTEMS-beatnik +++ /dev/null @@ -1,36 +0,0 @@ -# -# CONFIG.Common.RTEMS-beatnik -# Author: Dayle Kotturi -# -# All RTEMS targets use the same Makefile fragment -# -EXE = .elf -RTEMS_TARGET_CPU = powerpc -GNU_TARGET = powerpc-rtems -ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL -ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD -ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 -ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 - -OP_SYS_LDLIBS += -lbspExt - -MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) -define MUNCH_CMD - $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ -endef - -include $(CONFIG)/os/CONFIG.Common.RTEMS - -RTEMSSYMS=$(PRODNAME:%$(EXE)=%.sym) -RTEMSIMGS=$(PRODNAME:%$(EXE)=%.bin) -INSTALL_RTEMSSYMS=$(RTEMSSYMS:%=$(INSTALL_BIN)/%) -INSTALL_RTEMSIMGS=$(RTEMSIMGS:%=$(INSTALL_BIN)/%) - -%.sym: %$(EXE) - $(XSYMS) $^ $@ - -%.bin: %$(EXE) - $(OBJCOPY) -Obinary $^ $@ - -#PRODTARGETS+=$(INSTALL_RTEMSSYMS) $(INSTALL_RTEMSIMGS) diff --git a/configure/os/CONFIG.Common.RTEMS-gen68360 b/configure/os/CONFIG.Common.RTEMS-gen68360 deleted file mode 100644 index a6663afc2..000000000 --- a/configure/os/CONFIG.Common.RTEMS-gen68360 +++ /dev/null @@ -1,9 +0,0 @@ -# -# Author: W. Eric Norum -# Canadian Light Source -# eric@cls.usask.ca -# -# All RTEMS targets use the same Makefile fragment -# -RTEMS_TARGET_CPU=m68k -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-mcp750 b/configure/os/CONFIG.Common.RTEMS-mcp750 deleted file mode 100644 index d834ad9ec..000000000 --- a/configure/os/CONFIG.Common.RTEMS-mcp750 +++ /dev/null @@ -1,9 +0,0 @@ -# -# Author: W. Eric Norum -# Canadian Light Source -# eric@cls.usask.ca -# -# All RTEMS targets use the same Makefile fragment -# -RTEMS_TARGET_CPU=ppc -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-mvme167 b/configure/os/CONFIG.Common.RTEMS-mvme167 deleted file mode 100644 index a6663afc2..000000000 --- a/configure/os/CONFIG.Common.RTEMS-mvme167 +++ /dev/null @@ -1,9 +0,0 @@ -# -# Author: W. Eric Norum -# Canadian Light Source -# eric@cls.usask.ca -# -# All RTEMS targets use the same Makefile fragment -# -RTEMS_TARGET_CPU=m68k -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-mvme2100 b/configure/os/CONFIG.Common.RTEMS-mvme2100 deleted file mode 100644 index 687af2374..000000000 --- a/configure/os/CONFIG.Common.RTEMS-mvme2100 +++ /dev/null @@ -1,29 +0,0 @@ -# -# CONFIG.Common.RTEMS-mvme2100 -# Author: W. Eric Norum -# -# All RTEMS targets use the same Makefile fragment -# -EXE = .elf -RTEMS_TARGET_CPU = powerpc -GNU_TARGET = powerpc-rtems -ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL -ARCH_DEP_CFLAGS += -DHAVE_PPCBUG - -OP_SYS_LDLIBS += -lbspExt - -MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) -define MUNCH_CMD - $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< rtems - gzip -f9 rtems - $(RTEMS_TOOLS)/bin/$(LD_FOR_TARGET) -o $@ \ - $(PROJECT_RELEASE)/lib/bootloader.o \ - --just-symbols=$< \ - -b binary rtems.gz \ - -T $(PROJECT_RELEASE)/lib/ppcboot.lds \ - -Map $<.map - rm -f rtems.gz -endef - -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-mvme2700 b/configure/os/CONFIG.Common.RTEMS-mvme2700 deleted file mode 100644 index f45e321c4..000000000 --- a/configure/os/CONFIG.Common.RTEMS-mvme2700 +++ /dev/null @@ -1,25 +0,0 @@ -# -# Author: Matt Rippa -# -RTEMS_TARGET_CPU = powerpc -ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL -ARCH_DEP_CFLAGS += -DHAVE_PPCBUG -ARCH_DEP_CFLAGS += -DNVRAM_INDIRECT - -MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) -define MUNCH_CMD - $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< rtems - gzip -f9 rtems - $(RTEMS_TOOLS)/bin/$(LD_FOR_TARGET) -o $@ \ - $(PROJECT_RELEASE)/lib/bootloader.o \ - --just-symbols=$< \ - -b binary rtems.gz \ - -T $(PROJECT_RELEASE)/lib/ppcboot.lds \ - -Map $<.map - rm -f rtems.gz -endef - -OP_SYS_LDLIBS += -lbspExt - -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-mvme3100 b/configure/os/CONFIG.Common.RTEMS-mvme3100 deleted file mode 100644 index cd9416ce7..000000000 --- a/configure/os/CONFIG.Common.RTEMS-mvme3100 +++ /dev/null @@ -1,36 +0,0 @@ -# -# CONFIG.Common.RTEMS-mvme3100 -# Author: W. Eric Norum -# -# All RTEMS targets use the same Makefile fragment -# -EXE = .elf -RTEMS_TARGET_CPU = powerpc -GNU_TARGET = powerpc-rtems -ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL -ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD -ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 -ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 - -OP_SYS_LDLIBS += -lbspExt - -MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) -define MUNCH_CMD - $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ -endef - -include $(CONFIG)/os/CONFIG.Common.RTEMS - -RTEMSSYMS=$(PRODNAME:%$(EXE)=%.sym) -RTEMSIMGS=$(PRODNAME:%$(EXE)=%.bin) -INSTALL_RTEMSSYMS=$(RTEMSSYMS:%=$(INSTALL_BIN)/%) -INSTALL_RTEMSIMGS=$(RTEMSIMGS:%=$(INSTALL_BIN)/%) - -%.sym: %$(EXE) - $(XSYMS) $^ $@ - -%.bin: %$(EXE) - $(OBJCOPY) -Obinary $^ $@ - -#PRODTARGETS+=$(INSTALL_RTEMSSYMS) $(INSTALL_RTEMSIMGS) diff --git a/configure/os/CONFIG.Common.RTEMS-mvme5500 b/configure/os/CONFIG.Common.RTEMS-mvme5500 deleted file mode 100644 index 0c05b76a8..000000000 --- a/configure/os/CONFIG.Common.RTEMS-mvme5500 +++ /dev/null @@ -1,26 +0,0 @@ -# -# CONFIG.Common.RTEMS-mvme5500 -# Author: W. Eric Norum -# -# All RTEMS targets use the same Makefile fragment -# -EXE = .elf -RTEMS_TARGET_CPU = powerpc -GNU_TARGET = powerpc-rtems -ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL -ARCH_DEP_CFLAGS += -DHAVE_MOTLOAD -ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_MBUF_SPACE=2048 -ARCH_DEP_CFLAGS += -DRTEMS_NETWORK_CONFIG_CLUSTER_SPACE=5120 -ARCH_DEP_CFLAGS += -DBSP_NVRAM_BASE_ADDR=0xf1110000 - -OP_SYS_LDLIBS += -lbspExt - -MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) -define MUNCH_CMD - $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary $< $@ -endef - -OP_SYS_LDLIBS += -lbspExt - -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-pc386 b/configure/os/CONFIG.Common.RTEMS-pc386 deleted file mode 100644 index b3150cc66..000000000 --- a/configure/os/CONFIG.Common.RTEMS-pc386 +++ /dev/null @@ -1,24 +0,0 @@ -# -# Author: W. Eric Norum -# Canadian Light Source -# eric@cls.usask.ca -# -# All RTEMS targets use the same Makefile fragment -# -RTEMS_TARGET_CPU=i386 - -MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) -define MUNCH_CMD - $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< temp.bin - $(BIN2BOOT) $@ 0x00097E00 \ - $(PROJECT_RELEASE)/lib/start16.bin 0x00097C00 0 temp.bin 0x00100000 0 - rm -f temp.bin -endef - -include $(CONFIG)/os/CONFIG.Common.RTEMS - -# -# Put text segment where it will work with etherboot -# -OP_SYS_LDFLAGS += -Wl,-Ttext,0x100000 diff --git a/configure/os/CONFIG.Common.RTEMS-psim b/configure/os/CONFIG.Common.RTEMS-psim deleted file mode 100644 index 230d72e1f..000000000 --- a/configure/os/CONFIG.Common.RTEMS-psim +++ /dev/null @@ -1,9 +0,0 @@ -# -# Author: W. Eric Norum -# University of Saskatchewan -# eric.norum@usask.ca -# -# All RTEMS targets use the same Makefile fragment -# -RTEMS_TARGET_CPU=ppc -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.RTEMS-uC5282 b/configure/os/CONFIG.Common.RTEMS-uC5282 deleted file mode 100644 index 9c6a58d33..000000000 --- a/configure/os/CONFIG.Common.RTEMS-uC5282 +++ /dev/null @@ -1,17 +0,0 @@ -# -# Author: W. Eric Norum -# Canadian Light Source -# eric@cls.usask.ca -# -# All RTEMS targets use the same Makefile fragment -# -RTEMS_TARGET_CPU = m68k -ARCH_DEP_CFLAGS += -DMY_DO_BOOTP=NULL - -MUNCH_SUFFIX = .boot -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) -define MUNCH_CMD - $(RTEMS_TOOLS)/bin/$(OBJCOPY_FOR_TARGET) -O binary -R .comment -S $< $@ -endef - -include $(CONFIG)/os/CONFIG.Common.RTEMS diff --git a/configure/os/CONFIG.Common.UnixCommon b/configure/os/CONFIG.Common.UnixCommon deleted file mode 100644 index add84873e..000000000 --- a/configure/os/CONFIG.Common.UnixCommon +++ /dev/null @@ -1,107 +0,0 @@ -# CONFIG.Common.UnixCommon -# -# Contains definitions common to all Unix target archs -# -# This file is maintained by the build community. -# Sites may override definitions in CONFIG_SITE.Common.UnixCommon -# or CONFIG_SITE..UnixCommon -#------------------------------------------------------- - -# Unix valid build types -VALID_BUILDS = Host Ioc - -#------------------------------------------------------- -# Unix prefix and suffix definitions -EXE = -OBJ = .o -#Library prefix and suffixes -LIB_PREFIX = lib -LIB_SUFFIX = .a -SHRLIB_SUFFIX_BASE = .so -SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(SHRLIB_VERSION)) -LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE)$(addprefix .,$(LOADABLE_SHRLIB_VERSION)) -LOADABLE_SHRLIB_PREFIX = lib - -#------------------------------------------------------- -# names of libraries to build -# -> lib.a -LIBNAME = $(BUILD_LIBRARY:%=$(LIB_PREFIX)%$(LIB_SUFFIX)) -TESTLIBNAME = $(TESTBUILD_LIBRARY:%=$(LIB_PREFIX)%$(LIB_SUFFIX)) -# -> lib.so. -SHRLIBNAME_YES = $(BUILD_LIBRARY:%=$(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX)) -TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=$(SHRLIB_PREFIX)%$(SHRLIB_SUFFIX)) -LOADABLE_SHRLIBNAME = $(LOADABLE_BUILD_LIBRARY:%=$(LOADABLE_SHRLIB_PREFIX)%$(LOADABLE_SHRLIB_SUFFIX)) - -#------------------------------------------------------- -# shrlib: SHRLIB_DEPLIBS, SHRLIB_LDLIBS and SHRLIBDIR_LDFLAGS definitions - -# SHRLIB_LIBS deprecated -LIB_LIBS += $(SHRLIB_LIBS) - -SHRLIB_DEPLIBS = $(foreach lib, $(LIB_LIBS) $(USR_LIBS), \ - $(firstword $(wildcard \ - $(addsuffix /$(DLLSTUB_PREFIX)$(lib)$(DLLSTUB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - $(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - $(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - ) $(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), \ - $(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB))))) - -SHRLIB_LDLIBS = $(addprefix -l, $($*_LDLIBS) $(LIB_LIBS) $(USR_LIBS)) \ - $(STATIC_LDLIBS) \ - $(addprefix -l, $($*_SYS_LIBS) $(LIB_SYS_LIBS) $(USR_SYS_LIBS)) \ - $(LDLIBS) - -SHRLIB_DEPLIB_DIRS = $(foreach word, \ - $(sort $(INSTALL_LIB)/ $(dir $($*_DEPLIBS) $(SHRLIB_DEPLIBS))), \ - $(shell $(FULLPATHNAME) $(word))) - -SHRLIBDIR_LDFLAGS += $(SHRLIB_DEPLIB_DIRS:%=-L%) - -#------------------------------------------------------- -# Prod: PROD_DEPLIBS, PROD_LDLIBS and PRODDIR_LDFLAGS definitions - -PROD_DEPLIBS = $(foreach lib, $(PROD_LIBS) $(USR_LIBS), \ - $(firstword $(wildcard \ - $(addsuffix /$(DLLSTUB_PREFIX)$(lib)$(DLLSTUB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - $(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - $(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - ) $(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), \ - $(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB))))) - -PROD_LDLIBS = $(addprefix -l, $($*_LDLIBS) $(PROD_LIBS) $(USR_LIBS)) \ - $(STATIC_LDLIBS) \ - $(addprefix -l, $($*_SYS_LIBS) $(PROD_SYS_LIBS) $(USR_SYS_LIBS)) - -LDLIBS_STATIC_YES = LDLIBS -LDLIBS_SHARED_NO = LDLIBS -PROD_LDLIBS += $($(firstword $(LDLIBS_STATIC_$(STATIC_BUILD)) \ - $(LDLIBS_SHARED_$(SHARED_LIBRARIES)))) - -PROD_DEPLIB_DIRS = $(foreach word, \ - $(sort $(INSTALL_LIB)/ $(dir $($*_DEPLIBS) $(PROD_DEPLIBS))), \ - $(shell $(FULLPATHNAME) $(word))) - -PRODDIR_LDFLAGS += $(PROD_DEPLIB_DIRS:%=-L%) - -#-------------------------------------------------- -# Link definitions -LINK.cpp = $(CCC) -o $@ $(STATIC_LDFLAGS) $(PRODDIR_LDFLAGS) $(LDFLAGS) -LINK.cpp += $(PROD_LDFLAGS) $(PROD_LD_OBJS) $(PROD_LD_RESS) $(PROD_LDLIBS) -LINK.shrlib = $(CCC) -o $@ $(TARGET_LIB_LDFLAGS) $(SHRLIBDIR_LDFLAGS) $(LDFLAGS) -LINK.shrlib += $(LIB_LDFLAGS) $(LIBRARY_LD_OBJS) $(LIBRARY_LD_RESS) $(SHRLIB_LDLIBS) - -#-------------------------------------------------- -# Operating system definitions -OP_SYS_CPPFLAGS += -DUNIX -OP_SYS_LDLIBS += -lm - -#-------------------------------------------------- -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.Common.UnixCommon --include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).UnixCommon diff --git a/configure/os/CONFIG.Common.cygwin-x86 b/configure/os/CONFIG.Common.cygwin-x86 deleted file mode 100644 index 02dab10db..000000000 --- a/configure/os/CONFIG.Common.cygwin-x86 +++ /dev/null @@ -1,94 +0,0 @@ -# CONFIG.Common.cygwin-x86 -# -# This file is maintained by the build community. -# -# Definitions for cygwin-x86 target builds -# Sites may override these definitions in CONFIG_SITE.Common.cygwin-x86 -#------------------------------------------------------- - -# Include definitions common to all Unix targets -include $(CONFIG)/os/CONFIG.Common.UnixCommon - -OS_CLASS = cygwin32 -ARCH_CLASS = x86 - -# Link libraries controlled by COMMANDLINE_LIBRARY -# The Cygwin version 1.7.15 needs readline and ncursesw, -# older ones may need readline and curses. -LDLIBS_READLINE_NCURSESW = -lreadline -lncursesw -LDLIBS_READLINE_CURSES = -lreadline -lcurses -LDLIBS_READLINE = -lreadline - -POSIX_CPPFLAGS = -D_POSIX_THREADS -D_POSIX_TIMERS -POSIX_LDLIBS += -lpthread - -ARCH_DEP_CFLAGS += -m32 -ARCH_DEP_LDFLAGS += -m32 - -# 32-bit compiler defines _X86_ 1 -# Compiler defines __CYGWIN__ 1 -# 32-bit compiler defines __CYGWIN32__ 1 -# Compiler defines __unix__ 1 -# Compiler defines __unix 1 -# Compiler defines unix 1 - -# This macro now deprecated, use __CYGWIN__ in the future -OP_SYS_CPPFLAGS += -DCYGWIN32 - -EXE = .exe - -# Use .o for static object files, .obj for shared library object files -OBJ_NO = .o -OBJ_YES = .obj -OBJ = $(OBJ_$(SHARED_LIBRARIES)) - -COMPILE.c += $(if $(filter %$(OBJ),$@),-o $@) -COMPILE.cpp += $(if $(filter %$(OBJ),$@),-o $@) -HDEPENDS_ARCHFLAGS = -MT $*$(OBJ) - -BUILD_DLL_CFLAGS_YES = -DEPICS_BUILD_DLL -BUILD_DLL_CFLAGS_NO = -BUILD_DLL_CFLAGS = $(BUILD_DLL_CFLAGS_$(SHARED_LIBRARIES)) -STATIC_CFLAGS_YES = $(BUILD_DLL_CFLAGS) -STATIC_CFLAGS_NO = $(BUILD_DLL_CFLAGS) -DEPICS_CALL_DLL -STATIC_CXXFLAGS_YES = $(BUILD_DLL_CFLAGS) -STATIC_CXXFLAGS_NO = $(BUILD_DLL_CFLAGS) -DEPICS_CALL_DLL - -# Adjust names of libraries to build -# -SHRLIB_PREFIX = -SHRLIB_SUFFIX_BASE = .dll -SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE) -SHRLIBNAME_YES = $(BUILD_LIBRARY:%=%$(SHRLIB_SUFFIX)) -TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX_BASE)) -LOADABLE_SHRLIBNAME = $(LOADABLE_BUILD_LIBRARY:%=%$(LOADABLE_SHRLIB_SUFFIX)) - -# -# When SHARED_LIBRARIES is YES we are building a DLL link library -# When SHARED_LIBRARIES is NO we are building an object library -# -LIB_PREFIX_NO = -LIB_SUFFIX_NO = .lib -LIB_PREFIX_YES = lib -LIB_SUFFIX_YES = .dll.a -LIB_PREFIX = $(LIB_PREFIX_$(SHARED_LIBRARIES)) -LIB_SUFFIX = $(LIB_SUFFIX_$(SHARED_LIBRARIES)) -DLLSTUB_PREFIX = lib -DLLSTUB_SUFFIX = .dll.a - -DLLSTUB_LIBNAME_YES = $(BUILD_LIBRARY:%=$(LIB_PREFIX)%$(LIB_SUFFIX)) -DLLSTUB_LIBNAME = $(DLLSTUB_LIBNAME_$(SHARED_LIBRARIES)) -TESTDLLSTUB_LIBNAME_YES = $(TESTBUILD_LIBRARY:%=$(LIB_PREFIX)%$(LIB_SUFFIX)) -TESTDLLSTUB_LIBNAME = $(TESTDLLSTUB_LIBNAME_$(SHARED_LIBRARIES)) -TESTLIBNAME_NO = $(TESTBUILD_LIBRARY:%=$(LIB_PREFIX)%$(LIB_SUFFIX)) -TESTLIBNAME = $(TESTLIBNAME_$(SHARED_LIBRARIES)) - -# dll install location -INSTALL_SHRLIB = $(INSTALL_BIN) - - -# Cygwin supports the sunrpc package in versions before 1.7. -# Cygwin supports the tirpc (Transport Independent RPC) package in versions 1.7 and later. -# uname -r return a string like "1.76(0230/5/3)" -CYGWIN_RPC_LIB= $(if $(findstring 1.5,$(shell uname -r)),rpc,tirpc) - diff --git a/configure/os/CONFIG.Common.cygwin-x86_64 b/configure/os/CONFIG.Common.cygwin-x86_64 deleted file mode 100644 index b2b18dbfa..000000000 --- a/configure/os/CONFIG.Common.cygwin-x86_64 +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG.Common.cygwin-x86_64 -# -# This file is maintained by the build community. -# -# Definitions for cygwin-x86_64 target builds -# Sites may override these definitions in CONFIG_SITE.Common.cygwin-x86_64 -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.Common.cygwin-x86 - -ARCH_DEP_CFLAGS = -m64 -ARCH_DEP_LDFLAGS = -m64 - diff --git a/configure/os/CONFIG.Common.darwin-ppc b/configure/os/CONFIG.Common.darwin-ppc deleted file mode 100644 index 7ac704314..000000000 --- a/configure/os/CONFIG.Common.darwin-ppc +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG.Common.darwin-ppc -# -# This file is maintained by the build community. -# -# Definitions for darwin-ppc target builds -# Sites may override these definitions in CONFIG_SITE.Common.darwin-ppc -#------------------------------------------------------- - -# -# To build universal binaries, configure ARCH_CLASS -# in the file CONFIG_SITE.Common.darwin-ppc - -# Include definitions common to all Darwin targets -include $(CONFIG)/os/CONFIG.darwinCommon.darwinCommon diff --git a/configure/os/CONFIG.Common.darwin-ppcx86 b/configure/os/CONFIG.Common.darwin-ppcx86 deleted file mode 100644 index 12107944f..000000000 --- a/configure/os/CONFIG.Common.darwin-ppcx86 +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG.Common.darwin-ppcx86 -# -# This file is maintained by the build community. -# -# Definitions for Darwin universal PowerPC + x86 target builds -# Sites may override these definitions in CONFIG_SITE.Common.darwin-ppcx86 -#------------------------------------------------------- - -# -# To build universal binaries, configure ARCH_CLASS -# in the file CONFIG_SITE.Common.darwin-ppcx86 - -# Include definitions common to all Darwin targets -include $(CONFIG)/os/CONFIG.darwinCommon.darwinCommon diff --git a/configure/os/CONFIG.Common.darwin-x86 b/configure/os/CONFIG.Common.darwin-x86 deleted file mode 100644 index 89650ea7d..000000000 --- a/configure/os/CONFIG.Common.darwin-x86 +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG.Common.darwin-x86 -# -# This file is maintained by the build community. -# -# Definitions for darwin-x86 target builds -# Sites may override these definitions in CONFIG_SITE.Common.darwin-x86 -#------------------------------------------------------- - -# -# To build universal binaries, configure ARCH_CLASS -# in the file CONFIG_SITE.Common.darwin-x86 - -# Include definitions common to all Darwin targets -include $(CONFIG)/os/CONFIG.darwinCommon.darwinCommon diff --git a/configure/os/CONFIG.Common.freebsd-x86 b/configure/os/CONFIG.Common.freebsd-x86 deleted file mode 100644 index f0f18851f..000000000 --- a/configure/os/CONFIG.Common.freebsd-x86 +++ /dev/null @@ -1,33 +0,0 @@ -# -# This file is maintained by the build community. -# -# Definitions for freebsd-x86 target builds -# Sites may override these definitions in CONFIG_SITE.Common.freebsd-x86 -#------------------------------------------------------- - -# Include definitions common to all freebsd targets -include $(CONFIG)/os/CONFIG.Common.freebsdCommon - -ARCH_CLASS = x86 - -ARCH_DEP_CPPFLAGS += -D_X86_ - -ifeq ($(BUILD_CLASS),CROSS) -ifeq ($(EPICS_HOST_ARCH),freebsd-x86) - # Added for 386,486,... cross builds - CMPLR_PREFIX= - CROSS_INCLUDES= - CROSS_LDFLAGS= - # Use -w not -Wall - #WARN_CFLAGS_YES = -w - #WARN_CXXFLAGS_YES = -w --include $(CONFIG)/os/CONFIG_SITE.Common.freebsd-x86 --include $(CONFIG)/os/CONFIG.freebsd-x86.freebsd-x86 --include $(CONFIG)/os/CONFIG_SITE.freebsd-x86.freebsd-x86 -else - GNU_TARGET=i586-pc-freebsd-gnu - CMPLR_SUFFIX= - CMPLR_PREFIX=$(addsuffix -,$(GNU_TARGET)) -endif -endif - diff --git a/configure/os/CONFIG.Common.freebsd-x86_64 b/configure/os/CONFIG.Common.freebsd-x86_64 deleted file mode 100644 index f10be1058..000000000 --- a/configure/os/CONFIG.Common.freebsd-x86_64 +++ /dev/null @@ -1,33 +0,0 @@ -# -# This file is maintained by the build community. -# -# Definitions for freebsd-x86_64 target builds -# Sites may override these definitions in CONFIG_SITE.Common.freebsd-x86_64 -#------------------------------------------------------- - -# Include definitions common to all freebsd targets -include $(CONFIG)/os/CONFIG.Common.freebsdCommon - -ARCH_CLASS = x86_64 - -ARCH_DEP_CPPFLAGS += -D_X86_64_ - -ifeq ($(BUILD_CLASS),CROSS) -ifeq ($(EPICS_HOST_ARCH),freebsd-x86_64) - # Added for 386,486,... cross builds - CMPLR_PREFIX= - CROSS_INCLUDES= - CROSS_LDFLAGS= - # Use -w not -Wall - #WARN_CFLAGS_YES = -w - #WARN_CXXFLAGS_YES = -w --include $(CONFIG)/os/CONFIG_SITE.Common.freebsd-x86_64 --include $(CONFIG)/os/CONFIG.freebsd-x86_64.freebsd-x86_64 --include $(CONFIG)/os/CONFIG_SITE.freebsd-x86_64.freebsd-x86_64 -else - GNU_TARGET=i586-pc-freebsd-gnu - CMPLR_SUFFIX= - CMPLR_PREFIX=$(addsuffix -,$(GNU_TARGET)) -endif -endif - diff --git a/configure/os/CONFIG.Common.freebsdCommon b/configure/os/CONFIG.Common.freebsdCommon deleted file mode 100644 index 36796b758..000000000 --- a/configure/os/CONFIG.Common.freebsdCommon +++ /dev/null @@ -1,38 +0,0 @@ -# -# This file is maintained by the build community. -# -# Definitions for freebsd target builds -# Sites may override these definitions in CONFIG_SITE.Common.freebsdCommon -#------------------------------------------------------- - -# Include definitions common to all Unix targets -include $(CONFIG)/os/CONFIG.Common.UnixCommon - -OS_CLASS = freebsd - -CODE_CPPFLAGS = -D_REENTRANT - -POSIX_CPPFLAGS = -D_POSIX_THREADS -POSIX_LDLIBS = -lpthread - -# -D_BSD_SOURCE for gethostname() in unistd.h as needed by cacChannelIO.cpp. -OP_SYS_CPPFLAGS += -D_BSD_SOURCE -OP_SYS_CPPFLAGS += -Dfreebsd - -# Set runtime path for shared libraries -SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath,%) -SHRLIBDIR_LDFLAGS += $(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Set runtime path for products -PRODDIR_RPATH_LDFLAGS_YES += $(PROD_DEPLIB_DIRS:%=-Wl,-rpath,%) -PRODDIR_LDFLAGS += $(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Definitions used when COMMANDLINE_LIBRARY is READLINE -LDLIBS_READLINE = -lreadline -lcurses - -GNU_LDLIBS_YES = -lgcc_pic - -#-------------------------------------------------- -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.Common.freebsdCommon --include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).freebsdCommon diff --git a/configure/os/CONFIG.Common.ios-arm b/configure/os/CONFIG.Common.ios-arm deleted file mode 100644 index acca27d8c..000000000 --- a/configure/os/CONFIG.Common.ios-arm +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.ios-arm -# -# This file is maintained by the build community. -# -# Definitions for ios-arm target builds -# Sites may override these definitions in CONFIG_SITE.Common.ios-arm -# or CONFIG_SITE..ios-arm -#------------------------------------------------------- - -IOS_PLATFORM = iPhoneOS - -OP_SYS_CFLAGS += -fno-inline-functions -OP_SYS_CFLAGS += -miphoneos-version-min=$(IOS_DEPLOYMENT_TARGET) -OP_SYS_LDFLAGS += -miphoneos-version-min=$(IOS_DEPLOYMENT_TARGET) - -# iOS optimization flags for arm architecture -OPT_CFLAGS_YES = -O2 -OPT_CXXFLAGS_YES = -O2 - -# Include definitions common to all iphone targets -include $(CONFIG)/os/CONFIG.Common.iosCommon diff --git a/configure/os/CONFIG.Common.ios-x86 b/configure/os/CONFIG.Common.ios-x86 deleted file mode 100644 index 6031629c5..000000000 --- a/configure/os/CONFIG.Common.ios-x86 +++ /dev/null @@ -1,16 +0,0 @@ -# CONFIG.Common.ios-x86 -# -# This file is maintained by the build community. -# -# Definitions for ios-x86 target builds -# Sites may override these definitions in CONFIG_SITE.Common.ios-x86 -# or CONFIG_SITE..ios-x86 -#------------------------------------------------------- - -IOS_PLATFORM = iPhoneSimulator - -OP_SYS_CFLAGS += -mios-simulator-version-min=$(IOS_DEPLOYMENT_TARGET) -OP_SYS_LDFLAGS += -mios-simulator-version-min=$(IOS_DEPLOYMENT_TARGET) - -# Include definitions common to all iOS targets -include $(CONFIG)/os/CONFIG.Common.iosCommon diff --git a/configure/os/CONFIG.Common.iosCommon b/configure/os/CONFIG.Common.iosCommon deleted file mode 100644 index f9e5750e3..000000000 --- a/configure/os/CONFIG.Common.iosCommon +++ /dev/null @@ -1,116 +0,0 @@ -# CONFIG.Common.iosCommon -# -# This file is maintained by the build community. -# -# Definitions for all Apple iOS builds -# Sites may override these definitions in CONFIG_SITE.Common.iosCommon -# or CONFIG_SITE..iosCommon -#------------------------------------------------------- - -# Include definitions common to all Unix targets -include $(CONFIG)/os/CONFIG.Common.UnixCommon - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -#------------------------------------------------------- -# Valid build types -VALID_BUILDS = Ioc - -#------------------------------------------------------- -# operating system class (include/os/) -OS_CLASS = iOS - -#-------------------------------------------------- -# GNU and SDK directories -GNU_DIR = $(PLATFORM_DIR)/Developer/usr -SDK_DIR = $(PLATFORM_DIR)/Developer/SDKs/$(IOS_PLATFORM).sdk - -#------------------------------------------------------- -# Build architecture flags -# ARCH_CLASS must contain a list of CPU architectures which must be -# valid arguments to the -arch options for the cc and ld commands. -# ARCH_CLASS is defined in a CONFIG_SITE file which is not loaded -# until after this file. -# -ARCH_DEP_FLAGS = $(addprefix -arch ,$(ARCH_CLASS)) -ARCH_DEP_CFLAGS += $(ARCH_DEP_FLAGS) -ARCH_DEP_LDFLAGS += $(ARCH_DEP_FLAGS) - -#-------------------------------------------------- -# Operating system flags -OP_SYS_CFLAGS += -isysroot $(SDK_DIR) -OP_SYS_LDFLAGS += -isysroot $(SDK_DIR) - -#-------------------------------------------------- -# Always compile in debugging symbol table information -# -OPT_CFLAGS_YES += -g -OPT_CXXFLAGS_YES += -g - -#------------------------------------------------------- -# Compiler definitions: - -CC_GNU = gcc -CCC_GNU = g++ -CMPLR_CLASS_GNU = gcc - -CC_LLVM_GNU = llvm-gcc -CCC_LLVM_GNU = llvm-g++ -CMPLR_CLASS_LLVM_GNU = gcc - -CC_CLANG = clang -CCC_CLANG = clang++ -CMPLR_CLASS_CLANG = clang - -CMPLR_CLASS = $(CMPLR_CLASS_$(COMPILER)) - -# Convert the iOS platform to lowercase for passing to xcrun's sdk parameter -XCRUN_SDK_BASE = $(shell echo $(IOS_PLATFORM) | tr A-Z a-z) - -#------------------------------------------------------- -# Linker flags -GNU_LDLIBS_YES = -OP_SYS_LDFLAGS += -dynamic -Z -L$(SDK_DIR)/usr/lib -L$(SDK_DIR)/usr/lib/system - -#------------------------------------------------------- -# Shared libraries -SHRLIB_VERSION = $(EPICS_VERSION).$(EPICS_REVISION).$(EPICS_MODIFICATION) -SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined suppress \ - -install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \ - -compatibility_version $(EPICS_VERSION).$(EPICS_REVISION) \ - -current_version $(SHRLIB_VERSION) -SHRLIB_SUFFIX_BASE = .dylib -SHRLIB_SUFFIX = .$(SHRLIB_VERSION)$(SHRLIB_SUFFIX_BASE) - -LOADABLE_SHRLIB_LDFLAGS = -bundle -flat_namespace -undefined suppress - -#-------------------------------------------------- -# code flags -CODE_CFLAGS = -fno-common -Wno-unused-value -CODE_CXXFLAGS = -fno-common - -# -# Add support for Objective-C source -# -vpath %.m $(USR_VPATH) $(ALL_SRC_DIRS) -%.o: %.m - $(COMPILE.c) -c $< - -#-------------------------------------------------- -# Header dependency file generation -# -HDEPENDS_METHOD = MKMF - -#-------------------------------------------------- -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.Common.iosCommon --include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).iosCommon - -#-------------------------------------------------- -# Find the Xcode programs for the selected SDK -CC := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find $(CC_$(COMPILER))) -CCC := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find $(CCC_$(COMPILER))) -AR := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find ar) -rc -LD := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find ld) -r -RANLIB := $(shell xcrun -sdk $(XCRUN_SDK_BASE) -find ranlib) diff --git a/configure/os/CONFIG.Common.linux-386 b/configure/os/CONFIG.Common.linux-386 deleted file mode 100644 index 8549a8ab6..000000000 --- a/configure/os/CONFIG.Common.linux-386 +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.linux-386 -# -# This file is maintained by the build community. -# -# Definitions for linux-386 target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-386 -#------------------------------------------------------- - -# Include definitions common to all linux x86 targets -include $(CONFIG)/os/CONFIG.Common.linux-x86 - -ARCH_DEP_CFLAGS = -march=i386 - -ifeq ($(BUILD_CLASS),CROSS) - VALID_BUILDS = Ioc -endif - -# If your crosscompiler name has a GNU target prefix like -gcc, -# e.g. i386-pc-linux-gnu-gcc, put a GNU_TARGET definition in -# CONFIG_SITE..linux-386 file, e.g. GNU_TARGET=i386-pc-linux-gnu - diff --git a/configure/os/CONFIG.Common.linux-486 b/configure/os/CONFIG.Common.linux-486 deleted file mode 100644 index cf39b92d2..000000000 --- a/configure/os/CONFIG.Common.linux-486 +++ /dev/null @@ -1,19 +0,0 @@ -# CONFIG.Common.linux-486 -# -# Definitions for linux-486 target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-486 -#------------------------------------------------------- - -# Include definitions common to all linux x86 targets -include $(CONFIG)/os/CONFIG.Common.linux-x86 - -ARCH_DEP_CFLAGS = -march=i486 - -ifeq ($(BUILD_CLASS),CROSS) - VALID_BUILDS = Ioc -endif - -# If your crosscompiler name has a GNU target prefix like -gcc, -# e.g. i486-pc-linux-gnu-gcc, put a GNU_TARGET definition in -# CONFIG_SITE..linux-486 file, e.g. GNU_TARGET=i486-pc-linux-gnu - diff --git a/configure/os/CONFIG.Common.linux-586 b/configure/os/CONFIG.Common.linux-586 deleted file mode 100644 index 9b2fa466b..000000000 --- a/configure/os/CONFIG.Common.linux-586 +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.linux-586 -# -# Definitions for linux-586 target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-586 -#------------------------------------------------------- - -# Include definitions common to all linux x86 targets -include $(CONFIG)/os/CONFIG.Common.linux-x86 - -# i586 is equivalent to pentium -ARCH_DEP_CFLAGS = -march=i586 - -ifeq ($(BUILD_CLASS),CROSS) - VALID_BUILDS = Ioc -endif - -# If your crosscompiler name has a GNU target prefix like -gcc, -# e.g. i586-pc-linux-gnu-gcc, put a GNU_TARGET definition in -# CONFIG_SITE..linux-586 file, e.g. GNU_TARGET=i586-pc-linux-gnu - - diff --git a/configure/os/CONFIG.Common.linux-686 b/configure/os/CONFIG.Common.linux-686 deleted file mode 100644 index 5a2e0ef5f..000000000 --- a/configure/os/CONFIG.Common.linux-686 +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG.Common.linux-686 -# -# Definitions for linux-686 target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-686 -#------------------------------------------------------- - -# Include definitions common to all linux x86 targets -include $(CONFIG)/os/CONFIG.Common.linux-x86 - -# i686 is euivalent to pentiumpro -ARCH_DEP_CFLAGS = -march=i686 - -ifeq ($(BUILD_CLASS),CROSS) - VALID_BUILDS = Ioc -endif - -# If your crosscompiler name has a GNU target prefix like -gcc, -# e.g. i686-pc-linux-gnu-gcc, put a GNU_TARGET definition in -# CONFIG_SITE..linux-686 file, e.g. GNU_TARGET=i686-pc-linux-gnu - diff --git a/configure/os/CONFIG.Common.linux-arm b/configure/os/CONFIG.Common.linux-arm deleted file mode 100644 index a305523eb..000000000 --- a/configure/os/CONFIG.Common.linux-arm +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.linux-arm -# -# Definitions for linux-arm target builds -# Override these settings in CONFIG_SITE.Common.linux-arm -#------------------------------------------------------- - -# Include definitions common to all Linux targets -include $(CONFIG)/os/CONFIG.Common.linuxCommon - -ARCH_CLASS = arm - diff --git a/configure/os/CONFIG.Common.linux-arm-debug b/configure/os/CONFIG.Common.linux-arm-debug deleted file mode 100644 index c2a0e99eb..000000000 --- a/configure/os/CONFIG.Common.linux-arm-debug +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.Common.linux-arm-debug -# -# Definitions for linux-arm with debug compiler flags -# Override these settings in CONFIG_SITE.Common.linux-arm-debug -#------------------------------------------------------- - -# Include definitions common to all linux-arm target archs -include $(CONFIG)/os/CONFIG.Common.linux-arm - -HOST_OPT=NO diff --git a/configure/os/CONFIG.Common.linux-arm_eb b/configure/os/CONFIG.Common.linux-arm_eb deleted file mode 100644 index 69a255020..000000000 --- a/configure/os/CONFIG.Common.linux-arm_eb +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.Common.linux-arm_eb -# -# Definitions for linux-arm_eb (big endian) target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-arm_eb -#------------------------------------------------------- - -# Include definitions common to all Linux-arm targets -include $(CONFIG)/os/CONFIG.Common.linux-arm - diff --git a/configure/os/CONFIG.Common.linux-arm_el b/configure/os/CONFIG.Common.linux-arm_el deleted file mode 100644 index 40701b616..000000000 --- a/configure/os/CONFIG.Common.linux-arm_el +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.Common.linux-arm_el -# -# Definitions for linux-arm_el (little endian) target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-arm_el -#------------------------------------------------------- - -# Include definitions common to all linux-arm targets -include $(CONFIG)/os/CONFIG.Common.linux-arm - diff --git a/configure/os/CONFIG.Common.linux-athlon b/configure/os/CONFIG.Common.linux-athlon deleted file mode 100644 index 69f20a81d..000000000 --- a/configure/os/CONFIG.Common.linux-athlon +++ /dev/null @@ -1,19 +0,0 @@ -# CONFIG.Common.linux-athlon -# -# Definitions for linux-athlon target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-athlon -#------------------------------------------------------- - -# Include definitions common to all linux x86 targets -include $(CONFIG)/os/CONFIG.Common.linux-x86 - -ARCH_DEP_CFLAGS += -march=athlon-mp -mfpmath=sse - -ifeq ($(BUILD_CLASS),CROSS) - VALID_BUILDS = Ioc -endif - -# If your crosscompiler name has a GNU target prefix like -gcc, -# e.g. athlon-pc-linux-gnu-gcc, put a GNU_TARGET definition in -# CONFIG_SITE..linux-athlon file, e.g. GNU_TARGET=athlon-pc-linux-gnu - diff --git a/configure/os/CONFIG.Common.linux-cris b/configure/os/CONFIG.Common.linux-cris deleted file mode 100644 index d419b23e8..000000000 --- a/configure/os/CONFIG.Common.linux-cris +++ /dev/null @@ -1,58 +0,0 @@ -# CONFIG.Common.linux-cris -# -# Author: Peter Zumbruch -# GSI -# P.Zumbruch@gsi.de -# -# Definitions for linux-cris target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-cris -#------------------------------------------------------- - -# Include definitions common to all linux targets -include $(CONFIG)/os/CONFIG.Common.linuxCommon - -ARCH_CLASS = cris - -ifeq ($(BUILD_CLASS),CROSS) - GNU_TARGET = cris-axis-linux-gnu - - # prefix of compiler tools - CMPLR_SUFFIX = - CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET)) - - # CROSS_TOP_DIR - # usually AXIS_TOP_DIR is defined via - # the init_env script of the SDK provided by Axis - # - ## AXIS_TOP_DIR defined? Make missing mandatory variable visible - AXIS_TOP_DIR?=UNDEFINED_ENV__AXIS_TOP_DIR - AXIS_SDK_DIR?=$(AXIS_TOP_DIR) - - # CROSS_INCLUDES - AXIS_SDK_TARGET_INCLUDE_DIR = $(AXIS_SDK_DIR)/target/$(GNU_TARGET)/include - AXIS_SDK_TARGET_INCLUDE_DIR +=$(AXIS_SDK_DIR)/target/$(GNU_TARGET)/usr/include - - CROSS_INCLUDES = $(addprefix -isystem ,$(AXIS_SDK_TARGET_INCLUDE_DIR)) - - # CROSS_LDFLAGS - AXIS_SDK_TARGET_LIB_DIR = $(AXIS_SDK_DIR)/target/$(GNU_TARGET)/lib - AXIS_SDK_TARGET_LIB_DIR += $(AXIS_SDK_DIR)/target/$(GNU_TARGET)/usr/lib - - CROSS_LDFLAGS = $(addprefix -L,$(AXIS_SDK_TARGET_LIB_DIR)) - --include $(CONFIG)/os/CONFIG_SITE.Common.linux-cris -ifeq ($(EPICS_HOST_ARCH), linux-x86) --include $(CONFIG)/os/CONFIG.linux-x86.linux-cris --include $(CONFIG)/os/CONFIG_SITE.linux-x86.linux-cris -endif -endif - -SHARED_LIBRARIES=NO -STATIC_BUILD=YES - -ARCH_DEP_CFLAGS += -mno-mul-bug-workaround -OP_SYS_CFLAGS += -mlinux -ARCH_DEP_CPPFLAGS += -D_cris_ -mlinux - -#uncomment CRIS_COMPILER_DEBUG for debugging cris-compiled code -#CRIS_COMPILER_DEBUG diff --git a/configure/os/CONFIG.Common.linux-microblaze b/configure/os/CONFIG.Common.linux-microblaze deleted file mode 100644 index 21ecb03ac..000000000 --- a/configure/os/CONFIG.Common.linux-microblaze +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.linux-microblaze -# -# This file is maintained by the build community. -# -# Definitions for Xilinx MicroBlaze FPGA Soft Core Processor target builds. -# This target has been tested with the Xilinx Spartan 6 MicroBlaze. - -# Site-specific overrides of these definitions should be made in the file -# CONFIG_SITE.Common.linux-microblaze -#------------------------------------------------------- - -# Include definitions common to all Linux targets -include $(CONFIG)/os/CONFIG.Common.linuxCommon - -ARCH_CLASS = microblaze - -ifeq ($(BUILD_CLASS),CROSS) - VALID_BUILDS = Ioc - GNU_TARGET = microblazeel-unknown-linux-gnu - CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET)) -endif diff --git a/configure/os/CONFIG.Common.linux-ppc b/configure/os/CONFIG.Common.linux-ppc deleted file mode 100644 index 8eddca06e..000000000 --- a/configure/os/CONFIG.Common.linux-ppc +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG.Common.linux-ppc -# -# Definitions for linux-ppc target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-ppc -#------------------------------------------------------- - -# Include definitions common to all Unix targets -include $(CONFIG)/os/CONFIG.Common.linuxCommon - -ARCH_CLASS = ppc - -ARCH_DEP_CPPFLAGS += -D_ppc_ - diff --git a/configure/os/CONFIG.Common.linux-ppc64 b/configure/os/CONFIG.Common.linux-ppc64 deleted file mode 100644 index b2c754bad..000000000 --- a/configure/os/CONFIG.Common.linux-ppc64 +++ /dev/null @@ -1,15 +0,0 @@ -# CONFIG.Common.linux-ppc64 -# -# Definitions for linux-ppc64 target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-ppc64 -#------------------------------------------------------- - -# Include definitions common to all linux targets -include $(CONFIG)/os/CONFIG.Common.linuxCommon - -ARCH_CLASS = ppc64 - -ARCH_DEP_CPPFLAGS += -D_ppc_64_ -ARCH_DEP_CFLAGS += -m64 -ARCH_DEP_LDFLAGS += -m64 - diff --git a/configure/os/CONFIG.Common.linux-x86 b/configure/os/CONFIG.Common.linux-x86 deleted file mode 100644 index f2b94efae..000000000 --- a/configure/os/CONFIG.Common.linux-x86 +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.linux-x86 -# -# Definitions for linux-x86 target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-x86 -#------------------------------------------------------- - -# Include definitions common to all linux targets -include $(CONFIG)/os/CONFIG.Common.linuxCommon - -ARCH_CLASS = x86 - -ARCH_DEP_CFLAGS = $(GNU_TUNE_CFLAGS) -ARCH_DEP_CPPFLAGS += -D_X86_ - -OP_SYS_CFLAGS += -m32 -OP_SYS_LDFLAGS += -m32 - -# If your crosscompiler name has a GNU target prefix like -gcc, -# e.g. x86-redhat-linux-gcc, put a GNU_TARGET definition in -# CONFIG_SITE..linux-x86 file, e.g. GNU_TARGET=x86-redhat-linux - diff --git a/configure/os/CONFIG.Common.linux-x86-debug b/configure/os/CONFIG.Common.linux-x86-debug deleted file mode 100644 index 1a7eb09d6..000000000 --- a/configure/os/CONFIG.Common.linux-x86-debug +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.Common.linux-x86-debug -# -# Definitions for linux-x86 with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.Common.linux-x86-debug -#------------------------------------------------------- - -# Include definitions common to all linux-x86 target archs -include $(CONFIG)/os/CONFIG.Common.linux-x86 - -HOST_OPT=NO diff --git a/configure/os/CONFIG.Common.linux-x86_64 b/configure/os/CONFIG.Common.linux-x86_64 deleted file mode 100644 index 46b6231d4..000000000 --- a/configure/os/CONFIG.Common.linux-x86_64 +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.linux-x86_64 -# -# Definitions for linux-x86_64 target builds -# Sites may override these definitions in CONFIG_SITE.Common.linux-x86_64 -#------------------------------------------------------- - -# Include definitions common to all linux targets -include $(CONFIG)/os/CONFIG.Common.linuxCommon - -ARCH_CLASS = x86_64 - -ARCH_DEP_CFLAGS = $(GNU_TUNE_CFLAGS) -ARCH_DEP_CPPFLAGS += -D_X86_64_ - -OP_SYS_CFLAGS += -m64 -OP_SYS_LDFLAGS += -m64 - -# If your crosscompiler name has a GNU target prefix like -gcc, -# e.g. x86_64-redhat-linux-gcc, put a GNU_TARGET definition in -# CONFIG_SITE..linux-x86_64 file, e.g. GNU_TARGET=x86_64-redhat-linux - diff --git a/configure/os/CONFIG.Common.linux-x86_64-debug b/configure/os/CONFIG.Common.linux-x86_64-debug deleted file mode 100644 index b0a382b52..000000000 --- a/configure/os/CONFIG.Common.linux-x86_64-debug +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.Common.linux-x86_64-debug -# -# Definitions for linux-x86_64 with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.Common.linux-x86_64-debug -#------------------------------------------------------- - -# Include definitions common to all linux-x86_64 target archs -include $(CONFIG)/os/CONFIG.Common.linux-x86_64 - -HOST_OPT=NO diff --git a/configure/os/CONFIG.Common.linux-xscale_be b/configure/os/CONFIG.Common.linux-xscale_be deleted file mode 100644 index 8597aa208..000000000 --- a/configure/os/CONFIG.Common.linux-xscale_be +++ /dev/null @@ -1,19 +0,0 @@ -# CONFIG.Common.linux-xscale_be -# -# Definitions for linux-xscale_be (big-endian) target builds. -# This target has been tested with the MOXA UC-7408-LX Plus. - -# Site-specific overrides of these definitions should be made in the file -# CONFIG_SITE.Common.linux-xscale_be -#------------------------------------------------------- - -# Include definitions common to all Linux targets -include $(CONFIG)/os/CONFIG.Common.linuxCommon - -ARCH_CLASS = xscale - -ifeq ($(BUILD_CLASS),CROSS) - VALID_BUILDS = Ioc - GNU_TARGET = xscale_be - CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET)) -endif diff --git a/configure/os/CONFIG.Common.linuxCommon b/configure/os/CONFIG.Common.linuxCommon deleted file mode 100644 index d50ce60d9..000000000 --- a/configure/os/CONFIG.Common.linuxCommon +++ /dev/null @@ -1,44 +0,0 @@ -# CONFIG.Common.linuxCommon -# -# Definitions for linux target builds -# Sites may override these definitions in CONFIG_SITE.Common.linuxCommon -#------------------------------------------------------- - -# Include definitions common to all Unix targets -include $(CONFIG)/os/CONFIG.Common.UnixCommon - -OS_CLASS = Linux - -# Define _GNU_SOURCE and _DEFAULT_SOURCE for maximum portability -POSIX_CPPFLAGS = -D_GNU_SOURCE -D_DEFAULT_SOURCE -POSIX_LDLIBS = -lpthread - -OP_SYS_CPPFLAGS += -Dlinux -OP_SYS_LDLIBS += -lrt -ldl -# Use -rdynamic to maximize symbols available for stacktrace -OP_SYS_LDFLAGS += -rdynamic - -# Linker flags for static & shared-library builds -STATIC_LDFLAGS_YES= -Wl,-Bstatic -STATIC_LDFLAGS_NO= -STATIC_LDLIBS_YES= -Wl,-Bdynamic - -# Set runtime path for shared libraries -SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath,%) -SHRLIBDIR_LDFLAGS += $(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Set runtime path for products -PRODDIR_RPATH_LDFLAGS_YES += $(PROD_DEPLIB_DIRS:%=-Wl,-rpath,%) -PRODDIR_LDFLAGS += $(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Link libraries controlled by COMMANDLINE_LIBRARY -# The newest Linux versions only need readline, older ones need both -# readline and ncurses, and the oldest need readline and curses -LDLIBS_READLINE = -lreadline -LDLIBS_READLINE_NCURSES = -lreadline -lncurses -LDLIBS_READLINE_CURSES = -lreadline -lcurses - -#-------------------------------------------------- -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.Common.linuxCommon --include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).linuxCommon diff --git a/configure/os/CONFIG.Common.solaris-sparc b/configure/os/CONFIG.Common.solaris-sparc deleted file mode 100644 index af26b8680..000000000 --- a/configure/os/CONFIG.Common.solaris-sparc +++ /dev/null @@ -1,63 +0,0 @@ -# CONFIG.Common.solaris-sparc -# -# Definitions for solaris-sparc target archs -# Sites may override these definitions in CONFIG_SITE.Common.solaris-sparc -#------------------------------------------------------- - -# Include definitions common to all Unix target archs -include $(CONFIG)/os/CONFIG.Common.UnixCommon - -OS_CLASS = solaris -ARCH_CLASS = sparc - -CODE_CPPFLAGS = -D__EXTENSIONS__ - -COMPILER_CPPFLAGS += -mt -COMPILER_LDFLAGS += -mt - -SOLARIS_VERSION = $(subst 5.,,$(shell uname -r)) - -POSIX_CFLAGS = -xc99 -D_POSIX_C_SOURCE=200112L -POSIX_LDLIBS += -lposix4 -lpthread - -OP_SYS_CPPFLAGS += -DSOLARIS=$(SOLARIS_VERSION) $(COMPILER_CPPFLAGS) -OP_SYS_LDFLAGS += $(COMPILER_LDFLAGS) - -# Set runtime path for shared libraries -SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-R%) -SHRLIBDIR_LDFLAGS += $(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Set runtime path for products -PRODDIR_RPATH_LDFLAGS_YES += $(PROD_DEPLIB_DIRS:%=-R%) -PRODDIR_LDFLAGS += $(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -GNU_TARGET=sparc-sun-solaris2 - -STLPORT_CFLAGS_YES= -library=stlport4 -STLPORT_CFLAGS_NO= -STLPORT_LDLIBS_YES = -STLPORT_LDLIBS_NO = -lCstd - -# can be overridden in CONFIG_SITE.Common.solaris-sparc -USE_STLPORT=NO - -OP_SYS_CFLAGS+=$(STLPORT_CFLAGS_$(USE_STLPORT)) -OP_SYS_LDFLAGS+=$(STLPORT_CFLAGS_$(USE_STLPORT)) -OP_SYS_LDLIBS += $(STLPORT_LDLIBS_$(USE_STLPORT)) - -# OS libraries used when generating shared libraries or static binaries -OP_SYS_LDLIBS += -lsocket -lnsl -OP_SYS_LDLIBS_8 += -ldl -lCrun -lc -OP_SYS_LDLIBS_9 += -ldl -lumem -lCrun -lc -OP_SYS_LDLIBS_10 += -lumem -lCrun -lc -OP_SYS_LDLIBS += $(OP_SYS_LDLIBS_$(SOLARIS_VERSION)) - -# Definitions used when COMMANDLINE_LIBRARY is READLINE -READLINE_DIR = $(GNU_DIR) -INCLUDES_READLINE = -I$(READLINE_DIR)/include -RUNTIME_LDFLAGS_READLINE_YES += -R$(READLINE_DIR)/lib -RUNTIME_LDFLAGS_READLINE += $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)) -LDFLAGS_READLINE += -L$(READLINE_DIR)/lib -LDLIBS_READLINE = -lreadline -lcurses -# Use archive if there is a problem with the readline shared library -#LDLIBS_READLINE = -Bstatic -lreadline -Bdynamic -lcurses diff --git a/configure/os/CONFIG.Common.solaris-sparc-debug b/configure/os/CONFIG.Common.solaris-sparc-debug deleted file mode 100644 index d2d58f33e..000000000 --- a/configure/os/CONFIG.Common.solaris-sparc-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.solaris-sparc-debug -# -# Definitions for solaris-sparc with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.Common.solaris-sparc-debug -#------------------------------------------------------- - -# Include definitions common to all solaris-sparc target archs -include $(CONFIG)/os/CONFIG.Common.solaris-sparc - -# Removes -O optimization and adds -g compile option -HOST_OPT=NO diff --git a/configure/os/CONFIG.Common.solaris-sparc-gnu b/configure/os/CONFIG.Common.solaris-sparc-gnu deleted file mode 100644 index d600ff391..000000000 --- a/configure/os/CONFIG.Common.solaris-sparc-gnu +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG.Common.solaris-sparc-gnu -# -# Definitions for solaris-sparc gnu compiler target archs -# Sites may override these definitions in CONFIG_SITE.Common.solaris-sparc-gnu -#------------------------------------------------------- - -# Include definitions common to all solaris-sparc target archs -include $(CONFIG)/os/CONFIG.Common.solaris-sparc - -COMPILER_CPPFLAGS = -D_REENTRANT - -POSIX_CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200112L - -STLPORT_LDLIBS_NO = - -OP_SYS_LDLIBS_8 = -ldl -OP_SYS_LDLIBS_9 = -ldl -OP_SYS_LDLIBS_10 = -OP_SYS_LDLIBS_11 = -lc - diff --git a/configure/os/CONFIG.Common.solaris-sparc64 b/configure/os/CONFIG.Common.solaris-sparc64 deleted file mode 100644 index f6da3be3f..000000000 --- a/configure/os/CONFIG.Common.solaris-sparc64 +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.solaris-sparc64 -# -# Definitions for solaris-sparc64 compiler target archs -# Sites may override these definitions in CONFIG_SITE.Common.solaris-sparc64 -#------------------------------------------------------- - -# Include definitions common to all solaris-sparc target archs -include $(CONFIG)/os/CONFIG.Common.solaris-sparc - -ARCH_DEP_CFLAGS += -m64 -ARCH_DEP_LDFLAGS += -m64 diff --git a/configure/os/CONFIG.Common.solaris-sparc64-gnu b/configure/os/CONFIG.Common.solaris-sparc64-gnu deleted file mode 100644 index d82f91273..000000000 --- a/configure/os/CONFIG.Common.solaris-sparc64-gnu +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.Common.solaris-sparc64-gnu -# -# Definitions for solaris-sparc64 gnu compiler target archs -# Sites may override these definitions in CONFIG_SITE.Common.solaris-sparc64-gnu -#------------------------------------------------------- - -# Include definitions common to all solaris-sparc-gnu target archs -include $(CONFIG)/os/CONFIG.Common.solaris-sparc-gnu - -ARCH_DEP_CFLAGS += -mcpu=v9 -m64 -ARCH_DEP_LDFLAGS += -mcpu=v9 -m64 -ARCH_DEP_LDFLAGS += -L$(GNU_LIB)/sparcv9 -R$(GNU_LIB)/sparcv9 diff --git a/configure/os/CONFIG.Common.solaris-x86 b/configure/os/CONFIG.Common.solaris-x86 deleted file mode 100644 index 087cd40b2..000000000 --- a/configure/os/CONFIG.Common.solaris-x86 +++ /dev/null @@ -1,65 +0,0 @@ -# CONFIG.Common.solaris-x86 -# -# Definitions for solaris-x86 target archs -# Sites may override these definitions in CONFIG_SITE.Common.solaris-x86 -#------------------------------------------------------- - -# Include definitions common to all Unix target archs -include $(CONFIG)/os/CONFIG.Common.UnixCommon - -OS_CLASS = solaris -ARCH_CLASS = x86 - -CODE_CPPFLAGS = -D__EXTENSIONS__ - -COMPILER_CPPFLAGS += -mt -COMPILER_LDFLAGS += -mt - -SOLARIS_VERSION = $(subst 5.,,$(shell uname -r)) - -POSIX_CFLAGS = -xc99 -D_POSIX_C_SOURCE=200112L -POSIX_LDLIBS += -lposix4 -lpthread - -OP_SYS_CPPFLAGS += -DSOLARIS=$(SOLARIS_VERSION) $(COMPILER_CPPFLAGS) -OP_SYS_LDFLAGS += $(COMPILER_LDFLAGS) -ARCH_DEP_CPPFLAGS = -D_X86_ - -# Set runtime path for shared libraries -SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-R%) -SHRLIBDIR_LDFLAGS += $(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Set runtime path for products -PRODDIR_RPATH_LDFLAGS_YES += $(PROD_DEPLIB_DIRS:%=-R%) -PRODDIR_LDFLAGS += $(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -GNU_TARGET=x86-sun-solaris2 - -STLPORT_CFLAGS_YES= -library=stlport4 -STLPORT_CFLAGS_NO= -STLPORT_LDLIBS_YES = -STLPORT_LDLIBS_NO = -lCstd - -# can be overridden from ...SITE -USE_STLPORT=NO - -OP_SYS_CFLAGS+=$(STLPORT_CFLAGS_$(USE_STLPORT)) -OP_SYS_LDFLAGS+=$(STLPORT_CFLAGS_$(USE_STLPORT)) - -OP_SYS_LDLIBS += -lsocket -lnsl -OP_SYS_LDLIBS_8 += -ldl -lCrun -lc -OP_SYS_LDLIBS_9 += -ldl -lCrun -lc -OP_SYS_LDLIBS_10 += -lCrun -lc -OP_SYS_LDLIBS_11 += -lCrun -lc -OP_SYS_LDLIBS += $(OP_SYS_LDLIBS_$(SOLARIS_VERSION)) -OP_SYS_LDLIBS += $(STLPORT_LDLIBS_$(USE_STLPORT)) - -# Definitions used when COMMANDLINE_LIBRARY is READLINE -READLINE_DIR = $(GNU_DIR) -INCLUDES_READLINE = -I$(READLINE_DIR)/include -RUNTIME_LDFLAGS_READLINE_YES += -R$(READLINE_DIR)/lib -RUNTIME_LDFLAGS_READLINE += $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)) -LDFLAGS_READLINE += -L$(READLINE_DIR)/lib -LDLIBS_READLINE = -lreadline -lcurses -# Use archive if there is a problem with the readline shared library -#LDLIBS_READLINE = -Bstatic -lreadline -Bdynamic -lcurses - diff --git a/configure/os/CONFIG.Common.solaris-x86-gnu b/configure/os/CONFIG.Common.solaris-x86-gnu deleted file mode 100644 index ea5df2b5e..000000000 --- a/configure/os/CONFIG.Common.solaris-x86-gnu +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG.Common.solaris-x86-gnu -# -# Definitions for solaris-x86 gnu compiler target archs -# Sites may override these definitions in CONFIG_SITE.Common.solaris-x86-gnu -#------------------------------------------------------- - -# Include definitions common to all solaris-x86 target archs -include $(CONFIG)/os/CONFIG.Common.solaris-x86 - -COMPILER_CPPFLAGS = -D_REENTRANT - -POSIX_CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200112L - -STLPORT_LDLIBS_NO = - -OP_SYS_LDLIBS_8 = -ldl -lc -OP_SYS_LDLIBS_9 = -ldl -lc -OP_SYS_LDLIBS_10 = -lc -OP_SYS_LDLIBS_11 = -lc - diff --git a/configure/os/CONFIG.Common.solaris-x86_64 b/configure/os/CONFIG.Common.solaris-x86_64 deleted file mode 100644 index 509fc8e7c..000000000 --- a/configure/os/CONFIG.Common.solaris-x86_64 +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.solaris-x86_64 -# -# Definitions for solaris-x86_64 compiler target archs -# Sites may override these definitions in CONFIG_SITE.Common.solaris-x86_64 -#------------------------------------------------------- - -# Include definitions common to all solaris-x86 target archs -include $(CONFIG)/os/CONFIG.Common.solaris-x86 - -ARCH_DEP_CFLAGS += -m64 -ARCH_DEP_LDFLAGS += -m64 diff --git a/configure/os/CONFIG.Common.solaris-x86_64-gnu b/configure/os/CONFIG.Common.solaris-x86_64-gnu deleted file mode 100644 index 5bae0cee9..000000000 --- a/configure/os/CONFIG.Common.solaris-x86_64-gnu +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.Common.solaris-x86_64-gnu -# -# Definitions for solaris-x86_64 gnu compiler target archs -# Sites may override these definitions in CONFIG_SITE.Common.solaris-x86_64-gnu -#------------------------------------------------------- - -# Include definitions common to all solaris-x86-gnu target archs -include $(CONFIG)/os/CONFIG.Common.solaris-x86-gnu - -ARCH_DEP_CFLAGS += -m64 -ARCH_DEP_LDFLAGS += -m64 -#ARCH_DEP_LDFLAGS += -L$(GNU_LIB)/amd64 -R$(GNU_LIB)/amd64 diff --git a/configure/os/CONFIG.Common.vxWorks-486 b/configure/os/CONFIG.Common.vxWorks-486 deleted file mode 100644 index eaf66581a..000000000 --- a/configure/os/CONFIG.Common.vxWorks-486 +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.vxWorks-486 -# -# Definitions for vxWorks-486 target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-486 -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = pentium - -ARCH_CLASS = x86 - -ARCH_DEP_CPPFLAGS = -DCPU=I80486 -D_X86_ -ARCH_DEP_CFLAGS = -mtune=i486 -march=i486 -ARCH_DEP_CFLAGS += -fno-zero-initialized-in-bss -fno-defer-pop - -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.Common.vxWorks-486 - diff --git a/configure/os/CONFIG.Common.vxWorks-486-debug b/configure/os/CONFIG.Common.vxWorks-486-debug deleted file mode 100644 index 3caefe1e5..000000000 --- a/configure/os/CONFIG.Common.vxWorks-486-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-486-debug -# -# Definitions for vxWorks-486-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-486-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-486 - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-68040 b/configure/os/CONFIG.Common.vxWorks-68040 deleted file mode 100644 index a41c74647..000000000 --- a/configure/os/CONFIG.Common.vxWorks-68040 +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.vxWorks-68040 -# -# Definitions for vxWorks-68040 target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-68040 -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = 68k - -ARCH_CLASS = 68k - -# Architecture specific build flags -ARCH_DEP_CPPFLAGS = -DCPU=MC68040 -ARCH_DEP_CFLAGS = -m68040 - -OPT_CFLAGS_YES = -O0 - -GNU_TARGET = m68k-wrs-vxworks diff --git a/configure/os/CONFIG.Common.vxWorks-68040-debug b/configure/os/CONFIG.Common.vxWorks-68040-debug deleted file mode 100644 index c30a49730..000000000 --- a/configure/os/CONFIG.Common.vxWorks-68040-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-68040-debug -# -# Definitions for vxWorks-68040-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-68040-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-68040 - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-68040lc b/configure/os/CONFIG.Common.vxWorks-68040lc deleted file mode 100644 index 9df4abd51..000000000 --- a/configure/os/CONFIG.Common.vxWorks-68040lc +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.vxWorks-68040lc -# -# Definitions for vxWorks-68040lc target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-68040lc -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = 68k - -ARCH_CLASS = 68k - -# Architecture specific build flags -ARCH_DEP_CPPFLAGS = -DCPU=MC68LC040 -ARCH_DEP_CFLAGS = -m68040 -msoft-float - -OPT_CFLAGS_YES = -O0 - -GNU_TARGET = m68k-wrs-vxworks diff --git a/configure/os/CONFIG.Common.vxWorks-68040lc-debug b/configure/os/CONFIG.Common.vxWorks-68040lc-debug deleted file mode 100644 index 149b01dcd..000000000 --- a/configure/os/CONFIG.Common.vxWorks-68040lc-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-68040lc-debug -# -# Definitions for vxWorks-68040lc-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-68040lc-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-68040lc - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-68060 b/configure/os/CONFIG.Common.vxWorks-68060 deleted file mode 100644 index 312ab61bd..000000000 --- a/configure/os/CONFIG.Common.vxWorks-68060 +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.vxWorks-68060 -# -# Definitions for vxWorks-68060 target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-68060 -#------------------------------------------------------- - -# Include definitions common to all vxWorks target archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = 68k - -ARCH_CLASS = 68k - -# Architecture specific build flags -ARCH_DEP_CPPFLAGS = -DCPU=MC68060 -ARCH_DEP_CFLAGS = -m68040 - -OPT_CFLAGS_YES = -O0 - -GNU_TARGET = m68k-wrs-vxworks diff --git a/configure/os/CONFIG.Common.vxWorks-68060-debug b/configure/os/CONFIG.Common.vxWorks-68060-debug deleted file mode 100644 index 282538457..000000000 --- a/configure/os/CONFIG.Common.vxWorks-68060-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-68060-debug -# -# Definitions for vxWorks-68060-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-68060-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-68060 - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-mpc8540 b/configure/os/CONFIG.Common.vxWorks-mpc8540 deleted file mode 100644 index 451145bde..000000000 --- a/configure/os/CONFIG.Common.vxWorks-mpc8540 +++ /dev/null @@ -1,22 +0,0 @@ -# CONFIG.Common.vxWorks-mpc8540 -# -# Definitions for vxWorks-mpc8540 target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-mpc8540 -#------------------------------------------------------- - -# Include definitions common to all vxWorks target archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -GNU_DIR_5 = $(WIND_BASE)/gnu/3.3/$(WIND_HOST_TYPE) - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = ppc - -ARCH_CLASS = ppc - -# Architecture specific build flags -ARCH_DEP_CPPFLAGS = -DCPU=PPC85XX -ARCH_DEP_CFLAGS = -mcpu=8540 -msoft-float -mspe=no -mabi=no-spe -ARCH_DEP_CFLAGS += -mstrict-align -mlongcall - -GNU_TARGET = powerpc-wrs-vxworks diff --git a/configure/os/CONFIG.Common.vxWorks-mpc8540-debug b/configure/os/CONFIG.Common.vxWorks-mpc8540-debug deleted file mode 100644 index 800478729..000000000 --- a/configure/os/CONFIG.Common.vxWorks-mpc8540-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-mpc8540-debug -# -# Definitions for vxWorks-mpc8540-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-mpc8540-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-mpc8540 - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-mpc8548 b/configure/os/CONFIG.Common.vxWorks-mpc8548 deleted file mode 100644 index d7a759136..000000000 --- a/configure/os/CONFIG.Common.vxWorks-mpc8548 +++ /dev/null @@ -1,23 +0,0 @@ -# CONFIG.Common.vxWorks-mpc8548 -# -# Definitions for vxWorks-mpc8548 target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-mpc8548 -#------------------------------------------------------- - -# Include definitions common to all vxWorks target archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = ppc - -ARCH_CLASS = ppc - -# Architecture specific build flags -ARCH_DEP_CPPFLAGS = -DCPU=PPC32 -ARCH_DEP_CFLAGS = -DCPU_VARIANT=_ppc85XX_e500v2 -ARCH_DEP_CFLAGS += -mlongcall - -# This flag isn't present in early vxWorks 6.x versions -#ARCH_DEP_CFLAGS += -te500v2 - -GNU_TARGET = powerpc-wrs-vxworks diff --git a/configure/os/CONFIG.Common.vxWorks-mpc8548-debug b/configure/os/CONFIG.Common.vxWorks-mpc8548-debug deleted file mode 100644 index 37ae1fa35..000000000 --- a/configure/os/CONFIG.Common.vxWorks-mpc8548-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-mpc8548-debug -# -# Definitions for vxWorks-mpc8548-debug targets. -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-mpc8548-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-mpc8548 - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-pentium b/configure/os/CONFIG.Common.vxWorks-pentium deleted file mode 100644 index 9aee09ca8..000000000 --- a/configure/os/CONFIG.Common.vxWorks-pentium +++ /dev/null @@ -1,21 +0,0 @@ -# CONFIG.Common.vxWorks-pentium -# -# Definitions for vxWorks-pentium target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-pentium -#------------------------------------------------------- - -# Include definitions common to all vxWorks target archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = pentium - -ARCH_CLASS = x86 - -ARCH_DEP_CPPFLAGS = -DCPU=PENTIUM -D_X86_ -ARCH_DEP_CFLAGS = -mtune=pentium -march=pentium -ARCH_DEP_CFLAGS += -fno-zero-initialized-in-bss -fno-defer-pop - -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.Common.vxWorks-pentium - diff --git a/configure/os/CONFIG.Common.vxWorks-pentium-debug b/configure/os/CONFIG.Common.vxWorks-pentium-debug deleted file mode 100644 index f01fe4ce2..000000000 --- a/configure/os/CONFIG.Common.vxWorks-pentium-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-pentium-debug -# -# Definitions for vxWorks-pentium-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-pentium-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-pentium - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-ppc32 b/configure/os/CONFIG.Common.vxWorks-ppc32 deleted file mode 100644 index 4e208b59b..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc32 +++ /dev/null @@ -1,22 +0,0 @@ -# -# Definitions for vxWorks-ppc603 targets with >32MB of RAM -# Site-specific overrides go in CONFIG_SITE.Common.vxWorks-ppc603_long -# -#------------------------------------------------------- - -# Include definitions common to all vxWorks target archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = ppc - -ARCH_CLASS = ppc - -# Architecture specific build flags -ARCH_DEP_CPPFLAGS = -DCPU=PPC32 -ARCH_DEP_CFLAGS = -mstrict-align - -GNU_TARGET = powerpc-wrs-vxworks - -# Tell compiler to generate long branches -ARCH_DEP_CFLAGS += -mlongcall diff --git a/configure/os/CONFIG.Common.vxWorks-ppc32-debug b/configure/os/CONFIG.Common.vxWorks-ppc32-debug deleted file mode 100644 index 5c7907f25..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc32-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-ppc32-debug -# -# Definitions for vxWorks-ppc32-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc32-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc32 - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-ppc32sf b/configure/os/CONFIG.Common.vxWorks-ppc32sf deleted file mode 100644 index 26e0cc218..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc32sf +++ /dev/null @@ -1,11 +0,0 @@ -# -# Definitions for vxWorks-ppc32sf targets -# Site-specific overrides go in CONFIG_SITE.Common.vxWorks-ppc32sf -# -#------------------------------------------------------- - -# Inherit the settings from vxWorks-ppc32 -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc32 - -# Tell compiler to use software floating-point -ARCH_DEP_CFLAGS += -msoft-float diff --git a/configure/os/CONFIG.Common.vxWorks-ppc32sf-debug b/configure/os/CONFIG.Common.vxWorks-ppc32sf-debug deleted file mode 100644 index e8d5aea3f..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc32sf-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-ppc32sf-debug -# -# Definitions for vxWorks-ppc32sf-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc32sf-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc32sf - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-ppc603 b/configure/os/CONFIG.Common.vxWorks-ppc603 deleted file mode 100644 index 3b0e73b3d..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc603 +++ /dev/null @@ -1,19 +0,0 @@ -# -# Definitions for vxWorks-ppc603 targets: PPC603 and PMC8240 CPUs -# Site-specific overrides go in CONFIG_SITE.Common.vxWorks-ppc603 -# -#------------------------------------------------------- - -# Include definitions common to all vxWorks target archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = ppc - -ARCH_CLASS = ppc - -# Architecture specific build flags -ARCH_DEP_CPPFLAGS = -DCPU=PPC603 -ARCH_DEP_CFLAGS = -mcpu=603 -mstrict-align - -GNU_TARGET = powerpc-wrs-vxworks diff --git a/configure/os/CONFIG.Common.vxWorks-ppc603-debug b/configure/os/CONFIG.Common.vxWorks-ppc603-debug deleted file mode 100644 index 0e4157955..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc603-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-ppc603-debug -# -# Definitions for vxWorks-ppc603-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc603-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603 - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-ppc603_long b/configure/os/CONFIG.Common.vxWorks-ppc603_long deleted file mode 100644 index 4a61eef14..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc603_long +++ /dev/null @@ -1,11 +0,0 @@ -# -# Definitions for vxWorks-ppc603 targets with >32MB of RAM -# Site-specific overrides go in CONFIG_SITE.Common.vxWorks-ppc603_long -# -#------------------------------------------------------- - -# Inherit the settings from vxWorks-ppc603 -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603 - -# Tell compiler to generate long branches -ARCH_DEP_CFLAGS += -mlongcall diff --git a/configure/os/CONFIG.Common.vxWorks-ppc603_long-debug b/configure/os/CONFIG.Common.vxWorks-ppc603_long-debug deleted file mode 100644 index 7eab4376f..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc603_long-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-ppc603_long-debug -# -# Definitions for vxWorks-ppc603_long-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc603_long-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc603_long - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-ppc604 b/configure/os/CONFIG.Common.vxWorks-ppc604 deleted file mode 100644 index 45115a876..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc604 +++ /dev/null @@ -1,22 +0,0 @@ -# -# Definitions for vxWorks-ppc604 targets: PPC604, MPC7xx and MPC74xx CPUs -# Site-specific overrides go in CONFIG_SITE.Common.vxWorks-ppc604 -# -#------------------------------------------------------- - -# Include definitions common to all vxWorks target archs -include $(CONFIG)/os/CONFIG.Common.vxWorksCommon - -# Vx GNU cross compiler suffix -CMPLR_SUFFIX = ppc - -ARCH_CLASS = ppc - -# Architecture specific build flags -ARCH_DEP_CPPFLAGS = -DCPU=PPC604 -ARCH_DEP_CFLAGS_2 = -mcpu=604 -mstrict-align -mno-implicit-fp -ARCH_DEP_CFLAGS_3 = -mcpu=604 -mstrict-align -mno-implicit-fp -ARCH_DEP_CFLAGS_4 = -mcpu=604 -mstrict-align -fno-implicit-fp -ARCH_DEP_CFLAGS = $(ARCH_DEP_CFLAGS_$(VX_GNU_MAJOR_VERSION)) - -GNU_TARGET = powerpc-wrs-vxworks diff --git a/configure/os/CONFIG.Common.vxWorks-ppc604-debug b/configure/os/CONFIG.Common.vxWorks-ppc604-debug deleted file mode 100644 index ac66b68aa..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc604-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-ppc604-debug -# -# Definitions for vxWorks-ppc604-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc604-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604 - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-ppc604_altivec b/configure/os/CONFIG.Common.vxWorks-ppc604_altivec deleted file mode 100644 index d0becf2f7..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc604_altivec +++ /dev/null @@ -1,20 +0,0 @@ -# -# Definitions for vxWorks-ppc604 targets with an Altivec and >32MB of RAM. -# Site-specific overrides go in CONFIG_SITE.Common.vxWorks-ppc604_altivec -# -#------------------------------------------------------- - -# Inherit the settings from vxWorks-ppc604_long -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long - -defval = $(if $(strip $(1),),$(1),$(2)) - -# Tell compiler to include altivec support; not available in 5.4 -ALTIVEC_CFLAG_5.4 = THIS_VERSION_OF_VXWORKS DOES_NOT_SUPPORT_ALTIVEC -ALTIVEC_CFLAG_5.5 = -fvec -DALTIVEC -ALTIVEC_CFLAG_6.0 = -fvec -DALTIVEC - -# From 6.1 onwards the compiler option changed -ALTIVEC_CFLAG = -maltivec -DALTIVEC - -ARCH_DEP_CFLAGS += $(call defval,$(ALTIVEC_CFLAG_$(VXWORKS_VERSION)),$(ALTIVEC_CFLAG)) diff --git a/configure/os/CONFIG.Common.vxWorks-ppc604_altivec-debug b/configure/os/CONFIG.Common.vxWorks-ppc604_altivec-debug deleted file mode 100644 index b7e1307a5..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc604_altivec-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-ppc604_altivec-debug -# -# Definitions for vxWorks-ppc604_altivec-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc604_altivec-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_altivec - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorks-ppc604_long b/configure/os/CONFIG.Common.vxWorks-ppc604_long deleted file mode 100644 index a90cc897b..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc604_long +++ /dev/null @@ -1,11 +0,0 @@ -# -# Definitions for vxWorks-ppc604 targets with >32MB of RAM -# Site-specific overrides go in CONFIG_SITE.Common.vxWorks-ppc604_long -# -#------------------------------------------------------- - -# Inherit the settings from vxWorks-ppc604 -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604 - -# Tell compiler to generate long branches -ARCH_DEP_CFLAGS += -mlongcall diff --git a/configure/os/CONFIG.Common.vxWorks-ppc604_long-debug b/configure/os/CONFIG.Common.vxWorks-ppc604_long-debug deleted file mode 100644 index fa6bfe8f8..000000000 --- a/configure/os/CONFIG.Common.vxWorks-ppc604_long-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.Common.vxWorks-ppc604_long-debug -# -# Definitions for vxWorks-ppc604_long-debug target archs -# Sites may override these definitions in CONFIG_SITE.Common.vxWorks-ppc604_long-debug -#------------------------------------------------------- - -# Include definitions common to all vxWorks archs -include $(CONFIG)/os/CONFIG.Common.vxWorks-ppc604_long - -CROSS_OPT = NO - diff --git a/configure/os/CONFIG.Common.vxWorksCommon b/configure/os/CONFIG.Common.vxWorksCommon deleted file mode 100644 index 1ad5b5808..000000000 --- a/configure/os/CONFIG.Common.vxWorksCommon +++ /dev/null @@ -1,184 +0,0 @@ -# CONFIG.Common.vxWorksCommon -# -# Definitions for vxWorks target archs -# Override these definitions in CONFIG_SITE.Common.vxWorksCommon -# or CONFIG_SITE..vxWorksCommon -#------------------------------------------------------- - -# Vx valid build types -VALID_BUILDS = Ioc - -#-------------------------------------------------- -# operating system class (include/os/) -OS_CLASS = vxWorks - -#------------------------------------------------------- -# Prefix and suffix definitions -EXE = -OBJ = .o -LIB_PREFIX = lib -LIB_SUFFIX = .a -MUNCH_SUFFIX = .munch - -#------------------------------------------------------- -# Compiler definitions -CMPLR_PREFIX= -CC = $(GNU_BIN)/$(CMPLR_PREFIX)cc$(CMPLR_SUFFIX) -CCC = $(GNU_BIN)/$(CMPLR_PREFIX)cc$(CMPLR_SUFFIX) - -#------------------------------------------------------- -# Library definitions -LIBNAME = $(BUILD_LIBRARY:%=$(LIB_PREFIX)%$(LIB_SUFFIX)) -TESTLIBNAME = $(TESTBUILD_LIBRARY:%=$(LIB_PREFIX)%$(LIB_SUFFIX)) - -#-------------------------------------------------- -# Prod: DEPLIBS, LDFLAGS, and LDLIBS definitions - -PROD_DEPLIBS = $(foreach lib,$(PROD_LIBS) $(USR_LIBS), \ - $(firstword $(wildcard \ - $(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS))) \ - $(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \ - $(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB))))) - - -PROD_LDLIBS = $(addprefix -l,$($*_LDLIBS) $(PROD_LIBS) $(USR_LIBS) \ - $($*_SYS_LIBS) $(PROD_SYS_LIBS) $(USR_SYS_LIBS)) - -PROD_DEPLIB_DIRS = $(dir $($*_DEPLIBS)) $(dir $(PROD_DEPLIBS)) -PRODDIR_LDFLAGS += $(sort $(PROD_DEPLIB_DIRS:%=-L%)) - -#------------------------------------------------------- -# Prod definitions -MUNCHNAME = $(PRODNAME:%$(EXE)=%$(MUNCH_SUFFIX)) -CTDT_SRCS = $(PRODNAME:%$(EXE)=%_ctdt.c) -CTDT_OBJS = $(PRODNAME:%$(EXE)=%_ctdt$(OBJ)) -NMS = $(PRODNAME:%$(EXE)=%.nm) -MUNCH_DEPENDS = %_ctdt$(OBJ) - -#-------------------------------------------------- -# vxWorks version numbers - -VXWORKS_MAJOR_VERSION = $(basename $(basename $(VXWORKS_VERSION))) - -# These are needed for vxWorks 6.x; the GNU toolset version number -# is in the path to the compiler tools: -VX_GNU_VERSION_6.0 = 3.3.2 -VX_GNU_VERSION_6.1 = 3.3.2 -VX_GNU_VERSION_6.2 = 3.3.2 -VX_GNU_VERSION_6.3 = 3.4.4 -VX_GNU_VERSION_6.4 = 3.4.4 -VX_GNU_VERSION_6.5 = 3.4.4 -VX_GNU_VERSION_6.6 = 4.1.2 -VX_GNU_VERSION_6.7 = 4.1.2 -VX_GNU_VERSION_6.8 = 4.1.2 -VX_GNU_VERSION_6.9 = 4.3.3 -VX_GNU_VERSION = $(VX_GNU_VERSION_$(VXWORKS_VERSION)) - -VX_GNU_MAJOR_VERSION = $(basename $(basename $(VX_GNU_VERSION))) - -#-------------------------------------------------- -# Fix old Linux WIND_HOST_TYPE -ifeq ($(WIND_HOST_TYPE),x86-linux) - WIND_HOST_TYPE = x86-linux2 -endif - -#-------------------------------------------------- -# vxWorks directory definitions -VX_DIR = $(WIND_BASE)/vxworks-$(VXWORKS_VERSION) - -GNU_TARGET_INCLUDE_DIR = $(VX_DIR)/target/h $(VX_DIR)/target/h/wrn/coreip - -#-------------------------------------------------- -# vxWorks GNU directories - -GNU_DIR = $(WIND_BASE)/gnu/$(VX_GNU_VERSION)-vxworks-$(VXWORKS_VERSION)/$(WIND_HOST_TYPE) - -#-------------------------------------------------- -# Wind River moved nm out of GNU_BIN in some versions - -WORKBENCH_BIN = $(WIND_BASE)/workbench-$(WORKBENCH_VERSION)/$(WIND_HOST_TYPE)/bin -UTILITIES_BIN = $(WIND_BASE)/utilities-$(UTILITIES_VERSION)/$(WIND_HOST_TYPE)/bin - -NM_DIR_6.4 = $(WORKBENCH_BIN) -NM_DIR_6.5 = $(WORKBENCH_BIN) -NM_DIR_6.6 = $(WORKBENCH_BIN) -NM_DIR_6.7 = $(GNU_BIN) -NM_DIR_6.8 = $(UTILITIES_BIN) -NM_DIR_6.9 = $(UTILITIES_BIN) -NM_DIR = $(firstword $(NM_DIR_$(VXWORKS_VERSION)) $(GNU_BIN)) - -NM = $(NM_DIR)/$(CMPLR_PREFIX)nm$(CMPLR_SUFFIX)$(HOSTEXE) - -#-------------------------------------------------- -# A linker script is essential for munching from vxWorks 6.6 onwards -# (i.e. with versions that use gcc 4.1.2 or later). -MUNCH_LDFLAGS_6 = -T $(VX_DIR)/target/h/tool/gnu/ldscripts/link.OUT -MUNCH_LDFLAGS = $(MUNCH_LDFLAGS_$(VXWORKS_MAJOR_VERSION)) - -#-------------------------------------------------- -# These are required by some of the Wind River tools -export WIND_BASE -export WIND_HOST_TYPE -export TOOL_FAMILY = GNU - -#-------------------------------------------------- -# Operating system flags -OP_SYS_CPPFLAGS += -DvxWorks=vxWorks -OP_SYS_CFLAGS += -fno-builtin - -# Fix for vxWorks headers that use macros defined in vxWorks.h but -# which don't actually include vxWorks.h themselves, for example the -# target/h/sys/stat.h file which uses ULONG. This also stops dbDefs.h -# from defining the OFFSET macro, which generates lots of warnings. -OP_SYS_INCLUDE_CPPFLAGS += -include $(VX_DIR)/target/h/vxWorks.h - -#-------------------------------------------------- -# Optimization: Officially vxWorks only supports -O2 or less. -OPT_CFLAGS_YES = -O2 -OPT_CXXFLAGS_YES = -O2 - -#-------------------------------------------------- -# code flags -CODE_CFLAGS = -# -# For vxWorks versions before 6.3 we need this g++ compiler flag -CODE_CXXFLAGS_6.0 = -fno-implicit-templates -CODE_CXXFLAGS_6.1 = -fno-implicit-templates -CODE_CXXFLAGS_6.2 = -fno-implicit-templates -CODE_CXXFLAGS_6 = $(CODE_CXXFLAGS_$(VXWORKS_VERSION)) -CODE_CXXFLAGS = $(CODE_CXXFLAGS_$(VXWORKS_MAJOR_VERSION)) - -#-------------------------------------------------- -# no shared libs for vxWorks -SHRLIB_CFLAGS = -SHRLIB_LDFLAGS = - -#-------------------------------------------------- -# Earlier versions of gcc don't understand -MF -HDEPENDS_COMPFLAGS = -MM > $@ - -#-------------------------------------------------- -# osithead use default stack, YES or NO override -OSITHREAD_USE_DEFAULT_STACK = NO - -#-------------------------------------------------- -# Link definitions -LINK.cpp = $(LD) -o $@ $(STATIC_LDFLAGS) $(PRODDIR_LDFLAGS) $(LDFLAGS) -LINK.cpp += $(PROD_LDFLAGS) $(PROD_LD_OBJS) $(PROD_LD_RESS) $(PROD_LDLIBS) - -#-------------------------------------------------- -# Definitions for compile of *_ctdt.c file -CFLAGS_ctdt = $(filter-out -pedantic,$(CFLAGS)) -fdollars-in-identifiers -COMPILE.ctdt = $(CC) -c $(CPPFLAGS) $(CFLAGS_ctdt) $(INCLUDES) $(SOURCE_FLAG) - -#-------------------------------------------------- -# C preprocessor command -VXCPPFLAGS = $(filter-out $(OP_SYS_INCLUDE_CPPFLAGS),$(CPPFLAGS)) -PREPROCESS.cpp = $(CPP) $(VXCPPFLAGS) $(INCLUDES) $< > $@ - -#-------------------------------------------------- -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.Common.vxWorksCommon --include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).vxWorksCommon - diff --git a/configure/os/CONFIG.Common.win32-x86-mingw b/configure/os/CONFIG.Common.win32-x86-mingw deleted file mode 100644 index 936b1d954..000000000 --- a/configure/os/CONFIG.Common.win32-x86-mingw +++ /dev/null @@ -1,86 +0,0 @@ -# CONFIG.Common.win32-x86-mingw -# -# Definitions for win32-x86-mingw target builds -# Sites may override these definitions in CONFIG_SITE.Common.win32-x86-mingw -#------------------------------------------------------- - -# Include definitions common to all Unix targets -include $(CONFIG)/os/CONFIG.Common.UnixCommon - -OS_CLASS = WIN32 -ARCH_CLASS = x86 -POSIX = NO - -# Definitions used when COMMANDLINE_LIBRARY is READLINE -LDLIBS_READLINE = -lreadline -lcurses - -ARCH_DEP_CFLAGS += -m32 -ARCH_DEP_LDFLAGS += -m32 - -# Compiler defines _X86_ 1 -# Compiler defines __MSVCRT__ 1 -# Compiler defines __MINGW32__ 1 -# Compiler defines __WIN32 1 -# Compiler defines __WINNT 1 -# Compiler defines __WINNT__ 1 -# Compiler defines __WIN32__ 1 -# Compiler defines _WIN32 1 -# Compiler defines WIN32 1 -# Compiler defines WINNT 1 -# Compiler does not define __unix __unix__ unix - -# Override for -DUNIX from CONFIG.Common.UnixCommon -OP_SYS_CPPFLAGS = -D_MINGW - -EXE = .exe -RES = .coff - -# Use .o for static object files, .obj for shared library object files -OBJ_NO = .o -OBJ_YES = .obj -OBJ = $(OBJ_$(SHARED_LIBRARIES)) - -COMPILE.c += $(if $(filter %$(OBJ),$@),-o $@) -COMPILE.cpp += $(if $(filter %$(OBJ),$@),-o $@) -HDEPENDS_ARCHFLAGS = -MT $*$(OBJ) - -BUILD_DLL_CFLAGS_YES = -DEPICS_BUILD_DLL -BUILD_DLL_CFLAGS_NO = -BUILD_DLL_CFLAGS = $(BUILD_DLL_CFLAGS_$(SHARED_LIBRARIES)) -STATIC_CFLAGS_YES = $(BUILD_DLL_CFLAGS) -STATIC_CFLAGS_NO = $(BUILD_DLL_CFLAGS) -DEPICS_CALL_DLL -STATIC_CXXFLAGS_YES = $(BUILD_DLL_CFLAGS) -STATIC_CXXFLAGS_NO = $(BUILD_DLL_CFLAGS) -DEPICS_CALL_DLL - -# Adjust the names of the libraries to build -# -# When SHARED_LIBRARIES is YES we build a DLL and its stub library -# -SHRLIB_PREFIX = -SHRLIB_SUFFIX_BASE = .dll -SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE) -SHRLIBNAME_YES = $(BUILD_LIBRARY:%=%$(SHRLIB_SUFFIX)) -TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX_BASE)) -LOADABLE_SHRLIB_PREFIX = -LOADABLE_SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE) -LOADABLE_SHRLIBNAME = $(LOADABLE_BUILD_LIBRARY:%=%$(LOADABLE_SHRLIB_SUFFIX)) - -DLLSTUB_PREFIX = lib -DLLSTUB_SUFFIX = .dll.a -DLLSTUB_LIBNAME_YES = $(BUILD_LIBRARY:%=$(DLLSTUB_PREFIX)%$(DLLSTUB_SUFFIX)) -DLLSTUB_LIBNAME = $(DLLSTUB_LIBNAME_$(SHARED_LIBRARIES)) -TESTDLLSTUB_LIBNAME_YES = $(TESTBUILD_LIBRARY:%=$(DLLSTUB_PREFIX)%$(DLLSTUB_SUFFIX)) -TESTDLLSTUB_LIBNAME = $(TESTDLLSTUB_LIBNAME_$(SHARED_LIBRARIES)) - -# When SHARED_LIBRARIES is NO we build a static archive library -# -LIB_PREFIX = -LIB_SUFFIX = .lib -LIBNAME_NO = $(BUILD_LIBRARY:%=%$(LIB_SUFFIX)) -LIBNAME = $(LIBNAME_$(SHARED_LIBRARIES)) -TESTLIBNAME_NO = $(TESTBUILD_LIBRARY:%=%$(LIB_SUFFIX)) -TESTLIBNAME = $(TESTLIBNAME_$(SHARED_LIBRARIES)) - -# dll install location -INSTALL_SHRLIB = $(INSTALL_BIN) - diff --git a/configure/os/CONFIG.Common.windows-x64-mingw b/configure/os/CONFIG.Common.windows-x64-mingw deleted file mode 100644 index c2623bd39..000000000 --- a/configure/os/CONFIG.Common.windows-x64-mingw +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.Common.windows-x64-mingw -# -# Definitions for windows-x64-mingw target builds -# Sites may override these definitions in CONFIG_SITE.Common.windows-x64-mingw -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.Common.win32-x86-mingw - -ARCH_CLASS = x64 - -ARCH_DEP_CFLAGS = -m64 -ARCH_DEP_LDFLAGS = -m64 diff --git a/configure/os/CONFIG.UnixCommon.Common b/configure/os/CONFIG.UnixCommon.Common deleted file mode 100644 index 026a5234d..000000000 --- a/configure/os/CONFIG.UnixCommon.Common +++ /dev/null @@ -1,16 +0,0 @@ -# CONFIG.UnixCommon.Common -# -# Definitions common to unix hosts -# Sites may override these definitions in CONFIG_SITE.UnixCommon.Common -#------------------------------------------------------- - -# Unix command definitions -CP = cp -MV = mv -RM = rm -f -MKDIR = mkdir -p -RMDIR = rm -rf -CAT = cat - -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.UnixCommon.Common diff --git a/configure/os/CONFIG.cygwin-x86.Common b/configure/os/CONFIG.cygwin-x86.Common deleted file mode 100644 index 1fffc7b4c..000000000 --- a/configure/os/CONFIG.cygwin-x86.Common +++ /dev/null @@ -1,17 +0,0 @@ -# CONFIG.cygwin-x86.Common -# -# Definitions for cygwin-x86 host archs -# Sites may override these definitions in CONFIG_SITE.cygwin-x86.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -WIND_HOST_TYPE = x86-win32 -OSITHREAD_USE_DEFAULT_STACK = NO - -HOSTEXE=.exe - -# Needed to find dlls for base installed build tools (antelope,eflex,...) -PATH := $(EPICS_BASE_BIN):$(PATH) - diff --git a/configure/os/CONFIG.cygwin-x86.cygwin-x86 b/configure/os/CONFIG.cygwin-x86.cygwin-x86 deleted file mode 100644 index 965a524aa..000000000 --- a/configure/os/CONFIG.cygwin-x86.cygwin-x86 +++ /dev/null @@ -1,27 +0,0 @@ -# CONFIG.cygwin-x86.cygwin-x86 -# -# Definitions for cygwin-x86 host - cygwin-x86 target builds -# Sites may override these definitions in CONFIG_SITE.cygwin-x86.cygwin-x86 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -# cygwin's gcc, g++, ar, ld, and ranlib must be in user's path -CC = gcc -CCC = g++ -AR = ar -rc -LD = ld -r -RANLIB = ranlib -RES=.coff -RCCMD = windres $(INCLUDES) $< $@ - -# No -fPIC avoids "-fPIC ignored for target (all code is position independent)" -SHRLIB_CFLAGS = -SHRLIB_LDFLAGS = -shared -Wl,--out-implib,$(LIB_PREFIX)$*$(LIB_SUFFIX) -LOADABLE_SHRLIB_LDFLAGS = -shared -Wl,--out-implib,$(LIB_PREFIX)$*$(LIB_SUFFIX) - -# Override linking with gcc library from CONFIG.gnuCommon -GNU_LDLIBS_YES = - - diff --git a/configure/os/CONFIG.cygwin-x86.cygwin-x86-debug b/configure/os/CONFIG.cygwin-x86.cygwin-x86-debug deleted file mode 100644 index d51734542..000000000 --- a/configure/os/CONFIG.cygwin-x86.cygwin-x86-debug +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG.cygwin-x86.cygwin-x86-debug -# -# Definitions for cygwin-x86 host - cygwin-x86-debug target build -# Sites may override these definitions in CONFIG_SITE.cygwin-x86.cygwin-x86-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.Common.cygwin-x86 --include $(CONFIG)/os/CONFIG.cygwin-x86.cygwin-x86 --include $(CONFIG)/os/CONFIG_SITE.Common.cygwin-x86 --include $(CONFIG)/os/CONFIG_SITE.cygwin-x86.cygwin-x86 - -BUILD_CLASS = HOST - -HOST_OPT = NO diff --git a/configure/os/CONFIG.cygwin-x86.linux-arm b/configure/os/CONFIG.cygwin-x86.linux-arm deleted file mode 100644 index 464565f95..000000000 --- a/configure/os/CONFIG.cygwin-x86.linux-arm +++ /dev/null @@ -1,33 +0,0 @@ -# CONFIG.cygwin-x86.linux-arm -# -# Definitions for cywgin-x86 host - linux-arm target builds -# Override these settings in CONFIG_SITE.cygwin-x86.linux-arm -#------------------------------------------------------- - -VALID_BUILDS = Ioc -GNU_TARGET = arm-linux - -# prefix of compiler tools -CMPLR_SUFFIX = -CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET)) - -# Provide a link-time path for shared libraries -SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath-link,%) -SHRLIBDIR_LDFLAGS += $(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Provide a link-time path for products -PRODDIR_RPATH_LDFLAGS_YES += $(PROD_DEPLIB_DIRS:%=-Wl,-rpath-link,%) -PRODDIR_LDFLAGS += $(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Provide a link-time path for readline -RUNTIME_LDFLAGS_READLINE_YES = -Wl,-rpath-link,$(GNU_DIR)/lib -RUNTIME_LDFLAGS_READLINE = $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)) -RUNTIME_LDFLAGS_READLINE_CURSES = $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)) -RUNTIME_LDFLAGS_READLINE_NCURSES = $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)) - -# Library flags -STATIC_LDFLAGS_YES= -Wl,-Bstatic -STATIC_LDFLAGS_NO= -STATIC_LDLIBS_YES= -Wl,-Bdynamic -STATIC_LDLIBS_NO= - diff --git a/configure/os/CONFIG.cygwin-x86_64.Common b/configure/os/CONFIG.cygwin-x86_64.Common deleted file mode 100644 index de43b592e..000000000 --- a/configure/os/CONFIG.cygwin-x86_64.Common +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG.cygwin-x86_64.Common -# -# Definitions for cygwin-x86_64 host archs -# Sites may override these definitions in CONFIG_SITE.cygwin-x86_64.Common -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.cygwin-x86.Common diff --git a/configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64 b/configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64 deleted file mode 100644 index 0e9a96f01..000000000 --- a/configure/os/CONFIG.cygwin-x86_64.cygwin-x86_64 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.cygwin-x86_64.cygwin-x86_64 -# -# Definitions for cygwin-x86_64 host - cygwin-x86_64 target builds -# Sites may override these definitions in CONFIG_SITE.cygwin-x86_64.cygwin-x86_64 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/os/CONFIG.cygwin-x86.cygwin-x86 - diff --git a/configure/os/CONFIG.cygwin-x86_64.linux-arm b/configure/os/CONFIG.cygwin-x86_64.linux-arm deleted file mode 100644 index f7f37b8e6..000000000 --- a/configure/os/CONFIG.cygwin-x86_64.linux-arm +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG.cygwin-x86_64.linux-arm -# -# Definitions for cygwin-x86_64 host - linux-arkm targets -# Override these settings in CONFIG_SITE.cygwin-x86_64.linux-arm -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.cygwin-x86.linux-arm diff --git a/configure/os/CONFIG.darwin-ppc.Common b/configure/os/CONFIG.darwin-ppc.Common deleted file mode 100644 index ac176878f..000000000 --- a/configure/os/CONFIG.darwin-ppc.Common +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.darwin-ppc.Common -# -# Definitions for darwin-ppc host builds -# Sites may override these definitions in CONFIG_SITE.darwin-ppc.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common diff --git a/configure/os/CONFIG.darwin-ppc.darwin-ppc-debug b/configure/os/CONFIG.darwin-ppc.darwin-ppc-debug deleted file mode 100644 index 985052031..000000000 --- a/configure/os/CONFIG.darwin-ppc.darwin-ppc-debug +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG.darwin-ppc.darwin-ppc-debug -# -# Definitions for darwin-ppc host - darwin-ppc-debug target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.darwin-ppc.darwin-ppc-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.Common.darwin-ppc --include $(CONFIG)/os/CONFIG.darwin-ppc.darwin-ppc --include $(CONFIG)/os/CONFIG_SITE.Common.darwin-ppc --include $(CONFIG)/os/CONFIG_SITE.darwin-ppc.darwin-ppc - -BUILD_CLASS=HOST -HOST_OPT = NO diff --git a/configure/os/CONFIG.darwin-ppcx86.Common b/configure/os/CONFIG.darwin-ppcx86.Common deleted file mode 100644 index 749835ced..000000000 --- a/configure/os/CONFIG.darwin-ppcx86.Common +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.darwin-ppcx86.Common -# -# Definitions for Darwin universal PowerPC + x86 host builds -# Sites may override these definitions in CONFIG_SITE.darwin-ppcx86.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common diff --git a/configure/os/CONFIG.darwin-x86.Common b/configure/os/CONFIG.darwin-x86.Common deleted file mode 100644 index e779f7dc1..000000000 --- a/configure/os/CONFIG.darwin-x86.Common +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.darwin-x86.Common -# -# Definitions for darwin-x86 host builds -# Sites may override these definitions in CONFIG_SITE.darwin-x86.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common diff --git a/configure/os/CONFIG.darwin-x86.darwin-x86-debug b/configure/os/CONFIG.darwin-x86.darwin-x86-debug deleted file mode 100644 index 3bf4db63f..000000000 --- a/configure/os/CONFIG.darwin-x86.darwin-x86-debug +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG.darwin-x86.darwin-x86-debug -# -# Definitions for darwin-x86 host - darwin-x86-debug target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.darwin-x86.darwin-x86-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.Common.darwin-x86 --include $(CONFIG)/os/CONFIG.darwin-x86.darwin-x86 --include $(CONFIG)/os/CONFIG_SITE.Common.darwin-x86 --include $(CONFIG)/os/CONFIG_SITE.darwin-x86.darwin-x86 - - -BUILD_CLASS=HOST -HOST_OPT = NO diff --git a/configure/os/CONFIG.darwinCommon.darwinCommon b/configure/os/CONFIG.darwinCommon.darwinCommon deleted file mode 100644 index 56b539545..000000000 --- a/configure/os/CONFIG.darwinCommon.darwinCommon +++ /dev/null @@ -1,98 +0,0 @@ -# CONFIG.darwinCommon.darwinCommon -# -# Common definitions for darwin builds -# Sites may override these definitions in CONFIG_SITE.darwinCommon.darwinCommon -#------------------------------------------------------- - -# Include definitions common to all Unix targets -include $(CONFIG)/os/CONFIG.Common.UnixCommon - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -# -# Set OS-specific information -# -OS_CLASS = Darwin - -# -# Build architecture flags -# For Darwin, ARCH_CLASS may be empty, or may contain a list of CPU -# architectures which must be valid arguments to the -arch options -# for the cc and ld commands. -# ARCH_CLASS is defined in a CONFIG_SITE file which is not loaded -# until after this file. -# -ARCH_DEP_FLAGS = $(addprefix -arch ,$(ARCH_CLASS)) -ARCH_DEP_CFLAGS += $(ARCH_DEP_FLAGS) -ARCH_DEP_LDFLAGS += $(ARCH_DEP_FLAGS) - -# -# Special flags for Darwin -# No common blocks (as required when using shared libraries) -# -OP_SYS_CFLAGS += -fno-common - -# -# Darwin os definition -# -OP_SYS_CPPFLAGS += -Ddarwin - -# -# Always compile in debugging symbol table information -# -OPT_CFLAGS_YES += -g -OPT_CXXFLAGS_YES += -g - -# -# Libraries for command-line editing. -# -LDLIBS_READLINE = -lreadline - -# -# Command-line input support -# -COMMANDLINE_LIBRARY=READLINE - -GNU_DIR = /usr - -# Apple soft-links these compilers to clang/clang++ -CMPLR_CLASS = clang -CC = cc -CCC = c++ -GNU = NO - -# -# Darwin shared libraries -# -SHRLIB_LDFLAGS = -dynamiclib -flat_namespace -undefined suppress \ - -install_name $(shell $(FULLPATHNAME) $(INSTALL_LIB))/$@ \ - $(addprefix -compatibility_version , $(SHRLIB_VERSION)) \ - $(addprefix -current_version , $(SHRLIB_VERSION)) -SHRLIB_SUFFIX_BASE = .dylib -SHRLIB_SUFFIX = $(addprefix ., $(SHRLIB_VERSION))$(SHRLIB_SUFFIX_BASE) - -LOADABLE_SHRLIB_LDFLAGS = -bundle -flat_namespace -undefined suppress - -# -# Position-independent code is the default on Darwin. -# -CODE_CFLAGS = -CODE_CXXFLAGS = - -# -# Add support for Objective-C source -# -vpath %.m $(USR_VPATH) $(ALL_SRC_DIRS) -%.o: %.m - $(COMPILE.c) -c $< - -# -# Header dependency file generation -# -HDEPENDS_METHOD = MKMF - -#-------------------------------------------------- -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.darwinCommon.darwinCommon --include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).darwinCommon diff --git a/configure/os/CONFIG.freebsd-x86.Common b/configure/os/CONFIG.freebsd-x86.Common deleted file mode 100644 index 1bd10de2d..000000000 --- a/configure/os/CONFIG.freebsd-x86.Common +++ /dev/null @@ -1,7 +0,0 @@ -# -# Definitions for freebsd host builds -# Sites may override these definitions in CONFIG_SITE.freebsd-x86.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common diff --git a/configure/os/CONFIG.freebsd-x86.freebsd-x86 b/configure/os/CONFIG.freebsd-x86.freebsd-x86 deleted file mode 100644 index b5e2bcff4..000000000 --- a/configure/os/CONFIG.freebsd-x86.freebsd-x86 +++ /dev/null @@ -1,13 +0,0 @@ -# -# Definitions for freebsd-x86 host - freebsd-x86 target builds -# Sites may override these definitions in CONFIG_SITE.freebsd-x86.freebsd-x86 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -STATIC_LDFLAGS_YES= -Wl,-Bstatic -STATIC_LDFLAGS_NO= -STATIC_LDLIBS_YES= -Wl,-Bdynamic -STATIC_LDLIBS_NO= - diff --git a/configure/os/CONFIG.freebsd-x86_64.Common b/configure/os/CONFIG.freebsd-x86_64.Common deleted file mode 100644 index 397bf12f6..000000000 --- a/configure/os/CONFIG.freebsd-x86_64.Common +++ /dev/null @@ -1,8 +0,0 @@ -# -# Definitions for freebsd host builds -# Sites may override these definitions in CONFIG_SITE.freebsd-x86_64.Common -#------------------------------------------------------- - -# Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - diff --git a/configure/os/CONFIG.freebsd-x86_64.freebsd-x86_64 b/configure/os/CONFIG.freebsd-x86_64.freebsd-x86_64 deleted file mode 100644 index dcc8888ce..000000000 --- a/configure/os/CONFIG.freebsd-x86_64.freebsd-x86_64 +++ /dev/null @@ -1,13 +0,0 @@ -# -# Definitions for freebsd-x86_64 host - freebsd-x86_64 target builds -# Sites may override these definitions in CONFIG_SITE.freebsd-x86_64.freebsd-x86_64 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -STATIC_LDFLAGS_YES= -Wl,-Bstatic -STATIC_LDFLAGS_NO= -STATIC_LDLIBS_YES= -Wl,-Bdynamic -STATIC_LDLIBS_NO= - diff --git a/configure/os/CONFIG.linux-386.Common b/configure/os/CONFIG.linux-386.Common deleted file mode 100644 index 9a3633bdf..000000000 --- a/configure/os/CONFIG.linux-386.Common +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.linux-386.Common -# -# Definitions for linux-386 host builds -# Sites may override these definitions in CONFIG_SITE.linux-386.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -WIND_HOST_TYPE = x86-linux2 diff --git a/configure/os/CONFIG.linux-386.linux-386 b/configure/os/CONFIG.linux-386.linux-386 deleted file mode 100644 index f65ac46b7..000000000 --- a/configure/os/CONFIG.linux-386.linux-386 +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.linux-386.linux-386 -# -# Definitions for linux-386 host - linux-386 target builds -# Sites may override these definitions in CONFIG_SITE.linux-386.linux-386 -#------------------------------------------------------- - -# Include linux-x86 compiler definitions -include $(CONFIG)/os/CONFIG.linux-x86.linux-x86 diff --git a/configure/os/CONFIG.linux-486.Common b/configure/os/CONFIG.linux-486.Common deleted file mode 100644 index c151b3218..000000000 --- a/configure/os/CONFIG.linux-486.Common +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.linux-486.Common -# -# Definitions for linux-486 host builds -# Sites may override these definitions in CONFIG_SITE.linux-486.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -WIND_HOST_TYPE = x86-linux2 diff --git a/configure/os/CONFIG.linux-486.linux-486 b/configure/os/CONFIG.linux-486.linux-486 deleted file mode 100644 index 551cacc29..000000000 --- a/configure/os/CONFIG.linux-486.linux-486 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-486.linux-486 -# -# Definitions for linux-486 host - linux-486 target builds -# Sites may override these definitions in CONFIG_SITE.linux-486.linux-486 -#------------------------------------------------------- - -# Include linux-x86 compiler definitions -include $(CONFIG)/os/CONFIG.linux-x86.linux-x86 - diff --git a/configure/os/CONFIG.linux-586.Common b/configure/os/CONFIG.linux-586.Common deleted file mode 100644 index 43463e8a0..000000000 --- a/configure/os/CONFIG.linux-586.Common +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.linux-586.Common -# -# Definitions for linux-586 host builds -# Sites may override these definitions in CONFIG_SITE.linux-586.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -WIND_HOST_TYPE = x86-linux2 diff --git a/configure/os/CONFIG.linux-586.linux-586 b/configure/os/CONFIG.linux-586.linux-586 deleted file mode 100644 index 990bfad74..000000000 --- a/configure/os/CONFIG.linux-586.linux-586 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-586.linux-586 -# -# Definitions for linux-586 host - linux-586 target builds -# Sites may override these definitions in CONFIG_SITE.linux-586.linux-586 -#------------------------------------------------------- - -# Include linux-x86 compiler definitions -include $(CONFIG)/os/CONFIG.linux-x86.linux-x86 - diff --git a/configure/os/CONFIG.linux-686.Common b/configure/os/CONFIG.linux-686.Common deleted file mode 100644 index f36cddeac..000000000 --- a/configure/os/CONFIG.linux-686.Common +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.linux-686.Common -# -# Definitions for linux-686 host builds -# Sites may override these definitions in CONFIG_SITE.linux-686.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -WIND_HOST_TYPE = x86-linux2 diff --git a/configure/os/CONFIG.linux-686.linux-686 b/configure/os/CONFIG.linux-686.linux-686 deleted file mode 100644 index e4195a40a..000000000 --- a/configure/os/CONFIG.linux-686.linux-686 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-686.linux-686 -# -# Definitions for linux-686 host - linux-686 target builds -# Sites may override these definitions in CONFIG_SITE.linux-686.linux-686 -#------------------------------------------------------- - -# Include linux-x86 compiler definitions -include $(CONFIG)/os/CONFIG.linux-x86.linux-x86 - diff --git a/configure/os/CONFIG.linux-arm-debug.Common b/configure/os/CONFIG.linux-arm-debug.Common deleted file mode 100644 index 66dd0c89e..000000000 --- a/configure/os/CONFIG.linux-arm-debug.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-arm-debug.Common -# -# Definitions for linux-arm-debug host builds -# Override these settings in CONFIG_SITE.linux-arm-debug.Common -#------------------------------------------------------- - -#Include definitions common to linux-arm hosts -include $(CONFIG)/os/CONFIG.linux-arm.Common - diff --git a/configure/os/CONFIG.linux-arm-debug.linux-arm-debug b/configure/os/CONFIG.linux-arm-debug.linux-arm-debug deleted file mode 100644 index 6e38378ee..000000000 --- a/configure/os/CONFIG.linux-arm-debug.linux-arm-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.linux-arm-debug.linux-arm-debug -# -# Definitions for linux-arm-debug host and target build -# Override these settings in CONFIG_SITE.linux-arm-debug.linux-arm-debug -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.linux-arm.linux-arm - -# Removes -O optimization and adds -g compile option -HOST_OPT=NO - diff --git a/configure/os/CONFIG.linux-arm.Common b/configure/os/CONFIG.linux-arm.Common deleted file mode 100644 index 9ad637827..000000000 --- a/configure/os/CONFIG.linux-arm.Common +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.linux-arm.Common -# -# Definitions for linux-arm host builds -# Sites may override these definitions in CONFIG_SITE.linux-arm.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common diff --git a/configure/os/CONFIG.linux-arm.linux-arm b/configure/os/CONFIG.linux-arm.linux-arm deleted file mode 100644 index 2e7687d0a..000000000 --- a/configure/os/CONFIG.linux-arm.linux-arm +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.linux-arm.linux-arm -# -# Definitions for native linux-arm builds -# Sites may override these definitions in CONFIG_SITE.linux-arm.linux-arm -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon diff --git a/configure/os/CONFIG.linux-arm.linux-arm-debug b/configure/os/CONFIG.linux-arm.linux-arm-debug deleted file mode 100644 index 0fb2fca27..000000000 --- a/configure/os/CONFIG.linux-arm.linux-arm-debug +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.linux-arm.linux-arm-debug -# -# Definitions for linux-arm host - linux-arm-debug target build -# Override these settings in CONFIG_SITE.linux-arm.linux-arm-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.linux-arm.linux-arm --include $(CONFIG)/os/CONFIG_SITE.Common.linux-arm --include $(CONFIG)/os/CONFIG_SITE.linux-arm.linux-arm - -BUILD_CLASS=HOST -HOST_OPT=NO diff --git a/configure/os/CONFIG.linux-ppc.Common b/configure/os/CONFIG.linux-ppc.Common deleted file mode 100644 index 377a25f08..000000000 --- a/configure/os/CONFIG.linux-ppc.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-ppc.Common -# -# Definitions for linux-ppc host builds -# Sites may override these definitions in CONFIG_SITE.linux-ppc.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - diff --git a/configure/os/CONFIG.linux-ppc.linux-ppc b/configure/os/CONFIG.linux-ppc.linux-ppc deleted file mode 100644 index 5010d1bc3..000000000 --- a/configure/os/CONFIG.linux-ppc.linux-ppc +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-ppc.linux-ppc -# -# Definitions for linux-ppc host - linux-ppc target builds -# Sites may override these definitions in CONFIG_SITE.linux-ppc.linux-ppc -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - diff --git a/configure/os/CONFIG.linux-ppc64.Common b/configure/os/CONFIG.linux-ppc64.Common deleted file mode 100644 index 516cc4ffe..000000000 --- a/configure/os/CONFIG.linux-ppc64.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-ppc64.Common -# -# Definitions for linux-ppc64 host builds -# Sites may override these definitions in CONFIG_SITE.linux-ppc64.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - diff --git a/configure/os/CONFIG.linux-ppc64.linux-ppc64 b/configure/os/CONFIG.linux-ppc64.linux-ppc64 deleted file mode 100644 index cfd00a88f..000000000 --- a/configure/os/CONFIG.linux-ppc64.linux-ppc64 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-ppc64.linux-ppc64 -# -# Definitions for linux-ppc64 host - linux-ppc64 target builds -# Sites may override these definitions in CONFIG_SITE.linux-ppc64.linux-ppc64 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/os/CONFIG.linux-x86.linux-x86 - diff --git a/configure/os/CONFIG.linux-x86-debug.Common b/configure/os/CONFIG.linux-x86-debug.Common deleted file mode 100644 index 800edb394..000000000 --- a/configure/os/CONFIG.linux-x86-debug.Common +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.linux-x86-debug.Common -# -# Definitions for linux-x86 debug with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.linux-x86-debug.Common -#------------------------------------------------------- - -#Include definitions common to linux-x86 hosts -include $(CONFIG)/os/CONFIG.linux-x86.Common - -# Make all crosscompiler builds debug builds -#CROSS_OPT=NO - diff --git a/configure/os/CONFIG.linux-x86-debug.linux-x86-debug b/configure/os/CONFIG.linux-x86-debug.linux-x86-debug deleted file mode 100644 index 737a116f3..000000000 --- a/configure/os/CONFIG.linux-x86-debug.linux-x86-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.linux-x86-debug.linux-x86-debug -# -# Definitions for linux-x86 host - linux-x86 target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.linux-x86-debug.linux-x86-debug -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.linux-x86.linux-x86 - -# Removes -O optimization and adds -g compile option -HOST_OPT=NO - diff --git a/configure/os/CONFIG.linux-x86.Common b/configure/os/CONFIG.linux-x86.Common deleted file mode 100644 index 4a525551e..000000000 --- a/configure/os/CONFIG.linux-x86.Common +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.linux-x86.Common -# -# Definitions for linux-x86 host builds -# Sites may override these definitions in CONFIG_SITE.linux-x86.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -WIND_HOST_TYPE = x86-linux2 diff --git a/configure/os/CONFIG.linux-x86.linux-arm b/configure/os/CONFIG.linux-x86.linux-arm deleted file mode 100644 index e2cf36a52..000000000 --- a/configure/os/CONFIG.linux-x86.linux-arm +++ /dev/null @@ -1,33 +0,0 @@ -# CONFIG.linux-x86.linux-arm -# -# Definitions for linux-x86 host - linux-arm target builds -# Override these settings in CONFIG_SITE.linux-x86.linux-arm -#------------------------------------------------------- - -VALID_BUILDS = Ioc -GNU_TARGET = arm-linux - -# prefix of compiler tools -CMPLR_SUFFIX = -CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET)) - -# Provide a link-time path for shared libraries -SHRLIBDIR_RPATH_LDFLAGS_YES += $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath-link,%) -SHRLIBDIR_LDFLAGS += $(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Provide a link-time path for products -PRODDIR_RPATH_LDFLAGS_YES += $(PROD_DEPLIB_DIRS:%=-Wl,-rpath-link,%) -PRODDIR_LDFLAGS += $(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)) - -# Provide a link-time path for readline -RUNTIME_LDFLAGS_READLINE_YES = -Wl,-rpath-link,$(GNU_DIR)/lib -RUNTIME_LDFLAGS_READLINE = $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)) -RUNTIME_LDFLAGS_READLINE_CURSES = $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)) -RUNTIME_LDFLAGS_READLINE_NCURSES = $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)) - -# Library flags -STATIC_LDFLAGS_YES= -Wl,-Bstatic -STATIC_LDFLAGS_NO= -STATIC_LDLIBS_YES= -Wl,-Bdynamic -STATIC_LDLIBS_NO= - diff --git a/configure/os/CONFIG.linux-x86.linux-arm-debug b/configure/os/CONFIG.linux-x86.linux-arm-debug deleted file mode 100644 index 16dad62c3..000000000 --- a/configure/os/CONFIG.linux-x86.linux-arm-debug +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-x86.linux-arm-debug -# -# Definitions for linux-x86 host - linux-arm-debug target builds -# Override these settings in CONFIG_SITE.linux-x86.linux-arm-debug -#------------------------------------------------------- - -# Include definitions for linux-arm targets -include $(CONFIG)/os/CONFIG.linux-x86.linux-arm - diff --git a/configure/os/CONFIG.linux-x86.linux-arm_eb b/configure/os/CONFIG.linux-x86.linux-arm_eb deleted file mode 100644 index f67bf3990..000000000 --- a/configure/os/CONFIG.linux-x86.linux-arm_eb +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-x86.linux-arm_eb -# -# Definitions for linux-x86 host - linux-arm_eb (big endian) target builds -# Sites may override these definitions in CONFIG_SITE.linux-x86.linux-arm_eb -#------------------------------------------------------- - -# Include definitions for linux-arm targets -include $(CONFIG)/os/CONFIG.linux-x86.linux-arm - diff --git a/configure/os/CONFIG.linux-x86.linux-arm_el b/configure/os/CONFIG.linux-x86.linux-arm_el deleted file mode 100644 index f924796a9..000000000 --- a/configure/os/CONFIG.linux-x86.linux-arm_el +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-x86.linux-arm_el -# -# Definitions for linux-x86 host - linux-arm_el (little endian) target builds -# Sites may override these definitions in CONFIG_SITE.linux-x86.linux-arm_el -#------------------------------------------------------- - -# Include definitions for linux-arm targets -include $(CONFIG)/os/CONFIG.linux-x86.linux-arm - diff --git a/configure/os/CONFIG.linux-x86.linux-cris b/configure/os/CONFIG.linux-x86.linux-cris deleted file mode 100644 index 8244916e5..000000000 --- a/configure/os/CONFIG.linux-x86.linux-cris +++ /dev/null @@ -1,38 +0,0 @@ -# CONFIG.linux-x86.linux-cris -# -# Author: Peter Zumbruch -# GSI -# P.Zumbruch@gsi.de -# -# Definitions for linux-x86 host - linux-cris target builds -# Sites may override these definitions in CONFIG_SITE.linux-x86.linux-cris -#------------------------------------------------------- - -GNU_DIR = $(CRIS_CROSS_COMPILER) - -#STATIC_... -STATIC_LDFLAGS_YES= -Wl,-Bstatic - -## debian-gcc Bug#438641 -GNU_LDLIBS_YES = -STATIC_LDFLAGS_YES += -static-libgcc - -# if not in debug mode strip all symbols -ifndef CRIS_COMPILER_DEBUG -STATIC_LDFLAGS_YES += -Wl,--strip-all -endif - -ifeq ($(GNU),YES) -STATIC_LDFLAGS_NO = -lgcc -else -STATIC_LDFLAGS_NO = -endif - -STATIC_LDLIBS_YES= -STATIC_LDLIBS_NO= - -OPT_CXXFLAGS_YES = -Os - -ifeq ($(STATIC_BUILD), YES) - $(shell echo yes) -endif diff --git a/configure/os/CONFIG.linux-x86.linux-cris_v10 b/configure/os/CONFIG.linux-x86.linux-cris_v10 deleted file mode 100644 index a227ac07c..000000000 --- a/configure/os/CONFIG.linux-x86.linux-cris_v10 +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG.linux-x86.linux-cris_v10 -# -# Author: Peter Zumbruch -# GSI -# P.Zumbruch@gsi.de -# -# Definitions for linux-x86 host - linux-cris_v10 target builds -# Sites may override these definitions in CONFIG_SITE.linux-x86.linux-cris_v10 -#------------------------------------------------------- - -# Include definitions common to all linux-cris targets -include $(CONFIG)/os/CONFIG.Common.linux-cris - -GNU_TARGET = cris-axis-linux-gnu - -ARCH_DEP_CFLAGS += -march=v10 - -# if you are using different places for cris_v10 cris_v32 -# you have to define for each architecture -# AXIS_SDK_DIR= diff --git a/configure/os/CONFIG.linux-x86.linux-cris_v32 b/configure/os/CONFIG.linux-x86.linux-cris_v32 deleted file mode 100644 index eee8f3344..000000000 --- a/configure/os/CONFIG.linux-x86.linux-cris_v32 +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG.linux-x86.linux-cris_v32 -# -# Author: Peter Zumbruch -# GSI -# P.Zumbruch@gsi.de -# -# Definitions for linux-x86 host - linux-cris_v32 target builds -# Sites may override these definitions in CONFIG_SITE.linux-x86.linux-cris_v32 -#------------------------------------------------------- - -# Include definitions common to all linux-cris targets -include $(CONFIG)/os/CONFIG.Common.linux-cris - -GNU_TARGET = crisv32-axis-linux-gnu - -ARCH_DEP_CFLAGS += -march=v32 - -# if you are using different places for cris_v10 cris_v32 -# you have to define for each architecture -# AXIS_SDK_DIR= diff --git a/configure/os/CONFIG.linux-x86.linux-x86 b/configure/os/CONFIG.linux-x86.linux-x86 deleted file mode 100644 index f6a79241a..000000000 --- a/configure/os/CONFIG.linux-x86.linux-x86 +++ /dev/null @@ -1,16 +0,0 @@ -# CONFIG.linux-x86.linux-x86 -# -# Definitions for linux-x86 host - linux-x86 target builds -# Sites may override these definitions in CONFIG_SITE.linux-x86.linux-x86 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -STATIC_LDFLAGS_YES= -Wl,-Bstatic -STATIC_LDFLAGS_NO= -STATIC_LDLIBS_YES= -Wl,-Bdynamic -STATIC_LDLIBS_NO= - -SHRLIB_LDFLAGS += -Wl,-h$@ -LOADABLE_SHRLIB_LDFLAGS += -Wl,-h$@ diff --git a/configure/os/CONFIG.linux-x86.linux-x86-debug b/configure/os/CONFIG.linux-x86.linux-x86-debug deleted file mode 100644 index dc71572d3..000000000 --- a/configure/os/CONFIG.linux-x86.linux-x86-debug +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.linux-x86.linux-x86-debug -# -# Definitions for linux-x86 host - linux-x86-debug target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.linux-x86.linux-x86-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.linux-x86.linux-x86 -#-include $(CONFIG)/os/CONFIG_SITE.Common.linux-x86 -#-include $(CONFIG)/os/CONFIG_SITE.linux-x86.linux-x86 - -BUILD_CLASS=HOST -HOST_OPT=NO diff --git a/configure/os/CONFIG.linux-x86.win32-x86-mingw b/configure/os/CONFIG.linux-x86.win32-x86-mingw deleted file mode 100644 index 150f13864..000000000 --- a/configure/os/CONFIG.linux-x86.win32-x86-mingw +++ /dev/null @@ -1,24 +0,0 @@ -# CONFIG.linux-x86.win32-x86-mingw -# -# Definitions for linux-x86 host win32-x86-mingw target builds -# Override these definitions in CONFIG_SITE.linux-x86.win32-x86-mingw -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -# Add resource compiler -RCCMD = $(GNU_BIN)/$(CMPLR_PREFIX)windres$(CMPLR_SUFFIX) $(INCLUDES) $< $@ - -# Remove -fPIC flags, add out-implib -SHRLIB_CFLAGS = -SHRLIB_LDFLAGS = -shared \ - -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX) -LOADABLE_SHRLIB_LDFLAGS = -shared \ - -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX) - -# Don't link with gcc library -GNU_LDLIBS_YES = - -# Link with system libraries -OP_SYS_LDLIBS = -lws2_32 -ladvapi32 -luser32 -lkernel32 -lwinmm diff --git a/configure/os/CONFIG.linux-x86.windows-x64-mingw b/configure/os/CONFIG.linux-x86.windows-x64-mingw deleted file mode 100644 index 3becd0045..000000000 --- a/configure/os/CONFIG.linux-x86.windows-x64-mingw +++ /dev/null @@ -1,24 +0,0 @@ -# CONFIG.linux-x86.windows-x64-mingw -# -# Definitions for linux-x86 host windows-x64-mingw target builds -# Override these definitions in CONFIG_SITE.linux-x86.windows-x64-mingw -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -# Add resource compiler -RCCMD = $(GNU_BIN)/$(CMPLR_PREFIX)windres$(CMPLR_SUFFIX) $(INCLUDES) $< $@ - -# Remove -fPIC flags, add out-implib -SHRLIB_CFLAGS = -SHRLIB_LDFLAGS = -shared \ - -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX) -LOADABLE_SHRLIB_LDFLAGS = -shared \ - -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX) - -# No need to explicitly link with gcc library -GNU_LDLIBS_YES = - -# Link with winsock2 -OP_SYS_LDLIBS = -lws2_32 diff --git a/configure/os/CONFIG.linux-x86_64-debug.Common b/configure/os/CONFIG.linux-x86_64-debug.Common deleted file mode 100644 index 70bdf4e4b..000000000 --- a/configure/os/CONFIG.linux-x86_64-debug.Common +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.linux-x86_64-debug.Common -# -# Definitions for linux-x86_64 debug with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.linux-x86_64-debug.Common -#------------------------------------------------------- - -#Include definitions common to linux-x86_64 hosts -include $(CONFIG)/os/CONFIG.linux-x86_64.Common - -# Make all crosscompiler builds debug builds -#CROSS_OPT=NO - diff --git a/configure/os/CONFIG.linux-x86_64-debug.linux-x86_64-debug b/configure/os/CONFIG.linux-x86_64-debug.linux-x86_64-debug deleted file mode 100644 index 6f7980235..000000000 --- a/configure/os/CONFIG.linux-x86_64-debug.linux-x86_64-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.linux-x86_64-debug.linux-x86_64-debug -# -# Definitions for linux-x86_64 host - linux-x86_64 target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.linux-x86_64.linux-x86_64 - -# Removes -O optimization and adds -g compile option -HOST_OPT=NO - diff --git a/configure/os/CONFIG.linux-x86_64.Common b/configure/os/CONFIG.linux-x86_64.Common deleted file mode 100644 index 22cab92ef..000000000 --- a/configure/os/CONFIG.linux-x86_64.Common +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.linux-x86_64.Common -# -# Definitions for linux-x86_64 host builds -# Sites may override these definitions in CONFIG_SITE.linux-x86_64.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -WIND_HOST_TYPE = x86-linux2 diff --git a/configure/os/CONFIG.linux-x86_64.linux-arm b/configure/os/CONFIG.linux-x86_64.linux-arm deleted file mode 100644 index 38cd888ad..000000000 --- a/configure/os/CONFIG.linux-x86_64.linux-arm +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.linux-x86_64.linux-arm -# -# Definitions for linux-x86_64 host - linux-arm target builds -# Sites may override these definitions in CONFIG_SITE.linux-x86_64.linux-arm -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.linux-x86.linux-arm - diff --git a/configure/os/CONFIG.linux-x86_64.linux-arm-debug b/configure/os/CONFIG.linux-x86_64.linux-arm-debug deleted file mode 100644 index 3feb41089..000000000 --- a/configure/os/CONFIG.linux-x86_64.linux-arm-debug +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.linux-x86_64.linux-arm-debug -# -# Definitions for linux-x86_64 host - linux-arm-debug target builds -# Override these settings in CONFIG_SITE.linux-x86_64.linux-arm-debug -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.linux-x86.linux-arm - diff --git a/configure/os/CONFIG.linux-x86_64.linux-x86_64 b/configure/os/CONFIG.linux-x86_64.linux-x86_64 deleted file mode 100644 index 4466a7edb..000000000 --- a/configure/os/CONFIG.linux-x86_64.linux-x86_64 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-x86_64.linux-x86_64 -# -# Definitions for linux-x86_64 host - linux-x86_64 target builds -# Sites may override these definitions in CONFIG_SITE.linux-x86_64.linux-x86_64 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/os/CONFIG.linux-x86.linux-x86 - diff --git a/configure/os/CONFIG.linux-x86_64.linux-x86_64-debug b/configure/os/CONFIG.linux-x86_64.linux-x86_64-debug deleted file mode 100644 index 8c804ee08..000000000 --- a/configure/os/CONFIG.linux-x86_64.linux-x86_64-debug +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.linux-x86_64.linux-x86_64-debug -# -# Definitions for linux-x86_64 host - linux-x86_64-debug target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.linux-x86_64.linux-x86_64-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.linux-x86_64.linux-x86_64 --include $(CONFIG)/os/CONFIG_SITE.Common.linux-x86_64 --include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.linux-x86_64 - -BUILD_CLASS=HOST -HOST_OPT = NO diff --git a/configure/os/CONFIG.linux-x86_64.win32-x86-mingw b/configure/os/CONFIG.linux-x86_64.win32-x86-mingw deleted file mode 100644 index fe4edd1e8..000000000 --- a/configure/os/CONFIG.linux-x86_64.win32-x86-mingw +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-x86_64.win32-x86-mingw -# -# Definitions for linux-x86_64 host win32-x86-mingw target builds -# Override these definitions in CONFIG_SITE.linux-x86_64.win32-x86-mingw -#------------------------------------------------------- - -# Settings as for the linux-x86 host architecture -include $(CONFIG)/os/CONFIG.linux-x86.win32-x86-mingw - diff --git a/configure/os/CONFIG.linux-x86_64.windows-x64-mingw b/configure/os/CONFIG.linux-x86_64.windows-x64-mingw deleted file mode 100644 index f84301266..000000000 --- a/configure/os/CONFIG.linux-x86_64.windows-x64-mingw +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.linux-x86_64.windows-x64-mingw -# -# Definitions for linux-x86_64 host windows-x64-mingw target builds -# Override these definitions in CONFIG_SITE.linux-x86_64.windows-x64-mingw -#------------------------------------------------------- - -# Settings as for the linux-x86 host architecture -include $(CONFIG)/os/CONFIG.linux-x86.windows-x64-mingw - diff --git a/configure/os/CONFIG.solaris-sparc-debug.Common b/configure/os/CONFIG.solaris-sparc-debug.Common deleted file mode 100644 index 256a72118..000000000 --- a/configure/os/CONFIG.solaris-sparc-debug.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-sparc-debug.Common -# -# Definitions for solaris-sparc debug with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.solaris-sparc-debug.Common -#------------------------------------------------------- - -#Include definitions common to solaris-sparc hosts -include $(CONFIG)/os/CONFIG.solaris-sparc.Common - diff --git a/configure/os/CONFIG.solaris-sparc-debug.solaris-sparc-debug b/configure/os/CONFIG.solaris-sparc-debug.solaris-sparc-debug deleted file mode 100644 index 9510bc6fa..000000000 --- a/configure/os/CONFIG.solaris-sparc-debug.solaris-sparc-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.solaris-sparc-debug.solaris-sparc-debug -# -# Definitions for solaris-sparc host - solaris-sparc target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG_SITE.Common.solaris-sparc -include $(CONFIG)/os/CONFIG.solaris-sparc.solaris-sparc - -# Removes -O optimization and adds -g compile option -HOST_OPT=NO diff --git a/configure/os/CONFIG.solaris-sparc-gnu.Common b/configure/os/CONFIG.solaris-sparc-gnu.Common deleted file mode 100644 index 1ec37610f..000000000 --- a/configure/os/CONFIG.solaris-sparc-gnu.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-sparc-gnu.Common -# -# Definitions for solaris-sparc gnu compiler host builds -# Sites may override these definitions in CONFIG_SITE.solaris-sparc-gnu.Common -#------------------------------------------------------- - -#Include definitions common to solaris-sparc hosts -include $(CONFIG)/os/CONFIG.solaris-sparc.Common - diff --git a/configure/os/CONFIG.solaris-sparc-gnu.solaris-sparc-gnu b/configure/os/CONFIG.solaris-sparc-gnu.solaris-sparc-gnu deleted file mode 100644 index 03476b833..000000000 --- a/configure/os/CONFIG.solaris-sparc-gnu.solaris-sparc-gnu +++ /dev/null @@ -1,23 +0,0 @@ -# CONFIG.solaris-sparc-gnu.solaris-sparc-gnu -# -# Definitions for solaris-sparc gnu compiler host - solaris-sparc gnu compiler target builds -# Sites may override these definitions in CONFIG_SITE.solaris-sparc-gnu.solaris-sparc-gnu -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -AR = ar -rc -RANLIB= -LD = ld -r - -STATIC_LDFLAGS_YES= -Wl,-Bstatic -STATIC_LDFLAGS_NO= -STATIC_LDLIBS_YES= -Wl,-Bdynamic -STATIC_LDLIBS_NO= - -OP_SYS_LDFLAGS += -z ignore -z combreloc -z lazyload - -SHRLIB_LDFLAGS += -Wl,-z,defs -Wl,-z,text -Wl,-h,$@ -LOADABLE_SHRLIB_LDFLAGS += -Wl,-z,text -Wl,-h,$@ -GNU_LDLIBS_YES += -lc diff --git a/configure/os/CONFIG.solaris-sparc.Common b/configure/os/CONFIG.solaris-sparc.Common deleted file mode 100644 index 3c5fb044d..000000000 --- a/configure/os/CONFIG.solaris-sparc.Common +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.solaris-sparc.Common -# -# Definitions for solaris-sparc host archs -# Sites may override these definitions in CONFIG_SITE.solaris-sparc.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -WIND_HOST_TYPE = sun4-solaris2 - diff --git a/configure/os/CONFIG.solaris-sparc.solaris-sparc b/configure/os/CONFIG.solaris-sparc.solaris-sparc deleted file mode 100644 index de625aed1..000000000 --- a/configure/os/CONFIG.solaris-sparc.solaris-sparc +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-sparc.solaris-sparc -# -# Definitions for solaris-sparc host - solaris-sparc target build -# Sites may override these definitions in CONFIG_SITE.solaris-sparc.solaris-sparc -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.solarisCommon.solarisCommon - -SHRLIB_CFLAGS = -xcode=pic32 diff --git a/configure/os/CONFIG.solaris-sparc.solaris-sparc-debug b/configure/os/CONFIG.solaris-sparc.solaris-sparc-debug deleted file mode 100644 index 5578bcd66..000000000 --- a/configure/os/CONFIG.solaris-sparc.solaris-sparc-debug +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG.solaris-sparc.solaris-sparc-debug -# -# Definitions for solaris-sparc host - solaris-sparc-debug target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.solaris-sparc.solaris-sparc-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.solaris-sparc.solaris-sparc --include $(CONFIG)/os/CONFIG_SITE.Common.solaris-sparc --include $(CONFIG)/os/CONFIG_SITE.solaris-sparc.solaris-sparc - -BUILD_CLASS=HOST -HOST_OPT=NO - diff --git a/configure/os/CONFIG.solaris-sparc.solaris-sparc-gnu b/configure/os/CONFIG.solaris-sparc.solaris-sparc-gnu deleted file mode 100644 index 423d3dc4b..000000000 --- a/configure/os/CONFIG.solaris-sparc.solaris-sparc-gnu +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.solaris-sparc.solaris-sparc-gnu -# -# Definitions for solaris-sparc host - solaris-sparc-gnu target build with gnu compiler -# Sites may override these definitions in CONFIG_SITE.solaris-sparc.solaris-sparc-gnu -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.solaris-sparc-gnu.solaris-sparc-gnu - -BUILD_CLASS = HOST - diff --git a/configure/os/CONFIG.solaris-sparc.solaris-sparc64 b/configure/os/CONFIG.solaris-sparc.solaris-sparc64 deleted file mode 100644 index 06c9ffa17..000000000 --- a/configure/os/CONFIG.solaris-sparc.solaris-sparc64 +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.solaris-sparc.solaris-sparc64 -# -# Definitions for solaris-sparc host - solaris-sparc64 target build with Sun compiler -# Sites may override these definitions in CONFIG_SITE.solaris-sparc.solaris-sparc64 -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.solaris-sparc64.solaris-sparc64 - -BUILD_CLASS = HOST - -GNU = NO diff --git a/configure/os/CONFIG.solaris-sparc.solaris-sparc64-gnu b/configure/os/CONFIG.solaris-sparc.solaris-sparc64-gnu deleted file mode 100644 index 12c33de2b..000000000 --- a/configure/os/CONFIG.solaris-sparc.solaris-sparc64-gnu +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG.solaris-sparc.solaris-sparc64-gnu -# -# Definitions for solaris-sparc host - solaris-sparc64-gnu target build with gnu compiler -# Sites may override these definitions in CONFIG_SITE.solaris-sparc.solaris-sparc64-gnu -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.solaris-sparc64-gnu.solaris-sparc64-gnu - -BUILD_CLASS = HOST - diff --git a/configure/os/CONFIG.solaris-sparc64-gnu.Common b/configure/os/CONFIG.solaris-sparc64-gnu.Common deleted file mode 100644 index a8e281af2..000000000 --- a/configure/os/CONFIG.solaris-sparc64-gnu.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-sparc64-gnu.Common -# -# Definitions for solaris-sparc64 gnu compiler host builds -# Sites may override these definitions in CONFIG_SITE.solaris-sparc64-gnu.Common -#------------------------------------------------------- - -#Include definitions common to solaris-sparc-gnu hosts -include $(CONFIG)/os/CONFIG.solaris-sparc-gnu.Common - diff --git a/configure/os/CONFIG.solaris-sparc64-gnu.solaris-sparc64-gnu b/configure/os/CONFIG.solaris-sparc64-gnu.solaris-sparc64-gnu deleted file mode 100644 index cbc921cd1..000000000 --- a/configure/os/CONFIG.solaris-sparc64-gnu.solaris-sparc64-gnu +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-sparc64-gnu.solaris-sparc64-gnu -# -# Definitions for solaris-sparc64 gnu compiler host - solaris-sparc64 gnu compiler target builds -# Sites may override these definitions in CONFIG_SITE.solaris-sparc64-gnu.solaris-sparc64-gnu -#------------------------------------------------------- - -# Include common solaris-sparc-gnu definitions -include $(CONFIG)/os/CONFIG.solaris-sparc-gnu.solaris-sparc-gnu - diff --git a/configure/os/CONFIG.solaris-sparc64.Common b/configure/os/CONFIG.solaris-sparc64.Common deleted file mode 100644 index f87e58156..000000000 --- a/configure/os/CONFIG.solaris-sparc64.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-sparc64.Common -# -# Definitions for solaris-sparc64 Sun compiler host builds -# Sites may override these definitions in CONFIG_SITE.solaris-sparc64.Common -#------------------------------------------------------- - -#Include definitions common to solaris-sparc hosts -include $(CONFIG)/os/CONFIG.solaris-sparc.Common - diff --git a/configure/os/CONFIG.solaris-sparc64.solaris-sparc64 b/configure/os/CONFIG.solaris-sparc64.solaris-sparc64 deleted file mode 100644 index b862a3153..000000000 --- a/configure/os/CONFIG.solaris-sparc64.solaris-sparc64 +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.solaris-sparc64.solaris-sparc64 -# -# Definitions for solaris-sparc64 compiler host - solaris-sparc64 compiler target builds -# Sites may override these definitions in CONFIG_SITE.solaris-sparc64.solaris-sparc64 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/os/CONFIG.solaris-sparc.solaris-sparc diff --git a/configure/os/CONFIG.solaris-sparc64.solaris-sparc64-debug b/configure/os/CONFIG.solaris-sparc64.solaris-sparc64-debug deleted file mode 100644 index edbb733fc..000000000 --- a/configure/os/CONFIG.solaris-sparc64.solaris-sparc64-debug +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG.solaris-sparc64.solaris-sparc64-debug -# -# Definitions for solaris-sparc64 host - solaris-sparc64-debug target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.solaris-sparc64.solaris-sparc64-debug -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.Common.solaris-sparc64 -include $(CONFIG)/os/CONFIG.solaris-sparc64.solaris-sparc64 - -BUILD_CLASS=HOST - -# Removes -O optimization and adds -g compile option -HOST_OPT=NO diff --git a/configure/os/CONFIG.solaris-x86-gnu.Common b/configure/os/CONFIG.solaris-x86-gnu.Common deleted file mode 100644 index e8111548f..000000000 --- a/configure/os/CONFIG.solaris-x86-gnu.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-x86-gnu.Common -# -# Definitions for solaris-x86 gnu compiler host builds -# Sites may override these definitions in CONFIG_SITE.solaris-x86-gnu.Common -#------------------------------------------------------- - -#Include definitions common to solaris-x86 hosts -include $(CONFIG)/os/CONFIG.solaris-x86.Common - diff --git a/configure/os/CONFIG.solaris-x86-gnu.solaris-x86-gnu b/configure/os/CONFIG.solaris-x86-gnu.solaris-x86-gnu deleted file mode 100644 index 1c2c43826..000000000 --- a/configure/os/CONFIG.solaris-x86-gnu.solaris-x86-gnu +++ /dev/null @@ -1,17 +0,0 @@ -# CONFIG.solaris-x86-gnu.solaris-x86-gnu -# -# Definitions for solaris-x86 gnu compiler host - solaris-x86 gnu compiler target builds -# Sites may override these definitions in CONFIG_SITE.solaris-x86-gnu.solaris-x86-gnu -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -AR = ar -rc -RANLIB= -LD = ld -r - -SHRLIB_LDFLAGS += -h $@ -z defs -LOADABLE_SHRLIB_LDFLAGS += -h $@ - -OP_SYS_LDFLAGS += -z ignore -z combreloc -z lazyload diff --git a/configure/os/CONFIG.solaris-x86.Common b/configure/os/CONFIG.solaris-x86.Common deleted file mode 100644 index 9ae62e5ef..000000000 --- a/configure/os/CONFIG.solaris-x86.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-x86.Common -# -# Definitions for solaris-x86 host builds -# Sites may override these definitions in CONFIG_SITE.solaris-x86.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - diff --git a/configure/os/CONFIG.solaris-x86.solaris-x86 b/configure/os/CONFIG.solaris-x86.solaris-x86 deleted file mode 100644 index 2e4bb23e2..000000000 --- a/configure/os/CONFIG.solaris-x86.solaris-x86 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-x86.solaris-x86 -# -# Definitions for solaris-x86 host - solaris-x86 target builds -# Sites may override these definitions in CONFIG_SITE.solaris-x86.solaris-x86 -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.solarisCommon.solarisCommon - -SHRLIB_CFLAGS = -KPIC diff --git a/configure/os/CONFIG.solaris-x86.solaris-x86-debug b/configure/os/CONFIG.solaris-x86.solaris-x86-debug deleted file mode 100644 index 505080310..000000000 --- a/configure/os/CONFIG.solaris-x86.solaris-x86-debug +++ /dev/null @@ -1,15 +0,0 @@ -# CONFIG.solaris-x86.solaris-x86-debug -# -# Definitions for solaris-x86 host - solaris-x86-debug target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.solaris-x86.solaris-x86-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.Common.solaris-x86 --include $(CONFIG)/os/CONFIG.solaris-x86.solaris-x86 --include $(CONFIG)/os/CONFIG_SITE.Common.solaris-x86 --include $(CONFIG)/os/CONFIG_SITE.solaris-x86.solaris-x86 - -BUILD_CLASS=HOST - -# Removes -O optimization and adds -g compile option -HOST_OPT=NO diff --git a/configure/os/CONFIG.solaris-x86.solaris-x86_64 b/configure/os/CONFIG.solaris-x86.solaris-x86_64 deleted file mode 100644 index e1ef93afe..000000000 --- a/configure/os/CONFIG.solaris-x86.solaris-x86_64 +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG.solaris-x86.solaris-x86_64 -# -# Definitions for solaris-x86 host - solaris-x86_64 target build with Sun compiler -# Sites may override these definitions in CONFIG_SITE.solaris-x86.solaris-x86_64 -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.solaris-x86_64.solaris-x86_64 - -BUILD_CLASS = HOST - -GNU = NO diff --git a/configure/os/CONFIG.solaris-x86_64-gnu.Common b/configure/os/CONFIG.solaris-x86_64-gnu.Common deleted file mode 100644 index 9c0296d3d..000000000 --- a/configure/os/CONFIG.solaris-x86_64-gnu.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-x86_64-gnu.Common -# -# Definitions for solaris-x86_64 gnu compiler host builds -# Sites may override these definitions in CONFIG_SITE.solaris-sparc64-gnu.Common -#------------------------------------------------------- - -#Include definitions common to solaris-x86-gnu hosts -include $(CONFIG)/os/CONFIG.solaris-x86-gnu.Common - diff --git a/configure/os/CONFIG.solaris-x86_64-gnu.solaris-x86_64-gnu b/configure/os/CONFIG.solaris-x86_64-gnu.solaris-x86_64-gnu deleted file mode 100644 index 8ff61b8a8..000000000 --- a/configure/os/CONFIG.solaris-x86_64-gnu.solaris-x86_64-gnu +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-x86_64-gnu.solaris-x86_64-gnu -# -# Definitions for solaris-x86_64 gnu compiler host - solaris-sx86_64 gnu compiler target builds -# Sites may override these definitions in CONFIG_SITE.solaris-x86_64-gnu.solaris-x86_64-gnu -#------------------------------------------------------- - -# Include common solaris-x86-gnu definitions -include $(CONFIG)/os/CONFIG.solaris-x86-gnu.solaris-x86-gnu - diff --git a/configure/os/CONFIG.solaris-x86_64.Common b/configure/os/CONFIG.solaris-x86_64.Common deleted file mode 100644 index a8b6c17ec..000000000 --- a/configure/os/CONFIG.solaris-x86_64.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.solaris-x86_64.Common -# -# Definitions for solaris-x86_64 Sun compiler host builds -# Sites may override these definitions in CONFIG_SITE.solaris-x86_64.Common -#------------------------------------------------------- - -#Include definitions common to solaris-sparc hosts -include $(CONFIG)/os/CONFIG.solaris-x86.Common - diff --git a/configure/os/CONFIG.solaris-x86_64.solaris-x86_64 b/configure/os/CONFIG.solaris-x86_64.solaris-x86_64 deleted file mode 100644 index 7e2111e76..000000000 --- a/configure/os/CONFIG.solaris-x86_64.solaris-x86_64 +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.solaris-x86_64.solaris-x86_64 -# -# Definitions for solaris-x86_64 Sun compiler host - solaris-x86_64 Sun compiler target builds -# Sites may override these definitions in CONFIG_SITE.solaris-x86_64.solaris-x86_64 -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/os/CONFIG.solaris-x86.solaris-x86 diff --git a/configure/os/CONFIG.solaris-x86_64.solaris-x86_64-debug b/configure/os/CONFIG.solaris-x86_64.solaris-x86_64-debug deleted file mode 100644 index fb375157d..000000000 --- a/configure/os/CONFIG.solaris-x86_64.solaris-x86_64-debug +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG.solaris-x86_64.solaris-x86_64-debug -# -# Definitions for solaris-x86_64 host - solaris-x86_64-debug target build with debug compiler flags -# Sites may override these definitions in CONFIG_SITE.solaris-x86_64.solaris-x86_64-debug -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.Common.solaris-x86_64 -include $(CONFIG)/os/CONFIG.solaris-x86_64.solaris-x86_64 - -BUILD_CLASS=HOST - -# Removes -O optimization and adds -g compile option -HOST_OPT=NO diff --git a/configure/os/CONFIG.solarisCommon.solarisCommon b/configure/os/CONFIG.solarisCommon.solarisCommon deleted file mode 100644 index 2b04f53bd..000000000 --- a/configure/os/CONFIG.solarisCommon.solarisCommon +++ /dev/null @@ -1,64 +0,0 @@ -# CONFIG.solarisCommon.solarisCommon -# -# Definitions for solaris host - solaris target build -# Sites may override these definitions in CONFIG_SITE.solarisCommon.solarisCommon -#------------------------------------------------------- - -CMPLR_CLASS = solStudio - -SPARCWORKS = /opt/SUNWspro -GNU = NO - -# SPARCWORKS path is set in a CONFIG_SITE file - -CC = $(SPARCWORKS)/bin/cc -CCC = $(SPARCWORKS)/bin/CC -CPP = $(CC) -E -Qn -RANLIB = -# required by sun's C++ compiler -AR = $(CCC) -xar -o -LD = ld -r - -#Prepare the object code for profiling with prof. (YES or NO) -PROFILE=NO -#Prepare the object code for profiling with gprof. (YES or NO) -GPROF=NO - -# Configure OS vendor C compiler -PROF_CFLAGS_YES = -p -GPROF_CFLAGS_YES = -xpg -CODE_CFLAGS = $(PROF_CFLAGS_$(PROFILE)) $(GPROF_CFLAGS_$(GPROF)) -WARN_CFLAGS_YES = -WARN_CFLAGS_NO = -w -OPT_CFLAGS_YES = -xO4 -OPT_CFLAGS_NO = -g - -# Configure OS vendor C++ compiler -PROF_CXXFLAGS_YES = -p -GPROF_CXXFLAGS_YES = -xpg -CODE_CXXFLAGS = $(PROF_CXXFLAGS_$(PROFILE)) $(GPROF_CXXFLAGS_$(GPROF)) -WARN_CXXFLAGS_YES = +w -WARN_CXXFLAGS_NO = -OPT_CXXFLAGS_YES = -O -OPT_CXXFLAGS_NO = -g - -CODE_LDFLAGS = $(PROF_CXXFLAGS_$(PROFILE)) $(GPROF_CXXFLAGS_$(GPROF)) - -STATIC_LDFLAGS_YES= -Bstatic -STATIC_LDFLAGS_NO= -STATIC_LDLIBS_YES= -Bdynamic -STATIC_LDLIBS_NO= - -SHRLIB_LDFLAGS = -z defs -G -h $@ -z text -LOADABLE_SHRLIB_LDFLAGS = -G -h $@ -z text - -OP_SYS_LDFLAGS += -z ignore -z combreloc -z lazyload - -# Header dependency file generation command -HDEPENDS_METHOD = COMP -HDEPENDS_COMPFLAGS = -xM1 > $@ - -#-------------------------------------------------- -# Allow site overrides --include $(CONFIG)/os/CONFIG_SITE.solarisCommon.solarisCommon --include $(CONFIG)/os/CONFIG_SITE.(EPICS_HOST_ARCH).solarisCommon diff --git a/configure/os/CONFIG.win32-x86-debug.Common b/configure/os/CONFIG.win32-x86-debug.Common deleted file mode 100644 index 602fb9038..000000000 --- a/configure/os/CONFIG.win32-x86-debug.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.win32-x86-debug.Common -# -# Definitions for win32-x86-debug host arch -# Override these definitions in CONFIG_SITE.win32-x86-debug.Common -#------------------------------------------------------- - -#Include definitions common to win32-x86 hosts -include $(CONFIG)/os/CONFIG.win32-x86.Common - diff --git a/configure/os/CONFIG.win32-x86-debug.win32-x86-debug b/configure/os/CONFIG.win32-x86-debug.win32-x86-debug deleted file mode 100644 index 8ee66ff8f..000000000 --- a/configure/os/CONFIG.win32-x86-debug.win32-x86-debug +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.win32-x86-debug.win32-x86-debug -# -# Definitions for win32-x86-debug host - win32-x86-debug target build -# Override these definitions in CONFIG_SITE.win32-x86-debug.win32-x86-debug -#------------------------------------------------------- - -#Include definitions common to win32-x86 builds -include $(CONFIG)/os/CONFIG.win32-x86.win32-x86 --include $(CONFIG)/os/CONFIG_SITE.win32-x86.win32-x86 - -# Override CONFIG_SITE settings: -HOST_OPT=NO diff --git a/configure/os/CONFIG.win32-x86-mingw.Common b/configure/os/CONFIG.win32-x86-mingw.Common deleted file mode 100644 index ebe195a7c..000000000 --- a/configure/os/CONFIG.win32-x86-mingw.Common +++ /dev/null @@ -1,25 +0,0 @@ -# CONFIG.win32-x86-mingw.Common -# -# Definitions for win32-x86-mingw host archs -# Sites may override these definitions in CONFIG_SITE.win32-x86-mingw.Common -#------------------------------------------------------- - -#Include definitions common to unix hosts -include $(CONFIG)/os/CONFIG.UnixCommon.Common - -CP = $(PERL) -MExtUtils::Command -e cp -MV = $(PERL) -MExtUtils::Command -e mv -RM = $(PERL) -MExtUtils::Command -e rm_f -MKDIR = $(PERL) -MExtUtils::Command -e mkpath -RMDIR = $(PERL) -MExtUtils::Command -e rm_rf -NOP = $(PERL) -e '' -CAT = $(PERL) -MExtUtils::Command -e cat - -WIND_HOST_TYPE = x86-win32 -OSITHREAD_USE_DEFAULT_STACK = NO - -HOSTEXE=.exe - -# Needed to find dlls for base installed build tools (antelope,eflex,...) -PATH := $(EPICS_BASE_BIN):$(PATH) - diff --git a/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw b/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw deleted file mode 100644 index 2a7827ccd..000000000 --- a/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw +++ /dev/null @@ -1,35 +0,0 @@ -# CONFIG.win32-x86-mingw.win32-x86-mingw -# -# Definitions for win32-x86-mingw host - win32-x86-mingw target builds -# Sites may override these definitions in CONFIG_SITE.win32-x86-mingw.win32-x86-mingw -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/CONFIG.gnuCommon - -# Undo various things set by CONFIG.gnuCommon - -CMPLR_PREFIX = - -# Remove $(GNU_BIN)/ path -CC = $(CMPLR_PREFIX)gcc -CCC = $(CMPLR_PREFIX)g++ -AR = $(CMPLR_PREFIX)ar -rc -LD = $(CMPLR_PREFIX)ld -r -RANLIB = $(CMPLR_PREFIX)ranlib - -# Add resource compiler -RCCMD = $(CMPLR_PREFIX)windres $(INCLUDES) $< $@ - -# Remove -fPIC flags, add out-implib -SHRLIB_CFLAGS = -SHRLIB_LDFLAGS = -shared \ - -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX) -LOADABLE_SHRLIB_LDFLAGS = -shared \ - -Wl,--out-implib,$(DLLSTUB_PREFIX)$*$(DLLSTUB_SUFFIX) - -# Don't link with gcc library -GNU_LDLIBS_YES = - -# Link with system libraries -OP_SYS_LDLIBS = -lws2_32 -ladvapi32 -luser32 -lkernel32 -lwinmm diff --git a/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw-debug b/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw-debug deleted file mode 100644 index 33148a819..000000000 --- a/configure/os/CONFIG.win32-x86-mingw.win32-x86-mingw-debug +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG.win32-x86-mingw.win32-x86-mingw-debug -# -# Definitions for win32-x86-mingw compiler host - win32-x86-mingw debug compiler target builds -# Sites may override these definitions in CONFIG_SITE.win32-x86-mingw.win32-x86-mingw-debug -#------------------------------------------------------- - --include $(CONFIG)/os/CONFIG.Common.win32-x86-mingw --include $(CONFIG)/os/CONFIG.win32-x86-mingw.win32-x86-mingw --include $(CONFIG)/os/CONFIG_SITE.Common.win32-x86-mingw --include $(CONFIG)/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw - -BUILD_CLASS = HOST - -HOST_OPT=NO diff --git a/configure/os/CONFIG.win32-x86-static.Common b/configure/os/CONFIG.win32-x86-static.Common deleted file mode 100644 index d302e4614..000000000 --- a/configure/os/CONFIG.win32-x86-static.Common +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.win32-x86-static.Common -# -# Definitions for win32-x86-static host archs -# Sites may override these definitions in CONFIG_SITE.win32-x86-static.Common -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.win32-x86.Common - diff --git a/configure/os/CONFIG.win32-x86-static.win32-x86-static b/configure/os/CONFIG.win32-x86-static.win32-x86-static deleted file mode 100644 index da90f992a..000000000 --- a/configure/os/CONFIG.win32-x86-static.win32-x86-static +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG.win32-x86-static.win32-x86.static -# -# Definitions for win32-x86-static host - win32-x86-static target build -# Override these definitions in CONFIG_SITE.win32-x86-static.win32-x86-static -#------------------------------------------------------- - -#Include definitions common to win32-x86 builds -include $(CONFIG)/os/CONFIG.win32-x86.win32-x86 --include $(CONFIG)/os/CONFIG_SITE.win32-x86.win32-x86 - -# Override CONFIG_SITE settings: -SHARED_LIBRARIES = NO -STATIC_BUILD = YES diff --git a/configure/os/CONFIG.win32-x86.Common b/configure/os/CONFIG.win32-x86.Common deleted file mode 100644 index be328cc19..000000000 --- a/configure/os/CONFIG.win32-x86.Common +++ /dev/null @@ -1,28 +0,0 @@ -# CONFIG.win32-x86.Common -# -# Definitions for win32-x86 host archs -# Override these definitions in CONFIG_SITE.win32-x86.Common -#------------------------------------------------------- - -CP = $(PERL) -MExtUtils::Command -e cp -MV = $(PERL) -MExtUtils::Command -e mv -RM = $(PERL) -MExtUtils::Command -e rm_f -MKDIR = $(PERL) -MExtUtils::Command -e mkpath -RMDIR = $(PERL) -MExtUtils::Command -e rm_rf -NOP = $(PERL) -e '' -CAT = $(PERL) -MExtUtils::Command -e cat - -WIND_HOST_TYPE = x86-win32 -OSITHREAD_USE_DEFAULT_STACK = NO - -HOSTEXE=.exe - -# Does not work if using cygwin make -# because HOME is always defined -ifndef HOME -HOME = $(HOMEDRIVE)$(HOMEPATH) -endif - -# Needed to find dlls for base installed build tools (antelope,eflex,...) -PATH := $(EPICS_BASE_BIN):$(PATH) - diff --git a/configure/os/CONFIG.win32-x86.win32-x86 b/configure/os/CONFIG.win32-x86.win32-x86 deleted file mode 100644 index 29c15d3be..000000000 --- a/configure/os/CONFIG.win32-x86.win32-x86 +++ /dev/null @@ -1,283 +0,0 @@ -# CONFIG.win32-x86.win32-x86 -# -# Definitions for win32-x86 host - win32-x86 target build -# Override these definitions in CONFIG_SITE.win32-x86.win32-x86 -#------------------------------------------------------- - -# Win32 valid build types and include directory suffixes - -VALID_BUILDS = Host Ioc - -CMPLR_CLASS = msvc - -OPT_WHOLE_PROGRAM = YES - -#------------------------------------------------------- - -WINLINK = link - -RCCMD = rc -l 0x409 $(INCLUDES) -fo $@ $< - -ARCMD = lib -nologo -verbose -out:$@ $(LIB_OPT_LDFLAGS) $(LIBRARY_LD_OBJS) - -# -# Configure OS vendor C compiler -CC = cl - -# Override CONFIG.gnuCommon settings for cross builds. -GNU = NO -HDEPENDS_METHOD = MKMF - -# Compiler flags for C files (C++ is below) - -# -# -W display warnings at level d -# -W4 is for maximum (lint type) warnings -# -W3 is for production quality warnings -# -W2 displays significant warnings -# -W1 is the default and shows severe warnings only -# -w Set warning C to be shown at level -WARN_CFLAGS_YES = -W3 -WARN_CFLAGS_NO = -W1 - -# -# -Ox maximum optimizations -# -GL whole program optimization -# -Oy- re-enable creation of frame pointers -OPT_CFLAGS_YES_YES = -Ox -GL -Oy- -OPT_CFLAGS_YES_NO = -Ox -Oy- -OPT_CFLAGS_YES = $(OPT_CFLAGS_YES_$(OPT_WHOLE_PROGRAM)) - -# -# -Zi generate program database for debugging information -# -RTCsu enable run-time error checks -OPT_CFLAGS_NO = -Zi -RTCsu - -# specify object file name and location -OBJ_CFLAG = -Fo - -# -# the following options are required when -# vis c++ compiles the code (and includes -# the header files) -# -# -MT static multithreaded C RTL -# -MTd static multithreaded C RTL (debug version) -# -MD multithreaded C RTL in DLL -# -MDd multithreaded C RTL in DLL (debug version) -BUILD_DLL_CFLAGS_NO = -BUILD_DLL_CFLAGS_YES = -DEPICS_BUILD_DLL -BUILD_DLL_CFLAGS = $(BUILD_DLL_CFLAGS_$(SHARED_LIBRARIES)) -VISC_CFLAGS_DEBUG_NO = d -VISC_CFLAGS_DEBUG_YES = -VISC_CFLAGS_DEBUG = $(VISC_CFLAGS_DEBUG_$(HOST_OPT)) -STATIC_CFLAGS_YES= -MT$(VISC_CFLAGS_DEBUG) $(BUILD_DLL_CFLAGS) -STATIC_CFLAGS_NO= -MD$(VISC_CFLAGS_DEBUG) $(BUILD_DLL_CFLAGS) -DEPICS_CALL_DLL - -# OS vendor c preprocessor -CPP = cl -nologo -C -E - -# Configure OS vendor C++ compiler -# -# __STDC__=0 gives us both: -# 1) define STDC for code (pretend ANSI conformance) -# 2) set it to 0 to use MS C "extensions" (open for _open etc.) -# because MS uses: if __STDC__ ... disable many nice things -# -# -EHsc - generate code for exceptions -# -GR - generate code for run time type identification -# -CCC = cl -EHsc -GR -CODE_CPPFLAGS += -nologo -D__STDC__=0 -CODE_CPPFLAGS += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE - - -# Compiler flags for C++ files - -# -# -W disable warnings from levels > n -# -w set warning m to level n -# -w44355 "'this' used in the base initializer list" -# -w44344 "behavior change: use of explicit template arguments results in ..." -# -w44251 "class needs to have dll-interface to be used by clients of ..." -WARN_CXXFLAGS_YES = -W3 -w44355 -w44344 -w44251 -WARN_CXXFLAGS_NO = -W1 - -# -# -Ox maximum optimizations -# -GL whole program optimization -# -Oy- re-enable creation of frame pointers -OPT_CXXFLAGS_YES_YES = -Ox -GL -Oy- -OPT_CXXFLAGS_YES_NO = -Ox -Oy- -OPT_CXXFLAGS_YES = $(OPT_CXXFLAGS_YES_$(OPT_WHOLE_PROGRAM)) - -# -# -Zi generate program database for debugging information -# -RTCsu enable run-time error checks -OPT_CXXFLAGS_NO = -RTCsu -Zi - -# specify object file name and location -OBJ_CXXFLAG = -Fo - -# -# the following options are required when -# vis c++ compiles the code (and includes -# the header files) -# -# -MT static multithreaded C RTL -# -MTd static multithreaded C RTL (debug version) -# -MD multithreaded C RTL in DLL -# -MDd multithreaded C RTL in DLL (debug version) -STATIC_CXXFLAGS_YES= -MT$(VISC_CFLAGS_DEBUG) $(BUILD_DLL_CFLAGS) -STATIC_CXXFLAGS_NO= -MD$(VISC_CFLAGS_DEBUG) $(BUILD_DLL_CFLAGS) -DEPICS_CALL_DLL - -STATIC_LDLIBS_YES=ws2_32.lib advapi32.lib user32.lib kernel32.lib winmm.lib -STATIC_LDLIBS_NO= -STATIC_LDFLAGS= -RANLIB= - -# -# add -profile here to run the ms profiler -# -LTCG whole program optimization -# -incremental:no full linking -# -fixed:no generate relocatable code -# -version:. - only 2 components allowed, 0-65535 each -# -debug generate debugging info -LINK_OPT_FLAGS_WHOLE_YES = -LTCG -LINK_OPT_FLAGS_YES = $(LINK_OPT_FLAGS_WHOLE_$(OPT_WHOLE_PROGRAM)) -LINK_OPT_FLAGS_YES += -incremental:no -opt:ref -LINK_OPT_FLAGS_YES += -release $(PROD_VERSION:%=-version:%) -LINK_OPT_FLAGS_NO = -debug -incremental:no -fixed:no -OPT_LDFLAGS = $(LINK_OPT_FLAGS_$(HOST_OPT)) - -LIB_OPT_FLAGS_YES = $(LINK_OPT_FLAGS_WHOLE_$(OPT_WHOLE_PROGRAM)) -LIB_OPT_LDFLAGS = $(LIB_OPT_FLAGS_$(HOST_OPT)) - -ARCH_DEP_CFLAGS= -SHRLIB_CFLAGS= - -OS_CLASS=WIN32 -POSIX=NO - -# ifdef WIN32 looks better that ifeq ($(OS_CLASS),WIN32) ?? -WIN32=1 - -EXE=.exe -OBJ=.obj -RES=.res - -# MS Visual C++ doesn't recognize *.cc as a C++ source file, -# so C++ compiles get the flag -TP -COMPILER_CXXFLAGS = -TP - -# Operating system flags -OP_SYS_CFLAGS = -OP_SYS_CXXFLAGS = $(COMPILER_CXXFLAGS) - -# Files and flags needed to link DLLs (used in RULES_BUILD) -WIN32_DLLFLAGS = -subsystem:windows -dll $(OPT_LDFLAGS) \ - $(USR_LDFLAGS) $(CMD_LDFLAGS) $(TARGET_LDFLAGS) $(LIB_LDFLAGS) - -# Specify dll .def file only if it exists -DLL_DEF_FLAG = $(addprefix -def:,$(wildcard ../$(addsuffix .def,$*))) - -# A WIN32 dll has three parts: -# x.dll: the real dll (SHRLIBNAME) -# x.lib: what you link to progs that use the dll (DLLSTUB_LIBNAME) -# x.exp: what you need to build the dll (in no variable) -LINK.shrlib = $(WINLINK) -nologo $(WIN32_DLLFLAGS) -out:$@ \ - -implib:$(@:%$(SHRLIB_SUFFIX)=%$(LIB_SUFFIX)) \ - $(DLL_DEF_FLAG) $(LIBRARY_LD_OBJS) $(LIBRARY_LD_RESS) $(SHRLIB_LDLIBS) - -# Adjust names of libraries to build -SHRLIB_SUFFIX_BASE = .dll -SHRLIB_SUFFIX = $(SHRLIB_SUFFIX_BASE) -SHRLIBNAME_YES = $(BUILD_LIBRARY:%=%$(SHRLIB_SUFFIX)) -LOADABLE_SHRLIBNAME = $(LOADABLE_BUILD_LIBRARY:%=%$(SHRLIB_SUFFIX)) -TESTSHRLIBNAME_YES = $(TESTBUILD_LIBRARY:%=%$(SHRLIB_SUFFIX_BASE)) - -# When SHARED_LIBRARIES is YES we are building a DLL shared library. -# When SHARED_LIBRARIES is NO we are building an object library -DLLSTUB_SUFFIX = .lib -DLLSTUB_LIBNAME_YES = $(BUILD_LIBRARY:%=%.lib) -DLLSTUB_LIBNAME = $(DLLSTUB_LIBNAME_$(SHARED_LIBRARIES)) -TESTDLLSTUB_LIBNAME_YES = $(TESTBUILD_LIBRARY:%=%.lib) -TESTDLLSTUB_LIBNAME = $(TESTDLLSTUB_LIBNAME_$(SHARED_LIBRARIES)) - -LIB_PREFIX= -LIB_SUFFIX=.lib -LIBNAME_NO = $(BUILD_LIBRARY:%=%.lib) -LIBNAME = $(LIBNAME_$(SHARED_LIBRARIES)) -TESTLIBNAME_NO = $(TESTBUILD_LIBRARY:%=%.lib) -TESTLIBNAME = $(TESTLIBNAME_$(SHARED_LIBRARIES)) - -# dll install location -INSTALL_SHRLIB = $(INSTALL_BIN) - - -#-------------------------------------------------- -# Products dependancy definitions - -PROD_DEPLIBS = $(foreach lib, $(PROD_LIBS) $(USR_LIBS), \ - $(firstword $(wildcard \ - $(addsuffix /$(DLLSTUB_PREFIX)$(lib)$(DLLSTUB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - $(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - $(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - ) $(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), \ - $(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB))))) - - -PROD_LDLIBS += $($*_DEPLIBS) $(PROD_DEPLIBS) -PROD_LDLIBS += $(addsuffix .lib, \ - $($*_SYS_LIBS) $(PROD_SYS_LIBS) $(USR_SYS_LIBS)) - -LDLIBS_STATIC_YES = LDLIBS -LDLIBS_SHARED_NO = LDLIBS -PROD_LDLIBS += $(STATIC_LDLIBS) \ - $($(firstword $(LDLIBS_STATIC_$(STATIC_BUILD)) \ - $(LDLIBS_SHARED_$(SHARED_LIBRARIES)))) - -#-------------------------------------------------- -# Libraries dependancy definitions - -# libs that we need to link the DLL with -# (it isnt necessary to rebuild the dll if these change) - -SHRLIB_DEPLIBS = $(foreach lib, $(LIB_LIBS) $(USR_LIBS), \ - $(firstword $(wildcard \ - $(addsuffix /$(DLLSTUB_PREFIX)$(lib)$(DLLSTUB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - $(addsuffix /$(SHRLIB_PREFIX)$(lib)*$(SHRLIB_SUFFIX_BASE)*, \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - $(addsuffix /$(LIB_PREFIX)$(lib)$(LIB_SUFFIX), \ - $($(lib)_DIR) $(SHRLIB_SEARCH_DIRS)) \ - ) $(addsuffix /$(BUILDLIB_PREFIX)$(lib)$(BUILDLIB_SUFFIX), \ - $(if $(filter $(lib),$(TESTLIBRARY)),.,$(INSTALL_LIB))))) - - -SHRLIB_LDLIBS += $($*_DLL_DEPLIBS) $($*_DEPLIBS) $(SHRLIB_DEPLIBS) -SHRLIB_LDLIBS += $(addsuffix .lib, \ - $($*_SYS_DLL_LIBS) \ - $($*_SYS_LIBS) $(LIB_SYS_LIBS) $(USR_SYS_LIBS) ) - -#-------------------------------------------------- -# Linker definition -LINK.cpp = $(WINLINK) -nologo $(STATIC_LDFLAGS) $(LDFLAGS) $(PROD_LDFLAGS) \ - -out:$@ $(PROD_LD_OBJS) $(PROD_LD_RESS) $(PROD_LDLIBS) - -#-------------------------------------------------- -# UseManifestTool.pl checks MS Visual c++ compiler version number to -# decide whether or not to use the Manifest Tool command to embed the -# linker created .manifest file into a library or product target. -# useManifestTool.pl returns 0(don't use) or 1(use). -# -MT.exe = mt.exe -nologo -manifest $@.manifest -MT_DLL_COMMAND1 = $(MT.exe) "-outputresource:$@;\#2" -MT_EXE_COMMAND_YES = -MT_EXE_COMMAND_NO = $(MT.exe) "-outputresource:$@;\#1" -MT_EXE_COMMAND1 = $(MT_EXE_COMMAND_$(STATIC_BUILD)) -MT_DLL_COMMAND = $(MT_DLL_COMMAND$(shell $(PERL) $(TOOLS)/useManifestTool.pl)) -MT_EXE_COMMAND = $(MT_EXE_COMMAND$(shell $(PERL) $(TOOLS)/useManifestTool.pl)) diff --git a/configure/os/CONFIG.win32-x86.win32-x86-debug b/configure/os/CONFIG.win32-x86.win32-x86-debug deleted file mode 100644 index a71c9957a..000000000 --- a/configure/os/CONFIG.win32-x86.win32-x86-debug +++ /dev/null @@ -1,15 +0,0 @@ -# CONFIG.win32-x86.win32-x86-debug -# -# Definitions for win32-x86 host - win32-x86-debug target build -# Override these definitions in CONFIG_SITE.win32-x86.win32-x86-debug -#------------------------------------------------------- - -#Include definitions common to win32-x86 builds -include $(CONFIG)/os/CONFIG.win32-x86.win32-x86 --include $(CONFIG)/os/CONFIG_SITE.win32-x86.win32-x86 - -# Override CONFIG.CrossCommon settings: -BUILD_CLASS = HOST - -# Override CONFIG_SITE settings: -HOST_OPT = NO diff --git a/configure/os/CONFIG.win32-x86.win32-x86-static b/configure/os/CONFIG.win32-x86.win32-x86-static deleted file mode 100644 index ae5313a5c..000000000 --- a/configure/os/CONFIG.win32-x86.win32-x86-static +++ /dev/null @@ -1,16 +0,0 @@ -# CONFIG.win32-x86.win32-x86-static -# -# Definitions for win32-x86 host - win32-x86-static target build -# Override these definitions in CONFIG_SITE.win32-x86.win32-x86-static -#------------------------------------------------------- - -#Include definitions common to win32-x86 builds -include $(CONFIG)/os/CONFIG.win32-x86.win32-x86 --include $(CONFIG)/os/CONFIG_SITE.win32-x86.win32-x86 - -# Override CONFIG.CrossCommon settings: -BUILD_CLASS = HOST - -# Override CONFIG_SITE settings: -SHARED_LIBRARIES = NO -STATIC_BUILD = YES diff --git a/configure/os/CONFIG.windows-x64-debug.Common b/configure/os/CONFIG.windows-x64-debug.Common deleted file mode 100644 index ad433bc8f..000000000 --- a/configure/os/CONFIG.windows-x64-debug.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.windows-x64-debug.Common -# -# Definitions for windows-x64-debug host arch -# Override these definitions in CONFIG_SITE.windows-x64-debug.Common -#------------------------------------------------------- - -#Include definitions common to windows-x64 hosts -include $(CONFIG)/os/CONFIG.windows-x64.Common - diff --git a/configure/os/CONFIG.windows-x64-debug.windows-x64-debug b/configure/os/CONFIG.windows-x64-debug.windows-x64-debug deleted file mode 100644 index 0a2c88d4f..000000000 --- a/configure/os/CONFIG.windows-x64-debug.windows-x64-debug +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.windows-x64-debug.windows-x64-debug -# -# Definitions for windows-x64 debug compiler host - windows-x64 debug compiler target builds -# Sites may override these definitions in CONFIG_SITE.windows-x64-debug.windows-x64-debug -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.windows-x64.windows-x64 - -HOST_OPT=NO diff --git a/configure/os/CONFIG.windows-x64-mingw.Common b/configure/os/CONFIG.windows-x64-mingw.Common deleted file mode 100644 index 812168480..000000000 --- a/configure/os/CONFIG.windows-x64-mingw.Common +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.windows-x64-mingw.Common -# -# Definitions for windows-x64-mingw host archs -# Sites may override these definitions in CONFIG_SITE.windows-x64-mingw.Common -#------------------------------------------------------- - -include $(CONFIG)/os/CONFIG.win32-x86-mingw.Common - diff --git a/configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw b/configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw deleted file mode 100644 index d8e49637e..000000000 --- a/configure/os/CONFIG.windows-x64-mingw.windows-x64-mingw +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG.windows-x64-mingw.windows-x64-mingw -# -# Definitions for windows-x64-mingw target archs -# Sites may override these definitions in CONFIG_SITE.windows-x64-mingw.windows-x64-mingw -#------------------------------------------------------- - -# Include common gnu compiler definitions -include $(CONFIG)/os/CONFIG.win32-x86-mingw.win32-x86-mingw diff --git a/configure/os/CONFIG.windows-x64-static.Common b/configure/os/CONFIG.windows-x64-static.Common deleted file mode 100644 index 88bef64ff..000000000 --- a/configure/os/CONFIG.windows-x64-static.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.windows-x64-static.Common -# -# Definitions for windows-x64-static host archs -# Override these definitions in CONFIG_SITE.windows-x64-static.Common -#------------------------------------------------------- - -#Include definitions common to windows-x64 hosts -include $(CONFIG)/os/CONFIG.windows-x64.Common - diff --git a/configure/os/CONFIG.windows-x64-static.windows-x64-static b/configure/os/CONFIG.windows-x64-static.windows-x64-static deleted file mode 100644 index 097e65558..000000000 --- a/configure/os/CONFIG.windows-x64-static.windows-x64-static +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG.windows-x64-static.windows-x64-static -# -# Definitions for windows-x64-static host - windows-x64-static target build -# Override these definitions in CONFIG_SITE.windows-x64-static.windows-x64-static -#------------------------------------------------------- - -#Include definitions common to windows-x64 builds -include $(CONFIG)/os/CONFIG.windows-x64.windows-x64 - -# Override CONFIG_SITE settings: -SHARED_LIBRARIES = NO -STATIC_BUILD= YES diff --git a/configure/os/CONFIG.windows-x64.Common b/configure/os/CONFIG.windows-x64.Common deleted file mode 100644 index de2fa3f57..000000000 --- a/configure/os/CONFIG.windows-x64.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG.windows-x64.Common -# -# Definitions for windows-x64 host arch -# Override these definitions in CONFIG_SITE.windows-x64.Common -#------------------------------------------------------- - -#Include definitions common to win32-x86 hosts -include $(CONFIG)/os/CONFIG.win32-x86.Common - diff --git a/configure/os/CONFIG.windows-x64.windows-x64 b/configure/os/CONFIG.windows-x64.windows-x64 deleted file mode 100644 index dcb6e82de..000000000 --- a/configure/os/CONFIG.windows-x64.windows-x64 +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG.windows-x64.windows-x64 -# -# Definitions for windows-x64 host - windows-x64 target build -# Override these definitions in CONFIG_SITE.windows-x64.windows-x64 -#------------------------------------------------------- - -#Include definitions common to win32-x86 builds -include $(CONFIG)/os/CONFIG.win32-x86.win32-x86 --include $(CONFIG)/os/CONFIG_SITE.win32-x86.win32-x86 - -OPT_LDFLAGS += -MACHINE:X64 -# -MACHINE:X64 -# -MACHINE:IA64 (Itanium) -# -MACHINE:X86 diff --git a/configure/os/CONFIG.windows-x64.windows-x64-debug b/configure/os/CONFIG.windows-x64.windows-x64-debug deleted file mode 100644 index 8c97ac343..000000000 --- a/configure/os/CONFIG.windows-x64.windows-x64-debug +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG.windows-x64.windows-x64-debug -# -# Definitions for windows-x64 host - windows-x64-debug target build -# Override these definitions in CONFIG_SITE.windows-x64.windows-x64-debug -#------------------------------------------------------- - -#Include definitions common to windows-x64 builds -include $(CONFIG)/os/CONFIG.windows-x64.windows-x64 - -# Override CONFIG.CrossCommon settings: -BUILD_CLASS = HOST - -# Override CONFIG_SITE settings: -HOST_OPT=NO diff --git a/configure/os/CONFIG.windows-x64.windows-x64-static b/configure/os/CONFIG.windows-x64.windows-x64-static deleted file mode 100644 index 49bf2e0f6..000000000 --- a/configure/os/CONFIG.windows-x64.windows-x64-static +++ /dev/null @@ -1,15 +0,0 @@ -# CONFIG.windows-x64.windows-x64-static -# -# Definitions for windows-x64 host - windows-x64-static target build -# Override these definitions in CONFIG_SITE.windows-x64.windows-x64-static -#------------------------------------------------------- - -#Include definitions common to windows-x64 builds -include $(CONFIG)/os/CONFIG.windows-x64.windows-x64 - -# Override CONFIG.CrossCommon settings: -BUILD_CLASS = HOST - -# Override CONFIG_SITE settings: -SHARED_LIBRARIES = NO -STATIC_BUILD = YES diff --git a/configure/os/CONFIG_SITE.Common.RTEMS b/configure/os/CONFIG_SITE.Common.RTEMS deleted file mode 100644 index 0b5d227ee..000000000 --- a/configure/os/CONFIG_SITE.Common.RTEMS +++ /dev/null @@ -1,33 +0,0 @@ -# CONFIG_SITE.Common.RTEMS -# -# Site-specific information for all RTEMS targets -#------------------------------------------------------- - -# Where to find RTEMS -# -# APS: -RTEMS_VERSION = 4.10.2 -RTEMS_BASE = /usr/local/vw/rtems/rtems-$(RTEMS_VERSION) - -# Cross-compile toolchain in $(RTEMS_TOOLS)/bin -# -RTEMS_TOOLS = $(RTEMS_BASE) - -# Link Generic System loadable objects instead of full executable. -# -# A GeSys object is similar to a shared library. It can be (un)loaded -# at runtime by the Generic System loader which is available as a -# patch against RTEMS. -USE_GESYS = NO - -# If you're using neither BOOTP/DHCP nor FLASH to pick up your IOC -# network configuration you must uncomment and specify your Internet -# Domain Name here -# -#OP_SYS_CFLAGS += -DRTEMS_NETWORK_CONFIG_DNS_DOMAINNAME= - -# Select the command-line-input library to use -# -COMMANDLINE_LIBRARY = EPICS -#COMMANDLINE_LIBRARY = LIBTECLA -#COMMANDLINE_LIBRARY = READLINE diff --git a/configure/os/CONFIG_SITE.Common.RTEMS-pc386 b/configure/os/CONFIG_SITE.Common.RTEMS-pc386 deleted file mode 100644 index c772c44fc..000000000 --- a/configure/os/CONFIG_SITE.Common.RTEMS-pc386 +++ /dev/null @@ -1,3 +0,0 @@ -# -# Site-specific overrides for RTEMS-pc386 target -# diff --git a/configure/os/CONFIG_SITE.Common.cygwin-x86 b/configure/os/CONFIG_SITE.Common.cygwin-x86 deleted file mode 100644 index eae9ee5dd..000000000 --- a/configure/os/CONFIG_SITE.Common.cygwin-x86 +++ /dev/null @@ -1,18 +0,0 @@ -# CONFIG_SITE.Common.cygwin-x86 -# -# Site Specific definitions for cygwin-x86 target - -# Depending on your version of Cygwin you'll want one of the following -# lines to enable command-line editing and history in iocsh. If you're -# not sure which, start with the top one and work downwards until the -# build doesn't fail to link the readline library. If none of them work, -# comment them all out to build without readline support. - -# Needs -lncursesw (Cygwin 1.7): -COMMANDLINE_LIBRARY = READLINE_NCURSESW - -# Needs -lcurses (older versions) -#COMMANDLINE_LIBRARY = READLINE_CURSES - -# No other libraries needed -#COMMANDLINE_LIBRARY = READLINE diff --git a/configure/os/CONFIG_SITE.Common.cygwin-x86_64 b/configure/os/CONFIG_SITE.Common.cygwin-x86_64 deleted file mode 100644 index 8d318e04e..000000000 --- a/configure/os/CONFIG_SITE.Common.cygwin-x86_64 +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG_SITE.Common.cygwin-x86_64 -# -# Site Specific definitions for cygwin-x86_64 target -# Only the local epics system manager should modify this file - -# If readline is installed uncomment the following line -# to add command-line editing and history support -#COMMANDLINE_LIBRARY = READLINE - -# Uncomment the following line if readline has problems -#LDLIBS_READLINE = -lreadline -lcurses - - -# It makes sense to include debugging symbols even in optimized builds -# in case you want to attach gdb to the process or examine a core-dump. -# This does cost disk space, but not memory as debug symbols are not -# loaded into RAM when the binary is loaded. -OPT_CFLAGS_YES += -g -OPT_CXXFLAGS_YES += -g - diff --git a/configure/os/CONFIG_SITE.Common.darwin-ppc b/configure/os/CONFIG_SITE.Common.darwin-ppc deleted file mode 100644 index a2550147f..000000000 --- a/configure/os/CONFIG_SITE.Common.darwin-ppc +++ /dev/null @@ -1,12 +0,0 @@ -# CONFIG_SITE.Common.darwin-ppc -# -# Site override definitions for darwin-ppc target builds -#------------------------------------------------------- - -# Select which CPU architectures to include in your universal binaries: -# ppc -# ppc64 - Not tested - -ARCH_CLASS = ppc -#ARCH_CLASS = ppc64 -#ARCH_CLASS = ppc ppc64 diff --git a/configure/os/CONFIG_SITE.Common.darwin-ppcx86 b/configure/os/CONFIG_SITE.Common.darwin-ppcx86 deleted file mode 100644 index 2191d54f8..000000000 --- a/configure/os/CONFIG_SITE.Common.darwin-ppcx86 +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG_SITE.Common.darwin-ppcx86 -# -# Site override definitions for darwin-ppcx86 target builds -#---------------------------------------------------------- - -# Select which CPU architectures to include in your universal binaries: -# ppc -# i386 -# ppc64 - Not tested -# x86_64 - Needs MacOS 10.4 with Universal SDK, or 10.5 or later. - -ARCH_CLASS = ppc i386 -#ARCH_CLASS = ppc x86_64 -#ARCH_CLASS = ppc i386 x86_64 -#ARCH_CLASS = ppc64 i386 -#ARCH_CLASS = ppc64 x86_64 -#ARCH_CLASS = ppc64 i386 x86_64 -#ARCH_CLASS = ppc ppc64 i386 -#ARCH_CLASS = ppc ppc64 x86_64 -#ARCH_CLASS = ppc ppc64 i386 x86_64 diff --git a/configure/os/CONFIG_SITE.Common.darwin-x86 b/configure/os/CONFIG_SITE.Common.darwin-x86 deleted file mode 100644 index 1c5c93696..000000000 --- a/configure/os/CONFIG_SITE.Common.darwin-x86 +++ /dev/null @@ -1,36 +0,0 @@ -# CONFIG_SITE.Common.darwin-x86 -# -# Site override definitions for darwin-x86 target builds -#------------------------------------------------------- - -# Select which CPU architecture(s) to include in your MacOS binaries: -# i386, x86_64, or both (fat binaries). - -#ARCH_CLASS = i386 -ARCH_CLASS = x86_64 -#ARCH_CLASS = i386 x86_64 - -# -# Uncomment the following 3 lines to build with Apple's GCC instead of CLANG. -# -#CMPLR_CLASS = gcc -#CC = gcc -#CCC = g++ -#GNU = YES - - -# To use MacPorts GCC uncomment (and modify if necessary) the following: - -#GNU_DIR = /opt/local -#CMPLR_CLASS = gcc -#CC = $(GNU_BIN)/gcc -m64 -#CCC = $(GNU_BIN)/g++ -m64 -#GNU = YES - -# If you see this or similar errors while building in the src/cap5 directory -# gcc: error: unrecognized option '-no-cpp-precomp' -# the problem is due to the ccflags configuration that your version of Perl -# was built with. You can replace the Cap5_CFLAGS setting in the Makefile -# with a hand-edited set of flags for building that Perl library, or ignore -# this problem if you don't need to use Channel Access from Perl. - diff --git a/configure/os/CONFIG_SITE.Common.ios-arm b/configure/os/CONFIG_SITE.Common.ios-arm deleted file mode 100644 index f406007d1..000000000 --- a/configure/os/CONFIG_SITE.Common.ios-arm +++ /dev/null @@ -1,30 +0,0 @@ -# CONFIG_SITE.Common.ios-arm -# -# Site-specific settings for ios-arm target builds -#------------------------------------------------------- - -# Which ARM instruction set(s) to generate code for: -# Most iOS devices can run programs compiled for older -# instruction sets, although the newer instructions are -# more efficient. -# -# Apple's compilers can build for multiple architectures, -# generating a Universal binary. This is larger and takes -# longer to compile, but runs efficiently on all devices. -# -# Xcode 4.5 dropped support for the ARMv6. -# -# arm64 devices: iPhone 5S, 6 and 6 Plus, iPad Air Gen 1 and 2, -# iPad Mini Gen 2 and 3 -# armv7s devices: iPhone 5 and 5C, iPad Gen 4 -# armv7 devices: iPhone 3GS, 4 and 4S, iPod Touch Gen 3 to 5 -# iPad Gen 1 to 3, iPad Mini, Apple TV Gen 2 and 3 -# armv6 devices: iPhone 1 and 3G, iPod Touch Gen 1 and 2 - -#ARCH_CLASS = arm64 -#ARCH_CLASS = armv7s arm64 -ARCH_CLASS = armv7 armv7s arm64 -#ARCH_CLASS = armv7 armv7s -#ARCH_CLASS = armv7 -#ARCH_CLASS = armv6 armv7 -#ARCH_CLASS = armv6 diff --git a/configure/os/CONFIG_SITE.Common.ios-x86 b/configure/os/CONFIG_SITE.Common.ios-x86 deleted file mode 100644 index e97c8b778..000000000 --- a/configure/os/CONFIG_SITE.Common.ios-x86 +++ /dev/null @@ -1,16 +0,0 @@ -# CONFIG_SITE.Common.ios-x86 -# -# Site-specific settings for ios-x86 target builds -#------------------------------------------------------- - -# Which x86 instruction set(s) to generate code for: -# The iPhone Simulator now supports both 32-bit and 64-bit -# instruction sets since the iPhone 6 uses a 64-bit CPU. -# -# Apple's compilers can build for multiple architectures, -# generating a Universal binary. This is larger and takes -# longer to compile, but runs efficiently on all devices. - -#ARCH_CLASS = i386 -ARCH_CLASS = i386 x86_64 -#ARCH_CLASS = x86_64 diff --git a/configure/os/CONFIG_SITE.Common.iosCommon b/configure/os/CONFIG_SITE.Common.iosCommon deleted file mode 100644 index 573d855ae..000000000 --- a/configure/os/CONFIG_SITE.Common.iosCommon +++ /dev/null @@ -1,42 +0,0 @@ -# CONFIG_SITE.Common.iosCommon -# -# Site-specific settings for Apple iOS builds -#------------------------------------------------------- - -# Minimum version of iOS the executables must run on. -# Earlier versions may work, if XCode supports them. - -#IOS_DEPLOYMENT_TARGET = 5.0 -#IOS_DEPLOYMENT_TARGET = 5.1 -#IOS_DEPLOYMENT_TARGET = 6.0 -#IOS_DEPLOYMENT_TARGET = 6.1 -#IOS_DEPLOYMENT_TARGET = 7.0 -#IOS_DEPLOYMENT_TARGET = 7.1 -IOS_DEPLOYMENT_TARGET = 8.0 -#IOS_DEPLOYMENT_TARGET = 8.1 - -# Older versions of Xcode may require this SDK_DIR definition -#SDK_DIR = $(PLATFORM_DIR)/Developer/SDKs/$(IOS_PLATFORM)$(IOS_DEPLOYMENT_TARGET).sdk - - -# Which compiler to use: -# CLANG is required for Xcode 5.0 and later -# LLVM_GNU uses the llvm-gcc and llvm-g++ compilers -# GNU is needed for older versions of Xcode - -COMPILER = CLANG -#COMPILER = LLVM_GNU -#COMPILER = GNU - - -# Most sites will want to build shared libraries (which is the -# default), but if you get an error from ld while building libCom, -# try uncommenting this, which is needed for some compiler versions: - -#SHARED_LIBRARIES = NO - - -# Get platform path from OS, these are usually correct: - -XCODE_PATH := $(shell xcode-select -print-path) -PLATFORM_DIR = $(XCODE_PATH)/Platforms/$(IOS_PLATFORM).platform diff --git a/configure/os/CONFIG_SITE.Common.linux-arm b/configure/os/CONFIG_SITE.Common.linux-arm deleted file mode 100644 index 556ac6f09..000000000 --- a/configure/os/CONFIG_SITE.Common.linux-arm +++ /dev/null @@ -1,39 +0,0 @@ -# CONFIG_SITE.Common.linux-arm -# -# Site Specific definitions for all linux-arm targets -#------------------------------------------------------- - -# NOTE for SHARED_LIBRARIES: In most cases if this is set to YES the -# shared libraries will be found automatically. However if the .so -# files are installed at a different path to their compile-time path -# then in order to be found at runtime do one of these: -# a) LD_LIBRARY_PATH must include the full absolute pathname to -# $(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when invoking base -# executables. -# b) Add the runtime path to SHRLIB_DEPLIB_DIRS and PROD_DEPLIB_DIRS, which -# will add the named directory to the list contained in the executables. -# c) Add the runtime path to /etc/ld.so.conf and run ldconfig -# to inform the system of the shared library location. - -# Depending on your version of Linux you'll want one of the following -# lines to enable command-line editing and history in iocsh. If you're -# not sure which, start with the top one and work downwards until the -# build doesn't fail to link the readline library. If none of them work, -# comment them all out to build without readline support. - -# No other libraries needed (recent Fedora, Ubuntu etc.): -#COMMANDLINE_LIBRARY = READLINE - -# Needs -lncurses (RHEL 5 etc.): -#COMMANDLINE_LIBRARY = READLINE_NCURSES - -# Needs -lcurses (older versions) -#COMMANDLINE_LIBRARY = READLINE_CURSES - - -# It makes sense to include debugging symbols even in optimized builds -# in case you want to attach gdb to the process or examine a core-dump. -# This does cost disk space, but not memory as debug symbols are not -# loaded into RAM when the binary is loaded. -OPT_CFLAGS_YES += -g -OPT_CXXFLAGS_YES += -g diff --git a/configure/os/CONFIG_SITE.Common.linux-cris b/configure/os/CONFIG_SITE.Common.linux-cris deleted file mode 100644 index b17cb0ee5..000000000 --- a/configure/os/CONFIG_SITE.Common.linux-cris +++ /dev/null @@ -1,35 +0,0 @@ -# CONFIG_SITE.Common.linux-cris -# -# Site Specific definitions for linux-cris target -# Only the local epics system manager should modify this file - -# NOTE for SHARED_LIBRARIES: In most cases if this is set to YES the -# shared libraries will be found automatically. However if the .so -# files are installed at a different path to their compile-time path -# then in order to be found at runtime do one of these: -# a) LD_LIBRARY_PATH must include the full absolute pathname to -# $(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when invoking base -# executables. -# b) Add the runtime path to SHRLIB_DEPLIB_DIRS and PROD_DEPLIB_DIRS, which -# will add the named directory to the list contained in the executables. -# c) Add the runtime path to /etc/ld.so.conf and run ldconfig -# to inform the system of the shared library location. - -# Depending on your version of Linux you may want one of the following -# lines to enable command-line editing and history in iocsh. If you're -# not sure which, start with the top one and work downwards until the -# build doesn't fail to link the readline library. If none of them work, -# comment them all out to build without readline support. - -# No other libraries needed (recent Fedora, Ubuntu etc.): -#COMMANDLINE_LIBRARY = READLINE - -# Needs -lncurses (RHEL 5 etc.): -#COMMANDLINE_LIBRARY = READLINE_NCURSES - -# Needs -lcurses (older versions) -#COMMANDLINE_LIBRARY = READLINE_CURSES - - -OP_SYS_CFLAGS += -g - diff --git a/configure/os/CONFIG_SITE.Common.linux-microblaze b/configure/os/CONFIG_SITE.Common.linux-microblaze deleted file mode 100644 index 43c543c2b..000000000 --- a/configure/os/CONFIG_SITE.Common.linux-microblaze +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG_SITE.Common.linux-microblaze -# -# Site specific definitions for linux-microblaze target builds. -#------------------------------------------------------- - -# The gnu tools for cross compiling for MicroBlaze (little endian) -# on Linux can be downloaded from the Xilinx git server: -# git clone git://git.xilinx.com/xldk/microblaze_v2.0_le.git -# -# The result contains a .tgz file with the tool-chain in it. -# Set GNU_DIR to point to the un-tarred tool-chain: - -GNU_DIR = /usr/local/vw/microblaze-2.0/microblazeel-unknown-linux-gnu - diff --git a/configure/os/CONFIG_SITE.Common.linux-x86 b/configure/os/CONFIG_SITE.Common.linux-x86 deleted file mode 100644 index 07182820d..000000000 --- a/configure/os/CONFIG_SITE.Common.linux-x86 +++ /dev/null @@ -1,56 +0,0 @@ -# CONFIG_SITE.Common.linux-x86 -# -# Site Specific definitions for linux-x86 target -# Only the local epics system manager should modify this file - -# NOTE for SHARED_LIBRARIES: In most cases if this is set to YES the -# shared libraries will be found automatically. However if the .so -# files are installed at a different path to their compile-time path -# then in order to be found at runtime do one of these: -# a) LD_LIBRARY_PATH must include the full absolute pathname to -# $(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when invoking base -# executables. -# b) Add the runtime path to SHRLIB_DEPLIB_DIRS and PROD_DEPLIB_DIRS, which -# will add the named directory to the list contained in the executables. -# c) Add the runtime path to /etc/ld.so.conf and run ldconfig -# to inform the system of the shared library location. - -# Depending on your version of Linux you'll want one of the following -# lines to enable command-line editing and history in iocsh. If you're -# not sure which, start with the top one and work downwards until the -# build doesn't fail to link the readline library. If none of them work, -# comment them all out to build without readline support. - -# No other libraries needed (recent Fedora, Ubuntu etc.): -COMMANDLINE_LIBRARY = READLINE - -# Needs -lncurses (RHEL 5 etc.): -#COMMANDLINE_LIBRARY = READLINE_NCURSES - -# Needs -lcurses (older versions) -#COMMANDLINE_LIBRARY = READLINE_CURSES - - -# Permit access to 64-bit file-systems -OP_SYS_CFLAGS += -D_FILE_OFFSET_BITS=64 - - -# Uncomment the followings lines to build with CLANG instead of GCC. -# -#GNU = NO -#CMPLR_CLASS = clang -#CC = clang -#CCC = clang++ - - -# It makes sense to include debugging symbols even in optimized builds -# in case you want to attach gdb to the process or examine a core-dump. -# This does cost disk space, but not memory as debug symbols are not -# loaded into RAM when the binary is loaded. -OPT_CFLAGS_YES += -g -OPT_CXXFLAGS_YES += -g - - -# Tune GNU compiler output for a specific 32-bit cpu-type -# (e.g. generic, native, i386, i686, pentium2/3/4, prescott, k6, athlon etc.) -GNU_TUNE_CFLAGS = -mtune=generic diff --git a/configure/os/CONFIG_SITE.Common.linux-x86_64 b/configure/os/CONFIG_SITE.Common.linux-x86_64 deleted file mode 100644 index 18fb2974d..000000000 --- a/configure/os/CONFIG_SITE.Common.linux-x86_64 +++ /dev/null @@ -1,52 +0,0 @@ -# CONFIG_SITE.Common.linux-x86_64 -# -# Site Specific definitions for linux-x86_64 target -# Only the local epics system manager should modify this file - -# NOTE for SHARED_LIBRARIES: In most cases if this is set to YES the -# shared libraries will be found automatically. However if the .so -# files are installed at a different path to their compile-time path -# then in order to be found at runtime do one of these: -# a) LD_LIBRARY_PATH must include the full absolute pathname to -# $(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when invoking base -# executables. -# b) Add the runtime path to SHRLIB_DEPLIB_DIRS and PROD_DEPLIB_DIRS, which -# will add the named directory to the list contained in the executables. -# c) Add the runtime path to /etc/ld.so.conf and run ldconfig -# to inform the system of the shared library location. - -# Depending on your version of Linux you'll want one of the following -# lines to enable command-line editing and history in iocsh. If you're -# not sure which, start with the top one and work downwards until the -# build doesn't fail to link the readline library. If none of them work, -# comment them all out to build without readline support. - -# No other libraries needed (recent Fedora, Ubuntu etc.): -COMMANDLINE_LIBRARY = READLINE - -# Needs -lncurses (RHEL 5 etc.): -#COMMANDLINE_LIBRARY = READLINE_NCURSES - -# Needs -lcurses (older versions) -#COMMANDLINE_LIBRARY = READLINE_CURSES - - -# Uncomment the followings lines to build with CLANG instead of GCC. -# -#GNU = NO -#CMPLR_CLASS = clang -#CC = clang -#CCC = clang++ - - -# It makes sense to include debugging symbols even in optimized builds -# in case you want to attach gdb to the process or examine a core-dump. -# This does cost disk space, but not memory as debug symbols are not -# loaded into RAM when the binary is loaded. -OPT_CFLAGS_YES += -g -OPT_CXXFLAGS_YES += -g - - -# Tune GNU compiler output for a specific 64-bit cpu-type -# (e.g. generic, native, core2, nocona, k8, opteron, athlon64, barcelona etc.) -GNU_TUNE_CFLAGS = -mtune=generic diff --git a/configure/os/CONFIG_SITE.Common.linux-xscale_be b/configure/os/CONFIG_SITE.Common.linux-xscale_be deleted file mode 100644 index 69efd6ffa..000000000 --- a/configure/os/CONFIG_SITE.Common.linux-xscale_be +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG_SITE.Common.linux-xscale_be -# -# Site specific definitions for linux-xscale_be target builds. -#------------------------------------------------------- - -# Set GNU_DIR to point to directory containing the tool-chain - -# APS: -GNU_DIR = /usr/local/vw/xscale_be - diff --git a/configure/os/CONFIG_SITE.Common.solaris-sparc b/configure/os/CONFIG_SITE.Common.solaris-sparc deleted file mode 100644 index e8a6c875a..000000000 --- a/configure/os/CONFIG_SITE.Common.solaris-sparc +++ /dev/null @@ -1,17 +0,0 @@ -# CONFIG_SITE.Common.solaris-sparc -# -# Site Specific definitions for solaris-sparc target -# Only the local epics system manager should modify this file - -# location of the Solaris Studio (was SunPro) compilers -SPARCWORKS = /opt/SUNWspro -#SPARCWORKS = /opt/solarisstudio12.3 - -# If readline is installed, uncomment the following macro definition -# to use it for command-line editing and history support -#COMMANDLINE_LIBRARY = READLINE - -# Use stLport library instead of default Cstd library -# Must be either YES or NO -#USE_STLPORT=YES - diff --git a/configure/os/CONFIG_SITE.Common.solaris-sparc-gnu b/configure/os/CONFIG_SITE.Common.solaris-sparc-gnu deleted file mode 100644 index 6e9c00f65..000000000 --- a/configure/os/CONFIG_SITE.Common.solaris-sparc-gnu +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG_SITE.Common.solaris-sparc-gnu -# -# Site Specific definitions for solaris-sparc-gnu target -# Only the local epics system manager should modify this file - -# Include definitions common to all solaris-sparc-gnu target archs -include $(CONFIG)/os/CONFIG_SITE.Common.solaris-sparc - -# solaris 10 default location -#GNU_DIR=/usr/sfw - -# APS site override -GNU_DIR = /usr/local diff --git a/configure/os/CONFIG_SITE.Common.solaris-sparc64 b/configure/os/CONFIG_SITE.Common.solaris-sparc64 deleted file mode 100644 index 5a6bf8d82..000000000 --- a/configure/os/CONFIG_SITE.Common.solaris-sparc64 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.Common.solaris-sparc64 -# -# Site Specific definitions for solaris-sparc64 target -# Only the local epics system manager should modify this file - -# Include definitions common to all solaris-sparc64 target archs -include $(CONFIG)/os/CONFIG_SITE.Common.solaris-sparc - -COMMANDLINE_LIBRARY = EPICS diff --git a/configure/os/CONFIG_SITE.Common.solaris-sparc64-gnu b/configure/os/CONFIG_SITE.Common.solaris-sparc64-gnu deleted file mode 100644 index d7e1d726d..000000000 --- a/configure/os/CONFIG_SITE.Common.solaris-sparc64-gnu +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.Common.solaris-sparc64-gnu -# -# Site Specific definitions for solaris-sparc64-gnu target -# Only the local epics system manager should modify this file - -# Include definitions common to all solaris-sparc-gnu target archs -include $(CONFIG)/os/CONFIG_SITE.Common.solaris-sparc-gnu - -COMMANDLINE_LIBRARY = EPICS diff --git a/configure/os/CONFIG_SITE.Common.solaris-x86 b/configure/os/CONFIG_SITE.Common.solaris-x86 deleted file mode 100644 index 77bb8d45c..000000000 --- a/configure/os/CONFIG_SITE.Common.solaris-x86 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.Common.solaris-x86 -# -# Site Specific definitions for solaris-x86 targets -# Only the local epics system manager should modify this file - -# location of the Solaris Studio (was SunPro) compilers -SPARCWORKS = /opt/SUNWspro -#SPARCWORKS = /opt/solarisstudio12.3 - diff --git a/configure/os/CONFIG_SITE.Common.solaris-x86-gnu b/configure/os/CONFIG_SITE.Common.solaris-x86-gnu deleted file mode 100644 index 0f93f0f18..000000000 --- a/configure/os/CONFIG_SITE.Common.solaris-x86-gnu +++ /dev/null @@ -1,10 +0,0 @@ -# CONFIG_SITE.Common.solaris-x86-gnu -# -# Site Specific definitions for solaris-x86-gnu target -# Only the local epics system manager should modify this file - -# solaris 10 default location -#GNU_DIR=/usr/sfw - -# APS site override -GNU_DIR = /usr/local diff --git a/configure/os/CONFIG_SITE.Common.solaris-x86_64 b/configure/os/CONFIG_SITE.Common.solaris-x86_64 deleted file mode 100644 index e54ec4f94..000000000 --- a/configure/os/CONFIG_SITE.Common.solaris-x86_64 +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.Common.solaris-x86_64 -# -# Site Specific definitions for solaris-x86_64 target -# Only the local epics system manager should modify this file - -# Include definitions common to all solaris-x86 target archs --include $(CONFIG)/os/CONFIG_SITE.Common.solaris-x86 - -COMMANDLINE_LIBRARY = EPICS diff --git a/configure/os/CONFIG_SITE.Common.solaris-x86_64-gnu b/configure/os/CONFIG_SITE.Common.solaris-x86_64-gnu deleted file mode 100644 index 2b13215fb..000000000 --- a/configure/os/CONFIG_SITE.Common.solaris-x86_64-gnu +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.Common.solaris-x86_64-gnu -# -# Site Specific definitions for solaris-x86_64-gnu target -# Only the local epics system manager should modify this file - -# Include definitions common to all solaris-sparc-gnu target archs -include $(CONFIG)/os/CONFIG_SITE.Common.solaris-x86-gnu - -COMMANDLINE_LIBRARY = EPICS diff --git a/configure/os/CONFIG_SITE.Common.vxWorks-mpc8540 b/configure/os/CONFIG_SITE.Common.vxWorks-mpc8540 deleted file mode 100644 index ea9d9651e..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorks-mpc8540 +++ /dev/null @@ -1,5 +0,0 @@ -# -# Site Specific definitions for the vxWorks-mpc8540 target -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- diff --git a/configure/os/CONFIG_SITE.Common.vxWorks-mpc8548 b/configure/os/CONFIG_SITE.Common.vxWorks-mpc8548 deleted file mode 100644 index 6f84ac0a8..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorks-mpc8548 +++ /dev/null @@ -1,5 +0,0 @@ -# -# Site Specific definitions for the vxWorks-mpc8548 target -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- diff --git a/configure/os/CONFIG_SITE.Common.vxWorks-ppc603 b/configure/os/CONFIG_SITE.Common.vxWorks-ppc603 deleted file mode 100644 index aa59245c2..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorks-ppc603 +++ /dev/null @@ -1,6 +0,0 @@ -# -# Site Specific definitions for the vxWorks-ppc603 target -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- - diff --git a/configure/os/CONFIG_SITE.Common.vxWorks-ppc603_long b/configure/os/CONFIG_SITE.Common.vxWorks-ppc603_long deleted file mode 100644 index 1e18ad1e9..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorks-ppc603_long +++ /dev/null @@ -1,9 +0,0 @@ -# -# Site Specific definitions for the vxWorks-ppc603_long target -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- - -# Inherit the settings from vxWorks-ppc603 --include $(CONFIG)/os/CONFIG_SITE.Common.vxWorks-ppc603 - diff --git a/configure/os/CONFIG_SITE.Common.vxWorks-ppc604 b/configure/os/CONFIG_SITE.Common.vxWorks-ppc604 deleted file mode 100644 index 5b89bb342..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorks-ppc604 +++ /dev/null @@ -1,6 +0,0 @@ -# -# Site Specific definitions for the vxWorks-ppc604 target -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- - diff --git a/configure/os/CONFIG_SITE.Common.vxWorks-ppc604_altivec b/configure/os/CONFIG_SITE.Common.vxWorks-ppc604_altivec deleted file mode 100644 index 6790a8955..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorks-ppc604_altivec +++ /dev/null @@ -1,9 +0,0 @@ -# -# Site Specific definitions for the vxWorks-ppc604_altivec target -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- - -# Inherit the settings from vxWorks-ppc604_long --include $(CONFIG)/os/CONFIG_SITE.Common.vxWorks-ppc604_long - diff --git a/configure/os/CONFIG_SITE.Common.vxWorks-ppc604_long b/configure/os/CONFIG_SITE.Common.vxWorks-ppc604_long deleted file mode 100644 index 74a581b31..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorks-ppc604_long +++ /dev/null @@ -1,9 +0,0 @@ -# -# Site Specific definitions for the vxWorks-ppc604_long target -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- - -# Inherit the settings from vxWorks-ppc604 --include $(CONFIG)/os/CONFIG_SITE.Common.vxWorks-ppc604 - diff --git a/configure/os/CONFIG_SITE.Common.vxWorksCommon b/configure/os/CONFIG_SITE.Common.vxWorksCommon deleted file mode 100644 index 2259f9689..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorksCommon +++ /dev/null @@ -1,37 +0,0 @@ -# CONFIG_SITE.Common.vxWorksCommon -# -# Site specific definitions for vxWorks target builds. - -# Compiler options can vary with the vxWorks version number, so we -# need to know that. Do not include any third-level digits. - -# Note: vxWorks 5.4.x and 5.5.x (Tornado 2.x) are not supported. -# VxWorks 6.0 through 6.5 use older, untested versions of GCC. - -#VXWORKS_VERSION = 6.6 -#VXWORKS_VERSION = 6.7 -#VXWORKS_VERSION = 6.8 -VXWORKS_VERSION = 6.9 - - -# Sites may override the following path for a particular host -# architecture by adding it to an appropriate -# CONFIG_SITE.$(EPICS_HOST_ARCH).vxWorksCommon file. - -# WIND_BASE is where you installed the Wind River software. - -WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION) -#WIND_BASE = /ade/vxWorks/$(VXWORKS_VERSION) - - -# WorkBench Version number, if you're using vxWorks 6.x - -#WORKBENCH_VERSION = 2.6 -#WORKBENCH_VERSION = 3.0 -#WORKBENCH_VERSION = 3.2 -WORKBENCH_VERSION = 3.3 - - -# Utilities Version number, required from vxWorks 6.8 and later - -UTILITIES_VERSION = 1.0 diff --git a/configure/os/CONFIG_SITE.Common.win32-x86-mingw b/configure/os/CONFIG_SITE.Common.win32-x86-mingw deleted file mode 100644 index ba19ac65a..000000000 --- a/configure/os/CONFIG_SITE.Common.win32-x86-mingw +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG_SITE.Common.win32-x86-mingw -# -# Site Specific definitions for win32-x86-mingw target - -# If readline is available uncomment the following line -# to enable command-line editing and history support -#COMMANDLINE_LIBRARY = READLINE diff --git a/configure/os/CONFIG_SITE.Common.win32-x86-static b/configure/os/CONFIG_SITE.Common.win32-x86-static deleted file mode 100644 index de4e61760..000000000 --- a/configure/os/CONFIG_SITE.Common.win32-x86-static +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG_SITE.Common.win32-x86-static -# -# Site-specific settings for the win32-x86-static target - -# Whole-program optimization doesn't work with Visual Studio 2010 when -# building static binaries. Newer versions of Visual Studio than 2010 -# may work though, comment out or set this to YES to try. -OPT_WHOLE_PROGRAM = NO diff --git a/configure/os/CONFIG_SITE.Common.windows-x64-static b/configure/os/CONFIG_SITE.Common.windows-x64-static deleted file mode 100644 index 5db619b11..000000000 --- a/configure/os/CONFIG_SITE.Common.windows-x64-static +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG_SITE.Common.windows-x64-static -# -# Site-specific settings for the windows-x64-static target - -# Whole-program optimization doesn't work with Visual Studio 2010 when -# building static binaries. Newer versions of Visual Studio than 2010 -# may work though, comment out or set this to YES to try. -OPT_WHOLE_PROGRAM = NO diff --git a/configure/os/CONFIG_SITE.cygwin-x86.Common b/configure/os/CONFIG_SITE.cygwin-x86.Common deleted file mode 100644 index 7d132051c..000000000 --- a/configure/os/CONFIG_SITE.cygwin-x86.Common +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG_SITE.cygwin-x86.Common -# -# Site override definitions for cygwin-x86 host builds -#------------------------------------------------------- - -#CROSS_COMPILER_TARGET_ARCHS = linux-arm - diff --git a/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 b/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 deleted file mode 100644 index 3125c7a64..000000000 --- a/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG_SITE.cygwin-x86.cygwin-x86 -# -# Site override definitions for cygwin-x86 host - cygwin-x86 target builds -#------------------------------------------------------- - -# GNU_DIR used when COMMANDLINE_LIBRARY is READLINE -#GNU_DIR=C:/cygwin - diff --git a/configure/os/CONFIG_SITE.cygwin-x86.linux-arm b/configure/os/CONFIG_SITE.cygwin-x86.linux-arm deleted file mode 100644 index 75829c36d..000000000 --- a/configure/os/CONFIG_SITE.cygwin-x86.linux-arm +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG_SITE.cygwin-x86.linux-arm -# -# Site specific definitions for cygwin-x86 host - linux-arm target builds -#------------------------------------------------------- - -# Tools install path -GNU_DIR = /usr/local/arm-linux - -# GNU crosscompiler target name -GNU_TARGET = arm-linux - -STATIC_BUILD = YES -SHARED_LIBRARIES = NO - diff --git a/configure/os/CONFIG_SITE.cygwin-x86_64.linux-arm b/configure/os/CONFIG_SITE.cygwin-x86_64.linux-arm deleted file mode 100644 index 93ec7c878..000000000 --- a/configure/os/CONFIG_SITE.cygwin-x86_64.linux-arm +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG_SITE.cygwin-x86_64.linux-arm -# -# Site specific definitions for cygwin-x86_64 host - linux-arm target builds -#------------------------------------------------------- - -# Tools install path -GNU_DIR = /usr/local/arm-linux - -# GNU crosscompiler target name -GNU_TARGET = arm-linux - -STATIC_BUILD = YES -SHARED_LIBRARIES = NO - diff --git a/configure/os/CONFIG_SITE.darwin-ppc.Common b/configure/os/CONFIG_SITE.darwin-ppc.Common deleted file mode 100644 index 05417e1f9..000000000 --- a/configure/os/CONFIG_SITE.darwin-ppc.Common +++ /dev/null @@ -1,4 +0,0 @@ -# CONFIG_SITE.darwin-ppc.Common -# -# Site override definitions for darwin-ppc host builds -#------------------------------------------------------- diff --git a/configure/os/CONFIG_SITE.darwin-ppcx86.Common b/configure/os/CONFIG_SITE.darwin-ppcx86.Common deleted file mode 100644 index 42bd00531..000000000 --- a/configure/os/CONFIG_SITE.darwin-ppcx86.Common +++ /dev/null @@ -1,4 +0,0 @@ -# CONFIG_SITE.darwin-ppcx86.Common -# -# Site override definitions for darwin-ppcx86 host builds -#------------------------------------------------------- diff --git a/configure/os/CONFIG_SITE.darwin-x86.Common b/configure/os/CONFIG_SITE.darwin-x86.Common deleted file mode 100644 index 8a894104f..000000000 --- a/configure/os/CONFIG_SITE.darwin-x86.Common +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG_SITE.darwin-x86.Common -# -# Site override definitions for darwin-x86 host builds -#------------------------------------------------------- - -# Uncomment the following line to cross-compile the -# iOS device (arm) and simulator (x86) binaries -#CROSS_COMPILER_TARGET_ARCHS = ios-arm ios-x86 diff --git a/configure/os/CONFIG_SITE.darwinCommon.darwinCommon b/configure/os/CONFIG_SITE.darwinCommon.darwinCommon deleted file mode 100644 index 297fd8e4f..000000000 --- a/configure/os/CONFIG_SITE.darwinCommon.darwinCommon +++ /dev/null @@ -1,23 +0,0 @@ -# CONFIG_SITE.darwinCommon.darwinCommon -# -# Site specific definitions for darwin builds -#------------------------------------------------------- - -# Note the dir/firstword/wildcard functions below are used -# to avoid warnings about missing directories. - -# Mix-and-match of different package systems is probably not advisable, -# but you can try that if you like... - -# Uncomment these definitions when using Homebrew packages: -#OP_SYS_INCLUDES += -I/usr/local/include -#OP_SYS_LDFLAGS += $(addprefix -L,$(dir $(firstword $(wildcard /usr/local/lib/*)))) - -# Uncomment these definitions when using DarwinPorts packages: -#OP_SYS_INCLUDES += -I/opt/local/include -#OP_SYS_LDFLAGS += $(addprefix -L,$(dir $(firstword $(wildcard /opt/local/lib/*)))) - -# Uncomment these definitions when using Fink packages: -#OP_SYS_INCLUDES += -I/sw/include -#OP_SYS_LDFLAGS += $(addprefix -L,$(dir $(firstword $(wildcard /sw/lib/*)))) - diff --git a/configure/os/CONFIG_SITE.linux-arm-debug.linux-arm-debug b/configure/os/CONFIG_SITE.linux-arm-debug.linux-arm-debug deleted file mode 100644 index 972f7d6c8..000000000 --- a/configure/os/CONFIG_SITE.linux-arm-debug.linux-arm-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG_SITE.linux-arm-debug.linux-arm-debug -# -# Site specific overrides for linux-arm-debug host and target builds -#------------------------------------------------------- - -#Prepares the object code to collect data for profiling with prof. -#PROFILE=YES - -#Compiles for profiling with the gprof profiler. -#GPROF=YES - diff --git a/configure/os/CONFIG_SITE.linux-arm.linux-arm b/configure/os/CONFIG_SITE.linux-arm.linux-arm deleted file mode 100644 index a5e56eaa1..000000000 --- a/configure/os/CONFIG_SITE.linux-arm.linux-arm +++ /dev/null @@ -1,5 +0,0 @@ -# CONFIG_SITE.linux-arm.linux-arm -# -# Site specific definitions for native linux-arm builds -#------------------------------------------------------- - diff --git a/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug b/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug deleted file mode 100644 index b3fccda81..000000000 --- a/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG_SITE.linux-x86-debug.linux-x86-debug -# -# Site specific overrides for linux-x86-debug host and target builds -#------------------------------------------------------- - -#Prepares the object code to collect data for profiling with prof. -#PROFILE=YES - -#Compiles for profiling with the gprof profiler. -#GPROF=YES - diff --git a/configure/os/CONFIG_SITE.linux-x86.Common b/configure/os/CONFIG_SITE.linux-x86.Common deleted file mode 100644 index dc29e8f0d..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.linux-x86.Common -# -# Site override definitions for linux-x86 host builds -#------------------------------------------------------- - -# JBA test override values -#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040 solaris-sparc -#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040 -#CROSS_COMPILER_TARGET_ARCHS = RTEMS-mvme2100 RTEMS-pc386 # RTEMS-mvme5500 RTEMS-mvme167 diff --git a/configure/os/CONFIG_SITE.linux-x86.RTEMS b/configure/os/CONFIG_SITE.linux-x86.RTEMS deleted file mode 100644 index 8b0fd9131..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.RTEMS +++ /dev/null @@ -1,8 +0,0 @@ -# -# Site-specific information for all RTEMS targets -# -#------------------------------------------------------- - -# Needed by gcc -export LD_LIBRARY_PATH := $(LD_LIBRARY_PATH):$(RTEMS_BASE)/lib - diff --git a/configure/os/CONFIG_SITE.linux-x86.UnixCommon b/configure/os/CONFIG_SITE.linux-x86.UnixCommon deleted file mode 100644 index fcf81cb14..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.UnixCommon +++ /dev/null @@ -1,5 +0,0 @@ -# -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - diff --git a/configure/os/CONFIG_SITE.linux-x86.linux-arm b/configure/os/CONFIG_SITE.linux-x86.linux-arm deleted file mode 100644 index 1500c4526..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.linux-arm +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG_SITE.linux-x86.linux-arm -# -# Site specific definitions for linux-x86 host - linux-arm target builds -#------------------------------------------------------- - -# Set GNU crosscompiler target name -GNU_TARGET = arm-xilinx-linux-gnueabi - -# Set GNU tools install path -# This is the install path at APS: -GNU_DIR = /usr/local/vw/zynq-2011.09 - -# With a Xilinx SDK, it'll be something like -#GNU_DIR = /usr/local/zynq/Xilinx/SDK/2015.4/gnu/arm/lin diff --git a/configure/os/CONFIG_SITE.linux-x86.linux-arm-debug b/configure/os/CONFIG_SITE.linux-x86.linux-arm-debug deleted file mode 100644 index 57aff03b7..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.linux-arm-debug +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG_SITE.linux-x86.linux-arm-debug -# -# Site specific settings for linux-x86 host - linux-arm-debug target builds -#------------------------------------------------------- - -# Inherit settings from linux-arm -include $(CONFIG)/os/CONFIG_SITE.linux-x86.linux-arm diff --git a/configure/os/CONFIG_SITE.linux-x86.linux-arm_eb b/configure/os/CONFIG_SITE.linux-x86.linux-arm_eb deleted file mode 100644 index 0bc2a4e5a..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.linux-arm_eb +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG_SITE.linux-x86.linux-arm_eb -# -# Site specific definitions for linux-x86 host - linux-arm_eb target builds -#------------------------------------------------------- - -# Include definitions for linux-arm targets -include $(CONFIG)/os/CONFIG_SITE.linux-x86.linux-arm - -# Path to the GNU toolset for linux-arm_eb (big endian) target -#GNU_DIR = /local/anj/cross-arm/gcc-3.4.5-glibc-2.3.6/armeb-linux - -# GNU crosscompiler target name -#GNU_TARGET = armeb-linux diff --git a/configure/os/CONFIG_SITE.linux-x86.linux-arm_el b/configure/os/CONFIG_SITE.linux-x86.linux-arm_el deleted file mode 100644 index b82bc13bf..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.linux-arm_el +++ /dev/null @@ -1,13 +0,0 @@ -# CONFIG_SITE.linux-x86.linux-arm_el -# -# Site specific definitions for linux-x86 host - linux-arm_el target builds -#------------------------------------------------------- - -# Include definitions for linux-arm targets -include $(CONFIG)/os/CONFIG_SITE.linux-x86.linux-arm - -# Path to the GNU toolset for linux-arm_el (little endian) target -#GNU_DIR = /local/anj/cross-arm/gcc-3.4.5-glibc-2.3.6/armel-linux - -# GNU crosscompiler target name -#GNU_TARGET = armel-linux diff --git a/configure/os/CONFIG_SITE.linux-x86.linux-cris b/configure/os/CONFIG_SITE.linux-x86.linux-cris deleted file mode 100644 index eb756ca8a..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.linux-cris +++ /dev/null @@ -1,14 +0,0 @@ -# CONFIG_SITE.linux-x86.linux-cris -# -# Author: Peter Zumbruch -# GSI -# P.Zumbruch@gsi.de -# -# Site specific definitions for linux-x86 host - linux-cris target builds -#------------------------------------------------------- - -# define site specific location of cris cross compiler's gnu directory -# but without bin sub directory, this will be added automatically. - -CRIS_CROSS_COMPILER ?= UNDEFINED_ENV__CRIS_CROSS_COMPILER - diff --git a/configure/os/CONFIG_SITE.linux-x86.linux-x86 b/configure/os/CONFIG_SITE.linux-x86.linux-x86 deleted file mode 100644 index d359d174f..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.linux-x86 +++ /dev/null @@ -1,5 +0,0 @@ -# CONFIG_SITE.linux-x86.linux-x86 -# -# Site specific definitions for linux-x86 host - linux-x86 target builds -#------------------------------------------------------- - diff --git a/configure/os/CONFIG_SITE.linux-x86.solaris-sparc b/configure/os/CONFIG_SITE.linux-x86.solaris-sparc deleted file mode 100644 index 156c748bd..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.solaris-sparc +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG_SITE.linux-x86.solaris-sparc -# -# Site specific definitions for linux-x86 host - solaris-sparc target builds -#------------------------------------------------------- - -#GNU_DIR = /home/phoebus/JBA/gnu-solaris2 - diff --git a/configure/os/CONFIG_SITE.linux-x86.vxWorks-68040 b/configure/os/CONFIG_SITE.linux-x86.vxWorks-68040 deleted file mode 100644 index 4515d8b4c..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.vxWorks-68040 +++ /dev/null @@ -1,6 +0,0 @@ -# CONFIG_SITE.linux-x86.vxWorks-68040 -# -# Site specific definitions for linux-x86 host - vxWorks-68040 target builds -# Only the local epics system manager should modify this file -#------------------------------------------------------- - diff --git a/configure/os/CONFIG_SITE.linux-x86.vxWorks-ppc603 b/configure/os/CONFIG_SITE.linux-x86.vxWorks-ppc603 deleted file mode 100644 index de1f98c35..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.vxWorks-ppc603 +++ /dev/null @@ -1,6 +0,0 @@ -# -# Site-specific definitions for linux-x86 builds of vxWorks-ppc603 -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- - diff --git a/configure/os/CONFIG_SITE.linux-x86.vxWorks-ppc603_long b/configure/os/CONFIG_SITE.linux-x86.vxWorks-ppc603_long deleted file mode 100644 index 4cc5c6e81..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.vxWorks-ppc603_long +++ /dev/null @@ -1,8 +0,0 @@ -# -# Site-specific definitions for linux-x86 builds of vxWorks-ppc603_long -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- - -# Inherit settings from vxWorks-ppc603 --include $(CONFIG)/os/CONFIG_SITE.linux-x86.vxWorks-ppc603 diff --git a/configure/os/CONFIG_SITE.linux-x86.vxWorksCommon b/configure/os/CONFIG_SITE.linux-x86.vxWorksCommon deleted file mode 100644 index 4c7d044f5..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.vxWorksCommon +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG_SITE.linux-x86.vxWorksCommon -# -# This file is maintained by the build community. -# -# Definitions for linux-x86 host - vxWorks target builds -#------------------------------------------------------- - - diff --git a/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw b/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw deleted file mode 100644 index 363664f26..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.win32-x86-mingw +++ /dev/null @@ -1,25 +0,0 @@ -# CONFIG_SITE.linux-x86.win32-x86-mingw -# -# Configuration for linux-x86 host win32-x86-mingw target builds -#------------------------------------------------------- - -# Early versions of the MinGW cross-build tools can only build -# static (non-DLL) libraries. RHEL's cross-build of gcc 4.4.6 -# needs these uncommented, cross-gcc 4.6.3 from Ubuntu does not: -#SHARED_LIBRARIES = NO -#STATIC_BUILD = YES - -# The cross-build tools are in $(GNU_DIR)/bin -# Default is /usr -#GNU_DIR = /usr/local - -# Different distribution cross-build packages use different prefixes: -# Ubuntu, RHEL7: -CMPLR_PREFIX = i686-w64-mingw32- -# RHEL6: -#CMPLR_PREFIX = i686-pc-mingw32- -# Debian? -#CMPLR_PREFIX = i586-mingw32msvc- - -# Use static compiler-support libraries -OP_SYS_LDFLAGS += -static-libgcc -static-libstdc++ diff --git a/configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw b/configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw deleted file mode 100644 index 026410cfe..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.windows-x64-mingw +++ /dev/null @@ -1,23 +0,0 @@ -# CONFIG_SITE.linux-x86.windows-x64-mingw -# -# Configuration for linux-x86 host windows-x64-mingw target builds -#------------------------------------------------------- - -# Early versions of the MinGW cross-build tools can only build -# static (non-DLL) libraries. For example RHEL's cross-gcc 4.4.6 -# needs these uncommented, cross-gcc 4.6.3 for Ubuntu does not: -#SHARED_LIBRARIES = NO -#STATIC_BUILD = YES - -# The cross-build tools are in $(GNU_DIR)/bin -# Default is /usr -#GNU_DIR = /usr/local - -# Different distribution cross-build packages use different prefixes: -# Ubuntu: -#CMPLR_PREFIX = i686-w64-mingw32- -# RHEL: -CMPLR_PREFIX = x86_64-w64-mingw32- - -# Use static compiler-support libraries -OP_SYS_LDFLAGS += -static-libgcc -static-libstdc++ diff --git a/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug b/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug deleted file mode 100644 index 8ff68471a..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug +++ /dev/null @@ -1,11 +0,0 @@ -# CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug -# -# Site specific overrides for linux-x86_64 host and target builds -#------------------------------------------------------- - -#Prepares the object code to collect data for profiling with prof. -#PROFILE=YES - -#Compiles for profiling with the gprof profiler. -#GPROF=YES - diff --git a/configure/os/CONFIG_SITE.linux-x86_64.Common b/configure/os/CONFIG_SITE.linux-x86_64.Common deleted file mode 100644 index 244e163b4..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.linux-x86_64.Common -# -# Site override definitions for linux-x86_64 host builds -#------------------------------------------------------- - -#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040 solaris-sparc -#CROSS_COMPILER_TARGET_ARCHS = vxWorks-68040 -#CROSS_COMPILER_TARGET_ARCHS = RTEMS-mvme2100 - diff --git a/configure/os/CONFIG_SITE.linux-x86_64.UnixCommon b/configure/os/CONFIG_SITE.linux-x86_64.UnixCommon deleted file mode 100644 index fa67bd3b8..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.UnixCommon +++ /dev/null @@ -1,5 +0,0 @@ -# CONFIG_SITE.linux-x86_64.UnixCommon -# -# Site Specific configure override definitions -# Only the local epics system manager should modify this file - diff --git a/configure/os/CONFIG_SITE.linux-x86_64.linux-arm b/configure/os/CONFIG_SITE.linux-x86_64.linux-arm deleted file mode 100644 index 9fcf3452a..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.linux-arm +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG_SITE.linux-x86_64.linux-arm -# -# Site specific settings for linux-x86_64 host - linux-arm target builds -#------------------------------------------------------- - -# Inherit setting from linux-x86 -include $(CONFIG)/os/CONFIG_SITE.linux-x86.linux-arm diff --git a/configure/os/CONFIG_SITE.linux-x86_64.linux-arm-debug b/configure/os/CONFIG_SITE.linux-x86_64.linux-arm-debug deleted file mode 100644 index 4f1e89a1b..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.linux-arm-debug +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG_SITE.linux-x86_64.linux-arm-debug -# -# Site specific settings for linux-x86_64 host - linux-arm-debug target builds -#------------------------------------------------------- - -# Inherit settings from linux-arm -include $(CONFIG)/os/CONFIG_SITE.linux-x86.linux-arm diff --git a/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 b/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 deleted file mode 100644 index 7a19d0dfe..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 +++ /dev/null @@ -1,6 +0,0 @@ -# CONFIG_SITE.linux-x86_64.linux-x86_64 -# -# Site specific definitions for linux-x86_64 host - linux-x86_64 target builds -#------------------------------------------------------- - - diff --git a/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-68040 b/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-68040 deleted file mode 100644 index 63ca76f2d..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-68040 +++ /dev/null @@ -1,6 +0,0 @@ -# CONFIG_SITE.linux-x86_64.vxWorks-68040 -# -# Site specific definitions for linux-x86_64 host - vxWorks-68040 target builds -# Only the local epics system manager should modify this file -#------------------------------------------------------- - diff --git a/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-ppc603 b/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-ppc603 deleted file mode 100644 index dfcc96f42..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-ppc603 +++ /dev/null @@ -1,5 +0,0 @@ -# -# Site-specific definitions for linux-x86_64 builds of vxWorks-ppc603 -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- diff --git a/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-ppc603_long b/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-ppc603_long deleted file mode 100644 index 729bb80d4..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.vxWorks-ppc603_long +++ /dev/null @@ -1,8 +0,0 @@ -# -# Site-specific definitions for linux-x86 builds of vxWorks-ppc603_long -# -# Only the local epics system manager should modify this file -#------------------------------------------------------- - -# Inherit settings from vxWorks-ppc603 --include $(CONFIG)/os/CONFIG_SITE.linux-x86_64.vxWorks-ppc603 diff --git a/configure/os/CONFIG_SITE.linux-x86_64.win32-x86-mingw b/configure/os/CONFIG_SITE.linux-x86_64.win32-x86-mingw deleted file mode 100644 index 99836730a..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.win32-x86-mingw +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG_SITE.linux-x86_64.win32-x86-mingw -# -# Configuration for linux-x86_64 host win32-x86-mingw target builds -#------------------------------------------------------- - -# Inherit from the linux-x86 host architecture -include $(CONFIG)/os/CONFIG_SITE.linux-x86.win32-x86-mingw - diff --git a/configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw b/configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw deleted file mode 100644 index e98ac7a02..000000000 --- a/configure/os/CONFIG_SITE.linux-x86_64.windows-x64-mingw +++ /dev/null @@ -1,8 +0,0 @@ -# CONFIG_SITE.linux-x86_64.windows-x64-mingw -# -# Configuration for linux-x86_64 host windows-x64-mingw target builds -#------------------------------------------------------- - -# Inherit from the linux-x86 host architecture -include $(CONFIG)/os/CONFIG_SITE.linux-x86.windows-x64-mingw - diff --git a/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug b/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug deleted file mode 100644 index c0b1ec77e..000000000 --- a/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug +++ /dev/null @@ -1,8 +0,0 @@ -include $(CONFIG)/os/CONFIG_SITE.Common.solaris-sparc - -#Prepares the object code to collect data for profiling with prof. -#PROFILE=YES - -#Compiles for profiling with the gprof profiler. -#GPROF=YES - diff --git a/configure/os/CONFIG_SITE.solaris-sparc.Common b/configure/os/CONFIG_SITE.solaris-sparc.Common deleted file mode 100644 index eaa42044c..000000000 --- a/configure/os/CONFIG_SITE.solaris-sparc.Common +++ /dev/null @@ -1,5 +0,0 @@ -# CONFIG_SITE.solaris-sparc.Common -# -# Site specific override definitions for solaris-sparc host builds -# Only the local epics system manager should modify this file - diff --git a/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc-debug b/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc-debug deleted file mode 100644 index c0b1ec77e..000000000 --- a/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc-debug +++ /dev/null @@ -1,8 +0,0 @@ -include $(CONFIG)/os/CONFIG_SITE.Common.solaris-sparc - -#Prepares the object code to collect data for profiling with prof. -#PROFILE=YES - -#Compiles for profiling with the gprof profiler. -#GPROF=YES - diff --git a/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw b/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw deleted file mode 100644 index 1f0e83d61..000000000 --- a/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.win32-x86-mingw.win32-x86-mingw -# -# Site Specific definitions for win32-x86-mingw target - -# The MinGW bin directory must be in your path. - -# Set the compiler prefix for your MinGW installation -#CMPLR_PREFIX = i686-w64-mingw32- -#CMPLR_PREFIX = i586-mingw32msvc- diff --git a/configure/os/CONFIG_SITE.win32-x86.Common b/configure/os/CONFIG_SITE.win32-x86.Common deleted file mode 100644 index 9141333d0..000000000 --- a/configure/os/CONFIG_SITE.win32-x86.Common +++ /dev/null @@ -1,9 +0,0 @@ -# CONFIG_SITE.win32-x86.Common -# -# Site specific definitions for win32-x86 host -# Only the local epics system manager should modify this file - -# jba test overrides -#CROSS_COMPILER_TARGET_ARCHS=vxWorks-486 -#CROSS_COMPILER_TARGET_ARCHS+=vxWorks-68040 -#INSTALL_LOCATION = G:/testInstall diff --git a/configure/os/CONFIG_SITE.windows-x64-mingw.windows-x64-mingw b/configure/os/CONFIG_SITE.windows-x64-mingw.windows-x64-mingw deleted file mode 100644 index 63b559769..000000000 --- a/configure/os/CONFIG_SITE.windows-x64-mingw.windows-x64-mingw +++ /dev/null @@ -1,7 +0,0 @@ -# CONFIG_SITE.windows-x64-mingw.windows-x64-mingw -# -# Site Specific definitions for windows-x64-mingw target -# Only the local epics system manager should modify this file - -# Prefix for mingw compiler from cygwin -#CMPLR_PREFIX = x86_64-w64-mingw32- diff --git a/documentation/KnownProblems.html b/documentation/KnownProblems.html deleted file mode 100644 index f3e6a2d6d..000000000 --- a/documentation/KnownProblems.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - Known Problems in Base-3.16.1 - - - -

EPICS Base R3.16.1: Known Problems

- -

Any patch files linked below should be applied at the root of the -base-3.16.1 tree. Download them, then use the GNU Patch program as -follows:

- -
% cd /path/to/base-3.16.1
-% patch -p1 < /path/to/file.patch
- -

The following problems were known by the developers at the time of this -release:

- -
    - - - -
  • IOCs running on some versions of Cygwin may display warnings at iocInit - about duplicate EPICS CA Address list entries. These warnings might be due - to a bug in Cygwin; they are benign and can be ignored.
  • - -
  • 64-bit Windows builds of the CAS library may not work with some compilers. - The code in src/legacy/gdd is incompatible with the LLP64 model - that Windows uses for its 64-bit ABI.
  • - -
- - - diff --git a/documentation/README.1st b/documentation/README.1st deleted file mode 100644 index 4886bea7c..000000000 --- a/documentation/README.1st +++ /dev/null @@ -1,347 +0,0 @@ - Installation Instructions - - EPICS Base Release 3.16.1 - - -------------------------------------------------------------------------- - - Table of Contents - - * What is EPICS base? - * What is new in this release? - * Copyright - * Supported platforms - * Supported compilers - * Software requirements - * Host system storage requirements - * Documentation - * Directory Structure - * Build related components - * Building EPICS base (Unix and Win32) - * Example application and extension - * Multiple host platforms - - -------------------------------------------------------------------------- - - What is EPICS base? - - The Experimental Physics and Industrial Control Systems (EPICS) is an - extensible set of software components and tools with which application - developers can create a control system. This control system can be used - to control accelerators, detectors, telescopes, or other scientific - experimental equipment. EPICS base is the set of core software, i.e. the - components of EPICS without which EPICS would not function. EPICS base - allows an arbitrary number of target systems, IOCs (input/output - controllers), and host systems, OPIs (operator interfaces) of various - types. - - What is new in this release? - - Please check the RELEASE_NOTES file in the distribution for description - of changes and release migration details. - - Copyright - - Please review the LICENSE file included in the distribution for legal - terms of usage. - - Supported platforms - - The list of platforms supported by this version of EPICS base is given - in the configure/CONFIG_SITE file. If you are trying to build EPICS Base - on an unlisted host or for a different target machine you must have the - proper host/target cross compiler and header files, and you will have to - create and add the appropriate new configure files to the - base/configure/os/directory. You can start by copying existing - configuration files in the configure/os directory and then make changes - for your new platforms. - - Supported compilers - - This version of EPICS base has been built and tested using the host - vendor's C and C++ compilers, as well as the GNU gcc and g++ compilers. - The GNU cross-compilers work for all cross-compiled targets. You may - need the C and C++ compilers to be in your search path to do EPICS - builds; check the definitions of CC and CCC in - base/configure/os/CONFIG.. if you have problems. - - Software requirements - - GNU make - You must use GNU make, gnumake, for any EPICS builds. Set your path so - that a gnumake version 3.81 or later is available. - - Perl - You must have Perl version 5.8.1 or later installed. The EPICS - configuration files do not specify the perl full pathname, so the perl - executable must be found through your normal search path. - - Unzip and tar (Winzip on WIN32 systems) - You must have tools available to unzip and untar the EPICS base - distribution file. - - Target systems - EPICS supports IOCs running on embedded platforms such as VxWorks and - RTEMS built using a cross-compiler, and also supports soft IOCs running - as processes on the host platform. - - vxWorks - You must have vxWorks 6 installed if any of your target systems are - vxWorks systems; the C++ compilers for vxWorks 5.x are now too old to - support. The vxWorks installation provides the cross-compiler and header - files needed to build for these targets. The absolute path to and the - version number of the vxWorks installation must be set in the - base/configure/os/CONFIG_SITE.Common.vxWorksCommon file or in one of its - target-specific overrides. - - Consult the vxWorks 6.x EPICS web pages and the vxWorks documentation - for information about configuring your vxWorks operating system for use - with EPICS. - - RTEMS - For RTEMS targets, you need RTEMS core and toolset version 4.9.2 or - later. - - GNU readline or Tecla library - GNU readline and Tecla libraries can be used by the IOC shell to provide - command line editing and command line history recall and edit. GNU - readline (or Tecla library) must be installed on your target system when - COMMANDLINE_LIBRARY is set to READLINE (or TECLA) for that target. EPICS - (EPICS shell) is the default specified in CONFIG_COMMON. A READLINE - override is defined for linux-x86 in the EPICS distribution. Comment out - COMMANDLINE_LIBRARY=READLINE in - configure/os/CONFIG_SITE.Common.linux-x86 if readline is not installed - on linux-x86. Command-line editing and history will then be those - supplied by the os. On vxWorks the ledLib command-line input library is - used instead. - - Host system storage requirements - - The compressed tar file is approximately 1.6 MB in size. The - distribution source tree takes up approximately 12 MB. Each host target - will need around 40 MB for build files, and each cross-compiled target - around 20 MB. - - Documentation - - EPICS documentation is available through the EPICS website at Argonne. - - Release specific documentation can also be found in the - base/documentation directory of the distribution. - - Directory Structure - - Distribution directory structure: - - base Root directory of the base distribution - base/configure Operating system independent build config files - base/configure/os Operating system dependent build config files - base/documentation Distribution documentation - base/src Source code in various subdirectories - base/startup Scripts for setting up path and environment - - Install directories created by the build: - - bin Installed scripts and executables in subdirs - cfg Installed build configuration files - db Installed data bases - dbd Installed data base definitions - doc Installed documentation files - html Installed html documentation - include Installed header files - include/os Installed os specific header files in subdirs - include/compiler Installed compiler-specific header files - lib Installed libraries in arch subdirectories - lib/perl Installed perl modules - templates Installed templates - - Build related components - - base/documentation directory - contains setup, build, and install documents - - README.1st Instructions for setup and building epics base - README.html html version of README.1st - README.darwin.html Installation notes for Mac OS X (Darwin) - RELEASE_NOTES.html Notes on release changes - KnownProblems.html List of known problems and workarounds - - base/startup directory - contains scripts to set environment and path - - EpicsHostArch C shell script to set EPICS_HOST_ARCH env variable - EpicsHostArch.pl Perl script to set EPICS_HOST_ARCH env variable - Site.profile bourne shell script to set path and env variables - Site.cshrc c shell script to set path and env variables - cygwin.bat WIN32 bat file to set cygwin path and env variables - win32.bat WIN32 bat file to set path and env variables - - base/configure directory - contains build definitions and rules - - CONFIG Includes configure files and allows variable overrides - CONFIG.CrossCommon Cross build definitions - CONFIG.gnuCommon Gnu compiler build definitions for all archs - CONFIG_ADDONS Definitions for and DEFAULT options - CONFIG_APP_INCLUDE - CONFIG_BASE EPICS base tool and location definitions - CONFIG_BASE_VERSION Definitions for EPICS base version number - CONFIG_COMMON Definitions common to all builds - CONFIG_ENV Definitions of EPICS environment variables - CONFIG_FILE_TYPE - CONFIG_SITE Site specific make definitions - CONFIG_SITE_ENV Site defaults for EPICS environment variables - MAKEFILE Installs CONFIG* RULES* creates - RELEASE Location of external products - RULES Includes appropriate rules file - RULES.Db Rules for database and database definition files - RULES.ioc Rules for application iocBoot/ioc* directory - RULES_ARCHS Definitions and rules for building architectures - RULES_BUILD Build and install rules and definitions - RULES_DIRS Definitions and rules for building subdirectories - RULES_EXPAND - RULES_FILE_TYPE - RULES_TARGET - RULES_TOP Rules specific to a dir (uninstall and tar) - Sample.Makefile Sample makefile with comments - - base/configure/os directory - contains os-arch specific definitions - - CONFIG.. Specific host-target build definitions - CONFIG.Common. Specific target definitions for all hosts - CONFIG..Common Specific host definitions for all targets - CONFIG.UnixCommon.Common Definitions for Unix hosts and all targets - CONFIG.Common.UnixCommon Definitions for Unix targets and all hosts - CONFIG.Common.vxWorksCommon Specific host definitions for all vx targets - CONFIG_SITE.. Site specific host-target definitions - CONFIG_SITE.Common. Site specific target defs for all hosts - CONFIG_SITE..Common Site specific host defs for all targets - - Building EPICS base (Unix and Win32) - - Unpack file - - Unzip and untar the distribution file. Use WinZip on Windows systems. - - Set environment variables - - Files in the base/startup directory have been provided to help set - required path and other environment variables. - - EPICS_HOST_ARCH - Before you can build or use EPICS R3.15, the environment variable - EPICS_HOST_ARCH must be defined. A perl script EpicsHostArch.pl in the - base/startup directory has been provided to help set EPICS_HOST_ARCH. - You should have EPICS_HOST_ARCH set to your host operating system - followed by a dash and then your host architecture, e.g. - solaris-sparc. If you are not using the OS vendor's c/c++ compiler for - host builds, you will need another dash followed by the alternate - compiler name (e.g. "-gnu" for GNU c/c++ compilers on a solaris host - or "-mingw" for MinGW c/c++ compilers on a WIN32 host). See - configure/CONFIG_SITE for a list of supported EPICS_HOST_ARCH values. - - PERLLIB - On WIN32, some versions of Perl require that the environment variable - PERLLIB be set to . - - PATH - As already mentioned, you must have the perl executable and you may - need C and C++ compilers in your search path. For building base you - also must have echo in your search path. For Unix host builds you also - need ln, cpp, cp, rm, mv, and mkdir in your search path and /bin/chmod - must exist. On some Unix systems you may also need ar and ranlib in - your path, and the C compiler may require as and ld in your path. On - solaris systems you need uname in your path. - - LD_LIBRARY_PATH - R3.15 shared libraries and executables normally contain the full path - to any libraries they require. However, if you move the EPICS files or - directories from their build-time location then in order for the - shared libraries to be found at runtime LD_LIBRARY_PATH must include - the full pathname to $(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when - invoking executables, or some equivalent OS-specific mechanism (such - as /etc/ld.so.conf on Linux) must be used. Shared libraries are now - built by default on all Unix type hosts. - - Do site-specific build configuration - - Site configuration - To configure EPICS, you may want to modify the default definitions in - the following files: - - configure/CONFIG_SITE Build choices. Specify target archs. - configure/CONFIG_SITE_ENV Environment variable defaults - configure/RELEASE TORNADO2 full path location - - Host configuration - To configure each host system, you may override the default - definitions by adding a new file in the configure/os directory with - override definitions. The new file should have the same name as the - distribution file to be overridden except with CONFIG in the name - changed to CONFIG_SITE. - - configure/os/CONFIG.. Host build settings - configure/os/CONFIG..Common Host common build settings - - Target configuration - To configure each target system, you may override the default - definitions by adding a new file in the configure/os directory with - override definitions. The new file should have the same name as the - distribution file to be overridden except with CONFIG in the name - replaced by CONFIG_SITE. This step is necessary even if the host - system is the only target system. - - configure/os/CONFIG.Common. Target common settings - configure/os/CONFIG.. Host-target settings - - Build EPICS base - - After configuring the build you should be able to build EPICS base by - issuing the following commands in the distribution's root directory - (base): - - gnumake clean uninstall - gnumake - - The command "gnumake clean uninstall" will remove all files and - directories generated by a previous build. The command "gnumake" will - build and install everything for the configured host and targets. - - It is recommended that you do a "gnumake clean uninstall" at the root - directory of an EPICS directory structure before each complete rebuild - to ensure that all components will be rebuilt. - - Example application and extension - - A perl tool, makeBaseApp.pl is included in the distribution file. This - script will create a sample application that can be built and then - executed to try out this release of base. - - Instructions for building and executing the 3.15 example application can - be found in the section "Example Application" of Chapter 2, "Getting - Started", in the "IOC Application Developer's Guide" for this release. - The "Example IOC Application" section briefly explains how to create and - build an example application in a user created directory. It also - explains how to run the example application on a vxWorks ioc or as a - process on the host system. By running the example application as a - host-based IOC, you will be able to quickly implement a complete EPICS - system and be able to run channel access clients on the host system. - - A perl script, makeBaseExt.pl, is included in the distribution file. - This script will create a sample extension that can be built and - executed. The makeBaseApp.pl and makeBaseExt.pl scripts are installed - into the install location bin/ directory during the base - build. - - Multiple host platforms - - You can build using a single EPICS directory structure on multiple host - systems and for multiple cross target systems. The intermediate and - binary files generated by the build will be created in separate - subdirectories and installed into the appropriate separate host/target - install directories. EPICS executables and perl scripts are installed - into the $(INSTALL_LOCATION)/bin/ directories. Libraries are - installed into $(INSTALL_LOCATION)/lib/. The default definition - for $(INSTALL_LOCATION) is $(TOP) which is the root directory in the - distribution directory structure, base. Created object files are stored - in O. source subdirectories, This allows objects for multiple - cross target architectures to be maintained at the same time. To build - EPICS base for a specific host/target combination you must have the - proper host/target C/C++ cross compiler and target header files and the - base/configure/os directory must have the appropriate configure files. diff --git a/documentation/README.cris b/documentation/README.cris deleted file mode 100644 index c44f31bb0..000000000 --- a/documentation/README.cris +++ /dev/null @@ -1,67 +0,0 @@ -cross compiling EPICS and - building IOC Applications for cris architectures - (linux-cris_v10, linux-cris_v32) -====================================================================== - -Please mail questions, comments, corrections, etc. ... -to P.Zumbruch@gsi.de -November 2007 - -Tools needed ------------- - - o Axis SDK - - Overview: - http://developer.axis.com/wiki/doku.php?id=axis:sdk - - Download: - http://www.axis.com/products/dev_sdk/download_dist.php - - Install HOWTO: - http://developer.axis.com/wiki/doku.php?id=axis:software_distribution_install_howto - o Axis GNU gcc release for cross compiling - - Download: - http://www.axis.com/products/dev_sdk/download_compiler.php - - Install HOWTO: - http://developer.axis.com/wiki/doku.php?id=axis:compiler_install - -Environment ------------ - - o CRIS_CROSS_COMPILER - - path to top directory of cris cross compiler, - where binaries are in sub directory bin/ - - if not set, the make process will stop at place - UNDEFINED_ENV__CRIS_CROSS_COMPILER - o AXIS_TOP_DIR?=UNDEFINED_ENV__AXIS_TOP_DIR - - path to axis SDK top directory - - if not set compile and link commands will contain references to - UNDEFINED_ENV__AXIS_TOP_DIR - - to set the necessary variables, execute - . ./init_env - in the top directory of the SDK provided here. - o CRIS_COMPILER_DEBUG - - if defined symbols won't be stripped, - resulting in comparably large files - -Building --------- - - o Edit the CONFIG_SITE files - - CONFIG_SITE.linux-x86.Common: - for CROSS_COMPILER_TARGET_ARCHS += linux-cris_v10 - for CROSS_COMPILER_TARGET_ARCHS += linux-cris_v32 - - optionally CONFIG_SITE.linux-x86.linux-cris - for setting CRIS_CROSS_COMPILER - - optionally create CONFIG_SITE.linux-x86.linux-cris_v10 - - optionally create CONFIG_SITE.linux-x86.linux-cris_v32 - o "make". - -Shared Libraries ----------------- - -Generating shared libraries is not supported. - - -Please feel free to contact me if you -encounter serious problems. - -Peter diff --git a/documentation/README.darwin.html b/documentation/README.darwin.html deleted file mode 100644 index cbc290178..000000000 --- a/documentation/README.darwin.html +++ /dev/null @@ -1,184 +0,0 @@ - - -Installation notes for EPICS on Mac OS X (Darwin) - - - - -

Building EPICS base

-
    -
  • -To build base: -
      -
    1. -Set the EPICS_HOST_ARCH environment variable to darwin-ppc, darwin-x86 or darwin-ppcx86. -The scripts in the -base/startup directory can automate this. For example, here's part -of my Bash login script (~/.bash_login): -
      -#
      -# EPICS
      -#
      -EPICS_BASE="${HOME}/src/EPICS/base"
      -EPICS_EXTENSIONS="${HOME}/src/EPICS/extensions"
      -. "${EPICS_BASE}"/startup/Site.profile
      -
      -
    2. -
    3. -cd to the EPICS base top-level source directory. -
    4. -
    5. -Uncomment the appropriate line in the relevent -EPICS_BASE/configure/os/CONFIG_SITE.Common.darwin-xxx file for your EPICS_HOST_ARCH value. -Newer versions of OS X (e.g. Snow Leopard) may include only 64 bit versions of some OS libraries, -so should only have the x86_64 ARCH_CLASS. -
    6. -
    7. -Run make. -
    8. -
    - -
  • - -
  • -As distributed, EPICS on Mac OS X uses the readline command line input -routines. IOC applications are more pleasant to interact with if -either the readline or libtecla library is used. The easiest -way to get either or both of these libraries on to your system is to -download and install them using the either the DarwinPorts -distribution or the Fink package manager. If you don't want to install -the readline library, set the COMMANDLINE_LIBRARY variable in one of -the CONFIG_SITE files to EPICS. -

    -Information on DarwinPorts is available from -the DarwinPorts -project page. -DarwinPorts binary packages are available from -here. -

    -Fink may be downloaded from -the Source Forge. -

  • - -
  • -If broadcasts are not seen locally, try adding "localhost" (127.0.0.1) -to the EPICS_CA_ADDR_LIST. -
  • -
- -

Building EPICS extensions

-

-Many extensions build and run properly on OS X. To build and run medm, first -obtain the X11 run-time and developer packages from Apple and the OpenMotif3 -package from Fink. - -

Objective-C and AppleScript

-

-Code written in Objective-C can be included in host or IOC applications. -Here are a couple of short Objective-C examples which can be used to send -AppleScript events to other applications on the OS X machine. - -

-/*
- * exampleAppleScriptRecord.m 
- *
- * Simple Objective-C/AppleScript subroutine record
- *
- * To use this record in an application:
- *
- * 1) Make the following changes to the application Makefile:
- *    - Add exampleAppleScriptRecord.m to the application SRCS.
- *    - Add -framework Foundation to the application LDFLAGS.
- * 2) Add the following line to the application database description:
- *      registrar(registerExampleAppleScript)
- * 3) Add a record to the application database:
- *      record(sub,"setVolume")
- *      {
- *          field(SNAM,"exampleAppleScriptProcess")
- *      }
- */
-#import <Foundation/Foundation.h>
-#include <registryFunction.h>
-#include <subRecord.h>
-#include <alarm.h>
-#include <errlog.h>
-#include <recGbl.h>
-#include <epicsExport.h>
-
-/*
- * Shim between EPICS and NSAppleScript class.
- */
-static long
-exampleAppleScriptProcess(struct subRecord *psub)
- {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSDictionary *err;
-    NSAppleScript *nsa;
-    
-    nsa = [[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:
-                @"tell application \"Finder\" to set volume %g\n", psub->a]];
-    if ([nsa executeAndReturnError:&err] == nil) {
-        errlogPrintf("Failed to run AppleScript: %s\n",
-                        [[err objectForKey:NSAppleScriptErrorMessage] cString]);
-        recGblSetSevr(psub, SOFT_ALARM, INVALID_ALARM);
-    }
-    [nsa release];
-    [pool release];
-    return 0;
-}
-
-static registryFunctionRef subRef[] = {
-    {"exampleAppleScriptProcess",(REGISTRYFUNCTION)exampleAppleScriptProcess}
-};
-
-static void registerExampleAppleScript(void)
-{
-    registryFunctionRefAdd(subRef,NELEMENTS(subRef));
-}
-epicsExportRegistrar(registerExampleAppleScript);
-
-
-==============================================================================
-/*
- * runAppleScript.m 
- *
- * Simple Objective-C/AppleScript shim to allow EPICS application to
- * send arbitrary AppleScript messages to other applications.
- *
- * To use this subroutine in an application make the following
- * changes to the application Makefile:
- * - Add runAppleScript.m to the application SRCS.
- * - Add -framework Foundation to the application LDFLAGS.
- */
-#import <Foundation/Foundation.h>
-#include <errlog.h>
-
-int
-runAppleScript(const char *format, ...)
-{
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSString *script;
-    NSMutableDictionary *err;
-    NSAppleScript *nsa;
-    va_list args;
-    int ret = 0;
-    
-    va_start(args, format);
-    script = [[NSString alloc] initWithFormat:
-                            [NSString stringWithCString:format] arguments:args];
-    va_end(args);
-    err = [NSMutableDictionary dictionaryWithCapacity:10];
-    nsa = [[NSAppleScript alloc] initWithSource:script];
-    if ([nsa executeAndReturnError:&err] == nil) {
-        errlogPrintf("Failed to run AppleScript: %s\n",
-                        [[err objectForKey:NSAppleScriptErrorMessage] cString]);
-        ret = -1;
-    }
-    [script release];
-    [nsa release];
-    [pool release];
-    return ret;
-}
-
- - diff --git a/documentation/README.html b/documentation/README.html deleted file mode 100644 index 8917fa2e7..000000000 --- a/documentation/README.html +++ /dev/null @@ -1,383 +0,0 @@ - - - - -README - EPICS Base Installation Instructions - - -
-

Installation Instructions

-

EPICS Base Release 3.16.1


-
-
-

Table of Contents

- -
- -

What is EPICS base?

-
The Experimental Physics and Industrial Control Systems - (EPICS) is an extensible set of software components and tools with - which application developers can create a control system. This control - system can be used to control accelerators, detectors, telescopes, or - other scientific experimental equipment. EPICS base is the set of core - software, i.e. the components of EPICS without which EPICS would not - function. EPICS base allows an arbitrary number of target systems, IOCs - (input/output controllers), and host systems, OPIs (operator - interfaces) of various types.
- -

What is new in this release?

-
Please check the RELEASE_NOTES file in the distribution for - description of changes and release migration details.
- -

Copyright

-
Please review the LICENSE file included in the - distribution for legal terms of usage.
- -

Supported platforms

- -
The list of platforms supported by this version of EPICS base - is given in the configure/CONFIG_SITE file. If you are trying to build - EPICS Base on an unlisted host or for a different target machine you - must have the proper host/target cross compiler and header files, and - you will have to create and add the appropriate new configure files to - the base/configure/os/directory. You can start by copying existing - configuration files in the configure/os directory and then make changes - for your new platforms.
- -

Supported compilers

- -
This version of EPICS base has been built and tested using the host - vendor's C and C++ compilers, as well as the GNU gcc and g++ compilers. The GNU - cross-compilers work for all cross-compiled targets. You may need the C and C++ - compilers to be in your search path to do EPICS builds; check the definitions - of CC and CCC in base/configure/os/CONFIG.<host>.<host> if you have - problems.
- -

Software requirements

- -
GNU make
- You must use GNU make, gnumake, for any EPICS builds. Set your path - so that a gnumake version 3.81 or later is available. - -

Perl
- You must have Perl version 5.8.1 or later installed. The EPICS configuration - files do not specify the perl full pathname, so the perl executable must - be found through your normal search path.

- -

Unzip and tar (Winzip on WIN32 systems)
- You must have tools available to unzip and untar the EPICS base - distribution file.

- -

Target systems
- EPICS supports IOCs running on embedded platforms such as VxWorks - and RTEMS built using a cross-compiler, and also supports soft IOCs running - as processes on the host platform.

- -

vxWorks
- You must have vxWorks 6 installed if any of your target systems are vxWorks - systems; the C++ compilers for vxWorks 5.x are now too old to support. The - vxWorks installation provides the cross-compiler and header files needed to - build for these targets. The absolute path to and the version number of the - vxWorks installation must be set in the - base/configure/os/CONFIG_SITE.Common.vxWorksCommon file or in one of its - target-specific overrides.

- -

Consult the vxWorks - 6.x EPICS web pages and the vxWorks documentation for information - about configuring your vxWorks operating system for use with EPICS.

- -

RTEMS
- For RTEMS targets, you need RTEMS core and toolset version 4.9.2 or later.

- -

GNU readline or Tecla library
- GNU readline and Tecla libraries can be used by the IOC shell to - provide command line editing and command line history recall and edit. - GNU readline (or Tecla library) must be installed on your target system - when COMMANDLINE_LIBRARY is set to READLINE (or TECLA) for that target. - EPICS (EPICS shell) is the default specified in CONFIG_COMMON. A - READLINE override is defined for linux-x86 in the EPICS distribution. - Comment out COMMANDLINE_LIBRARY=READLINE in - configure/os/CONFIG_SITE.Common.linux-x86 if readline is not installed - on linux-x86. Command-line editing and history will then be those - supplied by the os. On vxWorks the ledLib command-line input library is - used instead.

-
- -

Host system storage requirements

- -
The compressed tar file is approximately 1.6 MB in size. The - distribution source tree takes up approximately 12 MB. Each host target will - need around 40 MB for build files, and each cross-compiled target around 20 - MB.
- -

Documentation

-
EPICS documentation is available through the - EPICS website at Argonne. -

Release specific documentation can also be found in the base/documentation - directory of the distribution.

- -

Directory Structure

-

Distribution directory structure:

- -
-        base                    Root directory of the base distribution
-        base/configure          Operating system independent build config files
-        base/configure/os       Operating system dependent build config files
-        base/documentation      Distribution documentation
-        base/src                Source code in various subdirectories
-        base/startup            Scripts for setting up path and environment
-
- -

Install directories created by the build:

-
-        bin                     Installed scripts and executables in subdirs
-        cfg                     Installed build configuration files
-        db                      Installed data bases
-        dbd                     Installed data base definitions
-        doc                     Installed documentation files
-        html                    Installed html documentation
-        include                 Installed header files
-        include/os              Installed os specific header files in subdirs
-        include/compiler        Installed compiler-specific header files
-        lib                     Installed libraries in arch subdirectories
-        lib/perl                Installed perl modules
-        templates               Installed templates
-
-
- -

Build related components

-
- -

base/documentation directory - contains setup, build, and install - documents

-
-        README.1st           Instructions for setup and building epics base
-        README.html          html version of README.1st
-        README.darwin.html   Installation notes for Mac OS X (Darwin)
-        RELEASE_NOTES.html   Notes on release changes
-        KnownProblems.html   List of known problems and workarounds
-
- -

base/startup directory - contains scripts to set environment and path

-
-        EpicsHostArch       C shell script to set EPICS_HOST_ARCH env variable
-        EpicsHostArch.pl    Perl script to set EPICS_HOST_ARCH env variable
-        Site.profile        bourne shell script to set path and env variables
-        Site.cshrc          c shell script to set path and env variables
-        cygwin.bat          WIN32 bat file to set cygwin path and env variables
-        win32.bat           WIN32 bat file to set path and env variables
-
- -

base/configure directory - contains build definitions and rules

-
-        CONFIG                Includes configure files and allows variable overrides
-        CONFIG.CrossCommon    Cross build definitions
-        CONFIG.gnuCommon      Gnu compiler build definitions for all archs
-        CONFIG_ADDONS         Definitions for <osclass> and DEFAULT options
-        CONFIG_APP_INCLUDE
-        CONFIG_BASE           EPICS base tool and location definitions
-        CONFIG_BASE_VERSION   Definitions for EPICS base version number
-        CONFIG_COMMON         Definitions common to all builds
-        CONFIG_ENV            Definitions of EPICS environment variables
-        CONFIG_FILE_TYPE
-        CONFIG_SITE           Site specific make definitions
-        CONFIG_SITE_ENV       Site defaults for EPICS environment variables
-        MAKEFILE              Installs CONFIG* RULES* creates
-        RELEASE               Location of external products
-        RULES                 Includes appropriate rules file
-        RULES.Db              Rules for database and database definition files
-        RULES.ioc             Rules for application iocBoot/ioc* directory
-        RULES_ARCHS           Definitions and rules for building architectures
-        RULES_BUILD           Build and install rules and definitions
-        RULES_DIRS            Definitions and rules for building subdirectories
-        RULES_EXPAND
-        RULES_FILE_TYPE
-        RULES_TARGET
-        RULES_TOP             Rules specific to a <top> dir (uninstall and tar)
-        Sample.Makefile       Sample makefile with comments
-
- -

base/configure/os directory - contains os-arch specific definitions

-
-        CONFIG.<host>.<target>      Specific host-target build definitions
-        CONFIG.Common.<target>      Specific target definitions for all hosts
-        CONFIG.<host>.Common        Specific host definitions for all targets
-        CONFIG.UnixCommon.Common    Definitions for Unix hosts and all targets
-        CONFIG.Common.UnixCommon    Definitions for Unix targets and all hosts
-        CONFIG.Common.vxWorksCommon Specific host definitions for all vx targets
-        CONFIG_SITE.<host>.<target> Site specific host-target definitions
-        CONFIG_SITE.Common.<target> Site specific target defs for all hosts
-        CONFIG_SITE.<host>.Common   Site specific host defs for all targets
-
- -
- -

Building EPICS base (Unix and Win32)

-
- -

Unpack file

-
-Unzip and untar the distribution file. Use WinZip on Windows - systems. -
- -

Set environment variables

-
-Files in the base/startup directory have been provided to - help set required path and other environment variables. - -

EPICS_HOST_ARCH
- Before you can build or use EPICS R3.15, the environment variable - EPICS_HOST_ARCH must be defined. A perl script EpicsHostArch.pl in the - base/startup directory has been provided to help set EPICS_HOST_ARCH. - You should have EPICS_HOST_ARCH set to your host operating system - followed by a dash and then your host architecture, e.g. solaris-sparc. - If you are not using the OS vendor's c/c++ compiler for host builds, - you will need another dash followed by the alternate compiler name - (e.g. "-gnu" for GNU c/c++ compilers on a solaris host or "-mingw" - for MinGW c/c++ compilers on a WIN32 host). See configure/CONFIG_SITE - for a list of supported EPICS_HOST_ARCH values.

- -

PERLLIB
- On WIN32, some versions of Perl require that the environment - variable PERLLIB be set to <perl directory location>.

- -

PATH
- As already mentioned, you must have the perl executable and you may - need C and C++ compilers in your search path. For building base you - also must have echo in your search path. For Unix host builds you also - need ln, cpp, cp, rm, mv, and mkdir in your search path and /bin/chmod - must exist. On some Unix systems you may also need ar and ranlib in - your path, and the C compiler may require as and ld in your path. On - solaris systems you need uname in your path.

- -

LD_LIBRARY_PATH
- - R3.15 shared libraries and executables normally contain the full path - to any libraries they require. - However, if you move the EPICS files or directories from their build-time - location then in order for the shared libraries to be found at runtime - LD_LIBRARY_PATH must include the full pathname to - $(INSTALL_LOCATION)/lib/$(EPICS_HOST_ARCH) when invoking executables, or - some equivalent OS-specific mechanism (such as /etc/ld.so.conf on Linux) - must be used. - Shared libraries are now built by default on all Unix type hosts.

-
- -

Do site-specific build configuration

-
- -Site configuration
- To configure EPICS, you may want to modify the default definitions - in the following files: -
-        configure/CONFIG_SITE      Build choices. Specify target archs.
-        configure/CONFIG_SITE_ENV  Environment variable defaults
-        configure/RELEASE          TORNADO2 full path location
-
- - Host configuration
- To configure each host system, you may override the default - definitions by adding a new file in the configure/os directory with - override definitions. The new file should have the same name as the - distribution file to be overridden except with CONFIG in the name - changed to CONFIG_SITE. - -
-        configure/os/CONFIG.<host>.<host>      Host build settings
-        configure/os/CONFIG.<host>.Common      Host common build settings
-
- -Target configuration
- To configure each target system, you may override the default - definitions by adding a new file in the configure/os directory with - override definitions. The new file should have the same name as the - distribution file to be overridden except with CONFIG in the name - replaced by CONFIG_SITE. This step is necessary even if the host system - is the only target system. -
-        configure/os/CONFIG.Common.<target>     Target common settings
-        configure/os/CONFIG.<host>.<target>     Host-target settings
-
-
- -

Build EPICS base

-
After configuring the build you should be able to build - EPICS base by issuing the following commands in the distribution's root - directory (base): -
-        gnumake clean uninstall
-        gnumake
-
- - The command "gnumake clean uninstall" - will remove all files and directories generated by a previous build. - The command "gnumake" will build and install everything for the - configured host and targets. - -

It is recommended that you do a "gnumake clean uninstall" at the - root directory of an EPICS directory structure before each complete - rebuild to ensure that all components will be rebuilt. -

-
- -

Example application and extension

-
A perl tool, makeBaseApp.pl is included in the distribution - file. This script will create a sample application that can be built - and then executed to try out this release of base. - -

- Instructions for building and executing the 3.15 example application - can be found in the section "Example Application" of Chapter 2, - "Getting Started", in the "IOC Application Developer's Guide" for this - release. The "Example IOC Application" section briefly explains how to - create and build an example application in a user created <top> - directory. It also explains how to run the example application on a - vxWorks ioc or as a process on the host system. - By running the example application as a host-based IOC, you will be - able to quickly implement a complete EPICS system and be able to run channel - access clients on the host system. - -

- A perl script, - makeBaseExt.pl, is included in the distribution file. This script will - create a sample extension that can be built and executed. The - makeBaseApp.pl and makeBaseExt.pl scripts are installed into the - install location bin/<hostarch> directory during the base build. -

- -

Multiple host platforms

-
You can build using a single EPICS directory structure on - multiple host systems and for multiple cross target systems. The - intermediate and binary files generated by the build will be created in - separate subdirectories and installed into the appropriate separate - host/target install directories. EPICS executables and perl scripts are - installed into the $(INSTALL_LOCATION)/bin/<arch> directories. - Libraries are installed into $(INSTALL_LOCATION)/lib/<arch>. - The default definition for $(INSTALL_LOCATION) is $(TOP) - which is the root directory in the distribution directory structure, - base. Created object files are stored in O.<arch> source - subdirectories, This allows objects for multiple cross target - architectures to be maintained at the same time. To build EPICS base - for a specific host/target combination you must have the proper - host/target C/C++ cross compiler and target header files and the - base/configure/os directory must have the appropriate configure files. -
- - diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html deleted file mode 100644 index 111c604d3..000000000 --- a/documentation/RELEASE_NOTES.html +++ /dev/null @@ -1,1030 +0,0 @@ - - - - - EPICS Base R3.16.1 Release Notes - - - -

EPICS Base Release 3.16.1

- - - -

Changes made between 3.16.0.1 and 3.16.1

- -

IOC Database Support for 64-bit integers

- -

The IOC now supports the 64-bit integer field types DBF_INT64 and -DBF_UINT64, and there are new record types int64in and -int64out derived from the longin and longout types -respectively that use the DBF_INT64 data type for their VAL and related -fields. The usual range of Soft Channel device support are included for these -new record types.

- -

All internal IOC APIs such as dbAccess can handle the new field types and -their associated request values DBR_INT64 and DBR_UINT64, -which are implemented using the epicsInt64 and epicsUInt64 -typedef's from the epicsTypes.h header.

- -

The waveform record type has been updated to support these new field types. -All waveform device support layers must be updated to recognize the new -type enumeration values, which had to be inserted before the -FLOAT value in the enum dbfType and in menuFtype. C -or C++ code can detect at compile-time whether this version of base provides -64-bit support by checking for the presence of the DBR_INT64 macro as -follows (Note that DBF_INT64 is an enum tag and not a -preprocessor macro):

- -
-#ifdef DBR_INT64
-    /* Code where Base has INT64 support */
-#else
-    /* Code for older versions */
-#endif
-
- -

Channel Access does not (and probably never will) directly support 64-bit -integer types, so the new field types are presented to the CA server as -DBF_DOUBLE values. This means that field values larger than 2^52 -(0x10_0000_0000_0000 = 4503599627370496) cannot be transported over Channel -Access without their least significant bits being truncated. The EPICS V4 -pvAccess network protocol can transport 64-bit data types however, and -a future release of the pvaSrv module will connect this ability to the fields of -the IOC.

- -

Additional 64-bit support will be provided in later release. For instance the -JSON parser for the new Link Support feature only handles integers up to -32 bits wide, so constant array initializer values cannot hold larger -values in this release.

- - -

Add EPICS_CA_MCAST_TTL

- -

A new environment parameter EPICS_CA_MCAST_TTL is used to set the Time To -Live (TTL) value of any IP multi-cast CA search or beacon packets sent.

- - -

EPICS_CA_MAX_ARRAY_BYTES is optional

- -

A new environment parameter EPICS_CA_AUTO_ARRAY_BYTES is now used by libca -and RSRV (CA clients and the IOC CA server). The default is equivalent to -setting EPICS_CA_AUTO_ARRAY_BYTES=YES which removes the need to set -EPICS_CA_MAX_ARRAY_BYTES and always attempts to allocate sufficiently large -network buffers to transfer large arrays properly over the network. In this case -the value of the EPICS_CA_MAX_ARRAY_BYTES parameter is ignored.

- -

Explicitly setting EPICS_CA_AUTO_ARRAY_BYTES=NO will continue to honor the -buffer setting in EPICS_CA_AUTO_ARRAY_BYTES as in previous releases.

- -

The default setting for EPICS_CA_AUTO_ARRAY_BYTES can be changed by -adding the line

- -
-EPICS_CA_AUTO_ARRAY_BYTES=NO
-
- -

to the configure/CONFIG_SITE_ENV file before building Base. Sites that wish -to override this only for specific IOC architectures can create new files for -each architecture named configure/os/CONFIG_SITE_ENV.<target-arch> with -the above setting in before building Base. The configuration can also be -explicitly changed by setting the environment variable in the IOC's startup -script, anywhere above the iocInit line.

- -

The PCAS server (used by the PV Gateway and other CA servers) now always -behaves as if EPICS_CA_AUTO_ARRAY_BYTES is set to YES (it ignores the -configuration parameter and environment variable).

- - -

Channel Access "modernization"

- -

Drop support for CA clients advertising protocol versions less than 4.

- -

This effects clients from Base older than 3.12.0-beta1. -Newer clients will continue to be able to connect to older servers. -Older clients will be ignored by newer servers.

- -

This allows removal of UDP echo and similar protocol features which -are not compatible with secure protocol design practice.

- - -

Lookup-tables using the subArrray record

- -

The subArray record can now be used as a lookup-table from a constant array -specified in its INP field. For example:

- -
-record(subArray, "powers-of-2") {
-  field(FTVL, "LONG")
-  field(MALM, 12)
-  field(INP, [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048])
-  field(INDX, 0)
-  field(NELM, 1)
-}
-
- -

The INDX field selects which power of 2 to set the VAL field to. In previous -releases the INP field would have to have been pointed to a separate waveform -record that was initialized with the array values somehow at initialization -time.

- -

Synchronized Timestamps with TSEL=-2

- -

Most Soft Channel input device support routines have supported fetching the -timestamp through the INP link along with the input data. However before now -there was no guarantee that the timestamp provided by a CA link came from the -same update as the data, since the two were read from the CA input buffer at -separate times without maintaining a lock on that buffer in between. This -shortcoming could be fixed as a result of the new link support code, which -allows code using a link to pass a subroutine to the link type which will be run -with the link locked. The subroutine may make multiple requests for metadata -from the link, but must not block.

- - -

Extensible Link Types

- -
- -

A major new feature introduced with this release of EPICS Base is an -Extensible Link Type mechanism, also known as Link Support or JSON Link Types. -This addition permits new kinds of link I/O to be added to an IOC in a similar -manner to the other extension points already supported (e.g. record, device and -driver support).

- -

A new link type must implement two related APIs, one for parsing the JSON -string which provides the link address and the other which implements the link -operations that get called at run-time to perform I/O. The link type is built -into the IOC by providing a new link entry in a DBD file.

- - -

New Link Types Added

- -

This release contains two new JSON link types, const and -calc:

- -
    - -
  • The const link type is almost equivalent to the old CONSTANT link -type with the updates described below to accept arrays and strings, except that -there is no need to wrap a scalar string constant inside array brackets since a -constant string will never be confused with a PV name.
  • - -
  • The calc link type allows CALC expressions to be used to combine -values from other JSON links to produce its value. Until additional JSON link -types are created though, the calc link type has little practical -utility as it can currently only fetch inputs from other calc links or -from const links.
  • - -
- -
-  field(INP, {calc:{expr:"A+B+1",
-                    args:[5,         # A
-                          {const:6}] # B
-             }})
-
- -

The new link types are documented in a -separate -document -.

- - -

Device Support Addressing using JSON_LINK

- -

The API to allow device support to use JSON addresses is currently -incomplete; developers are advised not to try creating device support that -specifies a JSON_LINK address type.

- - -

Support Routine Modifications for Extensible Link Types

- -

For link fields in external record types and soft device support to be able -to use the new link types properly, various changes are required to utilize the -new Link Support API as defined in the dbLink.h header file and outlined below. -The existing built-in Database and Channel Access link types have been altered -to implement the link APIs, so will work properly after these conversions:

- -
    - -
  • Make all calls to recGblInitConstantLink() unconditional on the -link type, i.e. change this code: - -
    -    if (prec->siml.type == CONSTANT) {
    -        recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
    -    }
    -
    - -into this: - -
    -    recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm);
    -
    - -Note that recGblInitConstantLink() still returns TRUE if the field was -successfully initialized from the link (implying the link is constant).
    -This change will work properly with all Base releases currently in use.
  • - -
  • Code that needs to identify a constant link should be modified to use the -new routine dbLinkIsConstant() instead, which returns TRUE for constant -or undefined links, FALSE for links whose dbGetLink() routine may -return different values on different calls. For example this: - -
    -    if (prec->dol.type != CONSTANT)
    -
    - -should become this: - -
    -    if (!dbLinkIsConstant(&prec->dol))
    -
    - -When the converted software is also required to build against older versions of -Base, this macro definition may be useful: - -
    -#define dbLinkIsConstant(lnk) ((lnk)->type == CONSTANT)
    -
    -
  • - -
  • Any code that calls dbCa routines directly, or that explicitly checks if a -link has been resolved as a CA link using code such as - -
    -    if (prec->inp.type == CA_LINK)
    -
    - -will still compile and run, but will only work properly with the old CA link -type. To operate with the new extensible link types such code must be modified -to use the new generic routines defined in dbLink.h and should never attempt to -examine or modify data inside the link. After conversion the above line would -probably become: - -
    -    if (dbLinkIsVolatile(&prec->inp))
    -
    - -A volatile link is one like a Channel Access link which may disconnect and -reconnect without notice at runtime. Database links and constant links are not -volatile; unless their link address is changed they will always remain in the -same state they started in. For compatibility when building against older -versions of Base, this macro definition may be useful: - -
    -#define dbLinkIsVolatile(lnk) ((lnk)->type == CA_LINK)
    -
    -
  • - -
  • The current connection state of a volatile link can be found using the -routine dbIsLinkConnected() which will only return TRUE for a volatile -link that is currently connected. Code using the older dbCa API returning this -information used to look like this: - -
    -    stat = dbCaIsLinkConnected(plink);
    -
    - -which should become: -
    -    stat = dbIsLinkConnected(plink);
    -
    - -Similar changes should be made for calls to the other dbCa routines.
  • - - -
  • A full example can be found by looking at the changes to the calcout record -type, which has been modified in this release to use the new dbLink generic -API.
  • - -
- -
- - -

Constant Link Values

- -

Previously a constant link (i.e. a link that did not point to another PV, -either locally or over Channel Access) was only able to provide a single numeric -value to a record initialization; any string given in a link field that was not -recognized as a number was treated as a PV name. In this release, constant links -can be expressed using JSON array syntax and may provide array initialization of -values containing integers, doubles or strings. An array containing a single -string value can also be used to initialize scalar strings, so the stringin, -stringout, lsi (long string input), lso (long string output), printf, waveform, -subArray and aai (analog array input) record types and/or their soft device -supports have been modified to support this.

- -

Some examples of constant array and string initialized records are:

- -
-  record(stringin, "const:string") {
-    field(INP, ["Not-a-PV-name"])
-  }
-  record(waveform, "const:longs") {
-    field(FTVL, LONG)
-    field(NELM, 10)
-    field(INP, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
-  }
-  record(aai, "const:doubles") {
-    field(FTVL, DOUBLE)
-    field(NELM, 10)
-    field(INP, [0, 1, 1.6e-19, 2.718, 3.141593])
-  }
-  record(aSub, "select") {
-    field(FTA, STRING)
-    field(NOA, 4)
-    field(INPA, ["Zero", "One", "Two", "Three"])
-    field(FTB, SHORT)
-    field(NOB, 1)
-    field(FTVA, STRING)
-    field(NOVA, 1)
-    field(SNAM, "select_asub")
-  }
-
- -

Reminder: Link initialization with constant values normally only occurs at -record initialization time. The calcout and printf record types are the only -exceptions in the Base record types to this rule, so it is generally not useful -to change a const link value after iocInit.

- - -

Database Parsing of "Relaxed JSON" Values

- -

A database file can now provide a "relaxed JSON" value for a database field -value or an info tag. Only a few field types can currently accept such values, -but the capability is now available for use in other places in the future. When -writing to a JSON-capable field at run-time however, only strictly compliant -JSON may be used (the dbStaticLib parser rewrites relaxed JSON values into -strict JSON before passing them to the datase for interpretation, where the -strict rules must be followed).

- -

"Relaxed JSON" was developed to maximize compatibility with the previous -database parser rules and reduce the number of double-quotes that would be -needed for strict JSON syntax. The parser does accept strict JSON too though, -which should be used when machine-generating database files. The differences -are:

- -
    - -
  • Strings containing only the characters a-z A-Z 0-9 _ - + . -do not have to be enclosed in double-quote characters.
  • - -
  • The above rule applies to map keys as well as to regular string values.
  • - -
  • The JSON keywords null, true and false (all -lower-case) will be recognized as keywords, so they must be quoted to use any of -these single words as a string.
  • - -
  • Comments may be used, introduced as usual by the # -character and extending to the end of the line.
  • - -
- -

A JSON field or info value is only enclosed in quotes when the value being -provided is a single string, and even here the quotes can be omitted in some -cases as described above. The following shows both correct and incorrect -excerpts from a database file:

- -
-    record(ai, math:pi) {
-        field(INP, {const: 3.14159265358979})   # Correct
-        field(SIOL, "{const: 3.142857}")        # Wrong
-
-        info(autosave, {            # White-space and comments are allowed
-            fields:[DESC, SIMM],
-            pass0:[VAL]
-        })                          # Correct
-    }
-
- -

Note that the record, field and info-tag names do not accept JSON -values, so they follows the older bareword rules for quoting where the colon -: and several additional characters are legal in a bareword -string. Only the value (after the comma) is parsed as JSON. The autosave module -has not been modified to accept JSON syntax, the above is only an example of -how JSON might be used.

- -

Echoless comments in iocsh

- -

The way comments are parsed by the iocsh interpreter has changed. The -interpreter can be selectively disabled from echoing comments coming from -a script by starting those lines with '#-' rather than just '#'.

- - -

Typed record support methods

- -

The table of record support functions (rset methods for short) no longer -has entries of type RECSUPFUN (which says: any number and type of -arguments). Instead, rset methods are now typed by default. The -RECSUPFUN typedef has been deprecated and casts to it as well as -using the untyped struct rset will create compilation warnings.

- -

Existing code (e.g. external record supports) will generate such -warnings when compiled against this version of Base, but it will work -without changes.

- -

For a conversion period, the new typed rset definitions are activated -by defining USE_TYPED_RSET, preferably by setting -USR_CPPFLAGS += -DUSE_TYPED_RSET inside a Makefile. -After activating the new typed rset in this way and making the following -changes, the result should still compile and work properly against older -versions of Base.

- -

The first parameter of init_record and process has been -changed to struct dbCommon *. Record types that use -void* here should be changed to use struct dbCommon*, and -cast the argument to their own xxxRecord *.

- -

When compiled against this release, compiler warnings about incompatible -types for the method pointers should be taken seriously. When compiled -against older versions of base, such warnings are unavoidable.

- -

Record types written in C++ need to take more drastic measures because of -the stricter type checking in C++. To remain compatible with older versions -of base you will need to use something like:

- -
-#include "epicsVersion.h"
-#ifdef VERSION_INT
-#  if EPICS_VERSION_INT < VERSION_INT(3,16,0,2)
-#    define RECSUPFUN_CAST (RECSUPFUN)
-#  else
-#    define RECSUPFUN_CAST
-#  endif
-#else
-#  define RECSUPFUN_CAST (RECSUPFUN)
-#endif
-
- -

and then replace (RECSUPFUN) with RECSUPFUN_CAST -when initializing the rset. -Further changes might also be needed, e.g. to adapt const-ness of -method parameters.

- -
- -

Changes made between 3.15.3 and 3.16.0.1

- -

Build support for CapFast and dbst removed

- -

The build rules associated with the CapFast-related tools sch2edif -and e2db and the database optimization tool dbst have -been removed, along with the DB_OPT build configuration variable.

- -

compressRecord buffering order

- -

The compressRecord has a new field BALG which can select between -FIFO (append) and LIFO (prepend) ordering for insertion of new elements. FIFO -ordering is the default, matching the behviour of previous versions.

- -

Valgrind Instrumentation

- -

Valgrind is a software debugging suite provided by many Linux distributions. -The header valgrind/valgrind.h is now included in, and installed by, Base. -When included by a C or C++ source file this header defines some macros which -expand to provide hints to the Valgrind runtime. -These have no effect on normal operation of the software, but when run using the -valgrind tool they can help to find memory leaks and buffer overflows. -Suitable hints have been added to several free-lists within libCom, including -freeListLib, allowing valgrind to provide more accurate information about the -source of potential leaks.

- -

valgrind.h automatically disables itself when the build target is not -supported by the valgrind tool. -It can also explicitly be disabled by defining the macro NVALGRIND. -See src/libCom/Makefile for a commented-out example.

- -

As a matter of policy valgrind.h will never be included by any header file -installed by Base, so its use will remain purely an implementation -detail hidden from application software. -Support modules which choose to use valgrind.h are advised to do -likewise.

- -

Database Multi-locking

- -

The IOC record locking code has been re-written with an expanded API; global -locks are no longer required by the IOC database implementation.

- -

The new API functions center around dbScanLockMany(), which behaves like -dbScanLock() applied to an arbitrary group of records. dbLockerAlloc() is used -to prepare a list or record pointers, then dbScanLockMany() is called. When it -returns, all of the records listed may be accessed (in any order) until -dbScanUnlockMany() is called.

- -

The Application Developer's Guide has been updated to describe the API and -implementation is more detail.

- -

Previously a global mutex 'lockSetModifyLock' was locked and unlocked during -dbScanLock(), acting as a sequencing point for otherwise unrelated calls. The -new dbLock.c implementation does not include any global mutex in dbScanLock() or -dbScanLockMany(). Locking/unlocking of unrelated lock sets is now completely -concurrent.

- -

Generate Version Header

- -

A Perl script and Makefile rules have been added to allow modules to generate -a C header file with a macro defined with an automatically updated identifier. -This is a VCS revision ID (Darcs, Git, Mercurial, Subversion, and Bazaar are -supported) or the date/time of the build if no VCS system is in use.

- -

The makeBaseApp example template has been updated with a new device support -which makes this identifier visible via a lsi (long string input) record.

- -

epicsTime API return status

- -

The epicsTime routines that used to return epicsTimeERROR now return a -specific S_time_ status value, allowing the caller to discover the reason for -any failure. The identifier epicsTimeERROR is no longer defined, so any -references to it in source code will no longer compile. The identifier -epicsTimeOK still exists and has the value 0 as before, so most code that uses -these APIs can be changed in a way that is backwards-compatible with the -previous return status.

- -

Time providers that have to return a status value and still need to be built -with earlier versions of Base can define the necessary status symbols like -this:

- -
-#include "epicsTime.h"
-
-#ifndef M_time
-/* S_time_... status values were not provided before Base 3.16 */
-#define S_time_unsynchronized epicsTimeERROR
-#define S_time_...whatever... epicsTimeERROR
-#endif
-
- -

Refactoring of epicsReadline

- -

The epicsReadline code has been reorganized to allow the commandline history -editor to be disabled at runtime. The EPICS_COMMANDLINE_LIBRARY build setting -still selects the preferred editor, but the new IOCSH_HISTEDIT_DISABLE -environment variable can be set at runtime to disable history editing and make -the IOC or other program use the basic editor instead. This is useful when -starting and controlling an IOC from another program through its stdin and -stdout streams since history editors often insert invisible escape codes into -the stdout stream, making it hard to parse.

- -

Callback subsystem API

- -

Added a new macro callbackGetPriority(prio, callback) to the -callback.h header and removed the need for dbScan.c to reach into the internals -of its CALLBACK objects.

- - -

Changes from the 3.15 branch since 3.15.5

- - - -

Support for CONFIG_SITE.local in Base

- -

This feature is mostly meant for use by developers; configuration -settings that would normally appear in Base/configure/CONFIG_SITE can now -be put in a locally created base/configure/CONFIG_SITE.local file instead -of having go modify or replace the original. A new .gitignore pattern -tells git to ignore all configure/*.local files.

- - -

Changes from the 3.14 branch since 3.15.5

- - - -

Extend maximum Posix epicsEventWaitWithTimeout() delay

- -

The Posix implementation of epicsEventWaitWithTimeout() was limiting the -timeout delay to at most 60 minutes (3600.0 seconds). This has been changed to -10 years; significantly longer maximum delays cause problems on systems where -time_t is still a signed 32-bit integer so cannot represent absolute -time-stamps after 2038-01-19. Our assumption is that such 32-bit systems will -have been retired before the year 2028, but some additional tests have been -added to the epicsTimeTest program to detect and fail if this assumption is -violated.

- -

New test-related make targets

- -

This release adds several new make targets intended for use by developers -and Continuous Integration systems which simplify the task of running the -built-in self-test programs and viewing the results. Since these targets are -intended for limited use they can have requirements for the build host which -go beyond the standard minimum set needed to build and run Base.

- -
- -

test-results — Summarize test results

- -

The new make target test-results will run the self-tests if -necessary to generate a TAP file for each test, then summarizes the TAP output -files in each test directory in turn, displaying the details of any failures. -This step uses the program prove which comes with Perl, but also needs -cat to be provided in the default search path so will not work on most -Windows systems.

- -

junitfiles — Convert test results to JUnit XML Format

- -

The new make target junitfiles will run the self-tests if necessary -and then convert the TAP output files into the more commonly-supported JUnit -XML format. The program that performs this conversion needs the Perl module -XML::Generator to have been installed.

- -

clean-tests — Delete test result files

- -

The new make target clean-tests removes any test result files from -previous test runs. It cleans both TAP and JUnit XML files.

- -
- -

Fix DNS related crash on exit

- -

The attempt to fix DNS related delays for short lived CLI programs (eg. caget) -in lp:1527636 introduced a bug which cased these short lived clients to crash on exit. -This bug should now be fixed.

- -

Server bind issue on Windows

- -

When a National Instruments network variables CA server is already running on -a Windows system and an IOC or PCAS server is started, the IOC's attempt to -bind a TCP socket to the CA server port number fails, but Windows returns a -different error status value than the IOC is expecting in that circumstance -(because the National Instruments code requests exclusive use of that port, -unlike the EPICS code) so the IOC fails to start properly. The relevent EPICS -bind() checks have now been updated so the IOC will request that a dynamic port -number be allocated for this TCP socket instead when this happens.

- -

Checking Periodic Scan Rates

- -

Code has been added to the IOC startup to better protect it against bad -periodic scan rates, including against locales where . is not -accepted as a decimal separator character. If the scan period in a menuScan -choice string cannot be parsed, the associated periodic scan thread will no -longer be started by the IOC and a warning message will be displayed at iocInit -time. The scanppl command will also flag the faulty menuScan value.

- - -

Changes made between 3.15.4 and 3.15.5

- -

dbStatic Library Speedup and Cleanup

- -

Loading of database files has been optimized to avoid overproportionally -long loading times for large databases. As a part of this, the alphabetical -ordering of records instances (within a record type) has been dropped. In the -unexpected case that applications were relying on the alphabetic order, setting -dbRecordsAbcSorted = 1 before loading the databases will retain the -old behavior.

- -

The routine dbRenameRecord() has been removed, as it was intended -to be used by database configuration tools linked against a host side version -of the dbStatic library that is not being built anymore.

- -

Launchpad Bug-fixes

- -

In addition to the more detailed change descriptions below, the following -Launchpad bugs have also been fixed in this release:

- -
    -
  • - #1440186 Crash due to a too small buffer being provided in - dbContextReadNotifyCache
  • -
  • - #1479316 Some data races found using Helgrind
  • -
  • - #1495833 biRecord prompt groups are nonsensical
  • -
  • - #1606848 WSAIoctl SIO_GET_INTERFACE_LIST failed in Windows
  • -
- -

Whole-Program Optimization for MS Visual Studio Targets

- -

When using the Microsoft compilers a new build system variable is provided -that controls whether whole program optimization is used or not. For static -builds using Visual Studio 2010 this optimization must be disabled. This is -controlled in the files configure/os/CONFIG_SITE.Common.windows-x64-static and -configure/os/CONFIG_SITE.Common.win32-x86-static by setting the variable -OPT_WHOLE_PROGRAM = NO to override the default value -YES that would otherwise be used.

- -

Note that enabling this optimization slows down the build process. It is not -possible to selectively disable this optimization, when building a particular -module say; Microsoft's linker will restart itself automatically with the --LTCG flag set and display a warning if it is asked to link any object -files that were compiled with the -GL flag.

- -

Add dynamic (variable length) array support to PCAS

- -

Dynamic array sizing support was added to the IOC server (RSRV) in the -Base-3.14.12 release, but has not until now been supported in the Portable -Channel Access Server (PCAS). Channel Access server applications using the -PCAS may not need to be modified at all; if they already push monitors with -different gdd array lengths, those variable sizes will be forwarded to any CA -clients who have requested variable length updates. The example CAS server -application has been modified to demonstrate this feature.

- -

In implementing the above, the gdd method gdd::put(const gdd *) now -copies the full-sized array from the source gdd if the destination gdd is of -type array, has no allocated memory and a boundary size of 0.

- -

Additional epicsTime conversion

- -

The EPICS timestamp library (epicsTime) inside libCom's OSI layer has -been extended by routines that convert from struct tm to the EPICS -internal epicsTime type, assuming UTC - i.e. without going through -the timezone mechanism. This solves issues with converting from the structured -type to the EPICS timestamp at driver level from multiple threads at a high -repetition rate, where the timezone mechanism was blocking on file access.

- -

MinGW Cross-builds from Linux

- -

The build configuration files that allow cross-building of the 32-bit -win32-x86-mingw cross-target have been adjusted to default to building shared -libraries (DLLs) as this is now supported by recent MinGW compilers. The 64-bit -windows-x64-mingw cross-target was already being built that way by default. The -configuration options to tell the minGW cross-compiler to link programs with -static versions of the compiler support libraries have now been moved into the -CONFIG_SITE.linux-x86.target files.

- -

General Time updates

- -

The iocInit code now performs a sanity check of the current time -returned by the generalTime subsystem and will print a warning if the wall-clock -time returned has not been initialized yet. This is just a warning message; when -a time provider does synchonize the IOC will subsequently pick up and use the -correct time. This check code also primes the registered event system provider -if there is one so the epicsTimeGetEventInt() routine will work on IOCs -that ask for event time within an interrupt service routine.

- -

The osiClockTime provider's synchronization thread (which is only used on -some embedded targets) will now poll the other time providers at 1Hz until the -first time it manages to get a successful timestamp, after which it will poll -for updates every 60 seconds as before.

- -

The routine generalTimeGetExceptPriority() was designed for use by -backup (lower priority) time providers like the osiClockTime provider which do -not have their own absolute time reference and rely on other providers for an -absolute time source. This routine no longer implements the ratchet mechanism -that prevented the time it returned from going backwards. If the backup clock's -tick-timer runs fast the synchronization of the backup time provider would never -allow it to be corrected backwards when the ratchet was in place. The regular -epicsTimeGetCurrent() API still uses the ratchet mechanism, so this -change will not cause the IOC to see time going backwards.

- -

Microsoft Visual Studio builds

- -

The build configuration files for builds using the Microsoft compilers have -been updated, although there should be no noticable difference at most sites. -One extra compiler warning is now being suppressed for C++ code, C4344: -behavior change: use of explicit template arguments results in ... which is -gratuitous and was appearing frequently in builds of the EPICS V4 modules.

- -

Cross-builds of the windows-x64 target from a win32-x86 host have been -removed as they don't actually work within the context of a single make -run. Significant changes to the build configuration files would be necessary for -these kinds of cross-builds to work properly, which could be done if someone -needs them (email Andrew Johnson before working on this, and see - -this stack-overflow answer for a starting point).

- -

Bazaar keywords such as 'Revision-Id' removed

- -

In preparation for moving to git in place of the Bazaar revision control -system we have removed all the keywords from the Base source code.

- -

Linux systemd service file for CA Repeater

- -

Building this version of Base on a Linux system creates a systemd service -file suitable for starting the Channel Access Repeater under systemd. The file -will be installed into the target bin directory, from where it can be copied -into the appropriate systemd location and modified as necessary. Installation -instructions are included as comments in the file.

- - -

Changes made between 3.15.3 and 3.15.4

- -

New string input device support "getenv"

- -

A new "getenv" device support for both the stringin and lsi (long string -input) record types can be used to read the value of an environment variable -from the IOC at runtime. See base/db/softIocExit.db for sample usage.

- -

Build rules and DELAY_INSTALL_LIBS

- -

A new order-only prerequisite build rule has been added to ensure that -library files (and DLL stubs on Windows) get installed before linking any -executables, which resolves parallel build problems on high-powered CPUs. There -are some (rare) cases though where a Makefile has to build an executable and run -it to be able to compile code for a library built by the same Makefile. With -this new build rule GNUmake will complain about a circular dependency and the -build will probably fail in those cases. To avoid this problem the failing -Makefile should set DELAY_INSTALL_LIBS = YES before including the -$(TOP)/configure/RULES file, disabling the new build rule.

- -

IOC environment variables and build parameters

- -

The IOC now sets a number of environment variables at startup that provide -the version of EPICS Base it was built against (EPICS_VERSION_...) and its build -architecture (ARCH). In some cases this allows a single iocBoot/ioc directory to -be used to run the same IOC on several different architectures without any -changes.

- -

There are also 3 new environment parameters (EPICS_BUILD_...) available that -C/C++ code can use to find out the target architecture, OS class and compiler -class it was built with. These may be useful when writing interfaces to other -languages.

- -

New implementation of promptgroup/gui_group field property

- -

The mechanism behind the "promptgroup()" field property inside a record type -definition has been changed. Instead of using a fixed set of choices, -the static database access library now collects the used gui group names -while parsing DBD information. Group names should start with a two-digit number -plus space-dash-space to allow proper sorting of groups.

- -

The include file guigroup.h that defined the fixed set of choices -has been deprecated. Instead, use the conversion functions between index number -and group string that have been added to dbStaticLib.

- -

When a DBD file containing record-type descriptions is expanded, any -old-style GUI_xxx group names will be replaced by a new-style -string for use by the IOC. This permits an older record type to be used with -the 3.15.4 release, although eventually record types should be converted by -hand with better group names used.

- -

CA server configuration changes

- -

RSRV now honors EPICS_CAS_INTF_ADDR_LIST and binds only to the provided list -of network interfaces. Name searches (UDP and TCP) on other network interfaces -are ignored. For example on a computer with interfaces 10.5.1.1/24, 10.5.2.1/24, -and 10.5.3.1/24, setting "EPICS_CAS_INTF_ADDR_LIST='10.5.1.1 10.5.2.1'" will -accept traffic on the .1.1 and .2.1, but ignore from .3.1

- -

RSRV now honors EPICS_CAS_IGNORE_ADDR_LIST and ignores UDP messages received -from addresses in this list.

- -

Previously, CA servers (RSRV and PCAS) would build the beacon address list -using EPICS_CA_ADDR_LIST if EPICS_CAS_BEACON_ADDR_LIST was no set. This is no -longer done. Sites depending on this should set both envronment variables to the -same value.

- -

IPv4 multicast for name search and beacons

- -

libca, RSRV, and PCAS may now use IPv4 multicasting for UDP traffic (name -search and beacons). This is disabled by default. To enable multicast address(s) -must be listed in EPICS_CA_ADDR_LIST for clients and EPICS_CAS_INTF_ADDR_LIST -for servers (IOCs should set both). For example: -"EPICS_CAS_INTF_ADDR_LIST='224.0.2.9' EPICS_CA_ADDR_LIST=224.0.2.9".

- -

Please note that no IPv4 multicast address is officially assigned for Channel -Access by IANA. The example 224.0.2.9 is taken from the AD-HOC Block I range.

- -

Moved mlockall() into its own epicsThread routine

- -

Since EPICS Base 3.15.0.2 on Posix OSs the initialization of the epicsThread -subsystem has called mlockall() when the OS supports it and thread -priority scheduling is enabled. Doing so has caused problems in third-party -applications that call the CA client library, so the functionality has been -moved to a separate routine epicsThreadRealtimeLock() which will be -called by the IOC at iocInit (unless disabled by setting the global variable -dbThreadRealtimeLock to zero).

- -

Added dbQuietMacroWarnings control

- -

When loading database files, macros get expanded even on comment lines. If a -comment contains an undefined macro, the load still continues but an error -message gets printed. For this release the error message has been changed to a -warning, but even this warning can be made less verbose by setting this new -variable to a non-zero value before loading the file, like this:

- -
-var dbQuietMacroWarnings 1      iocsh
-dbQuietMacroWarnings=1          VxWorks
-
- -

This was Launchpad bug -541119.

- - -

Changes from the 3.14 branch between 3.15.3 and 3.15.4

- -

NTP Time Provider adjusts to OS tick rate changes

- -

Dirk Zimoch provided code that allows the NTP Time provider (used on VxWorks -and RTEMS only) to adapt to changes in the OS clock tick rate after the provider -has been initialized. Note that changing the tick rate after iocInit() is not -advisable, and that other software might still misbehave if initialized before -an OS tick rate change. This change was back-ported from the 3.15 branch.

- -

Making IOC ca_get operations atomic

- -

When a CA client gets data from an IOC record using a compound data type such -as DBR_TIME_DOUBLE the value field is fetched from the database in a -separate call than the other metadata, without keeping the record locked. This -allows some other thread such as a periodic scan thread a chance to interrupt -the get operation and process the record in between. CA monitors have always -been atomic as long as the value data isn't a string or an array, but this race -condition in the CA get path has now been fixed so the record will stay locked -between the two fetch operations.

- -

This fixes -Launchpad bug #1581212, thanks to Till Strauman and Dehong Zhang.

- -

New CONFIG_SITE variable for running self-tests

- -

The 'make runtests' and 'make tapfiles' build targets normally only run the -self-tests for the main EPICS_HOST_ARCH architecture. If the host is -able to execute self-test programs for other target architectures that are being -built by the host, such as when building a -debug version of the host -architecture for example, the names of those other architectures can be added to -the new CROSS_COMPILER_RUNTEST_ARCHS variable in either the -configure/CONFIG_SITE file or in an appropriate -configure/os/CONFIG_SITE.<host>.Common file to have the test -programs for those targets be run as well.

- -

Additional RELEASE file checks

- -

An additional check has been added at build-time for the contents of the -configure/RELEASE file(s), which will mostly only affect users of the Debian -EPICS packages published by NSLS-2. Support modules may share an install path, -but all such modules must be listed adjacent to each other in any RELEASE files -that point to them. For example the following will fail the new checks:

- -
-AUTOSAVE = /usr/lib/epics
-ASYN = /home/mdavidsaver/asyn
-EPICS_BASE = /usr/lib/epics
-
- -

giving the compile-time error

- -
-This application's RELEASE file(s) define
-	EPICS_BASE = /usr/lib/epics
-after but not adjacent to
-	AUTOSAVE = /usr/lib/epics
-Module definitions that share paths must be grouped together.
-Either remove a definition, or move it to a line immediately
-above or below the other(s).
-Any non-module definitions belong in configure/CONFIG_SITE.
-
- - -

In many cases such as the one above the order of the AUTOSAVE and -ASYN lines can be swapped to let the checks pass, but if the -AUTOSAVE module depended on ASYN and hence had to appear -before it in the list this error indicates that AUTOSAVE should also be -built in its own private area; a shared copy would likely be incompatible with -the version of ASYN built in the home directory.

- -

String field buffer overflows

- -

Two buffer overflow bugs that can crash the IOC have been fixed, caused by -initializing a string field with a value larger than the field size -(Launchpad bug -#1563191).

- -

Fixed stack corruption bug in epicsThread C++ API

- -

The C++ interface to the epicsThread API could corrupt the stack on thread -exit in some rare circumstances, usually at program exit. This bug has been -fixed (Launchpad bug -#1558206).

- -

RTEMS NTP Support Issue

- -

On RTEMS the NTP Time Provider could in some circumstances get out of sync -with the server because the osdNTPGet() code wasn't clearing its input socket -before sending out a new request. This -(Launchpad bug 1549908) -has now been fixed.

- -

CALC engine bitwise operator fixes

- -

The bitwise operators in the CALC engine have been modified to work properly -with values that have bit 31 (0x80000000) set. This modification involved -back-porting some earlier changes from the 3.15 branch, and fixes -Launchpad bug -#1514520.

- -

Fix ipAddrToAsciiAsync(): Don't try to join the daemon thread

- -

On process exit, don't try to stop the worker thread that makes DNS lookups -asynchronous. Previously this would wait for any lookups still in progress, -delaying the exit unnecessarily. This was most obvious with catools (eg. -cainfo). -lp:1527636

- -

Fix epicsTime_localtime() on Windows

- -

Simpler versions of the epicsTime_gmtime() and epicsTime_localtime() -routines have been included in the Windows implementations, and a new test -program added. The original versions do not report DST status properly. Fixes -Launchpad bug 1528284.

- - - - diff --git a/documentation/ReleaseChecklist.html b/documentation/ReleaseChecklist.html deleted file mode 100644 index bcabe61c5..000000000 --- a/documentation/ReleaseChecklist.html +++ /dev/null @@ -1,368 +0,0 @@ - - - - - - EPICS Release Procedures & Checklist - - - - -

EPICS Base Release Procedures & Checklist

- -

This document describes the procedures and provides a checklist of tasks -that should be performed when creating production releases of EPICS Base.

- -

The Release Process

- -

The version released on the Feature Freeze date is designated the first -pre-release, -pre1. The first release candidate -rc1 is the -first version that has undergone widespread testing and which has no known -problems in it that are slated to be fixed in this release. New versions should -be made at about weekly intervals during the testing and debugging period, and -will be designated as either pre-release or release candidate versions by the -Release Manager. After a release candidate has been available to the whole -community for testing for at least a week without any additional problems being -reported or significant changes being committed, the branch can be designated as -the final release version.

- -

Roles

- -

The following roles are used below:

- -
-
Release Manager ()
-
Responsible for managing and tagging the release
-
Platform Developers (optional)
-
Responsible for individual operating system platforms
-
Application Developers
-
Responsible for support modules that depend on EPICS Base.
-
Website Manager (Andrew Johnson)
-
Responsible for the EPICS website
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CheckWhoDescription
Preparing for a release
 Release ManagerEmail all developers about the upcoming release and ask for a list - of remaining jobs that must be finished.
 All developersCheck the bug tracker for any outstanding items and handle - appropriately. All bugs that have been fixed should have been marked - as Fix Committed.
 Release ManagerSet the Feature Freeze date, by which time all Git commits for - enhancements and new functionality should have been completed. After - this date, commits should only be made to fix problems that show up - during testing.
 Release Manager
- & all developers
Ensure that documentation will be updated before the release date: -
    -
  • Application Developers Guide
  • -
  • Release Notes
  • -
  • Known Problems
  • -
  • Other documents
  • -
-
 Release ManagerReview and update this document for the upcoming release.
 Website ManagerCreate a release milestone on Launchpad if necessary and set the - expected release date. Note that pre-release and release-candidate - versions do not appear on Launchpad, only the final release.
Creating pre-release and release-candidate versions
 Release ManagerEdit and commit changes to the EPICS version number file - configure/CONFIG_BASE_VERSION.
 Release ManagerTag the module in Git using these tag conventions: -
    -
  • - R3.16.1-pren - — pre-release tag -
  • -
  • - R3.16.1-rcn - — release candidate tag -
  • -
-
- cd base-3.16
- git tag -m 'ANJ: Tagged for 3.16.1-rc1' R3.16.1-rc1 -
-
 Release ManagerExport the tagged version into a tarfile. This command generates a - gzipped tarfile directly from the repository, excluding those files and - directories needed only for continuous integration: -
- cd base-3.16
- git archive - --prefix=base-3.16.1-rc1/ - --output=../base-3.16.1-rc1.tar.gz - R3.16.1-rc1 - configure documentation LICENSE Makefile README src startup -
- Create a GPG signature file of the tarfile as follows: -
- gpg --armor --sign --detach-sig base-3.16.1-rc1.tar.gz -
-
 Release ManagerTest the tarfile by extracting its contents and building it on at - least one supported platform.
 Website ManagerIf necessary recreate the tarfile following the instructions above. - Copy the tar file to the Base download area of the website
 Website ManagerCreate or update a website subdirectory to hold the release - documentation, and copy in selected files from the base/documentation - and base/html directories of the tarfile.
 Website ManagerCreate or modify the webpage for the new release with links to the - release documents and tar file. Pre-release and release-candidate - versions should use the page and URL for the final release version - number.
 Website ManagerAdd the new tar file to the website Base download index page.
Testing
 Platform DevelopersRun the built-in test programs on all available host platforms using -
- make -s runtests -
 Platform DevelopersRun the CA client side regression tests on all available host - platforms.
 Platform DevelopersCheck that all makeBaseApp templates build and run properly, all - xxxApp and xxxBoot types and any internal options, e.g. - setting STATIC_BUILD=YES or using a different - INSTALL_LOCATION in configure/CONFIG_SITE.
 Platform DevelopersBuild the SNL Sequencer against this version of Base, and check that - the makeBaseApp example builds and runs correctly with it.
 Application DevelopersBuild external applications against this version of Base on all - available platforms and test as appropriate. Application code changes - may be necessary where the EPICS Base APIs have been modified.
 Release ManagerCheck that documentation has been updated: - -
Release Approval
 Release ManagerObtain a positive Ok to release from all platform developers - once a release candidate version has gone a whole week without any - issues being reported.
Creating the final release version
 Release ManagerEdit and commit changes to the EPICS version number file - configure/CONFIG_BASE_VERSION.
 Release ManagerTag the module in Git: -
- cd base-3.16
- git tag -m 'ANJ: Tagged for 3.16.1' R3.16.1 -
-
 Release ManagerExport the tagged version into a tarfile. This command generates a - gzipped tarfile directly from the repository, excluding those files and - directories needed only for continuous integration: -
- cd base-3.16
- git archive - --prefix=base-3.16.1/ - --output=../base-3.16.1.tar.gz - R3.16.1 - configure documentation LICENSE Makefile README src startup -
- Create a GPG signature file of the tarfile as follows: -
- gpg --armor --sign --detach-sig base-3.16.1.tar.gz -
-
 Release ManagerTest the tar file by extracting its contents and building it on at - least one supported platform
 Release ManagerUpload the release tar file to the Launchpad download area.
 Release ManagerFind all Launchpad bug reports with the status Fix Committed which - have been fixed in this release and mark them Fix Released.
Publish and Announce it
 Website ManagerCopy the tar file and its .asc signature file to the Base - download area of the website.
 Website ManagerUpdate the website subdirectory that holds the release - documentation, and copy in the files from the base/documentation - directory of the tarfile.
 Website ManagerUpdate the webpage for the new release with links to the release - documents and tar file.
 Website ManagerAdd the new release tar file to the website Base download index - page.
 Website ManagerLink to the release webpage from other relevent areas of the - website - update front page and sidebars.
 Website ManagerAdd an entry to the website News page, linking to the new version - webpage.
 Release ManagerAnnounce the release on the tech-talk mailing list.
- - diff --git a/src/Makefile b/src/Makefile index 257099840..81f0dcacd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,80 +1,14 @@ -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - +# Makefile at top of src tree TOP = .. include $(TOP)/configure/CONFIG -DIRS += tools +# Directories to build, any order +DIRS += gdd +DIRS += pcas +DIRS += template -DIRS += tools/test -tools/test_DEPEND_DIRS = tools +# Add any additional dependency rules here: -DIRS += template/base -template/base_DEPEND_DIRS = tools - -DIRS += template/ext -template/ext_DEPEND_DIRS = tools - -# Common - -DIRS += libCom -libCom_DEPEND_DIRS = tools - -DIRS += libCom/RTEMS -libCom/RTEMS_DEPEND_DIRS = libCom - -DIRS += libCom/test -libCom/test_DEPEND_DIRS = libCom/RTEMS - -# Channel Access - -DIRS += ca/client -ca/client_DEPEND_DIRS = libCom - -DIRS += ca/client/tools -ca/client/tools_DEPEND_DIRS = ca/client - -DIRS += ca/legacy/gdd -ca/legacy/gdd_DEPEND_DIRS = ca/client - -DIRS += ca/legacy/pcas -ca/legacy/pcas_DEPEND_DIRS = ca/legacy/gdd - -DIRS += ca/legacy/pcas/ex -# needs ioc for dbStaticHost -ca/legacy/pcas/ex_DEPEND_DIRS = ca/legacy/pcas libCom ioc - -DIRS += ca/client/perl -ca/client/perl_DEPEND_DIRS = ca/client - -# PDB Core - -DIRS += ioc -ioc_DEPEND_DIRS = libCom ca/client - -DIRS += ioc/db/test -ioc/db/test_DEPEND_DIRS = ioc libCom/RTEMS - -DIRS += ioc/dbtemplate/test -ioc/dbtemplate/test_DEPEND_DIRS = ioc - -# PDB Standard Record Definitions - -DIRS += std -std_DEPEND_DIRS = ioc libCom/RTEMS - -DIRS += std/filters/test -std/filters/test_DEPEND_DIRS = std - -DIRS += std/rec/test -std/rec/test_DEPEND_DIRS = std - - -include $(TOP)/configure/RULES_DIRS +pcas_DEPEND_DIRS += gdd +include $(TOP)/configure/RULES_TOP diff --git a/src/ca/client/CASG.cpp b/src/ca/client/CASG.cpp deleted file mode 100644 index b2dbaac4d..000000000 --- a/src/ca/client/CASG.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - */ - -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "syncGroup.h" -#include "oldAccess.h" -#include "cac.h" -#include "sgAutoPtr.h" - -CASG::CASG ( epicsGuard < epicsMutex > & guard, ca_client_context & cacIn ) : - client ( cacIn ), magic ( CASG_MAGIC ) -{ - client.installCASG ( guard, *this ); -} - -CASG::~CASG () -{ -} - -void CASG::destructor ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - - if ( this->verify ( guard ) ) { - this->reset ( cbGuard, guard ); - this->client.uninstallCASG ( guard, *this ); - this->magic = 0; - } - else { - this->printFormated ( "cac: attempt to destroy invalid sync group ignored\n" ); - } - this->~CASG (); -} - -bool CASG::verify ( epicsGuard < epicsMutex > & ) const -{ - return ( this->magic == CASG_MAGIC ); -} - -/* - * CASG::block () - */ -int CASG::block ( - epicsGuard < epicsMutex > * pcbGuard, - epicsGuard < epicsMutex > & guard, - double timeout ) -{ - epicsTime cur_time; - epicsTime beg_time; - double delay; - double remaining; - int status; - - guard.assertIdenticalMutex ( this->client.mutexRef() ); - - // prevent recursion nightmares by disabling blocking - // for IO from within a CA callback. - if ( epicsThreadPrivateGet ( caClientCallbackThreadId ) ) { - return ECA_EVDISALLOW; - } - - if ( timeout < 0.0 ) { - return ECA_TIMEOUT; - } - - cur_time = epicsTime::getCurrent (); - - this->client.flush ( guard ); - - beg_time = cur_time; - delay = 0.0; - - while ( 1 ) { - if ( this->ioPendingList.count() == 0u ) { - status = ECA_NORMAL; - break; - } - - remaining = timeout - delay; - if ( remaining <= CAC_SIGNIFICANT_DELAY ) { - /* - * Make sure that we take care of - * recv backlog at least once - */ - status = ECA_TIMEOUT; - break; - } - - if ( pcbGuard ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - { - epicsGuardRelease < epicsMutex > uncbGuard ( *pcbGuard ); - this->sem.wait ( remaining ); - } - } - else { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->sem.wait ( remaining ); - } - - /* - * force a time update - */ - cur_time = epicsTime::getCurrent (); - - delay = cur_time - beg_time; - } - - return status; -} - -void CASG::reset ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - this->destroyCompletedIO ( cbGuard, guard ); - this->destroyPendingIO ( cbGuard, guard ); -} - -// lock must be applied -void CASG::destroyCompletedIO ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - syncGroupNotify * pNotify; - while ( ( pNotify = this->ioCompletedList.get () ) ) { - pNotify->destroy ( cbGuard, guard ); - } -} - -void CASG::destroyPendingIO ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - while ( syncGroupNotify * pNotify = this->ioPendingList.first () ) { - pNotify->cancel ( cbGuard, guard ); - // cancel must release the guard while - // canceling put callbacks so we - // must double check list membership - if ( pNotify->ioPending ( guard ) ) { - this->ioPendingList.remove ( *pNotify ); - } - else { - this->ioCompletedList.remove ( *pNotify ); - } - pNotify->destroy ( cbGuard, guard ); - } -} - -void CASG::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->client.mutexRef () ); - this->show ( guard, level ); -} - -void CASG::show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - ::printf ( "Sync Group: id=%u, magic=%u, opPend=%u\n", - this->getId (), this->magic, this->ioPendingList.count () ); - if ( level ) { - ::printf ( "\tPending" ); - tsDLIterConst < syncGroupNotify > notifyPending = - this->ioPendingList.firstIter (); - while ( notifyPending.valid () ) { - notifyPending->show ( guard, level - 1u ); - notifyPending++; - } - ::printf ( "\tCompleted" ); - tsDLIterConst < syncGroupNotify > notifyCompleted = - this->ioCompletedList.firstIter (); - while ( notifyCompleted.valid () ) { - notifyCompleted->show ( guard, level - 1u ); - notifyCompleted++; - } - } -} - -bool CASG::ioComplete ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - this->destroyCompletedIO ( cbGuard, guard ); - return this->ioPendingList.count () == 0u; -} - -void CASG::put ( epicsGuard < epicsMutex > & guard, chid pChan, - unsigned type, arrayElementCount count, const void * pValue ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - sgAutoPtr < syncGroupWriteNotify > pNotify ( guard, *this ); - pNotify = syncGroupWriteNotify::factory ( - this->freeListWriteOP, *this, & CASG :: recycleWriteNotifyIO, pChan ); - pNotify->begin ( guard, type, count, pValue ); - pNotify.release (); -} - -void CASG::get ( epicsGuard < epicsMutex > & guard, chid pChan, - unsigned type, arrayElementCount count, void *pValue ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - sgAutoPtr < syncGroupReadNotify > pNotify ( guard, *this ); - pNotify = syncGroupReadNotify::factory ( - this->freeListReadOP, *this, & CASG :: recycleReadNotifyIO, pChan, pValue ); - pNotify->begin ( guard, type, count ); - pNotify.release (); -} - -void CASG::completionNotify ( - epicsGuard < epicsMutex > & guard, syncGroupNotify & notify ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - this->ioPendingList.remove ( notify ); - this->ioCompletedList.add ( notify ); - if ( this->ioPendingList.count () == 0u ) { - this->sem.signal (); - } -} - -void CASG :: recycleReadNotifyIO ( epicsGuard < epicsMutex > & guard, - syncGroupReadNotify & io ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - this->freeListReadOP.release ( & io ); -} - -void CASG :: recycleWriteNotifyIO ( epicsGuard < epicsMutex > & guard, - syncGroupWriteNotify & io ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - this->freeListWriteOP.release ( & io ); -} - -int CASG :: printFormated ( const char *pformat, ... ) -{ - va_list theArgs; - int status; - - va_start ( theArgs, pformat ); - - status = this->client.varArgsPrintFormated ( pformat, theArgs ); - - va_end ( theArgs ); - - return status; -} - -void CASG::exception ( - epicsGuard < epicsMutex > & guard, - int status, const char * pContext, - const char * pFileName, unsigned lineNo ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - if ( status != ECA_CHANDESTROY ) { - this->client.exception ( - guard, status, pContext, pFileName, lineNo ); - } -} - -void CASG::exception ( - epicsGuard < epicsMutex > & guard, - int status, const char * pContext, - const char * pFileName, unsigned lineNo, oldChannelNotify & chan, - unsigned type, arrayElementCount count, unsigned op ) -{ - guard.assertIdenticalMutex ( this->client.mutexRef() ); - if ( status != ECA_CHANDESTROY ) { - this->client.exception ( - guard, status, pContext, pFileName, - lineNo, chan, type, count, op ); - } -} - -void CASG::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} diff --git a/src/ca/client/CAref.html b/src/ca/client/CAref.html deleted file mode 100644 index 3b3d36f58..000000000 --- a/src/ca/client/CAref.html +++ /dev/null @@ -1,4495 +0,0 @@ - - - - - EPICS R3.15 Channel Access Reference Manual - - - - -
- -

EPICS R3.15 Channel Access Reference Manual

-
- Jeffrey O. Hill -
- -

Los Alamos National -Laboratory, SNS Division

-
- Ralph Lange -
- -

Helmholtz-Zentrum -Berlin (BESSY II)

- -

Copyright © 2009 -Helmholtz-Zentrum Berlin für Materialien und Energie GmbH.
-Copyright © 2002 The University of Chicago, as Operator of Argonne National -Laboratory.
-Copyright © 2002 The Regents of the University of California, as Operator of -Los Alamos National Laboratory.
-Copyright © 2002 Berliner Speicherringgesellschaft für Synchrotronstrahlung -GmbH.

- -

EPICS BASE is -distributed subject to a Software License Agreement found -in the file LICENSE that is included with this distribution.

- -

W3C-Amaya Valid HTML 4.01!

- -
- -

Table of Contents

- -

Configuration

- - -

Building an Application

- - -

Command Line Utilities

- - -

Command Line Tools

- - -

Troubleshooting

- - -

Function Call Interface Guidelines

- - -

Functionality Index

- - -

Function Call Interface Index

- - -

Deprecated Function Call Interface Function Index

- - -

Return Codes

-
- -

Configuration

- -

Why Reconfigure Channel Access

- -

Typical reasons to reconfigure EPICS Channel Access:

-
    -
  • Two independent control systems must share a network without fear of - interaction
  • -
  • A test system must not interact with an operational system
  • -
  • Use of address lists instead of broadcasts for name resolution and server - beacons
  • -
  • Control system occupies multiple IP subnets
  • -
  • Nonstandard client disconnect time outs or server beacon intervals
  • -
  • Specify the local time zone
  • -
  • Transport of large arrays
  • -
- -

EPICS Environment Variables

- -

All Channel Access (CA) configuration occurs through EPICS environment -variables. When searching for an EPICS environment variable EPICS first looks -in the environment using the ANSI C getenv() call. If no matching variable -exists then the default specified in the EPICS build system configuration files -is used.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameRangeDefault
EPICS_CA_ADDR_LIST{N.N.N.N N.N.N.N:P ...}<none>
EPICS_CA_AUTO_ADDR_LIST{YES, NO}YES
EPICS_CA_NAME_SERVERS{N.N.N.N N.N.N.N:P ...}<none>
EPICS_CA_CONN_TMOr > 0.1 seconds30.0
EPICS_CA_BEACON_PERIODr > 0.1 seconds15.0
EPICS_CA_REPEATER_PORTi > 50005065
EPICS_CA_SERVER_PORTi > 50005064
EPICS_CA_MAX_ARRAY_BYTESi >= 1638416384
EPICS_CA_AUTO_ARRAY_BYTES{YES, NO}YES
EPICS_CA_MAX_SEARCH_PERIODr > 60 seconds300
EPICS_CA_MCAST_TTLr > 11
EPICS_TS_MIN_WEST-720 < i <720 minutes360
- -

Environment variables are set differently depending on the command line -shell that is in use.

- - - - - - - - - - - - - - - - - - - - - - - - -
C shellsetenv EPICS_CA_ADDR_LIST 1.2.3.4
bashexport EPICS_CA_ADDR_LIST=1.2.3.4
vxWorks shellputenv ( "EPICS_CA_ADDR_LIST=1.2.3.4" )
DOS command lineset EPICS_CA_ADDR_LIST=1.2.3.4
Windows NT / 2000 / XPcontrol panel / system / environment tab
- -

CA and Wide Area Networks

- -

Normally in a local area network (LAN) environment CA discovers the address -of the host for an EPICS process variable by broadcasting frames containing a -list of channel names (CA search messages) and waiting for responses from the -servers that host the channels identified. Likewise CA clients efficiently -discover that CA servers have recently joined the LAN or disconnected from the -LAN by monitoring periodically broadcasted beacons sent out by the servers. -Since hardware broadcasting requires special hardware capabilities, we are -required to provide additional configuration information when EPICS is extended -to operate over a wide area network (WAN).

- -

IP Network Administration Background Information

- -

Channel Access is implemented using Internet protocols (IP). IP addresses -are divided into host and network portions. The boundary between each portion -is determined by the IP netmask. Portions of the IP address corresponding to -zeros in the netmask specify the hosts address within an IP subnet. Portions of -the IP address corresponding to binary ones in the netmask specify the address -of a host's IP subnet. Normally the scope of a broadcasted frame will be -limited to one IP subnet. Addresses with the host address portion set to all -zeros or all ones are special. Modern IP kernel implementations reserve -destination addresses with the host portion set to all ones for the purpose of -addressing broadcasts to a particular subnet. In theory we can issue a -broadcast frame on any broadcast capable LAN within the interconnected Internet -by specifying the proper subnet address combined with a host portion set to all -ones. In practice these "directed broadcasts" are frequently limited by the -default router configuration. The proper directed broadcast address required to -reach a particular host can be obtained by logging into that host and typing -the command required by your local operating environment. Ignore the loop back -interface and use the broadcast address associated with an interface connected -to a path through the network to your client. Typically there will be only one -Ethernet interface.

- - - - - - - - - - - - - - - - -
UNIXifconfig -a
vxWorksifShow
Windowsipconfig
- -

IP ports are positive integers. The IP address, port number, and protocol -type uniquely identify the source and destination of a particular frame -transmitted between computers. Servers are typically addressed by a well known -port number. Clients are assigned a unique ephemeral port number during -initialization. IP ports below 1024 are reserved for servers that provide -standardized facilities such as mail or file transfer. Port number between 1024 -and 5000 are typically reserved for ephemeral port number assignments.

- -

IP port numbers

- -

The two default IP port numbers used by Channel Access may be reconfigured. -This might occur when a site decides to set up two or more completely -independent control systems that will share the same network. For instance, a -site might set up an operational control system and a test control system on -the same network. In this situation it is desirable for the test system and the -operational system to use identical PV names without fear of collision. A site -might also configure the CA port numbers because some other facility is already -using the default port numbers. The default Channel Access port numbers have -been registered with IANA.

- - - - - - - - - - - - - - - - - - - - -
PurposeDefaultEnvironment Variable
CA Server5064EPICS_CA_SERVER_PORT
CA Beacons (sent to CA repeater daemon)5065EPICS_CA_REPEATER_PORT
- -

If a client needs to communicate with two servers that are residing at -different port numbers then an extended syntax may be used with the -EPICS_CA_ADDR_LIST environment variable. See WAN -Environment below.

- -

Firewalls

- -

If you want channel access clients on a machine to be able to see beacons -and replies to broadcast PV search requests, you need to permit inbound UDP -packets with source port EPICS_CA_SERVER_PORT (default is 5064) or destination -port EPICS_CA_REPEATER_PORT (default is 5065). On systems using iptables this -can be accomplished by rules like

-
     -A INPUT -s 192.168.0.0/22 -p udp --sport 5064 -j ACCEPT
-     -A INPUT -s 192.168.0.0/22 -p udp --dport 5065 -j ACCEPT
- -

If you want channel access servers (e.g. "soft IOCs") on a machine to be -able to be seen by clients, you need to permit inbound TCP or UDP packets with -destination port EPICS_CA_SERVER_PORT (default is 5064). On systems using -iptables this can be accomplished by rules like

-
     -A INPUT -s 192.168.0.0/22 -p udp --dport 5064 -j ACCEPT
-     -A INPUT -s 192.168.0.0/22 -p tcp --dport 5064 -j ACCEPT
- -

In all cases the "-s 192.168.0.0/22" specifies the range of addresses from -which you wish to accept packets.

- -

WAN Environment

- -

When the CA client library connects a channel it must first determine the IP -address of the server the channels Process Variable resides on. To accomplish -this the client sends name resolution (search) requests to a list of server -destination addresses. These server destination addresses can be IP unicast -addresses (individual host addresses) or IP broadcast addresses. Each name -resolution (search) request contains a list of Process Variable names.If one of -the servers reachable by this address list knows the IP address of a CA server -that can service one or more of the specified Process Variables, then it sends -back a response containing the server's IP address and port number.

- -

During initialization CA builds the list of server destination addresses -used when sending CA client name resolution (search) requests. This table is -initialized by introspecting the network interfaces attached to the host. For -each interface found that is attached to a broadcast capable IP subnet, the -broadcast address of that subnet is added to the list. For each point to point -interface found, the destination address of that link is added to the list. -This automatic server address list initialization can be disabled if the EPICS -environment variable EPICS_CA_AUTO_ADDR_LIST exists and its value is either -"no" or "NO". The typical default is to enable network interface introspection -driven initialization with EPICS_CA_AUTO_ADDR_LIST set to "YES" or "yes".

- -

Following network interface introspection, any IP addresses specified in the -EPICS environment variable EPICS_CA_ADDR_LIST are added to the list of -destination addresses for CA client name resolution requests. In an EPICS -system crossing multiple subnets the EPICS_CA_ADDR_LIST must be set so that CA -name resolution (search requests) frames pass from CA clients to the targeted -CA servers unless a CA proxy (gateway) is installed. The addresses in -EPICS_CA_ADDR_LIST may be dotted IP addresses or host names if the local OS has -support for host name to IP address translation. When multiple names are added -to EPICS_CA_ADDR_LIST they must be separated by white space. There is no -requirement that the addresses specified in the EPICS_CA_ADDR_LIST be broadcast -addresses, but this will often be the most convenient choice.

- -

For any IP addresses specified in the EPICS environment variable -EPICS_CA_NAME_SERVERS, TCP connections are opened and used for CA client name -resolution requests. (Thus, broadcast addresses are not allowed in -EPICS_CA_NAME_SERVERS.) When used in combination with an empty -EPICS_CA_ADDR_LIST and EPICS_CA_AUTO_ADDR_LIST set to "NO", Channel Access can -be run without using UDP for name resolution. Such an TCP-only mode allows for -Channel Access to work e.g. through SSH tunnels.

- - - - - - - - - - - - - - - - -
C shellsetenv EPICS_CA_ADDR_LIST "1.2.3.255 8.9.10.255"
bashexport EPICS_CA_ADDR_LIST="1.2.3.255 8.9.10.255"
vxWorksputenv ( "EPICS_CA_ADDR_LIST=1.2.3.255 8.9.10.255" )
- -

If a client needs to communicate with two servers that are residing at -different port numbers then an extended syntax may be used with the -EPICS_CA_ADDR_LIST environment variable. Each host name or IP address in the -EPICS_CA_ADDR_LIST may be immediately followed by a colon and an IP port number -without intervening whitespace. Entries that do not specify a port number will -default to EPICS_CA_SERVER_PORT.

- - - - - - - - -
C shellsetenv EPICS_CA_ADDR_LIST "1.2.3.255 8.9.10.255:10000"
- -

Routing Restrictions on vxWorks Systems

- -

Frequently vxWorks systems boot by default with routes limiting access only -to the local subnet. If a EPICS system is operating in a WAN environment it may -be necessary to configure routes into the vxWorks system which enable a vxWorks -based CA server to respond to requests originating outside its subnet. These -routing restrictions can also apply to vxWorks base CA clients communicating -with off subnet servers. An EPICS system manager can implement an rudimentary, -but robust, form of access control for a particular host by not providing -routes in that host that reach outside of a limited set of subnets. See -"routeLib" in the vxWorks reference manual.

- -

Disconnect Time Out Interval

- -

If the CA client library does not see a beacon from a server that it is -connected to for EPICS_CA_CONN_TMO seconds then an state-of-health message is -sent to the server over TCP/IP. If this state-of-health message isn't promptly -replied to then the client library will conclude that channels communicating -with the server are no longer responsive and inform the CA client side -application via function callbacks. The parameter EPICS_CA_CONN_TMO is -specified in floating point seconds. The default is typically 30 seconds. For -efficient operation it is recommended that EPICS_CA_CONN_TMO be set to no less -than twice the value specified for EPICS_CA_BEACON_PERIOD.

- -

Prior to EPICS R3.14.5 an unresponsive server implied an immediate TCP -circuit disconnect, immediate resumption of UDP based search requests, and -immediate attempts to reconnect. There was concern about excessive levels of -additional activity when servers are operated close to the edge of resource -limitations. Therefore with version R3.14.5 and greater the CA client library -continues to inform client side applications when channels are unresponsive, -but does not immediately disconnect the TCP circuit. Instead the CA client -library postpones circuit shutdown until receiving indication of circuit -disconnect from the IP kernel. This can occur either because a server is -restarted or because the IP kernel's internal TCP circuit inactivity keep alive -timer has expired after a typically long duration (as is appropriate for IP -based systems that need to avoid thrashing during periods of excessive load). -The net result is less search and TCP circuit setup and shutdown activity -during periods of excessive load.

- -

Dynamic Changes in the CA Client Library Search -Interval

- -

The CA client library will continuously attempt to connect any CA channels -that an application has created until it is successful. The library -periodically queries the server destination address list described above with -name resolution requests for any unresolved channels. Since this address list -frequently contains broadcast addresses, and because nonexistent process -variable names are frequently configured, or servers may be temporarily -unavailable, then it is necessary for the CA client library internals to -carefully schedule these requests in time to avoid introducing excessive load -on the network and the servers.

- -

When the CA client library has many channels to connect, and most of its -name resolution requests are responded to, then it sends name resolution -requests at an interval that is twice the estimated round trip interval for the -set of servers responding, or at the minimum delay quantum for the operating -system - whichever is greater. The number of UDP frames per interval is also -dynamically adjusted based on the past success rates.

- -

If a name resolution request is not responded to, then the client library -doubles the delay between name resolution attempts and reduces the number of -requests per interval. The maximum delay between attempts is limited by -EPICS_CA_MAX_SEARCH_PERIOD (see Configuring the Maximum -Search Period). Note however that prior to R3.14.7, if the client library -did not receive any responses over a long interval it stopped sending name -resolution attempts altogether until a beacon anomaly was detected (see -below).

- -

The CA client library continually estimates the beacon period of all server -beacons received. If a particular server's beacon period becomes significantly -shorter or longer then the client is said to detect a beacon anomaly. The -library boosts the search interval for unresolved channels when a beacon -anomaly is seen or when any successful search response is received, -but with a longer initial interval between requests than is used when the -application creates a channel. Creation of a new channel does not -(starting with EPICS R3.14.7) change the interval used when searching for -preexisting unresolved channels. The program "casw" prints a message on -standard out for each CA client beacon anomaly detect event.

- -

See also When a Client Does not See the Server's -Beacon.

- -

Configuring the Maximum Search -Period

- -

The rate at which name resolution (search) requests are sent exponentially -backs off to a plateau rate. The value of this plateau has an impact on network -traffic because it determines the rate that clients search for channel names -that are miss-spelled or otherwise don't exist in a server. Furthermore, for -clients that are unable to see the beacon from a new server, the plateau rate -may also determine the maximum interval that the client will wait until -discovering a new server.

- -

Starting with EPICS R3.14.7 this maximum search rate interval plateau in -seconds is determined by the EPICS_CA_MAX_SEARCH_PERIOD environment -variable.

- -

See also When a Client Does not See the Server's -Beacon.

- -

The CA Repeater

- -

When several client processes run on the same host it is not possible for -all of them to directly receive a copy of the server beacon messages when the -beacon messages are sent to unicast addresses, or when legacy IP kernels are -still in use. To avoid confusion over these restrictions a special UDP server, -the CA Repeater, is automatically spawned by the CA client library when it is -not found to be running. This program listens for server beacons sent to the -UDP port specified in the EPICS_CA_REPEATER_PORT parameter and fans any beacons -received out to any CA client program running on the same host that have -registered themselves with the CA Repeater. If the CA Repeater is not already -running on a workstation, then the "caRepeater" program must be in your path -before using the CA client library for the first time.

- -

If a host based IOC is run on the same workstation with standalone CA client -processes, then it is probably best to start the caRepeater process when the -workstation is booted. Otherwise it is possible for the standalone CA client -processes to become dependent on a CA repeater started within the confines of -the host based IOC. As long as the host based IOC continues to run there is -nothing wrong with this situation, but problems could arise if this host based -IOC process exits before the standalone client processes which are relying on -its CA repeater for services exit.

- -

Since the repeater is intended to be shared by multiple clients then it -could be argued that it makes less sense to set up a CA repeater that listens -for beacons on only a subset of available network interfaces. In the worst case -situation the client library might see beacon anomalies from servers that it is -not interested in. Modifications to the CA repeater forcing it to listen only -on a subset of network interfaces might be considered for a future release if -there appear to be situations that require it.

- -

Configuring the Time Zone

- -

Note: Starting with EPICS R3.14 all of the libraries in the EPICS base -distribution rely on facilities built into the operating system to determine -the correct time zone. Nevertheless, several programs commonly used with EPICS -still use the original "tssubr" library and therefore they still rely on proper -configuration of EPICS_TS_MIN_WEST.

- -

While the CA client library does not translate between the local time and -the time zone independent internal storage of EPICS time stamps, many EPICS -client side applications call core EPICS libraries which provide these -services. To set the correct time zone users must compute the number of -positive minutes west of GMT (maximum 720 inclusive) or the negative number of -minutes east of GMT (minimum -720 inclusive). This integer value is then placed -in the variable EPICS_TS_MIN_WEST.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Time ZoneEPICS_TS_MIN_WEST
USA Eastern300
USA Central360
USA Mountain420
USA Pacific480
Alaska540
Hawaii600
Japan-540
China-420
Germany-120
United Kingdom0
- -

Configuring the Maximum Array Size

- -

From version R3.16.1, the default setting of EPICS_CA_AUTO_ARRAY_BYTES=YES -will cause the software to ignore EPICS_CA_MAX_ARRAY_BYTES and attempt to -allocate network buffer space as needed by the particular client connection -using malloc. Setting EPICS_CA_AUTO_ARRAY_BYTES=NO will configure the software -to respect the EPICS_CA_MAX_ARRAY_BYTES setting as described below instead.

- -

Starting with version R3.14 the environment variable -EPICS_CA_MAX_ARRAY_BYTES determines the size of the largest array that may pass -through CA. Prior to this version only arrays smaller than 16k bytes could be -transfered. The CA libraries maintains a free list of 16384 byte network -buffers that are used for ordinary communication. If EPICS_CA_MAX_ARRAY_BYTES -is larger than 16384 then a second free list of larger data buffers is -established and used only after a client send its first large array request.

- -

The CA client library uses EPICS_CA_MAX_ARRAY_BYTES to determines the -maximum array that it will send or receive. Likewise, the CA server uses -EPICS_CA_MAX_ARRAY_BYTES to determine the maximum array that it may send or -receive. The client does not influence the server's message size quotas and -visa versa. In fact the value of EPICS_CA_MAX_ARRAY_BYTES need not be the same -in the client and the server. If the server receives a request which is too -large to read or respond to in entirety then it sends an exception message to -the client. Likewise, if the CA client library receives a request to send an -array larger than EPICS_CA_MAX_ARRAY_BYTES it will return ECA_TOLARGE.

- -

A common mistake is to correctly calculate the maximum datum size in bytes -by multiplying the number of elements by the size of a single element, but -neglect to add additional bytes for the compound data types (for example -DBR_GR_DOUBLE) commonly used by the more sophisticated client side -applications.

- -

Configuring a CA Server

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameRangeDefault
EPICS_CAS_SERVER_PORTi > 5000EPICS_CA_SERVER_PORT
EPICS_CAS_AUTO_BEACON_ADDR_LIST{YES, NO}EPICS_CA_AUTO_ADDR_LIST
EPICS_CAS_BEACON_ADDR_LIST{N.N.N.N N.N.N.N:P ...}EPICS_CA_ADDR_LIST1
EPICS_CAS_BEACON_PERIODr > 0.1 secondsEPICS_CA_BEACON_PERIOD
EPICS_CAS_BEACON_PORTi > 5000EPICS_CA_REPEATER_PORT
EPICS_CAS_INTF_ADDR_LIST{N.N.N.N N.N.N.N:P ...}<none>
EPICS_CAS_IGNORE_ADDR_LIST{N.N.N.N N.N.N.N:P ...}<none>
- -

Server Port

- -

The server configures its port number from the EPICS_CAS_SERVER_PORT -environment variable if it is specified. Otherwise the EPICS_CA_SERVER_PORT -environment variable determines the server's port number. Two servers can share -the same UDP port number on the same machine, but there are restrictions - see -a discussion of unicast addresses and two servers sharing -the same UDP port on the same host.

- -

Server Beacons

- -

The EPICS_CAS_BEACON_PERIOD parameter determines the server's beacon period -and is specified in floating point seconds. The default is typically 15 -seconds. See also EPICS_CA_CONN_TMO and -Dynamic Changes in the CA Client Library Search -Interval.

- -

CA servers build a list of addresses to send beacons to during -initialization. If EPICS_CAS_AUTO_BEACON_ADDR_LIST has the value "YES" -(the default) this list will be automatically populated with the broadcast -addresses of all network interfaces. However, if the user also -defines EPICS_CAS_INTF_ADDR_LIST then beacon address list automatic -configuration is constrained to the network interfaces specified therein, and -therefore only the broadcast addresses of the specified LAN interfaces, will be -automatically configured.

- -

If EPICS_CAS_BEACON_ADDR_LIST is defined then its contents will be used to -augment any automatic configuration of the beacon address list. Individual -entries in EPICS_CAS_BEACON_ADDR_LIST may override the destination port number -if ":nnn" follows the host name or IP address there.

- -

The EPICS_CAS_BEACON_PORT parameter specifies the destination port for -server beacons. The only exception to this occurs when ports are specified in -EPICS_CAS_BEACON_ADDR_LIST or possibly in EPICS_CA_ADDR_LIST. If -EPICS_CAS_BEACON_PORT is not specified then beacons are sent to the port -specified in EPICS_CA_REPEATER_PORT.

- -

Binding a Server to a Limited Set of Network Interfaces

- -

The parameter EPICS_CAS_INTF_ADDR_LIST allows a ca server to bind itself to, -and therefore accept messages received by, a limited set of the local host's -network interfaces (each specified by its IP address). On UNIX systems type -"netstat -ie" (type "ipconfig" on windows) to see a list of the local host's -network interfaces. By default, -the CA server is accessible from all network interfaces configured into its -host.

- -

Until R3.15.4 the CA server employed by iocCore did not -implement the EPICS_CAS_INTF_ADDR_LIST feature.

- -

Prior to R3.15.4 CA servers would build the beacon address list -using EPICS_CA_ADDR_LIST if EPICS_CAS_BEACON_ADDR_LIST was no set.

- -

Ignoring Process Variable Name Resolution Requests From Certain Hosts

- -

Name resolution requests originating from any of the IP addresses specified -in the EPICS_CAS_IGNORE_ADDR_LIST parameter are not replied to.In R3.14 and -previous releases the CA server employed by iocCore does not implement this -feature.

- -

Client Configuration that also Applies to Servers

- -

See also Configuring the Maximum Array Size.

- -

See also Routing Restrictions on vxWorks Systems.

-
- -

Building an Application

- -

Required Header (.h) Files

- -

An application that uses the CA client library functions described in this -document will need to include the cadef.h header files as follows.

- -

#include "cadef.h"

- -

This header file is located at "<EPICS base>/include/". It includes -many other header files (operating system specific and otherwise), and -therefore the application must also specify "<EPICS -base>/include/os/<arch>" in its header file search path.

- -

Required Libraries

- -

An application that uses the Channel Access Client Library functions -described in this document will need to link with the EPICS CA Client Library -and also the EPICS Common Library. The EPICS CA Client Library calls the EPICS -Common Library. The following table shows the names of these libraries on UNIX -and Windows systems.

- - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
UNIX ObjectUNIX ShareableWindows ObjectWindows Shareable
EPICS CA Client Librarylibca.alibca.soca.libca.dll
-
- EPICS Common Library
-
libCom.alibCom.soCom.libCom.dll
- -

- -

The above libraries are located in "<EPICS -base>/lib/<architecture>".

- -

Compiler and System Specific Build -Options

- -

If you do not use the EPICS build environment (layered make files) then it -may be helpful to run one of the EPICS make files and watch the compile/link -lines. This may be the simplest way to capture the latest system and compiler -specific options required by your build environment. Some snapshots of typical -build lines are shown below, but this information may be out of date.

- -

Typical Linux Build Options

- -

gcc -D_GNU_SOURCE -DOSITHREAD_USE_DEFAULT_STACK -D_X86_ -DUNIX -Dlinux --O3 -g -Wall -I. -I.. -I../../../../include/compiler/gcc --I../../../../include/os/Linux -I../../../../include -c ../acctst.c

- -

g++ -o acctst -L/home/user/epics/base-3.15/lib/linux-x86 --Wl,-rpath,/home/user/epics/base-3.15/lib/linux-x86 -acctstMain.o acctst.o -lca -lCom

- -

Typical Solaris Build Options

- -

/opt/SUNWspro/bin/cc -c -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE=500 --DOSITHREAD_USE_DEFAULT_STACK -DUNIX -DSOLARIS=9 -mt -D__EXTENSIONS__ -Xc -v --xO4 -I. -I.. -I../../../../include/compiler/solStudio --I../../../../include/os/solaris -I../../../../include ../acctst.c

- -

/opt/SUNWspro/bin/CC -o acctst --L/home/user/epics/base-3.15/lib/solaris-sparc/ -mt -z ignore -z combreloc --z lazyload -R/home/user/epics/base-3.15/lib/solaris-sparc acctstMain.o -acctst.o -lca -lCom

- -

Typical Windows Build Options

- -

cl -c /nologo /D__STDC__=0 /Ox /GL /W3 /w44355 /MD -I. -I.. --I..\\..\\..\\..\\include\\compiler\\msvc -I..\\..\\..\\..\\include\\os\\WIN32 --I..\\..\\..\\..\\include ..\\acctst.c

- -

link -nologo /LTCG /incremental:no /opt:ref /release /version:3.15 --out:acctst.exe acctstMain.obj acctst.obj -d:/user/epics/base-3.15/lib/win32-x86/ca.lib -d:/user/epics/base-3.15/lib/win32-x86/Com.lib

- -

Typical vxWorks Build Options

- -

/usr/local/vxWorks-6.9/gnu/4.3.3-vxworks-6.9/x86-linux2/bin/ccppc --DCPU=PPC32 -DvxWorks=vxWorks -O2 -Wall -mstrict-align -mlongcall -fno-builtin --include /usr/local/vxWorks-6.9/vxworks-6.9/target/h/vxWorks.h --I. -I../O.Common -I.. -I../../../../include/compiler/gcc --I../../../../include/os/vxWorks -I../../../../include --I/usr/local/vxWorks-6.9/vxworks-6.9/target/h --I/usr/local/vxWorks-6.9/vxworks-6.9/target/h/wrn/coreip --c ../acctst.c

- -

Other Systems and Compilers

- -

Contributions gratefully accepted.

-
- -

Command Line Utilities

- -

acctst

-
acctst <PV name> [progress logging level] [channel duplication count] 
-                 [test repetition count] [enable preemptive callback]
- -

Description

- -

Channel Access Client Library regression test.

- -

The PV used with the test must be native type DBR_DOUBLE or DBR_FLOAT, and -modified only by acctst while the test is running. Therefore, periodically -scanned hardware attached analog input records do not work well. Test failure -is indicated if the program stops prior to printing "test complete". If -unspecified the progress logging level is zero, and no messages are printed -while the test is progressing. If unspecified, the channel duplication count is -20000. If unspecified, the test repetition count is once only. If unspecified, -preemptive callback is disabled.

- -

catime

-
catime <PV name> [channel count] [append number to pv name if true]
- -

Description

- -

Channel Access Client Library performance test.

- -

If unspecified, the channel count is 10000. If the "append number to pv name -if true" argument is specified and it is greater than zero then the channel -names in the test are numbered as follows.

- -

<PV name>000000, <PV name>000001, ... <PV name>nnnnnn

- -

casw

-
casw [-i <interest level>]
- -

Description

- -

CA server "beacon anomaly" logging.

- -

CA server beacon anomalies occur when a new server joins the network, a -server is rebooted, network connectivity to a server is reestablished, or if a -server's CPU exits a CPU load saturated state.

- -

CA clients with unresolved channels reset their search request scheduling -timers whenever they see a beacon anomaly.

- -

This program can be used to detect situations where there are too many -beacon anomalies. IP routing configuration problems may result in false beacon -anomalies that might cause CA clients to use unnecessary additional network -bandwidth and server CPU load when searching for unresolved channels.

- -

If there are no new CA servers appearing on the network, and network -connectivity remains constant, then casw should print no messages at all. At -higher interest levels the program prints a message for every beacon that is -received, and anomalous entries are flagged with a star.

- -

caEventRate

-
caEventRate <PV name> [subscription count]
- -

Description

- -

Connect to the specified PV, subscribe for monitor updates the specified -number of times (default once), and periodically log the current sampled event -rate, average event rate, and the standard deviation of the event rate in Hertz -to standard out.

- -

ca_test

-
ca_test <PV name> [value to be written]
- -

Description

- -

If a value is specified it is written to the PV. Next, the current value of -the PV is converted to each of the many external data type that can be -specified at the CA client library interface, and each of these is formated and -then output to the console.

-
- -

Command Line Tools

- -

caget

-
caget [options] <PV name> ...
- -

Description

- -

Get and print value for PV(s).

- -

The values for one or multiple PVs are read and printed to stdout. The -DBR_... format in which the data is read, the output format, and a number of -details of how integer and float values are represented can be controlled using -command line options.

- -

When getting multiple PVs, their order on the command line is retained in -the output.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionDescription
-hPrint usage information
CA options:
-w <sec>Wait time, specifies longer CA timeout, default is 1.0 second
-cAsynchronous get (use ca_get_callback instead of ca_get)
-p <prio>CA priority (0-99, default 0=lowest)
Format and data type options:
Default output format is "name value"
-tTerse mode - print only value, without name
-aWide mode "name timestamp value stat sevr" (read PVs as - DBR_TIME_xxx)
-d <type>Request specific dbr type; use string (DBR_ prefix may be omitted)
- or number of one of the following types:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DBR_STRING0DBR_STS_FLOAT9DBR_TIME_LONG19DBR_CTRL_SHORT29
DBR_INT1DBR_STS_ENUM10DBR_TIME_DOUBLE20DBR_CTRL_INT29
DBR_SHORT1DBR_STS_CHAR11DBR_GR_STRING21DBR_CTRL_FLOAT30
DBR_FLOAT2DBR_STS_LONG12DBR_GR_SHORT22DBR_CTRL_ENUM31
DBR_ENUM3DBR_STS_DOUBLE13DBR_GR_INT22DBR_CTRL_CHAR32
DBR_CHAR4DBR_TIME_STRING14DBR_GR_FLOAT23DBR_CTRL_LONG33
DBR_LONG5DBR_TIME_INT15DBR_GR_ENUM24DBR_CTRL_DOUBLE34
DBR_DOUBLE6DBR_TIME_SHORT15DBR_GR_CHAR25DBR_STSACK_STRING37
DBR_STS_STRING7DBR_TIME_FLOAT16DBR_GR_LONG26DBR_CLASS_NAME38
DBR_STS_SHORT8DBR_TIME_ENUM17DBR_GR_DOUBLE27
DBR_STS_INT8DBR_TIME_CHAR18DBR_CTRL_STRING28
-
Enum format:
-nPrint DBF_ENUM value as number (default is enum string)
Arrays:
Value format: Print number of requested values, then list of - values
Default:Print all values
-# <count>Print first <count> elements of an array
-SPrint array of char as a string (long string)
Floating point type format:
Default:Use %g format
-e <nr>Use %e format, with a precision of <nr> digits
-f <nr>Use %f format, with a precision of <nr> digits
-g <nr>Use %g format, with a precision of <nr> digits
-sGet value as string (honors server-side precision)
-lxRound to long integer and print as hex number
-loRound to long integer and print as octal number
-lbRound to long integer and print as binary number
Integer number format:
Default:Print as decimal number
-0xPrint as hex number
-0oPrint as octal number
-0bPrint as binary number
Alternate output field separator:
-F <ofs>Use <ofs> as an alternate output field separator
- -

camonitor

-
camonitor [options] <PV name> ...
- -

Description

- -

Subscribe to and print value updates for PV(s).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionDescription
-hPrint usage information
CA options:
-w <sec>Wait time, specifies longer CA timeout, default is 1.0 second
-m <msk>Specify CA event mask to use. <msk> is any combination of
- 'v' (value), 'a' (alarm), 'l' (log/archive), 'p' (property).
- Default event mask is 'va'
-p <prio>CA priority (0-99, default 0=lowest)
Timestamps:
Default:Print absolute timestamps (as reported by CA server)
-t <key>Specify timestamp source(s) and type, with <key> containing
- 's' = CA server (remote) timestamps
- 'c' = CA client (local) timestamps (shown in '()'s)
- 'n' = no timestamps
- 'r' = relative timestamps (time elapsed since start of program)
- 'i' = incremental timestamps (time elapsed since last update)
- 'I' = incremental timestamps (time since last update, by channel)
- 'r', 'i' or 'I' require 's' or 'c' to select the time source
Enum Format:
-nPrint DBF_ENUM values as number (default is enum string)
Arrays:
Array values: Print number of elements, then list of values
Default:Default: Request and print all elements (dynamic arrays supported)
-# <num>Request and print up to <num> elements
-SPrint array of char as a string (long string)
Floating point format:
Default:Use %g format
-e <num>Use %e format, with a precision of <num> digits
-f <num>Use %f format, with a precision of <num> digits
-g <num>Use %g format, with a precision of <num> digits
-sGet value as string (honors server-side precision)
-lxRound to long integer and print as hex number
-loRound to long integer and print as octal number
-lbRound to long integer and print as binary number
Integer number format:
Default:Print as decimal number
-0xPrint as hex number
-0oPrint as octal number
-0bPrint as binary number
- -

caput

-
caput [options] <PV name> <value> ...
-caput -a [options] <PV name> <no of elements> <value> ...
- -

Description

- -

Put value to a PV.

- -

The specified value is written to the PV (as a string). The PV's value is -read before and after the write operation and printed as "Old" and "New" values -on stdout.

- -

There are two variants to the arguments for this command. For the scalar -variant without the -a flag, all the value arguments provided after -the PV name are concatenated with a single space character between them, and the -resulting string (up to 40 characters long unless the -S flag is -given) is written to the specified PV.

- -

The array variant with the -a flag writes an array of string -values to the specified PV. The numeric argument giving the number of array -elements is actually ignored, the array length to be written is actually -controlled by the number of values provided on the command line.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionDescription
-hPrint usage information
CA options:
-w <sec>Wait time, specifies longer CA timeout, default is 1.0 second
-cAsynchronous put (use ca_put_callback and wait for completion)
-p <prio>CA priority (0-99, default 0=lowest)
Format options:
-tTerse mode - print only successfully written value, without name
-lLong mode "name timestamp value stat sevr" (read PVs as DBR_TIME_xxx)
Enum Format:
Default:Auto - try value as ENUM string, then as index number
-nForce interpretation of values as numbers
-sForce interpretation of values as strings
Arrays:
Default:Put scalar
Value format: all value arguments concatenated with spaces
-SPut string as an array of chars (long string)
-aPut array
Value format: number of values, then list of values
- -

cainfo

-
cainfo [options] <PV name> ...
- -

Description

- -

Get and print channel and connection information for PV(s).

- -

All available Channel Access related information about PV(s) is printed to -stdout.

- -

The -s option allows to specify an interest level for calling Channel -Access' internal report function ca_client_status(), that prints lots of -internal informations on stdout, including environment settings, used CA ports -etc.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionDescription
-hPrint usage information
CA options:
-w <sec>Wait time, specifies longer CA timeout, default is 1.0 second
-s <level>Call ca_client_status with the specified interest level
-p <prio>CA priority (0-99, default 0=lowest)
- -

excas

- -

excas [options]

- -

This is an example CA server that is sometimes used for testing purposes. An -example server can be created with the makeBaseApp Perl script, as described in -the application Developer's Guide.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionDescription
-d <uuuu>set level uuuu for debug messages, where uuuu is an positive integer - number
-p <aaaa>prefix all of the PV names below with aaaa changing, for example, the - name of "bill" to "xyz:bill"
-t <n.n>set execution time where n.n is a positive real number
-c <uuuu>set the numbered alias count
-s <nnn>the default, nnn is one, enables periodic scanning of the PV - replacing the PV with its value added with a small random change, when - nnn is zero it turns off this type of periodic scanning
-ss <nnn>the default, nnn is one, enables synchronous scanning, and if nnn is - zero it turns on asynchronous scanning
-ad <n.n>set the delay before asynchronous operations complete (defaults to - 0.1 seconds)
-an <nnn>set the maximum number of simultaneous asynchronous operations - (defaults to 1000)
- -

The example server has a compile time fixed set of example variables.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Process Variable NameNumber of ElementsIO TypeData TypeHigh LimitLow LimitScan Period
jane1Synchronousfloat point, 64 bits10.00.00.1 Seconds, random noise changes
fred1Synchronousfloat point, 64 bits10.0-10.02.0 Seconds, random noise changes
janet1Asynchronousfloat point, 64 bits10.00.00.1 Seconds, random noise changes
freddy1Asynchronousfloat point, 64 bits10.0-10.02.0 Seconds, random noise changes
alan100Synchronousfloat point, 64 bits10.0-10.02.0 Seconds, random noise changes
albert1000Synchronousfloat point, 64 bits10.0-10.020.0 Seconds, random noise changes
boot1Synchronousenumerated, 16 bits10.0-10.0changed only by client
booty1Asynchronousenumerated, 16 bits10.0-10.01.0 Seconds, random noise changes
bill1Synchronousfloat point, 64 bits10.0-10.0changed only by client
billy1Asynchronousfloat point, 64 bits10.0-10.0changed only by client
bloaty100000Synchronousfloat point, 64 bits10.0-10.0changed only by client
- -

Bugs

- -

Not all of the options listed above have been tested recently.

-
- -

Troubleshooting

- -

When Clients Do Not Connect to Their Server

- -

Client and Server Broadcast Addresses Don't -Match

- -

Verify that the broadcast addresses are identical on the server's host and -on the client's host. This can be checked on UNIX with "netstat -i" or -"ifconfig -a"; on vxWorks with ifShow; and on windows with ipconfig. It is -normal for the broadcast addresses to not be identical if the client and server -are not directly attached to the same IP subnet, and in this situation the -EPICS_CA_ADDR_LIST must be set. Otherwise, if the client and server are -intended to be on the same IP subnet, then the problem may be that the IP -netmask is incorrectly set in the network interface configuration. On most -operating systems, when the host's IP address is configured, the host's IP -subnet mask is also configured.

- -

Client Isn't Configured to Use the Server's Port

- -

Verify that the client and server are using the same UDP port. Check the -server's port by running "netstat -a | grep nnn" where nnn is the port number -configured in the client. If you do not set EPICS_CA_SERVER_PORT or -EPICS_CAS_SERVER_PORT then the default port will be 5064.

- -

Unicast Addresses in the EPICS_CA_ADDR_LIST Does not -Reliably Contact Servers Sharing the Same UDP Port on the Same Host

- -

Two servers can run on the same host with the same server port number, but -there are restrictions. If the host has a modern IP kernel it is possible to -have two or more servers share the same UDP port. It is not possible for these -servers to run on the same host using the same TCP port. If the CA server -library detects that a server is attempting to start on the same port as an -existing CA server then both servers will use the same UDP port, and the 2nd -server will be allocated an ephemeral TCP port. Clients can be configured to -use the same port number for both servers. They will locate the 2nd server via -the shared UDP port, and transparently connect to the 2nd server's ephemeral -TCP port. Be aware however that If there are two server's running on the same -host sharing the same UDP port then they will both receive UDP search requests -sent as broadcasts, but unfortunately (due to a weakness of most IP kernel -implementations) only one of the servers will typically receive UDP search -requests sent to unicast addresses (i.e. a single specific host's ip -address).

- -

Client Does not See Server's Beacons

- -

Two conclusions deserve special emphasis. First, if a client does not -see the server's beacons, then it will use additional network and server -resources sending periodic state-of-health messages. Second, if a -client does not see a newly introduced server's beacon, then it will take up to -EPICS_CA_MAX_SEARCH_PERIOD to find that newly introduced server. Also, -starting with EPICS R3.14.7 the client library does not suspend -searching for a channel after 100 unsuccessful attempts until a beacon anomaly -is seen. Therefore, if the client library is from before version R3.14.7 of -EPICS and it timed out attempting to find a server whose beacon can't be seen -by the client library then the client application might need to be restarted in -order to connect to this new beacon-out-of-range server. The typical situation -where a client would not see the server's beacon might be when the client isn't -on the same IP subnet as the server, and the client's EPICS_CA_ADDR_LIST was -modified to include a destination address for the server, but the server's -beacon address list was not modified so that its beacons are received by the -client.

- -

A Server's IP Address Was Changed

- -

When communication over a virtual circuit times out, then each channel -attached to the circuit enters a disconnected state and the disconnect callback -handler specified for the channel is called. However, the circuit is not -disconnected until TCP/IP's internal, typically long duration, keep alive timer -expires. The disconnected channels remain attached to the beleaguered circuit -and no attempt is made to search for, or to reestablish, a new circuit. If, at -some time in the future, the circuit becomes responsive again, then the -attached channels enter a connected state again and reconnect callback -handlers are called. Any monitor subscriptions that received an update message -while the channel was disconnected are also refreshed. If at any time the -library receives an indication from the operating system that a beleaguered -circuit has shutdown or was disconnected then the library will immediately -reattempt to find servers for each channel and connect circuits to them.

- -

A well known negative side effect of the above behavior is that CA clients -will wait the full (typically long) duration of TCP/IP's internal keep alive -timer prior to reconnecting under the following scenario (all of the following -occur):

-
    -
  • An server's (IOC's) operating system crashes (or is abruptly turned off) - or a vxWorks system is stopped by any means
  • -
  • This operating system does not immediately reboot using the same IP - address
  • -
  • A duplicate of the server (IOC) is started appearing at a different IP - address
  • -
- -

It is unlikely that any rational organization will advocate the above -scenario in a production system. Nevertheless, there are opportunities -for users to become confused during control system development, but it -is felt that the robustness improvements justify isolated confusion during the -system integration and checkout activities where the above scenarios are most -likely to occur.

- -

Contrast the above behavior with the CA client library behavior of releases -prior to R3.14.5 where the beleaguered circuit was immediately closed when -communication over it timed out. Any attached channels were immediately -searched for, and after successful search responses arrived then attempts were -made to build a new circuit. This behavior could result in undesirable resource -consumption resulting from periodic circuit setup and teardown overhead -(thrashing) during periods of CPU / network / IP kernel buffer congestion.

- -

Put Requests Just Prior to Process -Termination Appear to be Ignored

- -

Short lived CA client applications that issue a CA put request and then -immediately exit the process (return from main or call -exit) may find that there request isn't executed. To guarantee -that the request is sent call ca_flush_io() followed by -ca_context_destroy() prior to terminating the process.

- -

ENOBUFS Messages

- -

Many Berkley UNIX derived Internet Protocol (IP) kernels use a memory -management scheme with a fixed sized low level memory allocation quantum called -an "mbuf". Messages about "ENOBUFS" are an indication that your IP kernel is -running low on mbuf buffers. An IP kernel mbuf starvation situation may lead to -temporary IP communications stalls or reduced throughput. This issue has to -date been primarily associated with vxWorks systems where mbuf starvation on -earlier vxWorks versions is rumored to lead to permanent IP communications -stalls which are resolved only by a system reboot. IP kernels that use mbufs -frequently allow the initial and maximum number of mbufs to be configured. -Consult your OS's documentation for configuration procedures which vary between -OS and even between different versions of the same OS.

- -

Contributing Circumstances

-
    -
  • The total number of connected clients is high. Each active socket - requires dedicated mbufs for protocol control blocks, and for any data that - might be pending in the operating system for transmission to Channel Access - or to the network at a given instant. If you increase the vxWorks limit on - the maximum number of file descriptors then it may also be necessary to - increase the size of the mbuf pool.
  • -
-
    -
  • The server has multiple connections where the server's sustained event - (monitor subscription update) production rate is higher than the client's - or the network's sustained event consumption rate. This ties up a per - socket quota of mbufs for data that are pending transmission to the client - via the network. In particular, if there are multiple clients that - subscribe for monitor events but do not call ca_pend_event() - or ca_poll() - to process their CA input queue, then a significant mbuf consuming backlog - can occur in the server.
  • -
-
    -
  • The server does not get a chance to run (because some other higher - priority thread is running) and the CA clients are sending a high volume of - data over TCP or UDP. This ties up a quota of mbufs for each socket in the - server that isn't being reduced by the server's socket read system - calls.
  • -
-
    -
  • The server has multiple stale connections. Stale connections occur when a - client is abruptly turned off or disconnected from the network, and an - internal "keepalive" timer has not yet expired for the virtual circuit in - the operating system, and therefore mbufs may be dedicated to unused - virtual circuits. This situation is made worse if there are active monitor - subscriptions associated with stale connections which will rapidly increase - the number of dedicated mbufs to the quota available for each circuit.
  • -
  • When sites switch to the vxWorks 5.4 IP kernel they frequently run into - network pool exhaustion problems. This may be because the original vxWorks - IP kernel expanded the network pool as needed at runtime while the new - kernel's pool is statically configured at compile time, and does - not expand as needed at runtime. Also, at certain sites problems - related to vxWorks network driver pool exhaustion have also been reported - (this can also result in ENOBUF diagnostic messages).
  • -
- -

Related Diagnostics

-
    -
  • The EPICS command "casr [interest level]" displays information about the - CA server and how many clients are connected.
  • -
  • The vxWorks command "inetstatShow" indicates how many bytes are pending - in mbufs and indirectly (based on the number of circuits listed) how many - mbuf based protocol control blocks have been consumed. The vxWorks commands - (availability depending on vxWorks version) mbufShow, netStackSysPoolShow, - and netStackDataPoolShow indicate how much space remains in the network - stack pool.
  • -
  • The RTEMS command "netstat [interest level]" displays network information - including mbuf consumption statistics.
  • -
- -

Server Subscription Update Queuing

- -

If the subscription update producer in the server produces subscription -updates faster than the subscription update consumer in the client consumes -them, then events have to be discarded if the buffering in the server -isn't allowed to grow to an infinite size. This is a law of nature – -based on queuing theory of course.

- -

What is done depends on the version of the CA server. All server versions -place quotas on the maximum number of subscription updates allowed on the -subscription update queue at any given time. If this limit is reached, an -intervening update is discarded in favor of a more recent update. Depending on -the version of the server, rapidly updating subscriptions are or are not -allowed to cannibalize the quotas of slow updating subscriptions in limited -ways. Nevertheless, there is always room on the queue for at least one update -for each subscription. This guarantees that the most recent update is always -sent.

- -

Adding further complication, the CA client library also implements a -primitive type of flow control. If the client library sees that it is reading a -large number of messages one after another w/o intervening delay it knows that -it is not consuming events as fast as they are produced. In that situation it -sends a message telling the server to temporarily stop sending subscription -update messages. When the client catches up it sends another message asking the -server to resume with subscription updates. This prevents slow clients from -getting time warped, but also guarantees that intervening events are discarded -until the slow client catches up.

- -

There is currently no message on the IOC's console when a particular client -is slow on the uptake. A message of this type used to exist many years ago, but -it was a source of confusion (and what we will call message noise) so it was -removed.

- -

There is unfortunately no field in the protocol allowing the server to -indicate that an intervening subscription update was discarded. We should -probably add that capability in a future version. Such a feature would, for -example, be beneficial when tuning an archiver installation.

-
- -

Function Call Interface General Guidelines

- -

Flushing and Blocking

- -

Significant performance gains can be realized when the CA client library -doesn't wait for a response to return from the server after each request. All -requests which require interaction with a CA server are accumulated (buffered) -and not forwarded to the IOC until one of ca_flush_io(), -ca_pend_io(), ca_pend_event(), or -ca_sg_block() are called allowing several operations to be -efficiently sent over the network together. Any process variable values written -into your program's variables by ca_get() should not be referenced by your -program until ECA_NORMAL has been received from ca_pend_io().

- -

Status Codes

- -

If successful, the routines described here return the status code -ECA_NORMAL. Unsuccessful status codes returned from the client library are -listed with each routine in this manual. Operations that appear to be valid to -the client can still fail in the server. Writing the string "off" to a floating -point field is an example of this type of error. If the server for a channel is -located in a different address space than the client then the ca_xxx() -operations that communicate with the server return status indicating the -validity of the request and whether it was successfully enqueued to the server, -but communication of completion status is deferred until a user callback is -called, or lacking that an exception handler is called. An error number and the -error's severity are embedded in CA status (error) constants. Applications -shouldn't test the success of a CA function call by checking to see if the -returned value is zero as is the UNIX convention. Below are several methods to -test CA function returns. See ca_signal() and -SEVCHK() for more information on this topic.

-
status = ca_XXXX(); 
-SEVCHK( status, "ca_XXXX() returned failure status"); 
-
-if ( status & CA_M_SUCCESS ) { 
-        printf ( "The requested ca_XXXX() operation didn't complete successfully"); 
-} 
-
-if ( status != ECA_NORMAL ) { 
-        printf("The requested ca_XXXX() operation didn't complete successfully because \"%s\"\n",
-                ca_message ( status ) ); 
-}
- -

Channel Access Data Types

- -

CA channels form a virtual circuit between a process variable (PV) and a -client side application program. It is possible to connect a wide variety of -data sources into EPICS using the CA server library. When a CA channel -communicates with an EPICS Input Output Controller (IOC) then a field is a -specialization of a PV, and an EPICS record is a plug compatible function block -that contains fields, and the meta data below frequently are mapped onto -specific fields within the EPICS records by the EPICS record support (see the -EPICS Application Developer Guide).

- -

Arguments of type chtype specifying the data type you wish to transfer. They -expect one of the set of DBR_XXXX data type codes defined in db_access.h. There -are data types for all of the C primitive types, and there are also compound (C -structure) types that include various process variable properties such as -units, limits, time stamp, or alarm status. The primitive C types follow a -naming convention where the C typedef dbr_xxxx_t corresponds to the DBR_XXXX -data type code. The compound (C structure) types follow a naming convention -where the C structure tag dbr_xxxx corresponds to the DBR_XXXX data type code. -The following tables provides more details on the structure of the CA data type -space. Since data addresses are passed to the CA client library as typeless -"void *" pointers then care should be taken to ensure that you have passed the -correct C data type corresponding to the DBR_XXXX type that you have specified. -Architecture independent types are provided in db_access.h to assist -programmers in writing portable code. For example "dbr_short_t" should be used -to send or receive type DBR_SHORT. Be aware that type name DBR_INT has been -deprecated in favor of the less confusing type name DBR_SHORT. In practice, -both the DBR_INT type code and the DBR_SHORT type code refer to a 16 bit -integer type, and are functionally equivalent.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Channel Access Primitive Data Types
CA Type CodePrimitive C Data TypeData Size
DBR_CHARdbr_char_t8 bit character
DBR_SHORTdbr_short_t16 bit integer
DBR_ENUMdbr_enum_t16 bit unsigned integer
DBR_LONGdbr_long_t32 bit signed integer
DBR_FLOATdbr_float_t32 bit IEEE floating point
DBR_DOUBLEdbr_double_t64 bit IEEE floating point
DBR_STRINGdbr_string_t40 character string
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Structure of the Channel Access Data Type Space
CA Type CodeRead / WritePrimitive C Data TypeProcess Variable Properties
DBR_<PRIMITIVE TYPE>RWdbr_<primitive type>_tvalue
DBR_STS_<PRIMITIVE TYPE>Rstruct dbr_sts_<primitive type>value, alarm status, and alarm severity
DBR_TIME_<PRIMITIVE TYPE>Rstruct dbr_time_<primitive type>value, alarm status, alarm severity, and time stamp
DBR_GR_<PRIMITIVE TYPE>Rstruct dbr_gr_<primitive type>value, alarm status, alarm severity, units, display precision, and - graphic limits
DBR_CTRL_<PRIMITIVE TYPE>Rstruct dbr_ctrl_<primitive type>value, alarm status, alarm severity, units, display precision, - graphic limits, and control limits
DBR_PUT_ACKTWdbr_put_ackt_tUsed for global alarm acknowledgement. Do transient alarms have to be - acknowledged? (0,1) means (no, yes).
DBR_PUT_ACKSWdbr_put_acks_tUsed for global alarm acknowledgement. The highest alarm severity to - acknowledge. If the current alarm severity is less then or equal to - this value the alarm is acknowledged.
DBR_STSACK_STRINGRstruct dbr_stsack_stringvalue, alarm status, alarm severity, ackt, acks
DBR_CLASS_NAMERdbr_class_name_tname of enclosing interface (name of the record if channel is - attached to EPICS run time database)
- -

- -

Channel value arrays can also be included within the structured CA data -types. If more than one element is requested, then the individual elements can -be accessed in an application program by indexing a pointer to the value field -in the DBR_XXX structure. For example, the following code computes the sum of -the elements in a array process variable and prints its time stamp. The -dbr_size_n() function can be used to determine the correct -number of bytes to reserve when there are more than one value field elements in -a structured CA data type.

-
#include <stdio.h>
-#include <stdlib.h>
-
-#include "cadef.h"
-
-int main ( int argc, char ** argv )
-{
-    struct dbr_time_double * pTD;
-    const dbr_double_t * pValue;
-    unsigned nBytes;
-    unsigned elementCount;
-    char timeString[32];
-    unsigned i;    
-    chid chan;
-    double sum;
-    int status;
-
-    if ( argc != 2 ) {
-        fprintf ( stderr, "usage: %s <channel name>", argv[0] );
-        return -1;
-    }
-
-    status = ca_create_channel ( argv[1], 0, 0, 0, & chan );
-    SEVCHK ( status, "ca_create_channel()" );
-    status = ca_pend_io ( 15.0 );
-    if ( status != ECA_NORMAL ) {
-        fprintf ( stderr, "\"%s\" not found.\n", argv[1] );
-        return -1;
-    }
-
-    elementCount = ca_element_count ( chan );
-    nBytes = dbr_size_n ( DBR_TIME_DOUBLE, elementCount );
-    pTD = ( struct dbr_time_double * ) malloc ( nBytes );
-    if ( ! pTD ) {
-        fprintf ( stderr, "insufficient memory to complete request\n" );
-        return -1;
-    }
-
-    status = ca_array_get ( DBR_TIME_DOUBLE, elementCount, chan, pTD );
-    SEVCHK ( status, "ca_array_get()" );
-    status = ca_pend_io ( 15.0 );
-    if ( status != ECA_NORMAL ) {
-        fprintf ( stderr, "\"%s\" didn't return a value.\n", argv[1] );
-        return -1;
-    }
-
-    pValue = & pTD->value;
-    sum = 0.0;
-    for ( i = 0; i < elementCount; i++ ) {
-        sum += pValue[i];
-    }
-
-    epicsTimeToStrftime ( timeString, sizeof ( timeString ),
-        "%a %b %d %Y %H:%M:%S.%f", & pTD->stamp );
-
-    printf ( "The sum of elements in %s at %s was %f\n", 
-        argv[1], timeString, sum );
-
-    ca_clear_channel ( chan );
-    ca_task_exit ();
-    free ( pTD );
-
-    return 0;
-}
- -

User Supplied Callback Functions

- -

Certain CA client initiated requests asynchronously execute an application -supplied callback in the client process when a response arrives. The functions -ca_put_callback(), ca_get_callback(), and -ca_create_subscription() all request notification of -asynchronous completion via this mechanism. The event_handler_args -structure is passed by value to the application supplied -callback. In this structure the dbr field is a void pointer to any -data that might be returned. The status field will be -set to one of the CA error codes in caerr.h and will indicate the status of the -operation performed in the IOC. If the status field isn't set to ECA_NORMAL or -data isn't normally returned from the operation (i.e. put callback) then you -should expect that the dbr field will be set to a null pointer -(zero). The fields usr, chid, and type -are set to the values specified when the request was made by the application. -The dbr pointer, and any data that it points to, are valid only when -executing within the user's callback function.

-
typedef struct event_handler_args {
-    void            *usr;   /* user argument supplied with request */
-    chanId          chid;   /* channel id */
-    long            type;   /* the type of the item returned */ 
-    long            count;  /* the element count of the item returned */
-    const void      *dbr;   /* a pointer to the item returned */
-    int             status; /* ECA_XXX status of the requested op from the server */
-} evargs;
-
-void myCallback ( struct event_handler_args args )
-{
-    if ( args.status != ECA_NORMAL ) {
-    }
-    if ( args.type == DBR_TIME_DOUBLE ) {
-         const struct dbr_time_double * pTD =
-              ( const struct dbr_time_double * ) args.dbr;
-    }
-}
- -

Channel Access Exceptions

- -

When the server detects a failure, and there is no client callback function -attached to the request, an exception handler is executed in the client. The -default exception handler prints a message on the console and exits if the -exception condition is severe. Certain internal exceptions within the CA client -library, and failures detected by the SEVCHK macro may also cause the exception -handler to be invoked. To modify this behavior see -ca_add_exception_event().

- -

Server and Client Share the Same Address Space on The Same -Host

- -

If the Process Variable's server and it's client are colocated within the -same memory address space and the same host then the ca_xxx() operations bypass -the server and directly interact with the server tool component (commonly the -IOC's function block database). In this situation the ca_xxx() routines -frequently return the completion status of the requested operation directly to -the caller with no opportunity for asynchronous notification of failure via an -exception handler. Likewise, callbacks may be directly invoked by the CA -library functions that request them.

- -

Arrays

- -

For routines that require an argument specifying the number of array -elements, no more than the process variable's maximum native element count may -be requested. The process variable's maximum native element count is available -from ca_element_count() when the channel is connected. If fewer elements than -the process variable's native element count are requested, the requested values -will be fetched beginning at element zero. By default CA limits the number of -elements in an array to be no more than approximately 16k divided by the size -of one element in the array. Starting with EPICS R3.14 the maximum array size -may be configured in the client and in the server.

- -

Connection Management

- -

Application programs should assume that CA servers may be restarted, and -that network connectivity is transient. When you create a CA channel its -initial connection state will most commonly be disconnected. If the Process -Variable's server is available the library will immediately initiate the -necessary actions to make a connection with it. Otherwise, the client library -will monitor the state of servers on the network and connect or reconnect with -the process variable's server as it becomes available. After the channel -connects the application program can freely perform IO operations through the -channel, but should expect that the channel might disconnect at any time due to -network connectivity disruptions or server restarts.

- -

Three methods can be used to determine if a channel is connected: the -application program might call ca_state() -to obtain the current connection state, block in -ca_pend_io() until the channel connects, -or install a connection callback handler when it calls -ca_create_channel(). The -ca_pend_io() approach is best suited to -simple command line programs with short runtime duration, and the connection -callback method is best suited to toolkit components with long runtime duration. -Use of ca_state() is appropriate only in -programs that prefer to poll for connection state changes instead of opting for -asynchronous notification. The ca_pend_io() function blocks only -for channels created specifying a null connection handler callback function. The -user's connection state change function will be run immediately from within -ca_create_channel() if the CA -client and CA server are both hosted within the same address space (within the -same process).

- -

Thread Safety and Preemptive Callback to User Code

- -

Starting with EPICS R3.14 the CA client libraries are fully thread safe on -all OS (in past releases the library was thread safe only on vxWorks). When the -client library is initialized the programmer may specify if preemptive callback -is to be enabled. Preemptive callback is disabled by default. If preemptive -callback is enabled, then the user's callback functions might be called by CA's -auxiliary threads when the main initiating channel access thread is not inside -of a function in the channel access client library. Otherwise, the user's -callback functions will be called only when the main initiating channel access -thread is executing inside of the CA client library. When the CA client library -invokes a user's callback function, it will always wait for the current -callback to complete prior to executing another callback function. Programmers -enabling preemptive callback should be familiar with using mutex locks to -create a reliable multi-threaded program.

- -

To set up a traditional single threaded client, you will need code like this -(see ca_context_create() and -CA Client Contexts and Application Specific Auxiliary -Threads) .

- -

SEVCHK ( ca_context_create(ca_disable_preemptive_callback ), -"application pdq calling ca_context_create" );

- -

To set up a preemptive callback enabled CA client context you will need code -like this (see ca_context_create() and -CA Client Contexts and Application Specific Auxiliary -Threads).

- -

SEVCHK ( ca_context_create(ca_enable_preemptive_callback ), -"application pdq calling ca_context_create" );

- -

CA Client Contexts and Application Specific Auxiliary -Threads

- -

It is often necessary for several CA client side tools running in the same -address space (process) to be independent of each other. For example, the -database CA links and the sequencer are designed to not use the same CA client -library threads, network circuits, and data structures. Each thread that calls -ca_context_create() for the first time either -directly or implicitly when calling any CA library function for the first time, -creates a CA client library context. A CA client library context contains all -of the threads, network circuits, and data structures required to connect and -communicate with the channels that a CA client application has created. The -priority of auxiliary threads spawned by the CA client library are at fixed -offsets from the priority of the thread that called -ca_context_create(). An application specific -auxiliary thread can join a CA context by calling -ca_attach_context() using the CA context -identifier that was returned from -ca_current_context() when it is called by the -thread that created the context which needs to be joined. A context which is to -be joined must be preemptive - it must be created using -ca_context_create(ca_enable_preemptive_callback). -It is not possible to attach a thread to a non-preemptive CA context created -explicitly or implicitly with -ca_create_context(ca_disable_preemptive_callback). Once a thread has joined -with a CA context it need only make ordinary ca_xxxx() library calls to use the -context.

- - -

A CA client library context can be shut down and cleaned up, after -destroying any channels or application specific threads that are attached to -it, by calling ca_context_destroy(). The -context may be created and destroyed by different threads as long as they are -both part of the same context.

- -

Polling the CA Client Library From Single Threaded -Applications

- -

If preemptive callback is not enabled, then for proper operation CA must -periodically be polled to take care of background activity. This requires that -your application must either wait in one of ca_pend_event(), ca_pend_io(), or -ca_sg_block() or alternatively it should call ca_poll() at least every 100 -milliseconds. In single threaded applications a file descriptor manager like -Xt or the interface described in fdManager.h can be used to monitor both mouse -clicks and also CA's file descriptors so that ca_poll() can be called -immediately when CA server messages arrives over the network.

- -

Avoid Emulating Bad Practices that May Still be -Common

- -

With the embryonic releases of EPICS it was a common practice to examine a -channel's connection state, its native type, and its native element count by -directly accessing fields in a structure using a pointer stored in type -chid. Likewise, a user private pointer in the per channel -structure was also commonly set by directly accessing fields in the channel -structure. A number of difficulties arise from this practice, which has long -since been deprecated. For example, prior to release 3.13 it was recognized -that transient changes in certain private fields in the per channel structure -would make it difficult to reliably test the channels connection state using -these private fields directly. Therefore, in release 3.13 the names of certain -fields were changed to discourage this practice. Starting with release 3.14 -codes written this way will not compile. Codes intending to maintain the -highest degree of portability over a wide range of EPICS versions should be -especially careful. For example you should replace all instances off -channel_id->count with -ca_element_count(channel_id). This approach should be reliable on -all versions of EPICS in use today. The construct ca_puser(chid) = -xxxx is particularly problematic. The best mechanisms for setting the -per channel private pointer will be to pass the user private pointer in when -creating the channel. This approach is implemented on all versions. Otherwise, -you can also use ca_set_puser(CHID,PUSER), but this function is -available only after the first official (post beta) release of EPICS 3.13.

- -

Calling CA Functions from the vxWorks Shell -Thread

- -

Calling CA functions from the vxWorks shell thread is a somewhat -questionable practice for the following reasons.

-
    -
  • The vxWorks shell thread runs at the very highest priority in the system - and therefore socket calls are made at a priority that is above the - priority of tNetTask. This has caused problems with the WRS IP kernel in - the past. That symptom was observed some time ago, but we don't know if - WRS has fixed the problem.
  • -
-
    -
  • The vxWorks shell thread runs at the very highest priority in the system - and therefore certain CA auxiliary threads will not get the priorities that - are requested for them. This might cause problems only when in a CPU - saturation situations.
  • -
-
    -
  • If the code does not call ca_context_destroy() (named ca_task_exit() in past - releases) then resources are left dangling.
  • -
-
    -
  • In EPICS R3.13 the CA client library installed vxWorks task exit handlers - behaved strangely if CA functions were called from the vxWorks shell, - ca_task_exit() wasn't called, and the vxWorks shell restarted. In - EPICS R3.14 vxWorks task exit handlers are not installed and therefore - cleanup is solely the responsibility of the user. With EPICS R3.14 the user - must call ca_context_destroy() or ca_task_exit() to clean up on vxWorks. This - is the same behavior as on all other OS.
  • -
- -

Calling CA Functions from POSIX signal -handlers

- -

As you might expect, it isn't safe to call the CA client library from a POSIX -signal handler. Likewise, it isn't safe to call the CA client library from -interrupt context.

-
- -

Function Call Reference

- -

ca_context_create()

-
#include <cadef.h>
-enum ca_preemptive_callback_select
-    { ca_disable_preemptive_callback, ca_enable_preemptive_callback };
-int ca_context_create ( enum ca_preemptive_callback_select SELECT );
- -

Description

- -

This function, or ca_attach_context(), -should be called once from each thread prior to making any of the other Channel -Access calls. If one of the above is not called before making other CA calls -then a non-preemptive context is created by default, and future attempts to -create a preemptive context for the current threads will fail.

- -

If ca_disable_preemptive_callback is specified then additional -threads are not allowed to join the CA context using -ca_context_attach() because allowing other threads to join implies that CA -callbacks will be called preemptively from more than one thread.

- -

Arguments

-
-
SELECT
-
This argument specifies if preemptive invocation of callback functions - is allowed. If so your callback functions might be called when the thread - that calls this routine is not executing in the CA client library. There - are two implications to consider.
-

First, if preemptive callback mode is enabled the developer must - provide mutual exclusion protection for his data structures. In this mode - it's possible for two threads to touch the application's data structures - at once: this might be the initializing thread (the thread that called - ca_context_create) and also a private thread created by the CA client - library for the purpose of receiving network messages and calling - callbacks. It might be prudent for developers who are unfamiliar with - mutual exclusion locking in a multi-threaded environment to specify - ca_disable_preemptive_callback.

-

Second, if preemptive callback mode is enabled the application is no - longer burdened with the necessity of periodically polling the CA client - library in order that it might take care of its background activities. If - ca_enable_preemptive_callback is specified then CA client - background activities, such as connection management, will proceed even - if the thread that calls this routine is not executing in the CA client - library. Furthermore, in preemptive callback mode callbacks might be - called with less latency because the library is not required to wait - until the initializing thread (the thread that called ca_context_create) - is executing within the CA client library.

-
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_ALLOCMEM - Failed, unable to allocate space in pool

- -

ECA_NOTTHREADED - Current thread is already a member of a non-preemptive -callback CA context (possibly created implicitly)

- -

See Also

- -

ca_context_destroy()

- -

ca_context_destroy()

-
#include <cadef.h>
-void ca_context_destroy();
- -

Description

- -

Shut down the calling thread's channel access client context and free any -resources allocated. Detach the calling thread from any CA client context.

- -

Any user-created threads that have attached themselves to the CA context -must stop using it prior to its being destroyed. A program running in an IOC -context must delete all of its channels prior to calling ca_context_destroy() -to avoid a crash.

- -

A CA client application that calls epicsExit() must install an -EPICS exit handler that calls ca_context_destroy() only after first -calling ca_create_context(). This will guarantee that the EPICS exit handlers -get called in the correct order.

- -

On many OS that execute programs in a process based environment the -resources used by the client library such as sockets and allocated memory are -automatically released by the system when the process exits and -ca_context_destroy() hasn't been called, but on light weight systems such as -vxWorks or RTEMS no cleanup occurs unless the application calls -ca_context_destroy().

- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

See Also

- -

ca_context_create()

- -

ca_create_channel()

-
#include <cadef.h>
-typedef void ( caCh ) (struct connection_handler_args);
-int ca_create_channel (const char *PVNAME,
-        caCh *USERFUNC, void *PUSER,
-        capri PRIORITY, chid *PCHID );
- -

Description

- -

This function creates a CA channel. The CA client library will attempt to -establish and maintain a virtual circuit between the caller's application and a -named process variable in a CA server. Each call to ca_create_channel() allocates -resources in the CA client library and potentially also a CA server. The -function ca_clear_channel() is used to release these resources. If successful, -the routine writes a channel identifier into the user's variable of type -"chid". This identifier can be used with any channel access call that operates -on a channel.

- -

The circuit may be initially connected or disconnected depending on the -state of the network and the location of the channel. A channel will only enter -a connected state after the server's address is determined, and only if channel -access successfully establishes a virtual circuit through the network to the -server. Channel access routines that send a request to a server will return -ECA_DISCONNCHID if the channel is currently disconnected.

- -

There are two ways to obtain asynchronous notification when a channel enters -a connected state.

-
    -
  • The first and simplest method requires that you call ca_pend_io(), and - wait for successful completion, prior to using a channel that was created - specifying a null connection callback function pointer.
  • -
  • The second method requires that you register a connection handler by - supplying a valid connection callback function pointer. This connection - handler is called whenever the connection state of the channel changes. If - you have installed a connection handler then ca_pend_io() will not - block waiting for the channel to enter a connected state.
  • -
- -

The function ca_state(CHID) can be used to test the connection state of a -channel. Valid connections may be isolated from invalid ones with this function -if ca_pend_io() times out.

- -

Due to the inherently transient nature of network connections the order of -connection callbacks relative to the order that ca_create_channel() calls are -made by the application can't be guaranteed, and application programs may need -to be prepared for a connected channel to enter a disconnected state at any -time.

- -

Example

- -

See caExample.c in the example application created by makeBaseApp.pl.

- -

Arguments

-
-
PVNAME
-
A nil terminated process variable name string. EPICS process control - function block database variable names are of the form "<record - name>.<field name>". If the field name and the period separator - are omitted then the "VAL" field is implicit. For example "RFHV01" and - "RFHV01.VAL" reference the same EPICS process control function block - database variable.
-
-
-
USERFUNC
-
Optional address of the user's callback function to be run when the - connection state changes. Casual users of channel access may decide to - set this field to null or 0 if they do not need to have a callback - function run in response to each connection state change event. -

The following structure is passed by value to the user's - connection callback function. The op field will - be set by the CA client library to CA_OP_CONN_UP when the - channel connects, and to CA_OP_CONN_DOWN when the channel - disconnects. See ca_puser() if the - PUSER argument is required in your callback - handler.

-
struct  ca_connection_handler_args {
-    chanId  chid;  /* channel id */
-    long    op;    /* one of CA_OP_CONN_UP or CA_OP_CONN_DOWN */
-};
-
-
-
-
PUSER
-
The value of this void pointer argument is retained in - storage associated with the specified channel. See the MACROS manual page - for reading and writing this field. Casual users of channel access may - wish to set this field to null or 0.
-
-
-
PRIORITY
-
The priority level for dispatch within the server or network with 0 - specifying the lowest dispatch priority and 99 the highest. This - parameter currently does not impact dispatch priorities within the - client, but this might change in the future. The abstract priority range - specified is mapped into an operating system specific range of priorities - within the server. This parameter is ignored if the server is running on - a network or operating system that does not have native support for - prioritized delivery or execution respectively. Specifying many different - priorities within the same program can increase resource consumption in - the client and the server because an independent virtual circuit, and - associated data structures, is created for each priority that is used on - a particular server.
-
-
-
PCHID
-
The user supplied channel identifier storage is overwritten with a - channel identifier if this routine is successful.
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADTYPE - Invalid DBR_XXXX type

- -

ECA_STRTOBIG - Unusually large string

- -

ECA_ALLOCMEM - Unable to allocate memory

- -

ca_clear_channel()

-
#include <cadef.h>
-int ca_clear_channel (chid CHID);
- -

Description

- -

Shutdown and reclaim resources associated with a channel created by -ca_create_channel().

- -

All remote operation requests such as the above are accumulated (buffered) -and not forwarded to the IOC until one of ca_flush_io(), ca_pend_io(), -ca_pend_event(), or ca_sg_block() are called. This allows several requests to be -efficiently sent over the network in one message.

- -

Clearing a channel does not cause its disconnect handler to be called, but -clearing a channel does shutdown and reclaim any channel state change event -subscriptions (monitors) registered with the channel.

- -

Arguments

-
-
CHID
-
Identifies the channel to delete.
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADCHID - Corrupted CHID

- -

ca_put()

-
#include <cadef.h>
-int ca_put ( chtype TYPE, 
-        chid CHID, void *PVALUE ); 
-int ca_array_put ( chtype TYPE, unsigned long COUNT, 
-        chid CHID, const void *PVALUE);
-typedef void ( caEventCallBackFunc ) (struct event_handler_args);
-int ca_put_callback ( chtype TYPE, 
-        chid CHID, const void *PVALUE, 
-        caEventCallBackFunc PFUNC, void *USERARG ); 
-int ca_array_put_callback ( chtype TYPE, unsigned long COUNT, 
-        chid CHID, const void *PVALUE, 
-        caEventCallBackFunc PFUNC, void *USERARG );
- -

Description

- -

Write a scalar or array value to a process variable.

- -

When ca_put() or ca_array_put() are invoked the client will receive no response -unless the request can not be fulfilled in the server. If unsuccessful an -exception handler is run on the client side.

- -

When ca_put_callback() or ca_array_put_callback() are invoked the user supplied -asynchronous callback is called only after the initiated write operation, and -all actions resulting from the initiating write operation, complete.

- -

If unsuccessful the callback function is invoked indicating failure status. -

- -

If the channel disconnects before a put callback request can be completed, -then the client's callback function is called with failure status, but this -does not guarantee that the server did not receive and process the request -before the disconnect. If a connection is lost and then resumed outstanding ca -put requests are not automatically reissued following reconnect.

- -

All of these functions return ECA_DISCONN if the channel is currently -disconnected.

- -

All put requests are accumulated (buffered) and not forwarded to the IOC -until one of ca_flush_io(), ca_pend_io(), ca_pend_event(), or ca_sg_block() are called. -This allows several requests to be efficiently combined into one message.

- -

Description (IOC Database Specific)

- -

A CA put request causes the record to process if the record's SCAN field is -set to passive, and the field being written has its process passive attribute -set to true. If such a record is already processing when a put request is -initiated the specified field is written immediately, and the record is -scheduled to process again as soon as it finishes processing. Earlier instances -of multiple put requests initiated while the record is being processing may be -discarded, but the last put request initiated is always written and -processed.

- -

A CA put callback request causes the record to process if the -record's SCAN field is set to passive, and the field being written has its -process passive attribute set to true. For such a record, the user's put -callback function is not called until after the record, and any records that -the record links to, finish processing. If such a record is already processing -when a put callback request is initiated the put callback -request is postponed until the record, and any records it links to, finish -processing.

- -

If the record's SCAN field is not set to passive, or the field being written -has its process passive attribute set to false then the CA put or CA put -callback request cause the specified field to be immediately written, -but they do not cause the record to be processed.

- -

Arguments

-
-
TYPE
-
The external type of the supplied value to be written. Conversion will - occur if this does not match the native type. Specify one from the set of - DBR_XXXX in db_access.h
-
-
-
COUNT
-
Element count to be written to the specified channel. This must match - the array pointed to by PVALUE.
-
-
-
CHID
-
Channel identifier
-
-
-
PVALUE
-
Pointer to a value or array of values provided by the application to be - written to the channel.
-
-
-
PFUNC
-
address of user supplied callback function to be - run when the requested operation completes
-
-
-
USERARG
-
pointer sized variable retained and then passed back to user supplied - function above
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADCHID - Corrupted CHID

- -

ECA_BADTYPE - Invalid DBR_XXXX type

- -

ECA_BADCOUNT - Requested count larger than native element count

- -

ECA_STRTOBIG - Unusually large string supplied

- -

ECA_NOWTACCESS - Write access denied

- -

ECA_ALLOCMEM - Unable to allocate memory

- -

ECA_DISCONN - Channel is disconnected

- -

See Also

- -

ca_flush_io()

- -

ca_pend_event()

- -

ca_sg_array_put()

- -

ca_get()

-
#include <cadef.h>
-int ca_get ( chtype TYPE,
-        chid CHID, void *PVALUE );
-int ca_array_get ( chtype TYPE, unsigned long COUNT,
-        chid CHID, void *PVALUE );
-typedef void ( caEventCallBackFunc ) (struct event_handler_args);
-int ca_get_callback ( chtype TYPE,
-        chid CHID,
-        caEventCallBackFunc USERFUNC, void *USERARG);
-int ca_array_get_callback ( chtype TYPE, unsigned long COUNT,
-        chid CHID,
-        caEventCallBackFunc USERFUNC, void *USERARG);
- -

Description

- -

Read a scalar or array value from a process variable.

- -

When ca_get() or ca_array_get() are invoked the returned channel value can't be -assumed to be stable in the application supplied buffer until after ECA_NORMAL -is returned from ca_pend_io(). If a connection is lost outstanding ca get -requests are not automatically reissued following reconnect.

- -

When ca_get_callback() or ca_array_get_callback() are invoked a value is read -from the channel and then the user's callback is invoked with a pointer to the -retrieved value. Note that ca_pend_io() will not block for the delivery of values -requested by ca_get_callback(). If the channel disconnects before a -ca_get_callback() request can be completed, then the client's callback function is -called with failure status.

- -

All of these functions return ECA_DISCONN if the channel is currently -disconnected.

- -

All get requests are accumulated (buffered) and not forwarded to the IOC -until one of ca_flush_io(), ca_pend_io(), ca_pend_event(), or ca_sg_block() are called. -This allows several requests to be efficiently sent over the network in one -message.

- -

Description (IOC Database Specific)

- -

A CA get or CA get callback request causes the record's field to be read -immediately independent of whether the record is currently being processed or -not. There is currently no mechanism in place to cause a record to be processed -when a CA get request is initiated.

- -

Example

- -

See caExample.c in the example application created by makeBaseApp.pl.

- -

Arguments

-
-
TYPE
-
The external type of the user variable to return the value into. - Conversion will occur if this does not match the native type. Specify one - from the set of DBR_XXXX in db_access.h
-
-
-
COUNT
-
Element count to be read from the specified channel. Must match the - array pointed to by PVALUE. For ca_array_get_callback() a count of zero - means use the current element count from the server.
-
-
-
CHID
-
Channel identifier
-
-
-
PVALUE
-
Pointer to an application supplied buffer where the current value of - the channel is to be written.
-
-
-
USERFUNC
-
Address of user supplied callback function to be - run when the requested operation completes.
-
-
-
USERARG
-
Pointer sized variable retained and then passed back to user supplied - callback function above.
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADTYPE - Invalid DBR_XXXX type

- -

ECA_BADCHID - Corrupted CHID

- -

ECA_BADCOUNT - Requested count larger than native element count

- -

ECA_GETFAIL - A local database get failed

- -

ECA_NORDACCESS - Read access denied

- -

ECA_ALLOCMEM - Unable to allocate memory

- -

ECA_DISCONN - Channel is disconnected

- -

See Also

- -

ca_pend_io()

- -

ca_pend_event()

- -

ca_sg_array_get()

- -

ca_create_subscription()

-
#include <cadef.h>
-typedef void ( caEventCallBackFunc ) (struct event_handler_args);
-int ca_create_subscription ( chtype TYPE, unsigned long COUNT,
-        chid CHID, unsigned long MASK,
-        caEventCallBackFunc USERFUNC, void *USERARG, 
-        evid *PEVID );
- -

Description

- -

Register a state change subscription and specify a callback function to be -invoked whenever the process variable undergoes significant state changes. A -significant change can be a change in the process variable's value, alarm -status, or alarm severity. In the process control function block database the -deadband field determines the magnitude of a significant change for the -process variable's value. Each call to this function consumes resources in the -client library and potentially a CA server until one of ca_clear_channel() or -ca_clear_subscription() is called.

- -

Subscriptions may be installed or canceled against both connected and -disconnected channels. The specified USERFUNC is called once immediately after -the subscription is installed with the process variable's current state if the -process variable is connected. Otherwise, the specified USERFUNC is called -immediately after establishing a connection (or reconnection) with the process -variable. The specified USERFUNC is called immediately with the process -variable's current state from within ca_create_subscription() if the client and the -process variable share the same address space.

- -

If a subscription is installed on a channel in a disconnected state then the -requested count will be set to the native maximum element count of the channel -if the requested count is larger.

- -

All subscription requests such as the above are accumulated (buffered) and -not forwarded to the IOC until one of ca_flush_io(), ca_pend_io(), ca_pend_event(), -or ca_sg_block() are called. This allows several requests to be efficiently sent -over the network in one message.

- -

If at any time after subscribing, read access to the specified process -variable is lost, then the callback will be invoked immediately indicating -that read access was lost via the status argument. When read access is restored -normal event processing will resume starting always with at least one update -indicating the current state of the channel.

- -

A better name for this function might have been ca_subscribe().

- -

Example

- -

See caMonitor.c in the example application created by makeBaseApp.pl.

- -

Arguments

-
-
TYPE
-
The type of value presented to the callback function. Conversion will - occur if it does not match native type. Specify one from the set of - DBR_XXXX in db_access.h
-
-
-
COUNT
-
The element count to be read from the specified channel. A count of - zero means use the current element count from the server.
-
-
-
CHID
-
channel identifier
-
-
-
USRERFUNC
-
The address of user supplied callback function to - be invoked with each subscription update.
-
-
-
USERARG
-
pointer sized variable retained and passed back to user callback - function
-
-
-
RESERVED
-
Reserved for future use. Specify 0.0 to remain upwardly compatible.
-
-
-
PEVID
-
This is a pointer to user supplied event id which is overwritten if - successful. This event id can later be used to clear a specific event. - This option may be omitted by passing a null pointer.
-
-
-
MASK
-
A mask with bits set for each of the event trigger types requested. The - event trigger mask must be a bitwise or of one or more of the - following constants. -
    -
  • DBE_VALUE - Trigger events when the channel value exceeds the - monitor dead band
  • -
  • DBE_ARCHIVE (or DBE_LOG) - Trigger events when the channel value - exceeds the archival dead band
  • -
  • DBE_ALARM - Trigger events when the channel alarm state changes
  • -
  • DBE_PROPERTY - Trigger events when a channel property changes.
  • -
-

For functions above that do not include a trigger specification, - events will be triggered when there are significant changes in the - channel's value or when there are changes in the channel's alarm state. - This is the same as "DBE_VALUE | DBE_ALARM."

-
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADCHID - Corrupted CHID

- -

ECA_BADTYPE - Invalid DBR_XXXX type

- -

ECA_ALLOCMEM - Unable to allocate memory

- -

ECA_ADDFAIL - A local database event add failed

- -

See Also

- -

ca_pend_event()

- -

ca_flush_io()

- -

ca_clear_subscription()

-
#include <cadef.h>
-int ca_clear_subscription ( evid EVID );
- -

Description

- -

Cancel a subscription.

- -

All cancel-subscription requests such as the above are accumulated (buffered) -and not forwarded to the server until one of ca_flush_io(), ca_pend_io(), -ca_pend_event(), or ca_sg_block() are called. This allows several requests to be -efficiently sent together in one message.

- -

Arguments

-
-
EVID
-
event id returned by ca_create_subscription()
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADCHID - Corrupted CHID

- -

See Also

- -

ca_create_subscription()

- -

ca_pend_io()

-
#include <cadef.h>
-int ca_pend_io ( double TIMEOUT );
- -

Description

- -

This function flushes the send buffer and then blocks until outstanding -ca_get() requests complete, and until channels created -specifying null connection handler function pointers connect for the first -time.

-
    -
  • If ECA_NORMAL is returned then it can be safely assumed that all - outstanding ca_get() requests have completed - successfully and channels created specifying null connection handler - function pointers have connected for the first time.
  • -
  • If ECA_TIMEOUT is returned then it must be assumed for all previous - ca_get() requests and properly qualified first time - channel connects have failed.
  • -
- -

If ECA_TIMEOUT is returned then get requests may be reissued followed by a -subsequent call to ca_pend_io(). Specifically, the function will block only for -outstanding ca_get() requests issued, and also any channels -created specifying a null connection handler function pointer, after the last -call to ca_pend_io() or ca client context creation whichever is later. Note -that ca_create_channel() requests generally -should not be reissued for the same process variable unless -ca_clear_channel() is called first.

- -

If no ca_get() or connection state change events are -outstanding then ca_pend_io() will flush the send buffer and return immediately -without processing any outstanding channel access background -activities.

- -

The delay specified to ca_pend_io() should take into account worst case -network delays such as Ethernet collision exponential back off until -retransmission delays which can be quite long on overloaded networks.

- -

Unlike ca_pend_event(), this routine -will not process CA's background activities if none of the selected IO requests -are pending.

- -

Arguments

-
-
TIMEOUT
-
Specifies the time out interval. A TIMEOUT interval of - zero specifies forever.
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_TIMEOUT - Selected IO requests didn't complete before specified -timeout

- -

ECA_EVDISALLOW - Function inappropriate for use within an event handler

- -

See Also

- -

ca_get()

- -

ca_create_channel()

- -

ca_test_io()

- -

ca_test_io()

-
#include <cadef.h>
-int ca_test_io();
- -

Description

- -

This function tests to see if all ca_get() requests are -complete and channels created specifying a null connection callback function -pointer are connected. It will report the status of outstanding -ca_get() requests issued, and channels created specifying a -null connection callback function pointer, after the last call to ca_pend_io() -or CA context initialization whichever is later.

- -

Returns

- -

ECA_IODONE - All IO operations completed

- -

ECA_IOINPROGRESS - IO operations still in progress

- -

See Also

- -

ca_pend_io()

- -

ca_pend_event()

-
#include <cadef.h>
-int ca_pend_event ( double TIMEOUT );
-int ca_poll ();
- -

Description

- -

When ca_pend_event() is invoked the send buffer is flushed and CA background -activity is processed for TIMEOUT seconds.

- -

When ca_poll() is invoked the send buffer is flushed and any outstanding CA -background activity is processed.

- -

The ca_pend_event() function will not return before the specified -timeout expires and all unfinished channel access labor has been processed, -and unlike ca_pend_io() returning from the -function does not indicate anything about the status of pending IO -requests.

- -

Both ca_pend_event() and ca_poll() return ECA_TIMEOUT -when successful. This behavior probably isn't intuitive, but it is preserved to -insure backwards compatibility.

- -

See also Thread Safety and Preemptive Callback to User -Code.

- -

Arguments

-
-
TIMEOUT
-
The duration to block in this routine in seconds. A timeout of zero - seconds blocks forever.
-
- -

Returns

- -

ECA_TIMEOUT - The operation timed out

- -

ECA_EVDISALLOW - Function inappropriate for use within a callback -handler

- -

ca_flush_io()

-
#include <cadef.h>
-int ca_flush_io();
- -

Description

- -

Flush outstanding IO requests to the server. This routine might be useful -to users who need to flush requests prior to performing client side labor in -parallel with labor performed in the server.

- -

Outstanding requests are also sent whenever the buffer which holds them -becomes full.

- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ca_signal()

-
#include <cadef.h>
-int ca_signal ( long CA_STATUS, const char * CONTEXT_STRING ); 
-void SEVCHK( CA_STATUS, CONTEXT_STRING );
- -

Description

- -

Provide the error message character string associated with the supplied -channel access error code and the supplied error context to diagnostics. If the -error code indicates an unsuccessful operation a stack dump is printed, if this -capability is available on the local operating system, and execution is -terminated.

- -

SEVCHK is a macro envelope around ca_signal() which only calls ca_signal() if -the supplied error code indicates an unsuccessful operation. SEVCHK is the -recommended error handler for simple applications which do not wish to write -code testing the status returned from each channel access call.

- -

Examples

-
status = ca_context_create (...); 
-SEVCHK ( status, "Unable to create a CA client context" );
- -

If the application only wishes to print the message associated with an error -code or test the severity of an error there are also functions provided for -this purpose.

- -

Arguments

-
-
CA_STATUS
-
The status (error code) returned from a channel access function.
-
-
-
CONTEXT_STRING
-
A null terminated character string to supply as error context to - diagnostics.
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ca_add_exception_event()

-
#include <cadef.h> 
-typedef void (*pCallback) ( struct exception_handler_args HANDLERARGS );
-int ca_add_exception_event ( pCallback  USERFUNC, void *USERARG );
- -

Description

- -

Replace the currently installed CA context global exception handler callback.

- -

When an error occurs in the server asynchronous to the clients thread then -information about this type of error is passed from the server to the client in -an exception message. When the client receives this exception message an -exception handler callback is called.The default exception handler prints a -diagnostic message on the client's standard out and terminates execution if the -error condition is severe.

- -

Note that certain fields in "struct exception_handler_args" are not -applicable in the context of some error messages. For instance, a failed get -will supply the address in the client task where the returned value was -requested to be written. For other failed operations the value of the addr -field should not be used.

- -

Arguments

-
-
USERFUNC
-
Address of user callback function to be executed when an exceptions - occur. Passing a null value causes the default exception handler to be - reinstalled. The following structure is passed by value to the user's - callback function. Currently, the op field can be one of - CA_OP_GET, CA_OP_PUT, CA_OP_CREATE_CHANNEL, CA_OP_ADD_EVENT, - CA_OP_CLEAR_EVENT, or CA_OP_OTHER. -
struct exception_handler_args {
-    void            *usr;   /* user argument supplied when installed */
-    chanId          chid;   /* channel id (may be null) */
-    long            type;   /* type requested */
-    long            count;  /* count requested */
-    void            *addr;  /* user's address to write results of CA_OP_GET */
-    long            stat;   /* channel access ECA_XXXX status code */
-    long            op;     /* CA_OP_GET, CA_OP_PUT, ..., CA_OP_OTHER */
-    const char      *ctx;   /* a character string containing context info */
-    sonst char      *pFile; /* source file name (may be NULL) */
-    unsigned        lineNo; /* source file line number (may be zero) */
-};
-
-
-
-
USERARG
-
pointer sized variable retained and passed back to user function - above
-
- -

Example

-
void ca_exception_handler (
-    struct exception_handler_args args)
-{
-    char buf[512];
-    char *pName;
-
-    if ( args.chid ) {
-        pName = ca_name ( args.chid );
-    }
-    else {
-        pName = "?";
-    }
-    sprintf ( buf,
-            "%s - with request chan=%s op=%d data type=%s count=%d",
-            args.ctx, pName, args.op, dbr_type_to_text ( args.type ), args.count );
-    ca_signal ( args.stat, buf );
-}
-ca_add_exception_event ( ca_exception_handler , 0 );
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

- -

ca_add_fd_registration()

-
#include <cadef.h>
-int ca_add_fd_registration ( void ( USERFUNC * ) ( void *USERARG, int FD, int OPENED ), void * USERARG )
- -

Description

- -

For use with the services provided by a file descriptor manager (IO -multiplexor) such as "fdmgr.c". A file descriptor manager is often needed when -two file descriptor IO intensive libraries such as the EPICS channel access -client library and the X window system client library must coexist in the same -UNIX process. This function allows an application code to be notified whenever -the CA client library places a new file descriptor into service and whenever -the CA client library removes a file descriptor from service. Specifying -USERFUNC=NULL disables file descriptor registration (this is the default).

- -

Arguments

- -

USERFUNC

- -

Pointer to a user supplied C function returning null with the above -arguments.

- -

USERARG

- -

User supplied pointer sized variable passed to the above function.

- -

FD

- -

A file descriptor.

- -

OPENED

- -

Boolean argument is true if the file descriptor was opened and false if the -file descriptor was closed.

- -

Example

-
int s;
-static struct myStruct aStruct;
-
-void fdReg ( struct myStruct *pStruct, int fd, int opened )
-{
-    if ( opened ) printf ( "fd %d was opened\n", fd );
-    else printf ( "fd %d was closed\n", fd );
-}
-s = ca_add_fd_registration ( fdReg, & aStruct );
-SEVCHK ( s, NULL );
- -

Comments

- -

When using this function it is advisable to call it only once prior to -calling any other CA function, or once just after creating the CA context (if -you create the context explicitly). Use of this interface can improve latency -slightly in applications that use non preemptive callback mode at the expense -of some additional runtime overhead when compared to the alternative which is -just polling ca_pend_event() periodically. It would probably not be appropriate -to use this function with preemptive callback mode. Starting with R3.14 this -function is implemented in a special backward compatibility mode. if -ca_add_fd_registration() is called, a single pseudo UDP fd is -created which CA pokes whenever something significant happens. Xt and others -can watch this fd so that backwards compatibility is preserved, and so that -they will not need to use preemptive callback mode but they will nevertheless -get the lowest latency response to the arrival of CA messages.

- -

Returns

- -

"ECA_NORMAL - Normal successful completion

- -

- -

ca_replace_printf_handler -()

-
#include <cadef.h>
-typedef int caPrintfFunc ( const char *pFormat, va_list args );
-int ca_replace_printf_handler ( caPrintfFunc *PFUNC );
- -

Description

- -

Replace the default handler for formatted diagnostic message output. The -default handler uses fprintf to send messages to 'stderr'.

- -

Arguments

-
-
PFUNC
-
The address of a user supplied callback handler to be invoked when CA - prints diagnostic messages. Installing a null pointer will cause the - default callback handler to be reinstalled.
-
- -

Examples

-
int my_printf ( char *pformat, va_list args ) {
-        int status;
-        status = vfprintf( stderr, pformat, args);
-        return status;
-}
-status = ca_replace_printf_handler ( my_printf );
-SEVCHK ( status, "failed to install my printf handler" );
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ca_replace_access_rights_event()

-
#include <cadef.h>
-typedef void ( caEventCallBackFunc )(struct access_rights_handler_args);
-int ca_replace_access_rights_event ( chid CHAN,
-        caEventCallBackFunc PFUNC );
- -

Description

- -

Install or replace the access rights state change callback handler for the -specified channel.

- -

The callback handler is called in the following situations.

-
    -
  • whenever CA connects the channel immediately before the channel's - connection handler is called
  • -
  • whenever CA disconnects the channel immediately after the channel's - disconnect callback is called
  • -
  • once immediately after installation if the channel is connected.
  • -
  • whenever the access rights state of a connected channel changes
  • -
- -

When a channel is created no access rights handler is installed.

- -

Arguments

-
-
CHAN
-
The channel identifier.
-
-
-
PFUNC
-
Address of user supplied callback function. A null pointer uninstalls - the current handler. The following arguments are passed by value - to the supplied callback handler. -
typedef struct ca_access_rights {
-    unsigned    read_access:1;
-    unsigned    write_access:1;
-} caar;
-
-/* arguments passed to user access rights handlers */
-struct  access_rights_handler_args {
-    chanId  chid;   /* channel id */
-    caar    ar;     /* new access rights state */
-};
-
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ca_field_type()

-
#include <cadef.h>
-chtype ca_field_type ( CHID );
- -

Description

- -

Return the native type in the server of the process variable.

- -

Arguments

-
-
CHID
-
channel identifier
-
- -

Returns

-
-
TYPE
-
The data type code will be a member of the set of DBF_XXXX in - db_access.h. The constant TYPENOTCONN is returned if the channel is - disconnected.
-
- -

ca_element_count()

-
#include <cadef.h>
-unsigned ca_element_count ( CHID );
- -

Description

- -

Return the maximum array element count in the server for the specified IO -channel.

- -

Arguments

-
-
CHID
-
channel identifier
-
- -

Returns

-
-
COUNT
-
The maximum array element count in the server. An element count of - zero is returned if the channel is disconnected.
-
- -

ca_name()

-
#include <cadef.h>
-char * ca_name ( CHID );
- -

Description

- -

Return the name provided when the supplied channel id was created.

- -

Arguments

-
-
CHID
-
channel identifier
-
- -

Returns

-
-
PNAME
-
The channel name. The string returned is valid as long as the channel - specified exists.
-
- -

ca_set_puser()

-
#include <cadef.h>
-void ca_set_puser ( chid CHID, void *PUSER );
- -

Description

- -

Set a user private void pointer variable retained with each channel for use -at the users discretion.

- -

Arguments

-
-
CHID
-
channel identifier
-
-
-
PUSER
-
user private void pointer
-
- -

ca_puser()

-
#include <cadef.h>
-void * ca_puser ( CHID );
- -

Description

- -

Return a user private void pointer variable retained with each channel for -use at the users discretion.

- -

Arguments

-
-
CHID
-
channel identifier
-
- -

Returns

-
-
PUSER
-
user private pointer
-
- -

ca_state()

-
#include <cadef.h>
-enum channel_state {
-    cs_never_conn, /* valid chid, server not found or unavailable */
-    cs_prev_conn,  /* valid chid, previously connected to server */
-    cs_conn,       /* valid chid, connected to server */
-    cs_closed };   /* channel deleted by user */
-enum channel_state ca_state ( CHID );
- -

Description

- -

Returns an enumerated type indicating the current state of the specified IO -channel.

- -

Arguments

-
-
CHID
-
channel identifier
-
- -

Returns

-
-
STATE
-
the connection state
-
- -

ca_message()

-
#include <cadef.h>
-const char * ca_message ( STATUS );
- -

Description

- -

return a message character string corresponding to a user specified CA -status code.

- -

Arguments

-
-
STATUS
-
a CA status code
-
- -

Returns

-
-
STRING
-
the corresponding error message string
-
- -

ca_host_name()

-
#include <cadef.h>
-char * ca_host_name ( CHID );
- -

Description

- -

Return a character string which contains the name of the host to which a -channel is currently connected.

- -

Arguments

-
-
CHID
-
the channel identifier
-
- -

Returns

-
-
STRING
-
The process variable server's host name. If the channel is disconnected - the string "<disconnected>" is returned.
-
- -

ca_read_access()

-
#include <cadef.h>
-int ca_read_access ( CHID );
- -

Description

- -

Returns boolean true if the client currently has read access to the -specified channel and boolean false otherwise.

- -

Arguments

-
-
CHID
-
the channel identifier
-
- -

Returns

-
-
STRING
-
boolean true if the client currently has read access to the specified - channel and boolean false otherwise
-
- -

ca_write_access()

-
#include <cadef.h>
-int ca_write_access ( CHID );
- -

Description

- -

Returns boolean true if the client currently has write access to the -specified channel and boolean false otherwise.

- -

Arguments

-
-
CHID
-
the channel identifier
-
- -

Returns

-
-
STRING
-
boolean true if the client currently has write access to the specified - channel and boolean false otherwise
-
- -

dbr_size[]

-
#include <db_access.h>
-extern unsigned dbr_size[/* TYPE */];
- -

Description

- -

An array that returns the size in bytes for a DBR_XXXX type.

- -

Arguments

-
-
TYPE
-
The data type code. A member of the set of DBF_XXXX in db_access.h.
-
- -

Returns

-
-
SIZE
-
the size in bytes of the specified type
-
- -

dbr_size_n()

-
#include <db_access.h>
-unsigned dbr_size_n ( TYPE, COUNT );
- -

Description

- -

Returns the size in bytes for a DBR_XXXX type with COUNT elements. If the -DBR type is a structure then the value field is the last field in the -structure. If COUNT is greater than one then COUNT-1 elements are appended to -the end of the structure so that they can be addressed as an array through a -pointer to the value field.

- -

Arguments

-
-
TYPE
-
The data type
-
-
-
COUNT
-
The element count
-
- -

Returns

-
-
SIZE
-
the size in bytes of the specified type with the specified number of - elements
-
- -

dbr_value_size[]

-
#include <db_access.h>
-extern unsigned dbr_value_size[/* TYPE */];
- -

Description

- -

The array dbr_value_size[TYPE] returns the size in bytes for the value -stored in a DBR_XXXX type. If the type is a structure the size of the value -field is returned otherwise the size of the type is returned.

- -

Arguments

-
-
TYPE
-
The data type code. A member of the set of DBF_XXXX in db_access.h.
-
- -

Returns

-
-
SIZE
-
the size in bytes of the value field if the type is a structure and - otherwise the size in bytes of the type
-
- -

dbr_type_to_text()

-
#include <db_access.h>
-const char * dbr_type_text ( chtype TYPE );
- -

Description

- -

Returns a constant null terminated string corresponding to the specified dbr -type.

- -

Arguments

-
-
TYPE
-
The data type code. A member of the set of DBR_XXXX in db_access.h.
-
- -

Returns

-
-
STRING
-
-
The const string corresponding to the DBR_XXX type.
-
- -

ca_test_event()

-
#include <cadef.h>
- -

Description

-
void ca_test_event ( struct event_handler_args );
- -

A built-in subscription update callback handler for debugging purposes that -prints diagnostics to standard out.

- -

Examples

-
void ca_test_event (); 
-status = ca_create_subscription ( type, chid, ca_test_event, NULL, NULL ); 
-SEVCHK ( status, .... );
- -

See Also

- -

ca_create_subscription()

- -

ca_sg_create()

-
#include <cadef.h>
-int ca_sg_create ( CA_SYNC_GID *PGID );
- -

Description

- -

Create a synchronous group and return an identifier for it.

- -

A synchronous group can be used to guarantee that a set of channel access -requests have completed. Once a synchronous group has been created then channel -access get and put requests may be issued within it using -ca_sg_array_get() and ca_sg_array_put() respectively. -The routines ca_sg_block() and ca_sg_test() can be -used to block for and test for completion respectively. The routine -ca_sg_reset() is used to discard knowledge of old requests which -have timed out and in all likelihood will never be satisfied.

- -

Any number of asynchronous groups can have application requested operations -outstanding within them at any given time.

- -

Arguments

-
-
PGID
-
Pointer to a user supplied CA_SYNC_GID.
-
- -

Examples

-
CA_SYNC_GID gid; 
-status = ca_sg_create ( &gid ); 
-SEVCHK ( status, Sync group create failed );
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_ALLOCMEM - Failed, unable to allocate memory

- -

See Also

- -

ca_sg_delete()

- -

ca_sg_block()

- -

ca_sg_test()

- -

ca_sg_reset()

- -

ca_sg_array_put()

- -

ca_sg_array_get()

- -

ca_sg_delete()

-
#include <cadef.h>
-int ca_sg_delete ( CA_SYNC_GID GID );
- -

Description

- -

Deletes a synchronous group.

- -

Arguments

-
-
GID
-
Identifier of the synchronous group to be deleted.
-
- -

Examples

-
CA_SYNC_GID gid; 
-status = ca_sg_delete ( gid ); 
-SEVCHK ( status, Sync group delete failed );
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADSYNCGRP - Invalid synchronous group

- -

See Also

- -

ca_sg_create()

- -

ca_sg_block()

-
#include <cadef.h>
-int ca_sg_block ( CA_SYNC_GID GID, double TIMEOUT );
- -

Description

- -

Flushes the send buffer and then waits until outstanding requests complete -or the specified time out expires. At this time outstanding requests include -calls to ca_sg_array_get() and calls to ca_sg_array_put(). If ECA_TIMEOUT is -returned then failure must be assumed for all outstanding queries. Operations -can be reissued followed by another ca_sg_block(). This routine will only block -on outstanding queries issued after the last call to ca_sg_block(), -ca_sg_reset(), or ca_sg_create() whichever occurs later in time. If no queries -are outstanding then ca_sg_block() will return immediately without processing -any pending channel access activities.

- -

Values written into your program's variables by a channel access synchronous -group request should not be referenced by your program until ECA_NORMAL has -been received from ca_sg_block(). This routine will process pending channel -access background activity while it is waiting.

- -

Arguments

-
-
GID
-
Identifier of the synchronous group.
-
TIMEOUT
-
The duration to block in this routine in seconds. A timeout of zero - seconds blocks forever.
-
- -

Examples

-
CA_SYNC_GID gid;
-status = ca_sg_block(gid, 0.0);
-SEVCHK(status, Sync group block failed);
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_TIMEOUT - The operation timed out

- -

ECA_EVDISALLOW - Function inappropriate for use within an event handler

- -

ECA_BADSYNCGRP - Invalid synchronous group

- -

See Also

- -

ca_sg_test()

- -

ca_sg_reset()

- -

ca_sg_test()

-
#include <cadef.h>
-int ca_sg_test ( CA_SYNC_GID GID )
- -

Description

- -

Test to see if all requests made within a synchronous group have -completed.

- -

Arguments

-
-
GID
-
Identifier of the synchronous group.
-
- -

Description

- -

Test to see if all requests made within a synchronous group have -completed.

- -

Examples

-
CA_SYNC_GID gid;
-status = ca_sg_test ( gid );
- -

Returns

- -

ECA_IODONE - IO operations completed

- -

ECA_IOINPROGRESS - Some IO operations still in progress

- -

ca_sg_reset()

-
#include <cadef.h>
-int ca_sg_reset ( CA_SYNC_GID GID )
- -

Description

- -

Reset the number of outstanding requests within the specified synchronous -group to zero so that ca_sg_test() will return ECA_IODONE and ca_sg_block() -will not block unless additional subsequent requests are made.

- -

Arguments

-
-
GID
-
Identifier of the synchronous group.
-
- -

Examples

-
CA_SYNC_GID gid; 
-status = ca_sg_reset(gid);
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADSYNCGRP - Invalid synchronous group

- -

ca_sg_array_put()

-
#include <cadef.h>
-int ca_sg_put ( CA_SYNC_GID GID, chtype TYPE,
-        chid CHID, void *PVALUE );
-int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE, 
-        unsigned long COUNT, chid CHID, void *PVALUE );
- -

Write a value, or array of values, to a channel and increment the outstanding -request count of a synchronous group. The ca_sg_put() and -ca_sg_array_put() functionality is implemented using -ca_array_put_callback().

- -

All remote operation requests such as the above are accumulated (buffered) -and not forwarded to the server until one of ca_flush_io(), -ca_pend_io(), ca_pend_event(), or -ca_sg_block() are called. This allows several requests to be -efficiently sent in one message.

- -

If a connection is lost and then resumed outstanding puts are not -reissued.

- -

Arguments

-
-
GID
-
synchronous group identifier
-
-
-
TYPE
-
The type of supplied value. Conversion will occur if it does not match - the native type. Specify one from the set of DBR_XXXX in db_access.h.
-
-
-
COUNT
-
element count to be written to the specified channel - must match the - array pointed to by PVALUE
-
-
-
CHID
-
channel identifier
-
-
-
PVALUE
-
A pointer to an application supplied buffer containing the value or - array of values returned
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADSYNCGRP - Invalid synchronous group

- -

ECA_BADCHID - Corrupted CHID

- -

ECA_BADTYPE - Invalid DBR_XXXX type

- -

ECA_BADCOUNT - Requested count larger than native element count

- -

ECA_STRTOBIG - Unusually large string supplied

- -

ECA_PUTFAIL - A local database put failed

- -

See Also

- -

ca_flush_io()

- -

ca_sg_array_get()

-
#include <cadef.h>
-int ca_sg_get ( CA_SYNC_GID GID, chtype TYPE,
-        chid CHID, void *PVALUE );
-int ca_sg_array_get ( CA_SYNC_GID GID,
-        chtype TYPE, unsigned long COUNT,
-        chid CHID, void *PVALUE );
- -

Description

- -

Read a value from a channel and increment the outstanding request count of a -synchronous group. The ca_sg_get() and -ca_sg_array_get() functionality is implemented using -ca_array_get_callback().

- -

The values written into your program's variables by ca_sg_get() -or ca_sg_array_get() should not be referenced by your program until -ECA_NORMAL has been received from ca_sg_block(), or until -ca_sg_test() returns ECA_IODONE.

- -

All remote operation requests such as the above are accumulated (buffered) -and not forwarded to the server until one of ca_flush_io(), -ca_pend_io(), ca_pend_event(), or -ca_sg_block() are called. This allows several requests to be -efficiently sent in one message.

- -

If a connection is lost and then resumed outstanding gets are not -reissued.

- -

Arguments

-
-
GID
-
Identifier of the synchronous group.
-
-
-
TYPE
-
External type of returned value. Conversion will occur if this does not - match native type. Specify one from the set of DBR_XXXX in - db_access.h
-
-
-
COUNT
-
Element count to be read from the specified channel. It must match the - array pointed to by PVALUE.
-
-
-
CHID
-
channel identifier
-
-
-
PVALUE
-
Pointer to application supplied buffer that is to contain the value or - array of values to be returned
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_BADSYNCGRP - Invalid synchronous group

- -

ECA_BADCHID - Corrupted CHID

- -

ECA_BADCOUNT - Requested count larger than native element count

- -

ECA_BADTYPE - Invalid DBR_XXXX type

- -

ECA_GETFAIL - A local database get failed

- -

See Also

- -

ca_pend_io()

- -

ca_flush_io()

- -

ca_get_callback()

- -

ca_client_status()

-
int ca_client_status ( unsigned level );
-int ca_context_status ( struct ca_client_context *CONTEXT, 
-       unsigned LEVEL );
- -

Description

- -

Prints information about the client context including, at higher interest -levels, status for each channel. Lacking a CA context pointer, -ca_client_status() prints information about the calling threads CA context.

- -

Arguments

-
-
CONTEXT
-
A pointer to the CA context to examine.
-
LEVEL
-
The interest level. Increasing level produces increasing detail.
-
- -

ca_current_context()

-
struct ca_client_context * ca_current_context ();
- -

Description

- -

Returns a pointer to the current thread's CA context. If none then null is -returned.

- -

See Also

- -

ca_attach_context()

- -

ca_detach_context()

- -

ca_context_create()

- -

ca_context_destroy()

- -

ca_attach_context()

-
int ca_attach_context (struct ca_client_context *CONTEXT);
- -

Description

- -

The calling thread becomes a member of the specified CA context. If -ca_disable_preemptive_callback is specified when -ca_context_create() is called (or if ca_task_initialize() is called) then -additional threads are not allowed to join the CA context because -allowing other threads to join implies that CA callbacks will be called -preemptively from more than one thread.

- -

Arguments

-
-
CONTEXT
-
A pointer to the CA context to join with.
-
- -

Returns

- -

ECA_NORMAL - Normal successful completion

- -

ECA_NOTTHREADED - Context is not preemptive so cannot be joined

- -

ECA_ISATTACHED - Thread already attached to a CA context

- -

See Also

- -

ca_current_context()

- -

ca_detach_context()

- -

ca_context_create()

- -

ca_context_destroy()

- -

ca_detach_context()

-
void ca_detach_context();
- -

Description

- -

Detach from any CA context currently attached to the calling thread. This -does not cleanup or shutdown any currently attached CA context (for -that use ca_context_destroy()).

- -

See Also

- -

ca_current_context()

- -

ca_attach_context()

- -

ca_context_create()

- -

ca_context_destroy()

- -

ca_dump_dbr()

-
void ca_dump_dbr (chtype TYPE, unsigned COUNT, const void * PDBR);
- -

Description

- -

Dumps the specified dbr data type to standard out.

- -

Arguments

-
-
TYPE
-
The data type (from the DBR_XXX set described in db_access.h).
-
COUNT
-
The array element count
-
PDBR
-
A pointer to data of the specified count and number.
-
-
- -

Return Codes

-
-
ECA_NORMAL
-
Normal successful completion
-
ECA_ALLOCMEM
-
Unable to allocate additional dynamic memory
-
ECA_TOLARGE
-
The requested data transfer is greater than available memory or - EPICS_CA_MAX_ARRAY_BYTES
-
ECA_BADTYPE
-
The data type specified is invalid
-
ECA_BADSTR
-
Invalid string
-
ECA_BADCHID
-
Invalid channel identifier
-
ECA_BADCOUNT
-
Invalid element count requested
-
ECA_PUTFAIL
-
Channel write request failed
-
ECA_GETFAIL
-
Channel read request failed
-
ECA_ADDFAIL
-
unable to install subscription request
-
ECA_TIMEOUT
-
User specified timeout on IO operation expired
-
ECA_EVDISALLOW
-
function called was inappropriate for use within a callback - function
-
ECA_IODONE
-
IO operations have completed
-
ECA_IOINPROGRESS
-
IO operations are in progress
-
ECA_BADSYNCGRP
-
Invalid synchronous group identifier
-
ECA_NORDACCESS
-
Read access denied
-
ECA_NOWTACCESS
-
Write access denied
-
ECA_DISCONN
-
Virtual circuit disconnect"
-
ECA_DBLCHNL
-
Identical process variable name on multiple servers
-
ECA_EVDISALLOW
-
Request inappropriate within subscription (monitor) update callback
-
ECA_BADMONID
-
Bad event subscription (monitor) identifier
-
ECA_BADMASK
-
Invalid event selection mask
-
ECA_PUTCBINPROG
-
Put callback timed out
-
ECA_PUTCBINPROG
-
Put callback timed out
-
ECA_ANACHRONISM
-
Requested feature is no longer supported
-
ECA_NOSEARCHADDR
-
Empty PV search address list
-
ECA_NOCONVERT
-
No reasonable data conversion between client and server types
-
ECA_BADFUNCPTR
-
Invalid function pointer
-
ECA_ISATTACHED
-
Thread is already attached to a client context
-
ECA_UNAVAILINSERV
-
Not supported by attached service
-
ECA_CHANDESTROY
-
User destroyed channel
-
ECA_BADPRIORITY
-
Invalid channel priority
-
ECA_NOTTHREADED
-
Preemptive callback not enabled - additional threads may not join - context
-
ECA_16KARRAYCLIENT
-
Client's protocol revision does not support transfers exceeding 16k - bytes
-
- -

- - diff --git a/src/ca/client/Makefile b/src/ca/client/Makefile deleted file mode 100644 index 358552b46..000000000 --- a/src/ca/client/Makefile +++ /dev/null @@ -1,117 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -TOP=../../.. - -include $(TOP)/configure/CONFIG - -HTMLS += CAref.html - -# -# includes to install from this subproject -# -INC += cadef.h -INC += caerr.h -INC += caeventmask.h -INC += caProto.h -INC += db_access.h -INC += addrList.h -INC += cacIO.h -INC += caDiagnostics.h - -LIBSRCS += cac.cpp -LIBSRCS += cacChannel.cpp -LIBSRCS += cacChannelNotify.cpp -LIBSRCS += cacContextNotify.cpp -LIBSRCS += cacReadNotify.cpp -LIBSRCS += cacWriteNotify.cpp -LIBSRCS += cacStateNotify.cpp -LIBSRCS += access.cpp -LIBSRCS += iocinf.cpp -LIBSRCS += convert.cpp -LIBSRCS += test_event.cpp -LIBSRCS += repeater.cpp -LIBSRCS += searchTimer.cpp -LIBSRCS += disconnectGovernorTimer.cpp -LIBSRCS += repeaterSubscribeTimer.cpp -LIBSRCS += baseNMIU.cpp -LIBSRCS += nciu.cpp -LIBSRCS += netiiu.cpp -LIBSRCS += udpiiu.cpp -LIBSRCS += tcpiiu.cpp -LIBSRCS += noopiiu.cpp -LIBSRCS += netReadNotifyIO.cpp -LIBSRCS += netWriteNotifyIO.cpp -LIBSRCS += netSubscription.cpp -LIBSRCS += tcpSendWatchdog.cpp -LIBSRCS += tcpRecvWatchdog.cpp -LIBSRCS += bhe.cpp -LIBSRCS += ca_client_context.cpp -LIBSRCS += oldChannelNotify.cpp -LIBSRCS += oldSubscription.cpp -LIBSRCS += getCallback.cpp -LIBSRCS += getCopy.cpp -LIBSRCS += putCallback.cpp -LIBSRCS += syncgrp.cpp -LIBSRCS += CASG.cpp -LIBSRCS += syncGroupNotify.cpp -LIBSRCS += syncGroupReadNotify.cpp -LIBSRCS += syncGroupWriteNotify.cpp -LIBSRCS += localHostName.cpp -LIBSRCS += comQueRecv.cpp -LIBSRCS += comQueSend.cpp -LIBSRCS += comBuf.cpp -LIBSRCS += hostNameCache.cpp -LIBSRCS += msgForMultiplyDefinedPV.cpp - -LIBRARY=ca - -ca_RCS = ca.rc - -ca_LIBS = Com - -ca_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 - -# libs needed for PROD and TESTPRODUCT -PROD_LIBS = ca Com -# needed when its an object library build -PROD_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 - -PROD_DEFAULT += caRepeater catime acctst caConnTest casw caEventRate -PROD_vxWorks = -nil- -PROD_RTEMS = -nil- -PROD_iOS = -nil- - -OBJS_vxWorks = catime acctst caConnTest casw caEventRate acctstRegister - -caRepeater_SRCS = caRepeater.cpp -catime_SRCS = catimeMain.c catime.c -acctst_SRCS = acctstMain.c acctst.c -caEventRate_SRCS = caEventRateMain.cpp caEventRate.cpp -casw_SRCS = casw.cpp -caConnTest_SRCS = caConnTestMain.cpp caConnTest.cpp - -casw_SYS_LIBS_solaris = socket - -SCRIPTS_HOST = S99caRepeater -SCRIPTS_Linux = caRepeater.service - -EXPAND += S99caRepeater@ -EXPAND += caRepeater.service@ -EXPAND_VARS = INSTALL_BIN=$(abspath $(INSTALL_BIN)) - -SRC_DIRS += $(TOP)/src/ca/client/test -PROD_HOST += ca_test -ca_test_SRCS = ca_test_main.c ca_test.c -ca_test_LIBS = ca Com -ca_test_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 - -OBJS_vxWorks += ca_test - -include $(TOP)/configure/RULES diff --git a/src/ca/client/S99caRepeater@ b/src/ca/client/S99caRepeater@ deleted file mode 100644 index aabefb72c..000000000 --- a/src/ca/client/S99caRepeater@ +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -# -# System-V init script for the EPICS CA Repeater. -# - -INSTALL_BIN=@INSTALL_BIN@ - -# To change the default values for the EPICS environment parameters, -# uncomment and modify the relevant lines below. These are the only -# EPICS environment variables that the CA Repeater makes use of. - -# EPICS_CA_REPEATER_PORT="5065" export EPICS_CA_REPEATER_PORT - -if [ $1 = "start" ]; then - if [ -x $INSTALL_BIN/caRepeater ]; then - echo "Starting EPICS CA Repeater " - $INSTALL_BIN/caRepeater & - fi -else - if [ $1 = "stop" ]; then - pid=`ps -e | sed -ne '/caRepeat/s/^ *\([1-9][0-9]*\).*$/\1/p'` - if [ "${pid}" != "" ]; then - echo "Stopping EPICS CA Repeater " - kill ${pid} - fi - fi -fi - diff --git a/src/ca/client/SearchDest.h b/src/ca/client/SearchDest.h deleted file mode 100644 index c22be7c87..000000000 --- a/src/ca/client/SearchDest.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef SearchDest_h -#define SearchDest_h - -#include -#include -#include -#include "caProto.h" - -class channelNode; -class epicsMutex; -template < class T > class epicsGuard; - -struct SearchDest : - public tsDLNode < SearchDest > { - virtual ~SearchDest () {}; - struct Callback { - virtual ~Callback () {}; - virtual void notify ( - const caHdr & msg, const void * pPayload, - const osiSockAddr & addr, const epicsTime & ) = 0; - virtual void show ( - epicsGuard < epicsMutex > &, unsigned level ) const = 0; - }; - virtual void searchRequest ( epicsGuard < epicsMutex > &, - const char * pbuf, size_t len ) = 0; - virtual void show ( epicsGuard < epicsMutex > &, unsigned level ) const = 0; -}; - -#endif // SearchDest_h diff --git a/src/ca/client/access.cpp b/src/ca/client/access.cpp deleted file mode 100644 index 8c1f9901e..000000000 --- a/src/ca/client/access.cpp +++ /dev/null @@ -1,1118 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeffrey O. Hill - * - */ - -#include -#include - -#include "dbDefs.h" -#include "epicsExit.h" - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - - -/* - * allocate error message string array - * here so I can use sizeof - */ -#define CA_ERROR_GLBLSOURCE - -/* - * allocate header version strings here - */ -#define CAC_VERSION_GLOBAL - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "oldAccess.h" -#include "cac.h" - -epicsThreadPrivateId caClientContextId; - -const char * ca_message_text [] -= -{ -"Normal successful completion", -"Maximum simultaneous IOC connections exceeded", -"Unknown internet host", -"Unknown internet service", -"Unable to allocate a new socket", - -"Unable to connect to internet host or service", -"Unable to allocate additional dynamic memory", -"Unknown IO channel", -"Record field specified inappropriate for channel specified", -"The requested data transfer is greater than available memory or EPICS_CA_MAX_ARRAY_BYTES", - -"User specified timeout on IO operation expired", -"Sorry, that feature is planned but not supported at this time", -"The supplied string is unusually large", -"The request was ignored because the specified channel is disconnected", -"The data type specifed is invalid", - -"Remote Channel not found", -"Unable to locate all user specified channels", -"Channel Access Internal Failure", -"The requested local DB operation failed", -"Channel read request failed", - -"Channel write request failed", -"Channel subscription request failed", -"Invalid element count requested", -"Invalid string", -"Virtual circuit disconnect", - -"Identical process variable names on multiple servers", -"Request inappropriate within subscription (monitor) update callback", -"Database value get for that channel failed during channel search", -"Unable to initialize without the vxWorks VX_FP_TASK task option set", -"Event queue overflow has prevented first pass event after event add", - -"Bad event subscription (monitor) identifier", -"Remote channel has new network address", -"New or resumed network connection", -"Specified task isnt a member of a CA context", -"Attempt to use defunct CA feature failed", - -"The supplied string is empty", -"Unable to spawn the CA repeater thread- auto reconnect will fail", -"No channel id match for search reply- search reply ignored", -"Reseting dead connection- will try to reconnect", -"Server (IOC) has fallen behind or is not responding- still waiting", - -"No internet interface with broadcast available", -"Invalid event selection mask", -"IO operations have completed", -"IO operations are in progress", -"Invalid synchronous group identifier", - -"Put callback timed out", -"Read access denied", -"Write access denied", -"Requested feature is no longer supported", -"Empty PV search address list", - -"No reasonable data conversion between client and server types", -"Invalid channel identifier", -"Invalid function pointer", -"Thread is already attached to a client context", -"Not supported by attached service", - -"User destroyed channel", -"Invalid channel priority", -"Preemptive callback not enabled - additional threads may not join context", -"Client's protocol revision does not support transfers exceeding 16k bytes", -"Virtual circuit connection sequence aborted", - -"Virtual circuit unresponsive" -}; - -static epicsThreadOnceId caClientContextIdOnce = EPICS_THREAD_ONCE_INIT; - -extern "C" void ca_client_exit_handler (void *) -{ - if ( caClientContextId ) { - epicsThreadPrivateDelete ( caClientContextId ); - caClientContextId = 0; - } -} - -// runs once only for each process -extern "C" void ca_init_client_context ( void * ) -{ - caClientContextId = epicsThreadPrivateCreate (); - if ( caClientContextId ) { - epicsAtExit ( ca_client_exit_handler,0 ); - } -} - -/* - * fetchClientContext (); - */ -int fetchClientContext ( ca_client_context **ppcac ) -{ - epicsThreadOnce ( &caClientContextIdOnce, ca_init_client_context, 0 ); - if ( caClientContextId == 0 ) { - return ECA_ALLOCMEM; - } - - int status; - *ppcac = ( ca_client_context * ) epicsThreadPrivateGet ( caClientContextId ); - if ( *ppcac ) { - status = ECA_NORMAL; - } - else { - status = ca_task_initialize (); - if ( status == ECA_NORMAL ) { - *ppcac = (ca_client_context *) epicsThreadPrivateGet ( caClientContextId ); - if ( ! *ppcac ) { - status = ECA_INTERNAL; - } - } - } - - return status; -} - -/* - * ca_task_initialize () - */ -// extern "C" -int epicsShareAPI ca_task_initialize ( void ) -{ - return ca_context_create ( ca_disable_preemptive_callback ); -} - -// extern "C" -int epicsShareAPI ca_context_create ( - ca_preemptive_callback_select premptiveCallbackSelect ) -{ - ca_client_context *pcac; - - try { - epicsThreadOnce ( & caClientContextIdOnce, ca_init_client_context, 0); - if ( caClientContextId == 0 ) { - return ECA_ALLOCMEM; - } - - pcac = ( ca_client_context * ) epicsThreadPrivateGet ( caClientContextId ); - if ( pcac ) { - if ( premptiveCallbackSelect == ca_enable_preemptive_callback && - ! pcac->preemptiveCallbakIsEnabled() ) { - return ECA_NOTTHREADED; - } - return ECA_NORMAL; - } - - pcac = new ca_client_context ( - premptiveCallbackSelect == ca_enable_preemptive_callback ); - if ( ! pcac ) { - return ECA_ALLOCMEM; - } - - epicsThreadPrivateSet ( caClientContextId, (void *) pcac ); - } - catch ( ... ) { - return ECA_ALLOCMEM; - } - return ECA_NORMAL; -} - -// -// ca_modify_host_name () -// -// defunct -// -// extern "C" -int epicsShareAPI ca_modify_host_name ( const char * ) -{ - return ECA_NORMAL; -} - -// -// ca_modify_user_name() -// -// defunct -// -// extern "C" -int epicsShareAPI ca_modify_user_name ( const char * ) -{ - return ECA_NORMAL; -} - -// -// ca_context_destroy () -// -// extern "C" -void epicsShareAPI ca_context_destroy () -{ - ca_client_context *pcac; - - if ( caClientContextId != NULL ) { - pcac = (ca_client_context *) epicsThreadPrivateGet ( caClientContextId ); - if ( pcac ) { - delete pcac; - epicsThreadPrivateSet ( caClientContextId, 0 ); - } - } -} - -/* - * ca_task_exit() - * - * releases all resources alloc to a channel access client - */ -// extern "C" -int epicsShareAPI ca_task_exit () -{ - ca_context_destroy (); - return ECA_NORMAL; -} - -/* - * - * CA_BUILD_AND_CONNECT - * - * backwards compatible entry point to ca_search_and_connect() - */ -// extern "C" -int epicsShareAPI ca_build_and_connect ( const char *name_str, chtype get_type, - arrayElementCount get_count, chid * chan, void *pvalue, - caCh *conn_func, void *puser ) -{ - if ( get_type != TYPENOTCONN && pvalue != 0 && get_count != 0 ) { - return ECA_ANACHRONISM; - } - - return ca_search_and_connect ( name_str, chan, conn_func, puser ); -} - -/* - * ca_search_and_connect() - */ -// extern "C" -int epicsShareAPI ca_search_and_connect ( - const char * name_str, chid * chanptr, - caCh * conn_func, void * puser ) -{ - return ca_create_channel ( name_str, conn_func, - puser, CA_PRIORITY_DEFAULT, chanptr ); -} - -// extern "C" -int epicsShareAPI ca_create_channel ( - const char * name_str, caCh * conn_func, void * puser, - capri priority, chid * chanptr ) -{ - ca_client_context * pcac; - int caStatus = fetchClientContext ( & pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - { - CAFDHANDLER * pFunc = 0; - void * pArg = 0; - { - epicsGuard < epicsMutex > - guard ( pcac->mutex ); - if ( pcac->fdRegFuncNeedsToBeCalled ) { - pFunc = pcac->fdRegFunc; - pArg = pcac->fdRegArg; - pcac->fdRegFuncNeedsToBeCalled = false; - } - } - if ( pFunc ) { - ( *pFunc ) ( pArg, pcac->sock, true ); - } - } - - try { - epicsGuard < epicsMutex > guard ( pcac->mutex ); - oldChannelNotify * pChanNotify = - new ( pcac->oldChannelNotifyFreeList ) - oldChannelNotify ( guard, *pcac, name_str, - conn_func, puser, priority ); - // make sure that their chan pointer is set prior to - // calling connection call backs - *chanptr = pChanNotify; - pChanNotify->initiateConnect ( guard ); - // no need to worry about a connect preempting here because - // the connect sequence will not start untill initiateConnect() - // is called - } - catch ( cacChannel::badString & ) { - return ECA_BADSTR; - } - catch ( std::bad_alloc & ) { - return ECA_ALLOCMEM; - } - catch ( cacChannel::badPriority & ) { - return ECA_BADPRIORITY; - } - catch ( cacChannel::unsupportedByService & ) { - return ECA_UNAVAILINSERV; - } - catch ( std :: exception & except ) { - pcac->printFormated ( - "ca_create_channel: " - "unexpected exception was \"%s\"", - except.what () ); - return ECA_INTERNAL; - } - catch ( ... ) { - return ECA_INTERNAL; - } - - return ECA_NORMAL; -} - -/* - * ca_clear_channel () - * - * a known defect here is that there will be a - * crash if they destroy the channel after destroying - * its context - */ -// extern "C" -int epicsShareAPI ca_clear_channel ( chid pChan ) -{ - ca_client_context & cac = pChan->getClientCtx (); - { - epicsGuard < epicsMutex > guard ( cac.mutex ); - try { - pChan->eliminateExcessiveSendBacklog ( guard ); - } - catch ( cacChannel::notConnected & ) { - // intentionally ignored - } - } - if ( cac.pCallbackGuard.get() && - cac.createdByThread == epicsThreadGetIdSelf () ) { - epicsGuard < epicsMutex > guard ( cac.mutex ); - pChan->destructor ( *cac.pCallbackGuard.get(), guard ); - cac.oldChannelNotifyFreeList.release ( pChan ); - } - else { - // - // we will definately stall out here if all of the - // following are true - // - // o user creates non-preemtive mode client library context - // o user doesnt periodically call a ca function - // o user calls this function from an auxiillary thread - // - CallbackGuard cbGuard ( cac.cbMutex ); - epicsGuard < epicsMutex > guard ( cac.mutex ); - pChan->destructor ( *cac.pCallbackGuard.get(), guard ); - cac.oldChannelNotifyFreeList.release ( pChan ); - } - return ECA_NORMAL; -} - -/* - * Specify an event subroutine to be run for asynch exceptions - */ -// extern "C" -int epicsShareAPI ca_add_exception_event ( caExceptionHandler *pfunc, void *arg ) -{ - ca_client_context *pcac; - int caStatus = fetchClientContext ( &pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - pcac->changeExceptionEvent ( pfunc, arg ); - - return ECA_NORMAL; -} - -/* - * ca_add_masked_array_event - */ -int epicsShareAPI ca_add_masked_array_event ( - chtype type, arrayElementCount count, chid pChan, - caEventCallBackFunc *pCallBack, void *pCallBackArg, - ca_real, ca_real, ca_real, - evid *monixptr, long mask ) -{ - return ca_create_subscription ( type, count, pChan, mask, - pCallBack, pCallBackArg, monixptr ); -} - -/* - * ca_clear_event () - */ -int epicsShareAPI ca_clear_event ( evid pMon ) -{ - return ca_clear_subscription ( pMon ); -} - -// extern "C" -chid epicsShareAPI ca_evid_to_chid ( evid pMon ) -{ - return & pMon->channel (); -} - -// extern "C" -int epicsShareAPI ca_pend ( ca_real timeout, int early ) -{ - if ( early ) { - return ca_pend_io ( timeout ); - } - else { - return ca_pend_event ( timeout ); - } -} - -/* - * ca_pend_event () - */ -// extern "C" -int epicsShareAPI ca_pend_event ( ca_real timeout ) -{ - ca_client_context *pcac; - int status = fetchClientContext ( &pcac ); - if ( status != ECA_NORMAL ) { - return status; - } - - try { - // preserve past odd ball behavior of waiting forever when - // the delay is zero - if ( timeout == 0.0 ) { - while ( true ) { - pcac->pendEvent ( 60.0 ); - } - } - return pcac->pendEvent ( timeout ); - } - catch ( ... ) { - return ECA_INTERNAL; - } -} - -/* - * ca_pend_io () - */ -// extern "C" -int epicsShareAPI ca_pend_io ( ca_real timeout ) -{ - ca_client_context *pcac; - int status = fetchClientContext ( &pcac ); - if ( status != ECA_NORMAL ) { - return status; - } - - try { - // preserve past odd ball behavior of waiting forever when - // the delay is zero - if ( timeout == 0.0 ) { - return pcac->pendIO ( DBL_MAX ); - } - - return pcac->pendIO ( timeout ); - } - catch ( ... ) { - return ECA_INTERNAL; - } -} - -/* - * ca_flush_io () - */ -int epicsShareAPI ca_flush_io () -{ - ca_client_context * pcac; - int caStatus = fetchClientContext (&pcac); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - epicsGuard < epicsMutex > guard ( pcac->mutex ); - pcac->flush ( guard ); - - return ECA_NORMAL; -} - -/* - * CA_TEST_IO () - */ -int epicsShareAPI ca_test_io () -{ - ca_client_context *pcac; - int caStatus = fetchClientContext ( &pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - if ( pcac->ioComplete () ) { - return ECA_IODONE; - } - else{ - return ECA_IOINPROGRESS; - } -} - -/* - * CA_SIGNAL() - */ -// extern "C" -void epicsShareAPI ca_signal ( long ca_status, const char *message ) -{ - ca_signal_with_file_and_lineno ( ca_status, message, NULL, 0 ); -} - -/* - * ca_message (long ca_status) - * - * - if it is an unknown error code then it possible - * that the error string generated below - * will be overwritten before (or while) the caller - * of this routine is calling this routine - * (if they call this routine again). - */ -// extern "C" -const char * epicsShareAPI ca_message ( long ca_status ) -{ - unsigned msgNo = CA_EXTRACT_MSG_NO ( ca_status ); - - if ( msgNo < NELEMENTS (ca_message_text) ) { - return ca_message_text[msgNo]; - } - else { - return "new CA message number known only by server - see caerr.h"; - } -} - -/* - * ca_signal_with_file_and_lineno() - */ -// extern "C" -void epicsShareAPI ca_signal_with_file_and_lineno ( long ca_status, - const char *message, const char *pfilenm, int lineno ) -{ - ca_signal_formated ( ca_status, pfilenm, lineno, message ); -} - -/* - * ca_signal_formated() - */ -// extern "C" -void epicsShareAPI ca_signal_formated ( long ca_status, const char *pfilenm, - int lineno, const char *pFormat, ... ) -{ - ca_client_context *pcac; - - if ( caClientContextId ) { - pcac = ( ca_client_context * ) epicsThreadPrivateGet ( caClientContextId ); - } - else { - pcac = 0; - } - - va_list theArgs; - va_start ( theArgs, pFormat ); - if ( pcac ) { - pcac->vSignal ( ca_status, pfilenm, lineno, pFormat, theArgs ); - } - else { - fprintf ( stderr, "CA exception in thread w/o CA ctx: status=%s file=%s line=%d: \n", - ca_message ( ca_status ), pfilenm, lineno ); - if ( pFormat ) { - vfprintf ( stderr, pFormat, theArgs ); - } - } - va_end ( theArgs ); -} - -/* - * CA_ADD_FD_REGISTRATION - * - * call their function with their argument whenever - * a new fd is added or removed - * (for a manager of the select system call under UNIX) - * - */ -// extern "C" -int epicsShareAPI ca_add_fd_registration ( CAFDHANDLER * func, void * arg ) -{ - ca_client_context *pcac; - int caStatus = fetchClientContext ( &pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - pcac->registerForFileDescriptorCallBack ( func, arg ); - - return ECA_NORMAL; -} - -/* - * ca_version() - * function that returns the CA version string - */ -// extern "C" -const char * epicsShareAPI ca_version () -{ - return CA_VERSION_STRING ( CA_MINOR_PROTOCOL_REVISION ); -} - -/* - * ca_replace_printf_handler () - */ -// extern "C" -int epicsShareAPI ca_replace_printf_handler ( caPrintfFunc *ca_printf_func ) -{ - ca_client_context *pcac; - int caStatus = fetchClientContext (&pcac); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - pcac->replaceErrLogHandler ( ca_printf_func ); - - return ECA_NORMAL; -} - -/* - * ca_get_ioc_connection_count() - * - * returns the number of IOC's that CA is connected to - * (for testing purposes only) - */ -// extern "C" -unsigned epicsShareAPI ca_get_ioc_connection_count () -{ - ca_client_context * pcac; - int caStatus = fetchClientContext ( & pcac ); - if ( caStatus != ECA_NORMAL ) { - return 0u; - } - - return pcac->circuitCount (); -} - -unsigned epicsShareAPI ca_beacon_anomaly_count () -{ - ca_client_context * pcac; - int caStatus = fetchClientContext ( & pcac ); - if ( caStatus != ECA_NORMAL ) { - return 0u; - } - - return pcac->beaconAnomaliesSinceProgramStart (); -} - -// extern "C" -int epicsShareAPI ca_channel_status ( epicsThreadId /* tid */ ) -{ - ::printf ("The R3.14 EPICS OS abstraction API does not allow peeking at thread private storage of another thread.\n"); - ::printf ("Please call \"ca_client_status ( unsigned level )\" from the subsystem specific diagnostic code.\n"); - return ECA_ANACHRONISM; -} - -// extern "C" -int epicsShareAPI ca_client_status ( unsigned level ) -{ - ca_client_context *pcac; - int caStatus = fetchClientContext ( &pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - pcac->show ( level ); - return ECA_NORMAL; -} - -int epicsShareAPI ca_context_status ( ca_client_context * pcac, unsigned level ) -{ - pcac->show ( level ); - return ECA_NORMAL; -} - -/* - * ca_current_context () - * - * used when an auxillary thread needs to join a CA client context started - * by another thread - */ -// extern "C" -struct ca_client_context * epicsShareAPI ca_current_context () -{ - struct ca_client_context *pCtx; - if ( caClientContextId ) { - pCtx = ( struct ca_client_context * ) - epicsThreadPrivateGet ( caClientContextId ); - } - else { - pCtx = 0; - } - return pCtx; -} - -/* - * ca_attach_context () - * - * used when an auxillary thread needs to join a CA client context started - * by another thread - */ -// extern "C" -int epicsShareAPI ca_attach_context ( struct ca_client_context * pCtx ) -{ - ca_client_context *pcac = (ca_client_context *) epicsThreadPrivateGet ( caClientContextId ); - if ( pcac && pCtx != 0 ) { - return ECA_ISATTACHED; - } - if ( ! pCtx->preemptiveCallbakIsEnabled() ) { - return ECA_NOTTHREADED; - } - epicsThreadPrivateSet ( caClientContextId, pCtx ); - return ECA_NORMAL; -} - -void epicsShareAPI ca_detach_context () -{ - if ( caClientContextId ) { - epicsThreadPrivateSet ( caClientContextId, 0 ); - } -} - -int epicsShareAPI ca_preemtive_callback_is_enabled () -{ - ca_client_context *pcac = (ca_client_context *) epicsThreadPrivateGet ( caClientContextId ); - if ( ! pcac ) { - return 0; - } - return pcac->preemptiveCallbakIsEnabled (); -} - - -// extern "C" -void epicsShareAPI ca_self_test () -{ - ca_client_context *pcac = (ca_client_context *) epicsThreadPrivateGet ( caClientContextId ); - if ( ! pcac ) { - return; - } - pcac->selfTest (); -} - -// extern "C" -epicsShareDef const int epicsTypeToDBR_XXXX [lastEpicsType+1] = { - DBR_SHORT, /* forces conversion fronm uint8 to int16 */ - DBR_CHAR, - DBR_SHORT, - DBR_LONG, /* forces conversion fronm uint16 to int32 */ - DBR_ENUM, - DBR_LONG, - DBR_LONG, /* very large unsigned number will not map */ - DBR_FLOAT, - DBR_DOUBLE, - DBR_STRING, - DBR_STRING -}; - -// extern "C" -epicsShareDef const epicsType DBR_XXXXToEpicsType [LAST_BUFFER_TYPE+1] = { - epicsOldStringT, - epicsInt16T, - epicsFloat32T, - epicsEnum16T, - epicsUInt8T, - epicsInt32T, - epicsFloat64T, - - epicsOldStringT, - epicsInt16T, - epicsFloat32T, - epicsEnum16T, - epicsUInt8T, - epicsInt32T, - epicsFloat64T, - - epicsOldStringT, - epicsInt16T, - epicsFloat32T, - epicsEnum16T, - epicsUInt8T, - epicsInt32T, - epicsFloat64T, - - epicsOldStringT, - epicsInt16T, - epicsFloat32T, - epicsEnum16T, - epicsUInt8T, - epicsInt32T, - epicsFloat64T, - - epicsOldStringT, - epicsInt16T, - epicsFloat32T, - epicsEnum16T, - epicsUInt8T, - epicsInt32T, - epicsFloat64T, - - epicsUInt16T, - epicsUInt16T, - epicsOldStringT, - epicsOldStringT -}; - -// extern "C" -epicsShareDef const unsigned short dbr_size[LAST_BUFFER_TYPE+1] = { - sizeof(dbr_string_t), /* string max size */ - sizeof(dbr_short_t), /* short */ - sizeof(dbr_float_t), /* IEEE Float */ - sizeof(dbr_enum_t), /* item number */ - sizeof(dbr_char_t), /* character */ - - sizeof(dbr_long_t), /* long */ - sizeof(dbr_double_t), /* double */ - sizeof(struct dbr_sts_string), /* string field with status */ - sizeof(struct dbr_sts_short), /* short field with status */ - sizeof(struct dbr_sts_float), /* float field with status */ - - sizeof(struct dbr_sts_enum), /* item number with status */ - sizeof(struct dbr_sts_char), /* char field with status */ - sizeof(struct dbr_sts_long), /* long field with status */ - sizeof(struct dbr_sts_double), /* double field with time */ - sizeof(struct dbr_time_string), /* string field with time */ - - sizeof(struct dbr_time_short), /* short field with time */ - sizeof(struct dbr_time_float), /* float field with time */ - sizeof(struct dbr_time_enum), /* item number with time */ - sizeof(struct dbr_time_char), /* char field with time */ - sizeof(struct dbr_time_long), /* long field with time */ - - sizeof(struct dbr_time_double), /* double field with time */ - sizeof(struct dbr_sts_string), /* graphic string info */ - sizeof(struct dbr_gr_short), /* graphic short info */ - sizeof(struct dbr_gr_float), /* graphic float info */ - sizeof(struct dbr_gr_enum), /* graphic item info */ - - sizeof(struct dbr_gr_char), /* graphic char info */ - sizeof(struct dbr_gr_long), /* graphic long info */ - sizeof(struct dbr_gr_double), /* graphic double info */ - sizeof(struct dbr_sts_string), /* control string info */ - sizeof(struct dbr_ctrl_short), /* control short info */ - - sizeof(struct dbr_ctrl_float), /* control float info */ - sizeof(struct dbr_ctrl_enum), /* control item info */ - sizeof(struct dbr_ctrl_char), /* control char info */ - sizeof(struct dbr_ctrl_long), /* control long info */ - sizeof(struct dbr_ctrl_double), /* control double info */ - - sizeof(dbr_put_ackt_t), /* put ackt */ - sizeof(dbr_put_acks_t), /* put acks */ - sizeof(struct dbr_stsack_string),/* string field with status/ack*/ - sizeof(dbr_string_t), /* string max size */ -}; - -// extern "C" -epicsShareDef const unsigned short dbr_value_size[LAST_BUFFER_TYPE+1] = { - sizeof(dbr_string_t), /* string max size */ - sizeof(dbr_short_t), /* short */ - sizeof(dbr_float_t), /* IEEE Float */ - sizeof(dbr_enum_t), /* item number */ - sizeof(dbr_char_t), /* character */ - - sizeof(dbr_long_t), /* long */ - sizeof(dbr_double_t), /* double */ - sizeof(dbr_string_t), /* string max size */ - sizeof(dbr_short_t), /* short */ - sizeof(dbr_float_t), /* IEEE Float */ - - sizeof(dbr_enum_t), /* item number */ - sizeof(dbr_char_t), /* character */ - sizeof(dbr_long_t), /* long */ - sizeof(dbr_double_t), /* double */ - sizeof(dbr_string_t), /* string max size */ - - sizeof(dbr_short_t), /* short */ - sizeof(dbr_float_t), /* IEEE Float */ - sizeof(dbr_enum_t), /* item number */ - sizeof(dbr_char_t), /* character */ - sizeof(dbr_long_t), /* long */ - - sizeof(dbr_double_t), /* double */ - sizeof(dbr_string_t), /* string max size */ - sizeof(dbr_short_t), /* short */ - sizeof(dbr_float_t), /* IEEE Float */ - sizeof(dbr_enum_t), /* item number */ - - sizeof(dbr_char_t), /* character */ - sizeof(dbr_long_t), /* long */ - sizeof(dbr_double_t), /* double */ - sizeof(dbr_string_t), /* string max size */ - sizeof(dbr_short_t), /* short */ - - sizeof(dbr_float_t), /* IEEE Float */ - sizeof(dbr_enum_t), /* item number */ - sizeof(dbr_char_t), /* character */ - sizeof(dbr_long_t), /* long */ - sizeof(dbr_double_t), /* double */ - - sizeof(dbr_ushort_t), /* put_ackt */ - sizeof(dbr_ushort_t), /* put_acks */ - sizeof(dbr_string_t), /* string max size */ - sizeof(dbr_string_t), /* string max size */ -}; - -//extern "C" -epicsShareDef const enum dbr_value_class dbr_value_class[LAST_BUFFER_TYPE+1] = { - dbr_class_string, /* string max size */ - dbr_class_int, /* short */ - dbr_class_float, /* IEEE Float */ - dbr_class_int, /* item number */ - dbr_class_int, /* character */ - dbr_class_int, /* long */ - dbr_class_float, /* double */ - - dbr_class_string, /* string max size */ - dbr_class_int, /* short */ - dbr_class_float, /* IEEE Float */ - dbr_class_int, /* item number */ - dbr_class_int, /* character */ - dbr_class_int, /* long */ - dbr_class_float, /* double */ - - dbr_class_string, /* string max size */ - dbr_class_int, /* short */ - dbr_class_float, /* IEEE Float */ - dbr_class_int, /* item number */ - dbr_class_int, /* character */ - dbr_class_int, /* long */ - dbr_class_float, /* double */ - - dbr_class_string, /* string max size */ - dbr_class_int, /* short */ - dbr_class_float, /* IEEE Float */ - dbr_class_int, /* item number */ - dbr_class_int, /* character */ - dbr_class_int, /* long */ - dbr_class_float, /* double */ - - dbr_class_string, /* string max size */ - dbr_class_int, /* short */ - dbr_class_float, /* IEEE Float */ - dbr_class_int, /* item number */ - dbr_class_int, /* character */ - dbr_class_int, /* long */ - dbr_class_float, /* double */ - dbr_class_int, - dbr_class_int, - dbr_class_string, - dbr_class_string, /* string max size */ -}; - -// extern "C" -epicsShareDef const unsigned short dbr_value_offset[LAST_BUFFER_TYPE+1] = { - 0, /* string */ - 0, /* short */ - 0, /* IEEE Float */ - 0, /* item number */ - 0, /* character */ - 0, /* long */ - 0, /* IEEE double */ - (unsigned short) offsetof(dbr_sts_string,value[0]),/* string field with status */ - (unsigned short) offsetof(dbr_sts_short,value), /* short field with status */ - (unsigned short) offsetof(dbr_sts_float,value), /* float field with status */ - (unsigned short) offsetof(dbr_sts_enum,value), /* item number with status */ - (unsigned short) offsetof(dbr_sts_char,value), /* char field with status */ - (unsigned short) offsetof(dbr_sts_long,value), /* long field with status */ - (unsigned short) offsetof(dbr_sts_double,value), /* double field with time */ - (unsigned short) offsetof(dbr_time_string,value[0] ),/* string field with time */ - (unsigned short) offsetof(dbr_time_short,value), /* short field with time */ - (unsigned short) offsetof(dbr_time_float,value), /* float field with time */ - (unsigned short) offsetof(dbr_time_enum,value), /* item number with time */ - (unsigned short) offsetof(dbr_time_char,value), /* char field with time */ - (unsigned short) offsetof(dbr_time_long,value), /* long field with time */ - (unsigned short) offsetof(dbr_time_double,value), /* double field with time */ - (unsigned short) offsetof(dbr_sts_string,value[0]),/* graphic string info */ - (unsigned short) offsetof(dbr_gr_short,value), /* graphic short info */ - (unsigned short) offsetof(dbr_gr_float,value), /* graphic float info */ - (unsigned short) offsetof(dbr_gr_enum,value), /* graphic item info */ - (unsigned short) offsetof(dbr_gr_char,value), /* graphic char info */ - (unsigned short) offsetof(dbr_gr_long,value), /* graphic long info */ - (unsigned short) offsetof(dbr_gr_double,value), /* graphic double info */ - (unsigned short) offsetof(dbr_sts_string,value[0]),/* control string info */ - (unsigned short) offsetof(dbr_ctrl_short,value), /* control short info */ - (unsigned short) offsetof(dbr_ctrl_float,value), /* control float info */ - (unsigned short) offsetof(dbr_ctrl_enum,value), /* control item info */ - (unsigned short) offsetof(dbr_ctrl_char,value), /* control char info */ - (unsigned short) offsetof(dbr_ctrl_long,value), /* control long info */ - (unsigned short) offsetof(dbr_ctrl_double,value), /* control double info */ - 0, /* put ackt */ - 0, /* put acks */ - (unsigned short) offsetof(dbr_stsack_string,value[0]),/* string field with status */ - 0, /* string */ -}; - -// extern "C" -epicsShareDef const char *dbf_text[LAST_TYPE+3] = { - "TYPENOTCONN", - "DBF_STRING", - "DBF_SHORT", - "DBF_FLOAT", - "DBF_ENUM", - "DBF_CHAR", - "DBF_LONG", - "DBF_DOUBLE", - "DBF_NO_ACCESS" -}; - -// extern "C" -epicsShareDef const char *dbf_text_invalid = "DBF_invalid"; - -// extern "C" -epicsShareDef const short dbf_text_dim = (sizeof dbf_text)/(sizeof (char *)); - -// extern "C" -epicsShareDef const char *dbr_text[LAST_BUFFER_TYPE+1] = { - "DBR_STRING", - "DBR_SHORT", - "DBR_FLOAT", - "DBR_ENUM", - "DBR_CHAR", - "DBR_LONG", - "DBR_DOUBLE", - "DBR_STS_STRING", - "DBR_STS_SHORT", - "DBR_STS_FLOAT", - "DBR_STS_ENUM", - "DBR_STS_CHAR", - "DBR_STS_LONG", - "DBR_STS_DOUBLE", - "DBR_TIME_STRING", - "DBR_TIME_SHORT", - "DBR_TIME_FLOAT", - "DBR_TIME_ENUM", - "DBR_TIME_CHAR", - "DBR_TIME_LONG", - "DBR_TIME_DOUBLE", - "DBR_GR_STRING", - "DBR_GR_SHORT", - "DBR_GR_FLOAT", - "DBR_GR_ENUM", - "DBR_GR_CHAR", - "DBR_GR_LONG", - "DBR_GR_DOUBLE", - "DBR_CTRL_STRING", - "DBR_CTRL_SHORT", - "DBR_CTRL_FLOAT", - "DBR_CTRL_ENUM", - "DBR_CTRL_CHAR", - "DBR_CTRL_LONG", - "DBR_CTRL_DOUBLE", - "DBR_PUT_ACKT", - "DBR_PUT_ACKS", - "DBR_STSACK_STRING", - "DBR_CLASS_NAME" -}; - -// extern "C" -epicsShareDef const char *dbr_text_invalid = "DBR_invalid"; - -// extern "C" -epicsShareDef const short dbr_text_dim = (sizeof dbr_text) / (sizeof (char *)) + 1; diff --git a/src/ca/client/acctst.c b/src/ca/client/acctst.c deleted file mode 100644 index fd18ae4b1..000000000 --- a/src/ca/client/acctst.c +++ /dev/null @@ -1,3555 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * CA regression test - * Authors: - * Jeff Hill - * Murali Shankar - initial versions of verifyMultithreadSubscr - * Michael Abbott - initial versions of multiSubscrDestroyNoLateCallbackTest - * - */ - -/* - * ANSI - */ -#include -#include -#include -#include -#include - -/* - * EPICS - */ -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" -#include "epicsAssert.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsTime.h" -#include "dbDefs.h" -#include "envDefs.h" -#include "caDiagnostics.h" -#include "cadef.h" -#include "fdmgr.h" -#include "epicsExit.h" - -typedef struct appChan { - char name[64]; - chid channel; - evid subscription; - unsigned char connected; - unsigned char accessRightsHandlerInstalled; - unsigned subscriptionUpdateCount; - unsigned accessUpdateCount; - unsigned connectionUpdateCount; - unsigned getCallbackCount; -} appChan; - -unsigned subscriptionUpdateCount; -unsigned accessUpdateCount; -unsigned connectionUpdateCount; -unsigned getCallbackCount; - -static epicsTimeStamp showProgressBeginTime; - -static const double timeoutToPendIO = 1e20; - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -void showProgressBegin ( const char *pTestName, unsigned interestLevel ) -{ - - if ( interestLevel > 0 ) { - if ( interestLevel > 1 ) { - printf ( "%s ", pTestName ); - epicsTimeGetCurrent ( & showProgressBeginTime ); - } - printf ( "{" ); - } - fflush ( stdout ); -} - -void showProgressEnd ( unsigned interestLevel ) -{ - if ( interestLevel > 0 ) { - printf ( "}" ); - if ( interestLevel > 1 ) { - epicsTimeStamp showProgressEndTime; - double delay; - epicsTimeGetCurrent ( & showProgressEndTime ); - delay = epicsTimeDiffInSeconds ( &showProgressEndTime, &showProgressBeginTime ); - printf ( " %f sec\n", delay ); - } - else { - fflush ( stdout ); - } - } -} - -void showProgress ( unsigned interestLevel ) -{ - if ( interestLevel > 0 ) { - printf ( "." ); - fflush ( stdout ); - } -} - -void nUpdatesTester ( struct event_handler_args args ) -{ - if ( args.status == ECA_NORMAL ) { - unsigned *pCtr = (unsigned *) args.usr; - ( *pCtr ) ++; - } - else { - printf ( "subscription update failed for \"%s\" because \"%s\"", - ca_name ( args.chid ), ca_message ( args.status ) ); - } -} - -void monitorSubscriptionFirstUpdateTest ( const char *pName, chid chan, unsigned interestLevel ) -{ - int status; - struct dbr_ctrl_double currentVal; - double delta; - unsigned eventCount = 0u; - unsigned waitCount = 0u; - evid id; - chid chan2; - - showProgressBegin ( "monitorSubscriptionFirstUpdateTest", interestLevel ); - - /* - * verify that the first event arrives (with evid) - * and channel connected - */ - status = ca_add_event ( DBR_FLOAT, - chan, nUpdatesTester, &eventCount, &id ); - SEVCHK ( status, 0 ); - ca_flush_io (); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - while ( eventCount < 1 && waitCount++ < 100 ) { - printf ( "e" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - verify ( eventCount > 0 ); - - /* clear any knowledge of old gets */ - ca_pend_io ( 1e-5 ); - - /* verify that a ca_put() produces an update, but */ - /* this may fail if there is an unusual deadband */ - status = ca_get ( DBR_CTRL_DOUBLE, chan, ¤tVal ); - SEVCHK ( status, NULL ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, NULL ); - eventCount = 0u; - waitCount = 0u; - delta = ( currentVal.upper_ctrl_limit - currentVal.lower_ctrl_limit ) / 4.0; - if ( delta <= 0.0 ) { - delta = 100.0; - } - if ( currentVal.value + delta < currentVal.upper_ctrl_limit ) { - currentVal.value += delta; - } - else { - currentVal.value -= delta; - } - status = ca_put ( DBR_DOUBLE, chan, ¤tVal.value ); - SEVCHK ( status, NULL ); - ca_flush_io (); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - while ( eventCount < 1 && waitCount++ < 100 ) { - printf ( "p" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - verify ( eventCount > 0 ); - - status = ca_clear_event ( id ); - SEVCHK (status, 0); - - /* - * verify that the first event arrives (w/o evid) - * and when channel initially disconnected - */ - eventCount = 0u; - waitCount = 0u; - status = ca_search ( pName, &chan2 ); - SEVCHK ( status, 0 ); - status = ca_add_event ( DBR_FLOAT, chan2, - nUpdatesTester, &eventCount, 0 ); - SEVCHK ( status, 0 ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK (status, 0); - epicsThreadSleep ( 0.1 ); - ca_poll (); - while ( eventCount < 1 && waitCount++ < 100 ) { - printf ( "w" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - verify ( eventCount > 0 ); - - /* verify that a ca_put() produces an update, but */ - /* this may fail if there is an unusual deadband */ - status = ca_get ( DBR_CTRL_DOUBLE, chan2, ¤tVal ); - SEVCHK ( status, NULL ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, NULL ); - eventCount = 0u; - waitCount = 0u; - delta = ( currentVal.upper_ctrl_limit - currentVal.lower_ctrl_limit ) / 4.0; - if ( delta <= 0.0 ) { - delta = 100.0; - } - if ( currentVal.value + delta < currentVal.upper_ctrl_limit ) { - currentVal.value += delta; - } - else { - currentVal.value -= delta; - } - status = ca_put ( DBR_DOUBLE, chan2, ¤tVal.value ); - SEVCHK ( status, NULL ); - ca_flush_io (); - epicsThreadSleep ( 0.1 ); - ca_poll (); - while ( eventCount < 1 && waitCount++ < 100 ) { - printf ( "t" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - verify ( eventCount > 0 ); - - /* clean up */ - status = ca_clear_channel ( chan2 ); - SEVCHK ( status, 0 ); - - showProgressEnd ( interestLevel ); -} - -void ioTesterGet ( struct event_handler_args args ) -{ - if ( args.status == ECA_NORMAL ) { - unsigned *pCtr = (unsigned *) args.usr; - ( *pCtr ) ++; - } - else { - printf("get call back failed for \"%s\" because \"%s\"", - ca_name ( args.chid ), ca_message ( args.status ) ); - } -} - -void ioTesterEvent ( struct event_handler_args args ) -{ - if ( args.status == ECA_NORMAL ) { - int status; - status = ca_get_callback ( DBR_STS_STRING, args.chid, ioTesterGet, args.usr ); - SEVCHK ( status, 0 ); - } - else { - printf ( "subscription update failed for \"%s\" because \"%s\"", - ca_name ( args.chid ), ca_message ( args.status ) ); - } -} - -void verifyMonitorSubscriptionFlushIO ( chid chan, unsigned interestLevel ) -{ - int status; - unsigned eventCount = 0u; - unsigned waitCount = 0u; - evid id; - - showProgressBegin ( "verifyMonitorSubscriptionFlushIO", interestLevel ); - - /* - * verify that the first event arrives - */ - status = ca_add_event ( DBR_FLOAT, - chan, nUpdatesTester, &eventCount, &id ); - SEVCHK (status, 0); - ca_flush_io (); - epicsThreadSleep ( 0.1 ); - ca_poll (); - while ( eventCount < 1 && waitCount++ < 100 ) { - printf ( "-" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - verify ( eventCount > 0 ); - status = ca_clear_event ( id ); - SEVCHK (status, 0); - - showProgressEnd ( interestLevel ); -} - -void accessRightsStateChange ( struct access_rights_handler_args args ) -{ - appChan *pChan = (appChan *) ca_puser ( args.chid ); - - verify ( pChan->channel == args.chid ); - verify ( args.ar.read_access == ca_read_access ( args.chid ) ); - verify ( args.ar.write_access == ca_write_access ( args.chid ) ); - accessUpdateCount++; - pChan->accessUpdateCount++; -} - -void getCallbackStateChange ( struct event_handler_args args ) -{ - appChan *pChan = (appChan *) args.usr; - - verify ( pChan->channel == args.chid ); - verify ( pChan->connected ); - if ( args.status != ECA_NORMAL ) { - printf ( "getCallbackStateChange abnormal status was \"%s\"\n", - ca_message ( args.status ) ); - verify ( args.status == ECA_NORMAL ); - } - - getCallbackCount++; - pChan->getCallbackCount++; -} - -void connectionStateChange ( struct connection_handler_args args ) -{ - int status; - - appChan *pChan = (appChan *) ca_puser ( args.chid ); - - verify ( pChan->channel == args.chid ); - - if ( args.op == CA_OP_CONN_UP ) { - if ( pChan->accessRightsHandlerInstalled ) { - verify ( pChan->accessUpdateCount > 0u ); - } - verify ( ! pChan->connected ); - pChan->connected = 1; - status = ca_get_callback ( DBR_STS_STRING, args.chid, getCallbackStateChange, pChan ); - SEVCHK (status, 0); - } - else if ( args.op == CA_OP_CONN_DOWN ) { - verify ( pChan->connected ); - pChan->connected = 0u; - verify ( ! ca_read_access ( args.chid ) ); - verify ( ! ca_write_access ( args.chid ) ); - } - else { - verify ( 0 ); - } - pChan->connectionUpdateCount++; - connectionUpdateCount++; -} - -void subscriptionStateChange ( struct event_handler_args args ) -{ - struct dbr_sts_string * pdbrgs = ( struct dbr_sts_string * ) args.dbr; - appChan *pChan = (appChan *) args.usr; - - verify ( args.status == ECA_NORMAL ); - verify ( pChan->channel == args.chid ); - verify ( pChan->connected ); - verify ( args.type == DBR_STS_STRING ); - verify ( strlen ( pdbrgs->value ) <= MAX_STRING_SIZE ); - pChan->subscriptionUpdateCount++; - subscriptionUpdateCount++; -} - -void noopSubscriptionStateChange ( struct event_handler_args args ) -{ - if ( args.status != ECA_NORMAL ) { - printf ( "noopSubscriptionStateChange: subscription update failed for \"%s\" because \"%s\"", - ca_name ( args.chid ), ca_message ( args.status ) ); - } -} - -/* - * verifyConnectionHandlerConnect () - * - * 1) verify that connection handler runs during connect - * - * 2) verify that access rights handler runs during connect - * - * 3) verify that get call back runs from connection handler - * (and that they are not required to flush in the connection handler) - * - * 4) verify that first event callback arrives after connect - * - * 5) verify subscription can be cleared before channel is cleared - * - * 6) verify subscription can be cleared by clearing the channel - * - * 7) verify that a nill access rights handler can be installed - */ -void verifyConnectionHandlerConnect ( appChan *pChans, unsigned chanCount, - unsigned repetitionCount, unsigned interestLevel ) -{ - int status; - unsigned i, j; - - showProgressBegin ( "verifyConnectionHandlerConnect", interestLevel ); - - for ( i = 0; i < repetitionCount; i++ ) { - subscriptionUpdateCount = 0u; - accessUpdateCount = 0u; - connectionUpdateCount = 0u; - getCallbackCount = 0u; - - for ( j = 0u; j < chanCount; j++ ) { - - pChans[j].subscriptionUpdateCount = 0u; - pChans[j].accessUpdateCount = 0u; - pChans[j].accessRightsHandlerInstalled = 0; - pChans[j].connectionUpdateCount = 0u; - pChans[j].getCallbackCount = 0u; - pChans[j].connected = 0u; - - status = ca_search_and_connect ( pChans[j].name, - &pChans[j].channel, connectionStateChange, &pChans[j] ); - SEVCHK ( status, NULL ); - - status = ca_replace_access_rights_event ( - pChans[j].channel, accessRightsStateChange ); - SEVCHK ( status, NULL ); - pChans[j].accessRightsHandlerInstalled = 1; - - status = ca_add_event ( DBR_STS_STRING, pChans[j].channel, - subscriptionStateChange, &pChans[j], &pChans[j].subscription ); - SEVCHK ( status, NULL ); - - verify ( ca_test_io () == ECA_IODONE ); - } - - ca_flush_io (); - - showProgress ( interestLevel ); - - while ( connectionUpdateCount < chanCount || - getCallbackCount < chanCount ) { - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - - for ( j = 0u; j < chanCount; j++ ) { - verify ( pChans[j].getCallbackCount == 1u); - verify ( pChans[j].connectionUpdateCount > 0 ); - if ( pChans[j].connectionUpdateCount > 1u ) { - printf ("Unusual connection activity count = %u on channel %s?\n", - pChans[j].connectionUpdateCount, pChans[j].name ); - } - verify ( pChans[j].accessUpdateCount > 0 ); - if ( pChans[j].accessUpdateCount > 1u ) { - printf ("Unusual access rights activity count = %u on channel %s?\n", - pChans[j].connectionUpdateCount, pChans[j].name ); - } - } - - ca_self_test (); - - showProgress ( interestLevel ); - - for ( j = 0u; j < chanCount; j += 2 ) { - status = ca_clear_event ( pChans[j].subscription ); - SEVCHK ( status, NULL ); - } - - ca_self_test (); - - showProgress ( interestLevel ); - - for ( j = 0u; j < chanCount; j++ ) { - status = ca_replace_access_rights_event ( - pChans[j].channel, 0 ); - SEVCHK ( status, NULL ); - } - - for ( j = 0u; j < chanCount; j++ ) { - status = ca_clear_channel ( pChans[j].channel ); - SEVCHK ( status, NULL ); - } - - ca_self_test (); - - showProgress ( interestLevel ); - - } - showProgressEnd ( interestLevel ); -} - -/* - * verifyBlockingConnect () - * - * 1) verify that we dont print a disconnect message when - * we delete the last channel - * - * 2) verify that we delete the connection to the IOC - * when the last channel is deleted. - * - * 3) verify channel connection state variables - * - * 4) verify ca_test_io () and ca_pend_io () work with - * channels w/o connection handlers - * - * 5) verify that the pending IO count is properly - * maintained when we are add/removing a connection - * handler - * - * 6) verify that the pending IO count goes to zero - * if the channel is deleted before it connects. - */ -void verifyBlockingConnect ( appChan *pChans, unsigned chanCount, - unsigned repetitionCount, unsigned interestLevel ) -{ - int status; - unsigned i, j; - unsigned connections; - unsigned backgroundConnCount = ca_get_ioc_connection_count (); - - showProgressBegin ( "verifyBlockingConnect", interestLevel ); - - i = 0; - while ( backgroundConnCount > 1u ) { - backgroundConnCount = ca_get_ioc_connection_count (); - verify ( i++ < 10 ); - printf ( "Z" ); - fflush ( stdout ); - epicsThreadSleep ( 1.0 ); - } - - for ( i = 0; i < repetitionCount; i++ ) { - - for ( j = 0u; j < chanCount; j++ ) { - pChans[j].subscriptionUpdateCount = 0u; - pChans[j].accessUpdateCount = 0u; - pChans[j].accessRightsHandlerInstalled = 0; - pChans[j].connectionUpdateCount = 0u; - pChans[j].getCallbackCount = 0u; - pChans[j].connected = 0u; - - status = ca_search_and_connect ( pChans[j].name, &pChans[j].channel, NULL, &pChans[j] ); - SEVCHK ( status, NULL ); - - if ( ca_state ( pChans[j].channel ) == cs_conn ) { - verify ( VALID_DB_REQ ( ca_field_type ( pChans[j].channel ) ) ); - } - else { - verify ( INVALID_DB_REQ ( ca_field_type ( pChans[j].channel ) ) ); - verify ( ca_test_io () == ECA_IOINPROGRESS ); - } - - status = ca_replace_access_rights_event ( - pChans[j].channel, accessRightsStateChange ); - SEVCHK ( status, NULL ); - pChans[j].accessRightsHandlerInstalled = 1; - } - - showProgress ( interestLevel ); - - for ( j = 0u; j < chanCount; j += 2 ) { - status = ca_change_connection_event ( pChans[j].channel, connectionStateChange ); - SEVCHK ( status, NULL ); - } - - for ( j = 0u; j < chanCount; j += 2 ) { - status = ca_change_connection_event ( pChans[j].channel, NULL ); - SEVCHK ( status, NULL ); - } - - for ( j = 0u; j < chanCount; j += 2 ) { - status = ca_change_connection_event ( pChans[j].channel, connectionStateChange ); - SEVCHK ( status, NULL ); - } - - for ( j = 0u; j < chanCount; j += 2 ) { - status = ca_change_connection_event ( pChans[j].channel, NULL ); - SEVCHK ( status, NULL ); - } - - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, NULL ); - - ca_self_test (); - - showProgress ( interestLevel ); - - verify ( ca_test_io () == ECA_IODONE ); - - connections = ca_get_ioc_connection_count (); - verify ( connections == backgroundConnCount ); - - for ( j = 0u; j < chanCount; j++ ) { - verify ( VALID_DB_REQ ( ca_field_type ( pChans[j].channel ) ) ); - verify ( ca_state ( pChans[j].channel ) == cs_conn ); - SEVCHK ( ca_clear_channel ( pChans[j].channel ), NULL ); - } - - ca_self_test (); - - ca_flush_io (); - - showProgress ( interestLevel ); - - /* - * verify that connections to IOC's that are - * not in use are dropped - */ - if ( ca_get_ioc_connection_count () != backgroundConnCount ) { - epicsThreadSleep ( 0.1 ); - ca_poll (); - j=0; - while ( ca_get_ioc_connection_count () != backgroundConnCount ) { - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - verify ( ++j < 100 ); - } - } - showProgress ( interestLevel ); - } - - for ( j = 0u; j < chanCount; j++ ) { - status = ca_search ( pChans[j].name, &pChans[j].channel ); - SEVCHK ( status, NULL ); - } - - for ( j = 0u; j < chanCount; j++ ) { - status = ca_clear_channel ( pChans[j].channel ); - SEVCHK ( status, NULL ); - } - - verify ( ca_test_io () == ECA_IODONE ); - - /* - * verify ca_pend_io() does not see old search requests - * (that did not specify a connection handler) - */ - status = ca_search_and_connect ( pChans[0].name, &pChans[0].channel, NULL, NULL); - SEVCHK ( status, NULL ); - - if ( ca_state ( pChans[0].channel ) == cs_never_conn ) { - /* force an early timeout */ - status = ca_pend_io ( 1e-16 ); - if ( status == ECA_TIMEOUT ) { - /* - * we end up here if the channel isnt on the same host - */ - epicsThreadSleep ( 0.1 ); - ca_poll (); - if ( ca_state( pChans[0].channel ) != cs_conn ) { - while ( ca_state ( pChans[0].channel ) != cs_conn ) { - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - } - - status = ca_search_and_connect ( pChans[1].name, &pChans[1].channel, NULL, NULL ); - SEVCHK ( status, NULL ); - status = ca_pend_io ( 1e-16 ); - if ( status != ECA_TIMEOUT ) { - verify ( ca_state ( pChans[1].channel ) == cs_conn ); - } - status = ca_clear_channel ( pChans[1].channel ); - SEVCHK ( status, NULL ); - } - else { - verify ( ca_state( pChans[0].channel ) == cs_conn ); - } - } - status = ca_clear_channel( pChans[0].channel ); - SEVCHK ( status, NULL ); - - ca_self_test (); - - showProgressEnd ( interestLevel ); -} - -/* - * 1) verify that use of NULL evid does not cause problems - * 2) verify clear before connect - */ -void verifyClear ( appChan *pChans, unsigned interestLevel ) -{ - int status; - - showProgressBegin ( "verifyClear", interestLevel ); - - /* - * verify channel clear before connect - */ - status = ca_search ( pChans[0].name, &pChans[0].channel ); - SEVCHK ( status, NULL ); - - status = ca_clear_channel ( pChans[0].channel ); - SEVCHK ( status, NULL ); - - /* - * verify subscription clear before connect - * and verify that NULL evid does not cause failure - */ - status = ca_search ( pChans[0].name, &pChans[0].channel ); - SEVCHK ( status, NULL ); - - SEVCHK ( status, NULL ); - status = ca_add_event ( DBR_GR_DOUBLE, - pChans[0].channel, noopSubscriptionStateChange, NULL, NULL ); - SEVCHK ( status, NULL ); - - status = ca_clear_channel ( pChans[0].channel ); - SEVCHK ( status, NULL ); - showProgressEnd ( interestLevel ); -} - -/* - * grEnumTest - */ -void grEnumTest ( chid chan, unsigned interestLevel ) -{ - struct dbr_gr_enum ge; - unsigned count; - int status; - unsigned i; - - showProgressBegin ( "grEnumTest", interestLevel ); - - ge.no_str = -1; - - status = ca_get (DBR_GR_ENUM, chan, &ge); - SEVCHK (status, "DBR_GR_ENUM ca_get()"); - - status = ca_pend_io (timeoutToPendIO); - verify (status == ECA_NORMAL); - - verify ( ge.no_str >= 0 && ge.no_str < NELEMENTS(ge.strs) ); - if ( ge.no_str > 0 ) { - printf ("Enum state str = {"); - count = (unsigned) ge.no_str; - for (i=0; i epsilon ) { - printf ( "float test failed val written %f\n", fval ); - printf ( "float test failed val read %f\n", fretval ); - verify (0); - } - fval += increment; - } -} - -/* - * doubleTest () - */ -void doubleTest ( chid chan, dbr_double_t beginValue, - dbr_double_t increment, dbr_double_t epsilon, - unsigned iterations) -{ - unsigned i; - dbr_double_t fval; - dbr_double_t fretval; - int status; - - fval = beginValue; - for ( i = 0; i < iterations; i++ ) { - fretval = DBL_MAX; - status = ca_put ( DBR_DOUBLE, chan, &fval ); - SEVCHK ( status, NULL ); - status = ca_get ( DBR_DOUBLE, chan, &fretval ); - SEVCHK ( status, NULL ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, NULL ); - if ( fabs ( fval - fretval ) > epsilon ) { - printf ( "double test failed val written %f\n", fval ); - printf ( "double test failed val read %f\n", fretval ); - verify ( 0 ); - } - fval += increment; - } -} - -/* - * Verify that we can write and then read back - * the same analog value - */ -void verifyAnalogIO ( chid chan, int dataType, double min, double max, - int minExp, int maxExp, double epsilon, unsigned interestLevel ) -{ - int i; - double incr; - double epsil; - double base; - unsigned iter; - - - if ( ! ca_write_access ( chan ) ) { - printf ("skipped analog test - no write access\n"); - return; - } - - if ( dbr_value_class[ca_field_type ( chan )] != dbr_class_float ) { - printf ("skipped analog test - not an analog type\n"); - return; - } - - showProgressBegin ( "verifyAnalogIO", interestLevel ); - - epsil = epsilon * 4.0; - base = min; - for ( i = minExp; i <= maxExp; i += maxExp / 10 ) { - incr = ldexp ( 0.5, i ); - if ( fabs (incr) > max /10.0 ) { - iter = ( unsigned ) ( max / fabs (incr) ); - } - else { - iter = 10u; - } - if ( dataType == DBR_FLOAT ) { - floatTest ( chan, (dbr_float_t) base, (dbr_float_t) incr, - (dbr_float_t) epsil, iter ); - } - else if (dataType == DBR_DOUBLE ) { - doubleTest ( chan, (dbr_double_t) base, (dbr_double_t) incr, - (dbr_double_t) epsil, iter ); - } - else { - verify ( 0 ); - } - } - base = max; - for ( i = minExp; i <= maxExp; i += maxExp / 10 ) { - incr = - ldexp ( 0.5, i ); - if ( fabs (incr) > max / 10.0 ) { - iter = (unsigned) ( max / fabs (incr) ); - } - else { - iter = 10u; - } - if ( dataType == DBR_FLOAT ) { - floatTest ( chan, (dbr_float_t) base, (dbr_float_t) incr, - (dbr_float_t) epsil, iter ); - } - else if (dataType == DBR_DOUBLE ) { - doubleTest ( chan, (dbr_double_t) base, (dbr_double_t) incr, - (dbr_double_t) epsil, iter ); - } - else { - verify ( 0 ); - } - } - base = - max; - for ( i = minExp; i <= maxExp; i += maxExp / 10 ) { - incr = ldexp ( 0.5, i ); - if ( fabs (incr) > max / 10.0 ) { - iter = (unsigned) ( max / fabs ( incr ) ); - } - else { - iter = 10l; - } - if ( dataType == DBR_FLOAT ) { - floatTest ( chan, (dbr_float_t) base, (dbr_float_t) incr, - (dbr_float_t) epsil, iter ); - } - else if (dataType == DBR_DOUBLE ) { - doubleTest ( chan, (dbr_double_t) base, (dbr_double_t) incr, - (dbr_double_t) epsil, iter ); - } - else { - verify ( 0 ); - } - } - showProgressEnd ( interestLevel ); -} - -/* - * Verify that we can write and then read back - * the same DBR_LONG value - */ -void verifyLongIO ( chid chan, unsigned interestLevel ) -{ - int status; - - dbr_long_t iter, rdbk, incr; - struct dbr_ctrl_long cl; - - if ( ca_write_access ( chan ) ) { - return; - } - - status = ca_get ( DBR_CTRL_LONG, chan, &cl ); - SEVCHK ( status, "control long fetch failed\n" ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "control long pend failed\n" ); - - incr = ( cl.upper_ctrl_limit - cl.lower_ctrl_limit ); - if ( incr >= 1 ) { - showProgressBegin ( "verifyLongIO", interestLevel ); - incr /= 1000; - if ( incr == 0 ) { - incr = 1; - } - for ( iter = cl.lower_ctrl_limit; - iter <= cl.upper_ctrl_limit; iter+=incr ) { - - ca_put ( DBR_LONG, chan, &iter ); - ca_get ( DBR_LONG, chan, &rdbk ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "get pend failed\n" ); - verify ( iter == rdbk ); - } - showProgressEnd ( interestLevel ); - } - else { - printf ( "strange limits configured for channel \"%s\"\n", ca_name (chan) ); - } -} - -/* - * Verify that we can write and then read back - * the same DBR_SHORT value - */ -void verifyShortIO ( chid chan, unsigned interestLevel ) -{ - int status; - - dbr_short_t iter, rdbk, incr; - struct dbr_ctrl_short cl; - - if ( ca_write_access ( chan ) ) { - return; - } - - status = ca_get ( DBR_CTRL_SHORT, chan, &cl ); - SEVCHK ( status, "control short fetch failed\n" ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "control short pend failed\n" ); - - incr = (dbr_short_t) ( cl.upper_ctrl_limit - cl.lower_ctrl_limit ); - if ( incr >= 1 ) { - showProgressBegin ( "verifyShortIO", interestLevel ); - - incr /= 1000; - if ( incr == 0 ) { - incr = 1; - } - for ( iter = (dbr_short_t) cl.lower_ctrl_limit; - iter <= (dbr_short_t) cl.upper_ctrl_limit; - iter = (dbr_short_t) (iter + incr) ) { - - ca_put ( DBR_SHORT, chan, &iter ); - ca_get ( DBR_SHORT, chan, &rdbk ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "get pend failed\n" ); - verify ( iter == rdbk ); - } - showProgressEnd ( interestLevel ); - } - else { - printf ( "Strange limits configured for channel \"%s\"\n", ca_name (chan) ); - } -} - -void verifyHighThroughputRead ( chid chan, unsigned interestLevel ) -{ - int status; - unsigned i; - - /* - * verify we dont jam up on many uninterrupted - * solicitations - */ - if ( ca_read_access (chan) ) { - dbr_float_t temp; - showProgressBegin ( "verifyHighThroughputRead", interestLevel ); - for ( i=0; i<10000; i++ ) { - status = ca_get ( DBR_FLOAT, chan, &temp ); - SEVCHK ( status ,NULL ); - } - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, NULL ); - showProgressEnd ( interestLevel ); - } - else { - printf ( "Skipped highthroughput read test - no read access\n" ); - } -} - -void verifyHighThroughputWrite ( chid chan, unsigned interestLevel ) -{ - int status; - unsigned i; - - if (ca_write_access ( chan ) ) { - showProgressBegin ( "verifyHighThroughputWrite", interestLevel ); - for ( i=0; i<10000; i++ ) { - dbr_double_t fval = 3.3; - status = ca_put ( DBR_DOUBLE, chan, &fval ); - SEVCHK ( status, NULL ); - } - SEVCHK ( ca_pend_io (timeoutToPendIO), NULL ); - showProgressEnd ( interestLevel ); - } - else{ - printf("Skipped multiple put test - no write access\n"); - } -} - -/* - * verify we dont jam up on many uninterrupted - * get callback requests - */ -void verifyHighThroughputReadCallback ( chid chan, unsigned interestLevel ) -{ - unsigned i; - int status; - - if ( ca_read_access ( chan ) ) { - unsigned count = 0u; - showProgressBegin ( "verifyHighThroughputReadCallback", interestLevel ); - for ( i=0; i<10000; i++ ) { - status = ca_array_get_callback ( - DBR_FLOAT, 1, chan, nUpdatesTester, &count ); - SEVCHK ( status, NULL ); - } - SEVCHK ( ca_flush_io (), NULL ); - while ( count < 10000u ) { - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - showProgressEnd ( interestLevel ); - } - else { - printf ( "Skipped multiple get cb test - no read access\n" ); - } -} - -/* - * verify we dont jam up on many uninterrupted - * put callback request - */ -void verifyHighThroughputWriteCallback ( chid chan, unsigned interestLevel ) -{ - unsigned i; - int status; - - if ( ca_write_access (chan) && ca_v42_ok (chan) ) { - unsigned count = 0u; - dbr_double_t dval; - showProgressBegin ( "verifyHighThroughputWriteCallback", interestLevel ); - for ( i=0; i<10000; i++ ) { - dval = i + 1; - status = ca_array_put_callback ( - DBR_DOUBLE, 1, chan, &dval, - nUpdatesTester, &count ); - SEVCHK ( status, NULL ); - } - SEVCHK ( ca_flush_io (), NULL ); - dval = 0.0; - status = ca_get ( DBR_DOUBLE, chan, &dval ); - SEVCHK ( status, - "verifyHighThroughputWriteCallback, verification get" ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, - "verifyHighThroughputWriteCallback, verification get pend" ); - verify ( dval == i ); - showProgressEnd ( interestLevel ); - } - else { - printf ( "Skipped multiple put cb test - no write access\n" ); - } -} - -void verifyBadString ( chid chan, unsigned interestLevel ) -{ - int status; - - /* - * verify that we detect that a large string has been written - */ - if ( ca_write_access (chan) ) { - dbr_string_t stimStr; - dbr_string_t respStr; - showProgressBegin ( "verifyBadString", interestLevel ); - memset (stimStr, 'a', sizeof (stimStr) ); - status = ca_array_put ( DBR_STRING, 1u, chan, stimStr ); - verify ( status != ECA_NORMAL ); - sprintf ( stimStr, "%u", 8u ); - status = ca_array_put ( DBR_STRING, 1u, chan, stimStr ); - verify ( status == ECA_NORMAL ); - status = ca_array_get ( DBR_STRING, 1u, chan, respStr ); - verify ( status == ECA_NORMAL ); - status = ca_pend_io ( timeoutToPendIO ); - verify ( status == ECA_NORMAL ); - if ( strcmp ( stimStr, respStr ) ) { - printf ( - "Test fails if stim \"%s\" isnt roughly equiv to resp \"%s\"\n", - stimStr, respStr); - } - showProgressEnd ( interestLevel ); - } - else { - printf ( "Skipped bad string test - no write access\n" ); - } -} - -/* - * multiple_sg_requests() - */ -void multiple_sg_requests ( chid chix, CA_SYNC_GID gid ) -{ - int status; - unsigned i; - static dbr_float_t fvalput = 3.3F; - static dbr_float_t fvalget; - - for ( i=0; i < 1000; i++ ) { - if ( ca_write_access (chix) ){ - status = ca_sg_array_put ( gid, DBR_FLOAT, 1, - chix, &fvalput); - SEVCHK ( status, NULL ); - } - - if ( ca_read_access (chix) ) { - status = ca_sg_array_get ( gid, DBR_FLOAT, 1, - chix, &fvalget); - SEVCHK ( status, NULL ); - } - } -} - -/* - * test_sync_groups() - */ -void test_sync_groups ( chid chan, unsigned interestLevel ) -{ - int status; - CA_SYNC_GID gid1=0; - CA_SYNC_GID gid2=0; - - if ( ! ca_v42_ok ( chan ) ) { - printf ( "skipping sync group test - server is on wrong version\n" ); - } - - showProgressBegin ( "test_sync_groups", interestLevel ); - - status = ca_sg_create ( &gid1 ); - SEVCHK ( status, NULL ); - - multiple_sg_requests ( chan, gid1 ); - status = ca_sg_reset ( gid1 ); - SEVCHK ( status, NULL ); - - status = ca_sg_create ( &gid2 ); - SEVCHK ( status, NULL ); - - multiple_sg_requests ( chan, gid2 ); - multiple_sg_requests ( chan, gid1 ); - status = ca_sg_test ( gid2 ); - SEVCHK ( status, "SYNC GRP2" ); - status = ca_sg_test ( gid1 ); - SEVCHK ( status, "SYNC GRP1" ); - status = ca_sg_block ( gid1, 500.0 ); - SEVCHK ( status, "SYNC GRP1" ); - status = ca_sg_block ( gid2, 500.0 ); - SEVCHK ( status, "SYNC GRP2" ); - - status = ca_sg_delete ( gid2 ); - SEVCHK (status, NULL); - status = ca_sg_create ( &gid2 ); - SEVCHK (status, NULL); - - multiple_sg_requests ( chan, gid1 ); - multiple_sg_requests ( chan, gid2 ); - status = ca_sg_block ( gid1, 500.0 ); - SEVCHK ( status, "SYNC GRP1" ); - status = ca_sg_block ( gid2, 500.0 ); - SEVCHK ( status, "SYNC GRP2" ); - status = ca_sg_delete ( gid1 ); - SEVCHK ( status, NULL ); - status = ca_sg_delete ( gid2 ); - SEVCHK ( status, NULL ); - - showProgressEnd ( interestLevel ); -} - -#define multiSubscrDestroyNoLateCallbackEventCount 500 - -struct MultiSubscrDestroyNoLateCallbackEventData { - evid m_id; - size_t m_nCallback; - int m_callbackIsOk; - struct MultiSubscrDestroyNoLateCallbackTestData * m_pTestData; -}; - -struct MultiSubscrDestroyNoLateCallbackTestData { - const char * m_pChanName; - chid m_chan; - epicsMutexId m_mutex; - epicsEventId m_testDoneEvent; - unsigned m_interestLevel; - struct MultiSubscrDestroyNoLateCallbackEventData - m_eventData [multiSubscrDestroyNoLateCallbackEventCount]; -}; - -static void noLateCallbackDetect ( struct event_handler_args args ) -{ - int callbackIsOk; - struct MultiSubscrDestroyNoLateCallbackEventData * const pEventData = args.usr; - epicsMutexLockStatus lockStatus = epicsMutexLock ( pEventData->m_pTestData->m_mutex ); - callbackIsOk = pEventData->m_callbackIsOk; - pEventData->m_nCallback++; - epicsMutexUnlock ( pEventData->m_pTestData->m_mutex ); - verify ( lockStatus == epicsMutexLockOK ); - verify ( callbackIsOk ); -} - -static void multiSubscrDestroyNoLateCallbackThread ( void * pParm ) -{ - struct MultiSubscrDestroyNoLateCallbackTestData * const pTestData = - ( struct MultiSubscrDestroyNoLateCallbackTestData * ) pParm; - unsigned i, j; - int status; - - status = ca_context_create ( ca_enable_preemptive_callback ); - verify ( status == ECA_NORMAL ); - - status = ca_create_channel ( pTestData->m_pChanName, 0, 0, - CA_PRIORITY_DEFAULT, &pTestData->m_chan ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "multiSubscrDestroyLateNoCallbackTest: channel connect failed" ); - verify ( status == ECA_NORMAL ); - - /* - * create a set of subscriptions - */ - for ( i=0; i < 10000; i++ ) { - unsigned int priorityOfTestThread; - for ( j=0; j < multiSubscrDestroyNoLateCallbackEventCount; j++ ) { - epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex ); - verify ( lockStatus == epicsMutexLockOK ); - pTestData->m_eventData[j].m_nCallback = 0; - pTestData->m_eventData[j].m_callbackIsOk = TRUE; - pTestData->m_eventData[j].m_pTestData = pTestData; - epicsMutexUnlock ( pTestData->m_mutex ); - SEVCHK ( ca_add_event ( DBR_GR_FLOAT, pTestData->m_chan, noLateCallbackDetect, - &pTestData->m_eventData[j], &pTestData->m_eventData[j].m_id ) , NULL ); - } - SEVCHK ( ca_flush_io(), NULL ); - - /* - * raise the priority of the current thread hoping to improve our - * likelyhood of detecting a bug - */ - priorityOfTestThread = epicsThreadGetPrioritySelf (); - epicsThreadSetPriority ( epicsThreadGetIdSelf(), epicsThreadPriorityHigh ); - - - /* - * wait for the first subscription update to arrive - */ - { - epicsMutexLockStatus lockStatus = epicsMutexLock ( pTestData->m_mutex ); - verify ( lockStatus == epicsMutexLockOK ); - while ( pTestData->m_eventData[0].m_nCallback == 0 ) { - epicsMutexUnlock ( pTestData->m_mutex ); - epicsThreadSleep ( 50e-6 ); - lockStatus = epicsMutexLock ( pTestData->m_mutex ); - verify ( lockStatus == epicsMutexLockOK ); - } - epicsMutexUnlock ( pTestData->m_mutex ); - } - /* - * try to destroy all of the subscriptions at precisely the same time that - * their first callbacks are running - */ - for ( j=0; j < multiSubscrDestroyNoLateCallbackEventCount; j++ ) { - epicsMutexLockStatus lockStatus; - SEVCHK ( ca_clear_event ( pTestData->m_eventData[j].m_id ) , NULL ); - lockStatus = epicsMutexLock ( pTestData->m_mutex ); - verify ( lockStatus == epicsMutexLockOK ); - pTestData->m_eventData[j].m_callbackIsOk = FALSE; - epicsMutexUnlock ( pTestData->m_mutex ); - } - /* - * return to the original priority - */ - epicsThreadSetPriority ( epicsThreadGetIdSelf(), priorityOfTestThread ); - - if ( i % 1000 == 0 ) { - showProgress ( pTestData->m_interestLevel ); - } - } - - SEVCHK ( ca_clear_channel ( pTestData->m_chan ), NULL ); - - ca_context_destroy (); - - epicsEventMustTrigger ( pTestData->m_testDoneEvent ); -} - -/* - * verify that, in a preemtive callback mode client, a subscription callback never - * comes after the subscription is destroyed - */ -static void multiSubscrDestroyNoLateCallbackTest ( const char *pName, unsigned interestLevel ) -{ - struct MultiSubscrDestroyNoLateCallbackTestData * pTestData; - - showProgressBegin ( "multiSubscrDestroyNoLateCallbackTest", interestLevel ); - - pTestData = calloc ( 1u, sizeof ( struct MultiSubscrDestroyNoLateCallbackTestData ) ); - verify ( pTestData ); - pTestData->m_mutex = epicsMutexMustCreate (); - pTestData->m_testDoneEvent = epicsEventMustCreate ( epicsEventEmpty ); - pTestData->m_pChanName = pName; - pTestData->m_interestLevel = interestLevel; - epicsThreadMustCreate ( - "multiSubscrDestroyNoLateCallbackTest", - epicsThreadPriorityLow, - epicsThreadGetStackSize ( epicsThreadStackMedium ), - multiSubscrDestroyNoLateCallbackThread, - pTestData ); - - /* - * wait for test to complete - */ - epicsEventMustWait ( pTestData->m_testDoneEvent ); - - /* - * cleanup - */ - epicsMutexDestroy ( pTestData->m_mutex ); - epicsEventDestroy ( pTestData->m_testDoneEvent ); - free ( pTestData ); - - showProgressEnd ( interestLevel ); -} - -/* - * multiSubscriptionDeleteTest - * - * 1) verify we can add many monitors at once - * 2) verify that under heavy load the last monitor - * returned is the last modification sent - * 3) attempt to delete monitors while many monitors - * are running - */ -void multiSubscriptionDeleteTest ( chid chan, unsigned interestLevel ) -{ - unsigned count = 0u; - evid mid[1000]; - dbr_float_t temp, getResp; - unsigned i; - - showProgressBegin ( "multiSubscriptionDeleteTest", interestLevel ); - - for ( i=0; i < NELEMENTS (mid); i++ ) { - SEVCHK ( ca_add_event ( DBR_GR_FLOAT, chan, noopSubscriptionStateChange, - &count, &mid[i]) , NULL ); - } - - /* - * force all of the monitors subscription requests to - * complete - * - * NOTE: this hopefully demonstrates that when the - * server is very busy with monitors the client - * is still able to punch through with a request. - */ - SEVCHK ( ca_get ( DBR_FLOAT,chan,&getResp ), NULL ); - SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL ); - - showProgress ( interestLevel ); - - /* - * attempt to generate heavy event traffic before initiating - * the monitor delete - */ - if ( ca_write_access (chan) ) { - for ( i=0; i < NELEMENTS (mid); i++ ) { - temp = (float) i; - SEVCHK ( ca_put (DBR_FLOAT, chan, &temp), NULL); - } - } - - showProgress ( interestLevel ); - - /* - * without pausing begin deleting the event subscriptions - * while the queue is full - * - * continue attempting to generate heavy event traffic - * while deleting subscriptions with the hope that we will - * deleting an event at the instant that its callback is - * occurring - */ - for ( i=0; i < NELEMENTS (mid); i++ ) { - if ( ca_write_access (chan) ) { - temp = (float) i; - SEVCHK ( ca_put (DBR_FLOAT, chan, &temp), NULL); - } - SEVCHK ( ca_clear_event ( mid[i]), NULL ); - } - - showProgress ( interestLevel ); - - /* - * force all of the clear event requests to complete - */ - SEVCHK ( ca_get (DBR_FLOAT,chan,&temp), NULL ); - SEVCHK ( ca_pend_io (timeoutToPendIO), NULL ); - - showProgressEnd ( interestLevel ); -} - - -/* - * singleSubscriptionDeleteTest - * - * verify that we dont fail when we repeatedly create - * and delete only one subscription with a high level of - * traffic on it - */ -void singleSubscriptionDeleteTest ( chid chan, unsigned interestLevel ) -{ - unsigned count = 0u; - evid sid; - dbr_float_t temp, getResp; - unsigned i; - - showProgressBegin ( "singleSubscriptionDeleteTest", interestLevel ); - - for ( i=0; i < 1000; i++ ){ - count = 0u; - SEVCHK ( ca_add_event ( DBR_GR_FLOAT, chan, noopSubscriptionStateChange, - &count, &sid) , NULL ); - - if ( i % 100 == 0 ) { - showProgress ( interestLevel ); - } - - /* - * force the subscription request to complete - */ - SEVCHK ( ca_get ( DBR_FLOAT, chan, &getResp ), NULL ); - SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL ); - - /* - * attempt to generate heavy event traffic before initiating - * the monitor delete - * - * try to interrupt the recv thread while it is processing - * incoming subscription updates - */ - if ( ca_write_access (chan) ) { - unsigned j = 0; - while ( j < i ) { - temp = (float) j++; - SEVCHK ( ca_put (DBR_FLOAT, chan, &temp), - "singleSubscriptionDeleteTest - one of multiple puts" ); - } - ca_flush_io (); - } - - SEVCHK ( ca_clear_event ( sid ), NULL ); - } - - showProgressEnd ( interestLevel ); -} - -/* - * channelClearWithEventTrafficTest - * - * verify that we can delete a channel that has subcriptions - * attached with heavy update traffic - */ -void channelClearWithEventTrafficTest ( const char *pName, unsigned interestLevel ) -{ - unsigned count = 0u; - evid sid; - dbr_float_t temp, getResp; - unsigned i; - - showProgressBegin ( "channelClearWithEventTrafficTest", interestLevel ); - - for ( i=0; i < 1000; i++ ) { - chid chan; - - int status = ca_create_channel ( pName, 0, 0, - CA_PRIORITY_DEFAULT, &chan ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "channelClearWithEventTrafficTest: channel connect failed" ); - verify ( status == ECA_NORMAL ); - - count = 0u; - SEVCHK ( ca_add_event ( DBR_GR_FLOAT, chan, noopSubscriptionStateChange, - &count, &sid ) , NULL ); - - /* - * force the subscription request to complete - */ - SEVCHK ( ca_get ( DBR_FLOAT, chan, &getResp ), NULL ); - SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL ); - - /* - * attempt to generate heavy event traffic before initiating - * the channel delete - * - * try to interrupt the recv thread while it is processing - * incoming subscription updates - */ - if ( ca_write_access (chan) ) { - unsigned j = 0; - while ( j < i ) { - temp = (float) j++; - SEVCHK ( ca_put (DBR_FLOAT, chan, &temp), NULL); - } - ca_flush_io (); - epicsThreadSleep ( 0.001 ); - } - - SEVCHK ( ca_clear_channel ( chan ), NULL ); - } - - showProgressEnd ( interestLevel ); -} - - - -evid globalEventID; - -void selfDeleteEvent ( struct event_handler_args args ) -{ - int status; - status = ca_clear_event ( globalEventID ); - verify ( status == ECA_NORMAL ); -} - -void eventClearTest ( chid chan ) -{ - int status; - evid monix1, monix2, monix3; - - status = ca_add_event ( DBR_FLOAT, chan, noopSubscriptionStateChange, - NULL, &monix1 ); - SEVCHK ( status, NULL ); - - status = ca_clear_event ( monix1 ); - SEVCHK ( status, NULL ); - - status = ca_add_event ( DBR_FLOAT, chan, noopSubscriptionStateChange, - NULL, &monix1 ); - SEVCHK ( status, NULL ); - - status = ca_add_event ( DBR_FLOAT, chan, noopSubscriptionStateChange, - NULL, &monix2); - SEVCHK (status, NULL); - - status = ca_clear_event ( monix2 ); - SEVCHK ( status, NULL); - - status = ca_add_event ( DBR_FLOAT, chan, noopSubscriptionStateChange, - NULL, &monix2); - SEVCHK ( status, NULL ); - - status = ca_add_event ( DBR_FLOAT, chan, noopSubscriptionStateChange, - NULL, &monix3); - SEVCHK ( status, NULL ); - - status = ca_clear_event ( monix2 ); - SEVCHK ( status, NULL); - - status = ca_clear_event ( monix1 ); - SEVCHK ( status, NULL); - - status = ca_clear_event ( monix3 ); - SEVCHK ( status, NULL); - - status = ca_add_event ( DBR_FLOAT, chan, selfDeleteEvent, - 0, &globalEventID ); - SEVCHK ( status, NULL ); -} - -unsigned acctstExceptionCount = 0u; -void acctstExceptionNotify ( struct exception_handler_args args ) -{ - acctstExceptionCount++; -} - -static unsigned arrayEventExceptionNotifyComplete = 0; -void arrayEventExceptionNotify ( struct event_handler_args args ) -{ - if ( args.status == ECA_NORMAL ) { - printf ( - "arrayEventExceptionNotify: expected " - "exception but didnt receive one against \"%s\" \n", - ca_name ( args.chid ) ); - } - else { - arrayEventExceptionNotifyComplete = 1; - } -} - -void exceptionTest ( chid chan, unsigned interestLevel ) -{ - int status; - - showProgressBegin ( "exceptionTest", interestLevel ); - - /* - * force a get exception to occur - */ - { - dbr_put_ackt_t *pRS; - - acctstExceptionCount = 0u; - status = ca_add_exception_event ( acctstExceptionNotify, 0 ); - SEVCHK ( status, "exception notify install failed" ); - - pRS = malloc ( ca_element_count (chan) * sizeof (*pRS) ); - verify ( pRS ); - status = ca_array_get ( DBR_PUT_ACKT, - ca_element_count (chan), chan, pRS ); - SEVCHK ( status, "array read request failed" ); - ca_pend_io ( 1e-5 ); - epicsThreadSleep ( 0.1 ); - ca_poll (); - while ( acctstExceptionCount < 1u ) { - printf ( "G" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - status = ca_add_exception_event ( 0, 0 ); - SEVCHK ( status, "exception notify install failed" ); - free ( pRS ); - } - - /* - * force a get call back exception to occur - */ - { - arrayEventExceptionNotifyComplete = 0u; - status = ca_array_get_callback ( DBR_PUT_ACKT, - ca_element_count (chan), chan, arrayEventExceptionNotify, 0 ); - if ( status != ECA_NORMAL ) { - verify ( status == ECA_BADTYPE || status == ECA_GETFAIL ); - arrayEventExceptionNotifyComplete = 1; - } - ca_flush_io (); - epicsThreadSleep ( 0.1 ); - ca_poll (); - while ( ! arrayEventExceptionNotifyComplete ) { - printf ( "GCB" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - } - - /* - * force a subscription exception to occur - */ - { - evid id; - - arrayEventExceptionNotifyComplete = 0u; - status = ca_add_array_event ( DBR_PUT_ACKT, ca_element_count ( chan ), - chan, arrayEventExceptionNotify, 0, 0.0, 0.0, 0.0, &id ); - if ( status != ECA_NORMAL ) { - verify ( status == ECA_BADTYPE || status == ECA_GETFAIL ); - arrayEventExceptionNotifyComplete = 1; - } - ca_flush_io (); - epicsThreadSleep ( 0.1 ); - ca_poll (); - while ( ! arrayEventExceptionNotifyComplete ) { - printf ( "S" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - status = ca_clear_event ( id ); - SEVCHK ( status, "subscription clear failed" ); - } - - /* - * force a put exception to occur - */ - { - dbr_string_t * pWS; - unsigned i; - - acctstExceptionCount = 0u; - status = ca_add_exception_event ( acctstExceptionNotify, 0 ); - SEVCHK ( status, "exception notify install failed" ); - - pWS = malloc ( ca_element_count (chan) * MAX_STRING_SIZE ); - verify ( pWS ); - for ( i = 0; i < ca_element_count (chan); i++ ) { - strcpy ( pWS[i], "@#$%" ); - } - status = ca_array_put ( DBR_STRING, - ca_element_count (chan), chan, pWS ); - if ( status != ECA_NORMAL ) { - verify ( status == ECA_BADTYPE || status == ECA_PUTFAIL ); - acctstExceptionCount++; /* local PV case */ - } - ca_flush_io (); - epicsThreadSleep ( 0.1 ); - ca_poll (); - while ( acctstExceptionCount < 1u ) { - printf ( "P" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - status = ca_add_exception_event ( 0, 0 ); - SEVCHK ( status, "exception notify install failed" ); - free ( pWS ); - } - - /* - * force a put callback exception to occur - */ - { - dbr_string_t *pWS; - unsigned i; - - pWS = malloc ( ca_element_count (chan) * MAX_STRING_SIZE ); - verify ( pWS ); - for ( i = 0; i < ca_element_count (chan); i++ ) { - strcpy ( pWS[i], "@#$%" ); - } - arrayEventExceptionNotifyComplete = 0u; - status = ca_array_put_callback ( DBR_STRING, - ca_element_count (chan), chan, pWS, - arrayEventExceptionNotify, 0); - if ( status != ECA_NORMAL ) { - arrayEventExceptionNotifyComplete = 1; - } - ca_flush_io (); - epicsThreadSleep ( 0.1 ); - ca_poll (); - while ( ! arrayEventExceptionNotifyComplete ) { - printf ( "PCB" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - free ( pWS ); - } - - showProgressEnd ( interestLevel ); -} - -/* - * array test - * - * verify that we can at least write and read back the same array - * if multiple elements are present - */ -static unsigned arrayReadNotifyComplete = 0; -static unsigned arrayWriteNotifyComplete = 0; -void arrayReadNotify ( struct event_handler_args args ) -{ - dbr_double_t *pWF = ( dbr_double_t * ) ( args.usr ); - dbr_double_t *pRF = ( dbr_double_t * ) ( args.dbr ); - int i; - for ( i = 0; i < args.count; i++ ) { - verify ( pWF[i] == pRF[i] ); - } - arrayReadNotifyComplete = 1; -} -void arrayWriteNotify ( struct event_handler_args args ) -{ - if ( args.status == ECA_NORMAL ) { - arrayWriteNotifyComplete = 1; - } - else { - printf ( "arrayWriteNotify: update failed for \"%s\" because \"%s\"", - ca_name ( args.chid ), ca_message ( args.status ) ); - } -} - -void arrayTest ( chid chan, unsigned maxArrayBytes, unsigned interestLevel ) -{ - dbr_double_t *pRF, *pWF; - unsigned i; - int status; - evid id; - - if ( ! ca_write_access ( chan ) ) { - printf ( "skipping array test - no write access\n" ); - return; - } - - showProgressBegin ( "arrayTest", interestLevel ); - - pRF = (dbr_double_t *) calloc ( ca_element_count (chan), sizeof (*pRF) ); - verify ( pRF != NULL ); - - pWF = (dbr_double_t *) calloc ( ca_element_count (chan), sizeof (*pWF) ); - verify ( pWF != NULL ); - - /* - * write some random numbers into the array - */ - for ( i = 0; i < ca_element_count (chan); i++ ) { - pWF[i] = rand (); - pRF[i] = - pWF[i]; - } - status = ca_array_put ( DBR_DOUBLE, ca_element_count ( chan ), - chan, pWF ); - SEVCHK ( status, "array write request failed" ); - - /* - * read back the array - */ - status = ca_array_get ( DBR_DOUBLE, ca_element_count (chan), - chan, pRF ); - SEVCHK ( status, "array read request failed" ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "array read failed" ); - - /* - * verify read response matches values written - */ - for ( i = 0; i < ca_element_count ( chan ); i++ ) { - if ( pWF[i] != pRF[i] ) { - printf ( "i=%u, pWF[i]=%f, pRF[i]=%f\n", - i, pWF[i], pRF[i]); - } - verify ( pWF[i] == pRF[i] ); - } - - /* - * read back the array as strings - */ - { - char *pRS; - unsigned size = ca_element_count (chan) * MAX_STRING_SIZE; - - if ( size <= maxArrayBytes ) { - - pRS = malloc ( ca_element_count (chan) * MAX_STRING_SIZE ); - verify ( pRS ); - status = ca_array_get ( DBR_STRING, - ca_element_count (chan), chan, pRS ); - SEVCHK ( status, "array read request failed" ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "array read failed" ); - free ( pRS ); - } - else { - printf ( "skipping the fetch array in string data type test - does not fit\n" ); - } - } - - /* - * write some random numbers into the array - */ - for ( i = 0; i < ca_element_count (chan); i++ ) { - pWF[i] = rand (); - pRF[i] = - pWF[i]; - } - status = ca_array_put_callback ( DBR_DOUBLE, ca_element_count (chan), - chan, pWF, arrayWriteNotify, 0 ); - SEVCHK ( status, "array write notify request failed" ); - status = ca_array_get_callback ( DBR_DOUBLE, ca_element_count (chan), - chan, arrayReadNotify, pWF ); - SEVCHK ( status, "array read notify request failed" ); - ca_flush_io (); - while ( ! arrayWriteNotifyComplete || ! arrayReadNotifyComplete ) { - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - - /* - * write some random numbers into the array - */ - for ( i = 0; i < ca_element_count (chan); i++ ) { - pWF[i] = rand (); - pRF[i] = - pWF[i]; - } - arrayReadNotifyComplete = 0; - status = ca_array_put ( DBR_DOUBLE, ca_element_count ( chan ), - chan, pWF ); - SEVCHK ( status, "array write notify request failed" ); - status = ca_add_array_event ( DBR_DOUBLE, ca_element_count ( chan ), - chan, arrayReadNotify, pWF, 0.0, 0.0, 0.0, &id ); - SEVCHK ( status, "array subscription request failed" ); - ca_flush_io (); - while ( ! arrayReadNotifyComplete ) { - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - status = ca_clear_event ( id ); - SEVCHK ( status, "clear event request failed" ); - - /* - * a get request should fail or fill with zeros - * when the array size is too large - */ - { - acctstExceptionCount = 0u; - status = ca_add_exception_event ( acctstExceptionNotify, 0 ); - SEVCHK ( status, "exception notify install failed" ); - status = ca_array_get ( DBR_DOUBLE, - ca_element_count (chan)+1, chan, pRF ); - if ( status == ECA_NORMAL ) { - ca_poll (); - while ( acctstExceptionCount < 1u ) { - printf ( "N" ); - fflush ( stdout ); - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - } - } - else { - verify ( status == ECA_BADCOUNT ); - } - status = ca_add_exception_event ( 0, 0 ); - SEVCHK ( status, "exception notify install failed" ); - } - - free ( pRF ); - free ( pWF ); - - showProgressEnd ( interestLevel ); -} - -/* - * verify that unequal send/recv buffer sizes work - * (a bug related to this test was detected in early R3.14) - * - * this test must be run when no other channels are connected - */ -void unequalServerBufferSizeTest ( const char * pName, unsigned interestLevel ) -{ - dbr_double_t *pRF, *pWF; - unsigned connections; - chid newChan; - int status; - - showProgressBegin ( "unequalServerBufferSizeTest", interestLevel ); - - /* this test must be run when no channels are connected */ - connections = ca_get_ioc_connection_count (); - verify ( connections == 0u ); - - status = ca_create_channel ( pName, 0, 0, 0, & newChan ); - verify ( status == ECA_NORMAL ); - status = ca_pend_io ( timeoutToPendIO ); - verify ( status == ECA_NORMAL ); - - showProgress ( interestLevel ); - - if ( ! ca_write_access ( newChan ) ) { - printf ( "skipping unequal buffer size test - no write access\n" ); - status = ca_clear_channel ( newChan ); - verify ( status == ECA_NORMAL ); - return; - } - - pRF = (dbr_double_t *) calloc ( ca_element_count (newChan), sizeof (*pRF) ); - verify ( pRF != NULL ); - - pWF = (dbr_double_t *) calloc ( ca_element_count (newChan), sizeof (*pWF) ); - verify ( pWF != NULL ); - - status = ca_array_get ( DBR_DOUBLE, ca_element_count ( newChan ), - newChan, pRF ); - status = ca_pend_io ( timeoutToPendIO ); - verify ( status == ECA_NORMAL ); - status = ca_clear_channel ( newChan ); - verify ( status == ECA_NORMAL ); - - showProgress ( interestLevel ); - - status = ca_create_channel ( pName, 0, 0, 0, &newChan ); - verify ( status == ECA_NORMAL ); - status = ca_pend_io ( timeoutToPendIO ); - verify ( status == ECA_NORMAL ); - - showProgress ( interestLevel ); - - status = ca_array_put ( DBR_DOUBLE, ca_element_count ( newChan ), - newChan, pWF ); - verify ( status == ECA_NORMAL ); - status = ca_array_get ( DBR_DOUBLE, 1, - newChan, pRF ); - verify ( status == ECA_NORMAL ); - status = ca_pend_io ( timeoutToPendIO ); - verify ( status == ECA_NORMAL ); - status = ca_clear_channel ( newChan ); - verify ( status == ECA_NORMAL ); - - free ( pRF ); - free ( pWF ); - - showProgressEnd ( interestLevel ); -} - -/* - * pend_event_delay_test() - */ -void pend_event_delay_test ( dbr_double_t request ) -{ - int status; - epicsTimeStamp end_time; - epicsTimeStamp start_time; - dbr_double_t delay; - dbr_double_t accuracy; - - epicsTimeGetCurrent ( &start_time ); - status = ca_pend_event ( request ); - if (status != ECA_TIMEOUT) { - SEVCHK(status, NULL); - } - epicsTimeGetCurrent(&end_time); - delay = epicsTimeDiffInSeconds ( &end_time, &start_time ); - accuracy = 100.0*(delay-request)/request; - printf ( "CA pend event delay = %f sec results in error = %f %%\n", - request, accuracy ); - verify ( fabs(accuracy) < 10.0 ); -} - -void caTaskExitTest ( unsigned interestLevel ) -{ - int status; - - showProgressBegin ( "caTaskExitTest", interestLevel ); - - status = ca_task_exit (); - SEVCHK ( status, NULL ); - - showProgressEnd ( interestLevel ); -} - -void verifyDataTypeMacros (void) -{ - int type; - - type = dbf_type_to_DBR ( DBF_SHORT ); - verify ( type == DBR_SHORT ); - type = dbf_type_to_DBR_STS ( DBF_SHORT ); - verify ( type == DBR_STS_SHORT ); - type = dbf_type_to_DBR_GR ( DBF_SHORT ); - verify ( type == DBR_GR_SHORT ); - type = dbf_type_to_DBR_CTRL ( DBF_SHORT ); - verify ( type == DBR_CTRL_SHORT ); - type = dbf_type_to_DBR_TIME ( DBF_SHORT ); - verify ( type == DBR_TIME_SHORT ); - verify ( strcmp ( dbr_type_to_text( DBR_SHORT ), "DBR_SHORT" ) == 0 ); - verify ( strcmp ( dbf_type_to_text( DBF_SHORT ), "DBF_SHORT" ) == 0 ); - verify ( dbr_type_is_SHORT ( DBR_SHORT ) ); - verify ( dbr_type_is_valid ( DBR_SHORT ) ); - verify ( dbf_type_is_valid ( DBF_SHORT ) ); - { - int dataType = -1; - dbf_text_to_type ( "DBF_SHORT", dataType ); - verify ( dataType == DBF_SHORT ); - dbr_text_to_type ( "DBR_CLASS_NAME", dataType ); - verify ( dataType == DBR_CLASS_NAME ); - } -} - -typedef struct { - evid id; - dbr_float_t lastValue; - unsigned count; -} eventTest; - -/* - * updateTestEvent () - */ -void updateTestEvent ( struct event_handler_args args ) -{ - eventTest *pET = (eventTest *) args.usr; - struct dbr_gr_float *pGF = (struct dbr_gr_float *) args.dbr; - pET->lastValue = pGF->value; - pET->count++; -} - -dbr_float_t monitorUpdateTestPattern ( unsigned iter ) -{ - return ( (float) iter ) * 10.12345f + 10.7f; -} - -void callbackClearsChannel ( struct event_handler_args args ) -{ - int status; - status = ca_clear_channel ( args.chid ); - SEVCHK ( status, "clearChannelInXxxxCallbackTest clear channel" ); -} - -void clearChannelInGetCallbackTest ( const char *pName, unsigned level ) -{ - unsigned i; - chid chan; - int status; - - showProgressBegin ( "clearChannelInGetCallbackTest", level ); - - for ( i = 0; ca_get_ioc_connection_count () > 0 ; i++ ) { - ca_pend_event ( 0.1 ); - verify ( i < 100 ); - } - - status = ca_create_channel ( pName, 0, 0, 0, & chan ); - SEVCHK ( status, "clearChannelInGetCallbackTest create channel" ); - - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "clearChannelInGetCallbackTest connect channel" ); - - status = ca_get_callback ( DBR_DOUBLE, chan, callbackClearsChannel, 0 ); - SEVCHK ( status, "clearChannelInGetCallbackTest get callback" ); - - for ( i = 0; ca_get_ioc_connection_count () > 0 ; i++ ) { - ca_pend_event ( 0.1 ); - verify ( i < 100 ); - } - - showProgressEnd ( level ); -} - -void clearChannelInPutCallbackTest ( const char *pName, unsigned level ) -{ - unsigned i; - const dbr_double_t value = 1.1; - chid chan; - int status; - - showProgressBegin ( "clearChannelInPutCallbackTest", level ); - - for ( i = 0; ca_get_ioc_connection_count () > 0 ; i++ ) { - ca_pend_event ( 0.1 ); - verify ( i < 100 ); - } - - status = ca_create_channel ( pName, 0, 0, 0, & chan ); - SEVCHK ( status, "clearChannelInPutCallbackTest create channel" ); - - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "clearChannelInPutCallbackTest connect channel" ); - - status = ca_put_callback ( DBR_DOUBLE, chan, & value, - callbackClearsChannel, 0 ); - SEVCHK ( status, "clearChannelInPutCallbackTest get callback" ); - - for ( i = 0; ca_get_ioc_connection_count () > 0 ; i++ ) { - ca_pend_event ( 0.1 ); - verify ( i < 100 ); - } - - showProgressEnd ( level ); -} - -void clearChannelInSubscrCallbackTest ( const char *pName, unsigned level ) -{ - unsigned i; - chid chan; - int status; - - showProgressBegin ( "clearChannelInSubscrCallbackTest", level ); - - for ( i = 0; ca_get_ioc_connection_count () > 0 ; i++ ) { - ca_pend_event ( 0.1 ); - verify ( i < 100 ); - } - - status = ca_create_channel ( pName, 0, 0, 0, & chan ); - SEVCHK ( status, "clearChannelInSubscrCallbackTest create channel" ); - - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "clearChannelInSubscrCallbackTest connect channel" ); - - status = ca_create_subscription ( DBR_DOUBLE, 1, chan, - DBE_VALUE, callbackClearsChannel, 0, 0 ); - SEVCHK ( status, "clearChannelInSubscrCallbackTest subscribe" ); - - for ( i = 0; ca_get_ioc_connection_count () > 0 ; i++ ) { - ca_pend_event ( 0.1 ); - verify ( i < 100 ); - } - - showProgressEnd ( level ); -} - -void monitorAddConnectionCallback ( struct connection_handler_args args ) -{ - if ( args.op == CA_OP_CONN_UP ) { - unsigned * pEventCount = ( unsigned * ) ca_puser ( args.chid ); - int status; - verify ( *pEventCount == 0u ); - (*pEventCount)++; - status = ca_create_subscription ( DBR_DOUBLE, 1, - args.chid, DBE_VALUE, nUpdatesTester, ca_puser ( args.chid ), 0 ); - SEVCHK ( status, "monitorAddConnectionCallback create subscription" ); - } - else { - fprintf ( stderr, "disconnect during monitorAddConnectionCallbackTest?\n" ); - } -} - -/* - * monitorAddConnectionCallbackTest - * 1) subscription add from within connection callback needs to work - * 2) check for problems where subscription is installed twice if - * its installed within the connection callback handler - */ -void monitorAddConnectionCallbackTest ( const char *pName, unsigned interestLevel ) -{ - unsigned i; - chid chan; - int status; - unsigned eventCount = 0u; - unsigned getCallbackCount = 0u; - - showProgressBegin ( "monitorAddConnectionCallbackTest", interestLevel ); - - for ( i = 0; ca_get_ioc_connection_count () > 0 ; i++ ) { - ca_pend_event ( 0.1 ); - verify ( i < 100 ); - } - - status = ca_create_channel ( pName, - monitorAddConnectionCallback, &eventCount, 0, & chan ); - SEVCHK ( status, "monitorAddConnectionCallbackTest create channel" ); - - while ( eventCount < 2 ) { - ca_pend_event ( 0.1 ); - } - verify ( eventCount >= 2u ); - - status = ca_get_callback ( DBR_DOUBLE, chan, nUpdatesTester, &getCallbackCount ); - SEVCHK ( status, "monitorAddConnectionCallback get callback" ); - while ( getCallbackCount == 0 ) { - ca_pend_event ( 0.1 ); - } - verify ( eventCount >= 2u ); - verify ( getCallbackCount == 1u ); - - status = ca_clear_channel ( chan ); - SEVCHK ( status, "monitorAddConnectionCallbackTest clear channel" ); - - status = ca_flush_io (); - SEVCHK ( status, "monitorAddConnectionCallbackTest flush" ); - - showProgressEnd ( interestLevel ); -} - - -/* - * monitorUpdateTest - * - * 1) verify we can add many monitors at once - * 2) verify that under heavy load the last monitor - * returned is the last modification sent - */ -void monitorUpdateTest ( chid chan, unsigned interestLevel ) -{ - eventTest test[100]; - dbr_float_t temp, getResp; - unsigned i, j; - unsigned flowCtrlCount = 0u; - unsigned prevPassCount; - unsigned tries; - - if ( ! ca_write_access ( chan ) ) { - printf ("skipped monitorUpdateTest test - no write access\n"); - return; - } - - if ( dbr_value_class[ca_field_type ( chan )] != dbr_class_float ) { - printf ("skipped monitorUpdateTest test - not an analog type\n"); - return; - } - - showProgressBegin ( "monitorUpdateTest", interestLevel ); - - /* - * set channel to known value - */ - temp = 1; - SEVCHK ( ca_put ( DBR_FLOAT, chan, &temp ), NULL ); - - for ( i = 0; i < NELEMENTS(test); i++ ) { - test[i].count = 0; - test[i].lastValue = -1.0f; - SEVCHK(ca_add_event(DBR_GR_FLOAT, chan, updateTestEvent, - &test[i], &test[i].id),NULL); - } - - /* - * force all of the monitors subscription requests to - * complete - * - * NOTE: this hopefully demonstrates that when the - * server is very busy with monitors the client - * is still able to punch through with a request. - */ - SEVCHK ( ca_get ( DBR_FLOAT, chan, &getResp) ,NULL ); - SEVCHK ( ca_pend_io ( timeoutToPendIO ) ,NULL ); - - showProgress ( interestLevel ); - - /* - * pass the test only if we get the first monitor update - */ - tries = 0; - while ( 1 ) { - unsigned nFailed = 0u; - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - for ( i = 0; i < NELEMENTS ( test ); i++ ) { - if ( test[i].count > 0 ) { - if ( test[i].lastValue != temp ) { - nFailed++; - } - } - else { - nFailed++; - } - } - if ( nFailed == 0u ) { - break; - } - printf ( "-" ); - fflush ( stdout ); - verify ( tries++ < 50 ); - } - - showProgress ( interestLevel ); - - /* - * attempt to uncover problems where the last event isnt sent - * and hopefully get into a flow control situation - */ - prevPassCount = 0u; - for ( i = 0; i < 10; i++ ) { - for ( j = 0; j < NELEMENTS(test); j++ ) { - SEVCHK ( ca_clear_event ( test[j].id ), NULL ); - test[j].count = 0; - test[j].lastValue = -1.0f; - SEVCHK ( ca_add_event ( DBR_GR_FLOAT, chan, updateTestEvent, - &test[j], &test[j].id ) , NULL ); - } - - for ( j = 0; j <= i; j++ ) { - temp = monitorUpdateTestPattern ( j ); - SEVCHK ( ca_put ( DBR_FLOAT, chan, &temp ), NULL ); - } - - /* - * wait for the above to complete - */ - getResp = -1; - SEVCHK ( ca_get ( DBR_FLOAT, chan, &getResp ), NULL ); - SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL ); - - if ( getResp != temp ) { - printf ( "getResp=%f, temp=%f\n", getResp, temp ); - verify ( getResp == temp ); - } - - /* - * wait for all of the monitors to have correct values - */ - tries = 0; - while (1) { - unsigned passCount = 0; - unsigned tmpFlowCtrlCount = 0u; - epicsThreadSleep ( 0.1 ); - ca_poll (); /* emulate typical GUI */ - for ( j = 0; j < NELEMENTS ( test ); j++ ) { - /* - * we shouldnt see old monitors because - * we resubscribed - */ - verify ( test[j].count <= i + 2 ); - if ( test[j].lastValue == temp ) { - if ( test[j].count < i + 1 ) { - tmpFlowCtrlCount++; - } - passCount++; - } - } - if ( passCount == NELEMENTS ( test ) ) { - flowCtrlCount += tmpFlowCtrlCount; - break; - } - if ( passCount == prevPassCount ) { - verify ( tries++ < 500 ); - if ( tries % 50 == 0 ) { - for ( j = 0; j <= i; j++ ) { - dbr_float_t pat = monitorUpdateTestPattern ( j ); - if ( pat == test[0].lastValue ) { - break; - } - } - if ( j <= i) { - printf ( "-(%d)", i-j ); - } - else { - printf ( "." ); - } - fflush ( stdout ); - } - } - prevPassCount = passCount; - } - } - - showProgress ( interestLevel ); - - /* - * delete the event subscriptions - */ - for ( i = 0; i < NELEMENTS ( test ); i++ ) { - SEVCHK ( ca_clear_event ( test[i].id ), NULL ); - } - - /* - * force all of the clear event requests to - * complete - */ - SEVCHK ( ca_get ( DBR_FLOAT, chan, &temp ), NULL ); - SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL ); - - /* printf ( "flow control bypassed %u events\n", flowCtrlCount ); */ - - showProgressEnd ( interestLevel ); -} - -void verifyReasonableBeaconPeriod ( chid chan, unsigned interestLevel ) -{ - if ( ca_get_ioc_connection_count () > 0 ) { - double beaconPeriod; - double watchDogDelay; - unsigned i; - - showProgressBegin ( "verifyReasonableBeaconPeriod", interestLevel ); - - - printf ( "Beacon anomalies detected since program start %u\n", - ca_beacon_anomaly_count () ); - - beaconPeriod = ca_beacon_period ( chan ); - printf ( "Estimated beacon period for channel %s = %g sec.\n", - ca_name ( chan ), beaconPeriod ); - - watchDogDelay = ca_receive_watchdog_delay ( chan ); - verify ( watchDogDelay >= 0.0 ); - - printf ( "busy: receive watchdog for \"%s\" expires in %g sec.\n", - ca_name ( chan ), watchDogDelay ); - - /* - * let one default connection timeout go by w/o receive activity - * so we can see if beacons reset the watchdog - */ - for ( i = 0u; i < 15u; i++ ) { - ca_pend_event ( 2.0 ); - showProgress ( interestLevel ); - } - if ( interestLevel > 0 ) { - printf ( "\n" ); - } - - watchDogDelay = ca_receive_watchdog_delay ( chan ); - verify ( watchDogDelay >= 0.0 ); - - printf ( "inactive: receive watchdog for \"%s\" expires in %g sec.\n", - ca_name ( chan ), watchDogDelay ); - - showProgressEnd ( interestLevel ); - } -} - -void verifyOldPend ( unsigned interestLevel ) -{ - int status; - - showProgressBegin ( "verifyOldPend", interestLevel ); - - /* - * verify that the old ca_pend() is in the symbol table - */ - status = ca_pend ( 100000.0, 1 ); - verify ( status == ECA_NORMAL ); - status = ca_pend ( 1e-12, 0 ); - verify ( status == ECA_TIMEOUT ); - - showProgressEnd ( interestLevel ); -} - -void verifyTimeStamps ( chid chan, unsigned interestLevel ) -{ - struct dbr_time_double first; - struct dbr_time_double last; - epicsTimeStamp localTime; - char buf[128]; - size_t length; - double diff; - int status; - - showProgressBegin ( "verifyTimeStamps", interestLevel ); - - status = epicsTimeGetCurrent ( & localTime ); - verify ( status >= 0 ); - - status = ca_get ( DBR_TIME_DOUBLE, chan, & first ); - SEVCHK ( status, "fetch of dbr time double failed\n" ); - status = ca_pend_io ( timeoutToPendIO ); - verify ( status == ECA_NORMAL ); - - status = ca_get ( DBR_TIME_DOUBLE, chan, & last ); - SEVCHK ( status, "fetch of dbr time double failed\n" ); - status = ca_pend_io ( timeoutToPendIO ); - verify ( status == ECA_NORMAL ); - - length = epicsTimeToStrftime ( buf, sizeof ( buf ), - "%a %b %d %Y %H:%M:%S.%f", & first.stamp ); - verify ( length ); - printf ("Processing time of channel \"%s\" was \"%s\"\n", - ca_name ( chan ), buf ); - - diff = epicsTimeDiffInSeconds ( & last.stamp, & first.stamp ); - printf ("Time difference between two successive reads was %g sec\n", - diff ); - - diff = epicsTimeDiffInSeconds ( & first.stamp, & localTime ); - printf ("Time difference between client and server %g sec\n", - diff ); - - showProgressEnd ( interestLevel ); -} - -/* - * attempts to verify from the client side that - * channel priorities work correctly - */ -void verifyChannelPriorities ( const char *pName, unsigned interestLevel ) -{ - static const unsigned nPrio = 30; - unsigned i; - - showProgressBegin ( "verifyChannelPriorities", interestLevel ); - - for ( i = 0u; i < nPrio; i++ ) { - int status; - double value; - chid chan0, chan1; - unsigned priority0, priority1; - - priority0 = ( i * ( CA_PRIORITY_MAX - CA_PRIORITY_MIN ) ) / nPrio; - priority0 += CA_PRIORITY_MIN; - if ( priority0 > CA_PRIORITY_MAX ) { - priority0 = CA_PRIORITY_MAX; - } - - priority1 = ( (i+1) * ( CA_PRIORITY_MAX - CA_PRIORITY_MIN ) ) / nPrio; - priority1 += CA_PRIORITY_MIN; - if ( priority1 > CA_PRIORITY_MAX ) { - priority1 = CA_PRIORITY_MAX; - } - - status = ca_create_channel ( pName, 0, 0, - priority0, &chan0 ); - SEVCHK ( status, "prioritized channel create failed" ); - - status = ca_create_channel ( pName, 0, 0, - priority1, &chan1 ); - SEVCHK ( status, "prioritized channel create failed" ); - - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "prioritized channel connect failed" ); - verify ( status == ECA_NORMAL ); - - value = i; - status = ca_put ( DBR_DOUBLE, chan0, &value ); - SEVCHK ( status, "prioritized channel put failed" ); - status = ca_put ( DBR_DOUBLE, chan1, &value ); - SEVCHK ( status, "prioritized channel put failed" ); - - status = ca_flush_io (); - SEVCHK ( status, "prioritized channel flush failed" ); - - status = ca_get ( DBR_DOUBLE, chan0, &value ); - SEVCHK ( status, "prioritized channel get failed" ); - status = ca_get ( DBR_DOUBLE, chan1, &value ); - SEVCHK ( status, "prioritized channel get failed" ); - - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "prioritized channel pend io failed" ); - - status = ca_clear_channel ( chan0 ); - SEVCHK ( status, "prioritized channel clear failed" ); - status = ca_clear_channel ( chan1 ); - SEVCHK ( status, "prioritized channel clear failed" ); - } - - showProgressEnd ( interestLevel ); -} - -void verifyTearDownWhenChannelConnected ( const char * pName, - enum ca_preemptive_callback_select select, - unsigned interestLevel ) -{ - static const unsigned chanCount = 20; - static const unsigned loopCount = 100; - - chid * const pChans = (chid * const) calloc ( chanCount, sizeof ( *pChans ) ); - double * const pValues = (double * const) calloc ( chanCount, sizeof ( *pValues ) ); - unsigned i, j; - - verify ( pChans && pValues ); - - showProgressBegin ( "verifyTearDownWhenChannelConnected", interestLevel ); - - for ( i = 0u; i < loopCount; i++ ) { - int status; - ca_context_create ( select ); - - for ( j = 0; j < chanCount; j++ ) { - status = ca_create_channel ( pName, 0, 0, 0, & pChans[j] ); - SEVCHK ( status, "immediate tear down channel create failed" ); - } - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "immediate tear down channel connect failed" ); - verify ( status == ECA_NORMAL ); - - for ( j = 0; j < chanCount; j++ ) { - status = ca_get ( DBR_DOUBLE, pChans[j], &pValues[j] ); - SEVCHK ( status, "immediate tear down channel get failed" ); - } - - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "immediate tear down get pend io failed" ); - - ca_context_destroy (); - } - - ca_context_create ( select ); - - free ( pChans ); - free ( pValues ); - - showProgressEnd ( interestLevel ); -} - - -void verifyImmediateTearDown ( const char * pName, - enum ca_preemptive_callback_select select, - unsigned interestLevel ) -{ - int i; - - showProgressBegin ( "verifyImmediateTearDown", interestLevel ); - - for ( i = 0u; i < 100; i++ ) { - chid chan; - int status; - dbr_long_t value = i % 8; - ca_context_create ( select ); - ca_task_initialize (); - status = ca_create_channel ( pName, 0, 0, 0, & chan ); - SEVCHK ( status, "immediate tear down channel create failed" ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "immediate tear down channel connect failed" ); - verify ( status == ECA_NORMAL ); - /* - * verify that puts pending when we call ca_task_exit() - * get flushed out - */ - if ( i > 0 ) { - dbr_long_t currentValue = value; - status = ca_get ( DBR_LONG, chan, & currentValue ); - SEVCHK ( status, "immediate tear down channel get failed" ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "immediate tear down channel get failed" ); - if ( currentValue != ( (i - 1) % 8 ) ) { - printf ( "currentValue = %i, i = %i\n", currentValue, i ); - verify ( currentValue == ( (i - 1) % 8 ) ); - } - } - status = ca_put ( DBR_LONG, chan, & value ); - SEVCHK ( status, "immediate tear down channel put failed" ); - status = ca_clear_channel ( chan ); - SEVCHK ( status, "immediate tear down channel clear failed" ); - ca_context_destroy (); - /* epicsThreadSleep ( 1e-15 ); */ - if ( i % 10 == 0 ) { - showProgress ( interestLevel ); - } - } - - ca_context_create ( select ); - - showProgressEnd ( interestLevel ); -} - -/* - * keeping these tests together detects a bug - */ -void eventClearAndMultipleMonitorTest ( chid chan, unsigned interestLevel ) -{ - eventClearTest ( chan ); - monitorUpdateTest ( chan, interestLevel ); -} - -void fdcb ( void * parg ) -{ - ca_poll (); -} - -void fdRegCB ( void * parg, int fd, int opened ) -{ - int status; - - fdctx * mgrCtx = ( fdctx * ) parg; - if ( opened ) { - status = fdmgr_add_callback ( - mgrCtx, fd, fdi_read, fdcb, 0 ); - verify ( status >= 0 ); - } - else { - status = fdmgr_clear_callback ( - mgrCtx, fd, fdi_read ); - verify ( status >= 0 ); - } -} - -typedef struct { - char m_chanName[100u]; - struct ca_client_context * m_pCtx; - chid m_chan; - epicsMutexId m_mutex; - epicsEventId m_testCompleteEvent; - epicsEventId m_threadExitEvent; - size_t m_nUpdatesReceived; - size_t m_nUpdatesRequired; - int m_testInitiated; - int m_testComplete; - unsigned m_interestLevel; -} MultiThreadSubscrTest; - -static void testMultithreadSubscrSubscrCallback - ( struct event_handler_args eha ) -{ - const epicsEventId firstUpdateEvent = ( epicsEventId ) eha.usr; - epicsEventSignal ( firstUpdateEvent ); -} - -static void testMultithreadSubscrCreateSubscr ( void * pParm ) -{ - static unsigned nElem = 0; - int testComplete = FALSE; - evid id; - epicsEventId firstUpdateEvent; - epicsEventWaitStatus eventWaitStatus; - MultiThreadSubscrTest * const pMultiThreadSubscrTest = - ( MultiThreadSubscrTest * ) pParm; - - /* this is required for the ca_flush below to work correctly */ - int status = ca_attach_context ( pMultiThreadSubscrTest->m_pCtx ); - verify ( status == ECA_NORMAL ); - firstUpdateEvent = epicsEventMustCreate ( epicsEventEmpty ); - verify ( firstUpdateEvent ); - status = ca_create_subscription ( - DBR_TIME_LONG, - nElem, - pMultiThreadSubscrTest->m_chan, - DBE_VALUE, - testMultithreadSubscrSubscrCallback, - firstUpdateEvent, - & id ); - verify ( status == ECA_NORMAL ); - status = ca_flush_io (); - verify ( status == ECA_NORMAL ); - /* wait for first update */ - eventWaitStatus = epicsEventWaitWithTimeout ( - firstUpdateEvent, 60.0 * 10 ); - verify ( eventWaitStatus == epicsEventWaitOK ); - epicsEventDestroy ( firstUpdateEvent ); - status = ca_clear_subscription ( id ); - verify ( status == ECA_NORMAL ); - epicsMutexMustLock ( pMultiThreadSubscrTest->m_mutex ); - pMultiThreadSubscrTest->m_nUpdatesReceived++; - testComplete = ( pMultiThreadSubscrTest->m_nUpdatesReceived == - pMultiThreadSubscrTest->m_nUpdatesRequired ); - pMultiThreadSubscrTest->m_testComplete = testComplete; - epicsMutexUnlock ( pMultiThreadSubscrTest->m_mutex ); - if ( testComplete ) { - epicsEventSignal ( pMultiThreadSubscrTest->m_testCompleteEvent ); - } -} - -void testMultithreadSubscrConnHandler ( struct connection_handler_args args ) -{ - MultiThreadSubscrTest * const pMultiThreadSubscrTest = - ( MultiThreadSubscrTest * ) ca_puser ( args.chid ); - epicsMutexMustLock ( pMultiThreadSubscrTest->m_mutex ); - if ( !pMultiThreadSubscrTest->m_testInitiated && - args.op == CA_OP_CONN_UP ) { - int i; - pMultiThreadSubscrTest->m_testInitiated = TRUE; - for ( i = 0; i < pMultiThreadSubscrTest->m_nUpdatesRequired; i++ ) { - char threadname[64]; - epicsThreadId threadId; - sprintf(threadname, "testSubscr%06u", i); - threadId = epicsThreadCreate ( threadname, - epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackSmall), - testMultithreadSubscrCreateSubscr, - pMultiThreadSubscrTest ); - verify ( threadId ); - } - } - epicsMutexUnlock ( pMultiThreadSubscrTest->m_mutex ); -} - -void testMultithreadSubscr ( void * pParm ) -{ - MultiThreadSubscrTest * const pMultiThreadSubscrTest = - ( MultiThreadSubscrTest * ) pParm; - int status; - unsigned i; - - status = ca_context_create ( ca_enable_preemptive_callback ); - verify ( status == ECA_NORMAL ); - pMultiThreadSubscrTest->m_pCtx = ca_current_context (); - verify ( pMultiThreadSubscrTest->m_pCtx ); - status = ca_create_channel ( - pMultiThreadSubscrTest->m_chanName, - testMultithreadSubscrConnHandler, - pMultiThreadSubscrTest, - CA_PRIORITY_MIN, - & pMultiThreadSubscrTest->m_chan ); - verify ( status == ECA_NORMAL ); - - showProgressBegin ( "verifyMultithreadSubscr", - pMultiThreadSubscrTest->m_interestLevel ); - i = 0; - while ( TRUE ) { - int success = FALSE; - epicsEventWaitStatus eventWaitStatus; - epicsMutexMustLock ( pMultiThreadSubscrTest->m_mutex ); - success = pMultiThreadSubscrTest->m_testComplete; - epicsMutexUnlock ( pMultiThreadSubscrTest->m_mutex ); - if ( success ) { - break; - } - eventWaitStatus = epicsEventWaitWithTimeout ( - pMultiThreadSubscrTest->m_testCompleteEvent, 0.1 ); - verify ( eventWaitStatus == epicsEventWaitOK || - eventWaitStatus == epicsEventWaitTimeout ); - if ( i++ % 100 == 0u ) - showProgress ( pMultiThreadSubscrTest->m_interestLevel ); - verify ( i < 1000 ); - } - showProgressEnd ( pMultiThreadSubscrTest->m_interestLevel ); - - status = ca_clear_channel ( pMultiThreadSubscrTest->m_chan ); - verify ( status == ECA_NORMAL ); - ca_context_destroy (); - epicsEventSignal ( pMultiThreadSubscrTest->m_threadExitEvent ); -} - -/* - * test installation of subscriptions similar to usage paterns - * employed by modern versions of the sequencer - */ -void verifyMultithreadSubscr ( const char * pName, unsigned interestLevel ) -{ - static unsigned nSubscr = 3000; - epicsThreadId threadId; - MultiThreadSubscrTest * const pMultiThreadSubscrTest = - (MultiThreadSubscrTest*) calloc ( 1, - sizeof ( MultiThreadSubscrTest ) ); - verify ( pMultiThreadSubscrTest); - pMultiThreadSubscrTest->m_mutex = epicsMutexMustCreate (); - verify ( pMultiThreadSubscrTest->m_mutex ); - pMultiThreadSubscrTest->m_testCompleteEvent = - epicsEventMustCreate ( epicsEventEmpty ); - verify ( pMultiThreadSubscrTest->m_testCompleteEvent ); - pMultiThreadSubscrTest->m_threadExitEvent = - epicsEventMustCreate ( epicsEventEmpty ); - verify ( pMultiThreadSubscrTest->m_threadExitEvent ); - strncpy ( pMultiThreadSubscrTest->m_chanName, pName, - sizeof ( pMultiThreadSubscrTest->m_chanName ) ); - pMultiThreadSubscrTest->m_chanName - [ sizeof ( pMultiThreadSubscrTest->m_chanName ) - 1u ] = '\0'; - pMultiThreadSubscrTest->m_nUpdatesRequired = nSubscr; - pMultiThreadSubscrTest->m_interestLevel = interestLevel; - threadId = epicsThreadCreate ( - "testMultithreadSubscr", - epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackSmall), - testMultithreadSubscr, pMultiThreadSubscrTest ); - verify ( threadId ); - { - epicsEventWaitStatus eventWaitStatus; - eventWaitStatus = epicsEventWaitWithTimeout ( - pMultiThreadSubscrTest->m_threadExitEvent, 1000.0 ); - verify ( eventWaitStatus == epicsEventWaitOK ); - } - epicsEventDestroy ( pMultiThreadSubscrTest->m_testCompleteEvent ); - epicsEventDestroy ( pMultiThreadSubscrTest->m_threadExitEvent ); - epicsMutexDestroy ( pMultiThreadSubscrTest->m_mutex ); - free ( pMultiThreadSubscrTest ); -} - -void fdManagerVerify ( const char * pName, unsigned interestLevel ) -{ - int status; - fdctx * mgrCtx; - struct timeval tmo; - chid newChan; - evid subscription; - unsigned eventCount = 0u; - epicsTimeStamp begin, end; - - mgrCtx = fdmgr_init (); - verify ( mgrCtx ); - - showProgressBegin ( "fdManagerVerify", interestLevel ); - - status = ca_add_fd_registration ( fdRegCB, mgrCtx ); - verify ( status == ECA_NORMAL ); - - status = ca_create_channel ( pName, 0, 0, 0, & newChan ); - verify ( status == ECA_NORMAL ); - - while ( ca_state ( newChan ) != cs_conn ) { - tmo.tv_sec = 6000; - tmo.tv_usec = 0; - status = fdmgr_pend_event ( mgrCtx, & tmo ); - verify ( status >= 0 ); - } - - showProgress ( interestLevel ); - - status = ca_add_event ( DBR_FLOAT, newChan, - nUpdatesTester, & eventCount, & subscription ); - verify ( status == ECA_NORMAL ); - - status = ca_flush_io (); - verify ( status == ECA_NORMAL ); - - while ( eventCount < 1 ) { - tmo.tv_sec = 6000; - tmo.tv_usec = 0; - status = fdmgr_pend_event ( mgrCtx, & tmo ); - verify ( status >= 0 ); - } - - showProgress ( interestLevel ); - - status = ca_clear_event ( subscription ); - verify ( status == ECA_NORMAL ); - - status = ca_flush_io (); - verify ( status == ECA_NORMAL ); - - /* look for infinite loop in fd manager schedualing */ - epicsTimeGetCurrent ( & begin ); - eventCount = 0u; - while ( 1 ) { - double delay; - tmo.tv_sec = 1; - tmo.tv_usec = 0; - status = fdmgr_pend_event ( mgrCtx, & tmo ); - verify ( status >= 0 ); - epicsTimeGetCurrent ( & end ); - delay = epicsTimeDiffInSeconds ( & end, & begin ); - if ( delay >= 1.0 ) { - break; - } - verify ( eventCount++ < 100 ); - } - - showProgress ( interestLevel ); - - status = ca_clear_channel ( newChan ); - verify ( status == ECA_NORMAL ); - - status = ca_add_fd_registration ( 0, 0 ); - verify ( status == ECA_NORMAL ); - - status = fdmgr_delete ( mgrCtx ); - verify ( status >= 0 ); - - showProgressEnd ( interestLevel ); -} - -void verifyConnectWithDisconnectedChannels ( - const char *pName, unsigned interestLevel ) -{ - int status; - chid bogusChan[300]; - chid validChan; - unsigned i; - - showProgressBegin ( "verifyConnectWithDisconnectedChannels", interestLevel ); - - for ( i= 0u; i < NELEMENTS ( bogusChan ); i++ ) { - char buf[256]; - sprintf ( buf, "aChannelThatShouldNeverNeverNeverExist%u", i ); - status = ca_create_channel ( buf, 0, 0, 0, & bogusChan[i] ); - verify ( status == ECA_NORMAL ); - } - - status = ca_pend_io ( 0.001 ); - verify ( status == ECA_TIMEOUT ); - - /* wait a long time for the search interval to increase */ - for ( i= 0u; i < 10; i++ ) { - epicsThreadSleep ( 1.0 ); - showProgress ( interestLevel ); - } - - status = ca_create_channel ( pName, 0, 0, 0, & validChan ); - verify ( status == ECA_NORMAL ); - - /* - * we should be able to connect to a valid - * channel within a reasonable delay even - * though there is one permanently - * diasconnected channel - */ - status = ca_pend_io ( timeoutToPendIO ); - verify ( status == ECA_NORMAL ); - - status = ca_clear_channel ( validChan ); - verify ( status == ECA_NORMAL ); - - for ( i= 0u; i < NELEMENTS ( bogusChan ); i++ ) { - status = ca_clear_channel ( bogusChan[i] ); - verify ( status == ECA_NORMAL ); - } - - showProgressEnd ( interestLevel ); -} - -void verifyClearChannelOnDisconnectCallback ( - struct connection_handler_args args ) -{ - int * pDisconnectFlag = ca_puser ( args.chid ); - if ( args.op == CA_OP_CONN_DOWN ) { - ca_clear_channel ( args.chid ); - *pDisconnectFlag = 1; - } -} - -void noopExceptionCallback ( struct exception_handler_args args ) -{ -} - -void verifyDisconnect ( - const char * pName, unsigned interestLevel ) -{ - int disconnectFlag = 0; - unsigned count = 0; - chid chan0; - chid chan1; - int status; - - status = ca_create_channel ( - pName, verifyClearChannelOnDisconnectCallback, - & disconnectFlag, 0, & chan0 ); - SEVCHK ( status, NULL ); - - fprintf ( stdout, "Waiting for test channel to connect." ); - fflush ( stdout ); - do { - ca_pend_event ( 0.1 ); - if ( count++%50 == 0 ) { - fprintf ( stdout, "." ); - fflush ( stdout ); - } - } while ( ca_state ( chan0 ) != cs_conn ); - fprintf ( stdout, "confirmed.\n" ); - - /* - * if its a local channel and will never disconnect - * then skip the portions of this test that cant be - * completed. - */ - if ( ca_get_ioc_connection_count () == 0 ) { - status = ca_clear_channel ( chan0 ); - SEVCHK ( status, NULL ); - return; - } - - status = ca_add_exception_event ( noopExceptionCallback, 0 ); - SEVCHK ( status, NULL ); - - fprintf ( stdout, "Please force test channel to disconnect." ); - fflush ( stdout ); - do { - ca_pend_event ( 0.1 );; - if ( count++%50 == 0 ) { - fprintf ( stdout, "." ); - fflush ( stdout ); - } - } while ( ! disconnectFlag ); - fprintf ( stdout, "confirmed.\n" ); - /* channel cleared by disconnect handler */ - - status = ca_create_channel ( - pName, 0, 0, 0, & chan1 ); - SEVCHK ( status, NULL ); - - fprintf ( stdout, "Waiting for test channel to connect." ); - fflush ( stdout ); - while ( ca_state ( chan1 ) != cs_conn ) { - ca_pend_event ( 5.0 ); - fprintf ( stdout, "." ); - fflush ( stdout ); - } - status = ca_clear_channel ( chan1 ); - SEVCHK ( status, NULL ); - fprintf ( stdout, "confirmed.\n" ); - - status = ca_add_exception_event ( 0, 0 ); - SEVCHK ( status, NULL ); -} - -void verifyName ( - const char * pName, unsigned interestLevel ) -{ - chid chan; - int status = ca_create_channel ( - pName, 0, 0, 0, & chan ); - SEVCHK ( status, NULL ); - if ( strcmp ( pName, ca_name ( chan ) ) != 0 ) { - printf ( "Canonical name for channel was \"%s\"\n", ca_name ( chan ) ); - } - status = ca_clear_channel ( chan ); - SEVCHK ( status, NULL ); -} - -void verifyContextRundownFlush ( const char * pName, unsigned interestLevel ) -{ - unsigned i; - - showProgressBegin ( "verifyContextRundownFlush", interestLevel ); - - for ( i=0u; i < 1000; i++ ) { - const dbr_double_t stim = i; - - { - chid chan; - int status; - status = ca_context_create ( ca_disable_preemptive_callback ); - SEVCHK ( status, "context create failed" ); - - status = ca_create_channel ( pName, 0, 0, 0, & chan ); - /* - * currently in-memory channels cant be used with this test - * !!!! FIX ME, FIX ME, FIX ME, FIX ME !!!! - */ - if ( status != ECA_UNAVAILINSERV ) { - SEVCHK ( status, NULL ); - - status = ca_pend_io( timeoutToPendIO ); - SEVCHK ( status, "channel connect failed" ); - - status = ca_put ( DBR_DOUBLE, chan, & stim ); - SEVCHK ( status, "channel put failed" ); - - status = ca_clear_channel ( chan ); - SEVCHK ( status, NULL ); - } - ca_context_destroy (); - } - - { - chid chan; - int status; - dbr_double_t resp; - status = ca_context_create ( ca_disable_preemptive_callback ); - SEVCHK ( status, "context create failed" ); - - status = ca_create_channel ( pName, 0, 0, 0, & chan ); - SEVCHK ( status, NULL ); - /* - * currently in-memory channels cant be used with this test - * !!!! FIX ME, FIX ME, FIX ME, FIX ME !!!! - */ - if ( status != ECA_UNAVAILINSERV ) { - status = ca_pend_io( timeoutToPendIO ); - SEVCHK ( status, "channel connect failed" ); - - status = ca_get ( DBR_DOUBLE, chan, & resp ); - SEVCHK ( status, "channel get failed" ); - - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, "get, pend io failed" ); - - verify ( stim == resp ); - - status = ca_clear_channel ( chan ); - SEVCHK ( status, NULL ); - } - ca_context_destroy (); - } - - if ( i % 100 == 0 ) { - showProgress ( interestLevel ); - } - } - - showProgressEnd ( interestLevel ); -} - -void verifyContextRundownChanStillExist ( - const char * pName, unsigned interestLevel ) -{ - chid chan[10000]; - int status; - unsigned i; - - showProgressBegin ( "verifyContextRundownChanStillExist", interestLevel ); - - status = ca_context_create ( ca_disable_preemptive_callback ); - SEVCHK ( status, "context create failed" ); - - for ( i = 0; i < NELEMENTS ( chan ); i++ ) { - status = ca_create_channel ( pName, 0, 0, 0, & chan[i] ); - /* - * currently in-memory channels cant be used with this test - * !!!! FIX ME, FIX ME, FIX ME, FIX ME !!!! - */ - if ( status == ECA_UNAVAILINSERV ) { - break; - } - SEVCHK ( status, NULL ); - } - - status = ca_pend_io( timeoutToPendIO ); - SEVCHK ( status, "channel connect failed" ); - - ca_context_destroy (); - - showProgressEnd ( interestLevel ); -} - -int acctst ( const char * pName, unsigned interestLevel, unsigned channelCount, - unsigned repetitionCount, enum ca_preemptive_callback_select select ) -{ - chid chan; - int status; - unsigned i; - appChan *pChans; - unsigned connections; - unsigned maxArrayBytes = 10000000; - - printf ( "CA Client V%s, channel name \"%s\", timeout %g\n", - ca_version (), pName, timeoutToPendIO ); - if ( select == ca_enable_preemptive_callback ) { - printf ( "Preemptive call back is enabled.\n" ); - } - - { - char tmpString[32]; - sprintf ( tmpString, "%u", maxArrayBytes ); - epicsEnvSet ( "EPICS_CA_MAX_ARRAY_BYTES", tmpString ); - } - - /* - * this test creates, and then destroys, a private CA context - */ - multiSubscrDestroyNoLateCallbackTest ( pName, interestLevel ); - - status = ca_context_create ( select ); - SEVCHK ( status, NULL ); - - verifyDisconnect ( pName, interestLevel ); - verifyImmediateTearDown ( pName, select, interestLevel ); - verifyTearDownWhenChannelConnected ( pName, select, interestLevel ); - - verifyDataTypeMacros (); - - connections = ca_get_ioc_connection_count (); - verify ( connections == 0u ); - unequalServerBufferSizeTest ( pName, interestLevel ); - clearChannelInGetCallbackTest ( pName, interestLevel ); - clearChannelInPutCallbackTest ( pName, interestLevel ); - clearChannelInSubscrCallbackTest ( pName, interestLevel ); - monitorAddConnectionCallbackTest ( pName, interestLevel ); - - showProgressBegin ( "connecting to test channel", interestLevel ); - status = ca_search ( pName, & chan ); - SEVCHK ( status, NULL ); - status = ca_pend_io ( timeoutToPendIO ); - SEVCHK ( status, NULL ); - showProgressEnd ( interestLevel ); - - printf ( "native type was %s, native count was %lu\n", - dbf_type_to_text ( ca_field_type ( chan ) ), - ca_element_count ( chan ) ); - - connections = ca_get_ioc_connection_count (); - verify ( connections == 1u || connections == 0u ); - if ( connections == 0u ) { - printf ( "testing with a local channel\n" ); - } - - verifyName ( pName, interestLevel ); - verifyConnectWithDisconnectedChannels ( pName, interestLevel ); - grEnumTest ( chan, interestLevel ); - test_sync_groups ( chan, interestLevel ); - verifyChannelPriorities ( pName, interestLevel ); - verifyTimeStamps ( chan, interestLevel ); - verifyOldPend ( interestLevel ); - exceptionTest ( chan, interestLevel ); - arrayTest ( chan, maxArrayBytes, interestLevel ); - verifyMonitorSubscriptionFlushIO ( chan, interestLevel ); - monitorSubscriptionFirstUpdateTest ( pName, chan, interestLevel ); - ctrlDoubleTest ( chan, interestLevel ); - verifyBlockInPendIO ( chan, interestLevel ); - verifyAnalogIO ( chan, DBR_FLOAT, FLT_MIN, FLT_MAX, - FLT_MIN_EXP, FLT_MAX_EXP, FLT_EPSILON, interestLevel ); - verifyAnalogIO ( chan, DBR_DOUBLE, DBL_MIN, DBL_MAX, - DBL_MIN_EXP, DBL_MAX_EXP, DBL_EPSILON, interestLevel ); - verifyLongIO ( chan, interestLevel ); - verifyShortIO ( chan, interestLevel ); - multiSubscriptionDeleteTest ( chan, interestLevel ); - singleSubscriptionDeleteTest ( chan, interestLevel ); - channelClearWithEventTrafficTest ( pName, interestLevel ); - eventClearAndMultipleMonitorTest ( chan, interestLevel ); - verifyHighThroughputRead ( chan, interestLevel ); - verifyHighThroughputWrite ( chan, interestLevel ); - verifyHighThroughputReadCallback ( chan, interestLevel ); - verifyHighThroughputWriteCallback ( chan, interestLevel ); - verifyBadString ( chan, interestLevel ); - verifyMultithreadSubscr ( pName, interestLevel ); - if ( select != ca_enable_preemptive_callback ) { - fdManagerVerify ( pName, interestLevel ); - } - - /* - * CA pend event delay accuracy test - * (CA asssumes that search requests can be sent - * at least every 25 mS on all supported os) - */ - printf ( "\n" ); - pend_event_delay_test ( 1.0 ); - pend_event_delay_test ( 0.1 ); - pend_event_delay_test ( 0.25 ); - - /* ca_channel_status ( 0 ); */ - ca_client_status ( 0 ); - /* ca_client_status ( 6u ); info about each channel */ - - pChans = calloc ( channelCount, sizeof ( *pChans ) ); - verify ( pChans ); - - for ( i = 0; i < channelCount; i++ ) { - strncpy ( pChans[ i ].name, pName, sizeof ( pChans[ i ].name ) ); - pChans[ i ].name[ sizeof ( pChans[i].name ) - 1 ] = '\0'; - } - - verifyConnectionHandlerConnect ( pChans, channelCount, repetitionCount, interestLevel ); - verifyBlockingConnect ( pChans, channelCount, repetitionCount, interestLevel ); - verifyClear ( pChans, interestLevel ); - - verifyReasonableBeaconPeriod ( chan, interestLevel ); - - /* - * Verify that we can do IO with the new types for ALH - */ -#if 0 - if ( ca_read_access (chan) && ca_write_access (chan) ) { - { - dbr_put_ackt_t acktIn = 1u; - dbr_put_acks_t acksIn = 1u; - struct dbr_stsack_string stsackOut; - - SEVCHK ( ca_put ( DBR_PUT_ACKT, chan, &acktIn ), NULL ); - SEVCHK ( ca_put ( DBR_PUT_ACKS, chan, &acksIn ), NULL ); - SEVCHK ( ca_get ( DBR_STSACK_STRING, chan, &stsackOut ), NULL ); - SEVCHK ( ca_pend_io ( timeoutToPendIO ), NULL ); - } -#endif - - /* test that ca_task_exit () works when there is still one channel remaining */ - /* status = ca_clear_channel ( chan ); */ - /* SEVCHK ( status, NULL ); */ - - caTaskExitTest ( interestLevel ); - - verifyContextRundownFlush ( pName, interestLevel ); - verifyContextRundownChanStillExist ( pName, interestLevel ); - - free ( pChans ); - - printf ( "\nTest Complete\n" ); - - epicsExit ( EXIT_SUCCESS ); - - return 0; -} - - diff --git a/src/ca/client/acctstMain.c b/src/ca/client/acctstMain.c deleted file mode 100644 index 4c700a30b..000000000 --- a/src/ca/client/acctstMain.c +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "cadef.h" -#include "caDiagnostics.h" - -int main ( int argc, char **argv ) -{ - unsigned progressLoggingLevel; - unsigned channelCount; - unsigned repetitionCount; - enum ca_preemptive_callback_select preempt; - int aBoolean; - - - if ( argc < 2 || argc > 6 ) { - printf ("usage: %s [progress logging level] [channel count] " - "[repetition count] [enable preemptive callback]\n", - argv[0] ); - return 1; - } - - if ( argc >= 3 ) { - progressLoggingLevel = atoi ( argv[2] ); - } - else { - progressLoggingLevel = 0; - } - - if ( argc >= 4 ) { - channelCount = atoi ( argv[3] ); - } - else { - channelCount = 20000; - } - - if ( argc >= 5 ) { - repetitionCount = atoi ( argv[4] ); - } - else { - repetitionCount = 1; - } - - if ( argc >= 6 ) { - aBoolean = atoi ( argv[5] ); - } - else { - aBoolean = 0; - } - if ( aBoolean ) { - preempt = ca_enable_preemptive_callback; - } - else { - preempt = ca_disable_preemptive_callback; - } - - acctst ( argv[1], progressLoggingLevel, channelCount, repetitionCount, preempt ); - - return 0; -} diff --git a/src/ca/client/acctstRegister.cpp b/src/ca/client/acctstRegister.cpp deleted file mode 100644 index e75ed7fe3..000000000 --- a/src/ca/client/acctstRegister.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * CA client library diagnostics IOC shell registration - * Authors: - * Jeff Hill - */ - -#include -#include "caDiagnostics.h" - -/* Information needed by iocsh */ -static const iocshArg acctstArg0 = { "channel name", iocshArgString }; -static const iocshArg acctstArg1 = { "interest level", iocshArgInt }; -static const iocshArg acctstArg2 = { "channel count", iocshArgInt }; -static const iocshArg acctstArg3 = { "repetition count", iocshArgInt }; -static const iocshArg acctstArg4 = { "preemptive callback select", iocshArgInt }; - -static const iocshArg *acctstArgs[] = -{ - &acctstArg0, - &acctstArg1, - &acctstArg2, - &acctstArg3, - &acctstArg4 -}; -static const iocshFuncDef acctstFuncDef = {"acctst", 5, acctstArgs}; - - -/* Wrapper called by iocsh, selects the argument types that print needs */ -static void acctstCallFunc(const iocshArgBuf *args) { - if ( args[1].ival < 0 ) { - printf ( "negative interest level not allowed\n" ); - return; - } - if ( args[2].ival < 0 ) { - printf ( "negative channel count not allowed\n" ); - return; - } - if ( args[3].ival < 0 ) { - printf ( "negative repetition count not allowed\n" ); - return; - } - acctst ( - args[0].sval, /* channel name */ - ( unsigned ) args[1].ival, /* interest level */ - ( unsigned ) args[2].ival, /* channel count */ - ( unsigned ) args[3].ival, /* repetition count */ - ( ca_preemptive_callback_select ) args[4].ival ); /* preemptive callback select */ -} - -struct AutoInit { - AutoInit (); -}; - -AutoInit :: AutoInit () -{ - iocshRegister ( &acctstFuncDef, acctstCallFunc ); -} - -AutoInit autoInit; - diff --git a/src/ca/client/addrList.h b/src/ca/client/addrList.h deleted file mode 100644 index c06c8b2bc..000000000 --- a/src/ca/client/addrList.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef addrListh -#define addrListh - -#include "shareLib.h" -#include "envDefs.h" -#include "osiSock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void epicsShareAPI configureChannelAccessAddressList - ( struct ELLLIST *pList, SOCKET sock, unsigned short port ); - -epicsShareFunc int epicsShareAPI addAddrToChannelAccessAddressList - ( struct ELLLIST *pList, const ENV_PARAM *pEnv, - unsigned short port, int ignoreNonDefaultPort ); - -epicsShareFunc void epicsShareAPI printChannelAccessAddressList - ( const struct ELLLIST *pList ); - -epicsShareFunc void epicsShareAPI removeDuplicateAddresses - ( struct ELLLIST *pDestList, ELLLIST *pSrcList, int silent); - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef addrListh */ - diff --git a/src/ca/client/autoPtrFreeList.h b/src/ca/client/autoPtrFreeList.h deleted file mode 100644 index 7dc73609a..000000000 --- a/src/ca/client/autoPtrFreeList.h +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef autoPtrFreeListh -#define autoPtrFreeListh - -#ifdef epicsExportSharedSymbols -# define autoPtrFreeListh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "tsFreeList.h" -#include "compilerDependencies.h" - -#ifdef autoPtrFreeListh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -#endif - -template < class T, unsigned N = 0x400, class MUTEX = epicsMutex > -class autoPtrFreeList { -public: - autoPtrFreeList ( tsFreeList < T, N, MUTEX > &, T * ); - ~autoPtrFreeList (); - T & operator * () const; - T * operator -> () const; - T * get () const; - T * release (); -private: - T * p; - tsFreeList < T, N, MUTEX > & freeList; - // not implemented - autoPtrFreeList & operator = ( const autoPtrFreeList & ); - autoPtrFreeList ( const autoPtrFreeList < T, N, MUTEX > & ); -}; - -template < class T, unsigned N, class MUTEX > -inline autoPtrFreeList < T, N, MUTEX >::autoPtrFreeList ( - tsFreeList < T, N, MUTEX > & freeListIn, T * pIn ) : - p ( pIn ), freeList ( freeListIn ) {} - -template < class T, unsigned N, class MUTEX > -inline autoPtrFreeList < T, N, MUTEX >::~autoPtrFreeList () -{ - if ( this->p ) { - this->p->~T(); - // its probably a good idea to require that the class has placement delete - // by calling it during cleanup if the compiler supports it -# if defined ( CXX_PLACEMENT_DELETE ) - T::operator delete ( this->p, this->freeList ); -# else - this->freeList.release ( this->p ); -# endif - } -} - -template < class T, unsigned N, class MUTEX > -inline T & autoPtrFreeList < T, N, MUTEX >::operator * () const -{ - return * this->p; -} - -template < class T, unsigned N, class MUTEX > -inline T * autoPtrFreeList < T, N, MUTEX >::operator -> () const -{ - return this->p; -} - -template < class T, unsigned N, class MUTEX > -inline T * autoPtrFreeList < T, N, MUTEX >::get () const -{ - return this->p; -} - -template < class T, unsigned N, class MUTEX > -inline T * autoPtrFreeList < T, N, MUTEX >::release () -{ - T *pTmp = this->p; - this->p = 0; - return pTmp; -} - -#endif // #ifdef autoPtrFreeListh diff --git a/src/ca/client/autoPtrRecycle.h b/src/ca/client/autoPtrRecycle.h deleted file mode 100644 index 173e148b8..000000000 --- a/src/ca/client/autoPtrRecycle.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef autoPtrRecycleh -#define autoPtrRecycleh - -template < class T > -class autoPtrRecycle { -public: - autoPtrRecycle ( - epicsGuard < epicsMutex > &, chronIntIdResTable < baseNMIU > &, - cacRecycle &, T * ); - ~autoPtrRecycle (); - T & operator * () const; - T * operator -> () const; - T * get () const; - T * release (); -private: - T * p; - cacRecycle & r; - chronIntIdResTable < baseNMIU > & ioTable; - epicsGuard < epicsMutex > & guard; - // not implemented - autoPtrRecycle ( const autoPtrRecycle & ); - autoPtrRecycle & operator = ( const autoPtrRecycle & ); -}; - -template < class T > -inline autoPtrRecycle::autoPtrRecycle ( - epicsGuard < epicsMutex > & guardIn, chronIntIdResTable < baseNMIU > & tbl, - cacRecycle & rIn, T * pIn ) : - p ( pIn ), r ( rIn ), ioTable ( tbl ), guard ( guardIn ) {} - -template < class T > -inline autoPtrRecycle::~autoPtrRecycle () -{ - if ( this->p ) { - baseNMIU *pb = this->p; - this->ioTable.remove ( *pb ); - pb->destroy ( this->guard, this->r ); - } -} - -template < class T > -inline T & autoPtrRecycle::operator * () const -{ - return * this->p; -} - -template < class T > -inline T * autoPtrRecycle::operator -> () const -{ - return this->p; -} - -template < class T > -inline T * autoPtrRecycle::get () const -{ - return this->p; -} - -template < class T > -inline T * autoPtrRecycle::release () -{ - T *pTmp = this->p; - this->p = 0; - return pTmp; -} - -#endif // #ifdef autoPtrRecycleh diff --git a/src/ca/client/baseNMIU.cpp b/src/ca/client/baseNMIU.cpp deleted file mode 100644 index 20f153b0a..000000000 --- a/src/ca/client/baseNMIU.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, the Regents of the University of California. - * - * Author: Jeff Hill - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "iocinf.h" -#include "nciu.h" -#include "netIO.h" - -baseNMIU::~baseNMIU () -{ -} - -void baseNMIU::forceSubscriptionUpdate ( - epicsGuard < epicsMutex > &, nciu & ) -{ -} - - - - diff --git a/src/ca/client/bhe.cpp b/src/ca/client/bhe.cpp deleted file mode 100644 index d6f1796be..000000000 --- a/src/ca/client/bhe.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include -#include -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "virtualCircuit.h" -#include "bhe.h" - -/* - * set average to -1.0 so that when the next beacon - * occurs we can distinguish between: - * o new server - * o existing server's beacon we are seeing - * for the first time shortly after program - * start up - * - * if creating this in response to a search reply - * and not in response to a beacon then - * we set the beacon time stamp to - * zero (so we can correctly compute the period - * between the 1st and 2nd beacons) - */ -bhe::bhe ( epicsMutex & mutexIn, const epicsTime & initialTimeStamp, - unsigned initialBeaconNumber, const inetAddrID & addr ) : - inetAddrID ( addr ), timeStamp ( initialTimeStamp ), averagePeriod ( - DBL_MAX ), - mutex ( mutexIn ), pIIU ( 0 ), lastBeaconNumber ( initialBeaconNumber ) -{ -# ifdef DEBUG - { - char name[64]; - addr.name ( name, sizeof ( name ) ); - ::printf ( "created beacon entry for %s\n", name ); - } -# endif -} - -bhe::~bhe () -{ -} - -void bhe::beaconAnomalyNotify ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->pIIU ) { - this->pIIU->beaconAnomalyNotify ( guard ); - } -} - -#ifdef DEBUG -void bhe::logBeacon ( const char * pDiagnostic, - const double & currentPeriod, - const epicsTime & currentTime ) -{ - if ( this->pIIU ) { - char name[64]; - this->name ( name, sizeof ( name ) ); - char date[64]; - currentTime.strftime ( date, sizeof ( date ), - "%a %b %d %Y %H:%M:%S.%f"); - ::printf ( "%s cp=%g ap=%g %s %s\n", - pDiagnostic, currentPeriod, - this->averagePeriod, name, date ); - } -} -#else -inline void bhe::logBeacon ( const char * /* pDiagnostic */, - const double & /* currentPeriod */, - const epicsTime & /* currentTime */ ) -{ -} -#endif - -#ifdef DEBUG -void bhe::logBeaconDiscard ( unsigned beaconAdvance, - const epicsTime & currentTime ) -{ - if ( this->pIIU ) { - char name[64]; - this->name ( name, sizeof ( name ) ); - char date[64]; - currentTime.strftime ( date, sizeof ( date ), - "%a %b %d %Y %H:%M:%S.%f"); - ::printf ( "bb %u %s %s\n", - beaconAdvance, name, date ); - } -} -#else -void bhe::logBeaconDiscard ( unsigned /* beaconAdvance */, - const epicsTime & /* currentTime */ ) -{ -} -#endif - -/* - * update beacon period - * - * updates beacon period, and looks for beacon anomalies - */ -bool bhe::updatePeriod ( - epicsGuard < epicsMutex > & guard, const epicsTime & programBeginTime, - const epicsTime & currentTime, ca_uint32_t beaconNumber, - unsigned protocolRevision ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - // - // this block is enetered if the beacon was created as a side effect of - // creating a connection and so we dont yet know the first beacon time - // and sequence number - // - if ( this->timeStamp == epicsTime () ) { - if ( CA_V410 ( protocolRevision ) ) { - this->lastBeaconNumber = beaconNumber; - } - - this->beaconAnomalyNotify ( guard ); - - /* - * this is the 1st beacon seen - the beacon time stamp - * was not initialized during BHE create because - * a TCP/IP connection created the beacon. - * (nothing to do but set the beacon time stamp and return) - */ - this->timeStamp = currentTime; - - logBeacon ( "fb", - DBL_MAX, currentTime ); - - return false; - } - - // 1) detect beacon duplications due to redundant routes - // 2) detect lost beacons due to input queue overrun or damage - if ( CA_V410 ( protocolRevision ) ) { - unsigned beaconSeqAdvance; - if ( beaconNumber >= this->lastBeaconNumber ) { - beaconSeqAdvance = beaconNumber - this->lastBeaconNumber; - } - else { - beaconSeqAdvance = ( ca_uint32_max - this->lastBeaconNumber ) + beaconNumber; - } - this->lastBeaconNumber = beaconNumber; - - // throw out sequence numbers just prior to, or the same as, the last one received - // (this situation is probably caused by a temporary duplicate route ) - if ( beaconSeqAdvance == 0 || beaconSeqAdvance > ca_uint32_max - 256 ) { - logBeaconDiscard ( beaconSeqAdvance, currentTime ); - return false; - } - - // throw out sequence numbers that jump forward by only a few numbers - // (this situation is probably caused by a duplicate route - // or a beacon due to input queue overun) - if ( beaconSeqAdvance > 1 && beaconSeqAdvance < 4 ) { - logBeaconDiscard ( beaconSeqAdvance, currentTime ); - return false; - } - } - - // compute the beacon period (if we have seen at least two beacons) - bool netChange = false; - double currentPeriod = currentTime - this->timeStamp; - - if ( this->averagePeriod < 0.0 ) { - double totalRunningTime; - - this->beaconAnomalyNotify ( guard ); - - /* - * this is the 2nd beacon seen. We cant tell about - * the change in period at this point so we just - * initialize the average period and return. - */ - this->averagePeriod = currentPeriod; - - logBeacon ( "fp", currentPeriod, currentTime ); - - - /* - * ignore beacons seen for the first time shortly after - * init, but do not ignore beacons arriving with a short - * period because the IOC was rebooted soon after the - * client starts up. - */ - totalRunningTime = this->timeStamp - programBeginTime; - if ( currentPeriod <= totalRunningTime ) { - netChange = true; - } - } - else { - - /* - * Is this an IOC seen because of a restored - * network segment? - * - * It may be possible to get false triggers here - * if the client is busy, but this does not cause - * problems because the echo response will tell us - * that the server is available - */ - if ( currentPeriod >= this->averagePeriod * 1.25 ) { - - /* - * trigger on any missing beacon - * if connected to this server - */ - this->beaconAnomalyNotify ( guard ); - - if ( currentPeriod >= this->averagePeriod * 3.25 ) { - /* - * trigger on any 3 contiguous missing beacons - * if not connected to this server - */ - netChange = true; - } - logBeacon ( "bah", currentPeriod, currentTime ); - } - - /* - * Is this an IOC seen because of an IOC reboot - * (beacon come at a higher rate just after the - * IOC reboots). Lower tolarance here because we - * dont have to worry about lost beacons. - * - * It may be possible to get false triggers here - * if the client is busy, but this does not cause - * problems because the echo response will tell us - * that the server is available - */ - else if ( currentPeriod <= this->averagePeriod * 0.80 ) { - this->beaconAnomalyNotify ( guard ); - netChange = true; - logBeacon ( "bal", currentPeriod, currentTime ); - } - else if ( this->pIIU ) { - // update state of health for active virtual circuits - // if the beacon looks ok - this->pIIU->beaconArrivalNotify ( guard ); - logBeacon ( "vb", currentPeriod, currentTime ); - } - - // update a running average period - this->averagePeriod = currentPeriod * 0.125 + - this->averagePeriod * 0.875; - } - - this->timeStamp = currentTime; - - return netChange; -} - -void bhe::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->show ( guard, level ); -} - -void bhe::show ( epicsGuard < epicsMutex > &, unsigned level ) const -{ - char host [64]; - this->name ( host, sizeof ( host ) ); - if ( this->averagePeriod == -DBL_MAX ) { - ::printf ( "CA beacon hash entry for %s \n", - host ); - } - else { - ::printf ( "CA beacon hash entry for %s with period estimate %f\n", - host, this->averagePeriod ); - } - if ( level > 0u ) { - char date[64]; - this->timeStamp.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S"); - ::printf ( "\tbeacon number %u, on %s\n", - this->lastBeaconNumber, date ); - } -} - -double bhe::period ( epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->averagePeriod; -} - -epicsTime bhe::updateTime ( epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->timeStamp; -} - -void bhe::registerIIU ( - epicsGuard < epicsMutex > & guard, tcpiiu & iiu ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->pIIU = & iiu; -} - -void bhe::unregisterIIU ( - epicsGuard < epicsMutex > & guard, tcpiiu & iiu ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->pIIU == & iiu ) { - this->pIIU = 0; - this->timeStamp = epicsTime(); - this->averagePeriod = - DBL_MAX; - logBeacon ( "ui", this->averagePeriod, epicsTime::getCurrent () ); - } -} - -void bhe::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void * bheFreeStore::allocate ( size_t size ) -{ - return freeList.allocate ( size ); -} - -void bheFreeStore::release ( void * pCadaver ) -{ - freeList.release ( pCadaver ); -} - -bheMemoryManager::~bheMemoryManager () {} - - diff --git a/src/ca/client/bhe.h b/src/ca/client/bhe.h deleted file mode 100644 index 4da95202a..000000000 --- a/src/ca/client/bhe.h +++ /dev/null @@ -1,122 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#ifndef bheh -#define bheh - -#ifdef epicsExportSharedSymbols -# define bhehEpicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "tsDLList.h" -#include "tsFreeList.h" -#include "epicsTime.h" -#include "compilerDependencies.h" - -#ifdef bhehEpicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "inetAddrID.h" -#include "caProto.h" - -class tcpiiu; -class bheMemoryManager; - -// using a pure abstract wrapper class around the free list avoids -// Tornado 2.0.1 GNU compiler bugs -class epicsShareClass bheMemoryManager { -public: - virtual ~bheMemoryManager (); - virtual void * allocate ( size_t ) = 0; - virtual void release ( void * ) = 0; -}; - -class bhe : public tsSLNode < bhe >, public inetAddrID { -public: - epicsShareFunc bhe ( - epicsMutex &, const epicsTime & initialTimeStamp, - unsigned initialBeaconNumber, const inetAddrID & addr ); - epicsShareFunc ~bhe (); - epicsShareFunc bool updatePeriod ( - epicsGuard < epicsMutex > &, - const epicsTime & programBeginTime, - const epicsTime & currentTime, ca_uint32_t beaconNumber, - unsigned protocolRevision ); - epicsShareFunc double period ( epicsGuard < epicsMutex > & ) const; - epicsShareFunc epicsTime updateTime ( epicsGuard < epicsMutex > & ) const; - epicsShareFunc void show ( unsigned level ) const; - epicsShareFunc void show ( epicsGuard < epicsMutex > &, unsigned /* level */ ) const; - epicsShareFunc void registerIIU ( epicsGuard < epicsMutex > &, tcpiiu & ); - epicsShareFunc void unregisterIIU ( epicsGuard < epicsMutex > &, tcpiiu & ); - epicsShareFunc void * operator new ( size_t size, bheMemoryManager & ); -#ifdef CXX_PLACEMENT_DELETE - epicsShareFunc void operator delete ( void *, bheMemoryManager & ); -#endif -private: - epicsTime timeStamp; - double averagePeriod; - epicsMutex & mutex; - tcpiiu * pIIU; - ca_uint32_t lastBeaconNumber; - void beaconAnomalyNotify ( epicsGuard < epicsMutex > & ); - void logBeacon ( const char * pDiagnostic, - const double & currentPeriod, - const epicsTime & currentTime ); - void logBeaconDiscard ( unsigned beaconAdvance, - const epicsTime & currentTime ); - bhe ( const bhe & ); - bhe & operator = ( const bhe & ); - epicsShareFunc void operator delete ( void * ); -}; - -// using a wrapper class around the free list avoids -// Tornado 2.0.1 GNU compiler bugs -class bheFreeStore : public bheMemoryManager { -public: - bheFreeStore () {} - void * allocate ( size_t ); - void release ( void * ); -private: - tsFreeList < bhe, 0x100 > freeList; - bheFreeStore ( const bheFreeStore & ); - bheFreeStore & operator = ( const bheFreeStore & ); -}; - -inline void * bhe::operator new ( size_t size, - bheMemoryManager & mgr ) -{ - return mgr.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void bhe::operator delete ( void * pCadaver, - bheMemoryManager & mgr ) -{ - mgr.release ( pCadaver ); -} -#endif - -#endif // ifdef bheh - - diff --git a/src/ca/client/ca.rc b/src/ca/client/ca.rc deleted file mode 100644 index b1f87acb4..000000000 --- a/src/ca/client/ca.rc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "epicsVersion.h" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - PRODUCTVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_UNKNOWN - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments","Channel Access Library for EPICS\0" - VALUE "CompanyName", "The EPICS collaboration\0" - VALUE "FileDescription", "Channel Access Library\0" - VALUE "FileVersion", EPICS_VERSION_STRING "\0" - VALUE "InternalName", "ca\0" - VALUE "LegalCopyright", "Copyright (C) Univ. of California, Univ. of Chicago\0" - VALUE "OriginalFilename", "ca.dll\0" - VALUE "ProductName", "Experimental Physics and Industrial Control System (EPICS)\0" - VALUE "ProductVersion", EPICS_VERSION_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/ca/client/caConnTest.cpp b/src/ca/client/caConnTest.cpp deleted file mode 100644 index 21077398a..000000000 --- a/src/ca/client/caConnTest.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "cadef.h" -#include "epicsTime.h" - -static unsigned channelCount = 0u; -static unsigned connCount = 0u; -static bool subsequentConnect = false; - -epicsTime begin; - -extern "C" void caConnTestConnHandler ( struct connection_handler_args args ) -{ - if ( args.op == CA_OP_CONN_UP ) { - if ( connCount == 0u ) { - if ( subsequentConnect ) { - printf ("the first channel connected\n"); - begin = epicsTime::getCurrent (); - } - } - connCount++; - // printf ( "." ); - // fflush ( stdout ); - if ( connCount == channelCount ) { - epicsTime current = epicsTime::getCurrent (); - double delay = current - begin; - printf ( "all channels connected after %f sec ( %f sec per channel)\n", - delay, delay / channelCount ); - } - } - else if ( args.op == CA_OP_CONN_DOWN ) { - if ( connCount == channelCount ) { - printf ( "channels are disconnected\n" ); - subsequentConnect = true; - } - connCount--; - if ( connCount == 0u ) { - printf ( "all channels are disconnected\n" ); - } - } - else { - assert ( 0 ); - } -} - -void caConnTest ( const char *pNameIn, unsigned channelCountIn, double delayIn ) -{ - unsigned iteration = 0u; - int status; - unsigned i; - chid *pChans; - - channelCount = channelCountIn; - - pChans = new chid [channelCount]; - - while ( 1 ) { - connCount = 0u; - subsequentConnect = false; - begin = epicsTime::getCurrent (); - - printf ( "initializing CA client library\n" ); - - status = ca_task_initialize(); - SEVCHK ( status, "CA init failed" ); - - printf ( "creating channels\n" ); - - for ( i = 0u; i < channelCount; i++ ) { - status = ca_search_and_connect ( pNameIn, - &pChans[i], caConnTestConnHandler, 0 ); - SEVCHK ( status, "CA search problems" ); - } - - printf ( "all channels were created\n" ); - - ca_pend_event ( delayIn ); - - if ( iteration & 1 ) { - for ( i = 0u; i < channelCount; i++ ) { - status = ca_clear_channel ( pChans[i] ); - SEVCHK ( status, "ca_clear_channel() problems" ); - } - printf ( "all channels were destroyed\n" ); - } - - printf ( "shutting down CA client library\n" ); - - status = ca_task_exit (); - SEVCHK ( status, "task exit problems" ); - - iteration++; - } - - //delete [] pChans; -} diff --git a/src/ca/client/caConnTestMain.cpp b/src/ca/client/caConnTestMain.cpp deleted file mode 100644 index f3985801a..000000000 --- a/src/ca/client/caConnTestMain.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "caDiagnostics.h" - -int main ( int argc, char **argv ) -{ - double delay = 60.0 * 5.0; - unsigned count = 2000; - - if ( argc < 2 || argc > 4 ) { - printf ( "usage: %s < channel name > [ < count > ] [ < delay sec > ]\n", argv[0] ); - return -1; - } - - if ( argc >= 3 ) { - int nConverted = sscanf ( argv[2], "%u", &count ); - if ( nConverted != 1 ) { - printf ( "conversion failed, changing channel count arg \"%s\" to %u\n", - argv[1], count ); - } - } - - if ( argc >= 4 ) { - int nConverted = epicsScanDouble( argv[3], &delay ); - if ( nConverted != 1 ) { - printf ( "conversion failed, changing delay arg \"%s\" to %f\n", - argv[2], delay ); - } - } - - caConnTest ( argv[1], count, delay ); - - return 0; -} diff --git a/src/ca/client/caDiagnostics.h b/src/ca/client/caDiagnostics.h deleted file mode 100644 index 90221e1ed..000000000 --- a/src/ca/client/caDiagnostics.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef caDiagnosticsh -#define caDiagnosticsh - -#include "cadef.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum appendNumberFlag {appendNumber, dontAppendNumber}; -int catime ( const char *channelName, unsigned channelCount, enum appendNumberFlag appNF ); - -int acctst ( const char *pname, unsigned logggingInterestLevel, - unsigned channelCount, unsigned repetitionCount, - enum ca_preemptive_callback_select select ); - -#define CATIME_OK 0 -#define CATIME_ERROR -1 - -#ifdef __cplusplus -} -#endif - -void caConnTest ( const char *pNameIn, unsigned channelCountIn, double delayIn ); - -#endif /* caDiagnosticsh */ - - diff --git a/src/ca/client/caEventRate.cpp b/src/ca/client/caEventRate.cpp deleted file mode 100644 index 8beb16333..000000000 --- a/src/ca/client/caEventRate.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include - -#include "cadef.h" -#include "dbDefs.h" -#include "epicsTime.h" -#include "errlog.h" - -/* - * event_handler() - */ -extern "C" void eventCallBack ( struct event_handler_args args ) -{ - unsigned *pCount = static_cast < unsigned * > ( args.usr ); - (*pCount)++; -} - -/* - * caEventRate () - */ -void caEventRate ( const char *pName, unsigned count ) -{ - static const double initialSamplePeriod = 1.0; - static const double maxSamplePeriod = 60.0 * 5.0; - unsigned eventCount = 0u; - - chid * pChidTable = new chid [ count ]; - - { - printf ( "Connecting to CA Channel \"%s\" %u times.", - pName, count ); - fflush ( stdout ); - - epicsTime begin = epicsTime::getCurrent (); - for ( unsigned i = 0u; i < count; i++ ) { - int status = ca_search ( pName, & pChidTable[i] ); - SEVCHK ( status, NULL ); - } - - int status = ca_pend_io ( 10000.0 ); - if ( status != ECA_NORMAL ) { - fprintf ( stderr, " not found.\n" ); - return; - } - epicsTime end = epicsTime::getCurrent (); - - printf ( " done(%f sec).\n", end - begin ); - } - - { - printf ( "Subscribing %u times.", count ); - fflush ( stdout ); - - epicsTime begin = epicsTime::getCurrent (); - for ( unsigned i = 0u; i < count; i++ ) { - int addEventStatus = ca_add_event ( DBR_FLOAT, - pChidTable[i], eventCallBack, &eventCount, NULL); - SEVCHK ( addEventStatus, __FILE__ ); - } - - int status = ca_flush_io (); - SEVCHK ( status, __FILE__ ); - - epicsTime end = epicsTime::getCurrent (); - - printf ( " done(%f sec).\n", end - begin ); - } - - { - printf ( "Waiting for initial value events." ); - fflush ( stdout ); - - // let the first one go by - epicsTime begin = epicsTime::getCurrent (); - while ( eventCount < count ) { - int status = ca_pend_event ( 0.01 ); - if ( status != ECA_TIMEOUT ) { - SEVCHK ( status, NULL ); - } - } - epicsTime end = epicsTime::getCurrent (); - - printf ( " done(%f sec).\n", end - begin ); - } - - double samplePeriod = initialSamplePeriod; - double X = 0.0; - double XX = 0.0; - unsigned N = 0u; - while ( true ) { - unsigned nEvents, lastEventCount, curEventCount; - - epicsTime beginPend = epicsTime::getCurrent (); - lastEventCount = eventCount; - int status = ca_pend_event ( samplePeriod ); - curEventCount = eventCount; - epicsTime endPend = epicsTime::getCurrent (); - if ( status != ECA_TIMEOUT ) { - SEVCHK ( status, NULL ); - } - - if ( curEventCount >= lastEventCount ) { - nEvents = curEventCount - lastEventCount; - } - else { - nEvents = ( UINT_MAX - lastEventCount ) + curEventCount + 1u; - } - - N++; - - double period = endPend - beginPend; - double Hz = nEvents / period; - - X += Hz; - XX += Hz * Hz; - - double mean = X / N; - double stdDev = sqrt ( XX / N - mean * mean ); - - printf ( "CA Event Rate (Hz): current %g mean %g std dev %g\n", - Hz, mean, stdDev ); - - if ( samplePeriod < maxSamplePeriod ) { - samplePeriod += samplePeriod; - } - } -} - diff --git a/src/ca/client/caEventRateMain.cpp b/src/ca/client/caEventRateMain.cpp deleted file mode 100644 index 725e66102..000000000 --- a/src/ca/client/caEventRateMain.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -void caEventRate ( const char *pName, unsigned count ); - -int main ( int argc, char **argv ) -{ - if ( argc < 2 || argc > 3 ) { - fprintf ( stderr, "usage: %s < PV name > [subscription count]\n", argv[0] ); - return 0; - } - - unsigned count; - if ( argc == 3 ) { - int status = sscanf ( argv[2], " %u ", & count ); - if ( status != 1 ) { - fprintf ( stderr, "expected unsigned integer 2nd argument\n" ); - return 0; - } - } - else { - count = 1; - } - - caEventRate ( argv[1], count ); - - return 0; -} diff --git a/src/ca/client/caProto.h b/src/ca/client/caProto.h deleted file mode 100644 index 781c89b34..000000000 --- a/src/ca/client/caProto.h +++ /dev/null @@ -1,187 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef __CAPROTO__ -#define __CAPROTO__ - -#define capStrOf(A) #A -#define capStrOfX(A) capStrOf ( A ) - -/* - * CA protocol revision - * TCP/UDP port number (bumped each major protocol change) - */ -#define CA_MAJOR_PROTOCOL_REVISION 4 -#define CA_VERSION_STRING( MINOR_REVISION ) \ -( capStrOfX ( CA_MAJOR_PROTOCOL_REVISION ) "." capStrOfX ( MINOR_REVISION ) ) -#define CA_UKN_MINOR_VERSION 0u /* unknown minor version */ -#define CA_MINIMUM_SUPPORTED_VERSION 4u -# define CA_VSUPPORTED(MINOR) ((MINOR)>=CA_MINIMUM_SUPPORTED_VERSION) -# define CA_V41(MINOR) ((MINOR)>=1u) -# define CA_V42(MINOR) ((MINOR)>=2u) -# define CA_V43(MINOR) ((MINOR)>=3u) -# define CA_V44(MINOR) ((MINOR)>=4u) -# define CA_V45(MINOR) ((MINOR)>=5u) -# define CA_V46(MINOR) ((MINOR)>=6u) -# define CA_V47(MINOR) ((MINOR)>=7u) -# define CA_V48(MINOR) ((MINOR)>=8u) -# define CA_V49(MINOR) ((MINOR)>=9u) /* large arrays, dispatch priorities */ -# define CA_V410(MINOR) ((MINOR)>=10u) /* beacon counter */ -# define CA_V411(MINOR) ((MINOR)>=11u) /* sequence numbers in UDP version command */ -# define CA_V412(MINOR) ((MINOR)>=12u) /* TCP-based search requests */ -# define CA_V413(MINOR) ((MINOR)>=13u) /* Allow zero length in requests. */ - -/* - * These port numbers are only used if the CA repeater and - * CA server port numbers cant be obtained from the EPICS - * environment variables "EPICS_CA_REPEATER_PORT" and - * "EPICS_CA_SERVER_PORT" - */ -#define CA_PORT_BASE IPPORT_USERRESERVED + 56U -#define CA_SERVER_PORT (CA_PORT_BASE+CA_MAJOR_PROTOCOL_REVISION*2u) -#define CA_REPEATER_PORT (CA_PORT_BASE+CA_MAJOR_PROTOCOL_REVISION*2u+1u) - -/* - * 1500 (max of ethernet and 802.{2,3} MTU) - 20(IP) - 8(UDP) - * (the MTU of Ethernet is currently independent of its speed varient) - */ -#define ETHERNET_MAX_UDP ( 1500u - 20u - 8u ) -#define MAX_UDP_RECV ( 0xffff + 16u ) /* allow large frames to be received in the future */ -#define MAX_UDP_SEND 1024u /* original MAX_UDP */ -#define MAX_TCP ( 1024 * 16u ) /* so waveforms fit */ -#define MAX_MSG_SIZE ( MAX_TCP ) /* the larger of tcp and udp max */ - -#define CA_PROTO_PRIORITY_MIN 0u -#define CA_PROTO_PRIORITY_MAX 99u - -/* - * architecture independent types - * - * (so far this works on all archs we have ported to) - */ -typedef unsigned char ca_uint8_t; -typedef unsigned short ca_uint16_t; -typedef unsigned int ca_uint32_t; -typedef float ca_float32_t; -typedef ca_uint32_t caResId; - -#define ca_uint32_max 0xffffffff - - /* values for m_cmmd */ -#define CA_PROTO_VERSION 0u /* set minor version and priority (used to be NOOP cmd) */ -#define CA_PROTO_EVENT_ADD 1u /* add an event */ -#define CA_PROTO_EVENT_CANCEL 2u /* cancel an event */ -#define CA_PROTO_READ 3u /* read and return a channel value*/ -#define CA_PROTO_WRITE 4u /* write a channel value */ -#define CA_PROTO_SNAPSHOT 5u /* snapshot of the system */ -#define CA_PROTO_SEARCH 6u /* IOC channel search */ -#define CA_PROTO_BUILD 7u /* build - obsolete */ -#define CA_PROTO_EVENTS_OFF 8u /* flow control */ -#define CA_PROTO_EVENTS_ON 9u /* flow control */ -#define CA_PROTO_READ_SYNC 10u /* purge old reads */ -#define CA_PROTO_ERROR 11u /* an operation failed */ -#define CA_PROTO_CLEAR_CHANNEL 12u /* free chan resources */ -#define CA_PROTO_RSRV_IS_UP 13u /* CA server has joined the net */ -#define CA_PROTO_NOT_FOUND 14u /* channel not found */ -#define CA_PROTO_READ_NOTIFY 15u /* add a one shot event */ -#define CA_PROTO_READ_BUILD 16u /* read and build - obsolete */ -#define REPEATER_CONFIRM 17u /* registration confirmation */ -#define CA_PROTO_CREATE_CHAN 18u /* client creates channel in server */ -#define CA_PROTO_WRITE_NOTIFY 19u /* notify after write chan value */ -#define CA_PROTO_CLIENT_NAME 20u /* CA V4.1 identify client */ -#define CA_PROTO_HOST_NAME 21u /* CA V4.1 identify client */ -#define CA_PROTO_ACCESS_RIGHTS 22u /* CA V4.2 asynch access rights chg */ -#define CA_PROTO_ECHO 23u /* CA V4.3 connection verify */ -#define REPEATER_REGISTER 24u /* register for repeater fan out */ -#define CA_PROTO_SIGNAL 25u /* knock the server out of select */ -#define CA_PROTO_CREATE_CH_FAIL 26u /* unable to create chan resource in server */ -#define CA_PROTO_SERVER_DISCONN 27u /* server deletes PV (or channel) */ - -#define CA_PROTO_LAST_CMMD CA_PROTO_SERVER_DISCONN - -/* - * for use with search and not_found (if search fails and - * its not a broadcast tell the client to look elesewhere) - */ -#define DOREPLY 10u -#define DONTREPLY 5u - -/* - * for use with the m_dataType field in UDP messages emitted by servers - */ -#define sequenceNoIsValid 1 - -/* size of object in bytes rounded up to nearest oct word */ -#define OCT_ROUND(A) (((A)+7)/8) -#define OCT_SIZEOF(A) (OCT_ROUND(sizeof(A))) - -/* size of object in bytes rounded up to nearest long word */ -#define QUAD_ROUND(A) ((A)+3)/4) -#define QUAD_SIZEOF(A) (QUAD_ROUND(sizeof(A))) - -/* size of object in bytes rounded up to nearest short word */ -#define BI_ROUND(A) (((A)+1)/2) -#define BI_SIZEOF(A) (BI_ROUND(sizeof(A))) - -/* - * For communicating access rights to the clients - * - * (placed in m_available hdr field of CA_PROTO_ACCESS_RIGHTS cmmd - */ -#define CA_PROTO_ACCESS_RIGHT_READ (1u<<0u) -#define CA_PROTO_ACCESS_RIGHT_WRITE (1u<<1u) - -/* - * All structures passed in the protocol must have individual - * fields aligned on natural boundaries. - * - * NOTE: all structures declared in this file must have a - * byte count which is evenly divisible by 8 matching - * the largest atomic data type in db_access.h. - */ -#define CA_MESSAGE_ALIGN(A) (OCT_ROUND(A)<<3u) - -/* - * the common part of each message sent/recv by the - * CA server. - */ -typedef struct ca_hdr { - ca_uint16_t m_cmmd; /* operation to be performed */ - ca_uint16_t m_postsize; /* size of payload */ - ca_uint16_t m_dataType; /* operation data type */ - ca_uint16_t m_count; /* operation data count */ - ca_uint32_t m_cid; /* channel identifier */ - ca_uint32_t m_available; /* protocol stub dependent */ -} caHdr; - -/* - * for monitor (event) message extension - */ -struct mon_info { - ca_float32_t m_lval; /* low delta */ - ca_float32_t m_hval; /* high delta */ - ca_float32_t m_toval; /* period btween samples */ - ca_uint16_t m_mask; /* event select mask */ - ca_uint16_t m_pad; /* extend to 32 bits */ -}; - -/* - * PV names greater than this length assumed to be invalid - */ -#define unreasonablePVNameSize 500u - -#endif /* __CAPROTO__ */ - diff --git a/src/ca/client/caRepeater.cpp b/src/ca/client/caRepeater.cpp deleted file mode 100644 index 9879af2b4..000000000 --- a/src/ca/client/caRepeater.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * CA UDP repeater standalone executable - * - * Author: Jeff Hill - * Date: 3-27-90 - * - * PURPOSE: - * Broadcasts fan out over the LAN, but old IP kernels do not allow - * two processes on the same machine to get the same broadcast - * (and modern IP kernels do not allow two processes on the same machine - * to receive the same unicast). - * - * This code fans out UDP messages sent to the CA repeater port - * to all CA client processes that have subscribed. - * - * NOTES: - * - * see repeater.c - * - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "epicsAssert.h" -#include "udpiiu.h" - -int main() -{ - ca_repeater (); - return ( 0 ); -} - diff --git a/src/ca/client/caRepeater.service@ b/src/ca/client/caRepeater.service@ deleted file mode 100644 index ee50305a1..000000000 --- a/src/ca/client/caRepeater.service@ +++ /dev/null @@ -1,25 +0,0 @@ -# -# Linux systemd service file for the EPICS CA Repeater -# -# To install this file, as root: -# cp caRepeater.service /etc/systemd/system -# chmod 664 /etc/systemd/system/caRepeater.service -# systemctl daemon-reload -# systemctl enable caRepeater -# systemctl start caRepeater -# -# To check the status: -# systemctl status caRepeater - -[Unit] -Description=EPICS CA Repeater -Requires=network.target -After=network.target - -[Service] -ExecStart=@INSTALL_BIN@/caRepeater -Restart=always -User=daemon - -[Install] -WantedBy=multi-user.target diff --git a/src/ca/client/caServerID.h b/src/ca/client/caServerID.h deleted file mode 100644 index 08bfdd5df..000000000 --- a/src/ca/client/caServerID.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#ifndef caServerIDh -#define caServerIDh - -#include "osiSock.h" -#include "resourceLib.h" -#include "caProto.h" - -class caServerID { -public: - caServerID ( const struct sockaddr_in & addrIn, unsigned priority ); - bool operator == ( const caServerID & ) const; - resTableIndex hash () const; - osiSockAddr address () const; - unsigned priority () const; -private: - struct sockaddr_in addr; - ca_uint8_t pri; -}; - -inline caServerID::caServerID ( - const struct sockaddr_in & addrIn, unsigned priorityIn ) : - addr ( addrIn ), pri ( static_cast ( priorityIn ) ) -{ - assert ( priorityIn <= 0xff ); -} - -inline bool caServerID::operator == ( const caServerID & rhs ) const -{ - if ( this->addr.sin_addr.s_addr == rhs.addr.sin_addr.s_addr && - this->addr.sin_port == rhs.addr.sin_port && - this->pri == rhs.pri ) { - return true; - } - return false; -} - -inline resTableIndex caServerID::hash () const -{ - // start with a very small server table to speed - // up the flush traverse for the frequent case - - // a small numbers of servers - const unsigned caServerMinIndexBitWidth = 2u; - const unsigned caServerMaxIndexBitWidth = 32u; - - unsigned index; - index = this->addr.sin_addr.s_addr; - index ^= this->addr.sin_port; - index ^= this->addr.sin_port >> 8u; - index ^= this->pri; - return integerHash ( caServerMinIndexBitWidth, - caServerMaxIndexBitWidth, index ); -} - -inline osiSockAddr caServerID::address () const -{ - osiSockAddr tmp; - tmp.ia = this->addr; - return tmp; -} - -inline unsigned caServerID::priority () const -{ - return this->pri; -} - -#endif // ifdef caServerID - - diff --git a/src/ca/client/ca_client_context.cpp b/src/ca/client/ca_client_context.cpp deleted file mode 100644 index 2bb3e24a8..000000000 --- a/src/ca/client/ca_client_context.cpp +++ /dev/null @@ -1,811 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifdef _MSC_VER -# pragma warning(disable:4355) -#endif - -#include -#include // vxWorks 6.0 requires this include -#include - -#include "epicsExit.h" -#include "errlog.h" -#include "locationException.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "oldAccess.h" -#include "cac.h" - -epicsShareDef epicsThreadPrivateId caClientCallbackThreadId; - -static epicsThreadOnceId cacOnce = EPICS_THREAD_ONCE_INIT; - -const unsigned ca_client_context :: flushBlockThreshold = 0x58000; - -extern "C" void cacExitHandler ( void *) -{ - epicsThreadPrivateDelete ( caClientCallbackThreadId ); - caClientCallbackThreadId = 0; - delete ca_client_context::pDefaultServiceInstallMutex; -} - -// runs once only for each process -extern "C" void cacOnceFunc ( void * ) -{ - caClientCallbackThreadId = epicsThreadPrivateCreate (); - assert ( caClientCallbackThreadId ); - ca_client_context::pDefaultServiceInstallMutex = newEpicsMutex; - epicsAtExit ( cacExitHandler,0 ); -} - -extern epicsThreadPrivateId caClientContextId; - -cacService * ca_client_context::pDefaultService = 0; -epicsMutex * ca_client_context::pDefaultServiceInstallMutex; - -ca_client_context::ca_client_context ( bool enablePreemptiveCallback ) : - createdByThread ( epicsThreadGetIdSelf () ), - ca_exception_func ( 0 ), ca_exception_arg ( 0 ), - pVPrintfFunc ( errlogVprintf ), fdRegFunc ( 0 ), fdRegArg ( 0 ), - pndRecvCnt ( 0u ), ioSeqNo ( 0u ), callbackThreadsPending ( 0u ), - localPort ( 0 ), fdRegFuncNeedsToBeCalled ( false ), - noWakeupSincePend ( true ) -{ - static const unsigned short PORT_ANY = 0u; - - if ( ! osiSockAttach () ) { - throwWithLocation ( noSocket () ); - } - - epicsThreadOnce ( & cacOnce, cacOnceFunc, 0 ); - { - epicsGuard < epicsMutex > guard ( *ca_client_context::pDefaultServiceInstallMutex ); - if ( ca_client_context::pDefaultService ) { - this->pServiceContext.reset ( - & ca_client_context::pDefaultService->contextCreate ( - this->mutex, this->cbMutex, *this ) ); - } - else { - this->pServiceContext.reset ( new cac ( this->mutex, this->cbMutex, *this ) ); - } - } - - this->sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); - if ( this->sock == INVALID_SOCKET ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - this->printFormated ( - "ca_client_context: unable to create " - "datagram socket because = \"%s\"\n", - sockErrBuf ); - throwWithLocation ( noSocket () ); - } - - { - osiSockIoctl_t yes = true; - int status = socket_ioctl ( this->sock, - FIONBIO, & yes); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy ( this->sock ); - this->printFormated ( - "%s: non blocking IO set fail because \"%s\"\n", - __FILE__, sockErrBuf ); - throwWithLocation ( noSocket () ); - } - } - - // force a bind to an unconstrained address so we can obtain - // the local port number below - { - osiSockAddr addr; - memset ( (char *)&addr, 0 , sizeof ( addr ) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); - addr.ia.sin_port = htons ( PORT_ANY ); - int status = bind (this->sock, &addr.sa, sizeof (addr) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy (this->sock); - this->printFormated ( - "CAC: unable to bind to an unconstrained " - "address because = \"%s\"\n", - sockErrBuf ); - throwWithLocation ( noSocket () ); - } - } - - { - osiSockAddr tmpAddr; - osiSocklen_t saddr_length = sizeof ( tmpAddr ); - int status = getsockname ( this->sock, & tmpAddr.sa, & saddr_length ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy ( this->sock ); - this->printFormated ( "CAC: getsockname () error was \"%s\"\n", sockErrBuf ); - throwWithLocation ( noSocket () ); - } - if ( tmpAddr.sa.sa_family != AF_INET) { - epicsSocketDestroy ( this->sock ); - this->printFormated ( "CAC: UDP socket was not inet addr family\n" ); - throwWithLocation ( noSocket () ); - } - this->localPort = htons ( tmpAddr.ia.sin_port ); - } - - std::auto_ptr < CallbackGuard > pCBGuard; - if ( ! enablePreemptiveCallback ) { - pCBGuard.reset ( new CallbackGuard ( this->cbMutex ) ); - } - - // multiple steps ensure exception safety - this->pCallbackGuard = pCBGuard; -} - -ca_client_context::~ca_client_context () -{ - if ( this->fdRegFunc ) { - ( *this->fdRegFunc ) - ( this->fdRegArg, this->sock, false ); - } - epicsSocketDestroy ( this->sock ); - - osiSockRelease (); - - // force a logical shutdown order - // so that the cac class does not hang its - // receive threads during their shutdown sequence - // and so that classes using this classes mutex - // are destroyed before the mutex is destroyed - if ( this->pCallbackGuard.get() ) { - epicsGuardRelease < epicsMutex > unguard ( *this->pCallbackGuard ); - this->pServiceContext.reset ( 0 ); - } - else { - this->pServiceContext.reset ( 0 ); - } -} - -void ca_client_context::destroyGetCopy ( - epicsGuard < epicsMutex > & guard, getCopy & gc ) -{ - guard.assertIdenticalMutex ( this->mutex ); - gc.~getCopy (); - this->getCopyFreeList.release ( & gc ); -} - -void ca_client_context::destroyGetCallback ( - epicsGuard < epicsMutex > & guard, getCallback & gcb ) -{ - guard.assertIdenticalMutex ( this->mutex ); - gcb.~getCallback (); - this->getCallbackFreeList.release ( & gcb ); -} - -void ca_client_context::destroyPutCallback ( - epicsGuard < epicsMutex > & guard, putCallback & pcb ) -{ - guard.assertIdenticalMutex ( this->mutex ); - pcb.~putCallback (); - this->putCallbackFreeList.release ( & pcb ); -} - -void ca_client_context::destroySubscription ( - epicsGuard < epicsMutex > & guard, oldSubscription & os ) -{ - guard.assertIdenticalMutex ( this->mutex ); - os.~oldSubscription (); - this->subscriptionFreeList.release ( & os ); -} - -void ca_client_context::changeExceptionEvent ( - caExceptionHandler * pfunc, void * arg ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->ca_exception_func = pfunc; - this->ca_exception_arg = arg; -// should block here until releated callback in progress completes -} - -void ca_client_context::replaceErrLogHandler ( - caPrintfFunc * ca_printf_func ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( ca_printf_func ) { - this->pVPrintfFunc = ca_printf_func; - } - else { - this->pVPrintfFunc = epicsVprintf; - } -// should block here until releated callback in progress completes -} - -void ca_client_context::registerForFileDescriptorCallBack ( - CAFDHANDLER *pFunc, void *pArg ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->fdRegFunc = pFunc; - this->fdRegArg = pArg; - this->fdRegFuncNeedsToBeCalled = true; - if ( pFunc ) { - // the receive thread might already be blocking - // w/o having sent the wakeup message - this->_sendWakeupMsg (); - } -// should block here until releated callback in progress completes -} - -int ca_client_context :: printFormated ( - const char *pformat, ... ) const -{ - va_list theArgs; - int status; - - va_start ( theArgs, pformat ); - - status = this->ca_client_context :: varArgsPrintFormated ( pformat, theArgs ); - - va_end ( theArgs ); - - return status; -} - -int ca_client_context :: varArgsPrintFormated ( - const char *pformat, va_list args ) const -{ - caPrintfFunc * pFunc; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - pFunc = this->pVPrintfFunc; - } - if ( pFunc ) { - return ( *pFunc ) ( pformat, args ); - } - else { - return :: vfprintf ( stderr, pformat, args ); - } -} - -void ca_client_context::exception ( - epicsGuard < epicsMutex > & guard, int stat, const char * pCtx, - const char * pFile, unsigned lineNo ) -{ - struct exception_handler_args args; - caExceptionHandler * pFunc = this->ca_exception_func; - void * pArg = this->ca_exception_arg; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - // NOOP if they disable exceptions - if ( pFunc ) { - args.chid = NULL; - args.type = TYPENOTCONN; - args.count = 0; - args.addr = NULL; - args.stat = stat; - args.op = CA_OP_OTHER; - args.ctx = pCtx; - args.pFile = pFile; - args.lineNo = lineNo; - args.usr = pArg; - ( *pFunc ) ( args ); - } - else { - this->signal ( stat, pFile, lineNo, pCtx ); - } - } -} - -void ca_client_context::exception ( - epicsGuard < epicsMutex > & guard, int status, const char * pContext, - const char * pFileName, unsigned lineNo, oldChannelNotify & chan, - unsigned type, arrayElementCount count, unsigned op ) -{ - struct exception_handler_args args; - caExceptionHandler * pFunc = this->ca_exception_func; - void * pArg = this->ca_exception_arg; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - // NOOP if they disable exceptions - if ( pFunc ) { - args.chid = &chan; - args.type = type; - args.count = count; - args.addr = NULL; - args.stat = status; - args.op = op; - args.ctx = pContext; - args.pFile = pFileName; - args.lineNo = lineNo; - args.usr = pArg; - ( *pFunc ) ( args ); - } - else { - this->signal ( status, pFileName, lineNo, - "op=%u, channel=%s, type=%s, count=%lu, ctx=\"%s\"", - op, ca_name ( &chan ), - dbr_type_to_text ( static_cast ( type ) ), - count, pContext ); - } - } -} - -void ca_client_context::signal ( int ca_status, const char * pfilenm, - int lineno, const char * pFormat, ... ) -{ - va_list theArgs; - va_start ( theArgs, pFormat ); - this->vSignal ( ca_status, pfilenm, lineno, pFormat, theArgs); - va_end ( theArgs ); -} - -void ca_client_context :: vSignal ( - int ca_status, const char *pfilenm, - int lineno, const char *pFormat, va_list args ) -{ - static const char *severity[] = - { - "Warning", - "Success", - "Error", - "Info", - "Fatal", - "Fatal", - "Fatal", - "Fatal" - }; - - this->printFormated ( "CA.Client.Exception...............................................\n" ); - - this->printFormated ( " %s: \"%s\"\n", - severity[ CA_EXTRACT_SEVERITY ( ca_status ) ], - ca_message ( ca_status ) ); - - if ( pFormat ) { - this->printFormated ( " Context: \"" ); - this->varArgsPrintFormated ( pFormat, args ); - this->printFormated ( "\"\n" ); - } - - if ( pfilenm ) { - this->printFormated ( " Source File: %s line %d\n", - pfilenm, lineno ); - } - - epicsTime current = epicsTime::getCurrent (); - char date[64]; - current.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f"); - this->printFormated ( " Current Time: %s\n", date ); - - /* - * Terminate execution if unsuccessful - */ - if( ! ( ca_status & CA_M_SUCCESS ) && - CA_EXTRACT_SEVERITY ( ca_status ) != CA_K_WARNING ){ - errlogFlush (); - abort (); - } - - this->printFormated ( "..................................................................\n" ); -} - -void ca_client_context::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - ::printf ( "ca_client_context at %p pndRecvCnt=%u ioSeqNo=%u\n", - static_cast ( this ), - this->pndRecvCnt, this->ioSeqNo ); - - if ( level > 0u ) { - this->pServiceContext->show ( guard, level - 1u ); - ::printf ( "\tpreemptive callback is %s\n", - this->pCallbackGuard.get() ? "disabled" : "enabled" ); - ::printf ( "\tthere are %u unsatisfied IO operations blocking ca_pend_io()\n", - this->pndRecvCnt ); - ::printf ( "\tthe current io sequence number is %u\n", - this->ioSeqNo ); - ::printf ( "IO done event:\n"); - this->ioDone.show ( level - 1u ); - ::printf ( "Synchronous group identifier hash table:\n" ); - this->sgTable.show ( level - 1u ); - } -} - -void ca_client_context::attachToClientCtx () -{ - assert ( ! epicsThreadPrivateGet ( caClientContextId ) ); - epicsThreadPrivateSet ( caClientContextId, this ); -} - -void ca_client_context::incrementOutstandingIO ( - epicsGuard < epicsMutex > & guard, unsigned ioSeqNoIn ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->ioSeqNo == ioSeqNoIn ) { - assert ( this->pndRecvCnt < UINT_MAX ); - this->pndRecvCnt++; - } -} - -void ca_client_context::decrementOutstandingIO ( - epicsGuard < epicsMutex > & guard, unsigned ioSeqNoIn ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->ioSeqNo == ioSeqNoIn ) { - assert ( this->pndRecvCnt > 0u ); - this->pndRecvCnt--; - if ( this->pndRecvCnt == 0u ) { - this->ioDone.signal (); - } - } -} - -// !!!! This routine is only visible in the old interface - or in a new ST interface. -// !!!! In the old interface we restrict thread attach so that calls from threads -// !!!! other than the initializing thread are not allowed if preemptive callback -// !!!! is disabled. This prevents the preemptive callback lock from being released -// !!!! by other threads than the one that locked it. -// -int ca_client_context::pendIO ( const double & timeout ) -{ - // prevent recursion nightmares by disabling calls to - // pendIO () from within a CA callback. - if ( epicsThreadPrivateGet ( caClientCallbackThreadId ) ) { - return ECA_EVDISALLOW; - } - - int status = ECA_NORMAL; - epicsTime beg_time = epicsTime::getCurrent (); - double remaining = timeout; - - epicsGuard < epicsMutex > guard ( this->mutex ); - - this->flush ( guard ); - - while ( this->pndRecvCnt > 0 ) { - if ( remaining < CAC_SIGNIFICANT_DELAY ) { - status = ECA_TIMEOUT; - break; - } - - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->blockForEventAndEnableCallbacks ( this->ioDone, remaining ); - } - - double delay = epicsTime::getCurrent () - beg_time; - if ( delay < timeout ) { - remaining = timeout - delay; - } - else { - remaining = 0.0; - } - } - - this->ioSeqNo++; - this->pndRecvCnt = 0u; - - return status; -} - -// !!!! This routine is only visible in the old interface - or in a new ST interface. -// !!!! In the old interface we restrict thread attach so that calls from threads -// !!!! other than the initializing thread are not allowed if preemptive callback -// !!!! is disabled. This prevents the preemptive callback lock from being released -// !!!! by other threads than the one that locked it. -// -int ca_client_context::pendEvent ( const double & timeout ) -{ - // prevent recursion nightmares by disabling calls to - // pendIO () from within a CA callback. - if ( epicsThreadPrivateGet ( caClientCallbackThreadId ) ) { - return ECA_EVDISALLOW; - } - - epicsTime current = epicsTime::getCurrent (); - - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->flush ( guard ); - } - - // process at least once if preemptive callback is disabled - if ( this->pCallbackGuard.get() ) { - epicsGuardRelease < epicsMutex > cbUnguard ( *this->pCallbackGuard ); - epicsGuard < epicsMutex > guard ( this->mutex ); - - // - // This is needed because in non-preemptive callback mode - // legacy applications that use file descriptor managers - // will register for ca receive thread activity and keep - // calling ca_pend_event until all of the socket data has - // been read. We must guarantee that other threads get a - // chance to run if there is data in any of the sockets. - // - if ( this->fdRegFunc ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - - // remove short udp message sent to wake - // up a file descriptor manager - osiSockAddr tmpAddr; - osiSocklen_t addrSize = sizeof ( tmpAddr.sa ); - char buf = 0; - int status = 0; - do { - status = recvfrom ( this->sock, & buf, sizeof ( buf ), - 0, & tmpAddr.sa, & addrSize ); - } while ( status > 0 ); - } - while ( this->callbackThreadsPending > 0 ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->callbackThreadActivityComplete.wait ( 30.0 ); - } - this->noWakeupSincePend = true; - } - - double elapsed = epicsTime::getCurrent() - current; - double delay; - - if ( timeout > elapsed ) { - delay = timeout - elapsed; - } - else { - delay = 0.0; - } - - if ( delay >= CAC_SIGNIFICANT_DELAY ) { - if ( this->pCallbackGuard.get() ) { - epicsGuardRelease < epicsMutex > unguard ( *this->pCallbackGuard ); - epicsThreadSleep ( delay ); - } - else { - epicsThreadSleep ( delay ); - } - } - - return ECA_TIMEOUT; -} - -void ca_client_context::blockForEventAndEnableCallbacks ( - epicsEvent & event, const double & timeout ) -{ - if ( this->pCallbackGuard.get() ) { - epicsGuardRelease < epicsMutex > unguard ( *this->pCallbackGuard ); - event.wait ( timeout ); - } - else { - event.wait ( timeout ); - } -} - -void ca_client_context::callbackProcessingInitiateNotify () -{ - // if preemptive callback is enabled then this is a noop - if ( this->pCallbackGuard.get() ) { - bool sendNeeded = false; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->callbackThreadsPending++; - if ( this->fdRegFunc && this->noWakeupSincePend ) { - this->noWakeupSincePend = false; - sendNeeded = true; - } - } - if ( sendNeeded ) { - _sendWakeupMsg (); - } - } -} - -void ca_client_context :: _sendWakeupMsg () -{ - // send short udp message to wake up a file descriptor manager - // when a message arrives - osiSockAddr tmpAddr; - tmpAddr.ia.sin_family = AF_INET; - tmpAddr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - tmpAddr.ia.sin_port = htons ( this->localPort ); - char buf = 0; - sendto ( this->sock, & buf, sizeof ( buf ), - 0, & tmpAddr.sa, sizeof ( tmpAddr.sa ) ); -} - -void ca_client_context::callbackProcessingCompleteNotify () -{ - // if preemptive callback is enabled then this is a noop - if ( this->pCallbackGuard.get() ) { - bool signalNeeded = false; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->callbackThreadsPending <= 1 ) { - if ( this->callbackThreadsPending == 1 ) { - this->callbackThreadsPending = 0; - signalNeeded = true; - } - } - else { - this->callbackThreadsPending--; - } - } - if ( signalNeeded ) { - this->callbackThreadActivityComplete.signal (); - } - } -} - -cacChannel & ca_client_context::createChannel ( - epicsGuard < epicsMutex > & guard, const char * pChannelName, - cacChannelNotify & chan, cacChannel::priLev pri ) -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->pServiceContext->createChannel ( - guard, pChannelName, chan, pri ); -} - -void ca_client_context::flush ( epicsGuard < epicsMutex > & guard ) -{ - this->pServiceContext->flush ( guard ); -} - -unsigned ca_client_context::circuitCount () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->pServiceContext->circuitCount ( guard ); -} - -unsigned ca_client_context::beaconAnomaliesSinceProgramStart () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->pServiceContext->beaconAnomaliesSinceProgramStart ( guard ); -} - -void ca_client_context::installCASG ( - epicsGuard < epicsMutex > & guard, CASG & sg ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->sgTable.idAssignAdd ( sg ); -} - -void ca_client_context::uninstallCASG ( - epicsGuard < epicsMutex > & guard, CASG & sg ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->sgTable.remove ( sg ); -} - -CASG * ca_client_context::lookupCASG ( - epicsGuard < epicsMutex > & guard, unsigned idIn ) -{ - guard.assertIdenticalMutex ( this->mutex ); - CASG * psg = this->sgTable.lookup ( idIn ); - if ( psg ) { - if ( ! psg->verify ( guard ) ) { - psg = 0; - } - } - return psg; -} - -void ca_client_context::selfTest () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->sgTable.verify (); - this->pServiceContext->selfTest ( guard ); -} - -epicsMutex & ca_client_context::mutexRef () const -{ - return this->mutex; -} - -cacContext & ca_client_context::createNetworkContext ( - epicsMutex & mutexIn, epicsMutex & cbMutexIn ) -{ - return * new cac ( mutexIn, cbMutexIn, *this ); -} - -void ca_client_context::installDefaultService ( cacService & service ) -{ - epicsThreadOnce ( & cacOnce, cacOnceFunc, 0 ); - - epicsGuard < epicsMutex > guard ( *ca_client_context::pDefaultServiceInstallMutex ); - if ( ca_client_context::pDefaultService ) { - throw std::logic_error - ( "CA in-memory service already installed and can't be replaced"); - } - ca_client_context::pDefaultService = & service; -} - -void epicsShareAPI caInstallDefaultService ( cacService & service ) -{ - ca_client_context::installDefaultService ( service ); -} - -epicsShareFunc int epicsShareAPI ca_clear_subscription ( evid pMon ) -{ - oldChannelNotify & chan = pMon->channel (); - ca_client_context & cac = chan.getClientCtx (); - // !!!! the order in which we take the mutex here prevents deadlocks - { - epicsGuard < epicsMutex > guard ( cac.mutex ); - try { - // if this stalls out on a live circuit then an exception - // can be forthcoming which we must ignore as the clear - // request must always be successful - chan.eliminateExcessiveSendBacklog ( guard ); - } - catch ( cacChannel::notConnected & ) { - // intentionally ignored - } - } - if ( cac.pCallbackGuard.get() && - cac.createdByThread == epicsThreadGetIdSelf () ) { - epicsGuard < epicsMutex > guard ( cac.mutex ); - pMon->cancel ( *cac.pCallbackGuard.get(), guard ); - } - else { - // - // we will definately stall out here if all of the - // following are true - // - // o user creates non-preemtive mode client library context - // o user doesnt periodically call a ca function - // o user calls this function from an auxiillary thread - // - CallbackGuard cbGuard ( cac.cbMutex ); - epicsGuard < epicsMutex > guard ( cac.mutex ); - pMon->cancel ( cbGuard, guard ); - } - return ECA_NORMAL; -} - -void ca_client_context :: eliminateExcessiveSendBacklog ( - epicsGuard < epicsMutex > & guard, cacChannel & chan ) -{ - if ( chan.requestMessageBytesPending ( guard ) > - ca_client_context :: flushBlockThreshold ) { - if ( this->pCallbackGuard.get() && - this->createdByThread == epicsThreadGetIdSelf () ) { - // we need to be very careful about lock hierarchy - // inversion in this situation - epicsGuardRelease < epicsMutex > unguard ( guard ); - { - epicsGuardRelease < epicsMutex > cbunguard ( - * this->pCallbackGuard.get() ); - { - epicsGuard < epicsMutex > nestedGuard ( this->mutex ); - chan.flush ( nestedGuard ); - } - } - } - else { - chan.flush ( guard ); - } - } -} diff --git a/src/ca/client/cac.cpp b/src/ca/client/cac.cpp deleted file mode 100644 index 5748353bd..000000000 --- a/src/ca/client/cac.cpp +++ /dev/null @@ -1,1336 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - * - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include -#include -#include // vxWorks 6.0 requires this include - -#include "dbDefs.h" -#include "epicsGuard.h" -#include "epicsVersion.h" -#include "osiProcess.h" -#include "epicsSignal.h" -#include "envDefs.h" -#include "locationException.h" -#include "errlog.h" -#include "epicsExport.h" - -#define epicsExportSharedSymbols -#include "addrList.h" -#include "iocinf.h" -#include "cac.h" -#include "inetAddrID.h" -#include "caServerID.h" -#include "virtualCircuit.h" -#include "syncGroup.h" -#include "nciu.h" -#include "autoPtrRecycle.h" -#include "msgForMultiplyDefinedPV.h" -#include "udpiiu.h" -#include "bhe.h" -#include "net_convert.h" -#include "autoPtrFreeList.h" -#include "noopiiu.h" - -static const char pVersionCAC[] = - "@(#) " EPICS_VERSION_STRING - ", CA Client Library " __DATE__; - -// TCP response dispatch table -const cac::pProtoStubTCP cac::tcpJumpTableCAC [] = -{ - &cac::versionAction, - &cac::eventRespAction, - &cac::badTCPRespAction, - &cac::readRespAction, - &cac::badTCPRespAction, - &cac::badTCPRespAction, - &cac::searchRespAction, - &cac::badTCPRespAction, - &cac::badTCPRespAction, - &cac::badTCPRespAction, - // legacy CA_PROTO_READ_SYNC used as an echo with legacy server - &cac::echoRespAction, - &cac::exceptionRespAction, - &cac::clearChannelRespAction, - &cac::badTCPRespAction, - &cac::badTCPRespAction, - &cac::readNotifyRespAction, - &cac::badTCPRespAction, - &cac::badTCPRespAction, - &cac::createChannelRespAction, - &cac::writeNotifyRespAction, - &cac::badTCPRespAction, - &cac::badTCPRespAction, - &cac::accessRightsRespAction, - &cac::echoRespAction, - &cac::badTCPRespAction, - &cac::badTCPRespAction, - &cac::verifyAndDisconnectChan, - &cac::verifyAndDisconnectChan -}; - -// TCP exception dispatch table -const cac::pExcepProtoStubTCP cac::tcpExcepJumpTableCAC [] = -{ - &cac::defaultExcep, // CA_PROTO_VERSION - &cac::eventAddExcep, // CA_PROTO_EVENT_ADD - &cac::defaultExcep, // CA_PROTO_EVENT_CANCEL - &cac::readExcep, // CA_PROTO_READ - &cac::writeExcep, // CA_PROTO_WRITE - &cac::defaultExcep, // CA_PROTO_SNAPSHOT - &cac::defaultExcep, // CA_PROTO_SEARCH - &cac::defaultExcep, // CA_PROTO_BUILD - &cac::defaultExcep, // CA_PROTO_EVENTS_OFF - &cac::defaultExcep, // CA_PROTO_EVENTS_ON - &cac::defaultExcep, // CA_PROTO_READ_SYNC - &cac::defaultExcep, // CA_PROTO_ERROR - &cac::defaultExcep, // CA_PROTO_CLEAR_CHANNEL - &cac::defaultExcep, // CA_PROTO_RSRV_IS_UP - &cac::defaultExcep, // CA_PROTO_NOT_FOUND - &cac::readNotifyExcep, // CA_PROTO_READ_NOTIFY - &cac::defaultExcep, // CA_PROTO_READ_BUILD - &cac::defaultExcep, // REPEATER_CONFIRM - &cac::defaultExcep, // CA_PROTO_CREATE_CHAN - &cac::writeNotifyExcep, // CA_PROTO_WRITE_NOTIFY - &cac::defaultExcep, // CA_PROTO_CLIENT_NAME - &cac::defaultExcep, // CA_PROTO_HOST_NAME - &cac::defaultExcep, // CA_PROTO_ACCESS_RIGHTS - &cac::defaultExcep, // CA_PROTO_ECHO - &cac::defaultExcep, // REPEATER_REGISTER - &cac::defaultExcep, // CA_PROTO_SIGNAL - &cac::defaultExcep, // CA_PROTO_CREATE_CH_FAIL - &cac::defaultExcep // CA_PROTO_SERVER_DISCONN -}; - -// -// cac::cac () -// -cac::cac ( - epicsMutex & mutualExclusionIn, - epicsMutex & callbackControlIn, - cacContextNotify & notifyIn ) : - _refLocalHostName ( localHostNameCache.getReference () ), - programBeginTime ( epicsTime::getCurrent() ), - connTMO ( CA_CONN_VERIFY_PERIOD ), - mutex ( mutualExclusionIn ), - cbMutex ( callbackControlIn ), - ipToAEngine ( ipAddrToAsciiEngine::allocate () ), - timerQueue ( epicsTimerQueueActive::allocate ( false, - lowestPriorityLevelAbove(epicsThreadGetPrioritySelf()) ) ), - pUserName ( 0 ), - pudpiiu ( 0 ), - tcpSmallRecvBufFreeList ( 0 ), - tcpLargeRecvBufFreeList ( 0 ), - notify ( notifyIn ), - initializingThreadsId ( epicsThreadGetIdSelf() ), - initializingThreadsPriority ( epicsThreadGetPrioritySelf() ), - maxRecvBytesTCP ( MAX_TCP ), - maxContigFrames ( contiguousMsgCountWhichTriggersFlowControl ), - beaconAnomalyCount ( 0u ), - iiuExistenceCount ( 0u ), - cacShutdownInProgress ( false ) -{ - if ( ! osiSockAttach () ) { - throwWithLocation ( udpiiu :: noSocket () ); - } - - try { - long status; - - /* - * Certain os, such as HPUX, do not unblock a socket system call - * when another thread asynchronously calls both shutdown() and - * close(). To solve this problem we need to employ OS specific - * mechanisms. - */ - epicsSignalInstallSigAlarmIgnore (); - epicsSignalInstallSigPipeIgnore (); - - { - char tmp[256]; - size_t len; - osiGetUserNameReturn gunRet; - - gunRet = osiGetUserName ( tmp, sizeof (tmp) ); - if ( gunRet != osiGetUserNameSuccess ) { - tmp[0] = '\0'; - } - len = strlen ( tmp ) + 1; - this->pUserName = new char [ len ]; - strncpy ( this->pUserName, tmp, len ); - } - - this->_serverPort = - envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT, - static_cast (CA_SERVER_PORT) ); - - status = envGetDoubleConfigParam ( &EPICS_CA_CONN_TMO, &this->connTMO ); - if ( status ) { - this->connTMO = CA_CONN_VERIFY_PERIOD; - epicsGuard < epicsMutex > cbGuard ( this->cbMutex ); - errlogPrintf ( "EPICS \"%s\" double fetch failed\n", EPICS_CA_CONN_TMO.name ); - errlogPrintf ( "Defaulting \"%s\" = %f\n", EPICS_CA_CONN_TMO.name, this->connTMO ); - } - - long maxBytesAsALong; - status = envGetLongConfigParam ( &EPICS_CA_MAX_ARRAY_BYTES, &maxBytesAsALong ); - if ( status || maxBytesAsALong < 0 ) { - errlogPrintf ( "cac: EPICS_CA_MAX_ARRAY_BYTES was not a positive integer\n" ); - } - else { - /* allow room for the protocol header so that they get the array size they requested */ - static const unsigned headerSize = sizeof ( caHdr ) + 2 * sizeof ( ca_uint32_t ); - ca_uint32_t maxBytes = ( unsigned ) maxBytesAsALong; - if ( maxBytes < 0xffffffff - headerSize ) { - maxBytes += headerSize; - } - else { - maxBytes = 0xffffffff; - } - if ( maxBytes < MAX_TCP ) { - errlogPrintf ( "cac: EPICS_CA_MAX_ARRAY_BYTES was rounded up to %u\n", MAX_TCP ); - } - else { - this->maxRecvBytesTCP = maxBytes; - } - } - freeListInitPvt ( &this->tcpSmallRecvBufFreeList, MAX_TCP, 1 ); - if ( ! this->tcpSmallRecvBufFreeList ) { - throw std::bad_alloc (); - } - - int autoMaxBytes; - if(envGetBoolConfigParam(&EPICS_CA_AUTO_ARRAY_BYTES, &autoMaxBytes)) - autoMaxBytes = 1; - - if(!autoMaxBytes) { - freeListInitPvt ( &this->tcpLargeRecvBufFreeList, this->maxRecvBytesTCP, 1 ); - if ( ! this->tcpLargeRecvBufFreeList ) { - throw std::bad_alloc (); - } - } - unsigned bufsPerArray = this->maxRecvBytesTCP / comBuf::capacityBytes (); - if ( bufsPerArray > 1u ) { - maxContigFrames = bufsPerArray * - contiguousMsgCountWhichTriggersFlowControl; - } - } - catch ( ... ) { - osiSockRelease (); - delete [] this->pUserName; - freeListCleanup ( this->tcpSmallRecvBufFreeList ); - if ( this->tcpLargeRecvBufFreeList ) { - freeListCleanup ( this->tcpLargeRecvBufFreeList ); - } - this->timerQueue.release (); - throw; - } - - /* - * load user configured tcp name server address list, - * create virtual circuits, and add them to server table - */ - ELLLIST dest, tmpList; - - ellInit ( & dest ); - ellInit ( & tmpList ); - - addAddrToChannelAccessAddressList ( &tmpList, &EPICS_CA_NAME_SERVERS, this->_serverPort, false ); - removeDuplicateAddresses ( &dest, &tmpList, 0 ); - - epicsGuard < epicsMutex > guard ( this->mutex ); - - while ( osiSockAddrNode * - pNode = reinterpret_cast < osiSockAddrNode * > ( ellGet ( & dest ) ) ) { - tcpiiu * piiu = NULL; - SearchDestTCP * pdst = new SearchDestTCP ( *this, pNode->addr ); - this->registerSearchDest ( guard, * pdst ); - /* Initially assume that servers listed in EPICS_CA_NAME_SERVERS support at least minor - * version 11. This causes tcpiiu to send the user and host name authentication - * messages. When the actual Version message is received from the server it will - * be overwrite this assumption. - */ - bool newIIU = findOrCreateVirtCircuit ( - guard, pNode->addr, cacChannel::priorityDefault, - piiu, 11, pdst ); - free ( pNode ); - if ( newIIU ) { - piiu->start ( guard ); - } - } -} - -cac::~cac () -{ - // this blocks until the UDP thread exits so that - // it will not sneak in any new clients - // - // lock intentionally not held here so that we dont deadlock - // waiting for the UDP thread to exit while it is waiting to - // get the lock. - { - epicsGuard < epicsMutex > cbGuard ( this->cbMutex ); - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pudpiiu ) { - this->pudpiiu->shutdown ( cbGuard, guard ); - - // make sure no new tcp circuits are created - this->cacShutdownInProgress = true; - - // - // shutdown all tcp circuits - // - tsDLIter < tcpiiu > iter = this->circuitList.firstIter (); - while ( iter.valid() ) { - // this causes a clean shutdown to occur - iter->unlinkAllChannels ( cbGuard, guard ); - iter++; - } - } - } - - // - // wait for all tcp threads to exit - // - // this will block for oustanding sends to go out so dont - // hold a lock while waiting - // - { - epicsGuard < epicsMutex > guard ( this->mutex ); - while ( this->iiuExistenceCount > 0 ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->iiuUninstall.wait (); - } - } - - if ( this->pudpiiu ) { - delete this->pudpiiu; - } - - freeListCleanup ( this->tcpSmallRecvBufFreeList ); - if ( this->tcpLargeRecvBufFreeList ) { - freeListCleanup ( this->tcpLargeRecvBufFreeList ); - } - - delete [] this->pUserName; - - tsSLList < bhe > tmpBeaconList; - this->beaconTable.removeAll ( tmpBeaconList ); - while ( bhe * pBHE = tmpBeaconList.get() ) { - pBHE->~bhe (); - this->bheFreeList.release ( pBHE ); - } - - this->timerQueue.release (); - - this->ipToAEngine.release (); - - // clean-up the list of un-notified msg objects - while ( msgForMultiplyDefinedPV * msg = this->msgMultiPVList.get() ) { - msg->~msgForMultiplyDefinedPV (); - this->mdpvFreeList.release ( msg ); - } - - errlogFlush (); - - osiSockRelease (); - - // its ok for channels and subscriptions to still - // exist at this point. The user created them and - // its his responsibility to clean them up. -} - -unsigned cac::lowestPriorityLevelAbove ( unsigned priority ) -{ - unsigned abovePriority; - epicsThreadBooleanStatus tbs; - tbs = epicsThreadLowestPriorityLevelAbove ( - priority, & abovePriority ); - if ( tbs != epicsThreadBooleanStatusSuccess ) { - abovePriority = priority; - } - return abovePriority; -} - -unsigned cac::highestPriorityLevelBelow ( unsigned priority ) -{ - unsigned belowPriority; - epicsThreadBooleanStatus tbs; - tbs = epicsThreadHighestPriorityLevelBelow ( - priority, & belowPriority ); - if ( tbs != epicsThreadBooleanStatusSuccess ) { - belowPriority = priority; - } - return belowPriority; -} - -// -// set the push pending flag on all virtual circuits -// -void cac::flush ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - tsDLIter < tcpiiu > iter = this->circuitList.firstIter (); - while ( iter.valid () ) { - iter->flushRequest ( guard ); - iter++; - } -} - -unsigned cac::circuitCount ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->circuitList.count (); -} - -void cac::show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - - ::printf ( "Channel Access Client Context at %p for user %s\n", - static_cast ( this ), this->pUserName ); - // this also supresses the "defined, but not used" - // warning message - ::printf ( "\trevision \"%s\"\n", pVersionCAC ); - - if ( level > 0u ) { - this->serverTable.show ( level - 1u ); - ::printf ( "\tconnection time out watchdog period %f\n", this->connTMO ); - } - - if ( level > 1u ) { - if ( this->pudpiiu ) { - this->pudpiiu->show ( level - 2u ); - } - } - - if ( level > 2u ) { - ::printf ( "Program begin time:\n"); - this->programBeginTime.show ( level - 3u ); - ::printf ( "Channel identifier hash table:\n" ); - this->chanTable.show ( level - 3u ); - ::printf ( "IO identifier hash table:\n" ); - this->ioTable.show ( level - 3u ); - ::printf ( "Beacon source identifier hash table:\n" ); - this->beaconTable.show ( level - 3u ); - ::printf ( "Timer queue:\n" ); - this->timerQueue.show ( level - 3u ); - ::printf ( "IP address to name conversion engine:\n" ); - this->ipToAEngine.show ( level - 3u ); - } - - if ( level > 3u ) { - ::printf ( "Default mutex:\n"); - this->mutex.show ( level - 4u ); - ::printf ( "mutex:\n" ); - this->mutex.show ( level - 4u ); - } -} - -/* - * cac::beaconNotify - */ -void cac::beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime, - ca_uint32_t beaconNumber, unsigned protocolRevision ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - if ( ! this->pudpiiu ) { - return; - } - - /* - * look for it in the hash table - */ - bhe *pBHE = this->beaconTable.lookup ( addr ); - if ( pBHE ) { - /* - * return if the beacon period has not changed significantly - */ - if ( ! pBHE->updatePeriod ( guard, this->programBeginTime, - currentTime, beaconNumber, protocolRevision ) ) { - return; - } - } - else { - /* - * This is the first beacon seen from this server. - * Wait until 2nd beacon is seen before deciding - * if it is a new server (or just the first - * time that we have seen a server's beacon - * shortly after the program started up) - */ - pBHE = new ( this->bheFreeList ) - bhe ( this->mutex, currentTime, beaconNumber, addr ); - if ( pBHE ) { - if ( this->beaconTable.add ( *pBHE ) < 0 ) { - pBHE->~bhe (); - this->bheFreeList.release ( pBHE ); - } - } - return; - } - - this->beaconAnomalyCount++; - - this->pudpiiu->beaconAnomalyNotify ( guard ); - -# ifdef DEBUG - { - char buf[128]; - addr.name ( buf, sizeof ( buf ) ); - ::printf ( "New server available: %s\n", buf ); - } -# endif -} - -cacChannel & cac::createChannel ( - epicsGuard < epicsMutex > & guard, const char * pName, - cacChannelNotify & chan, cacChannel::priLev pri ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( pri > cacChannel::priorityMax ) { - throw cacChannel::badPriority (); - } - - if ( pName == 0 || pName[0] == '\0' ) { - throw cacChannel::badString (); - } - - if ( ! this->pudpiiu ) { - this->pudpiiu = new udpiiu ( - guard, this->timerQueue, this->cbMutex, - this->mutex, this->notify, *this, this->_serverPort, - this->searchDestList ); - } - - nciu * pNetChan = new ( this->channelFreeList ) - nciu ( *this, noopIIU, chan, pName, pri ); - this->chanTable.idAssignAdd ( *pNetChan ); - return *pNetChan; -} - -bool cac::findOrCreateVirtCircuit ( - epicsGuard < epicsMutex > & guard, const osiSockAddr & addr, - unsigned priority, tcpiiu *& piiu, unsigned minorVersionNumber, - SearchDestTCP * pSearchDest ) -{ - guard.assertIdenticalMutex ( this->mutex ); - bool newIIU = false; - - if ( piiu ) { - if ( ! piiu->alive ( guard ) ) { - return newIIU; - } - } - else { - try { - autoPtrFreeList < tcpiiu, 32, epicsMutexNOOP > pnewiiu ( - this->freeListVirtualCircuit, - new ( this->freeListVirtualCircuit ) tcpiiu ( - *this, this->mutex, this->cbMutex, this->notify, this->connTMO, - this->timerQueue, addr, this->comBufMemMgr, minorVersionNumber, - this->ipToAEngine, priority, pSearchDest ) ); - - bhe * pBHE = this->beaconTable.lookup ( addr.ia ); - if ( ! pBHE ) { - pBHE = new ( this->bheFreeList ) - bhe ( this->mutex, epicsTime (), 0u, addr.ia ); - if ( this->beaconTable.add ( *pBHE ) < 0 ) { - return newIIU; - } - } - this->serverTable.add ( *pnewiiu ); - this->circuitList.add ( *pnewiiu ); - this->iiuExistenceCount++; - pBHE->registerIIU ( guard, *pnewiiu ); - piiu = pnewiiu.release (); - newIIU = true; - } - catch ( std :: exception & except ) { - errlogPrintf ( - "CAC: exception during virtual circuit creation \"%s\"\n", - except.what () ); - return newIIU; - } - catch ( ... ) { - errlogPrintf ( - "CAC: Nonstandard exception during virtual circuit creation\n" ); - return newIIU; - } - } - return newIIU; -} - -void cac::transferChanToVirtCircuit ( - unsigned cid, unsigned sid, - ca_uint16_t typeCode, arrayElementCount count, - unsigned minorVersionNumber, const osiSockAddr & addr, - const epicsTime & currentTime ) -{ - if ( addr.sa.sa_family != AF_INET ) { - return; - } - - epicsGuard < epicsMutex > guard ( this->mutex ); - - /* - * Do not open new circuits while the cac is shutting down - */ - if ( this->cacShutdownInProgress ) { - return; - } - - /* - * ignore search replies for deleted channels - */ - nciu * pChan = this->chanTable.lookup ( cid ); - if ( ! pChan ) { - return; - } - - /* - * Ignore duplicate search replies - */ - osiSockAddr chanAddr = pChan->getPIIU(guard)->getNetworkAddress (guard); - - if ( chanAddr.sa.sa_family != AF_UNSPEC ) { - if ( ! sockAddrAreIdentical ( &addr, &chanAddr ) ) { - char acc[64]; - pChan->getPIIU(guard)->getHostName ( guard, acc, sizeof ( acc ) ); - msgForMultiplyDefinedPV * pMsg = new ( this->mdpvFreeList ) - msgForMultiplyDefinedPV ( this->ipToAEngine, - *this, pChan->pName ( guard ), acc ); - // cac keeps a list of these objects for proper clean-up in ~cac - this->msgMultiPVList.add ( *pMsg ); - // It is possible for the ioInitiate call below to - // call the callback directly if queue quota is exceeded. - // This callback takes the callback lock and therefore we - // must release the primary mutex here to avoid a lock - // hierarchy inversion. - epicsGuardRelease < epicsMutex > unguard ( guard ); - pMsg->ioInitiate ( addr ); - } - return; - } - - caServerID servID ( addr.ia, pChan->getPriority(guard) ); - tcpiiu * piiu = this->serverTable.lookup ( servID ); - - bool newIIU = findOrCreateVirtCircuit ( - guard, addr, - pChan->getPriority(guard), piiu, minorVersionNumber ); - - // must occur before moving to new iiu - pChan->getPIIU(guard)->uninstallChanDueToSuccessfulSearchResponse ( - guard, *pChan, currentTime ); - if ( piiu ) { - piiu->installChannel ( - guard, *pChan, sid, typeCode, count ); - - if ( newIIU ) { - piiu->start ( guard ); - } - } -} - -void cac::destroyChannel ( - epicsGuard < epicsMutex > & guard, - nciu & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - // uninstall channel so that recv threads - // will not start a new callback for this channel's IO. - if ( this->chanTable.remove ( chan ) != & chan ) { - throw std::logic_error ( "Invalid channel identifier" ); - } - chan.~nciu (); - this->channelFreeList.release ( & chan ); -} - -void cac::disconnectAllIO ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, - nciu & chan, tsDLList < baseNMIU > & ioList ) -{ - cbGuard.assertIdenticalMutex ( this->cbMutex ); - guard.assertIdenticalMutex ( this->mutex ); - char buf[128]; - chan.getHostName ( guard, buf, sizeof ( buf ) ); - - tsDLIter < baseNMIU > pNetIO = ioList.firstIter(); - while ( pNetIO.valid () ) { - tsDLIter < baseNMIU > pNext = pNetIO; - pNext++; - if ( ! pNetIO->isSubscription() ) { - this->ioTable.remove ( pNetIO->getId () ); - } - pNetIO->exception ( guard, *this, ECA_DISCONN, buf ); - pNetIO = pNext; - } -} - -int cac :: printFormated ( - epicsGuard < epicsMutex > & callbackControl, - const char * pformat, ... ) const -{ - va_list theArgs; - va_start ( theArgs, pformat ); - int status = this->varArgsPrintFormated ( callbackControl, pformat, theArgs ); - va_end ( theArgs ); - return status; -} - -netWriteNotifyIO & cac::writeNotifyRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, privateInterfaceForIO & icni, - unsigned type, arrayElementCount nElem, const void * pValue, cacWriteNotify & notifyIn ) -{ - guard.assertIdenticalMutex ( this->mutex ); - autoPtrRecycle < netWriteNotifyIO > pIO ( - guard, this->ioTable, *this, - netWriteNotifyIO::factory ( this->freeListWriteNotifyIO, icni, notifyIn ) ); - this->ioTable.idAssignAdd ( *pIO ); - chan.getPIIU(guard)->writeNotifyRequest ( - guard, chan, *pIO, type, nElem, pValue ); - return *pIO.release(); -} - -netReadNotifyIO & cac::readNotifyRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, privateInterfaceForIO & icni, - unsigned type, arrayElementCount nElem, cacReadNotify & notifyIn ) -{ - guard.assertIdenticalMutex ( this->mutex ); - autoPtrRecycle < netReadNotifyIO > pIO ( - guard, this->ioTable, *this, - netReadNotifyIO::factory ( this->freeListReadNotifyIO, icni, notifyIn ) ); - this->ioTable.idAssignAdd ( *pIO ); - chan.getPIIU(guard)->readNotifyRequest ( guard, chan, *pIO, type, nElem ); - return *pIO.release(); -} - -bool cac::destroyIO ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & guard, - const cacChannel::ioid & idIn, nciu & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - baseNMIU * pIO = this->ioTable.remove ( idIn ); - if ( pIO ) { - class netSubscription * pSubscr = pIO->isSubscription (); - if ( pSubscr ) { - pSubscr->unsubscribeIfRequired ( guard, chan ); - } - - // this uninstalls from the list and destroys the IO - pIO->exception ( guard, *this, - ECA_CHANDESTROY, chan.pName ( guard ) ); - return true; - } - return false; -} - -void cac::ioShow ( - epicsGuard < epicsMutex > & guard, - const cacChannel::ioid & idIn, unsigned level ) const -{ - baseNMIU * pmiu = this->ioTable.lookup ( idIn ); - if ( pmiu ) { - pmiu->show ( guard, level ); - } -} - -void cac::ioExceptionNotify ( - unsigned idIn, int status, const char * pContext, - unsigned type, arrayElementCount count ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - baseNMIU * pmiu = this->ioTable.lookup ( idIn ); - if ( pmiu ) { - pmiu->exception ( guard, *this, status, pContext, type, count ); - } -} - -void cac::ioExceptionNotifyAndUninstall ( - unsigned idIn, int status, const char * pContext, - unsigned type, arrayElementCount count ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - baseNMIU * pmiu = this->ioTable.remove ( idIn ); - if ( pmiu ) { - pmiu->exception ( guard, *this, status, pContext, type, count ); - } -} - -void cac::recycleReadNotifyIO ( - epicsGuard < epicsMutex > & guard, netReadNotifyIO & io ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->freeListReadNotifyIO.release ( & io ); -} - -void cac::recycleWriteNotifyIO ( - epicsGuard < epicsMutex > & guard, netWriteNotifyIO & io ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->freeListWriteNotifyIO.release ( & io ); -} - -void cac::recycleSubscription ( - epicsGuard < epicsMutex > & guard, netSubscription & io ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->freeListSubscription.release ( & io ); -} - -netSubscription & cac::subscriptionRequest ( - epicsGuard < epicsMutex > & guard, - nciu & chan, privateInterfaceForIO & privChan, - unsigned type, - arrayElementCount nElem, unsigned mask, - cacStateNotify & notifyIn, - bool chanIsInstalled ) -{ - guard.assertIdenticalMutex ( this->mutex ); - autoPtrRecycle < netSubscription > pIO ( - guard, this->ioTable, *this, - netSubscription::factory ( this->freeListSubscription, - privChan, type, nElem, mask, notifyIn ) ); - this->ioTable.idAssignAdd ( *pIO ); - if ( chanIsInstalled ) { - pIO->subscribeIfRequired ( guard, chan ); - } - return *pIO.release (); -} - -bool cac::versionAction ( callbackManager &, tcpiiu & iiu, - const epicsTime &, const caHdrLargeArray & msg, void * ) -{ - iiu.versionRespNotify ( msg ); - return true; -} - -bool cac::echoRespAction ( - callbackManager & mgr, tcpiiu & iiu, - const epicsTime & /* current */, const caHdrLargeArray &, void * ) -{ - iiu.probeResponseNotify ( mgr.cbGuard ); - return true; -} - -bool cac::writeNotifyRespAction ( - callbackManager &, tcpiiu &, - const epicsTime &, const caHdrLargeArray & hdr, void * ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - baseNMIU * pmiu = this->ioTable.remove ( hdr.m_available ); - if ( pmiu ) { - if ( hdr.m_cid == ECA_NORMAL ) { - pmiu->completion ( guard, *this ); - } - else { - pmiu->exception ( guard, *this, - hdr.m_cid, "write notify request rejected" ); - } - } - return true; -} - -bool cac::readNotifyRespAction ( callbackManager &, tcpiiu & iiu, - const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - /* - * the channel id field is abused for - * read notify status starting with CA V4.1 - */ - int caStatus; - if ( iiu.ca_v41_ok ( guard ) ) { - caStatus = hdr.m_cid; - } - else { - caStatus = ECA_NORMAL; - } - - baseNMIU * pmiu = this->ioTable.remove ( hdr.m_available ); - // - // The IO destroy routines take the call back mutex - // when uninstalling and deleting the baseNMIU so there is - // no need to worry here about the baseNMIU being deleted while - // it is in use here. - // - if ( pmiu ) { - // if its a circuit-becomes-responsive subscription update - // then we need to reinstall the IO into the table - netSubscription * pSubscr = pmiu->isSubscription (); - if ( pSubscr ) { - // this does *not* assign a new resource id - this->ioTable.add ( *pmiu ); - } - if ( caStatus == ECA_NORMAL ) { - /* - * convert the data buffer from net - * format to host format - */ - caStatus = caNetConvert ( - hdr.m_dataType, pMsgBdy, pMsgBdy, false, hdr.m_count ); - } - if ( caStatus == ECA_NORMAL ) { - pmiu->completion ( guard, *this, - hdr.m_dataType, hdr.m_count, pMsgBdy ); - } - else { - pmiu->exception ( guard, *this, - caStatus, "read failed", - hdr.m_dataType, hdr.m_count ); - } - } - return true; -} - -bool cac::searchRespAction ( callbackManager &, tcpiiu & iiu, - const epicsTime & currentTime, const caHdrLargeArray & msg, - void * /* pMsgBdy */ ) -{ - assert ( this->pudpiiu ); - iiu.searchRespNotify ( currentTime, msg ); - return true; -} - -bool cac::eventRespAction ( callbackManager &, tcpiiu &iiu, - const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy ) -{ - int caStatus; - - /* - * m_postsize = 0 used to be a subscription cancel confirmation, - * but is now a noop because the IO block is immediately deleted - */ - if ( ! hdr.m_postsize ) { - return true; - } - - epicsGuard < epicsMutex > guard ( this->mutex ); - - /* - * the channel id field is abused for - * read notify status starting with CA V4.1 - */ - if ( iiu.ca_v41_ok ( guard ) ) { - caStatus = hdr.m_cid; - } - else { - caStatus = ECA_NORMAL; - } - - // - // The IO destroy routines take the call back mutex - // when uninstalling and deleting the baseNMIU so there is - // no need to worry here about the baseNMIU being deleted while - // it is in use here. - // - baseNMIU * pmiu = this->ioTable.lookup ( hdr.m_available ); - if ( pmiu ) { - /* - * convert the data buffer from net format to host format - */ - if ( caStatus == ECA_NORMAL ) { - caStatus = caNetConvert ( - hdr.m_dataType, pMsgBdy, pMsgBdy, false, hdr.m_count ); - } - if ( caStatus == ECA_NORMAL ) { - pmiu->completion ( guard, *this, - hdr.m_dataType, hdr.m_count, pMsgBdy ); - } - else { - pmiu->exception ( guard, *this, caStatus, - "subscription update read failed", - hdr.m_dataType, hdr.m_count ); - } - } - return true; -} - -bool cac::readRespAction ( callbackManager &, tcpiiu &, - const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - baseNMIU * pmiu = this->ioTable.remove ( hdr.m_available ); - // - // The IO destroy routines take the call back mutex - // when uninstalling and deleting the baseNMIU so there is - // no need to worry here about the baseNMIU being deleted while - // it is in use here. - // - if ( pmiu ) { - pmiu->completion ( guard, *this, - hdr.m_dataType, hdr.m_count, pMsgBdy ); - } - return true; -} - -bool cac::clearChannelRespAction ( callbackManager &, tcpiiu &, - const epicsTime &, const caHdrLargeArray &, void * /* pMsgBody */ ) -{ - return true; // currently a noop -} - -bool cac::defaultExcep ( - callbackManager &, tcpiiu & iiu, - const caHdrLargeArray &, const char * pCtx, unsigned status ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - char buf[512]; - char hostName[64]; - iiu.getHostName ( guard, hostName, sizeof ( hostName ) ); - sprintf ( buf, "host=%s ctx=%.400s", hostName, pCtx ); - this->notify.exception ( guard, status, buf, 0, 0u ); - return true; -} - -void cac::exception ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, int status, - const char * pContext, const char * pFileName, unsigned lineNo ) -{ - cbGuard.assertIdenticalMutex ( this->cbMutex ); - guard.assertIdenticalMutex ( this->mutex ); - this->notify.exception ( guard, status, pContext, - pFileName, lineNo ); -} - -bool cac::eventAddExcep ( - callbackManager &, tcpiiu &, - const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ) -{ - this->ioExceptionNotify ( hdr.m_available, status, pCtx, - hdr.m_dataType, hdr.m_count ); - return true; -} - -bool cac::readExcep ( callbackManager &, tcpiiu &, - const caHdrLargeArray & hdr, - const char * pCtx, unsigned status ) -{ - this->ioExceptionNotifyAndUninstall ( hdr.m_available, - status, pCtx, hdr.m_dataType, hdr.m_count ); - return true; -} - -bool cac::writeExcep ( - callbackManager & mgr, - tcpiiu &, const caHdrLargeArray & hdr, - const char * pCtx, unsigned status ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - nciu * pChan = this->chanTable.lookup ( hdr.m_available ); - if ( pChan ) { - pChan->writeException ( mgr.cbGuard, guard, status, pCtx, - hdr.m_dataType, hdr.m_count ); - } - return true; -} - -bool cac::readNotifyExcep ( callbackManager &, tcpiiu &, - const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ) -{ - this->ioExceptionNotifyAndUninstall ( hdr.m_available, - status, pCtx, hdr.m_dataType, hdr.m_count ); - return true; -} - -bool cac::writeNotifyExcep ( callbackManager &, tcpiiu &, - const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ) -{ - this->ioExceptionNotifyAndUninstall ( hdr.m_available, - status, pCtx, hdr.m_dataType, hdr.m_count ); - return true; -} - -bool cac::exceptionRespAction ( callbackManager & cbMutexIn, tcpiiu & iiu, - const epicsTime &, const caHdrLargeArray & hdr, void * pMsgBdy ) -{ - const caHdr * pReq = reinterpret_cast < const caHdr * > ( pMsgBdy ); - unsigned bytesSoFar = sizeof ( *pReq ); - if ( hdr.m_postsize < bytesSoFar ) { - return false; - } - caHdrLargeArray req; - req.m_cmmd = AlignedWireRef < const epicsUInt16 > ( pReq->m_cmmd ); - req.m_postsize = AlignedWireRef < const epicsUInt16 > ( pReq->m_postsize ); - req.m_dataType = AlignedWireRef < const epicsUInt16 > ( pReq->m_dataType ); - req.m_count = AlignedWireRef < const epicsUInt16 > ( pReq->m_count ); - req.m_cid = AlignedWireRef < const epicsUInt32 > ( pReq->m_cid ); - req.m_available = AlignedWireRef < const epicsUInt32 > ( pReq->m_available ); - const ca_uint32_t * pLW = reinterpret_cast < const ca_uint32_t * > ( pReq + 1 ); - if ( req.m_postsize == 0xffff ) { - static const unsigned annexSize = - sizeof ( req.m_postsize ) + sizeof ( req.m_count ); - bytesSoFar += annexSize; - if ( hdr.m_postsize < bytesSoFar ) { - return false; - } - req.m_postsize = AlignedWireRef < const epicsUInt32 > ( pLW[0] ); - req.m_count = AlignedWireRef < const epicsUInt32 > ( pLW[1] ); - pLW += 2u; - } - - // execute the exception message - pExcepProtoStubTCP pStub; - if ( hdr.m_cmmd >= NELEMENTS ( cac::tcpExcepJumpTableCAC ) ) { - pStub = &cac::defaultExcep; - } - else { - pStub = cac::tcpExcepJumpTableCAC [req.m_cmmd]; - } - const char *pCtx = reinterpret_cast < const char * > ( pLW ); - return ( this->*pStub ) ( cbMutexIn, iiu, req, pCtx, hdr.m_available ); -} - -bool cac::accessRightsRespAction ( - callbackManager & mgr, tcpiiu &, - const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - nciu * pChan = this->chanTable.lookup ( hdr.m_cid ); - if ( pChan ) { - unsigned ar = hdr.m_available; - caAccessRights accessRights ( - ( ar & CA_PROTO_ACCESS_RIGHT_READ ) ? true : false, - ( ar & CA_PROTO_ACCESS_RIGHT_WRITE ) ? true : false); - pChan->accessRightsStateChange ( accessRights, mgr.cbGuard, guard ); - } - - return true; -} - -bool cac::createChannelRespAction ( - callbackManager & mgr, tcpiiu & iiu, - const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - nciu * pChan = this->chanTable.lookup ( hdr.m_cid ); - if ( pChan ) { - unsigned sidTmp; - if ( iiu.ca_v44_ok ( guard ) ) { - sidTmp = hdr.m_available; - } - else { - sidTmp = pChan->getSID (guard); - } - bool wasExpected = iiu.connectNotify ( guard, *pChan ); - if ( wasExpected ) { - pChan->connect ( hdr.m_dataType, hdr.m_count, sidTmp, - mgr.cbGuard, guard ); - } - else { - errlogPrintf ( - "CA Client Library: Ignored duplicate create channel " - "response from CA server?\n" ); - } - } - else if ( iiu.ca_v44_ok ( guard ) ) { - // this indicates a claim response for a resource that does - // not exist in the client - so just remove it from the server - iiu.clearChannelRequest ( guard, hdr.m_available, hdr.m_cid ); - } - - return true; -} - -bool cac::verifyAndDisconnectChan ( - callbackManager & mgr, tcpiiu &, - const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - nciu * pChan = this->chanTable.lookup ( hdr.m_cid ); - if ( ! pChan ) { - return true; - } - this->disconnectChannel ( mgr.cbGuard, guard, *pChan ); - return true; -} - -void cac::disconnectChannel ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - assert ( this->pudpiiu ); - chan.disconnectAllIO ( cbGuard, guard ); - chan.getPIIU(guard)->uninstallChan ( guard, chan ); - this->pudpiiu->installDisconnectedChannel ( guard, chan ); - chan.unresponsiveCircuitNotify ( cbGuard, guard ); -} - -bool cac::badTCPRespAction ( callbackManager &, tcpiiu & iiu, - const epicsTime &, const caHdrLargeArray & hdr, void * /* pMsgBody */ ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - char hostName[64]; - iiu.getHostName ( guard, hostName, sizeof ( hostName ) ); - errlogPrintf ( "CAC: Undecipherable TCP message ( bad response type %u ) from %s\n", - hdr.m_cmmd, hostName ); - return false; -} - -bool cac::executeResponse ( callbackManager & mgr, tcpiiu & iiu, - const epicsTime & currentTime, caHdrLargeArray & hdr, char * pMshBody ) -{ - // execute the response message - pProtoStubTCP pStub; - if ( hdr.m_cmmd >= NELEMENTS ( cac::tcpJumpTableCAC ) ) { - pStub = &cac::badTCPRespAction; - } - else { - pStub = cac::tcpJumpTableCAC [hdr.m_cmmd]; - } - return ( this->*pStub ) ( mgr, iiu, currentTime, hdr, pMshBody ); -} - -void cac::selfTest ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - this->chanTable.verify (); - this->ioTable.verify (); - this->beaconTable.verify (); -} - -void cac::destroyIIU ( tcpiiu & iiu ) -{ - { - callbackManager mgr ( this->notify, this->cbMutex ); - epicsGuard < epicsMutex > guard ( this->mutex ); - - if ( iiu.channelCount ( guard ) ) { - char hostNameTmp[64]; - iiu.getHostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) ); - genLocalExcep ( mgr.cbGuard, guard, *this, ECA_DISCONN, hostNameTmp ); - } - osiSockAddr addr = iiu.getNetworkAddress ( guard ); - if ( addr.sa.sa_family == AF_INET ) { - inetAddrID tmp ( addr.ia ); - bhe * pBHE = this->beaconTable.lookup ( tmp ); - if ( pBHE ) { - pBHE->unregisterIIU ( guard, iiu ); - } - } - - assert ( this->pudpiiu ); - iiu.disconnectAllChannels ( mgr.cbGuard, guard, *this->pudpiiu ); - - this->serverTable.remove ( iiu ); - this->circuitList.remove ( iiu ); - } - - // this destroys a timer that takes the primary mutex - // so we must not hold the primary mutex here - // - // this waits for send/recv threads to exit - // this also uses the cac free lists so cac must wait - // for this to finish before it shuts down - - iiu.~tcpiiu (); - - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->freeListVirtualCircuit.release ( & iiu ); - this->iiuExistenceCount--; - // signal iiu uninstall event so that cac can properly shut down - this->iiuUninstall.signal(); - } - // do not touch "this" after lock is released above -} - -double cac::beaconPeriod ( - epicsGuard < epicsMutex > & guard, - const nciu & chan ) const -{ - const netiiu * pIIU = chan.getConstPIIU ( guard ); - if ( pIIU ) { - osiSockAddr addr = pIIU->getNetworkAddress ( guard ); - if ( addr.sa.sa_family == AF_INET ) { - inetAddrID tmp ( addr.ia ); - bhe *pBHE = this->beaconTable.lookup ( tmp ); - if ( pBHE ) { - return pBHE->period ( guard ); - } - } - } - return - DBL_MAX; -} - -void cac::initiateConnect ( - epicsGuard < epicsMutex > & guard, - nciu & chan, netiiu * & piiu ) -{ - guard.assertIdenticalMutex ( this->mutex ); - assert ( this->pudpiiu ); - this->pudpiiu->installNewChannel ( guard, chan, piiu ); -} - -void *cacComBufMemoryManager::allocate ( size_t size ) -{ - return this->freeList.allocate ( size ); -} - -void cacComBufMemoryManager::release ( void * pCadaver ) -{ - this->freeList.release ( pCadaver ); -} - -void cac::pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv, - const char * pChannelName, const char * pAcc, const char * pRej ) -{ - char buf[256]; - sprintf ( buf, "Channel: \"%.64s\", Connecting to: %.64s, Ignored: %.64s", - pChannelName, pAcc, pRej ); - { - callbackManager mgr ( this->notify, this->cbMutex ); - epicsGuard < epicsMutex > guard ( this->mutex ); - this->exception ( mgr.cbGuard, guard, ECA_DBLCHNL, buf, __FILE__, __LINE__ ); - - // remove from the list under lock - this->msgMultiPVList.remove ( mfmdpv ); - } - // delete msg object - mfmdpv.~msgForMultiplyDefinedPV (); - this->mdpvFreeList.release ( & mfmdpv ); -} - -void cac::registerSearchDest ( - epicsGuard < epicsMutex > & guard, - SearchDest & req ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->searchDestList.add ( req ); -} diff --git a/src/ca/client/cac.h b/src/ca/client/cac.h deleted file mode 100644 index 7db5c6ddc..000000000 --- a/src/ca/client/cac.h +++ /dev/null @@ -1,435 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author: Jeff Hill - * - */ - -#ifndef cach -#define cach - -#ifdef epicsExportSharedSymbols -# define cach_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "compilerDependencies.h" -#include "ipAddrToAsciiAsynchronous.h" -#include "msgForMultiplyDefinedPV.h" -#include "epicsTimer.h" -#include "epicsEvent.h" -#include "freeList.h" -#include "localHostName.h" - -#ifdef cach_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "nciu.h" -#include "comBuf.h" -#include "bhe.h" -#include "cacIO.h" -#include "netIO.h" -#include "localHostName.h" -#include "virtualCircuit.h" - -class netWriteNotifyIO; -class netReadNotifyIO; -class netSubscription; -class tcpiiu; - -// used to control access to cac's recycle routines which -// should only be indirectly invoked by CAC when its lock -// is applied -class cacRecycle { -public: - virtual void recycleReadNotifyIO ( - epicsGuard < epicsMutex > &, netReadNotifyIO &io ) = 0; - virtual void recycleWriteNotifyIO ( - epicsGuard < epicsMutex > &, netWriteNotifyIO &io ) = 0; - virtual void recycleSubscription ( - epicsGuard < epicsMutex > &, netSubscription &io ) = 0; -protected: - virtual ~cacRecycle() {} -}; - -struct CASG; -class inetAddrID; -class caServerID; -struct caHdrLargeArray; - -class cacComBufMemoryManager : public comBufMemoryManager -{ -public: - cacComBufMemoryManager () {} - void * allocate ( size_t ); - void release ( void * ); -private: - tsFreeList < comBuf, 0x20 > freeList; - cacComBufMemoryManager ( const cacComBufMemoryManager & ); - cacComBufMemoryManager & operator = ( const cacComBufMemoryManager & ); -}; - -class notifyGuard { -public: - notifyGuard ( cacContextNotify & ); - ~notifyGuard (); -private: - cacContextNotify & notify; - notifyGuard ( const notifyGuard & ); - notifyGuard & operator = ( const notifyGuard & ); -}; - -class callbackManager : public notifyGuard { -public: - callbackManager ( - cacContextNotify &, - epicsMutex & callbackControl ); - epicsGuard < epicsMutex > cbGuard; -}; - -class cac : - public cacContext, - private cacRecycle, - private callbackForMultiplyDefinedPV -{ -public: - cac ( - epicsMutex & mutualExclusion, - epicsMutex & callbackControl, - cacContextNotify & ); - virtual ~cac (); - - // beacon management - void beaconNotify ( const inetAddrID & addr, const epicsTime & currentTime, - ca_uint32_t beaconNumber, unsigned protocolRevision ); - unsigned beaconAnomaliesSinceProgramStart ( - epicsGuard < epicsMutex > & ) const; - - // IO management - void flush ( epicsGuard < epicsMutex > & guard ); - bool executeResponse ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, caHdrLargeArray &, char *pMsgBody ); - - // channel routines - void transferChanToVirtCircuit ( - unsigned cid, unsigned sid, - ca_uint16_t typeCode, arrayElementCount count, - unsigned minorVersionNumber, const osiSockAddr &, - const epicsTime & currentTime ); - cacChannel & createChannel ( - epicsGuard < epicsMutex > & guard, const char * pChannelName, - cacChannelNotify &, cacChannel::priLev ); - void destroyChannel ( - epicsGuard < epicsMutex > &, nciu & ); - void initiateConnect ( - epicsGuard < epicsMutex > &, nciu &, netiiu * & ); - nciu * lookupChannel ( - epicsGuard < epicsMutex > &, const cacChannel::ioid & ); - - // IO requests - netWriteNotifyIO & writeNotifyRequest ( - epicsGuard < epicsMutex > &, nciu &, privateInterfaceForIO &, - unsigned type, arrayElementCount nElem, const void * pValue, - cacWriteNotify & ); - netReadNotifyIO & readNotifyRequest ( - epicsGuard < epicsMutex > &, nciu &, privateInterfaceForIO &, - unsigned type, arrayElementCount nElem, - cacReadNotify & ); - netSubscription & subscriptionRequest ( - epicsGuard < epicsMutex > &, nciu &, privateInterfaceForIO &, - unsigned type, arrayElementCount nElem, unsigned mask, - cacStateNotify &, bool channelIsInstalled ); - bool destroyIO ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - const cacChannel::ioid & idIn, - nciu & chan ); - void disconnectAllIO ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, - nciu &, tsDLList < baseNMIU > & ioList ); - - void ioShow ( - epicsGuard < epicsMutex > & guard, - const cacChannel::ioid &id, unsigned level ) const; - - // exception generation - void exception ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, - int status, const char * pContext, - const char * pFileName, unsigned lineNo ); - - // search destination management - void registerSearchDest ( - epicsGuard < epicsMutex > &, SearchDest & req ); - bool findOrCreateVirtCircuit ( - epicsGuard < epicsMutex > &, const osiSockAddr &, - unsigned, tcpiiu *&, unsigned, SearchDestTCP * pSearchDest = NULL ); - - // diagnostics - unsigned circuitCount ( epicsGuard < epicsMutex > & ) const; - void show ( epicsGuard < epicsMutex > &, unsigned level ) const; - int printFormated ( - epicsGuard < epicsMutex > & callbackControl, - const char *pformat, ... ) const; - int varArgsPrintFormated ( - epicsGuard < epicsMutex > & callbackControl, - const char *pformat, va_list args ) const; - double connectionTimeout ( epicsGuard < epicsMutex > & ); - - unsigned maxContiguousFrames ( epicsGuard < epicsMutex > & ) const; - - // misc - const char * userNamePointer () const; - unsigned getInitializingThreadsPriority () const; - epicsMutex & mutexRef (); - void attachToClientCtx (); - void selfTest ( - epicsGuard < epicsMutex > & ) const; - double beaconPeriod ( - epicsGuard < epicsMutex > &, - const nciu & chan ) const; - static unsigned lowestPriorityLevelAbove ( unsigned priority ); - static unsigned highestPriorityLevelBelow ( unsigned priority ); - void destroyIIU ( tcpiiu & iiu ); - - const char * pLocalHostName (); - -private: - epicsSingleton < localHostName > :: reference _refLocalHostName; - chronIntIdResTable < nciu > chanTable; - // - // !!!! There is at this point no good reason - // !!!! to maintain one IO table for all types of - // !!!! IO. It would probably be better to maintain - // !!!! an independent table for each IO type. The - // !!!! new adaptive sized hash table will not - // !!!! waste memory. Making this change will - // !!!! avoid virtual function overhead when - // !!!! accessing the different types of IO. This - // !!!! approach would also probably be safer in - // !!!! terms of detecting damaged protocol. - // - chronIntIdResTable < baseNMIU > ioTable; - resTable < bhe, inetAddrID > beaconTable; - resTable < tcpiiu, caServerID > serverTable; - tsDLList < tcpiiu > circuitList; - tsDLList < SearchDest > searchDestList; - tsDLList < msgForMultiplyDefinedPV > msgMultiPVList; - tsFreeList - < class tcpiiu, 32, epicsMutexNOOP > - freeListVirtualCircuit; - tsFreeList - < class netReadNotifyIO, 1024, epicsMutexNOOP > - freeListReadNotifyIO; - tsFreeList - < class netWriteNotifyIO, 1024, epicsMutexNOOP > - freeListWriteNotifyIO; - tsFreeList - < class netSubscription, 1024, epicsMutexNOOP > - freeListSubscription; - tsFreeList - < class nciu, 1024, epicsMutexNOOP > - channelFreeList; - tsFreeList - < class msgForMultiplyDefinedPV, 16 > - mdpvFreeList; - cacComBufMemoryManager comBufMemMgr; - bheFreeStore bheFreeList; - epicsTime programBeginTime; - double connTMO; - // **** lock hierarchy **** - // 1) callback lock must always be acquired before - // the primary mutex if both locks are needed - epicsMutex & mutex; - epicsMutex & cbMutex; - epicsEvent iiuUninstall; - ipAddrToAsciiEngine & ipToAEngine; - epicsTimerQueueActive & timerQueue; - char * pUserName; - class udpiiu * pudpiiu; - void * tcpSmallRecvBufFreeList; - void * tcpLargeRecvBufFreeList; - cacContextNotify & notify; - epicsThreadId initializingThreadsId; - unsigned initializingThreadsPriority; - unsigned maxRecvBytesTCP; - unsigned maxContigFrames; - unsigned beaconAnomalyCount; - unsigned short _serverPort; - unsigned iiuExistenceCount; - bool cacShutdownInProgress; - - void recycleReadNotifyIO ( - epicsGuard < epicsMutex > &, netReadNotifyIO &io ); - void recycleWriteNotifyIO ( - epicsGuard < epicsMutex > &, netWriteNotifyIO &io ); - void recycleSubscription ( - epicsGuard < epicsMutex > &, netSubscription &io ); - - void disconnectChannel ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, nciu & chan ); - - void ioExceptionNotify ( unsigned id, int status, - const char * pContext, unsigned type, arrayElementCount count ); - void ioExceptionNotifyAndUninstall ( unsigned id, int status, - const char * pContext, unsigned type, arrayElementCount count ); - - void pvMultiplyDefinedNotify ( msgForMultiplyDefinedPV & mfmdpv, - const char * pChannelName, const char * pAcc, const char * pRej ); - - // recv protocol stubs - bool versionAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool echoRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool writeNotifyRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool searchRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool readNotifyRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool eventRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool readRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool clearChannelRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool exceptionRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool accessRightsRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool createChannelRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool verifyAndDisconnectChan ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - bool badTCPRespAction ( callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - - typedef bool ( cac::*pProtoStubTCP ) ( - callbackManager &, tcpiiu &, - const epicsTime & currentTime, const caHdrLargeArray &, void *pMsgBdy ); - static const pProtoStubTCP tcpJumpTableCAC []; - - bool defaultExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ); - bool eventAddExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ); - bool readExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ); - bool writeExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ); - bool clearChanExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ); - bool readNotifyExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ); - bool writeNotifyExcep ( callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ); - typedef bool ( cac::*pExcepProtoStubTCP ) ( - callbackManager &, tcpiiu &iiu, const caHdrLargeArray &hdr, - const char *pCtx, unsigned status ); - static const pExcepProtoStubTCP tcpExcepJumpTableCAC []; - - cac ( const cac & ); - cac & operator = ( const cac & ); - - friend class tcpiiu; -}; - -inline const char * cac::userNamePointer () const -{ - return this->pUserName; -} - -inline unsigned cac::getInitializingThreadsPriority () const -{ - return this->initializingThreadsPriority; -} - -inline epicsMutex & cac::mutexRef () -{ - return this->mutex; -} - -inline int cac :: varArgsPrintFormated ( - epicsGuard < epicsMutex > & callbackControl, - const char *pformat, va_list args ) const -{ - callbackControl.assertIdenticalMutex ( this->cbMutex ); - return this->notify.varArgsPrintFormated ( pformat, args ); -} - -inline void cac::attachToClientCtx () -{ - this->notify.attachToClientCtx (); -} - -inline unsigned cac::beaconAnomaliesSinceProgramStart ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->beaconAnomalyCount; -} - -inline notifyGuard::notifyGuard ( cacContextNotify & notifyIn ) : - notify ( notifyIn ) -{ - this->notify.callbackProcessingInitiateNotify (); -} - -inline notifyGuard::~notifyGuard () -{ - this->notify.callbackProcessingCompleteNotify (); -} - -inline callbackManager::callbackManager ( - cacContextNotify & notify, epicsMutex & callbackControl ) : - notifyGuard ( notify ), cbGuard ( callbackControl ) -{ -} - -inline nciu * cac::lookupChannel ( - epicsGuard < epicsMutex > & guard, - const cacChannel::ioid & idIn ) -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->chanTable.lookup ( idIn ); -} - -inline const char * cac :: pLocalHostName () -{ - return _refLocalHostName->pointer (); -} - -inline unsigned cac :: - maxContiguousFrames ( epicsGuard < epicsMutex > & ) const -{ - return maxContigFrames; -} - -inline double cac :: - connectionTimeout ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->connTMO; -} - -#endif // ifdef cach diff --git a/src/ca/client/cacChannel.cpp b/src/ca/client/cacChannel.cpp deleted file mode 100644 index c1a52a002..000000000 --- a/src/ca/client/cacChannel.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "localHostName.h" -#include "cacIO.h" - -class CACChannelPrivate { -public: - CACChannelPrivate (); - unsigned getHostName ( char * pBuf, unsigned bufLength ); - const char * pHostName (); -private: - epicsSingleton < localHostName > :: reference - _refLocalHostName; -}; - -static epicsThreadOnceId cacChannelIdOnce = EPICS_THREAD_ONCE_INIT; - -const cacChannel::priLev cacChannel::priorityMax = 99u; -const cacChannel::priLev cacChannel::priorityMin = 0u; -const cacChannel::priLev cacChannel::priorityDefault = priorityMin; -const cacChannel::priLev cacChannel::priorityLinksDB = priorityMax; -const cacChannel::priLev cacChannel::priorityArchive = ( priorityMax - priorityMin ) / 2; -const cacChannel::priLev cacChannel::priorityOPI = priorityMin; - -cacChannel::~cacChannel () -{ -} - -caAccessRights cacChannel::accessRights ( - epicsGuard < epicsMutex > & ) const -{ - static caAccessRights ar ( true, true ); - return ar; -} - -unsigned cacChannel::searchAttempts ( - epicsGuard < epicsMutex > & ) const -{ - return 0u; -} - -double cacChannel::beaconPeriod ( - epicsGuard < epicsMutex > & ) const -{ - return - DBL_MAX; -} - -double cacChannel::receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const -{ - return - DBL_MAX; -} - -bool cacChannel::ca_v42_ok ( - epicsGuard < epicsMutex > & ) const -{ - return true; -} - -bool cacChannel::connected ( - epicsGuard < epicsMutex > & ) const -{ - return true; -} - -CACChannelPrivate :: - CACChannelPrivate() : - _refLocalHostName ( localHostNameCache.getReference () ) -{ -} - -inline unsigned CACChannelPrivate :: - getHostName ( char * pBuf, unsigned bufLength ) -{ - return _refLocalHostName->getName ( pBuf, bufLength ); -} - -inline const char * CACChannelPrivate :: - pHostName () -{ - return _refLocalHostName->pointer (); -} - -static CACChannelPrivate * pCACChannelPrivate = 0; - -// runs once only for each process -extern "C" void cacChannelSetup ( void * ) -{ - pCACChannelPrivate = new CACChannelPrivate (); -} - -// the default is to assume that it is a locally hosted channel -unsigned cacChannel::getHostName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLength ) const throw () -{ - if ( bufLength ) { - epicsThreadOnce ( & cacChannelIdOnce, cacChannelSetup, 0); - return pCACChannelPrivate->getHostName ( pBuf, bufLength ); - } - return 0u; -} - -// the default is to assume that it is a locally hosted channel -const char * cacChannel::pHostName ( - epicsGuard < epicsMutex > & ) const throw () -{ - epicsThreadOnce ( & cacChannelIdOnce, cacChannelSetup, 0); - return pCACChannelPrivate->pHostName (); -} - -cacContext::~cacContext () {} - -cacService::~cacService () {} - - diff --git a/src/ca/client/cacChannelNotify.cpp b/src/ca/client/cacChannelNotify.cpp deleted file mode 100644 index 08d2cab94..000000000 --- a/src/ca/client/cacChannelNotify.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include "iocinf.h" - -#define epicsExportSharedSymbols -#include "cacIO.h" -#undef epicsExportSharedSymbols - -cacChannelNotify::~cacChannelNotify () -{ -} - diff --git a/src/ca/client/cacContextNotify.cpp b/src/ca/client/cacContextNotify.cpp deleted file mode 100644 index a4498ac04..000000000 --- a/src/ca/client/cacContextNotify.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include - -#include "iocinf.h" - -#define epicsExportSharedSymbols -#include "cacIO.h" -#undef epicsExportSharedSymbols - -cacContextNotify::~cacContextNotify () -{ -} - -void cacContextNotify::callbackProcessingInitiateNotify () -{ -} - -void cacContextNotify::callbackProcessingCompleteNotify () -{ -} - - - diff --git a/src/ca/client/cacIO.h b/src/ca/client/cacIO.h deleted file mode 100644 index 4e8af4a05..000000000 --- a/src/ca/client/cacIO.h +++ /dev/null @@ -1,392 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef cacIOh -#define cacIOh - -// -// Open Issues -// ----------- -// -// 1) A status code from the old client side interface is passed -// to the exception notify callback. Should we just pass a string? -// If so, then how do they detect the type of error and recover. -// Perhaps we should call a different vf for each type of exception. -// -// 2) Some exception types are present here but there is no common -// exception base class in use. -// -// 3) Should I be passing the channel reference in cacChannelNotify? -// -// 4) Should the code for caAccessRights not be inline so that this -// interface is version independent. -// -// - -#include -#include - -#ifdef epicsExportSharedSymbols -# define cacIOh_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "tsDLList.h" -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsThread.h" - -#ifdef cacIOh_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - - -class cacChannel; - -typedef unsigned long arrayElementCount; - -// 1) this should not be passing caerr.h status to the exception callback -// 2) needless-to-say the data should be passed here using the new data access API -class epicsShareClass cacWriteNotify { -public: - virtual ~cacWriteNotify () = 0; - virtual void completion ( epicsGuard < epicsMutex > & ) = 0; -// we should probably have a different vf for each type of exception ???? - virtual void exception ( - epicsGuard < epicsMutex > &, - int status, const char * pContext, - unsigned type, arrayElementCount count ) = 0; -}; - -// 1) this should not be passing caerr.h status to the exception callback -// 2) needless-to-say the data should be passed here using the new data access API -class epicsShareClass cacReadNotify { -public: - virtual ~cacReadNotify () = 0; - virtual void completion ( - epicsGuard < epicsMutex > &, unsigned type, - arrayElementCount count, const void * pData ) = 0; -// we should probably have a different vf for each type of exception ???? - virtual void exception ( - epicsGuard < epicsMutex > &, int status, - const char * pContext, unsigned type, - arrayElementCount count ) = 0; -}; - -// 1) this should not be passing caerr.h status to the exception callback -// 2) needless-to-say the data should be passed here using the new data access API -class epicsShareClass cacStateNotify { -public: - virtual ~cacStateNotify () = 0; - virtual void current ( - epicsGuard < epicsMutex > &, unsigned type, - arrayElementCount count, const void * pData ) = 0; -// we should probably have a different vf for each type of exception ???? - virtual void exception ( - epicsGuard < epicsMutex > &, int status, - const char *pContext, unsigned type, - arrayElementCount count ) = 0; -}; - -class caAccessRights { -public: - caAccessRights ( - bool readPermit = false, - bool writePermit = false, - bool operatorConfirmationRequest = false); - void setReadPermit (); - void setWritePermit (); - void setOperatorConfirmationRequest (); - void clrReadPermit (); - void clrWritePermit (); - void clrOperatorConfirmationRequest (); - bool readPermit () const; - bool writePermit () const; - bool operatorConfirmationRequest () const; -private: - bool f_readPermit:1; - bool f_writePermit:1; - bool f_operatorConfirmationRequest:1; -}; - -class epicsShareClass cacChannelNotify { -public: - virtual ~cacChannelNotify () = 0; - virtual void connectNotify ( epicsGuard < epicsMutex > & ) = 0; - virtual void disconnectNotify ( epicsGuard < epicsMutex > & ) = 0; - virtual void serviceShutdownNotify ( - epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0; - virtual void accessRightsNotify ( - epicsGuard < epicsMutex > &, const caAccessRights & ) = 0; - virtual void exception ( - epicsGuard < epicsMutex > &, int status, const char *pContext ) = 0; -// we should probably have a different vf for each type of exception ???? - virtual void readException ( - epicsGuard < epicsMutex > &, int status, const char *pContext, - unsigned type, arrayElementCount count, void *pValue ) = 0; -// we should probably have a different vf for each type of exception ???? - virtual void writeException ( - epicsGuard < epicsMutex > &, int status, const char * pContext, - unsigned type, arrayElementCount count ) = 0; -}; - -class CallbackGuard : - public epicsGuard < epicsMutex > { -public: - CallbackGuard ( epicsMutex & mutex ) : - epicsGuard < epicsMutex > ( mutex ) {} -private: - CallbackGuard ( const CallbackGuard & ); - CallbackGuard & operator = ( const CallbackGuard & ); -}; - -// -// Notes -// 1) This interface assumes that when a channel is deleted then all -// attached IO is deleted. This is left over from the old interface, -// but perhaps is a bad practice that should be eliminated? If so, -// then the IO should not store or use a pointer to the channel. -// -class epicsShareClass cacChannel { -public: - typedef unsigned priLev; - static const priLev priorityMax; - static const priLev priorityMin; - static const priLev priorityDefault; - static const priLev priorityLinksDB; - static const priLev priorityArchive; - static const priLev priorityOPI; - - typedef unsigned ioid; - enum ioStatus { iosSynch, iosAsynch }; - - cacChannel ( cacChannelNotify & ); - virtual void destroy ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0; - cacChannelNotify & notify () const; // required ????? - virtual unsigned getName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw () = 0; - // !! deprecated, avoid use !! - virtual const char * pName ( - epicsGuard < epicsMutex > & guard ) const throw () = 0; - virtual void show ( - epicsGuard < epicsMutex > &, - unsigned level ) const = 0; - virtual void initiateConnect ( - epicsGuard < epicsMutex > & ) = 0; - virtual unsigned requestMessageBytesPending ( - epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0; - virtual void flush ( - epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0; - virtual ioStatus read ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, - cacReadNotify &, ioid * = 0 ) = 0; - virtual void write ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, - const void *pValue ) = 0; - virtual ioStatus write ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, - const void *pValue, cacWriteNotify &, ioid * = 0 ) = 0; - virtual void subscribe ( - epicsGuard < epicsMutex > &, unsigned type, - arrayElementCount count, unsigned mask, cacStateNotify &, - ioid * = 0 ) = 0; - // The primary mutex must be released when calling the user's - // callback, and therefore a finite interval exists when we are - // moving forward with the intent to call the users callback - // but the users IO could be deleted during this interval. - // To prevent the user's callback from being called after - // destroying his IO we must past a guard for the callback - // mutex here. - virtual void ioCancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - const ioid & ) = 0; - virtual void ioShow ( - epicsGuard < epicsMutex > &, - const ioid &, unsigned level ) const = 0; - virtual short nativeType ( - epicsGuard < epicsMutex > & ) const = 0; - virtual arrayElementCount nativeElementCount ( - epicsGuard < epicsMutex > & ) const = 0; - virtual caAccessRights accessRights ( - epicsGuard < epicsMutex > & ) const; - virtual unsigned searchAttempts ( - epicsGuard < epicsMutex > & ) const; - virtual double beaconPeriod ( - epicsGuard < epicsMutex > & ) const; // negative DBL_MAX if UKN - virtual double receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const; // negative DBL_MAX if UKN - virtual bool ca_v42_ok ( - epicsGuard < epicsMutex > & ) const; - virtual bool connected ( - epicsGuard < epicsMutex > & ) const; - virtual unsigned getHostName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLength ) const throw (); - // !! deprecated, avoid use !! - virtual const char * pHostName ( - epicsGuard < epicsMutex > & guard ) const throw (); - - // exceptions - class badString {}; - class badType {}; - class badPriority {}; - class outOfBounds {}; - class badEventSelection {}; - class noWriteAccess {}; - class noReadAccess {}; - class notConnected {}; - class unsupportedByService {}; - class msgBodyCacheTooSmall {}; // hopefully this one goes away in the future - class requestTimedOut {}; - -protected: - virtual ~cacChannel () = 0; - -private: - cacChannelNotify & callback; - cacChannel ( const cacChannel & ); - cacChannel & operator = ( const cacChannel & ); -}; - -class epicsShareClass cacContext { -public: - virtual ~cacContext (); - virtual cacChannel & createChannel ( - epicsGuard < epicsMutex > &, - const char * pChannelName, cacChannelNotify &, - cacChannel::priLev = cacChannel::priorityDefault ) = 0; - virtual void flush ( - epicsGuard < epicsMutex > & ) = 0; - virtual unsigned circuitCount ( - epicsGuard < epicsMutex > & ) const = 0; - virtual void selfTest ( - epicsGuard < epicsMutex > & ) const = 0; - virtual unsigned beaconAnomaliesSinceProgramStart ( - epicsGuard < epicsMutex > & ) const = 0; - virtual void show ( - epicsGuard < epicsMutex > &, unsigned level ) const = 0; -}; - -class epicsShareClass cacContextNotify { -public: - virtual ~cacContextNotify () = 0; - virtual cacContext & createNetworkContext ( - epicsMutex & mutualExclusion, epicsMutex & callbackControl ) = 0; -// we should probably have a different vf for each type of exception ???? - virtual void exception ( - epicsGuard < epicsMutex > &, int status, const char * pContext, - const char * pFileName, unsigned lineNo ) = 0; -// perhaps this should be phased out in deference to the exception mechanism - virtual int varArgsPrintFormated ( const char * pformat, va_list args ) const = 0; -// backwards compatibility (from here down) - virtual void attachToClientCtx () = 0; - virtual void callbackProcessingInitiateNotify () = 0; - virtual void callbackProcessingCompleteNotify () = 0; -}; - -// **** Lock Hierarchy **** -// callbackControl must be taken before mutualExclusion if both are held at -// the same time -class epicsShareClass cacService { -public: - virtual ~cacService () = 0; - virtual cacContext & contextCreate ( - epicsMutex & mutualExclusion, - epicsMutex & callbackControl, - cacContextNotify & ) = 0; -}; - -epicsShareFunc void epicsShareAPI caInstallDefaultService ( cacService & service ); - -epicsShareExtern epicsThreadPrivateId caClientCallbackThreadId; - -inline cacChannel::cacChannel ( cacChannelNotify & notify ) : - callback ( notify ) -{ -} - -inline cacChannelNotify & cacChannel::notify () const -{ - return this->callback; -} - -inline caAccessRights::caAccessRights ( - bool readPermit, bool writePermit, bool operatorConfirmationRequest) : - f_readPermit ( readPermit ), f_writePermit ( writePermit ), - f_operatorConfirmationRequest ( operatorConfirmationRequest ) {} - -inline void caAccessRights::setReadPermit () -{ - this->f_readPermit = true; -} - -inline void caAccessRights::setWritePermit () -{ - this->f_writePermit = true; -} - -inline void caAccessRights::setOperatorConfirmationRequest () -{ - this->f_operatorConfirmationRequest = true; -} - -inline void caAccessRights::clrReadPermit () -{ - this->f_readPermit = false; -} - -inline void caAccessRights::clrWritePermit () -{ - this->f_writePermit = false; -} - -inline void caAccessRights::clrOperatorConfirmationRequest () -{ - this->f_operatorConfirmationRequest = false; -} - -inline bool caAccessRights::readPermit () const -{ - return this->f_readPermit; -} - -inline bool caAccessRights::writePermit () const -{ - return this->f_writePermit; -} - -inline bool caAccessRights::operatorConfirmationRequest () const -{ - return this->f_operatorConfirmationRequest; -} - -#endif // ifndef cacIOh diff --git a/src/ca/client/cacReadNotify.cpp b/src/ca/client/cacReadNotify.cpp deleted file mode 100644 index 23284c8df..000000000 --- a/src/ca/client/cacReadNotify.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include "iocinf.h" - -#define epicsExportSharedSymbols -#include "cacIO.h" -#undef epicsExportSharedSymbols - -cacReadNotify::~cacReadNotify () -{ -} diff --git a/src/ca/client/cacStateNotify.cpp b/src/ca/client/cacStateNotify.cpp deleted file mode 100644 index 08852489a..000000000 --- a/src/ca/client/cacStateNotify.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include "iocinf.h" - -#define epicsExportSharedSymbols -#include "cacIO.h" -#undef epicsExportSharedSymbols - -cacStateNotify::~cacStateNotify () -{ -} diff --git a/src/ca/client/cacWriteNotify.cpp b/src/ca/client/cacWriteNotify.cpp deleted file mode 100644 index 13d47cd45..000000000 --- a/src/ca/client/cacWriteNotify.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include "iocinf.h" - -#define epicsExportSharedSymbols -#include "cacIO.h" -#undef epicsExportSharedSymbols - -cacWriteNotify::~cacWriteNotify () -{ -} diff --git a/src/ca/client/cadef.h b/src/ca/client/cadef.h deleted file mode 100644 index e62dd7249..000000000 --- a/src/ca/client/cadef.h +++ /dev/null @@ -1,904 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - */ - -#ifndef INCLcadefh -#define INCLcadefh - -/* - * done in two ifdef steps so that we will remain compatible with - * traditional C - */ -#ifndef CA_DONT_INCLUDE_STDARGH -# include -#endif - -#ifdef epicsExportSharedSymbols -# define INCLcadefh_accessh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsThread.h" - -#ifdef INCLcadefh_accessh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - - -#include "caerr.h" -#include "db_access.h" -#include "caeventmask.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct oldChannelNotify *chid; -typedef chid chanId; /* for when the structures field name is "chid" */ -typedef long chtype; -typedef struct oldSubscription *evid; -typedef double ca_real; - -/* arguments passed to user connection handlers */ -struct connection_handler_args { - chanId chid; /* channel id */ - long op; /* one of CA_OP_CONN_UP or CA_OP_CONN_DOWN */ -}; - -typedef void caCh (struct connection_handler_args args); - -typedef struct ca_access_rights { - unsigned read_access:1; - unsigned write_access:1; -} caar; - -/* arguments passed to user access rights handlers */ -struct access_rights_handler_args { - chanId chid; /* channel id */ - caar ar; /* new access rights state */ -}; - -typedef void caArh (struct access_rights_handler_args args); - -/* The conversion routine to call for each type */ -#define VALID_TYPE(TYPE) (((unsigned short)TYPE)<=LAST_BUFFER_TYPE) - -/* - * Arguments passed to event handlers and get/put call back handlers. - * - * The status field below is the CA ECA_XXX status of the requested - * operation which is saved from when the operation was attempted in the - * server and copied back to the clients call back routine. - * If the status is not ECA_NORMAL then the dbr pointer will be NULL - * and the requested operation can not be assumed to be successful. - */ -typedef struct event_handler_args { - void *usr; /* user argument supplied with request */ - chanId chid; /* channel id */ - long type; /* the type of the item returned */ - long count; /* the element count of the item returned */ - const void *dbr; /* a pointer to the item returned */ - int status; /* ECA_XXX status of the requested op from the server */ -} evargs; -typedef void caEventCallBackFunc (struct event_handler_args); - -epicsShareFunc void epicsShareAPI ca_test_event -( - struct event_handler_args -); - -/* arguments passed to user exception handlers */ -struct exception_handler_args { - void *usr; /* user argument supplied when installed */ - chanId chid; /* channel id (may be nill) */ - long type; /* type requested */ - long count; /* count requested */ - void *addr; /* user's address to write results of CA_OP_GET */ - long stat; /* channel access ECA_XXXX status code */ - long op; /* CA_OP_GET, CA_OP_PUT, ..., CA_OP_OTHER */ - const char *ctx; /* a character string containing context info */ - const char *pFile; /* source file name (may be NULL) */ - unsigned lineNo; /* source file line number (may be zero) */ -}; - -typedef unsigned CA_SYNC_GID; - -/* - * External OP codes for CA operations - */ -#define CA_OP_GET 0 -#define CA_OP_PUT 1 -#define CA_OP_CREATE_CHANNEL 2 -#define CA_OP_ADD_EVENT 3 -#define CA_OP_CLEAR_EVENT 4 -#define CA_OP_OTHER 5 - -/* - * used with connection_handler_args - */ -#define CA_OP_CONN_UP 6 -#define CA_OP_CONN_DOWN 7 - -/* depricated */ -#define CA_OP_SEARCH 2 - -/* - * provides efficient test and display of channel access errors - */ -#define SEVCHK(CA_ERROR_CODE, MESSAGE_STRING) \ -{ \ - int ca_unique_status_name = (CA_ERROR_CODE); \ - if(!(ca_unique_status_name & CA_M_SUCCESS)) \ - ca_signal_with_file_and_lineno( \ - ca_unique_status_name, \ - (MESSAGE_STRING), \ - __FILE__, \ - __LINE__); \ -} - - -#define TYPENOTCONN (-1) /* the channel's native type when disconnected */ -epicsShareFunc short epicsShareAPI ca_field_type (chid chan); -epicsShareFunc unsigned long epicsShareAPI ca_element_count (chid chan); -epicsShareFunc const char * epicsShareAPI ca_name (chid chan); -epicsShareFunc void epicsShareAPI ca_set_puser (chid chan, void *puser); -epicsShareFunc void * epicsShareAPI ca_puser (chid chan); -epicsShareFunc unsigned epicsShareAPI ca_read_access (chid chan); -epicsShareFunc unsigned epicsShareAPI ca_write_access (chid chan); - -/* - * cs_ - `channel state' - * - * cs_never_conn valid chid, IOC not found - * cs_prev_conn valid chid, IOC was found, but unavailable - * cs_conn valid chid, IOC was found, still available - * cs_closed channel deleted by user - */ -enum channel_state {cs_never_conn, cs_prev_conn, cs_conn, cs_closed}; -epicsShareFunc enum channel_state epicsShareAPI ca_state (chid chan); - -/************************************************************************/ -/* Perform Library Initialization */ -/* */ -/* Must be called once before calling any of the other routines */ -/************************************************************************/ -epicsShareFunc int epicsShareAPI ca_task_initialize (void); -enum ca_preemptive_callback_select -{ ca_disable_preemptive_callback, ca_enable_preemptive_callback }; -epicsShareFunc int epicsShareAPI - ca_context_create (enum ca_preemptive_callback_select select); -epicsShareFunc void epicsShareAPI ca_detach_context (); - -/************************************************************************/ -/* Remove CA facility from your task */ -/* */ -/* Normally called automatically at task exit */ -/************************************************************************/ -epicsShareFunc int epicsShareAPI ca_task_exit (void); -epicsShareFunc void epicsShareAPI ca_context_destroy (void); - -typedef unsigned capri; -#define CA_PRIORITY_MAX 99 -#define CA_PRIORITY_MIN 0 -#define CA_PRIORITY_DEFAULT CA_PRIORITY_MIN - -#define CA_PRIORITY_DB_LINKS 80 -#define CA_PRIORITY_ARCHIVE 20 -#define CA_PRIORITY_OPI 0 - -/* - * ca_create_channel () - * - * pChanName R channel name string - * pConnStateCallback R address of connection state change - * callback function - * pUserPrivate R placed in the channel's user private field - * o can be fetched later by ca_puser(CHID) - * o passed as void * arg to *pConnectCallback above - * priority R priority level in the server 0 - 100 - * pChanID RW channel id written here - */ -epicsShareFunc int epicsShareAPI ca_create_channel -( - const char *pChanName, - caCh *pConnStateCallback, - void *pUserPrivate, - capri priority, - chid *pChanID -); - -/* - * ca_change_connection_event() - * - * chan R channel identifier - * pfunc R address of connection call-back function - */ -epicsShareFunc int epicsShareAPI ca_change_connection_event -( - chid chan, - caCh * pfunc -); - -/* - * ca_replace_access_rights_event () - * - * chan R channel identifier - * pfunc R address of access rights call-back function - */ -epicsShareFunc int epicsShareAPI ca_replace_access_rights_event ( - chid chan, - caArh *pfunc -); - -/* - * ca_add_exception_event () - * - * replace the default exception handler - * - * pfunc R address of exception call-back function - * pArg R copy of this pointer passed to exception - * call-back function - */ -typedef void caExceptionHandler (struct exception_handler_args); -epicsShareFunc int epicsShareAPI ca_add_exception_event -( - caExceptionHandler *pfunc, - void *pArg -); - -/* - * ca_clear_channel() - * - deallocate resources reserved for a channel - * - * chanId R channel ID - */ -epicsShareFunc int epicsShareAPI ca_clear_channel -( - chid chanId -); - -/************************************************************************/ -/* Write a value to a channel */ -/************************************************************************/ -/* - * ca_bput() - * - * WARNING: this copies the new value from a string (dbr_string_t) - * (and not as an integer) - * - * chan R channel identifier - * pValue R new channel value string copied from this location - */ -#define ca_bput(chan, pValue) \ -ca_array_put(DBR_STRING, 1u, chan, (const dbr_string_t *) (pValue)) - -/* - * ca_rput() - * - * WARNING: this copies the new value from a dbr_float_t - * - * chan R channel identifier - * pValue R new channel value copied from this location - */ -#define ca_rput(chan,pValue) \ -ca_array_put(DBR_FLOAT, 1u, chan, (const dbr_float_t *) pValue) - -/* - * ca_put() - * - * type R data type from db_access.h - * chan R channel identifier - * pValue R new channel value copied from this location - */ -#define ca_put(type, chan, pValue) ca_array_put (type, 1u, chan, pValue) - -/* - * ca_array_put() - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue R new channel value copied from this location - */ -epicsShareFunc int epicsShareAPI ca_array_put -( - chtype type, - unsigned long count, - chid chanId, - const void * pValue -); - -/* - * ca_array_put_callback() - * - * This routine functions identically to the original ca put request - * with the addition of a callback to the user supplied function - * after recod processing completes in the IOC. The arguments - * to the user supplied callback function are declared in - * the structure event_handler_args and include the pointer - * sized user argument supplied when ca_array_put_callback() is called. - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue R new channel value copied from this location - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -epicsShareFunc int epicsShareAPI ca_array_put_callback -( - chtype type, - unsigned long count, - chid chanId, - const void * pValue, - caEventCallBackFunc * pFunc, - void * pArg -); - -#define ca_put_callback(type, chan, pValue, pFunc, pArg) \ - ca_array_put_callback(type, 1u, chan, pValue, pFunc, pArg) - -/************************************************************************/ -/* Read a value from a channel */ -/************************************************************************/ - -/* - * ca_bget() - * - * WARNING: this copies the new value into a string (dbr_string_t) - * (and not into an integer) - * - * chan R channel identifier - * pValue W channel value copied to this location - */ -#define ca_bget(chan, pValue) \ -ca_array_get(DBR_STRING, 1u, chan, (dbr_string_t *)(pValue)) - -/* - * ca_rget() - * - * WARNING: this copies the new value into a 32 bit float (dbr_float_t) - * - * chan R channel identifier - * pValue W channel value copied to this location - */ -#define ca_rget(chan, pValue) \ -ca_array_get(DBR_FLOAT, 1u, chan, (dbr_float_t *)(pValue)) - -/* - * ca_rget() - * - * type R data type from db_access.h - * chan R channel identifier - * pValue W channel value copied to this location - */ -#define ca_get(type, chan, pValue) ca_array_get(type, 1u, chan, pValue) - -/* - * ca_array_get() - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue W channel value copied to this location - */ -epicsShareFunc int epicsShareAPI ca_array_get -( - chtype type, - unsigned long count, - chid chanId, - void * pValue -); - -/************************************************************************/ -/* Read a value from a channel and run a callback when the value */ -/* returns */ -/* */ -/* */ -/************************************************************************/ -/* - * ca_bget_callback() - * - * WARNING: this returns the new value as a string (dbr_string_t) - * (and not as an integer) - * - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -#define ca_bget_callback(chan, pFunc, pArg)\ -ca_array_get_callback (DBR_STRING, 1u, chan, pFunc, pArg) - -/* - * ca_rget_callback() - * - * WARNING: this returns the new value as a float (dbr_float_t) - * - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -#define ca_rget_callback(chan, pFunc, pArg)\ -ca_array_get_callback (DBR_FLOAT, 1u, chan, pFunc, pArg) - -/* - * ca_get_callback() - * - * type R data type from db_access.h - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -#define ca_get_callback(type, chan, pFunc, pArg)\ -ca_array_get_callback (type, 1u, chan, pFunc, pArg) - -/* - * ca_array_get_callback() - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - */ -epicsShareFunc int epicsShareAPI ca_array_get_callback -( - chtype type, - unsigned long count, - chid chanId, - caEventCallBackFunc * pFunc, - void * pArg -); - -/************************************************************************/ -/* Specify a function to be executed whenever significant changes */ -/* occur to a channel. */ -/* NOTES: */ -/* 1) Evid may be omited by passing a NULL pointer */ -/* */ -/* 2) An array count of zero specifies the native db count */ -/* */ -/************************************************************************/ - -/* - * ca_create_subscription () - * - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * mask R event mask - one of {DBE_VALUE, DBE_ALARM, DBE_LOG} - * pFunc R pointer to call-back function - * pArg R copy of this pointer passed to pFunc - * pEventID W event id written at specified address - */ -epicsShareFunc int epicsShareAPI ca_create_subscription -( - chtype type, - unsigned long count, - chid chanId, - long mask, - caEventCallBackFunc * pFunc, - void * pArg, - evid * pEventID -); - -/************************************************************************/ -/* Remove a function from a list of those specified to run */ -/* whenever significant changes occur to a channel */ -/* */ -/************************************************************************/ -/* - * ca_clear_subscription() - * - * eventID R event id - */ -epicsShareFunc int epicsShareAPI ca_clear_subscription -( - evid eventID -); - -epicsShareFunc chid epicsShareAPI ca_evid_to_chid ( evid id ); - - -/************************************************************************/ -/* */ -/* Requested data is not necessarily stable prior to */ -/* return from called subroutine. Call ca_pend_io() */ -/* to guarantee that requested data is stable. Call the routine */ -/* ca_flush_io() to force all outstanding requests to be */ -/* sent out over the network. Significant increases in */ -/* performance have been measured when batching several remote */ -/* requests together into one message. Additional */ -/* improvements can be obtained by performing local processing */ -/* in parallel with outstanding remote processing. */ -/* */ -/* FLOW OF TYPICAL APPLICATION */ -/* */ -/* search() ! Obtain Channel ids */ -/* . ! " */ -/* . ! " */ -/* pend_io ! wait for channels to connect */ -/* */ -/* get() ! several requests for remote info */ -/* get() ! " */ -/* add_event() ! " */ -/* get() ! " */ -/* . */ -/* . */ -/* . */ -/* flush_io() ! send get requests */ -/* ! optional parallel processing */ -/* . ! " */ -/* . ! " */ -/* pend_io() ! wait for replies from get requests */ -/* . ! access to requested data */ -/* . ! " */ -/* pend_event() ! wait for requested events */ -/* */ -/************************************************************************/ - -/************************************************************************/ -/* These routines wait for channel subscription events and call the */ -/* functions specified with add_event when events occur. If the */ -/* timeout is specified as 0 an infinite timeout is assumed. */ -/* ca_flush_io() is called by this routine. If ca_pend_io () */ -/* is called when no IO is outstanding then it will return immediately */ -/* without processing. */ -/************************************************************************/ - -/* - * ca_pend_event() - * - * timeOut R wait for this delay in seconds - */ -epicsShareFunc int epicsShareAPI ca_pend_event (ca_real timeOut); -#define ca_poll() ca_pend_event(1e-12) - -/* - * ca_pend_io() - * - * timeOut R wait for this delay in seconds but return early - * if all get requests (or search requests with null - * connection handler pointer have completed) - */ -epicsShareFunc int epicsShareAPI ca_pend_io (ca_real timeOut); - -/* calls ca_pend_io() if early is true otherwise ca_pend_event() is called */ -epicsShareFunc int epicsShareAPI ca_pend (ca_real timeout, int early); - -/* - * ca_test_io() - * - * returns TRUE when get requests (or search requests with null - * connection handler pointer) are outstanding - */ -epicsShareFunc int epicsShareAPI ca_test_io (void); - -/************************************************************************/ -/* Send out all outstanding messages in the send queue */ -/************************************************************************/ -/* - * ca_flush_io() - */ -epicsShareFunc int epicsShareAPI ca_flush_io (void); - - -/* - * ca_signal() - * - * errorCode R status returned from channel access function - * pCtxStr R context string included with error print out - */ -epicsShareFunc void epicsShareAPI ca_signal -( - long errorCode, - const char *pCtxStr -); - -/* - * ca_signal_with_file_and_lineno() - * errorCode R status returned from channel access function - * pCtxStr R context string included with error print out - * pFileStr R file name string included with error print out - * lineNo R line number included with error print out - * - */ -epicsShareFunc void epicsShareAPI ca_signal_with_file_and_lineno -( - long errorCode, - const char *pCtxStr, - const char *pFileStr, - int lineNo -); - -/* - * ca_signal_formated() - * errorCode R status returned from channel access function - * pFileStr R file name string included with error print out - * lineNo R line number included with error print out - * pFormat R printf dtyle format string (and optional arguments) - * - */ -epicsShareFunc void epicsShareAPI ca_signal_formated (long ca_status, const char *pfilenm, - int lineno, const char *pFormat, ...); - -/* - * ca_host_name_function() - * - * channel R channel identifier - * - * !!!! this function is _not_ thread safe !!!! - */ -epicsShareFunc const char * epicsShareAPI ca_host_name (chid channel); -/* thread safe version */ -epicsShareFunc unsigned epicsShareAPI ca_get_host_name ( chid pChan, - char *pBuf, unsigned bufLength ); - -/* - * CA_ADD_FD_REGISTRATION - * - * call their function with their argument whenever - * a new fd is added or removed - * (for use with a manager of the select system call under UNIX) - * - * if (opened) then fd was created - * if (!opened) then fd was deleted - * - */ -typedef void CAFDHANDLER (void *parg, int fd, int opened); - -/* - * ca_add_fd_registration() - * - * pHandler R pointer to function which is to be called - * when an fd is created or deleted - * pArg R argument passed to above function - */ -epicsShareFunc int epicsShareAPI ca_add_fd_registration -( - CAFDHANDLER *pHandler, - void *pArg -); - - -/* - * CA synch groups - * - * This facility will allow the programmer to create - * any number of synchronization groups. The programmer might then - * interleave IO requests within any of the groups. Once The - * IO operations are initiated then the programmer is free to - * block for IO completion within any one of the groups as needed. - */ - -/* - * ca_sg_create() - * - * create a sync group - * - * pgid W pointer to sync group id that will be written - */ -epicsShareFunc int epicsShareAPI ca_sg_create (CA_SYNC_GID * pgid); - -/* - * ca_sg_delete() - * - * delete a sync group - * - * gid R sync group id - */ -epicsShareFunc int epicsShareAPI ca_sg_delete (const CA_SYNC_GID gid); - -/* - * ca_sg_block() - * - * block for IO performed within a sync group to complete - * - * gid R sync group id - * timeout R wait for this duration prior to timing out - * and returning ECA_TIMEOUT - */ -epicsShareFunc int epicsShareAPI ca_sg_block (const CA_SYNC_GID gid, ca_real timeout); - -/* - * ca_sg_test() - * - * test for sync group IO operations in progress - * - * gid R sync group id - * - * returns one of ECA_BADSYNCGRP, ECA_IOINPROGRESS, ECA_IODONE - */ -epicsShareFunc int epicsShareAPI ca_sg_test (const CA_SYNC_GID gid); - -/* - * ca_sg_reset - * - * gid R sync group id - */ -epicsShareFunc int epicsShareAPI ca_sg_reset(const CA_SYNC_GID gid); - -/* - * ca_sg_array_get() - * - * initiate a get within a sync group - * (essentially a ca_array_get() with a sync group specified) - * - * gid R sync group id - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue W channel value copied to this location - */ -epicsShareFunc int epicsShareAPI ca_sg_array_get -( - const CA_SYNC_GID gid, - chtype type, - unsigned long count, - chid chan, - void *pValue -); - -#define ca_sg_get(gid, type, chan, pValue) \ -ca_sg_array_get (gid, type, 1u, chan, pValue) - -/* - * ca_sg_array_put() - * - * initiate a put within a sync group - * (essentially a ca_array_put() with a sync group specified) - * - * gid R sync group id - * type R data type from db_access.h - * count R array element count - * chan R channel identifier - * pValue R new channel value copied from this location - */ -epicsShareFunc int epicsShareAPI ca_sg_array_put -( - const CA_SYNC_GID gid, - chtype type, - unsigned long count, - chid chan, - const void *pValue -); - -#define ca_sg_put(gid, type, chan, pValue) \ -ca_sg_array_put (gid, type, 1u, chan, pValue) - -/* - * ca_sg_stat() - * - * print status of a sync group - * - * gid R sync group id - */ -epicsShareFunc int epicsShareAPI ca_sg_stat (CA_SYNC_GID gid); - -epicsShareFunc void epicsShareAPI ca_dump_dbr (chtype type, unsigned count, const void * pbuffer); - - -/* - * ca_v42_ok() - * - * Put call back is available if the CA server is on version is 4.2 - * or higher. - * - * chan R channel identifier - * - * (returns true or false) - */ -epicsShareFunc int epicsShareAPI ca_v42_ok (chid chan); - -/* - * ca_version() - * - * returns the CA version string - */ -epicsShareFunc const char * epicsShareAPI ca_version (void); - -/* - * ca_replace_printf_handler () - * - * for apps that want to change where ca formatted - * text output goes - * - * use two ifdef's for trad C compatibility - * - * ca_printf_func R pointer to new function called when - * CA prints an error message - */ -#ifndef CA_DONT_INCLUDE_STDARGH -typedef int caPrintfFunc (const char *pformat, va_list args); -epicsShareFunc int epicsShareAPI ca_replace_printf_handler ( - caPrintfFunc *ca_printf_func -); -#endif /*CA_DONT_INCLUDE_STDARGH*/ - -/* - * (for testing purposes only) - */ -epicsShareFunc unsigned epicsShareAPI ca_get_ioc_connection_count (void); -epicsShareFunc int epicsShareAPI ca_preemtive_callback_is_enabled (void); -epicsShareFunc void epicsShareAPI ca_self_test (void); -epicsShareFunc unsigned epicsShareAPI ca_beacon_anomaly_count (void); -epicsShareFunc unsigned epicsShareAPI ca_search_attempts (chid chan); -epicsShareFunc double epicsShareAPI ca_beacon_period (chid chan); -epicsShareFunc double epicsShareAPI ca_receive_watchdog_delay (chid chan); - -/* - * used when an auxillary thread needs to join a CA client context started - * by another thread - */ -epicsShareFunc struct ca_client_context * epicsShareAPI ca_current_context (); -epicsShareFunc int epicsShareAPI ca_attach_context ( struct ca_client_context * context ); - - -epicsShareFunc int epicsShareAPI ca_client_status ( unsigned level ); -epicsShareFunc int epicsShareAPI ca_context_status ( struct ca_client_context *, unsigned level ); - -/* - * deprecated - */ -#define ca_build_channel(NAME,XXXXX,CHIDPTR,YYYYY)\ -ca_build_and_connect(NAME, XXXXX, 1, CHIDPTR, YYYYY, 0, 0) -#define ca_array_build(NAME,XXXXX, ZZZZZZ, CHIDPTR,YYYYY)\ -ca_build_and_connect(NAME, XXXXX, ZZZZZZ, CHIDPTR, YYYYY, 0, 0) -epicsShareFunc int epicsShareAPI ca_build_and_connect - ( const char *pChanName, chtype, unsigned long, - chid * pChanID, void *, caCh * pFunc, void * pArg ); -#define ca_search(pChanName, pChanID)\ -ca_search_and_connect (pChanName, pChanID, 0, 0) -epicsShareFunc int epicsShareAPI ca_search_and_connect - ( const char * pChanName, chid * pChanID, - caCh *pFunc, void * pArg ); -epicsShareFunc int epicsShareAPI ca_channel_status (epicsThreadId tid); -epicsShareFunc int epicsShareAPI ca_clear_event ( evid eventID ); -#define ca_add_event(type,chan,pFunc,pArg,pEventID)\ -ca_add_array_event(type,1u,chan,pFunc,pArg,0.0,0.0,0.0,pEventID) -#define ca_add_delta_event(TYPE,CHID,ENTRY,ARG,DELTA,EVID)\ - ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,DELTA,DELTA,0.0,EVID) -#define ca_add_general_event(TYPE,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ -ca_add_array_event(TYPE,1,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID) -#define ca_add_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID)\ -ca_add_masked_array_event(TYPE,COUNT,CHID,ENTRY,ARG,P_DELTA,N_DELTA,TO,EVID, DBE_VALUE | DBE_ALARM) -epicsShareFunc int epicsShareAPI ca_add_masked_array_event - ( chtype type, unsigned long count, chid chanId, caEventCallBackFunc * pFunc, - void * pArg, ca_real p_delta, ca_real n_delta, ca_real timeout, - evid * pEventID, long mask ); - -/* - * defunct - */ -epicsShareFunc int epicsShareAPI ca_modify_user_name ( const char *pUserName ); -epicsShareFunc int epicsShareAPI ca_modify_host_name ( const char *pHostName ); - -#ifdef __cplusplus -} -#endif - -/* - * no additions below this endif - */ -#endif /* ifndef INCLcadefh */ - diff --git a/src/ca/client/caerr.h b/src/ca/client/caerr.h deleted file mode 100644 index 53930962d..000000000 --- a/src/ca/client/caerr.h +++ /dev/null @@ -1,160 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeffrey O. Hill - * - */ - - -#ifndef INCLcaerrh -#define INCLcaerrh - -#ifdef epicsExportSharedSymbols -# define INCLcaerrh_accessh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -# include "epicsTypes.h" - -#ifdef INCLcaerrh_accessh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -/* CA Status Code Definitions */ - -#define CA_K_INFO 3 /* successful */ -#define CA_K_ERROR 2 /* failed- continue */ -#define CA_K_SUCCESS 1 /* successful */ -#define CA_K_WARNING 0 /* unsuccessful */ -#define CA_K_SEVERE 4 /* failed- quit */ -#define CA_K_FATAL CA_K_ERROR | CA_K_SEVERE - -#define CA_M_MSG_NO 0x0000FFF8 -#define CA_M_SEVERITY 0x00000007 -#define CA_M_LEVEL 0x00000003 -#define CA_M_SUCCESS 0x00000001 -#define CA_M_ERROR 0x00000002 -#define CA_M_SEVERE 0x00000004 - -#define CA_S_MSG_NO 0x0D -#define CA_S_SEVERITY 0x03 - -#define CA_V_MSG_NO 0x03 -#define CA_V_SEVERITY 0x00 -#define CA_V_SUCCESS 0x00 - -/* Define MACROS to extract/insert individual fields from a status value */ - -#define CA_EXTRACT_MSG_NO(code)\ -( ( (code) & CA_M_MSG_NO ) >> CA_V_MSG_NO ) -#define CA_EXTRACT_SEVERITY(code)\ -( ( (code) & CA_M_SEVERITY ) >> CA_V_SEVERITY ) -#define CA_EXTRACT_SUCCESS(code)\ -( ( (code) & CA_M_SUCCESS ) >> CA_V_SUCCESS ) - -#define CA_INSERT_MSG_NO(code)\ -( ((code)<< CA_V_MSG_NO) & CA_M_MSG_NO ) -#define CA_INSERT_SEVERITY(code)\ -( ((code)<< CA_V_SEVERITY)& CA_M_SEVERITY ) -#define CA_INSERT_SUCCESS(code)\ -( ((code)<< CA_V_SUCCESS) & CA_M_SUCCESS ) - -#define DEFMSG(SEVERITY,NUMBER)\ -(CA_INSERT_MSG_NO(NUMBER) | CA_INSERT_SEVERITY(SEVERITY)) - -/* - * In the lines below "defunct" indicates that current release - * servers and client library will not return this error code, but - * servers on earlier releases that communicate with current clients - * might still generate exceptions with these error constants - */ -#define ECA_NORMAL DEFMSG(CA_K_SUCCESS, 0) /* success */ -#define ECA_MAXIOC DEFMSG(CA_K_ERROR, 1) /* defunct */ -#define ECA_UKNHOST DEFMSG(CA_K_ERROR, 2) /* defunct */ -#define ECA_UKNSERV DEFMSG(CA_K_ERROR, 3) /* defunct */ -#define ECA_SOCK DEFMSG(CA_K_ERROR, 4) /* defunct */ -#define ECA_CONN DEFMSG(CA_K_WARNING, 5) /* defunct */ -#define ECA_ALLOCMEM DEFMSG(CA_K_WARNING, 6) -#define ECA_UKNCHAN DEFMSG(CA_K_WARNING, 7) /* defunct */ -#define ECA_UKNFIELD DEFMSG(CA_K_WARNING, 8) /* defunct */ -#define ECA_TOLARGE DEFMSG(CA_K_WARNING, 9) -#define ECA_TIMEOUT DEFMSG(CA_K_WARNING, 10) -#define ECA_NOSUPPORT DEFMSG(CA_K_WARNING, 11) /* defunct */ -#define ECA_STRTOBIG DEFMSG(CA_K_WARNING, 12) /* defunct */ -#define ECA_DISCONNCHID DEFMSG(CA_K_ERROR, 13) /* defunct */ -#define ECA_BADTYPE DEFMSG(CA_K_ERROR, 14) -#define ECA_CHIDNOTFND DEFMSG(CA_K_INFO, 15) /* defunct */ -#define ECA_CHIDRETRY DEFMSG(CA_K_INFO, 16) /* defunct */ -#define ECA_INTERNAL DEFMSG(CA_K_FATAL, 17) -#define ECA_DBLCLFAIL DEFMSG(CA_K_WARNING, 18) /* defunct */ -#define ECA_GETFAIL DEFMSG(CA_K_WARNING, 19) -#define ECA_PUTFAIL DEFMSG(CA_K_WARNING, 20) -#define ECA_ADDFAIL DEFMSG(CA_K_WARNING, 21) /* defunct */ -#define ECA_BADCOUNT DEFMSG(CA_K_WARNING, 22) -#define ECA_BADSTR DEFMSG(CA_K_ERROR, 23) -#define ECA_DISCONN DEFMSG(CA_K_WARNING, 24) -#define ECA_DBLCHNL DEFMSG(CA_K_WARNING, 25) -#define ECA_EVDISALLOW DEFMSG(CA_K_ERROR, 26) -#define ECA_BUILDGET DEFMSG(CA_K_WARNING, 27) /* defunct */ -#define ECA_NEEDSFP DEFMSG(CA_K_WARNING, 28) /* defunct */ -#define ECA_OVEVFAIL DEFMSG(CA_K_WARNING, 29) /* defunct */ -#define ECA_BADMONID DEFMSG(CA_K_ERROR, 30) -#define ECA_NEWADDR DEFMSG(CA_K_WARNING, 31) /* defunct */ -#define ECA_NEWCONN DEFMSG(CA_K_INFO, 32) /* defunct */ -#define ECA_NOCACTX DEFMSG(CA_K_WARNING, 33) /* defunct */ -#define ECA_DEFUNCT DEFMSG(CA_K_FATAL, 34) /* defunct */ -#define ECA_EMPTYSTR DEFMSG(CA_K_WARNING, 35) /* defunct */ -#define ECA_NOREPEATER DEFMSG(CA_K_WARNING, 36) /* defunct */ -#define ECA_NOCHANMSG DEFMSG(CA_K_WARNING, 37) /* defunct */ -#define ECA_DLCKREST DEFMSG(CA_K_WARNING, 38) /* defunct */ -#define ECA_SERVBEHIND DEFMSG(CA_K_WARNING, 39) /* defunct */ -#define ECA_NOCAST DEFMSG(CA_K_WARNING, 40) /* defunct */ -#define ECA_BADMASK DEFMSG(CA_K_ERROR, 41) -#define ECA_IODONE DEFMSG(CA_K_INFO, 42) -#define ECA_IOINPROGRESS DEFMSG(CA_K_INFO, 43) -#define ECA_BADSYNCGRP DEFMSG(CA_K_ERROR, 44) -#define ECA_PUTCBINPROG DEFMSG(CA_K_ERROR, 45) -#define ECA_NORDACCESS DEFMSG(CA_K_WARNING, 46) -#define ECA_NOWTACCESS DEFMSG(CA_K_WARNING, 47) -#define ECA_ANACHRONISM DEFMSG(CA_K_ERROR, 48) -#define ECA_NOSEARCHADDR DEFMSG(CA_K_WARNING, 49) -#define ECA_NOCONVERT DEFMSG(CA_K_WARNING, 50) -#define ECA_BADCHID DEFMSG(CA_K_ERROR, 51) -#define ECA_BADFUNCPTR DEFMSG(CA_K_ERROR, 52) -#define ECA_ISATTACHED DEFMSG(CA_K_WARNING, 53) -#define ECA_UNAVAILINSERV DEFMSG(CA_K_WARNING, 54) -#define ECA_CHANDESTROY DEFMSG(CA_K_WARNING, 55) -#define ECA_BADPRIORITY DEFMSG(CA_K_ERROR, 56) -#define ECA_NOTTHREADED DEFMSG(CA_K_ERROR, 57) -#define ECA_16KARRAYCLIENT DEFMSG(CA_K_WARNING, 58) -#define ECA_CONNSEQTMO DEFMSG(CA_K_WARNING, 59) -#define ECA_UNRESPTMO DEFMSG(CA_K_WARNING, 60) - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc const char * epicsShareAPI ca_message(long ca_status); - -epicsShareExtern const char * ca_message_text []; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/ca/client/caeventmask.h b/src/ca/client/caeventmask.h deleted file mode 100644 index 5f0914509..000000000 --- a/src/ca/client/caeventmask.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INCLcaeventmaskh -#define INCLcaeventmaskh - -/* - event selections - (If any more than 8 of these are needed then update the - select field in the event_block struct in db_event.c from - unsigned char to unsigned short) - - - DBE_VALUE - Trigger an event when a significant change in the channel's value - occurs. Relies on the monitor deadband field under DCT. - - DBE_ARCHIVE (DBE_LOG) - Trigger an event when an archive significant change in the channel's - value occurs. Relies on the archiver monitor deadband field under DCT. - - DBE_ALARM - Trigger an event when the alarm state changes - - DBE_PROPERTY - Trigger an event when a property change (control limit, graphical - limit, status string, enum string ...) occurs. - -*/ - -#define DBE_VALUE (1<<0) -#define DBE_ARCHIVE (1<<1) -#define DBE_LOG DBE_ARCHIVE -#define DBE_ALARM (1<<2) -#define DBE_PROPERTY (1<<3) - -#endif diff --git a/src/ca/client/casw.cpp b/src/ca/client/casw.cpp deleted file mode 100644 index f69632c13..000000000 --- a/src/ca/client/casw.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "envDefs.h" -#include "errlog.h" -#include "osiWireFormat.h" - -#include "bhe.h" -#include "udpiiu.h" -#include "inetAddrID.h" - -// using a wrapper class around the free list avoids -// Tornado 2.0.1 GNU compiler bugs -class bheFreeStoreMgr : public bheMemoryManager { -public: - bheFreeStoreMgr () {} - void * allocate ( size_t ); - void release ( void * ); -private: - tsFreeList < class bhe, 0x100 > freeList; - bheFreeStoreMgr ( const bheFreeStoreMgr & ); - bheFreeStoreMgr & operator = ( const bheFreeStoreMgr & ); -}; - -void * bheFreeStoreMgr::allocate ( size_t size ) -{ - return freeList.allocate ( size ); -} - -void bheFreeStoreMgr::release ( void * pCadaver ) -{ - freeList.release ( pCadaver ); -} - -int main ( int argc, char ** argv ) -{ - epicsMutex mutex; - epicsGuard < epicsMutex > guard ( mutex ); - bheFreeStoreMgr bheFreeList; - epicsTime programBeginTime = epicsTime::getCurrent (); - bool validCommandLine = false; - unsigned interest = 0u; - SOCKET sock; - osiSockAddr addr; - osiSocklen_t addrSize; - char buf [0x4000]; - const char *pCurBuf; - const caHdr *pCurMsg; - ca_uint16_t serverPort; - ca_uint16_t repeaterPort; - int status; - - if ( argc == 1 ) { - validCommandLine = true; - } - else if ( argc == 2 ) { - status = sscanf ( argv[1], " -i%u ", & interest ); - if ( status == 1 ) { - validCommandLine = true; - } - } - else if ( argc == 3 ) { - if ( strcmp ( argv[1], "-i" ) == 0 ) { - status = sscanf ( argv[2], " %u ", & interest ); - if ( status == 1 ) { - validCommandLine = true; - } - } - } - - if ( ! validCommandLine ) { - printf ( "usage: casw <-i interestLevel>\n" ); - return 0; - } - - serverPort = - envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT, - static_cast (CA_SERVER_PORT) ); - - repeaterPort = - envGetInetPortConfigParam ( &EPICS_CA_REPEATER_PORT, - static_cast (CA_REPEATER_PORT) ); - - caStartRepeaterIfNotInstalled ( repeaterPort ); - - sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); - if ( sock == INVALID_SOCKET ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("casw: unable to create datagram socket because = \"%s\"\n", - sockErrBuf ); - return -1; - } - - memset ( (char *) &addr, 0 , sizeof (addr) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); - addr.ia.sin_port = htons ( 0 ); // any port - status = bind ( sock, &addr.sa, sizeof (addr) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy ( sock ); - errlogPrintf ( "casw: unable to bind to an unconstrained address because = \"%s\"\n", - sockErrBuf ); - return -1; - } - - osiSockIoctl_t yes = true; - status = socket_ioctl ( sock, FIONBIO, &yes ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy ( sock ); - errlogPrintf ( "casw: unable to set socket to nonblocking state because \"%s\"\n", - sockErrBuf ); - return -1; - } - - unsigned attemptNumber = 0u; - while ( true ) { - caRepeaterRegistrationMessage ( sock, repeaterPort, attemptNumber ); - epicsThreadSleep ( 0.1 ); - addrSize = ( osiSocklen_t ) sizeof ( addr ); - status = recvfrom ( sock, buf, sizeof ( buf ), 0, - &addr.sa, &addrSize ); - if ( status >= static_cast ( sizeof ( *pCurMsg ) ) ) { - pCurMsg = reinterpret_cast < caHdr * > ( buf ); - epicsUInt16 cmmd = AlignedWireRef < const epicsUInt16 > ( pCurMsg->m_cmmd ); - if ( cmmd == REPEATER_CONFIRM ) { - break; - } - } - - attemptNumber++; - if ( attemptNumber > 100 ) { - epicsSocketDestroy ( sock ); - errlogPrintf ( "casw: unable to register with the CA repeater\n" ); - return -1; - } - } - - osiSockIoctl_t no = false; - status = socket_ioctl ( sock, FIONBIO, &no ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy ( sock ); - errlogPrintf ( "casw: unable to set socket to blocking state because \"%s\"\n", - sockErrBuf ); - return -1; - } - - resTable < bhe, inetAddrID > beaconTable; - while ( true ) { - - addrSize = ( osiSocklen_t ) sizeof ( addr ); - status = recvfrom ( sock, buf, sizeof ( buf ), 0, - &addr.sa, &addrSize ); - if ( status <= 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy ( sock ); - errlogPrintf ("casw: error from recv was = \"%s\"\n", - sockErrBuf ); - return -1; - } - - if ( addr.sa.sa_family != AF_INET ) { - continue; - } - - unsigned byteCount = static_cast ( status ); - pCurMsg = reinterpret_cast < const caHdr * > ( ( pCurBuf = buf ) ); - while ( byteCount ) { - AlignedWireRef < const epicsUInt16 > pstSize ( pCurMsg->m_postsize ); - size_t msgSize = pstSize + sizeof ( *pCurMsg ) ; - if ( msgSize > byteCount ) { - errlogPrintf ( "CASW: udp input protocol violation\n" ); - break; - } - - epicsUInt16 cmmd = AlignedWireRef < const epicsUInt16 > ( pCurMsg->m_cmmd ); - if ( cmmd == CA_PROTO_RSRV_IS_UP ) { - bool anomaly = false; - epicsTime previousTime; - struct sockaddr_in ina; - - /* - * this allows a fan-out server to potentially - * insert the true address of the CA server - * - * old servers: - * 1) set this field to one of the ip addresses of the host _or_ - * 2) set this field to INADDR_ANY - * new servers: - * always set this field to INADDR_ANY - * - * clients always assume that if this - * field is set to something that isnt INADDR_ANY - * then it is the overriding IP address of the server. - */ - ina.sin_family = AF_INET; - ina.sin_addr.s_addr = pCurMsg->m_available; - - if ( pCurMsg->m_count != 0 ) { - ina.sin_port = pCurMsg->m_count; - } - else { - /* - * old servers dont supply this and the - * default port must be assumed - */ - ina.sin_port = htons ( serverPort ); - } - - ca_uint32_t beaconNumber = ntohl ( pCurMsg->m_cid ); - unsigned protocolRevision = ntohs ( pCurMsg->m_dataType ); - - epicsTime currentTime = epicsTime::getCurrent(); - - /* - * look for it in the hash table - */ - bhe *pBHE = beaconTable.lookup ( ina ); - if ( pBHE ) { - previousTime = pBHE->updateTime ( guard ); - anomaly = pBHE->updatePeriod ( - guard, programBeginTime, - currentTime, beaconNumber, protocolRevision ); - } - else { - /* - * This is the first beacon seen from this server. - * Wait until 2nd beacon is seen before deciding - * if it is a new server (or just the first - * time that we have seen a server's beacon - * shortly after the program started up) - */ - pBHE = new ( bheFreeList ) - bhe ( mutex, currentTime, beaconNumber, ina ); - if ( pBHE ) { - if ( beaconTable.add ( *pBHE ) < 0 ) { - pBHE->~bhe (); - bheFreeList.release ( pBHE ); - } - } - } - if ( anomaly || interest > 1 ) { - char date[64]; - currentTime.strftime ( date, sizeof ( date ), - "%Y-%m-%d %H:%M:%S.%09f"); - char host[64]; - ipAddrToA ( &ina, host, sizeof ( host ) ); - const char * pPrefix = ""; - if ( interest > 1 ) { - if ( anomaly ) { - pPrefix = "* "; - } - else { - pPrefix = " "; - } - } - printf ( "%s%-40s %s\n", - pPrefix, host, date ); - if ( anomaly && interest > 0 ) { - printf ( "\testimate=%f current=%f\n", - pBHE->period ( guard ), - currentTime - previousTime ); - } - fflush(stdout); - } - } - pCurBuf += msgSize; - pCurMsg = reinterpret_cast < const caHdr * > ( pCurBuf ); - byteCount -= msgSize; - } - } -} diff --git a/src/ca/client/catime.c b/src/ca/client/catime.c deleted file mode 100644 index cccd940bc..000000000 --- a/src/ca/client/catime.c +++ /dev/null @@ -1,685 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * CA performance test - * - * History - * joh 09-12-89 Initial release - * joh 12-20-94 portability - * - * - */ - -#include -#include -#include -#include -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "epicsAssert.h" -#include "epicsTime.h" -#include "cadef.h" -#include "caProto.h" - -#include "caDiagnostics.h" - -#ifndef NULL -#define NULL 0 -#endif - -#define WAIT_FOR_ACK - -typedef struct testItem { - chid chix; - char name[128]; - int type; - int count; - void * pValue; -} ti; - -typedef void tf ( ti *pItems, unsigned iterations, unsigned *pInlineIter ); - -/* - * test_pend() - */ -static void test_pend( -ti *pItems, -unsigned iterations, -unsigned *pInlineIter -) -{ - unsigned i; - int status; - - for (i=0; itype, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_put( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - } -#ifdef WAIT_FOR_ACK - status = ca_array_get (DBR_INT, 1, pItems[0].chix, &val); - SEVCHK (status, NULL); - ca_pend_io(100.0); -#endif - status = ca_array_put( - pItems[0].type, - pItems[0].count, - pItems[0].chix, - pItems[0].pValue); - SEVCHK (status, NULL); - status = ca_flush_io(); - SEVCHK (status, NULL); - - *pInlineIter = 10; -} - -/* - * test_get () - */ -static void test_get( -ti *pItems, -unsigned iterations, -unsigned *pInlineIter -) -{ - ti *pi; - int status; - - for (pi=pItems; pi<&pItems[iterations]; pi++) { - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - } - status = ca_pend_io(1e20); - SEVCHK (status, NULL); - - *pInlineIter = 10; -} - -/* - * test_wait () - */ -static void test_wait ( -ti *pItems, -unsigned iterations, -unsigned *pInlineIter -) -{ - ti *pi; - int status; - - for (pi=pItems; pi<&pItems[iterations]; pi++) { - status = ca_array_get( - pi->type, - pi->count, - pi->chix, - pi->pValue); - SEVCHK (status, NULL); - status = ca_pend_io(100.0); - SEVCHK (status, NULL); - } - - *pInlineIter = 1; -} - -/* - * measure_get_latency - */ -static void measure_get_latency (ti *pItems, unsigned iterations) -{ - epicsTimeStamp end_time; - epicsTimeStamp start_time; - double delay; - double X = 0u; - double XX = 0u; - double max = DBL_MIN; - double min = DBL_MAX; - double mean; - double stdDev; - ti *pi; - int status; - - for ( pi = pItems; pi < &pItems[iterations]; pi++ ) { - epicsTimeGetCurrent ( &start_time ); - status = ca_array_get ( pi->type, pi->count, - pi->chix, pi->pValue ); - SEVCHK ( status, NULL ); - status = ca_pend_io ( 100.0 ); - SEVCHK ( status, NULL ); - - epicsTimeGetCurrent ( &end_time ); - - delay = epicsTimeDiffInSeconds ( &end_time,&start_time ); - - X += delay; - XX += delay*delay; - - if ( delay > max ) { - max = delay; - } - - if ( delay < min ) { - min = delay; - } - } - - mean = X/iterations; - stdDev = sqrt ( XX/iterations - mean*mean ); - printf ( - "Get Latency - " - "mean = %3.1f uS, " - "std dev = %3.1f uS, " - "min = %3.1f uS " - "max = %3.1f uS\n", - mean * 1e6, stdDev * 1e6, - min * 1e6, max * 1e6 ); -} - -/* - * printSearchStat() - */ -static void printSearchStat ( const ti * pi, unsigned iterations ) -{ - unsigned i; - double X = 0u; - double XX = 0u; - double max = DBL_MIN; - double min = DBL_MAX; - double mean; - double stdDev; - - for ( i = 0; i < iterations; i++ ) { - double retry = ca_search_attempts ( pi[i].chix ); - X += retry; - XX += retry * retry; - if ( retry > max ) { - max = retry; - } - if ( retry < min ) { - min = retry; - } - } - - mean = X / iterations; - stdDev = sqrt( XX / iterations - mean * mean ); - printf ( - "Search tries per chan - " - "mean = %3.1f " - "std dev = %3.1f " - "min = %3.1f " - "max = %3.1f\n", - mean, stdDev, min, max); -} - -/* - * timeIt () - */ -void timeIt ( tf *pfunc, ti *pItems, unsigned iterations, - unsigned nBytesSent, unsigned nBytesRecv ) -{ - epicsTimeStamp end_time; - epicsTimeStamp start_time; - double delay; - unsigned inlineIter; - - epicsTimeGetCurrent ( &start_time ); - (*pfunc) ( pItems, iterations, &inlineIter ); - epicsTimeGetCurrent ( &end_time ); - delay = epicsTimeDiffInSeconds ( &end_time, &start_time ); - if ( delay > 0.0 ) { - double freq = ( iterations * inlineIter ) / delay; - printf ( "Per Op, %8.4f uS ( %8.4f MHz )", - 1e6 / freq, freq / 1e6 ); - if ( pItems != NULL ) { - printf(", %8.4f snd Mbps, %8.4f rcv Mbps\n", - (inlineIter*nBytesSent*CHAR_BIT)/(delay*1e6), - (inlineIter*nBytesRecv*CHAR_BIT)/(delay*1e6) ); - } - else { - printf ("\n"); - } - } -} - -/* - * test () - */ -static void test ( ti *pItems, unsigned iterations ) -{ - unsigned payloadSize, dblPayloadSize; - unsigned nBytesSent, nBytesRecv; - - payloadSize = - dbr_size_n ( pItems[0].type, pItems[0].count ); - payloadSize = CA_MESSAGE_ALIGN ( payloadSize ); - - dblPayloadSize = dbr_size [ DBR_DOUBLE ]; - dblPayloadSize = CA_MESSAGE_ALIGN ( dblPayloadSize ); - - if ( payloadSize > dblPayloadSize ) { - unsigned factor = payloadSize / dblPayloadSize; - while ( factor ) { - if ( iterations > 10 * factor ) { - iterations /= factor; - break; - } - factor /= 2; - } - } - - printf ( "\t### async put test ###\n"); - nBytesSent = sizeof ( caHdr ) + CA_MESSAGE_ALIGN( payloadSize ); - nBytesRecv = 0u; - timeIt ( test_put, pItems, iterations, - nBytesSent * iterations, - nBytesRecv * iterations ); - - printf ( "\t### async get test ###\n"); - nBytesSent = sizeof ( caHdr ); - nBytesRecv = sizeof ( caHdr ) + CA_MESSAGE_ALIGN ( payloadSize ); - timeIt ( test_get, pItems, iterations, - nBytesSent * ( iterations ), - nBytesRecv * ( iterations ) ); - - printf ("\t### synch get test ###\n"); - nBytesSent = sizeof ( caHdr ); - nBytesRecv = sizeof ( caHdr ) + CA_MESSAGE_ALIGN ( payloadSize ); - if ( iterations > 100 ) { - iterations /= 100; - } - else if ( iterations > 10 ) { - iterations /= 10; - } - timeIt ( test_wait, pItems, iterations, - nBytesSent * iterations, - nBytesRecv * iterations ); -} - -/* - * catime () - */ -int catime ( const char * channelName, - unsigned channelCount, enum appendNumberFlag appNF ) -{ - unsigned i; - int j; - unsigned strsize; - unsigned nBytesSent, nBytesRecv; - ti *pItemList; - - if ( channelCount == 0 ) { - printf ( "channel count was zero\n" ); - return 0; - } - - pItemList = calloc ( channelCount, sizeof (ti) ); - if ( ! pItemList ) { - return -1; - } - - SEVCHK ( ca_context_create ( ca_disable_preemptive_callback ), - "Unable to initialize" ); - - if ( appNF == appendNumber ) { - printf ( "Testing with %u channels named %snnn\n", - channelCount, channelName ); - } - else { - printf ( "Testing with %u channels named %s\n", - channelCount, channelName ); - } - - strsize = sizeof ( pItemList[0].name ) - 1; - nBytesSent = 0; - nBytesRecv = 0; - for ( i=0; i < channelCount; i++ ) { - if ( appNF == appendNumber ) { - sprintf ( pItemList[i].name,"%.*s%.6u", - (int) (strsize - 15u), channelName, i ); - } - else { - strncpy ( pItemList[i].name, channelName, strsize); - } - pItemList[i].name[strsize]= '\0'; - pItemList[i].count = 0; - pItemList[i].pValue = 0; - nBytesSent += 2 * ( CA_MESSAGE_ALIGN ( strlen ( pItemList[i].name ) ) - + sizeof (caHdr) ); - nBytesRecv += 2 * sizeof (caHdr); - } - - printf ( "Channel Connect Test\n" ); - printf ( "--------------------\n" ); - timeIt ( test_search, pItemList, channelCount, nBytesSent, nBytesRecv ); - printSearchStat ( pItemList, channelCount ); - - for ( i = 0; i < channelCount; i++ ) { - size_t count = ca_element_count ( pItemList[i].chix ); - size_t size = sizeof ( dbr_string_t ) * count; - pItemList[i].count = count; - pItemList[i].pValue = malloc ( size ); - assert ( pItemList[i].pValue ); - } - - printf ( - "channel name=%s, native type=%d, native count=%u\n", - ca_name (pItemList[0].chix), - ca_field_type (pItemList[0].chix), - pItemList[0].count ); - - printf ("Pend Event Test\n"); - printf ( "----------------\n" ); - timeIt ( test_pend, NULL, 100, 0, 0 ); - - for ( i = 0; i < channelCount; i++ ) { - dbr_float_t * pFltVal = ( dbr_float_t * ) pItemList[i].pValue; - double val = i; - val /= channelCount; - for ( j = 0; j < pItemList[i].count; j++ ) { - pFltVal[j] = (dbr_float_t) val; - } - pItemList[i].type = DBR_FLOAT; - } - printf ( "DBR_FLOAT Test\n" ); - printf ( "--------------\n" ); - test ( pItemList, channelCount ); - - for ( i = 0; i < channelCount; i++ ) { - dbr_double_t * pDblVal = ( dbr_double_t * ) pItemList[i].pValue; - double val = i; - val /= channelCount; - for ( j = 0; j < pItemList[i].count; j++ ) { - pDblVal[j] = (dbr_double_t) val; - } - pItemList[i].type = DBR_DOUBLE; - } - printf ( "DBR_DOUBLE Test\n" ); - printf ( "---------------\n" ); - test ( pItemList, channelCount ); - - - for ( i = 0; i < channelCount; i++ ) { - dbr_string_t * pStrVal = ( dbr_string_t * ) pItemList[i].pValue; - double val = i; - val /= channelCount; - for ( j = 0; j < pItemList[i].count; j++ ) { - sprintf ( pStrVal[j], "%f", val ); - } - pItemList[i].type = DBR_STRING; - } - printf ( "DBR_STRING Test\n" ); - printf ( "---------------\n" ); - test ( pItemList, channelCount ); - - for ( i = 0; i < channelCount; i++ ) { - dbr_int_t * pIntVal = ( dbr_int_t * ) pItemList[i].pValue; - double val = i; - val /= channelCount; - for ( j = 0; j < pItemList[i].count; j++ ) { - pIntVal[j] = (dbr_int_t) val; - } - pItemList[i].type = DBR_INT; - } - printf ( "DBR_INT Test\n" ); - printf ( "------------\n" ); - test ( pItemList, channelCount ); - - printf ( "Get Latency Test\n" ); - printf ( "----------------\n" ); - for ( i = 0; i < channelCount; i++ ) { - dbr_double_t * pDblVal = ( dbr_double_t * ) pItemList[i].pValue; - for ( j = 0; j < pItemList[i].count; j++ ) { - pDblVal[j] = 0; - } - pItemList[i].type = DBR_DOUBLE; - } - measure_get_latency ( pItemList, channelCount ); - - printf ( "Free Channel Test\n" ); - printf ( "-----------------\n" ); - timeIt ( test_free, pItemList, channelCount, 0, 0 ); - - SEVCHK ( ca_task_exit (), "Unable to free resources at exit" ); - - for ( i = 0; i < channelCount; i++ ) { - free ( pItemList[i].pValue ); - } - - free ( pItemList ); - - return CATIME_OK; -} - - - - diff --git a/src/ca/client/catimeMain.c b/src/ca/client/catimeMain.c deleted file mode 100644 index 598ec453b..000000000 --- a/src/ca/client/catimeMain.c +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "caDiagnostics.h" - -static const unsigned defaultIterations = 10000u; - -int main ( int argc, char **argv ) -{ - const char *pUsage = " [ []]"; - - if ( argc > 1 ) { - char *pname = argv[1]; - if ( argc > 2 ) { - int iterations = atoi (argv[2]); - if ( iterations > 0) { - if ( argc > 3 ) { - if ( argc == 4 ) { - int status; - unsigned appendNumberBool; - status = sscanf ( argv[3], " %u ", &appendNumberBool ); - if ( status == 1 ) { - if ( appendNumberBool ) { - return catime ( pname, (unsigned) iterations, appendNumber ); - } - else { - return catime ( pname, (unsigned) iterations, dontAppendNumber ); - } - } - } - } - else { - return catime ( pname, (unsigned) iterations, dontAppendNumber ); - } - } - } - else { - return catime ( pname, defaultIterations, dontAppendNumber ); - } - } - printf ( "usage: %s %s\n", argv[0], pUsage); - return -1; -} diff --git a/src/ca/client/comBuf.cpp b/src/ca/client/comBuf.cpp deleted file mode 100644 index 94245d387..000000000 --- a/src/ca/client/comBuf.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "comBuf.h" -#include "errlog.h" - -bool comBuf::flushToWire ( wireSendAdapter & wire, const epicsTime & currentTime ) -{ - unsigned index = this->nextReadIndex; - unsigned finalIndex = this->commitIndex; - while ( index < finalIndex ) { - unsigned nBytes = wire.sendBytes ( - &this->buf[index], finalIndex - index, currentTime ); - if ( nBytes == 0u ) { - this->nextReadIndex = index; - return false; - } - index += nBytes; - } - this->nextReadIndex = index; - return true; -} - -// throwing the exception from a function that isnt inline -// shrinks the GNU compiled object code -void comBuf::throwInsufficentBytesException () -{ - throw comBuf::insufficentBytesAvailable (); -} - -void comBuf::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -comBufMemoryManager::~comBufMemoryManager () {} diff --git a/src/ca/client/comBuf.h b/src/ca/client/comBuf.h deleted file mode 100644 index 59e38780b..000000000 --- a/src/ca/client/comBuf.h +++ /dev/null @@ -1,335 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef comBufh -#define comBufh - -#include -#include - -#include "epicsAssert.h" -#include "epicsTypes.h" -#include "tsFreeList.h" -#include "tsDLList.h" -#include "osiWireFormat.h" -#include "compilerDependencies.h" - -static const unsigned comBufSize = 0x4000; - -// this wrapper avoids Tornado 2.0.1 compiler bugs -class comBufMemoryManager { -public: - virtual ~comBufMemoryManager (); - virtual void * allocate ( size_t ) = 0; - virtual void release ( void * ) = 0; -}; - -class wireSendAdapter { -public: - virtual unsigned sendBytes ( const void * pBuf, - unsigned nBytesInBuf, - const class epicsTime & currentTime ) = 0; -protected: - virtual ~wireSendAdapter() {} -}; - -enum swioCircuitState { - swioConnected, - swioPeerHangup, - swioPeerAbort, - swioLinkFailure, - swioLocalAbort -}; -struct statusWireIO { - unsigned bytesCopied; - swioCircuitState circuitState; -}; - -class wireRecvAdapter { -public: - virtual void recvBytes ( void * pBuf, - unsigned nBytesInBuf, statusWireIO & ) = 0; -protected: - virtual ~wireRecvAdapter() {} -}; - -class comBuf : public tsDLNode < comBuf > { -public: - class insufficentBytesAvailable {}; - comBuf (); - unsigned unoccupiedBytes () const; - unsigned occupiedBytes () const; - unsigned uncommittedBytes () const; - static unsigned capacityBytes (); - void clear (); - unsigned copyInBytes ( const void *pBuf, unsigned nBytes ); - unsigned push ( comBuf & ); - template < class T > - bool push ( const T & value ); - template < class T > - unsigned push ( const T * pValue, unsigned nElem ); - unsigned push ( const epicsInt8 * pValue, unsigned nElem ); - unsigned push ( const epicsUInt8 * pValue, unsigned nElem ); - unsigned push ( const epicsOldString * pValue, unsigned nElem ); - void commitIncomming (); - void clearUncommittedIncomming (); - bool copyInAllBytes ( const void *pBuf, unsigned nBytes ); - unsigned copyOutBytes ( void *pBuf, unsigned nBytes ); - bool copyOutAllBytes ( void *pBuf, unsigned nBytes ); - unsigned removeBytes ( unsigned nBytes ); - bool flushToWire ( wireSendAdapter &, const epicsTime & currentTime ); - void fillFromWire ( wireRecvAdapter &, statusWireIO & ); - struct popStatus { - bool success; - bool nowEmpty; - }; - template < class T > - popStatus pop ( T & ); - static void throwInsufficentBytesException (); - void * operator new ( size_t size, - comBufMemoryManager & ); - epicsPlacementDeleteOperator (( void *, comBufMemoryManager & )) -private: - unsigned commitIndex; - unsigned nextWriteIndex; - unsigned nextReadIndex; - epicsUInt8 buf [ comBufSize ]; - void operator delete ( void * ); - template < class T > - bool push ( const T * ); // disabled -}; - -inline void * comBuf::operator new ( size_t size, - comBufMemoryManager & mgr ) -{ - return mgr.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void comBuf::operator delete ( void * pCadaver, - comBufMemoryManager & mgr ) -{ - mgr.release ( pCadaver ); -} -#endif - -inline comBuf::comBuf () : commitIndex ( 0u ), - nextWriteIndex ( 0u ), nextReadIndex ( 0u ) -{ -} - -inline void comBuf :: clear () -{ - this->commitIndex = 0u; - this->nextWriteIndex = 0u; - this->nextReadIndex = 0u; -} - -inline unsigned comBuf :: unoccupiedBytes () const -{ - return sizeof ( this->buf ) - this->nextWriteIndex; -} - -inline unsigned comBuf :: occupiedBytes () const -{ - return this->commitIndex - this->nextReadIndex; -} - -inline unsigned comBuf :: uncommittedBytes () const -{ - return this->nextWriteIndex - this->commitIndex; -} - -inline unsigned comBuf :: push ( comBuf & bufIn ) -{ - unsigned nBytes = this->copyInBytes ( - & bufIn.buf[ bufIn.nextReadIndex ], - bufIn.commitIndex - bufIn.nextReadIndex ); - bufIn.nextReadIndex += nBytes; - return nBytes; -} - -inline unsigned comBuf :: capacityBytes () -{ - return comBufSize; -} - -inline void comBuf :: fillFromWire ( - wireRecvAdapter & wire, statusWireIO & stat ) -{ - wire.recvBytes ( - & this->buf[this->nextWriteIndex], - sizeof ( this->buf ) - this->nextWriteIndex, stat ); - if ( stat.circuitState == swioConnected ) { - this->nextWriteIndex += stat.bytesCopied; - } -} - -template < class T > -inline bool comBuf :: push ( const T & value ) -{ - unsigned index = this->nextWriteIndex; - unsigned available = sizeof ( this->buf ) - index; - if ( sizeof ( value ) > available ) { - return false; - } - WireSet ( value, & this->buf[index] ); - this->nextWriteIndex = index + sizeof ( value ); - return true; -} - -inline unsigned comBuf :: push ( const epicsInt8 *pValue, unsigned nElem ) -{ - return copyInBytes ( pValue, nElem ); -} - -inline unsigned comBuf :: push ( const epicsUInt8 *pValue, unsigned nElem ) -{ - return copyInBytes ( pValue, nElem ); -} - -inline unsigned comBuf :: push ( const epicsOldString * pValue, unsigned nElem ) -{ - unsigned index = this->nextWriteIndex; - unsigned available = sizeof ( this->buf ) - index; - unsigned nBytes = sizeof ( *pValue ) * nElem; - if ( nBytes > available ) { - nElem = available / sizeof ( *pValue ); - nBytes = nElem * sizeof ( *pValue ); - } - memcpy ( &this->buf[ index ], pValue, nBytes ); - this->nextWriteIndex = index + nBytes; - return nElem; -} - -template < class T > -unsigned comBuf :: push ( const T * pValue, unsigned nElem ) -{ - unsigned index = this->nextWriteIndex; - unsigned available = sizeof ( this->buf ) - index; - unsigned nBytes = sizeof ( *pValue ) * nElem; - if ( nBytes > available ) { - nElem = available / sizeof ( *pValue ); - } - for ( unsigned i = 0u; i < nElem; i++ ) { - // allow native floating point formats to be converted to IEEE - WireSet( pValue[i], &this->buf[index] ); - index += sizeof ( *pValue ); - } - this->nextWriteIndex = index; - return nElem; -} - -inline void comBuf :: commitIncomming () -{ - this->commitIndex = this->nextWriteIndex; -} - -inline void comBuf :: clearUncommittedIncomming () -{ - this->nextWriteIndex = this->commitIndex; -} - -inline bool comBuf :: copyInAllBytes ( const void *pBuf, unsigned nBytes ) -{ - unsigned index = this->nextWriteIndex; - unsigned available = sizeof ( this->buf ) - index; - if ( nBytes <= available ) { - memcpy ( & this->buf[index], pBuf, nBytes ); - this->nextWriteIndex = index + nBytes; - return true; - } - return false; -} - -inline unsigned comBuf :: copyInBytes ( const void * pBuf, unsigned nBytes ) -{ - unsigned index = this->nextWriteIndex; - unsigned available = sizeof ( this->buf ) - index; - if ( nBytes > available ) { - nBytes = available; - } - memcpy ( & this->buf[index], pBuf, nBytes ); - this->nextWriteIndex = index + nBytes; - return nBytes; -} - -inline bool comBuf :: copyOutAllBytes ( void * pBuf, unsigned nBytes ) -{ - unsigned index = this->nextReadIndex; - unsigned occupied = this->commitIndex - index; - if ( nBytes <= occupied ) { - memcpy ( pBuf, &this->buf[index], nBytes); - this->nextReadIndex = index + nBytes; - return true; - } - return false; -} - -inline unsigned comBuf :: copyOutBytes ( void *pBuf, unsigned nBytes ) -{ - unsigned index = this->nextReadIndex; - unsigned occupied = this->commitIndex - index; - if ( nBytes > occupied ) { - nBytes = occupied; - } - memcpy ( pBuf, &this->buf[index], nBytes); - this->nextReadIndex = index + nBytes; - return nBytes; -} - -inline unsigned comBuf :: removeBytes ( unsigned nBytes ) -{ - unsigned index = this->nextReadIndex; - unsigned occupied = this->commitIndex - index; - if ( nBytes > occupied ) { - nBytes = occupied; - } - this->nextReadIndex = index + nBytes; - return nBytes; -} - -template < class T > -comBuf :: popStatus comBuf :: pop ( T & returnVal ) -{ - unsigned nrIndex = this->nextReadIndex; - unsigned popIndex = nrIndex + sizeof ( returnVal ); - unsigned cIndex = this->commitIndex; - popStatus status; - status.success = true; - status.nowEmpty = false; - if ( popIndex >= cIndex ) { - if ( popIndex == cIndex ) { - status.nowEmpty = true; - } - else { - status.success = false; - return status; - } - } - WireGet ( & this->buf[ nrIndex ], returnVal ); - this->nextReadIndex = popIndex; - return status; -} - -#endif // ifndef comBufh diff --git a/src/ca/client/comQueRecv.cpp b/src/ca/client/comQueRecv.cpp deleted file mode 100644 index 88263544d..000000000 --- a/src/ca/client/comQueRecv.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "iocinf.h" -#include "virtualCircuit.h" - -comQueRecv::comQueRecv ( comBufMemoryManager & comBufMemoryManagerIn ): - comBufMemMgr ( comBufMemoryManagerIn ), nBytesPending ( 0u ) -{ -} - -comQueRecv::~comQueRecv () -{ - this->clear (); -} - -void comQueRecv::clear () -{ - comBuf *pBuf; - while ( ( pBuf = this->bufs.get () ) ) { - pBuf->~comBuf (); - this->comBufMemMgr.release ( pBuf ); - } - this->nBytesPending = 0u; -} - -unsigned comQueRecv::copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes ) -{ - unsigned totalBytes = 0u; - do { - comBuf * pComBuf = this->bufs.first (); - if ( ! pComBuf ) { - this->nBytesPending -= totalBytes; - return totalBytes; - } - totalBytes += pComBuf->copyOutBytes ( &pBuf[totalBytes], nBytes - totalBytes ); - if ( pComBuf->occupiedBytes () == 0u ) { - this->bufs.remove ( *pComBuf ); - pComBuf->~comBuf (); - this->comBufMemMgr.release ( pComBuf ); - } - } - while ( totalBytes < nBytes ); - this->nBytesPending -= totalBytes; - return totalBytes; -} - -unsigned comQueRecv::removeBytes ( unsigned nBytes ) -{ - unsigned totalBytes = 0u; - unsigned bytesLeft = nBytes; - while ( bytesLeft ) { - comBuf * pComBuf = this->bufs.first (); - if ( ! pComBuf ) { - this->nBytesPending -= totalBytes; - return totalBytes; - } - unsigned nBytesThisTime = pComBuf->removeBytes ( bytesLeft ); - if ( pComBuf->occupiedBytes () == 0u ) { - this->bufs.remove ( *pComBuf ); - pComBuf->~comBuf (); - this->comBufMemMgr.release ( pComBuf ); - } - if ( nBytesThisTime == 0u) { - break; - } - totalBytes += nBytesThisTime; - bytesLeft = nBytes - totalBytes; - } - this->nBytesPending -= totalBytes; - return totalBytes; -} - -void comQueRecv::popString ( epicsOldString *pStr ) -{ - for ( unsigned i = 0u; i < sizeof ( *pStr ); i++ ) { - pStr[0][i] = this->popInt8 (); - } -} - -void comQueRecv::pushLastComBufReceived ( comBuf & bufIn ) - -{ - bufIn.commitIncomming (); - comBuf * pComBuf = this->bufs.last (); - if ( pComBuf ) { - if ( pComBuf->unoccupiedBytes() ) { - this->nBytesPending += pComBuf->push ( bufIn ); - pComBuf->commitIncomming (); - } - } - unsigned bufBytes = bufIn.occupiedBytes(); - if ( bufBytes ) { - this->nBytesPending += bufBytes; - this->bufs.add ( bufIn ); - } - else { - bufIn.~comBuf (); - this->comBufMemMgr.release ( & bufIn ); - } -} - -// 1) split between buffers expected to run slower -// 2) using canonical unsigned tmp avoids ANSI C conversions to int -// 3) cast required because sizeof(unsigned) >= sizeof(epicsUInt32) -epicsUInt16 comQueRecv::multiBufferPopUInt16 () -{ - epicsUInt16 tmp; - if ( this->occupiedBytes() >= sizeof (tmp) ) { - unsigned byte1 = this->popUInt8 (); - unsigned byte2 = this->popUInt8 (); - tmp = static_cast ( ( byte1 << 8u ) | byte2 ); - } - else { - comBuf::throwInsufficentBytesException (); - tmp = 0u; - } - return tmp; -} - -// 1) split between buffers expected to run slower -// 2) using canonical unsigned temporary avoids ANSI C conversions to int -// 3) cast required because sizeof(unsigned) >= sizeof(epicsUInt32) -epicsUInt32 comQueRecv::multiBufferPopUInt32 () -{ - epicsUInt32 tmp; - if ( this->occupiedBytes() >= sizeof (tmp) ) { - // 1) split between buffers expected to run slower - // 2) using canonical unsigned temporary avoids ANSI C conversions to int - // 3) cast required because sizeof(unsigned) >= sizeof(epicsUInt32) - unsigned byte1 = this->popUInt8(); - unsigned byte2 = this->popUInt8(); - unsigned byte3 = this->popUInt8(); - unsigned byte4 = this->popUInt8(); - tmp = static_cast - ( ( byte1 << 24u ) | ( byte2 << 16u ) | - ( byte3 << 8u ) | byte4 ); - } - else { - comBuf::throwInsufficentBytesException (); - tmp = 0u; // avoid compiler warnings - } - return tmp; -} - -void comQueRecv::removeAndDestroyBuf ( comBuf & buf ) -{ - this->bufs.remove ( buf ); - buf.~comBuf (); - this->comBufMemMgr.release ( & buf ); -} - -epicsUInt8 comQueRecv::popUInt8 () -{ - comBuf * pComBuf = this->bufs.first (); - if ( ! pComBuf ) { - comBuf::throwInsufficentBytesException (); - } - epicsUInt8 tmp = '\0'; - comBuf::popStatus status = pComBuf->pop ( tmp ); - if ( ! status.success ) { - comBuf::throwInsufficentBytesException (); - } - if ( status.nowEmpty ) { - this->removeAndDestroyBuf ( *pComBuf ); - } - this->nBytesPending--; - return tmp; -} - -epicsUInt16 comQueRecv::popUInt16 () -{ - comBuf * pComBuf = this->bufs.first (); - if ( ! pComBuf ) { - comBuf::throwInsufficentBytesException (); - } - // try first for all in one buffer efficent version - epicsUInt16 tmp = 0; - comBuf::popStatus status = pComBuf->pop ( tmp ); - if ( status.success ) { - this->nBytesPending -= sizeof ( epicsUInt16 ); - if ( status.nowEmpty ) { - this->removeAndDestroyBuf ( *pComBuf ); - } - return tmp; - } - return this->multiBufferPopUInt16 (); -} - -epicsUInt32 comQueRecv::popUInt32 () -{ - comBuf *pComBuf = this->bufs.first (); - if ( ! pComBuf ) { - comBuf::throwInsufficentBytesException (); - } - // try first for all in one buffer efficent version - epicsUInt32 tmp = 0; - comBuf::popStatus status = pComBuf->pop ( tmp ); - if ( status.success ) { - this->nBytesPending -= sizeof ( epicsUInt32 ); - if ( status.nowEmpty ) { - this->removeAndDestroyBuf ( *pComBuf ); - } - return tmp; - } - return this->multiBufferPopUInt32 (); -} - -bool comQueRecv::popOldMsgHeader ( caHdrLargeArray & msg ) -{ - // try first for all in one buffer efficent version - comBuf * pComBuf = this->bufs.first (); - if ( ! pComBuf ) { - return false; - } - unsigned avail = pComBuf->occupiedBytes (); - if ( avail >= sizeof ( caHdr ) ) { - pComBuf->pop ( msg.m_cmmd ); - ca_uint16_t smallPostsize = 0; - pComBuf->pop ( smallPostsize ); - msg.m_postsize = smallPostsize; - pComBuf->pop ( msg.m_dataType ); - ca_uint16_t smallCount = 0; - pComBuf->pop ( smallCount ); - msg.m_count = smallCount; - pComBuf->pop ( msg.m_cid ); - pComBuf->pop ( msg.m_available ); - this->nBytesPending -= sizeof ( caHdr ); - if ( avail == sizeof ( caHdr ) ) { - this->removeAndDestroyBuf ( *pComBuf ); - } - return true; - } - else if ( this->occupiedBytes () >= sizeof ( caHdr ) ) { - msg.m_cmmd = this->popUInt16 (); - msg.m_postsize = this->popUInt16 (); - msg.m_dataType = this->popUInt16 (); - msg.m_count = this->popUInt16 (); - msg.m_cid = this->popUInt32 (); - msg.m_available = this->popUInt32 (); - return true; - } - else { - return false; - } -} - diff --git a/src/ca/client/comQueRecv.h b/src/ca/client/comQueRecv.h deleted file mode 100644 index 7f3153d8d..000000000 --- a/src/ca/client/comQueRecv.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef comQueRecvh -#define comQueRecvh - -#include "comBuf.h" - -class comQueRecv { -public: - comQueRecv ( comBufMemoryManager & ); - ~comQueRecv (); - unsigned occupiedBytes () const; - unsigned copyOutBytes ( epicsInt8 *pBuf, unsigned nBytes ); - unsigned removeBytes ( unsigned nBytes ); - void pushLastComBufReceived ( comBuf & ); - void clear (); - bool popOldMsgHeader ( struct caHdrLargeArray & ); - epicsInt8 popInt8 (); - epicsUInt8 popUInt8 (); - epicsInt16 popInt16 (); - epicsUInt16 popUInt16 (); - epicsInt32 popInt32 (); - epicsUInt32 popUInt32 (); - epicsFloat32 popFloat32 (); - epicsFloat64 popFloat64 (); - void popString ( epicsOldString * ); -private: - tsDLList < comBuf > bufs; - comBufMemoryManager & comBufMemMgr; - unsigned nBytesPending; - epicsUInt16 multiBufferPopUInt16 (); - epicsUInt32 multiBufferPopUInt32 (); - void removeAndDestroyBuf ( comBuf & ); - comQueRecv ( const comQueRecv & ); - comQueRecv & operator = ( const comQueRecv & ); -}; - -inline unsigned comQueRecv::occupiedBytes () const -{ - return this->nBytesPending; -} - -inline epicsInt8 comQueRecv::popInt8 () -{ - return static_cast < epicsInt8 > ( this->popUInt8() ); -} - -inline epicsInt16 comQueRecv::popInt16 () -{ - return static_cast < epicsInt16 > ( this->popUInt16() ); -} - -inline epicsInt32 comQueRecv::popInt32 () -{ - return static_cast < epicsInt32 > ( this->popUInt32() ); -} - -// this has been optimized to aligned convert, maybe more could be done, -// but since it is currently not used ... -inline epicsFloat32 comQueRecv::popFloat32 () -{ - union { - epicsUInt8 _wire[ sizeof ( epicsFloat32 ) ]; - epicsFloat32 _fp; - } tmp; - // optimizer will unroll this loop - for ( unsigned i = 0u; i < sizeof ( tmp._wire ); i++ ) { - tmp._wire[i] = this->popUInt8 (); - } - return AlignedWireRef < epicsFloat32 > ( tmp._fp ); -} - -// this has been optimized to aligned convert, maybe more could be done, -// but since it is currently not used ... -inline epicsFloat64 comQueRecv::popFloat64 () -{ - union { - epicsUInt8 _wire[ sizeof ( epicsFloat64 ) ]; - epicsFloat64 _fp; - } tmp; - // optimizer will unroll this loop - for ( unsigned i = 0u; i < sizeof ( tmp._wire ); i++ ) { - tmp._wire[i] = this->popUInt8 (); - } - return AlignedWireRef < epicsFloat64 > ( tmp._fp ); -} - -#endif // ifndef comQueRecvh diff --git a/src/ca/client/comQueSend.cpp b/src/ca/client/comQueSend.cpp deleted file mode 100644 index 6ed516bb3..000000000 --- a/src/ca/client/comQueSend.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -// -// Requirements: -// 1) Allow sufficent headroom so that users will be able to perform -// a reasonable amount of IO within CA callbacks without experiencing -// a push/pull deadlock. If a potential push/pull deadlock situation -// occurs then detect and avoid it and provide diagnotic to the user -// via special status. -// 2) Return status to the user when there is insufficent memory to -// queue a complete message. -// 3) return status to the user when a message cant be flushed because -// a connection dropped. -// 4) Do not allocate too much memory in exception situatons (such as -// after a circuit disconnect). -// 5) Avoid allocating more memory than is absolutely necessary to meet -// the above requirements. -// 6) Message fragments must never be sent to the IOC when there isnt -// enough memory to queue part of a message (we also must not force -// a disconnect because the client is starved for memory). -// 7) avoid the need to check status for each byte pushed into the -// protocol stream. -// -// Implementation: -// 1) When queuing a complete message, first test to see if a flush is -// required. If it is a receive thread scheduals the flush with the -// send thread, and otherwise directly execute the system call. The -// send thread must run at a higher priority than the receive thread -// if we are to minimize memory consumption. -// 2) Preallocate space for the entire message prior to copying in the -// message so that message fragments are not flushed out just prior -// to detecting that memory is unavailable. -// 3) Return a special error constant when the following situations -// are detected when the user is attempting to queue a request -// from within a user callback executed by a receive thread: -// a) A user is queuing more requests that demand a response from a -// callback than are removed by the response that initiated the -// callback, and this situation persists for many callbacks until -// all buffering in the system is exausted. -// b) A user is queuing many requests that demand a response from one -// callback until all buffering in the system is exausted. -// c) Some combination of both (a) nad (b). -// -// - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "virtualCircuit.h" -#include "db_access.h" // for dbr_short_t etc - -// nill message alignment pad bytes -const char cacNillBytes [] = -{ - 0, 0, 0, 0, - 0, 0, 0, 0 -}; - -comQueSend::comQueSend ( wireSendAdapter & wireIn, - comBufMemoryManager & comBufMemMgrIn ): - comBufMemMgr ( comBufMemMgrIn ), wire ( wireIn ), - nBytesPending ( 0u ) -{ -} - -comQueSend::~comQueSend () -{ - this->clear (); -} - -void comQueSend::clear () -{ - comBuf *pBuf; - - while ( ( pBuf = this->bufs.get () ) ) { - this->nBytesPending -= pBuf->occupiedBytes (); - pBuf->~comBuf (); - this->comBufMemMgr.release ( pBuf ); - } - this->pFirstUncommited = tsDLIter < comBuf > (); - assert ( this->nBytesPending == 0 ); -} - -void comQueSend::copy_dbr_string ( const void * pValue ) -{ - this->push ( static_cast < const char * > ( pValue ), MAX_STRING_SIZE ); -} - -void comQueSend::copy_dbr_short ( const void * pValue ) -{ - this->push ( * static_cast ( pValue ) ); -} - -void comQueSend::copy_dbr_float ( const void * pValue ) -{ - this->push ( * static_cast ( pValue ) ); -} - -void comQueSend::copy_dbr_char ( const void * pValue ) -{ - this->push ( * static_cast ( pValue ) ); -} - -void comQueSend::copy_dbr_long ( const void * pValue ) -{ - this->push ( * static_cast ( pValue ) ); -} - -void comQueSend::copy_dbr_double ( const void * pValue ) -{ - this->push ( * static_cast ( pValue ) ); -} - -void comQueSend::copy_dbr_invalid ( const void * ) -{ - throw cacChannel::badType (); -} - -const comQueSend::copyScalarFunc_t comQueSend::dbrCopyScalar [39] = { - &comQueSend::copy_dbr_string, - &comQueSend::copy_dbr_short, - &comQueSend::copy_dbr_float, - &comQueSend::copy_dbr_short, // DBR_ENUM - &comQueSend::copy_dbr_char, - &comQueSend::copy_dbr_long, - &comQueSend::copy_dbr_double, - &comQueSend::copy_dbr_invalid, // DBR_STS_SHORT - &comQueSend::copy_dbr_invalid, // DBR_STS_FLOAT - &comQueSend::copy_dbr_invalid, // DBR_STS_ENUM - &comQueSend::copy_dbr_invalid, // DBR_STS_CHAR - &comQueSend::copy_dbr_invalid, // DBR_STS_LONG - &comQueSend::copy_dbr_invalid, // DBR_STS_DOUBLE - &comQueSend::copy_dbr_invalid, // DBR_TIME_STRING - &comQueSend::copy_dbr_invalid, // DBR_TIME_INT - &comQueSend::copy_dbr_invalid, // DBR_TIME_SHORT - &comQueSend::copy_dbr_invalid, // DBR_TIME_FLOAT - &comQueSend::copy_dbr_invalid, // DBR_TIME_ENUM - &comQueSend::copy_dbr_invalid, // DBR_TIME_CHAR - &comQueSend::copy_dbr_invalid, // DBR_TIME_LONG - &comQueSend::copy_dbr_invalid, // DBR_TIME_DOUBLE - &comQueSend::copy_dbr_invalid, // DBR_GR_STRING - &comQueSend::copy_dbr_invalid, // DBR_GR_SHORT - &comQueSend::copy_dbr_invalid, // DBR_GR_FLOAT - &comQueSend::copy_dbr_invalid, // DBR_GR_ENUM - &comQueSend::copy_dbr_invalid, // DBR_GR_CHAR - &comQueSend::copy_dbr_invalid, // DBR_GR_LONG - &comQueSend::copy_dbr_invalid, // DBR_GR_DOUBLE - &comQueSend::copy_dbr_invalid, // DBR_CTRL_STRING - &comQueSend::copy_dbr_invalid, // DBR_CTRL_SHORT - &comQueSend::copy_dbr_invalid, // DBR_CTRL_FLOAT - &comQueSend::copy_dbr_invalid, // DBR_CTRL_ENUM - &comQueSend::copy_dbr_invalid, // DBR_CTRL_CHAR - &comQueSend::copy_dbr_invalid, // DBR_CTRL_LONG - &comQueSend::copy_dbr_invalid, // DBR_CTRL_DOUBLE - &comQueSend::copy_dbr_short, // DBR_PUT_ACKT - &comQueSend::copy_dbr_short, // DBR_PUT_ACKS - &comQueSend::copy_dbr_invalid, // DBR_STSACK_STRING - &comQueSend::copy_dbr_invalid // DBR_CLASS_NAME -}; - -void comQueSend::copy_dbr_string ( const void *pValue, unsigned nElem ) -{ - this->push ( static_cast < const char * > ( pValue ), nElem * MAX_STRING_SIZE ); -} - -void comQueSend::copy_dbr_short ( const void *pValue, unsigned nElem ) -{ - this->push ( static_cast ( pValue ), nElem ); -} - -void comQueSend::copy_dbr_float ( const void *pValue, unsigned nElem ) -{ - this->push ( static_cast ( pValue ), nElem ); -} - -void comQueSend::copy_dbr_char ( const void *pValue, unsigned nElem ) -{ - this->push ( static_cast ( pValue ), nElem ); -} - -void comQueSend::copy_dbr_long ( const void *pValue, unsigned nElem ) -{ - this->push ( static_cast ( pValue ), nElem ); -} - -void comQueSend::copy_dbr_double ( const void *pValue, unsigned nElem ) -{ - this->push ( static_cast ( pValue ), nElem ); -} - -void comQueSend::copy_dbr_invalid ( const void *, unsigned ) -{ - throw cacChannel::badType (); -} - -const comQueSend::copyVectorFunc_t comQueSend::dbrCopyVector [39] = { - &comQueSend::copy_dbr_string, - &comQueSend::copy_dbr_short, - &comQueSend::copy_dbr_float, - &comQueSend::copy_dbr_short, // DBR_ENUM - &comQueSend::copy_dbr_char, - &comQueSend::copy_dbr_long, - &comQueSend::copy_dbr_double, - &comQueSend::copy_dbr_invalid, // DBR_STS_SHORT - &comQueSend::copy_dbr_invalid, // DBR_STS_FLOAT - &comQueSend::copy_dbr_invalid, // DBR_STS_ENUM - &comQueSend::copy_dbr_invalid, // DBR_STS_CHAR - &comQueSend::copy_dbr_invalid, // DBR_STS_LONG - &comQueSend::copy_dbr_invalid, // DBR_STS_DOUBLE - &comQueSend::copy_dbr_invalid, // DBR_TIME_STRING - &comQueSend::copy_dbr_invalid, // DBR_TIME_INT - &comQueSend::copy_dbr_invalid, // DBR_TIME_SHORT - &comQueSend::copy_dbr_invalid, // DBR_TIME_FLOAT - &comQueSend::copy_dbr_invalid, // DBR_TIME_ENUM - &comQueSend::copy_dbr_invalid, // DBR_TIME_CHAR - &comQueSend::copy_dbr_invalid, // DBR_TIME_LONG - &comQueSend::copy_dbr_invalid, // DBR_TIME_DOUBLE - &comQueSend::copy_dbr_invalid, // DBR_GR_STRING - &comQueSend::copy_dbr_invalid, // DBR_GR_SHORT - &comQueSend::copy_dbr_invalid, // DBR_GR_FLOAT - &comQueSend::copy_dbr_invalid, // DBR_GR_ENUM - &comQueSend::copy_dbr_invalid, // DBR_GR_CHAR - &comQueSend::copy_dbr_invalid, // DBR_GR_LONG - &comQueSend::copy_dbr_invalid, // DBR_GR_DOUBLE - &comQueSend::copy_dbr_invalid, // DBR_CTRL_STRING - &comQueSend::copy_dbr_invalid, // DBR_CTRL_SHORT - &comQueSend::copy_dbr_invalid, // DBR_CTRL_FLOAT - &comQueSend::copy_dbr_invalid, // DBR_CTRL_ENUM - &comQueSend::copy_dbr_invalid, // DBR_CTRL_CHAR - &comQueSend::copy_dbr_invalid, // DBR_CTRL_LONG - &comQueSend::copy_dbr_invalid, // DBR_CTRL_DOUBLE - &comQueSend::copy_dbr_short, // DBR_PUT_ACKT - &comQueSend::copy_dbr_short, // DBR_PUT_ACKS - &comQueSend::copy_dbr_invalid, // DBR_STSACK_STRING - &comQueSend::copy_dbr_invalid // DBR_CLASS_NAME -}; - -comBuf * comQueSend::popNextComBufToSend () -{ - comBuf *pBuf = this->bufs.get (); - if ( pBuf ) { - unsigned nBytesThisBuf = pBuf->occupiedBytes (); - if ( nBytesThisBuf ) { - assert ( this->nBytesPending >= nBytesThisBuf ); - this->nBytesPending -= nBytesThisBuf; - } - else { - this->bufs.push ( *pBuf ); - pBuf = 0; - } - } - else { - assert ( this->nBytesPending == 0u ); - } - return pBuf; -} - -void comQueSend::insertRequestHeader ( - ca_uint16_t request, ca_uint32_t payloadSize, - ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid, - ca_uint32_t requestDependent, bool v49Ok ) -{ - if ( payloadSize < 0xffff && nElem < 0xffff ) { - comBuf * pComBuf = this->bufs.last (); - if ( ! pComBuf || pComBuf->unoccupiedBytes() < 16u ) { - pComBuf = newComBuf (); - this->pushComBuf ( *pComBuf ); - } - pComBuf->push ( request ); - pComBuf->push ( static_cast < ca_uint16_t > ( payloadSize ) ); - pComBuf->push ( dataType ); - pComBuf->push ( static_cast < ca_uint16_t > ( nElem ) ); - pComBuf->push ( cid ); - pComBuf->push ( requestDependent ); - } - else if ( v49Ok ) { - comBuf * pComBuf = this->bufs.last (); - if ( ! pComBuf || pComBuf->unoccupiedBytes() < 24u ) { - pComBuf = newComBuf (); - this->pushComBuf ( *pComBuf ); - } - pComBuf->push ( request ); - pComBuf->push ( static_cast < ca_uint16_t > ( 0xffff ) ); - pComBuf->push ( dataType ); - pComBuf->push ( static_cast < ca_uint16_t > ( 0u ) ); - pComBuf->push ( cid ); - pComBuf->push ( requestDependent ); - pComBuf->push ( payloadSize ); - pComBuf->push ( nElem ); - } - else { - throw cacChannel::outOfBounds (); - } -} - -void comQueSend::insertRequestWithPayLoad ( - ca_uint16_t request, unsigned dataType, arrayElementCount nElem, - ca_uint32_t cid, ca_uint32_t requestDependent, - const void * pPayload, bool v49Ok ) -{ - if ( INVALID_DB_REQ ( dataType ) ) { - throw cacChannel::badType (); - } - if ( dataType >= comQueSendCopyDispatchSize ) { - throw cacChannel::badType(); - } - ca_uint32_t size = 0u; - ca_uint32_t payloadSize = 0u; - if ( nElem == 1 ) { - if ( dataType == DBR_STRING ) { - const char * pStr = static_cast < const char * > ( pPayload ); - size = strlen ( pStr ) + 1u; - if ( size > MAX_STRING_SIZE ) { - throw cacChannel::outOfBounds(); - } - payloadSize = CA_MESSAGE_ALIGN ( size ); - this->insertRequestHeader ( request, payloadSize, - static_cast ( dataType ), - nElem, cid, requestDependent, v49Ok ); - this->pushString ( pStr, size ); - } - else { - size = dbr_size[dataType]; - payloadSize = CA_MESSAGE_ALIGN ( size ); - this->insertRequestHeader ( request, payloadSize, - static_cast ( dataType ), - nElem, cid, requestDependent, v49Ok ); - ( this->*dbrCopyScalar [dataType] ) ( pPayload ); - } - } - else { - arrayElementCount maxBytes; - if ( v49Ok ) { - maxBytes = 0xffffffff; - } - else { - maxBytes = MAX_TCP - sizeof ( caHdr ); - } - arrayElementCount maxElem = - ( maxBytes - sizeof (dbr_double_t) - dbr_size[dataType] ) / - dbr_value_size[dataType]; - if ( nElem >= maxElem ) { - throw cacChannel::outOfBounds(); - } - // the above checks verify that the total size - // is lest that 0xffffffff - size = static_cast < ca_uint32_t > - ( dbr_size_n ( dataType, nElem ) ); - payloadSize = CA_MESSAGE_ALIGN ( size ); - this->insertRequestHeader ( request, payloadSize, - static_cast ( dataType ), - static_cast < ca_uint32_t > ( nElem ), - cid, requestDependent, v49Ok ); - ( this->*dbrCopyVector [dataType] ) ( pPayload, nElem ); - } - // set pad bytes to nill - unsigned padSize = payloadSize - size; - if ( padSize ) { - this->pushString ( cacNillBytes, payloadSize - size ); - } -} - -void comQueSend::commitMsg () -{ - while ( this->pFirstUncommited.valid() ) { - this->nBytesPending += this->pFirstUncommited->uncommittedBytes (); - this->pFirstUncommited->commitIncomming (); - this->pFirstUncommited++; - } - // printf ( "NBP: %u\n", this->nBytesPending ); -} - - -void comQueSend::clearUncommitedMsg () -{ - while ( this->pFirstUncommited.valid() ) { - tsDLIter < comBuf > next = this->pFirstUncommited; - next++; - this->pFirstUncommited->clearUncommittedIncomming (); - if ( this->pFirstUncommited->occupiedBytes() == 0u ) { - this->bufs.remove ( *this->pFirstUncommited ); - this->pFirstUncommited->~comBuf (); - this->comBufMemMgr.release ( this->pFirstUncommited.pointer() ); - } - this->pFirstUncommited = next; - } -} - diff --git a/src/ca/client/comQueSend.h b/src/ca/client/comQueSend.h deleted file mode 100644 index 808285e7a..000000000 --- a/src/ca/client/comQueSend.h +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef comQueSendh -#define comQueSendh - -#include - -#include "tsDLList.h" -#include "comBuf.h" - -#define comQueSendCopyDispatchSize 39 - -class epicsMutex; -template < class T > class epicsGuard; - -class comQueSendMsgMinder { -public: - comQueSendMsgMinder ( - class comQueSend &, epicsGuard < epicsMutex > & ); - ~comQueSendMsgMinder (); - void commit (); -private: - class comQueSend * pSendQue; -}; - -// -// Notes. -// o calling popNextComBufToSend() will clear any uncommitted bytes -// -class comQueSend { -public: - comQueSend ( wireSendAdapter &, comBufMemoryManager & ); - ~comQueSend (); - void clear (); - unsigned occupiedBytes () const; - bool flushEarlyThreshold ( unsigned nBytesThisMsg ) const; - bool flushBlockThreshold () const; - void pushUInt16 ( const ca_uint16_t value ); - void pushUInt32 ( const ca_uint32_t value ); - void pushFloat32 ( const ca_float32_t value ); - void pushString ( const char *pVal, unsigned nChar ); - void insertRequestHeader ( - ca_uint16_t request, ca_uint32_t payloadSize, - ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid, - ca_uint32_t requestDependent, bool v49Ok ); - void insertRequestWithPayLoad ( - ca_uint16_t request, unsigned dataType, arrayElementCount nElem, - ca_uint32_t cid, ca_uint32_t requestDependent, - const void * pPayload, bool v49Ok ); - comBuf * popNextComBufToSend (); -private: - comBufMemoryManager & comBufMemMgr; - tsDLList < comBuf > bufs; - tsDLIter < comBuf > pFirstUncommited; - wireSendAdapter & wire; - unsigned nBytesPending; - - typedef void ( comQueSend::*copyScalarFunc_t ) ( - const void * pValue ); - static const copyScalarFunc_t dbrCopyScalar [comQueSendCopyDispatchSize]; - void copy_dbr_string ( const void * pValue ); - void copy_dbr_short ( const void * pValue ); - void copy_dbr_float ( const void * pValue ); - void copy_dbr_char ( const void * pValue ); - void copy_dbr_long ( const void * pValue ); - void copy_dbr_double ( const void * pValue ); - void copy_dbr_invalid ( const void * pValue ); - - typedef void ( comQueSend::*copyVectorFunc_t ) ( - const void * pValue, unsigned nElem ); - static const copyVectorFunc_t dbrCopyVector [comQueSendCopyDispatchSize]; - void copy_dbr_string ( const void *pValue, unsigned nElem ); - void copy_dbr_short ( const void *pValue, unsigned nElem ); - void copy_dbr_float ( const void *pValue, unsigned nElem ); - void copy_dbr_char ( const void *pValue, unsigned nElem ); - void copy_dbr_long ( const void *pValue, unsigned nElem ); - void copy_dbr_double ( const void *pValue, unsigned nElem ); - void copy_dbr_invalid ( const void * pValue, unsigned nElem ); - - void pushComBuf ( comBuf & ); - comBuf * newComBuf (); - - void beginMsg (); - void commitMsg (); - void clearUncommitedMsg (); - - friend class comQueSendMsgMinder; - - // - // visual C++ versions 6 & 7 do not allow out of - // class member template function definition - // - template < class T > - inline void push ( const T *pVal, const unsigned nElem ) - { - comBuf * pLastBuf = this->bufs.last (); - unsigned nCopied; - if ( pLastBuf ) { - nCopied = pLastBuf->push ( pVal, nElem ); - } - else { - nCopied = 0u; - } - while ( nElem > nCopied ) { - comBuf * pComBuf = newComBuf (); - nCopied += pComBuf->push - ( &pVal[nCopied], nElem - nCopied ); - this->pushComBuf ( *pComBuf ); - } - } - - // - // visual C++ versions 6 and 7 do not allow out of - // class member template function definition - // - template < class T > - inline void push ( const T & val ) - { - comBuf * pComBuf = this->bufs.last (); - if ( pComBuf && pComBuf->push ( val ) ) { - return; - } - pComBuf = newComBuf (); - bool success = pComBuf->push ( val ); - assert ( success ); - this->pushComBuf ( *pComBuf ); - } - - template < class T > - inline void push ( const T * ); // disabled - - comQueSend ( const comQueSend & ); - comQueSend & operator = ( const comQueSend & ); -}; - -extern const char cacNillBytes[]; - -inline comQueSendMsgMinder::comQueSendMsgMinder ( - class comQueSend & sendQueIn, epicsGuard < epicsMutex > & ) : - pSendQue ( & sendQueIn ) -{ - sendQueIn.beginMsg (); -} - -inline comQueSendMsgMinder::~comQueSendMsgMinder () -{ - if ( this->pSendQue ) { - this->pSendQue->clearUncommitedMsg (); - } -} - -inline void comQueSendMsgMinder::commit () -{ - if ( this->pSendQue ) { - this->pSendQue->commitMsg (); - this->pSendQue = 0; - } -} - -inline void comQueSend::beginMsg () -{ - this->pFirstUncommited = this->bufs.lastIter (); -} - -inline void comQueSend::pushUInt16 ( const ca_uint16_t value ) -{ - this->push ( value ); -} - -inline void comQueSend::pushUInt32 ( const ca_uint32_t value ) -{ - this->push ( value ); -} - -inline void comQueSend::pushFloat32 ( const ca_float32_t value ) -{ - this->push ( value ); -} - -inline void comQueSend::pushString ( const char *pVal, unsigned nChar ) -{ - this->push ( pVal, nChar ); -} - -inline void comQueSend::pushComBuf ( comBuf & cb ) -{ - this->bufs.add ( cb ); - if ( ! this->pFirstUncommited.valid() ) { - this->pFirstUncommited = this->bufs.lastIter (); - } -} - -inline unsigned comQueSend::occupiedBytes () const -{ - return this->nBytesPending; -} - -inline bool comQueSend::flushBlockThreshold () const -{ - return ( this->nBytesPending > 16 * comBuf::capacityBytes () ); -} - -inline bool comQueSend::flushEarlyThreshold ( unsigned nBytesThisMsg ) const -{ - return ( this->nBytesPending + nBytesThisMsg > 4 * comBuf::capacityBytes () ); -} - -// wrapping this with a function avoids WRS T2.2 Cygnus GNU compiler bugs -inline comBuf * comQueSend::newComBuf () -{ - return new ( this->comBufMemMgr ) comBuf; -} - -#endif // ifndef comQueSendh diff --git a/src/ca/client/convert.cpp b/src/ca/client/convert.cpp deleted file mode 100644 index 851711774..000000000 --- a/src/ca/client/convert.cpp +++ /dev/null @@ -1,1440 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * C O N V E R T . C - * - * Author: D. Kersteins - * - * - * NOTES: - * - * 1) All routines in this file have an encode argument which - * determines if we are converting from the standard format to - * the local format or vise versa. To date only float and double data - * types must be converted differently depending on the encode - * argument - joh - * - */ - -#include - -#include "dbDefs.h" -#include "osiSock.h" -#include "osiWireFormat.h" - -#define epicsExportSharedSymbols -#include "net_convert.h" -#include "iocinf.h" -#include "caProto.h" -#include "caerr.h" - -/* - * NOOP if this isnt required - */ -#ifdef EPICS_CONVERSION_REQUIRED - -/* - * if hton is true then it is a host to network conversion - * otherwise vise-versa - * - * net format: big endian and IEEE float - */ -typedef void ( * CACVRTFUNCPTR ) ( - const void *pSrc, void *pDest, int hton, arrayElementCount count ); - -inline void dbr_htond ( - const dbr_double_t * pHost, dbr_double_t * pNet ) -{ - AlignedWireRef < epicsFloat64 > tmp ( *pNet ); - tmp = *pHost; -} -inline void dbr_ntohd ( - const dbr_double_t * pNet, dbr_double_t * pHost ) -{ - *pHost = AlignedWireRef < const epicsFloat64 > ( *pNet ); -} -inline void dbr_htonf ( - const dbr_float_t * pHost, dbr_float_t * pNet ) -{ - AlignedWireRef < epicsFloat32 > tmp ( *pNet ); - tmp = *pHost; -} -inline void dbr_ntohf ( - const dbr_float_t * pNet, dbr_float_t * pHost ) -{ - *pHost = AlignedWireRef < const epicsFloat32 > ( *pNet ); -} - -inline epicsUInt16 dbr_ntohs( const epicsUInt16 & net ) -{ - return AlignedWireRef < const epicsUInt16 > ( net ); -} - -inline epicsUInt16 dbr_htons ( const epicsUInt16 & host ) -{ - epicsUInt16 tmp; - AlignedWireRef < epicsUInt16 > awr ( tmp ); - awr = host; - return tmp; -} - -inline epicsUInt32 dbr_ntohl( const epicsUInt32 & net ) -{ - return AlignedWireRef < const epicsUInt32 > ( net ); -} - -inline epicsUInt32 dbr_htonl ( const epicsUInt32 & host ) -{ - epicsUInt32 tmp; - AlignedWireRef < epicsUInt32 > awr ( tmp ); - awr = host; - return tmp; -} - -/* - * if hton is true then it is a host to network conversion - * otherwise vise-versa - * - * net format: big endian and IEEE float - * - */ - -/* - * CVRT_STRING() - */ -static void cvrt_string( -const void *s, /* source */ -void *d, /* destination */ -int /* encode */, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - char *pSrc = (char *) s; - char *pDest = (char *) d; - - /* convert "in place" -> nothing to do */ - if (s == d) - return; - memcpy ( pDest, pSrc, num*MAX_STRING_SIZE ); -} - -/* - * CVRT_SHORT() - */ -static void cvrt_short( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - dbr_short_t *pSrc = (dbr_short_t *) s; - dbr_short_t *pDest = (dbr_short_t *) d; - - if(encode){ - for(arrayElementCount i=0; i nothing to do */ - if (s == d) - return; - for( arrayElementCount i=0; istatus = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - - /* convert "in place" -> nothing else to do */ - if (s == d) - return; - - memcpy ( pDest->value, pSrc->value, (MAX_STRING_SIZE * num) ); - -} - -/**************************************************************************** -** cvrt_sts_short(s,d) -** struct dbr_sts_int *s pointer to source struct -** struct dbr_sts_int *d pointer to destination struct -** int encode; boolean, if true vax to ieee -** else ieee to vax -** -** converts fields ofstruct in HOST format to ieee format -** or -** converts fields of struct in NET format to fields with HOST -** format -****************************************************************************/ - -static void cvrt_sts_short( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_sts_int *pSrc = (struct dbr_sts_int *) s; - struct dbr_sts_int *pDest = (struct dbr_sts_int *) d; - - /* convert vax to ieee or ieee to vax format -- same code*/ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - - if (num == 1) /* single value */ - pDest->value = dbr_ntohs(pSrc->value); - else /* array chan-- multiple pts */ - { - cvrt_short(&pSrc->value, &pDest->value, encode, num); - } -} -/**************************************************************************** -** cvrt_sts_float(s,d) -** struct dbr_sts_float *s pointer to source struct -** struct dbr_sts_float *d pointer to destination struct -** int encode; boolean, if true vax to ieee -** else ieee to vax -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_sts_float( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_sts_float *pSrc = (struct dbr_sts_float *) s; - struct dbr_sts_float *pDest = (struct dbr_sts_float *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - - cvrt_float(&pSrc->value, &pDest->value, encode, num); -} - -/**************************************************************************** -** cvrt_sts_double(s,d) -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_sts_double( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_sts_double *pSrc = (struct dbr_sts_double *) s; - struct dbr_sts_double *pDest = (struct dbr_sts_double *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - - cvrt_double(&pSrc->value, &pDest->value, encode, num); -} - -/**************************************************************************** -** cvrt_sts_enum(s,d) -** struct dbr_sts_enum *s pointer to source struct -** struct dbr_sts_enum *d pointer to destination struct -** int encode; boolean, if true vax to ieee -** else ieee to vax -** -** converts fields of struct in NET format to fields with HOST format -** or -** converts fields of struct in HOST format to fields with NET format -** -****************************************************************************/ - -static void cvrt_sts_enum( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_sts_enum *pSrc = (struct dbr_sts_enum *) s; - struct dbr_sts_enum *pDest = (struct dbr_sts_enum *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - if (num == 1) - pDest->value = dbr_ntohs(pSrc->value); - else { - cvrt_enum(&pSrc->value,&pDest->value,encode,num); - } -} - -/**************************************************************************** -** cvrt_gr_short() -** -** converts fields of struct in NET format to fields with HOST format -** or -** converts fields of struct in HOST format to fields with NET format -** -****************************************************************************/ - -static void cvrt_gr_short( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_gr_int *pSrc = (struct dbr_gr_int *) s; - struct dbr_gr_int *pDest = (struct dbr_gr_int *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - if ( s != d ) { - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - } - - pDest->upper_disp_limit = dbr_ntohs(pSrc->upper_disp_limit); - pDest->lower_disp_limit = dbr_ntohs(pSrc->lower_disp_limit); - pDest->upper_alarm_limit = dbr_ntohs(pSrc->upper_alarm_limit); - pDest->upper_warning_limit = dbr_ntohs(pSrc->upper_warning_limit); - pDest->lower_alarm_limit = dbr_ntohs(pSrc->lower_alarm_limit); - pDest->lower_warning_limit = dbr_ntohs(pSrc->lower_warning_limit); - - if (num == 1) - pDest->value = dbr_ntohs(pSrc->value); - else { - cvrt_short(&pSrc->value, &pDest->value, encode,num); - } -} - -/**************************************************************************** -** cvrt_gr_char() -** -** converts fields of struct in NET format to fields with HOST format -** or -** converts fields of struct in HOST format to fields with NET format -** -****************************************************************************/ - -static void cvrt_gr_char( -const void *s, /* source */ -void *d, /* destination */ -int /*encode*/, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_gr_char *pSrc = (struct dbr_gr_char *) s; - struct dbr_gr_char *pDest = (struct dbr_gr_char *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - - if (s == d) /* source == dest -> no more conversions */ - return; - - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - - pDest->upper_disp_limit = pSrc->upper_disp_limit; - pDest->lower_disp_limit = pSrc->lower_disp_limit; - pDest->upper_alarm_limit = pSrc->upper_alarm_limit; - pDest->upper_warning_limit = pSrc->upper_warning_limit; - pDest->lower_alarm_limit = pSrc->lower_alarm_limit; - pDest->lower_warning_limit = pSrc->lower_warning_limit; - - if (num == 1) - pDest->value = pSrc->value; - else { - memcpy((char *)&pDest->value, (char *)&pSrc->value, num); - } -} - -/**************************************************************************** -** cvrt_gr_long() -** -** converts fields of struct in NET format to fields with HOST format -** or -** converts fields of struct in HOST format to fields with NET format -** -****************************************************************************/ - -static void cvrt_gr_long( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_gr_long *pSrc = (struct dbr_gr_long *) s; - struct dbr_gr_long *pDest = (struct dbr_gr_long *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - if ( s != d ) { - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - } - - pDest->upper_disp_limit = dbr_ntohl(pSrc->upper_disp_limit); - pDest->lower_disp_limit = dbr_ntohl(pSrc->lower_disp_limit); - pDest->upper_alarm_limit = dbr_ntohl(pSrc->upper_alarm_limit); - pDest->upper_warning_limit = dbr_ntohl(pSrc->upper_warning_limit); - pDest->lower_alarm_limit = dbr_ntohl(pSrc->lower_alarm_limit); - pDest->lower_warning_limit = dbr_ntohl(pSrc->lower_warning_limit); - - if (num == 1) - pDest->value = dbr_ntohl(pSrc->value); - else { - cvrt_long(&pSrc->value, &pDest->value, encode, num); - } -} - -/**************************************************************************** -** cvrt_gr_enum(s,d) -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_gr_enum( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_gr_enum *pSrc = (struct dbr_gr_enum *) s; - struct dbr_gr_enum *pDest = (struct dbr_gr_enum *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->no_str = dbr_ntohs(pSrc->no_str); - if ( s != d ) { - memcpy((void *)pDest->strs,(void *)pSrc->strs,sizeof(pSrc->strs)); - } - - if (num == 1) /* single value */ - pDest->value = dbr_ntohs(pSrc->value); - else /* array chan-- multiple pts */ - { - cvrt_enum(&(pSrc->value), &(pDest->value), encode, num); - } -} - -/**************************************************************************** -** cvrt_gr_double(s,d) -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_gr_double( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_gr_double *pSrc = (struct dbr_gr_double *) s; - struct dbr_gr_double *pDest = (struct dbr_gr_double *) d; - - /* these are same for vax to ieee or ieee to vax */ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->precision = dbr_ntohs(pSrc->precision); - if ( s != d ) { - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - } - - if (encode) /* vax to ieee convert */ - { - if (num == 1){ - dbr_htond(&pSrc->value, &pDest->value); - } - else { - cvrt_double(&pSrc->value, &pDest->value, encode,num); - } - dbr_htond(&pSrc->upper_disp_limit,&pDest->upper_disp_limit); - dbr_htond(&pSrc->lower_disp_limit, &pDest->lower_disp_limit); - dbr_htond(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit); - dbr_htond(&pSrc->upper_warning_limit, &pDest->upper_warning_limit); - dbr_htond(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit); - dbr_htond(&pSrc->lower_warning_limit, &pDest->lower_warning_limit); - } - else /* ieee to vax convert */ - { - if (num == 1){ - dbr_ntohd(&pSrc->value, &pDest->value); - } - else { - cvrt_double(&pSrc->value, &pDest->value, encode,num); - } - dbr_ntohd(&pSrc->upper_disp_limit,&pDest->upper_disp_limit); - dbr_ntohd(&pSrc->lower_disp_limit, &pDest->lower_disp_limit); - dbr_ntohd(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit); - dbr_ntohd(&pSrc->upper_warning_limit, &pDest->upper_warning_limit); - dbr_ntohd(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit); - dbr_ntohd(&pSrc->lower_warning_limit, &pDest->lower_warning_limit); - } -} - - -/**************************************************************************** -** cvrt_gr_float(s,d) -** struct dbr_gr_float *d pointer to destination struct -** int encode; boolean, if true vax to ieee -** else ieee to vax -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_gr_float( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_gr_float *pSrc = (struct dbr_gr_float *) s; - struct dbr_gr_float *pDest = (struct dbr_gr_float *) d; - - /* these are same for vax to ieee or ieee to vax */ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->precision = dbr_ntohs(pSrc->precision); - if ( s != d ) { - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - } - - if (encode) /* vax to ieee convert */ - { - if (num == 1){ - dbr_htonf(&pSrc->value, &pDest->value); - } - else { - cvrt_float(&pSrc->value, &pDest->value, encode,num); - } - dbr_htonf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit); - dbr_htonf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit); - dbr_htonf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit); - dbr_htonf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit); - dbr_htonf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit); - dbr_htonf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit); - } - else /* ieee to vax convert */ - { - if (num == 1){ - dbr_ntohf(&pSrc->value, &pDest->value); - } - else { - cvrt_float(&pSrc->value, &pDest->value, encode,num); - } - dbr_ntohf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit); - dbr_ntohf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit); - dbr_ntohf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit); - dbr_ntohf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit); - dbr_ntohf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit); - dbr_ntohf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit); - } -} - - - -/**************************************************************************** -** cvrt_ctrl_short(s,d) -** struct dbr_gr_int *s pointer to source struct -** struct dbr_gr_int *d pointer to destination struct -** int encode; boolean, if true vax to ieee -** else ieee to vax -** -** converts fields of struct in NET format to fields with HOST format -** or -** converts fields of struct in HOST format to fields with NET format -** -****************************************************************************/ - -static void cvrt_ctrl_short( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_ctrl_int *pSrc = (struct dbr_ctrl_int *) s; - struct dbr_ctrl_int *pDest = (struct dbr_ctrl_int *) d; - - /* vax to ieee or ieee to vax -- same code */ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - if ( s != d ) { - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - } - - pDest->upper_disp_limit = dbr_ntohs(pSrc->upper_disp_limit); - pDest->lower_disp_limit = dbr_ntohs(pSrc->lower_disp_limit); - pDest->upper_alarm_limit = dbr_ntohs(pSrc->upper_alarm_limit); - pDest->upper_warning_limit = dbr_ntohs(pSrc->upper_warning_limit); - pDest->lower_alarm_limit = dbr_ntohs(pSrc->lower_alarm_limit); - pDest->lower_warning_limit = dbr_ntohs(pSrc->lower_warning_limit); - pDest->lower_ctrl_limit = dbr_ntohs(pSrc->lower_ctrl_limit); - pDest->upper_ctrl_limit = dbr_ntohs(pSrc->upper_ctrl_limit); - - if (num == 1) - pDest->value = dbr_ntohs(pSrc->value); - else { - cvrt_short(&pSrc->value, &pDest->value, encode, num); - } -} - -/**************************************************************************** -** cvrt_ctrl_long(s,d) -** -** converts fields of struct in NET format to fields with HOST format -** or -** converts fields of struct in HOST format to fields with NET format -** -****************************************************************************/ - -static void cvrt_ctrl_long( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_ctrl_long *pSrc = (struct dbr_ctrl_long*) s; - struct dbr_ctrl_long *pDest = (struct dbr_ctrl_long *) d; - - /* vax to ieee or ieee to vax -- same code */ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - if ( s != d ) { - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - } - - pDest->upper_disp_limit = dbr_ntohl(pSrc->upper_disp_limit); - pDest->lower_disp_limit = dbr_ntohl(pSrc->lower_disp_limit); - pDest->upper_alarm_limit = dbr_ntohl(pSrc->upper_alarm_limit); - pDest->upper_warning_limit = dbr_ntohl(pSrc->upper_warning_limit); - pDest->lower_alarm_limit = dbr_ntohl(pSrc->lower_alarm_limit); - pDest->lower_warning_limit = dbr_ntohl(pSrc->lower_warning_limit); - pDest->lower_ctrl_limit = dbr_ntohl(pSrc->lower_ctrl_limit); - pDest->upper_ctrl_limit = dbr_ntohl(pSrc->upper_ctrl_limit); - - if (num == 1) - pDest->value = dbr_ntohl(pSrc->value); - else { - cvrt_long(&pSrc->value, &pDest->value, encode, num); - } -} - -/**************************************************************************** -** cvrt_ctrl_short(s,d) -** -** converts fields of struct in NET format to fields with HOST format -** or -** converts fields of struct in HOST format to fields with NET format -** -****************************************************************************/ - -static void cvrt_ctrl_char( -const void *s, /* source */ -void *d, /* destination */ -int /*encode*/, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_ctrl_char *pSrc = (struct dbr_ctrl_char *) s; - struct dbr_ctrl_char *pDest = (struct dbr_ctrl_char *) d; - - /* vax to ieee or ieee to vax -- same code */ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - - if ( s == d ) - return; - - pDest->upper_disp_limit = pSrc->upper_disp_limit; - pDest->lower_disp_limit = pSrc->lower_disp_limit; - pDest->upper_alarm_limit = pSrc->upper_alarm_limit; - pDest->upper_warning_limit = pSrc->upper_warning_limit; - pDest->lower_ctrl_limit = pSrc->lower_ctrl_limit; - pDest->upper_ctrl_limit = pSrc->upper_ctrl_limit; - - if (num == 1) - pDest->value = pSrc->value; - else { - memcpy((void *)&pDest->value, (void *)&pSrc->value, num); - } -} - -/**************************************************************************** -** cvrt_ctrl_double(s,d) -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_ctrl_double( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_ctrl_double *pSrc = (struct dbr_ctrl_double *) s; - struct dbr_ctrl_double *pDest = (struct dbr_ctrl_double *) d; - - /* these are the same for ieee to vax or vax to ieee */ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->precision = dbr_ntohs(pSrc->precision); - if ( s != d ) { - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - } - if (encode) /* vax to ieee convert */ - { - if (num == 1){ - dbr_htond(&pSrc->value, &pDest->value); - } - else { - cvrt_double(&pSrc->value, &pDest->value, encode, num); - } - dbr_htond(&pSrc->upper_disp_limit,&pDest->upper_disp_limit); - dbr_htond(&pSrc->lower_disp_limit, &pDest->lower_disp_limit); - dbr_htond(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit); - dbr_htond(&pSrc->upper_warning_limit, &pDest->upper_warning_limit); - dbr_htond(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit); - dbr_htond(&pSrc->lower_warning_limit, &pDest->lower_warning_limit); - dbr_htond(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit); - dbr_htond(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit); - } - else /* ieee to vax convert */ - { - if (num == 1){ - dbr_ntohd(&pSrc->value, &pDest->value); - } - else { - cvrt_double(&pSrc->value, &pDest->value, encode, num); - } - dbr_ntohd(&pSrc->lower_disp_limit, &pDest->lower_disp_limit); - dbr_ntohd(&pSrc->upper_disp_limit, &pDest->upper_disp_limit); - dbr_ntohd(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit); - dbr_ntohd(&pSrc->upper_warning_limit, &pDest->upper_warning_limit); - dbr_ntohd(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit); - dbr_ntohd(&pSrc->lower_warning_limit, &pDest->lower_warning_limit); - dbr_ntohd(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit); - dbr_ntohd(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit); - } - -} - - - -/**************************************************************************** -** cvrt_ctrl_float(s,d) -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_ctrl_float( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_ctrl_float *pSrc = (struct dbr_ctrl_float *) s; - struct dbr_ctrl_float *pDest = (struct dbr_ctrl_float *) d; - - /* these are the same for ieee to vaax or vax to ieee */ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->precision = dbr_ntohs(pSrc->precision); - if ( s != d ) { - memcpy(pDest->units,pSrc->units,sizeof(pSrc->units)); - } - if (encode) /* vax to ieee convert */ - { - if (num == 1){ - dbr_htonf(&pSrc->value, &pDest->value); - } - else { - cvrt_float(&pSrc->value, &pDest->value, encode, num); - } - dbr_htonf(&pSrc->upper_disp_limit,&pDest->upper_disp_limit); - dbr_htonf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit); - dbr_htonf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit); - dbr_htonf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit); - dbr_htonf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit); - dbr_htonf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit); - dbr_htonf(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit); - dbr_htonf(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit); - } - else /* ieee to vax convert */ - { - if (num == 1){ - dbr_ntohf(&pSrc->value, &pDest->value); - } - else { - cvrt_float(&pSrc->value, &pDest->value, encode, num); - } - dbr_ntohf(&pSrc->lower_disp_limit, &pDest->lower_disp_limit); - dbr_ntohf(&pSrc->upper_disp_limit, &pDest->upper_disp_limit); - dbr_ntohf(&pSrc->upper_alarm_limit, &pDest->upper_alarm_limit); - dbr_ntohf(&pSrc->upper_warning_limit, &pDest->upper_warning_limit); - dbr_ntohf(&pSrc->lower_alarm_limit, &pDest->lower_alarm_limit); - dbr_ntohf(&pSrc->lower_warning_limit, &pDest->lower_warning_limit); - dbr_ntohf(&pSrc->lower_ctrl_limit, &pDest->lower_ctrl_limit); - dbr_ntohf(&pSrc->upper_ctrl_limit, &pDest->upper_ctrl_limit); - } - -} - - -/**************************************************************************** -** cvrt_ctrl_enum(s,d) -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_ctrl_enum( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_ctrl_enum *pSrc = (struct dbr_ctrl_enum *) s; - struct dbr_ctrl_enum *pDest = (struct dbr_ctrl_enum *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->no_str = dbr_ntohs(pSrc->no_str); - if ( s != d ) { - memcpy((void *)pDest->strs,(void *)pSrc->strs,sizeof(pSrc->strs)); - } - - if (num == 1) /* single value */ - pDest->value = dbr_ntohs(pSrc->value); - else /* array chan-- multiple pts */ - { - cvrt_enum(&(pSrc->value), &(pDest->value), encode, num); - } -} - -/**************************************************************************** -** cvrt_sts_char(s,d) -** struct dbr_sts_int *s pointer to source struct -** struct dbr_sts_int *d pointer to destination struct -** int encode; boolean, if true vax to ieee -** else ieee to vax -** -** converts fields ofstruct in HOST format to ieee format -** or -** converts fields of struct in NET format to fields with HOST -** format -****************************************************************************/ - -static void cvrt_sts_char( -const void *s, /* source */ -void *d, /* destination */ -int /*encode*/, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_sts_char *pSrc = (struct dbr_sts_char *) s; - struct dbr_sts_char *pDest = (struct dbr_sts_char *) d; - - /* convert vax to ieee or ieee to vax format -- same code*/ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - - if ( s == d ) - return; - - if (num == 1) /* single value */ - pDest->value = pSrc->value; - else /* array chan-- multiple pts */ - { - memcpy((void *)&pDest->value, (void *)&pSrc->value, num); - } -} - -/**************************************************************************** -** cvrt_sts_long(s,d) -** -** converts fields ofstruct in HOST format to ieee format -** or -** converts fields of struct in NET format to fields with HOST -** format -****************************************************************************/ - -static void cvrt_sts_long( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_sts_long *pSrc = (struct dbr_sts_long *) s; - struct dbr_sts_long *pDest = (struct dbr_sts_long *) d; - - /* convert vax to ieee or ieee to vax format -- same code*/ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - - if (num == 1) /* single value */ - pDest->value = dbr_ntohl(pSrc->value); - else /* array chan-- multiple pts */ - { - cvrt_long(&pDest->value, &pSrc->value, encode, num); - } -} - - -/**************************************************************************** -** cvrt_time_string(s,d) -** -** converts fields of struct in HOST format to NET format -** or -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_time_string( -const void *s, /* source */ -void *d, /* destination */ -int /*encode*/, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_time_string *pSrc = (struct dbr_time_string *) s; - struct dbr_time_string *pDest = (struct dbr_time_string *) d; - - /* convert ieee to vax format or vax to ieee */ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->stamp.secPastEpoch = dbr_ntohl(pSrc->stamp.secPastEpoch); - pDest->stamp.nsec = dbr_ntohl(pSrc->stamp.nsec); - - if ( s != d ) { - memcpy(pDest->value, pSrc->value, (MAX_STRING_SIZE * num)); - } -} - -/**************************************************************************** -** cvrt_time_short(s,d) -** -** converts fields ofstruct in HOST format to ieee format -** or -** converts fields of struct in NET format to fields with HOST -** format -****************************************************************************/ - -static void cvrt_time_short( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_time_short *pSrc = (struct dbr_time_short *) s; - struct dbr_time_short *pDest = (struct dbr_time_short *) d; - - /* convert vax to ieee or ieee to vax format -- same code*/ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->stamp.secPastEpoch = dbr_ntohl(pSrc->stamp.secPastEpoch); - pDest->stamp.nsec = dbr_ntohl(pSrc->stamp.nsec); - - if (num == 1) /* single value */ - pDest->value = dbr_ntohs(pSrc->value); - else /* array chan-- multiple pts */ - { - cvrt_short(&pSrc->value, &pDest->value, encode, num); - } -} - -/**************************************************************************** -** cvrt_time_float(s,d) -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_time_float( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_time_float *pSrc = (struct dbr_time_float *) s; - struct dbr_time_float *pDest = (struct dbr_time_float *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->stamp.secPastEpoch = dbr_ntohl(pSrc->stamp.secPastEpoch); - pDest->stamp.nsec = dbr_ntohl(pSrc->stamp.nsec); - - cvrt_float(&pSrc->value, &pDest->value, encode, num); -} - -/**************************************************************************** -** cvrt_time_double(s,d) -** -** if encode -** converts struct in HOST format to ieee format -** else -** converts fields of struct in NET format to fields with HOST -** format; -****************************************************************************/ - -static void cvrt_time_double( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_time_double *pSrc = (struct dbr_time_double *) s; - struct dbr_time_double *pDest = (struct dbr_time_double *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->stamp.secPastEpoch = dbr_ntohl(pSrc->stamp.secPastEpoch); - pDest->stamp.nsec = dbr_ntohl(pSrc->stamp.nsec); - - cvrt_double(&pSrc->value, &pDest->value, encode, num); -} - - - -/**************************************************************************** -** cvrt_time_enum(s,d) -** -** converts fields of struct in NET format to fields with HOST format -** or -** converts fields of struct in HOST format to fields with NET format -** -****************************************************************************/ - -static void cvrt_time_enum( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_time_enum *pSrc = (struct dbr_time_enum *) s; - struct dbr_time_enum *pDest = (struct dbr_time_enum *) d; - - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->stamp.secPastEpoch = dbr_ntohl(pSrc->stamp.secPastEpoch); - pDest->stamp.nsec = dbr_ntohl(pSrc->stamp.nsec); - if (num == 1) - pDest->value = dbr_ntohs(pSrc->value); - else { - cvrt_enum(&pSrc->value,&pDest->value,encode,num); - } -} - -/**************************************************************************** -** cvrt_sts_char(s,d) -** -** converts fields ofstruct in HOST format to ieee format -** or -** converts fields of struct in NET format to fields with HOST -** format -****************************************************************************/ - -static void cvrt_time_char( -const void *s, /* source */ -void *d, /* destination */ -int /*encode*/, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_time_char *pSrc = (struct dbr_time_char *) s; - struct dbr_time_char *pDest = (struct dbr_time_char *) d; - - /* convert vax to ieee or ieee to vax format -- same code*/ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->stamp.secPastEpoch = dbr_ntohl(pSrc->stamp.secPastEpoch); - pDest->stamp.nsec = dbr_ntohl(pSrc->stamp.nsec); - - if ( s == d ) - return; - - if (num == 1) /* single value */ - pDest->value = pSrc->value; - else /* array chan-- multiple pts */ - { - memcpy((void *)&pDest->value, (void *)&pSrc->value, num); - } -} -/**************************************************************************** -** cvrt_time_long(s,d) -** -** converts fields ofstruct in HOST format to ieee format -** or -** converts fields of struct in NET format to fields with HOST -** format -****************************************************************************/ - -static void cvrt_time_long( -const void *s, /* source */ -void *d, /* destination */ -int encode, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - struct dbr_time_long *pSrc = (struct dbr_time_long *) s; - struct dbr_time_long *pDest = (struct dbr_time_long *) d; - - /* convert vax to ieee or ieee to vax format -- same code*/ - pDest->status = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->stamp.secPastEpoch = dbr_ntohl(pSrc->stamp.secPastEpoch); - pDest->stamp.nsec = dbr_ntohl(pSrc->stamp.nsec); - - if (num == 1) /* single value */ - pDest->value = dbr_ntohl(pSrc->value); - else /* array chan-- multiple pts */ - { - cvrt_long(&pDest->value, &pSrc->value, encode, num); - } -} - -/* - * cvrt_put_ackt() - * - * - * - * - */ -static void cvrt_put_ackt( -const void *s, /* source */ -void *d, /* destination */ -int /*encode*/, /* cvrt HOST to NET if T */ -arrayElementCount num /* number of values */ -) -{ - dbr_put_ackt_t *pSrc = (dbr_put_ackt_t *) s; - dbr_put_ackt_t *pDest = (dbr_put_ackt_t *) d; - arrayElementCount i; - - for(i=0; istatus = dbr_ntohs(pSrc->status); - pDest->severity = dbr_ntohs(pSrc->severity); - pDest->ackt = dbr_ntohs(pSrc->ackt); - pDest->acks = dbr_ntohs(pSrc->acks); - - /* convert "in place" -> nothing else to do */ - if (s == d) - return; - - memcpy(pDest->value, pSrc->value, (MAX_STRING_SIZE * num)); -} - -/* cvrt is (array of) (pointer to) (function returning) int */ -static CACVRTFUNCPTR cac_dbr_cvrt[] = { - cvrt_string, - cvrt_short, - cvrt_float, - cvrt_enum, - cvrt_char, - cvrt_long, - cvrt_double, - - cvrt_sts_string, - cvrt_sts_short, - cvrt_sts_float, - cvrt_sts_enum, - cvrt_sts_char, - cvrt_sts_long, - cvrt_sts_double, - - cvrt_time_string, - cvrt_time_short, - cvrt_time_float, - cvrt_time_enum, - cvrt_time_char, - cvrt_time_long, - cvrt_time_double, - - cvrt_sts_string, /* DBR_GR_STRING identical to dbr_sts_string */ - cvrt_gr_short, - cvrt_gr_float, - cvrt_gr_enum, - cvrt_gr_char, - cvrt_gr_long, - cvrt_gr_double, - - cvrt_sts_string, /* DBR_CTRL_STRING identical to dbr_sts_string */ - cvrt_ctrl_short, - cvrt_ctrl_float, - cvrt_ctrl_enum, - cvrt_ctrl_char, - cvrt_ctrl_long, - cvrt_ctrl_double, - - cvrt_put_ackt, - cvrt_put_ackt, /* DBR_PUT_ACKS identical to DBR_PUT_ACKT */ - cvrt_stsack_string, - cvrt_string -}; - -#endif /* EPICS_CONVERSION_REQUIRED */ - -int caNetConvert ( unsigned type, const void *pSrc, void *pDest, - int hton, arrayElementCount count ) -{ -# ifdef EPICS_CONVERSION_REQUIRED - if ( type >= NELEMENTS ( cac_dbr_cvrt ) ) { - return ECA_BADTYPE; - } - ( * cac_dbr_cvrt [ type ] ) ( pSrc, pDest, hton, count ); -# else - if ( INVALID_DB_REQ ( type ) ) { - return ECA_BADTYPE; - } - if ( pSrc != pDest ) { - memcpy ( pDest, pSrc, dbr_size_n ( type, count ) ); - } -# endif - return ECA_NORMAL; -} - diff --git a/src/ca/client/db_access.h b/src/ca/client/db_access.h deleted file mode 100644 index 92aa5d011..000000000 --- a/src/ca/client/db_access.h +++ /dev/null @@ -1,740 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* base/include/db_access.h */ -/* Author: Bob Dalesio - * Date: 4-4-88 -*/ - -#ifndef INCLdb_accessh -#define INCLdb_accessh - -#include - -#ifdef epicsExportSharedSymbols -# define INCLdb_accessh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsTypes.h" -#include "epicsTime.h" - -#ifdef INCLdb_accessh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_UNITS_SIZE 8 -#define MAX_ENUM_STRING_SIZE 26 -#define MAX_ENUM_STATES 16 - -/* - * architecture independent types - * - * (so far this is sufficient for all archs we have ported to) - */ -typedef epicsOldString dbr_string_t; -typedef epicsUInt8 dbr_char_t; -typedef epicsInt16 dbr_short_t; -typedef epicsUInt16 dbr_ushort_t; -typedef epicsInt16 dbr_int_t; -typedef epicsUInt16 dbr_enum_t; -typedef epicsInt32 dbr_long_t; -typedef epicsUInt32 dbr_ulong_t; -typedef epicsFloat32 dbr_float_t; -typedef epicsFloat64 dbr_double_t; -typedef epicsUInt16 dbr_put_ackt_t; -typedef epicsUInt16 dbr_put_acks_t; -typedef epicsOldString dbr_stsack_string_t; -typedef epicsOldString dbr_class_name_t; - -#ifndef db_accessHFORdb_accessC -/* database field types */ -#define DBF_STRING 0 -#define DBF_INT 1 -#define DBF_SHORT 1 -#define DBF_FLOAT 2 -#define DBF_ENUM 3 -#define DBF_CHAR 4 -#define DBF_LONG 5 -#define DBF_DOUBLE 6 -#define DBF_NO_ACCESS 7 -#define LAST_TYPE DBF_DOUBLE -#define VALID_DB_FIELD(x) ((x >= 0) && (x <= LAST_TYPE)) -#define INVALID_DB_FIELD(x) ((x < 0) || (x > LAST_TYPE)) - -/* data request buffer types */ -#define DBR_STRING DBF_STRING -#define DBR_INT DBF_INT -#define DBR_SHORT DBF_INT -#define DBR_FLOAT DBF_FLOAT -#define DBR_ENUM DBF_ENUM -#define DBR_CHAR DBF_CHAR -#define DBR_LONG DBF_LONG -#define DBR_DOUBLE DBF_DOUBLE -#define DBR_STS_STRING 7 -#define DBR_STS_SHORT 8 -#define DBR_STS_INT DBR_STS_SHORT -#define DBR_STS_FLOAT 9 -#define DBR_STS_ENUM 10 -#define DBR_STS_CHAR 11 -#define DBR_STS_LONG 12 -#define DBR_STS_DOUBLE 13 -#define DBR_TIME_STRING 14 -#define DBR_TIME_INT 15 -#define DBR_TIME_SHORT 15 -#define DBR_TIME_FLOAT 16 -#define DBR_TIME_ENUM 17 -#define DBR_TIME_CHAR 18 -#define DBR_TIME_LONG 19 -#define DBR_TIME_DOUBLE 20 -#define DBR_GR_STRING 21 -#define DBR_GR_SHORT 22 -#define DBR_GR_INT DBR_GR_SHORT -#define DBR_GR_FLOAT 23 -#define DBR_GR_ENUM 24 -#define DBR_GR_CHAR 25 -#define DBR_GR_LONG 26 -#define DBR_GR_DOUBLE 27 -#define DBR_CTRL_STRING 28 -#define DBR_CTRL_SHORT 29 -#define DBR_CTRL_INT DBR_CTRL_SHORT -#define DBR_CTRL_FLOAT 30 -#define DBR_CTRL_ENUM 31 -#define DBR_CTRL_CHAR 32 -#define DBR_CTRL_LONG 33 -#define DBR_CTRL_DOUBLE 34 -#define DBR_PUT_ACKT DBR_CTRL_DOUBLE + 1 -#define DBR_PUT_ACKS DBR_PUT_ACKT + 1 -#define DBR_STSACK_STRING DBR_PUT_ACKS + 1 -#define DBR_CLASS_NAME DBR_STSACK_STRING + 1 -#define LAST_BUFFER_TYPE DBR_CLASS_NAME -#define VALID_DB_REQ(x) ((x >= 0) && (x <= LAST_BUFFER_TYPE)) -#define INVALID_DB_REQ(x) ((x < 0) || (x > LAST_BUFFER_TYPE)) - -/* - * The enumeration "epicsType" is an index to this array - * of type DBR types. In some cases we select the a - * larger type to avoid loss of information - */ -epicsShareExtern const int epicsTypeToDBR_XXXX [lastEpicsType+1]; - -/* - * The DBR_XXXX types are indicies into this array - */ -epicsShareExtern const epicsType DBR_XXXXToEpicsType [LAST_BUFFER_TYPE+1]; - -/* values returned for each field type - * DBR_STRING returns a NULL terminated string - * DBR_SHORT returns an unsigned short - * DBR_INT returns an unsigned short - * DBR_FLOAT returns an IEEE floating point value - * DBR_ENUM returns an unsigned short which is the enum item - * DBR_CHAR returns an unsigned char - * DBR_LONG returns an unsigned long - * DBR_DOUBLE returns a double precision floating point number - * DBR_STS_STRING returns a string status structure (dbr_sts_string) - * DBR_STS_SHORT returns a short status structure (dbr_sts_short) - * DBR_STS_INT returns a short status structure (dbr_sts_int) - * DBR_STS_FLOAT returns a float status structure (dbr_sts_float) - * DBR_STS_ENUM returns an enum status structure (dbr_sts_enum) - * DBR_STS_CHAR returns a char status structure (dbr_sts_char) - * DBR_STS_LONG returns a long status structure (dbr_sts_long) - * DBR_STS_DOUBLE returns a double status structure (dbr_sts_double) - * DBR_TIME_STRING returns a string time structure (dbr_time_string) - * DBR_TIME_SHORT returns a short time structure (dbr_time_short) - * DBR_TIME_INT returns a short time structure (dbr_time_short) - * DBR_TIME_FLOAT returns a float time structure (dbr_time_float) - * DBR_TIME_ENUM returns an enum time structure (dbr_time_enum) - * DBR_TIME_CHAR returns a char time structure (dbr_time_char) - * DBR_TIME_LONG returns a long time structure (dbr_time_long) - * DBR_TIME_DOUBLE returns a double time structure (dbr_time_double) - * DBR_GR_STRING returns a graphic string structure (dbr_gr_string) - * DBR_GR_SHORT returns a graphic short structure (dbr_gr_short) - * DBR_GR_INT returns a graphic short structure (dbr_gr_int) - * DBR_GR_FLOAT returns a graphic float structure (dbr_gr_float) - * DBR_GR_ENUM returns a graphic enum structure (dbr_gr_enum) - * DBR_GR_CHAR returns a graphic char structure (dbr_gr_char) - * DBR_GR_LONG returns a graphic long structure (dbr_gr_long) - * DBR_GR_DOUBLE returns a graphic double structure (dbr_gr_double) - * DBR_CTRL_STRING returns a control string structure (dbr_ctrl_int) - * DBR_CTRL_SHORT returns a control short structure (dbr_ctrl_short) - * DBR_CTRL_INT returns a control short structure (dbr_ctrl_int) - * DBR_CTRL_FLOAT returns a control float structure (dbr_ctrl_float) - * DBR_CTRL_ENUM returns a control enum structure (dbr_ctrl_enum) - * DBR_CTRL_CHAR returns a control char structure (dbr_ctrl_char) - * DBR_CTRL_LONG returns a control long structure (dbr_ctrl_long) - * DBR_CTRL_DOUBLE returns a control double structure (dbr_ctrl_double) - */ -#endif /*db_accessHFORdb_accessC*/ - -/* VALUES WITH STATUS STRUCTURES */ - -/* structure for a string status field */ -struct dbr_sts_string { - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_string_t value; /* current value */ -}; - -/* structure for a string status and ack field */ -struct dbr_stsack_string{ - dbr_ushort_t status; /* status of value */ - dbr_ushort_t severity; /* severity of alarm */ - dbr_ushort_t ackt; /* ack transient? */ - dbr_ushort_t acks; /* ack severity */ - dbr_string_t value; /* current value */ -}; -/* structure for an short status field */ -struct dbr_sts_int{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_short_t value; /* current value */ -}; -struct dbr_sts_short{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_short_t value; /* current value */ -}; - -/* structure for a float status field */ -struct dbr_sts_float{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_float_t value; /* current value */ -}; - -/* structure for a enum status field */ -struct dbr_sts_enum{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_enum_t value; /* current value */ -}; - -/* structure for a char status field */ -struct dbr_sts_char{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_char_t RISC_pad; /* RISC alignment */ - dbr_char_t value; /* current value */ -}; - -/* structure for a long status field */ -struct dbr_sts_long{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_long_t value; /* current value */ -}; - -/* structure for a double status field */ -struct dbr_sts_double{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_long_t RISC_pad; /* RISC alignment */ - dbr_double_t value; /* current value */ -}; - -/* VALUES WITH STATUS AND TIME STRUCTURES */ - -/* structure for a string time field */ -struct dbr_time_string{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - epicsTimeStamp stamp; /* time stamp */ - dbr_string_t value; /* current value */ -}; - -/* structure for an short time field */ -struct dbr_time_short{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - epicsTimeStamp stamp; /* time stamp */ - dbr_short_t RISC_pad; /* RISC alignment */ - dbr_short_t value; /* current value */ -}; - -/* structure for a float time field */ -struct dbr_time_float{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - epicsTimeStamp stamp; /* time stamp */ - dbr_float_t value; /* current value */ -}; - -/* structure for a enum time field */ -struct dbr_time_enum{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - epicsTimeStamp stamp; /* time stamp */ - dbr_short_t RISC_pad; /* RISC alignment */ - dbr_enum_t value; /* current value */ -}; - -/* structure for a char time field */ -struct dbr_time_char{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - epicsTimeStamp stamp; /* time stamp */ - dbr_short_t RISC_pad0; /* RISC alignment */ - dbr_char_t RISC_pad1; /* RISC alignment */ - dbr_char_t value; /* current value */ -}; - -/* structure for a long time field */ -struct dbr_time_long{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - epicsTimeStamp stamp; /* time stamp */ - dbr_long_t value; /* current value */ -}; - -/* structure for a double time field */ -struct dbr_time_double{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - epicsTimeStamp stamp; /* time stamp */ - dbr_long_t RISC_pad; /* RISC alignment */ - dbr_double_t value; /* current value */ -}; - -/* VALUES WITH STATUS AND GRAPHIC STRUCTURES */ - -/* structure for a graphic string */ - /* not implemented; use struct_dbr_sts_string */ - -/* structure for a graphic short field */ -struct dbr_gr_int{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_short_t upper_disp_limit; /* upper limit of graph */ - dbr_short_t lower_disp_limit; /* lower limit of graph */ - dbr_short_t upper_alarm_limit; - dbr_short_t upper_warning_limit; - dbr_short_t lower_warning_limit; - dbr_short_t lower_alarm_limit; - dbr_short_t value; /* current value */ -}; -struct dbr_gr_short{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_short_t upper_disp_limit; /* upper limit of graph */ - dbr_short_t lower_disp_limit; /* lower limit of graph */ - dbr_short_t upper_alarm_limit; - dbr_short_t upper_warning_limit; - dbr_short_t lower_warning_limit; - dbr_short_t lower_alarm_limit; - dbr_short_t value; /* current value */ -}; - -/* structure for a graphic floating point field */ -struct dbr_gr_float{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_short_t precision; /* number of decimal places */ - dbr_short_t RISC_pad0; /* RISC alignment */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_float_t upper_disp_limit; /* upper limit of graph */ - dbr_float_t lower_disp_limit; /* lower limit of graph */ - dbr_float_t upper_alarm_limit; - dbr_float_t upper_warning_limit; - dbr_float_t lower_warning_limit; - dbr_float_t lower_alarm_limit; - dbr_float_t value; /* current value */ -}; - -/* structure for a graphic enumeration field */ -struct dbr_gr_enum{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_short_t no_str; /* number of strings */ - char strs[MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]; - /* state strings */ - dbr_enum_t value; /* current value */ -}; - -/* structure for a graphic char field */ -struct dbr_gr_char{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_char_t upper_disp_limit; /* upper limit of graph */ - dbr_char_t lower_disp_limit; /* lower limit of graph */ - dbr_char_t upper_alarm_limit; - dbr_char_t upper_warning_limit; - dbr_char_t lower_warning_limit; - dbr_char_t lower_alarm_limit; - dbr_char_t RISC_pad; /* RISC alignment */ - dbr_char_t value; /* current value */ -}; - -/* structure for a graphic long field */ -struct dbr_gr_long{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_long_t upper_disp_limit; /* upper limit of graph */ - dbr_long_t lower_disp_limit; /* lower limit of graph */ - dbr_long_t upper_alarm_limit; - dbr_long_t upper_warning_limit; - dbr_long_t lower_warning_limit; - dbr_long_t lower_alarm_limit; - dbr_long_t value; /* current value */ -}; - -/* structure for a graphic double field */ -struct dbr_gr_double{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_short_t precision; /* number of decimal places */ - dbr_short_t RISC_pad0; /* RISC alignment */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_double_t upper_disp_limit; /* upper limit of graph */ - dbr_double_t lower_disp_limit; /* lower limit of graph */ - dbr_double_t upper_alarm_limit; - dbr_double_t upper_warning_limit; - dbr_double_t lower_warning_limit; - dbr_double_t lower_alarm_limit; - dbr_double_t value; /* current value */ -}; - -/* VALUES WITH STATUS, GRAPHIC and CONTROL STRUCTURES */ - -/* structure for a control string */ - /* not implemented; use struct_dbr_sts_string */ - -/* structure for a control integer */ -struct dbr_ctrl_int{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_short_t upper_disp_limit; /* upper limit of graph */ - dbr_short_t lower_disp_limit; /* lower limit of graph */ - dbr_short_t upper_alarm_limit; - dbr_short_t upper_warning_limit; - dbr_short_t lower_warning_limit; - dbr_short_t lower_alarm_limit; - dbr_short_t upper_ctrl_limit; /* upper control limit */ - dbr_short_t lower_ctrl_limit; /* lower control limit */ - dbr_short_t value; /* current value */ -}; -struct dbr_ctrl_short{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_short_t upper_disp_limit; /* upper limit of graph */ - dbr_short_t lower_disp_limit; /* lower limit of graph */ - dbr_short_t upper_alarm_limit; - dbr_short_t upper_warning_limit; - dbr_short_t lower_warning_limit; - dbr_short_t lower_alarm_limit; - dbr_short_t upper_ctrl_limit; /* upper control limit */ - dbr_short_t lower_ctrl_limit; /* lower control limit */ - dbr_short_t value; /* current value */ -}; - -/* structure for a control floating point field */ -struct dbr_ctrl_float{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_short_t precision; /* number of decimal places */ - dbr_short_t RISC_pad; /* RISC alignment */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_float_t upper_disp_limit; /* upper limit of graph */ - dbr_float_t lower_disp_limit; /* lower limit of graph */ - dbr_float_t upper_alarm_limit; - dbr_float_t upper_warning_limit; - dbr_float_t lower_warning_limit; - dbr_float_t lower_alarm_limit; - dbr_float_t upper_ctrl_limit; /* upper control limit */ - dbr_float_t lower_ctrl_limit; /* lower control limit */ - dbr_float_t value; /* current value */ -}; - -/* structure for a control enumeration field */ -struct dbr_ctrl_enum{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_short_t no_str; /* number of strings */ - char strs[MAX_ENUM_STATES][MAX_ENUM_STRING_SIZE]; - /* state strings */ - dbr_enum_t value; /* current value */ -}; - -/* structure for a control char field */ -struct dbr_ctrl_char{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_char_t upper_disp_limit; /* upper limit of graph */ - dbr_char_t lower_disp_limit; /* lower limit of graph */ - dbr_char_t upper_alarm_limit; - dbr_char_t upper_warning_limit; - dbr_char_t lower_warning_limit; - dbr_char_t lower_alarm_limit; - dbr_char_t upper_ctrl_limit; /* upper control limit */ - dbr_char_t lower_ctrl_limit; /* lower control limit */ - dbr_char_t RISC_pad; /* RISC alignment */ - dbr_char_t value; /* current value */ -}; - -/* structure for a control long field */ -struct dbr_ctrl_long{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_long_t upper_disp_limit; /* upper limit of graph */ - dbr_long_t lower_disp_limit; /* lower limit of graph */ - dbr_long_t upper_alarm_limit; - dbr_long_t upper_warning_limit; - dbr_long_t lower_warning_limit; - dbr_long_t lower_alarm_limit; - dbr_long_t upper_ctrl_limit; /* upper control limit */ - dbr_long_t lower_ctrl_limit; /* lower control limit */ - dbr_long_t value; /* current value */ -}; - -/* structure for a control double field */ -struct dbr_ctrl_double{ - dbr_short_t status; /* status of value */ - dbr_short_t severity; /* severity of alarm */ - dbr_short_t precision; /* number of decimal places */ - dbr_short_t RISC_pad0; /* RISC alignment */ - char units[MAX_UNITS_SIZE]; /* units of value */ - dbr_double_t upper_disp_limit; /* upper limit of graph */ - dbr_double_t lower_disp_limit; /* lower limit of graph */ - dbr_double_t upper_alarm_limit; - dbr_double_t upper_warning_limit; - dbr_double_t lower_warning_limit; - dbr_double_t lower_alarm_limit; - dbr_double_t upper_ctrl_limit; /* upper control limit */ - dbr_double_t lower_ctrl_limit; /* lower control limit */ - dbr_double_t value; /* current value */ -}; - -#define dbr_size_n(TYPE,COUNT)\ -((unsigned)((COUNT)<=0?dbr_size[TYPE]:dbr_size[TYPE]+((COUNT)-1)*dbr_value_size[TYPE])) - -/* size for each type - array indexed by the DBR_ type code */ -epicsShareExtern const unsigned short dbr_size[]; - -/* size for each type's value - array indexed by the DBR_ type code */ -epicsShareExtern const unsigned short dbr_value_size[]; - -#ifndef db_accessHFORdb_accessC -/* class for each type's value */ -enum dbr_value_class { - dbr_class_int, - dbr_class_float, - dbr_class_string, - dbr_class_max}; - -epicsShareExtern const enum dbr_value_class dbr_value_class[LAST_BUFFER_TYPE+1]; - -/* - * ptr to value given a pointer to the structure and the DBR type - */ -#define dbr_value_ptr(PDBR, DBR_TYPE) \ -((void *)(((char *)PDBR)+dbr_value_offset[DBR_TYPE])) - -/* - * ptr to value given a pointer to the structure and the structure declaration - */ -#define dbr_value_ptr_from_structure(PDBR, STRUCTURE)\ -((void *)(((char *)PDBR)+BYTE_OS(STRUCTURE, value))) - -epicsShareExtern const unsigned short dbr_value_offset[LAST_BUFFER_TYPE+1]; - - -/* union for each fetch buffers */ -union db_access_val{ - dbr_string_t strval; /* string max size */ - dbr_short_t shrtval; /* short */ - dbr_short_t intval; /* short */ - dbr_float_t fltval; /* IEEE Float */ - dbr_enum_t enmval; /* item number */ - dbr_char_t charval; /* character */ - dbr_long_t longval; /* long */ - dbr_double_t doubleval; /* double */ - struct dbr_sts_string sstrval; /* string field with status */ - struct dbr_sts_short sshrtval; /* short field with status */ - struct dbr_sts_float sfltval; /* float field with status */ - struct dbr_sts_enum senmval; /* item number with status */ - struct dbr_sts_char schrval; /* char field with status */ - struct dbr_sts_long slngval; /* long field with status */ - struct dbr_sts_double sdblval; /* double field with time */ - struct dbr_time_string tstrval; /* string field with time */ - struct dbr_time_short tshrtval; /* short field with time */ - struct dbr_time_float tfltval; /* float field with time */ - struct dbr_time_enum tenmval; /* item number with time */ - struct dbr_time_char tchrval; /* char field with time */ - struct dbr_time_long tlngval; /* long field with time */ - struct dbr_time_double tdblval; /* double field with time */ - struct dbr_sts_string gstrval; /* graphic string info */ - struct dbr_gr_short gshrtval; /* graphic short info */ - struct dbr_gr_float gfltval; /* graphic float info */ - struct dbr_gr_enum genmval; /* graphic item info */ - struct dbr_gr_char gchrval; /* graphic char info */ - struct dbr_gr_long glngval; /* graphic long info */ - struct dbr_gr_double gdblval; /* graphic double info */ - struct dbr_sts_string cstrval; /* control string info */ - struct dbr_ctrl_short cshrtval; /* control short info */ - struct dbr_ctrl_float cfltval; /* control float info */ - struct dbr_ctrl_enum cenmval; /* control item info */ - struct dbr_ctrl_char cchrval; /* control char info */ - struct dbr_ctrl_long clngval; /* control long info */ - struct dbr_ctrl_double cdblval; /* control double info */ - dbr_put_ackt_t putackt; /* item number */ - dbr_put_acks_t putacks; /* item number */ - struct dbr_sts_string sastrval; /* string field with status */ - dbr_string_t classname; /* string max size */ -}; - -/*---------------------------------------------------------------------------- -* repository for some useful PV database constants and utilities -* -* item dimensions -* db_strval_dim dimension for string values -* db_units_dim dimension for record units text -* db_desc_dim dimension for record description text -* db_name_dim dimension for channel names (record.field\0) -* db_state_dim number of states possible in a state table -* db_state_text_dim dimension for a state text string -* usage: char state_table[db_state_dim][db_state_text_dim] -* -* type checking macros -- return non-zero if condition is true, zero otherwise -* -* int dbf_type_is_valid(type) type is a valid DBF_xxx -* int dbr_type_is_valid(type) type is a valid DBR_xxx -* int dbr_type_is_plain(type) type is a valid plain DBR_xxx -* int dbr_type_is_STS(type) type is a valid DBR_STS_xxx -* int dbr_type_is_TIME(type) type is a valid DBR_TIME_xxx -* int dbr_type_is_GR(type) type is a valid DBR_GR_xxx -* int dbr_type_is_CTRL(type) type is a valid DBR_CTRL_xxx -* int dbr_type_is_STRING(type) type is a valid DBR_STRING_xxx -* int dbr_type_is_SHORT(type) type is a valid DBR_SHORT_xxx -* int dbr_type_is_FLOAT(type) type is a valid DBR_FLOAT_xxx -* int dbr_type_is_ENUM(type) type is a valid DBR_ENUM_xxx -* int dbr_type_is_CHAR(type) type is a valid DBR_CHAR_xxx -* int dbr_type_is_LONG(type) type is a valid DBR_LONG_xxx -* int dbr_type_is_DOUBLE(type) type is a valid DBR_DOUBLE_xxx -* -* type conversion macros -* -* char *dbf_type_to_text(type) returns text matching DBF_xxx -* void dbf_text_to_type(text, type) finds DBF_xxx matching text -* int dbf_type_to_DBR(type) returns DBR_xxx matching DBF_xxx -* int dbf_type_to_DBR_TIME(type) returns DBR_TIME_xxx matching DBF_xxx -* int dbf_type_to_DBR_GR(type) returns DBR_GR_xxx matching DBF_xxx -* int dbf_type_to_DBR_CTRL(type) returns DBR_CTRL_xxx matching DBF_xxx -* char *dbr_type_to_text(type) returns text matching DBR_xxx -* void dbr_text_to_type(text, type) finds DBR_xxx matching text -*---------------------------------------------------------------------------*/ -#define db_strval_dim MAX_STRING_SIZE -#define db_units_dim MAX_UNITS_SIZE -#define db_desc_dim 24 -#define db_name_dim 36 -#define db_state_dim MAX_ENUM_STATES -#define db_state_text_dim MAX_ENUM_STRING_SIZE - -#define dbf_type_is_valid(type) ((type) >= 0 && (type) <= LAST_TYPE) -#define dbr_type_is_valid(type) ((type) >= 0 && (type) <= LAST_BUFFER_TYPE) -#define dbr_type_is_plain(type) \ - ((type) >= DBR_STRING && (type) <= DBR_DOUBLE) -#define dbr_type_is_STS(type) \ - ((type) >= DBR_STS_STRING && (type) <= DBR_STS_DOUBLE) -#define dbr_type_is_TIME(type) \ - ((type) >= DBR_TIME_STRING && (type) <= DBR_TIME_DOUBLE) -#define dbr_type_is_GR(type) \ - ((type) >= DBR_GR_STRING && (type) <= DBR_GR_DOUBLE) -#define dbr_type_is_CTRL(type) \ - ((type) >= DBR_CTRL_STRING && (type) <= DBR_CTRL_DOUBLE) -#define dbr_type_is_STRING(type) \ - ((type) >= 0 && (type) <= LAST_BUFFER_TYPE && \ - (type)%(LAST_TYPE+1) == DBR_STRING) -#define dbr_type_is_SHORT(type) \ - ((type) >= 0 && (type) <= LAST_BUFFER_TYPE && \ - (type)%(LAST_TYPE+1) == DBR_SHORT) -#define dbr_type_is_FLOAT(type) \ - ((type) >= 0 && (type) <= LAST_BUFFER_TYPE && \ - (type)%(LAST_TYPE+1) == DBR_FLOAT) -#define dbr_type_is_ENUM(type) \ - ((type) >= 0 && (type) <= LAST_BUFFER_TYPE && \ - (type)%(LAST_TYPE+1) == DBR_ENUM) -#define dbr_type_is_CHAR(type) \ - ((type) >= 0 && (type) <= LAST_BUFFER_TYPE && \ - (type)%(LAST_TYPE+1) == DBR_CHAR) -#define dbr_type_is_LONG(type) \ - ((type) >= 0 && (type) <= LAST_BUFFER_TYPE && \ - (type)%(LAST_TYPE+1) == DBR_LONG) -#define dbr_type_is_DOUBLE(type) \ - ((type) >= 0 && (type) <= LAST_BUFFER_TYPE && \ - (type)%(LAST_TYPE+1) == DBR_DOUBLE) - -#define dbf_type_to_text(type) \ - ( ((type) >= -1 && (type) < dbf_text_dim-2) ? \ - dbf_text[type+1] : dbf_text_invalid ) - -#define dbf_text_to_type(text, type) \ - for (type=dbf_text_dim-3; type>=0; type--) { \ - if (strcmp(text, dbf_text[type+1]) == 0) \ - break; \ - } - -#define dbr_type_to_text(type) \ - ( ((type) >= 0 && (type) < dbr_text_dim) ? \ - dbr_text[(type)] : dbr_text_invalid ) - -#define dbr_text_to_type(text, type) \ - for (type=dbr_text_dim-2; type>=0; type--) { \ - if (strcmp(text, dbr_text[type]) == 0) \ - break; \ - } - -#define dbf_type_to_DBR(type) \ - (((type) >= 0 && (type) <= dbf_text_dim-3) ? \ - (type) : -1 ) - -#define dbf_type_to_DBR_STS(type) \ - (((type) >= 0 && (type) <= dbf_text_dim-3) ? \ - (type) + (dbf_text_dim-2) : -1 ) - -#define dbf_type_to_DBR_TIME(type) \ - (((type) >= 0 && (type) <= dbf_text_dim-3) ? \ - (type) + 2*(dbf_text_dim-2) : -1 ) - -#define dbf_type_to_DBR_GR(type) \ - (((type) >= 0 && (type) <= dbf_text_dim-3) ? \ - (type) + 3*(dbf_text_dim-2) : -1 ) - -#define dbf_type_to_DBR_CTRL(type) \ - (((type) >= 0 && (type) <= dbf_text_dim-3) ? \ - (type) + 4*(dbf_text_dim-2) : -1 ) - - -epicsShareExtern const char *dbf_text[LAST_TYPE+3]; -epicsShareExtern const short dbf_text_dim; -epicsShareExtern const char *dbf_text_invalid; - -epicsShareExtern const char *dbr_text[LAST_BUFFER_TYPE+1]; -epicsShareExtern const short dbr_text_dim; -epicsShareExtern const char *dbr_text_invalid; -#endif /*db_accessHFORdb_accessC*/ - -#ifdef __cplusplus -} -#endif - -#endif /* INCLdb_accessh */ diff --git a/src/ca/client/disconnectGovernorTimer.cpp b/src/ca/client/disconnectGovernorTimer.cpp deleted file mode 100644 index f1d517f07..000000000 --- a/src/ca/client/disconnectGovernorTimer.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// -// L O S A L A M O S -// Los Alamos National Laboratory -// Los Alamos, New Mexico 87545 -// -// Copyright, 1986, The Regents of the University of California. -// -// Author: Jeff Hill -// - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#define epicsExportSharedSymbols -#include "disconnectGovernorTimer.h" -#include "udpiiu.h" -#include "nciu.h" - -static const double disconnectGovernorPeriod = 10.0; // sec - -disconnectGovernorTimer::disconnectGovernorTimer ( - disconnectGovernorNotify & iiuIn, - epicsTimerQueue & queueIn, - epicsMutex & mutexIn ) : - mutex ( mutexIn ), timer ( queueIn.createTimer () ), - iiu ( iiuIn ) -{ -} - -disconnectGovernorTimer::~disconnectGovernorTimer () -{ - this->timer.destroy (); -} - -void disconnectGovernorTimer:: start () -{ - this->timer.start ( *this, disconnectGovernorPeriod ); -} - -void disconnectGovernorTimer::shutdown ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - { - epicsGuardRelease < epicsMutex > cbUnguard ( cbGuard ); - this->timer.cancel (); - } - } - while ( nciu * pChan = this->chanList.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - pChan->serviceShutdownNotify ( cbGuard, guard ); - } -} - -epicsTimerNotify::expireStatus disconnectGovernorTimer::expire ( - const epicsTime & /* currentTime */ ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - while ( nciu * pChan = chanList.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - this->iiu.govExpireNotify ( guard, *pChan ); - } - return expireStatus ( restart, disconnectGovernorPeriod ); -} - -void disconnectGovernorTimer::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - ::printf ( "disconnect governor timer: with %u channels pending\n", - this->chanList.count () ); - if ( level > 0u ) { - tsDLIterConst < nciu > pChan = this->chanList.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 1u ); - pChan++; - } - } -} - -void disconnectGovernorTimer::installChan ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->chanList.add ( chan ); - chan.channelNode::listMember = channelNode::cs_disconnGov; -} - -void disconnectGovernorTimer::uninstallChan ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->chanList.remove ( chan ); - chan.channelNode::listMember = channelNode::cs_none; -} - -disconnectGovernorNotify::~disconnectGovernorNotify () {} - diff --git a/src/ca/client/disconnectGovernorTimer.h b/src/ca/client/disconnectGovernorTimer.h deleted file mode 100644 index f636d6260..000000000 --- a/src/ca/client/disconnectGovernorTimer.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// -// -// L O S A L A M O S -// Los Alamos National Laboratory -// Los Alamos, New Mexico 87545 -// -// Copyright, 1986, The Regents of the University of California. -// -// -// Author Jeffrey O. Hill -// johill@lanl.gov -// 505 665 1831 -// - -#ifndef disconnectGovernorTimerh -#define disconnectGovernorTimerh - -#ifdef epicsExportSharedSymbols -# define searchTimerh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsTimer.h" - -#ifdef searchTimerh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "caProto.h" -#include "netiiu.h" - -class disconnectGovernorNotify { -public: - virtual ~disconnectGovernorNotify () = 0; - virtual void govExpireNotify ( - epicsGuard < epicsMutex > &, nciu & ) = 0; -}; - -class disconnectGovernorTimer : private epicsTimerNotify { -public: - disconnectGovernorTimer ( - class disconnectGovernorNotify &, epicsTimerQueue &, epicsMutex & ); - virtual ~disconnectGovernorTimer (); - void start (); - void shutdown ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void installChan ( - epicsGuard < epicsMutex > &, nciu & ); - void uninstallChan ( - epicsGuard < epicsMutex > &, nciu & ); - void show ( unsigned level ) const; -private: - tsDLList < nciu > chanList; - epicsMutex & mutex; - epicsTimer & timer; - class disconnectGovernorNotify & iiu; - epicsTimerNotify::expireStatus expire ( const epicsTime & currentTime ); - disconnectGovernorTimer ( const disconnectGovernorTimer & ); - disconnectGovernorTimer & operator = ( const disconnectGovernorTimer & ); -}; - -#endif // ifdef disconnectGovernorTimerh diff --git a/src/ca/client/evtime.c b/src/ca/client/evtime.c deleted file mode 100644 index d5cf58382..000000000 --- a/src/ca/client/evtime.c +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "dbDefs.h" -#include "epicsTime.h" -#include "cadef.h" - -void event_handler (struct event_handler_args args); -int evtime (char *pname); - -static unsigned iteration_count; -static epicsUInt32 last_time; - -#ifndef iocCore -int main(int argc, char **argv) -{ - char *pname; - - if(argc == 2){ - pname = argv[1]; - evtime(pname); - } - else{ - printf("usage: %s ", argv[0]); - } - return(0); -} -#endif - -/* - * evtime() - */ -int evtime(char *pname) -{ - chid chan; - int status; - - status = ca_search(pname, &chan); - SEVCHK(status, NULL); - - status = ca_pend_io(10.0); - if(status != ECA_NORMAL){ - printf("%s not found\n", pname); - return 0; - } - - status = ca_add_event( - DBR_FLOAT, - chan, - event_handler, - NULL, - NULL); - SEVCHK(status, __FILE__); - - status = ca_pend_event(0.0); - SEVCHK(status, NULL); -} - - -/* - * event_handler() - * - */ -void event_handler(struct event_handler_args args) -{ - epicsUInt32 current_time; -# define COUNT 0x8000 - double interval; - double delay; - epicsTimeStamp ts; - - if(iteration_count%COUNT == 0){ - epicsTimeGetCurrent(&ts); - current_time = ts.secPastEpoch; - if(last_time != 0){ - interval = current_time - last_time; - delay = interval/COUNT; - printf("Delay = %f sec per event\n", - delay); - } - last_time = current_time; - } - - iteration_count++; -} - diff --git a/src/ca/client/future_work.txt b/src/ca/client/future_work.txt deleted file mode 100644 index 3f3cb3317..000000000 --- a/src/ca/client/future_work.txt +++ /dev/null @@ -1,38 +0,0 @@ - -Potential upgrades to Channel Access - -o generalized access to abstract data -o use multicast for broadcasting and ax the repeater -o improve client API -o improve security -o name service (wildcard queries) -o PV name prefix (for all PVs) -o client access to process passive and for maximize severity -o detect name conflicts at boot time -o multi priority connections (quality of service) -o reduce protocol overhead -o compressed protocol - - -o If there is a beacon anomaly then this indicates that -the server is _not_ available. Perhaps we should only -reset the search timer interval when we see a beacon -anomaly transition into a sure steady beacon. - -o make certain that a monitor callback canceling itself -does not deadlock. - -o the free list library does not now cause exceptions to -occur (it uses new ( nothrow )), and therefore we should -change the new handlers to be nothrow also if this is -the design goal. - -o test the library when an IOC is running low on memory. - -o The new CA interface should be multi-threaded by default. -We should continue to support a single-threaded interface, -but this would should be restricted so that it always -runs with preemptive callback disable and no threads -may join in. Alternatively, the new CA interface could -be 100% preemptive multi-threaded and the old interface -could be layered on this. diff --git a/src/ca/client/getCallback.cpp b/src/ca/client/getCallback.cpp deleted file mode 100644 index 0fc050043..000000000 --- a/src/ca/client/getCallback.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "oldAccess.h" - -getCallback::getCallback ( oldChannelNotify & chanIn, - caEventCallBackFunc *pFuncIn, void *pPrivateIn ) : - chan ( chanIn ), pFunc ( pFuncIn ), pPrivate ( pPrivateIn ) -{ -} - -getCallback::~getCallback () -{ -} - -void getCallback::completion ( - epicsGuard < epicsMutex > & guard, - unsigned type, arrayElementCount count, const void *pData ) -{ - struct event_handler_args args; - args.usr = this->pPrivate; - args.chid = & this->chan; - args.type = type; - args.count = count; - args.status = ECA_NORMAL; - args.dbr = pData; - caEventCallBackFunc * pFuncTmp = this->pFunc; - // fetch client context and destroy prior to releasing - // the lock and calling cb in case they destroy channel there - this->chan.getClientCtx().destroyGetCallback ( guard, *this ); - if ( pFuncTmp ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - pFuncTmp ( args ); - } -} - -void getCallback::exception ( - epicsGuard < epicsMutex > & guard, - int status, const char * /* pContext */, - unsigned type, arrayElementCount count ) -{ - if ( status != ECA_CHANDESTROY ) { - struct event_handler_args args; - args.usr = this->pPrivate; - args.chid = & this->chan; - args.type = type; - args.count = count; - args.status = status; - args.dbr = 0; - caEventCallBackFunc * pFuncTmp = this->pFunc; - // fetch client context and destroy prior to releasing - // the lock and calling cb in case they destroy channel there - this->chan.getClientCtx().destroyGetCallback ( guard, *this ); - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - ( *pFuncTmp ) ( args ); - } - } - else { - this->chan.getClientCtx().destroyGetCallback ( guard, *this ); - } -} - -void getCallback::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - - diff --git a/src/ca/client/getCopy.cpp b/src/ca/client/getCopy.cpp deleted file mode 100644 index 23a508d9a..000000000 --- a/src/ca/client/getCopy.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#include "errlog.h" - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "oldAccess.h" -#include "cac.h" - -getCopy::getCopy ( - epicsGuard < epicsMutex > & guard, ca_client_context & cacCtxIn, - oldChannelNotify & chanIn, unsigned typeIn, - arrayElementCount countIn, void * pValueIn ) : - count ( countIn ), cacCtx ( cacCtxIn ), chan ( chanIn ), pValue ( pValueIn ), - ioSeqNo ( 0 ), type ( typeIn ) -{ - this->ioSeqNo = cacCtxIn.sequenceNumberOfOutstandingIO ( guard ); - cacCtxIn.incrementOutstandingIO ( guard, this->ioSeqNo ); -} - -getCopy::~getCopy () -{ -} - -void getCopy::cancel () -{ - epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef () ); - this->cacCtx.decrementOutstandingIO ( guard, this->ioSeqNo ); -} - -void getCopy::completion ( - epicsGuard < epicsMutex > & guard, unsigned typeIn, - arrayElementCount countIn, const void *pDataIn ) -{ - if ( this->type == typeIn ) { - unsigned size = dbr_size_n ( typeIn, countIn ); - memcpy ( this->pValue, pDataIn, size ); - this->cacCtx.decrementOutstandingIO ( guard, this->ioSeqNo ); - this->cacCtx.destroyGetCopy ( guard, *this ); - // this object destroyed by preceding function call - } - else { - this->exception ( guard, ECA_INTERNAL, - "bad data type match in get copy back response", - typeIn, countIn); - // this object destroyed by preceding function call - } -} - -void getCopy::exception ( - epicsGuard < epicsMutex > & guard, - int status, const char *pContext, - unsigned /* typeIn */, arrayElementCount /* countIn */ ) -{ - oldChannelNotify & chanTmp ( this->chan ); - unsigned typeTmp ( this->type ); - arrayElementCount countTmp ( this->count ); - ca_client_context & caClientCtx ( this->cacCtx ); - // fetch client context and destroy prior to releasing - // the lock and calling cb in case they destroy channel there - this->cacCtx.destroyGetCopy ( guard, *this ); - if ( status != ECA_CHANDESTROY ) { - caClientCtx.exception ( guard, status, pContext, - __FILE__, __LINE__, chanTmp, typeTmp, - countTmp, CA_OP_GET ); - } -} - -void getCopy::show ( unsigned level ) const -{ - int tmpType = static_cast ( this->type ); - ::printf ( "read copy IO at %p, type %s, element count %lu\n", - static_cast ( this ), dbf_type_to_text ( tmpType ), this->count ); - if ( level > 0u ) { - ::printf ( "\tIO sequence number %u, user's storage %p\n", - this->ioSeqNo, static_cast ( this->pValue ) ); - } -} - -void getCopy::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - diff --git a/src/ca/client/hostNameCache.cpp b/src/ca/client/hostNameCache.cpp deleted file mode 100644 index c3d105c06..000000000 --- a/src/ca/client/hostNameCache.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" -#include "hostNameCache.h" -#include "epicsGuard.h" - -hostNameCache::hostNameCache ( - const osiSockAddr & addr, ipAddrToAsciiEngine & engine ) : - dnsTransaction ( engine.createTransaction() ), nameLength ( 0 ) -{ - sockAddrToDottedIP ( &addr.sa, hostNameBuf, sizeof ( hostNameBuf ) ); - hostNameBuf[ sizeof ( hostNameBuf ) - 1 ] = '\0'; - nameLength = strlen ( hostNameBuf ); - this->dnsTransaction.ipAddrToAscii ( addr, *this ); -} - -void hostNameCache::destroy () -{ - delete this; -} - -hostNameCache::~hostNameCache () -{ - this->dnsTransaction.release (); -} - -void hostNameCache::transactionComplete ( const char * pHostNameIn ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - // a few legacy clients have a direct pointer to this buffer so we - // set the entrire string to nill terminators before we start copying - // in the name (this reduces the chance that another thread will see - // garbage characters). - size_t newNameLen = strlen ( pHostNameIn ); - if ( newNameLen > sizeof ( this->hostNameBuf ) - 1u ) { - newNameLen = sizeof ( this->hostNameBuf ) - 1u; - } - strncpy ( this->hostNameBuf, "", sizeof ( this->hostNameBuf ) ); - strncpy ( this->hostNameBuf, pHostNameIn, sizeof ( this->hostNameBuf ) - 1 ); - this->nameLength = newNameLen; -} - -unsigned hostNameCache::getName ( - char * pBuf, unsigned bufSize ) const -{ - if ( bufSize == 0u ) { - return 0u; - } - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->nameLength > 0u ) { - if ( this->nameLength < bufSize ) { - strcpy ( pBuf, this->hostNameBuf ); - return this->nameLength; - } - else { - unsigned reducedSize = bufSize - 1u; - strncpy ( pBuf, this->hostNameBuf, reducedSize ); - pBuf [ reducedSize ] = '\0'; - return reducedSize; - } - } - else { - osiSockAddr tmpAddr = this->dnsTransaction.address (); - return sockAddrToDottedIP ( &tmpAddr.sa, pBuf, bufSize ); - } -} - diff --git a/src/ca/client/hostNameCache.h b/src/ca/client/hostNameCache.h deleted file mode 100644 index a4eacfbb3..000000000 --- a/src/ca/client/hostNameCache.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef hostNameCacheh -#define hostNameCacheh - -#ifdef epicsExportSharedSymbols -# define hostNameCache_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "ipAddrToAsciiAsynchronous.h" -#include "epicsMutex.h" - -#ifdef hostNameCache_epicsExportSharedSymbols -# define epicsExportSharedSymbols -#endif - -class hostNameCache : public ipAddrToAsciiCallBack { -public: - hostNameCache ( const osiSockAddr & addr, ipAddrToAsciiEngine & engine ); - ~hostNameCache (); - void destroy (); - void transactionComplete ( const char * pHostName ); - unsigned getName ( char *pBuf, unsigned bufLength ) const; - const char * pointer () const; -private: - char hostNameBuf [128]; - mutable epicsMutex mutex; - ipAddrToAsciiTransaction & dnsTransaction; - unsigned nameLength; -}; - -inline const char * hostNameCache::pointer () const -{ - return this->hostNameBuf; -} - -#endif // #ifndef hostNameCacheh diff --git a/src/ca/client/inetAddrID.h b/src/ca/client/inetAddrID.h deleted file mode 100644 index 978787599..000000000 --- a/src/ca/client/inetAddrID.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#ifndef inetAddrIDh -#define inetAddrIDh - -#include "osiSock.h" -#include "resourceLib.h" - -class inetAddrID { -public: - inetAddrID ( const struct sockaddr_in & addrIn ); - bool operator == ( const inetAddrID & ) const; - resTableIndex hash () const; - void name ( char *pBuf, unsigned bufSize ) const; -private: - struct sockaddr_in addr; -}; - -inline inetAddrID::inetAddrID ( const struct sockaddr_in & addrIn ) : - addr ( addrIn ) -{ -} - -inline bool inetAddrID::operator == ( const inetAddrID &rhs ) const -{ - if ( this->addr.sin_addr.s_addr == rhs.addr.sin_addr.s_addr ) { - if ( this->addr.sin_port == rhs.addr.sin_port ) { - return true; - } - } - return false; -} - -inline resTableIndex inetAddrID::hash () const -{ - const unsigned inetAddrMinIndexBitWidth = 8u; - const unsigned inetAddrMaxIndexBitWidth = 32u; - unsigned index; - index = this->addr.sin_addr.s_addr; - index ^= this->addr.sin_port; - index ^= this->addr.sin_port >> 8u; - return integerHash ( inetAddrMinIndexBitWidth, - inetAddrMaxIndexBitWidth, index ); -} - -inline void inetAddrID::name ( char *pBuf, unsigned bufSize ) const -{ - ipAddrToDottedIP ( &this->addr, pBuf, bufSize ); -} - -#endif // ifdef inetAddrID - - diff --git a/src/ca/client/iocinf.cpp b/src/ca/client/iocinf.cpp deleted file mode 100644 index 09eea292b..000000000 --- a/src/ca/client/iocinf.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include -#include -#include -#include - -#include "envDefs.h" -#include "epicsAssert.h" -#include "epicsStdioRedirect.h" -#include "errlog.h" -#include "osiWireFormat.h" - -#define epicsExportSharedSymbols -#include "addrList.h" -#undef epicsExportSharedSymbols - -#include "iocinf.h" - -/* - * getToken() - */ -static char *getToken ( const char **ppString, char *pBuf, unsigned bufSIze ) -{ - bool tokenFound = false; - const char *pToken; - unsigned i; - - pToken = *ppString; - while ( isspace (*pToken) && *pToken ){ - pToken++; - } - - for ( i=0u; iname); - fprintf ( stderr, "\tBad internet address or host name: '%s'\n", pToken); - continue; - } - - if ( ignoreNonDefaultPort && ntohs ( addr.sin_port ) != port ) { - continue; - } - - pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode)); - if (pNewNode==NULL) { - fprintf ( stderr, "addAddrToChannelAccessAddressList(): no memory available for configuration\n"); - break; - } - - pNewNode->addr.ia = addr; - - /* - * LOCK applied externally - */ - ellAdd (pList, &pNewNode->node); - ret = 0; /* success if anything is added to the list */ - } - - return ret; -} - -/* - * removeDuplicateAddresses () - */ -extern "C" void epicsShareAPI removeDuplicateAddresses - ( ELLLIST *pDestList, ELLLIST *pSrcList, int silent ) -{ - ELLNODE *pRawNode; - - while ( (pRawNode = ellGet ( pSrcList ) ) ) { - STATIC_ASSERT ( offsetof (osiSockAddrNode, node) == 0 ); - osiSockAddrNode *pNode = reinterpret_cast ( pRawNode ); - osiSockAddrNode *pTmpNode; - - if ( pNode->addr.sa.sa_family == AF_INET ) { - - pTmpNode = (osiSockAddrNode *) ellFirst (pDestList); - while ( pTmpNode ) { - if (pTmpNode->addr.sa.sa_family == AF_INET) { - if ( pNode->addr.ia.sin_addr.s_addr == pTmpNode->addr.ia.sin_addr.s_addr && - pNode->addr.ia.sin_port == pTmpNode->addr.ia.sin_port ) { - if ( ! silent ) { - char buf[64]; - ipAddrToDottedIP ( &pNode->addr.ia, buf, sizeof (buf) ); - fprintf ( stderr, - "Warning: Duplicate EPICS CA Address list entry \"%s\" discarded\n", buf ); - } - free (pNode); - pNode = NULL; - break; - } - } - pTmpNode = (osiSockAddrNode *) ellNext (&pTmpNode->node); - } - if (pNode) { - ellAdd (pDestList, &pNode->node); - } - } - else { - ellAdd (pDestList, &pNode->node); - } - } -} - -/* - * forcePort () - */ -static void forcePort ( ELLLIST *pList, unsigned short port ) -{ - osiSockAddrNode *pNode; - - pNode = ( osiSockAddrNode * ) ellFirst ( pList ); - while ( pNode ) { - if ( pNode->addr.sa.sa_family == AF_INET ) { - pNode->addr.ia.sin_port = htons ( port ); - } - pNode = ( osiSockAddrNode * ) ellNext ( &pNode->node ); - } -} - - -/* - * configureChannelAccessAddressList () - */ -extern "C" void epicsShareAPI configureChannelAccessAddressList - ( ELLLIST *pList, SOCKET sock, unsigned short port ) -{ - ELLLIST tmpList; - char *pstr; - char yesno[32u]; - int yes; - - /* - * dont load the list twice - */ - assert ( ellCount (pList) == 0 ); - - ellInit ( &tmpList ); - - /* - * Check to see if the user has disabled - * initializing the search b-cast list - * from the interfaces found. - */ - yes = true; - pstr = envGetConfigParam ( &EPICS_CA_AUTO_ADDR_LIST, - sizeof (yesno), yesno ); - if ( pstr ) { - if ( strstr ( pstr, "no" ) || strstr ( pstr, "NO" ) ) { - yes = false; - } - } - - /* - * LOCK is for piiu->destAddr list - * (lock outside because this is used by the server also) - */ - if (yes) { - ELLLIST bcastList; - osiSockAddr addr; - ellInit ( &bcastList ); - addr.ia.sin_family = AF_UNSPEC; - osiSockDiscoverBroadcastAddresses ( &bcastList, sock, &addr ); - forcePort ( &bcastList, port ); - removeDuplicateAddresses ( &tmpList, &bcastList, 1 ); - if ( ellCount ( &tmpList ) == 0 ) { - osiSockAddrNode *pNewNode; - pNewNode = (osiSockAddrNode *) calloc ( 1, sizeof (*pNewNode) ); - if ( pNewNode ) { - /* - * if no interfaces found then look for local channels - * with the loop back interface - */ - pNewNode->addr.ia.sin_family = AF_INET; - pNewNode->addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - pNewNode->addr.ia.sin_port = htons ( port ); - ellAdd ( &tmpList, &pNewNode->node ); - } - else { - errlogPrintf ( "configureChannelAccessAddressList(): no memory available for configuration\n" ); - } - } - } - addAddrToChannelAccessAddressList ( &tmpList, &EPICS_CA_ADDR_LIST, port, false ); - - removeDuplicateAddresses ( pList, &tmpList, 0 ); -} - - -/* - * printChannelAccessAddressList () - */ -extern "C" void epicsShareAPI printChannelAccessAddressList ( const ELLLIST *pList ) -{ - osiSockAddrNode *pNode; - - ::printf ( "Channel Access Address List\n" ); - pNode = (osiSockAddrNode *) ellFirst ( pList ); - while (pNode) { - char buf[64]; - ipAddrToA ( &pNode->addr.ia, buf, sizeof ( buf ) ); - ::printf ( "%s\n", buf ); - pNode = (osiSockAddrNode *) ellNext ( &pNode->node ); - } -} diff --git a/src/ca/client/iocinf.h b/src/ca/client/iocinf.h deleted file mode 100644 index 0d3b57db1..000000000 --- a/src/ca/client/iocinf.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef INCiocinfh -#define INCiocinfh - -#ifdef DEBUG -# define debugPrintf(argsInParen) ::printf argsInParen -#else -# define debugPrintf(argsInParen) -#endif - -#if defined ( CLOCKS_PER_SEC ) -# define CAC_SIGNIFICANT_DELAY ( 1.0 / CLOCKS_PER_SEC ) -#else -# define CAC_SIGNIFICANT_DELAY (1.0 / 1000000u) -#endif - -/* - * these two control the period of connection verifies - * (echo requests) - CA_CONN_VERIFY_PERIOD - and how - * long we will wait for an echo reply before we - * give up and flag the connection for disconnect - * - CA_ECHO_TIMEOUT. - * - * CA_CONN_VERIFY_PERIOD is normally obtained from an - * EPICS environment variable. - */ -static const double CA_ECHO_TIMEOUT = 5.0; /* (sec) disconn no echo reply tmo */ -static const double CA_CONN_VERIFY_PERIOD = 30.0; /* (sec) how often to request echo */ - -/* - * this determines the number of messages received - * without a delay in between before we go into - * monitor flow control - * - * turning this down effects maximum throughput - * because we dont get an optimal number of bytes - * per network frame - */ -static const unsigned contiguousMsgCountWhichTriggersFlowControl = 10u; - -/* - * CA internal functions - */ -#define genLocalExcep( CBGUARD, GUARD, CAC, STAT, PCTX ) \ -(CAC).exception ( CBGUARD, GUARD, STAT, PCTX, __FILE__, __LINE__ ) - -#endif // ifdef INCiocinfh diff --git a/src/ca/client/localHostName.cpp b/src/ca/client/localHostName.cpp deleted file mode 100644 index b0b96bb47..000000000 --- a/src/ca/client/localHostName.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include "osiSock.h" - -#include "localHostName.h" - -epicsSingleton < localHostName > localHostNameCache; - -localHostName::localHostName () : - attachedToSockLib ( osiSockAttach () != 0 ), length ( 0u ) -{ - const char * pErrStr = ""; - int status = -1; - if ( this->attachedToSockLib ) { - status = gethostname ( - this->cache, sizeof ( this->cache ) ); - } - if ( status ) { - strncpy ( this->cache, pErrStr, sizeof ( this->cache ) ); - } - this->cache [ sizeof ( this->cache ) - 1u ] = '\0'; - this->length = strlen ( this->cache ); -} - -localHostName::~localHostName () -{ - if ( this->attachedToSockLib ) { - osiSockRelease (); - } -} - -unsigned localHostName::getName ( - char * pBuf, unsigned bufLength ) const -{ - if ( bufLength ) { - strncpy ( pBuf, this->cache, bufLength ); - if ( this->length < bufLength ) { - return this->length; - } - else { - unsigned reducedSize = bufLength - 1; - pBuf [ reducedSize ] = '\0'; - return reducedSize; - } - } - return 0u; -} diff --git a/src/ca/client/localHostName.h b/src/ca/client/localHostName.h deleted file mode 100644 index f116b8140..000000000 --- a/src/ca/client/localHostName.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#ifndef localHostNameh -#define localHostNameh - -#include - -#ifdef epicsExportSharedSymbols -# define localHostNameh_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsSingleton.h" - -#ifdef localHostNameh_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -#endif - -class localHostName { -public: - localHostName (); - ~localHostName (); - const char * pointer () const; - unsigned getName ( char * pBuf, unsigned bufLength ) const; - unsigned nameLength () const; -private: - bool attachedToSockLib; - unsigned length; - char cache [128]; -}; - -extern epicsSingleton < localHostName > localHostNameCache; - -inline unsigned localHostName::nameLength () const -{ - return this->length; -} - -inline const char * localHostName::pointer () const -{ - return this->cache; -} - -#endif // ifndef localHostNameh - - diff --git a/src/ca/client/msgForMultiplyDefinedPV.cpp b/src/ca/client/msgForMultiplyDefinedPV.cpp deleted file mode 100644 index 7002dd4b9..000000000 --- a/src/ca/client/msgForMultiplyDefinedPV.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "msgForMultiplyDefinedPV.h" -#include "cac.h" -#include "caerr.h" // for ECA_DBLCHNL - -msgForMultiplyDefinedPV::msgForMultiplyDefinedPV ( - ipAddrToAsciiEngine & engine, - callbackForMultiplyDefinedPV & cbIn, - const char * pChannelName, const char * pAcc ) : - dnsTransaction ( engine.createTransaction () ), cb ( cbIn ) -{ - strncpy ( this->acc, pAcc, sizeof ( this->acc ) ); - this->acc[ sizeof ( this->acc ) - 1 ] = '\0'; - strncpy ( this->channel, pChannelName, sizeof ( this->channel ) ); - this->channel[ sizeof ( this->channel ) - 1 ] = '\0'; -} - -msgForMultiplyDefinedPV::~msgForMultiplyDefinedPV () -{ - this->dnsTransaction.release (); -} - -void msgForMultiplyDefinedPV::transactionComplete ( const char * pHostNameRej ) -{ - // calls into cac for the notification - // the msg object (= this) is being deleted as part of the notification - this->cb.pvMultiplyDefinedNotify ( *this, this->channel, this->acc, pHostNameRej ); - // !! dont touch 'this' pointer after this point because object has been deleted !! -} - -void * msgForMultiplyDefinedPV::operator new ( size_t size, - tsFreeList < class msgForMultiplyDefinedPV, 16 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -void msgForMultiplyDefinedPV::operator delete ( void *pCadaver, - tsFreeList < class msgForMultiplyDefinedPV, 16 > & freeList ) -{ - freeList.release ( pCadaver, sizeof ( msgForMultiplyDefinedPV ) ); -} -#endif - -void msgForMultiplyDefinedPV::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -callbackForMultiplyDefinedPV::~callbackForMultiplyDefinedPV () -{ -} - - diff --git a/src/ca/client/msgForMultiplyDefinedPV.h b/src/ca/client/msgForMultiplyDefinedPV.h deleted file mode 100644 index 3f1e771c0..000000000 --- a/src/ca/client/msgForMultiplyDefinedPV.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef msgForMultiplyDefinedPVh -#define msgForMultiplyDefinedPVh - -#ifdef epicsExportSharedSymbols -# define msgForMultiplyDefinedPVh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "ipAddrToAsciiAsynchronous.h" -#include "tsFreeList.h" -#include "tsDLList.h" -#include "compilerDependencies.h" - -#ifdef msgForMultiplyDefinedPVh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -#endif - -class callbackForMultiplyDefinedPV { -public: - virtual ~callbackForMultiplyDefinedPV () = 0; - virtual void pvMultiplyDefinedNotify ( - class msgForMultiplyDefinedPV &, const char * pChannelName, - const char * pAcc, const char * pRej ) = 0; -}; - -class msgForMultiplyDefinedPV : - public ipAddrToAsciiCallBack, - public tsDLNode < msgForMultiplyDefinedPV > { -public: - msgForMultiplyDefinedPV ( ipAddrToAsciiEngine & engine, - callbackForMultiplyDefinedPV &, const char * pChannelName, - const char * pAcc ); - virtual ~msgForMultiplyDefinedPV (); - void ioInitiate ( const osiSockAddr & rej ); - void * operator new ( size_t size, tsFreeList < class msgForMultiplyDefinedPV, 16 > & ); - epicsPlacementDeleteOperator (( void *, tsFreeList < class msgForMultiplyDefinedPV, 16 > & )) -private: - char acc[64]; - char channel[64]; - ipAddrToAsciiTransaction & dnsTransaction; - callbackForMultiplyDefinedPV & cb; - void transactionComplete ( const char * pHostName ); - msgForMultiplyDefinedPV ( const msgForMultiplyDefinedPV & ); - msgForMultiplyDefinedPV & operator = ( const msgForMultiplyDefinedPV & ); - void operator delete ( void * ); -}; - -inline void msgForMultiplyDefinedPV::ioInitiate ( const osiSockAddr & rej ) -{ - this->dnsTransaction.ipAddrToAscii ( rej, *this ); -} - -#endif // ifdef msgForMultiplyDefinedPVh - diff --git a/src/ca/client/nciu.cpp b/src/ca/client/nciu.cpp deleted file mode 100644 index 8eb89c5c3..000000000 --- a/src/ca/client/nciu.cpp +++ /dev/null @@ -1,626 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - * - */ - -#include -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "epicsAlgorithm.h" - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "cac.h" -#include "osiWireFormat.h" -#include "udpiiu.h" -#include "virtualCircuit.h" -#include "cadef.h" -#include "db_access.h" // for INVALID_DB_REQ -#include "noopiiu.h" - -nciu::nciu ( cac & cacIn, netiiu & iiuIn, cacChannelNotify & chanIn, - const char *pNameIn, cacChannel::priLev pri ) : - cacChannel ( chanIn ), - cacCtx ( cacIn ), - piiu ( & iiuIn ), - sid ( UINT_MAX ), - count ( 0 ), - retry ( 0u ), - nameLength ( 0u ), - typeCode ( USHRT_MAX ), - priority ( static_cast ( pri ) ) -{ - size_t nameLengthTmp = strlen ( pNameIn ) + 1; - - // second constraint is imposed by size field in protocol header - if ( nameLengthTmp > MAX_UDP_SEND - sizeof ( caHdr ) || nameLengthTmp > USHRT_MAX ) { - throw cacChannel::badString (); - } - - if ( pri > 0xff ) { - throw cacChannel::badPriority (); - } - - this->nameLength = static_cast ( nameLengthTmp ); - - this->pNameStr = new char [ this->nameLength ]; - strcpy ( this->pNameStr, pNameIn ); -} - -nciu::~nciu () -{ - delete [] this->pNameStr; -} - -// channels are created by the user, and only destroyed by the user -// using this routine -void nciu::destroy ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExcusionGuard ) -{ - while ( baseNMIU * pNetIO = this->eventq.first () ) { - bool success = this->cacCtx.destroyIO ( callbackGuard, mutualExcusionGuard, - pNetIO->getId (), *this ); - assert ( success ); - } - - // if the claim reply has not returned yet then we will issue - // the clear channel request to the server when the claim reply - // arrives and there is no matching nciu in the client - if ( this->channelNode::isInstalledInServer ( mutualExcusionGuard ) ) { - this->getPIIU(mutualExcusionGuard)->clearChannelRequest ( - mutualExcusionGuard, this->sid, this->id ); - } - this->piiu->uninstallChan ( mutualExcusionGuard, *this ); - this->cacCtx.destroyChannel ( mutualExcusionGuard, *this ); -} - -void nciu::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void nciu::initiateConnect ( - epicsGuard < epicsMutex > & guard ) -{ - this->cacCtx.initiateConnect ( guard, *this, this->piiu ); -} - -void nciu::connect ( unsigned nativeType, - unsigned nativeCount, unsigned sidIn, - epicsGuard < epicsMutex > & /* cbGuard */, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - if ( ! dbf_type_is_valid ( nativeType ) ) { - throw std::logic_error ( "Ignored conn resp with bad native data type" ); - } - - this->typeCode = static_cast < unsigned short > ( nativeType ); - this->count = nativeCount; - this->sid = sidIn; - - /* - * if less than v4.1 then the server will never - * send access rights and there will always be access - */ - bool v41Ok = this->piiu->ca_v41_ok ( guard ); - if ( ! v41Ok ) { - this->accessRightState.setReadPermit(); - this->accessRightState.setWritePermit(); - } - - /* - * if less than v4.1 then the server will never - * send access rights and we know that there - * will always be access and also need to call - * their call back here - */ - if ( ! v41Ok ) { - this->notify().accessRightsNotify ( - guard, this->accessRightState ); - } - - // channel uninstal routine grabs the callback lock so - // a channel will not be deleted while a call back is - // in progress - // - // the callback lock is also taken when a channel - // disconnects to prevent a race condition with the - // code below - ie we hold the callback lock here - // so a chanel cant be destroyed out from under us. - this->notify().connectNotify ( guard ); -} - -void nciu::unresponsiveCircuitNotify ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - ioid tmpId = this->getId (); - cac & caRefTmp = this->cacCtx; - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - this->cacCtx.disconnectAllIO ( cbGuard, guard, - *this, this->eventq ); - this->notify().disconnectNotify ( guard ); - // if they destroy the channel in their disconnect - // handler then we have to be very careful to not - // touch this object if it has been destroyed - nciu * pChan = caRefTmp.lookupChannel ( guard, tmpId ); - if ( pChan ) { - caAccessRights noRights; - pChan->notify().accessRightsNotify ( guard, noRights ); - // likewise, they might destroy the channel in their access rights - // handler so we have to be very careful to not touch this - // object from here on down - } -} - -void nciu::setServerAddressUnknown ( netiiu & newiiu, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - this->piiu = & newiiu; - this->retry = 0; - this->typeCode = USHRT_MAX; - this->count = 0u; - this->sid = UINT_MAX; - this->accessRightState.clrReadPermit(); - this->accessRightState.clrWritePermit(); -} - -void nciu::accessRightsStateChange ( - const caAccessRights & arIn, epicsGuard < epicsMutex > & /* cbGuard */, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - this->accessRightState = arIn; - - // - // the channel delete routine takes the call back lock so - // that this will not be called when the channel is being - // deleted. - // - this->notify().accessRightsNotify ( guard, this->accessRightState ); -} - -/* - * nciu::searchMsg () - */ -bool nciu::searchMsg ( epicsGuard < epicsMutex > & guard ) -{ - bool success = this->piiu->searchMsg ( - guard, this->getId (), this->pNameStr, this->nameLength ); - if ( success ) { - if ( this->retry < UINT_MAX ) { - this->retry++; - } - } - return success; -} - -const char *nciu::pName ( - epicsGuard < epicsMutex > & guard ) const throw () -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - return this->pNameStr; -} - -unsigned nciu::getName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw () -{ - if ( bufLen == 0u ) { - return 0u; - } - if ( this->nameLength < bufLen ) { - strcpy ( pBuf, this->pNameStr ); - return this->nameLength; - } - else { - unsigned reducedSize = bufLen - 1u; - strncpy ( pBuf, this->pNameStr, bufLen ); - pBuf[reducedSize] = '\0'; - return reducedSize; - } -} - -unsigned nciu::nameLen ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - return this->nameLength; -} - -unsigned nciu::requestMessageBytesPending ( - epicsGuard < epicsMutex > & guard ) -{ - return piiu->requestMessageBytesPending ( guard ); -} - -void nciu::flush ( - epicsGuard < epicsMutex > & guard ) -{ - piiu->flush ( guard ); -} - -cacChannel::ioStatus nciu::read ( - epicsGuard < epicsMutex > & guard, - unsigned type, arrayElementCount countIn, - cacReadNotify ¬ify, ioid *pId ) -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - - if ( ! this->connected ( guard ) ) { - throw cacChannel::notConnected (); - } - if ( ! this->accessRightState.readPermit () ) { - throw cacChannel::noReadAccess (); - } - if ( countIn > this->count ) { - throw cacChannel::outOfBounds (); - } - - // - // fail out if their arguments are invalid - // - if ( INVALID_DB_REQ ( type ) ) { - throw cacChannel::badType (); - } - - netReadNotifyIO & io = this->cacCtx.readNotifyRequest ( - guard, *this, *this, type, countIn, notify ); - if ( pId ) { - *pId = io.getId (); - } - this->eventq.add ( io ); - return cacChannel::iosAsynch; -} - -void nciu::stringVerify ( const char *pStr, const unsigned count ) -{ - for ( unsigned i = 0; i < count; i++ ) { - unsigned int strsize = 0; - while ( pStr[strsize++] != '\0' ) { - if ( strsize >= MAX_STRING_SIZE ) { - throw badString(); - } - } - pStr += MAX_STRING_SIZE; - } -} - -void nciu::write ( - epicsGuard < epicsMutex > & guard, - unsigned type, arrayElementCount countIn, const void * pValue ) -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - - // make sure that they get this and not "no write access" - // if disconnected - if ( ! this->connected ( guard ) ) { - throw cacChannel::notConnected(); - } - if ( ! this->accessRightState.writePermit() ) { - throw cacChannel::noWriteAccess(); - } - if ( countIn > this->count || countIn == 0 ) { - throw cacChannel::outOfBounds(); - } - if ( type == DBR_STRING ) { - nciu::stringVerify ( (char *) pValue, countIn ); - } - this->piiu->writeRequest ( guard, *this, type, countIn, pValue ); -} - -cacChannel::ioStatus nciu::write ( - epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount countIn, - const void * pValue, cacWriteNotify & notify, ioid * pId ) -{ - // make sure that they get this and not "no write access" - // if disconnected - if ( ! this->connected ( guard ) ) { - throw cacChannel::notConnected(); - } - if ( ! this->accessRightState.writePermit() ) { - throw cacChannel::noWriteAccess(); - } - if ( countIn > this->count || countIn == 0 ) { - throw cacChannel::outOfBounds(); - } - if ( type == DBR_STRING ) { - nciu::stringVerify ( (char *) pValue, countIn ); - } - - netWriteNotifyIO & io = this->cacCtx.writeNotifyRequest ( - guard, *this, *this, type, countIn, pValue, notify ); - if ( pId ) { - *pId = io.getId (); - } - this->eventq.add ( io ); - return cacChannel::iosAsynch; -} - -void nciu::subscribe ( - epicsGuard < epicsMutex > & guard, unsigned type, - arrayElementCount nElem, unsigned mask, - cacStateNotify & notify, ioid *pId ) -{ - netSubscription & io = this->cacCtx.subscriptionRequest ( - guard, *this, *this, type, nElem, mask, notify, - this->channelNode::isInstalledInServer ( guard ) ); - this->eventq.add ( io ); - if ( pId ) { - *pId = io.getId (); - } -} - -void nciu::ioCancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - const ioid & idIn ) -{ - this->cacCtx.destroyIO ( callbackGuard, - mutualExclusionGuard, idIn, *this ); -} - -void nciu::ioShow ( - epicsGuard < epicsMutex > & guard, - const ioid &idIn, unsigned level ) const -{ - this->cacCtx.ioShow ( guard, idIn, level ); -} - -unsigned nciu::getHostName ( - epicsGuard < epicsMutex > & guard, - char *pBuf, unsigned bufLength ) const throw () -{ - return this->piiu->getHostName ( - guard, pBuf, bufLength ); -} - -const char * nciu::pHostName ( - epicsGuard < epicsMutex > & guard ) const throw () -{ - return this->piiu->pHostName ( guard ); -} - -bool nciu::ca_v42_ok ( - epicsGuard < epicsMutex > & guard ) const -{ - return this->piiu->ca_v42_ok ( guard ); -} - -short nciu::nativeType ( - epicsGuard < epicsMutex > & guard ) const -{ - short type = TYPENOTCONN; - if ( this->connected ( guard ) ) { - if ( this->typeCode < SHRT_MAX ) { - type = static_cast ( this->typeCode ); - } - } - return type; -} - -arrayElementCount nciu::nativeElementCount ( - epicsGuard < epicsMutex > & guard ) const -{ - arrayElementCount countOut = 0ul; - if ( this->connected ( guard ) ) { - countOut = this->count; - } - return countOut; -} - -caAccessRights nciu::accessRights ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - return this->accessRightState; -} - -unsigned nciu::searchAttempts ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - return this->retry; -} - -double nciu::beaconPeriod ( - epicsGuard < epicsMutex > & guard ) const -{ - return this->cacCtx.beaconPeriod ( guard, *this ); -} - -double nciu::receiveWatchdogDelay ( - epicsGuard < epicsMutex > & guard ) const -{ - return this->piiu->receiveWatchdogDelay ( guard ); -} - -bool nciu::connected ( epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - return this->channelNode::isConnected ( guard ); -} - -void nciu::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->cacCtx.mutexRef() ); - this->show ( guard, level ); -} - -void nciu::show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - if ( this->connected ( guard ) ) { - char hostNameTmp [256]; - this->getHostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) ); - ::printf ( "Channel \"%s\", connected to server %s", - this->pNameStr, hostNameTmp ); - if ( level > 1u ) { - int tmpTypeCode = static_cast < int > ( this->typeCode ); - ::printf ( ", native type %s, native element count %u", - dbf_type_to_text ( tmpTypeCode ), this->count ); - ::printf ( ", %sread access, %swrite access", - this->accessRightState.readPermit() ? "" : "no ", - this->accessRightState.writePermit() ? "" : "no "); - } - ::printf ( "\n" ); - } - else { - ::printf ( "Channel \"%s\" is disconnected\n", this->pNameStr ); - } - - if ( level > 2u ) { - ::printf ( "\tnetwork IO pointer = %p\n", - static_cast ( this->piiu ) ); - ::printf ( "\tserver identifier %u\n", this->sid ); - ::printf ( "\tsearch retry number=%u\n", this->retry ); - ::printf ( "\tname length=%u\n", this->nameLength ); - } -} - -void nciu::ioCompletionNotify ( - epicsGuard < epicsMutex > &, class baseNMIU & io ) -{ - this->eventq.remove ( io ); -} - -void nciu::resubscribe ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - tsDLIter < baseNMIU > pNetIO = this->eventq.firstIter (); - while ( pNetIO.valid () ) { - tsDLIter < baseNMIU > next = pNetIO; - next++; - class netSubscription * pSubscr = pNetIO->isSubscription (); - // Its normal for other types of IO to exist after the channel connects, - // but before all of the resubscription requests go out. We must ignore - // them here. - if ( pSubscr ) { - try { - pSubscr->subscribeIfRequired ( guard, *this ); - } - catch ( ... ) { - errlogPrintf ( "CAC: failed to send subscription request " - "during channel connect\n" ); - } - } - pNetIO = next; - } -} - -void nciu::sendSubscriptionUpdateRequests ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - tsDLIter < baseNMIU > pNetIO = this->eventq.firstIter (); - while ( pNetIO.valid () ) { - tsDLIter < baseNMIU > next = pNetIO; - next++; - try { - pNetIO->forceSubscriptionUpdate ( guard, *this ); - } - catch ( ... ) { - errlogPrintf ( - "CAC: failed to send subscription update request " - "during channel connect\n" ); - } - pNetIO = next; - } -} - -void nciu::disconnectAllIO ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - this->cacCtx.disconnectAllIO ( cbGuard, guard, - *this, this->eventq ); -} - -void nciu::serviceShutdownNotify ( - epicsGuard < epicsMutex > & callbackControlGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ) -{ - this->setServerAddressUnknown ( noopIIU, mutualExclusionGuard ); - this->notify().serviceShutdownNotify ( mutualExclusionGuard ); -} - -void channelNode::setRespPendingState ( - epicsGuard < epicsMutex > &, unsigned index ) -{ - this->listMember = - static_cast < channelNode::channelState > - ( channelNode::cs_searchRespPending0 + index ); - if ( this->listMember > cs_searchRespPending17 ) { - throw std::runtime_error ( - "resp search timer index out of bounds" ); - } -} - -void channelNode::setReqPendingState ( - epicsGuard < epicsMutex > &, unsigned index ) -{ - this->listMember = - static_cast < channelNode::channelState > - ( channelNode::cs_searchReqPending0 + index ); - if ( this->listMember > cs_searchReqPending17 ) { - throw std::runtime_error ( - "req search timer index out of bounds" ); - } -} - -unsigned channelNode::getMaxSearchTimerCount () -{ - return epicsMin ( - cs_searchReqPending17 - cs_searchReqPending0, - cs_searchRespPending17 - cs_searchRespPending0 ) + 1u; -} - -unsigned channelNode::getSearchTimerIndex ( - epicsGuard < epicsMutex > & ) -{ - channelNode::channelState chanState = this->listMember; - unsigned index = 0u; - if ( chanState >= cs_searchReqPending0 && - chanState <= cs_searchReqPending17 ) { - index = chanState - cs_searchReqPending0; - } - else if ( chanState >= cs_searchRespPending0 && - chanState <= cs_searchRespPending17 ) { - index = chanState - cs_searchRespPending0; - } - else { - throw std::runtime_error ( - "channel was expected to be in a search timer, but wasnt" );; - } - return index; -} - diff --git a/src/ca/client/nciu.h b/src/ca/client/nciu.h deleted file mode 100644 index 7cba6e82b..000000000 --- a/src/ca/client/nciu.h +++ /dev/null @@ -1,385 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef nciuh -#define nciuh - -#ifdef epicsExportSharedSymbols -# define nciuh_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "resourceLib.h" -#include "tsDLList.h" -#include "tsFreeList.h" -#include "epicsMutex.h" -#include "compilerDependencies.h" - -#ifdef nciuh_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#define CA_MINOR_PROTOCOL_REVISION 13 -#include "caProto.h" - -#include "cacIO.h" - -class cac; -class netiiu; - -// The node and the state which tracks the list membership -// are in the channel, but belong to the circuit. -// Protected by the callback mutex -class channelNode : public tsDLNode < class nciu > -{ -protected: - channelNode (); - bool isInstalledInServer ( epicsGuard < epicsMutex > & ) const; - bool isConnected ( epicsGuard < epicsMutex > & ) const; -public: - static unsigned getMaxSearchTimerCount (); -private: - enum channelState { - cs_none, - cs_disconnGov, - // note: indexing is used here - // so these must be contiguous - cs_searchReqPending0, - cs_searchReqPending1, - cs_searchReqPending2, - cs_searchReqPending3, - cs_searchReqPending4, - cs_searchReqPending5, - cs_searchReqPending6, - cs_searchReqPending7, - cs_searchReqPending8, - cs_searchReqPending9, - cs_searchReqPending10, - cs_searchReqPending11, - cs_searchReqPending12, - cs_searchReqPending13, - cs_searchReqPending14, - cs_searchReqPending15, - cs_searchReqPending16, - cs_searchReqPending17, - // note: indexing is used here - // so these must be contiguous - cs_searchRespPending0, - cs_searchRespPending1, - cs_searchRespPending2, - cs_searchRespPending3, - cs_searchRespPending4, - cs_searchRespPending5, - cs_searchRespPending6, - cs_searchRespPending7, - cs_searchRespPending8, - cs_searchRespPending9, - cs_searchRespPending10, - cs_searchRespPending11, - cs_searchRespPending12, - cs_searchRespPending13, - cs_searchRespPending14, - cs_searchRespPending15, - cs_searchRespPending16, - cs_searchRespPending17, - cs_createReqPend, - cs_createRespPend, - cs_v42ConnCallbackPend, - cs_subscripReqPend, - cs_connected, - cs_unrespCircuit, - cs_subscripUpdateReqPend - } listMember; - void setRespPendingState ( epicsGuard < epicsMutex > &, unsigned index ); - void setReqPendingState ( epicsGuard < epicsMutex > &, unsigned index ); - unsigned getSearchTimerIndex ( epicsGuard < epicsMutex > & ); - friend class tcpiiu; - friend class udpiiu; - friend class tcpSendThread; - friend class searchTimer; - friend class disconnectGovernorTimer; -}; - -class privateInterfaceForIO { -public: - virtual void ioCompletionNotify ( - epicsGuard < epicsMutex > &, class baseNMIU & ) = 0; - virtual arrayElementCount nativeElementCount ( - epicsGuard < epicsMutex > & ) const = 0; - virtual bool connected ( epicsGuard < epicsMutex > & ) const = 0; -protected: - virtual ~privateInterfaceForIO() {} -}; - -class nciu : - public cacChannel, - public chronIntIdRes < nciu >, - public channelNode, - private privateInterfaceForIO { -public: - nciu ( cac &, netiiu &, cacChannelNotify &, - const char * pNameIn, cacChannel::priLev ); - ~nciu (); - void connect ( unsigned nativeType, - unsigned nativeCount, unsigned sid, - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void connect ( epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void unresponsiveCircuitNotify ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void circuitHangupNotify ( class udpiiu &, - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void setServerAddressUnknown ( - netiiu & newiiu, epicsGuard < epicsMutex > & guard ); - bool searchMsg ( - epicsGuard < epicsMutex > & ); - void serviceShutdownNotify ( - epicsGuard < epicsMutex > & callbackControlGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void accessRightsStateChange ( const caAccessRights &, - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - ca_uint32_t getSID ( - epicsGuard < epicsMutex > & ) const; - ca_uint32_t getCID ( - epicsGuard < epicsMutex > & ) const; - netiiu * getPIIU ( - epicsGuard < epicsMutex > & ); - const netiiu * getConstPIIU ( - epicsGuard < epicsMutex > & ) const; - cac & getClient (); - void searchReplySetUp ( netiiu &iiu, unsigned sidIn, - ca_uint16_t typeIn, arrayElementCount countIn, - epicsGuard < epicsMutex > & ); - void show ( - unsigned level ) const; - void show ( - epicsGuard < epicsMutex > &, - unsigned level ) const; - unsigned getName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw (); - const char * pName ( - epicsGuard < epicsMutex > & ) const throw (); - unsigned nameLen ( - epicsGuard < epicsMutex > & ) const; - unsigned getHostName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw (); - void writeException ( - epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > &, - int status, const char *pContext, unsigned type, arrayElementCount count ); - cacChannel::priLev getPriority ( - epicsGuard < epicsMutex > & ) const; - void * operator new ( - size_t size, tsFreeList < class nciu, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator ( - ( void *, tsFreeList < class nciu, 1024, epicsMutexNOOP > & )) - //arrayElementCount nativeElementCount ( epicsGuard < epicsMutex > & ) const; - void resubscribe ( epicsGuard < epicsMutex > & ); - void sendSubscriptionUpdateRequests ( epicsGuard < epicsMutex > & ); - void disconnectAllIO ( - epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > & ); - bool connected ( epicsGuard < epicsMutex > & ) const; - unsigned getcount() const { return count; } - -private: - tsDLList < class baseNMIU > eventq; - caAccessRights accessRightState; - cac & cacCtx; - char * pNameStr; - netiiu * piiu; - ca_uint32_t sid; // server id - unsigned count; - unsigned retry; // search retry number - unsigned short nameLength; // channel name length - ca_uint16_t typeCode; - ca_uint8_t priority; - virtual void destroy ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void initiateConnect ( - epicsGuard < epicsMutex > & ); - unsigned requestMessageBytesPending ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void flush ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - ioStatus read ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, - cacReadNotify &, ioid * ); - void write ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, - const void *pValue ); - ioStatus write ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, - const void *pValue, cacWriteNotify &, ioid * ); - void subscribe ( - epicsGuard < epicsMutex > & guard, - unsigned type, arrayElementCount nElem, - unsigned mask, cacStateNotify ¬ify, ioid * ); - // The primary mutex must be released when calling the user's - // callback, and therefore a finite interval exists when we are - // moving forward with the intent to call the users callback - // but the users IO could be deleted during this interval. - // To prevent the user's callback from being called after - // destroying his IO we must past a guard for the callback - // mutex here. - virtual void ioCancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - const ioid & ); - void ioShow ( - epicsGuard < epicsMutex > &, - const ioid &, unsigned level ) const; - short nativeType ( - epicsGuard < epicsMutex > & ) const; - caAccessRights accessRights ( - epicsGuard < epicsMutex > & ) const; - unsigned searchAttempts ( - epicsGuard < epicsMutex > & ) const; - double beaconPeriod ( - epicsGuard < epicsMutex > & ) const; - double receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const; - bool ca_v42_ok ( - epicsGuard < epicsMutex > & ) const; - arrayElementCount nativeElementCount ( - epicsGuard < epicsMutex > & ) const; - static void stringVerify ( const char *pStr, const unsigned count ); - void ioCompletionNotify ( - epicsGuard < epicsMutex > &, class baseNMIU & ); - const char * pHostName ( - epicsGuard < epicsMutex > & guard ) const throw (); - nciu ( const nciu & ); - nciu & operator = ( const nciu & ); - void operator delete ( void * ); -}; - -inline void * nciu::operator new ( size_t size, - tsFreeList < class nciu, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void nciu::operator delete ( void * pCadaver, - tsFreeList < class nciu, 1024, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver, sizeof ( nciu ) ); -} -#endif - -inline ca_uint32_t nciu::getSID ( - epicsGuard < epicsMutex > & ) const -{ - return this->sid; -} - -inline ca_uint32_t nciu::getCID ( - epicsGuard < epicsMutex > & ) const -{ - return this->id; -} - -// this is to only be used by early protocol revisions -inline void nciu::connect ( epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - this->connect ( this->typeCode, this->count, - this->sid, cbGuard, guard ); -} - -inline void nciu::searchReplySetUp ( netiiu &iiu, unsigned sidIn, - ca_uint16_t typeIn, arrayElementCount countIn, - epicsGuard < epicsMutex > & ) -{ - this->piiu = & iiu; - this->typeCode = typeIn; - this->count = countIn; - this->sid = sidIn; -} - -inline netiiu * nciu::getPIIU ( - epicsGuard < epicsMutex > & ) -{ - return this->piiu; -} - -inline void nciu::writeException ( - epicsGuard < epicsMutex > & /* cbGuard */, - epicsGuard < epicsMutex > & guard, - int status, const char * pContext, - unsigned typeIn, arrayElementCount countIn ) -{ - this->notify().writeException ( guard, - status, pContext, typeIn, countIn ); -} - -inline const netiiu * nciu::getConstPIIU ( - epicsGuard < epicsMutex > & ) const -{ - return this->piiu; -} - -inline cac & nciu::getClient () -{ - return this->cacCtx; -} - -inline cacChannel::priLev nciu::getPriority ( - epicsGuard < epicsMutex > & ) const -{ - return this->priority; -} - -inline channelNode::channelNode () : - listMember ( cs_none ) -{ -} - -inline bool channelNode::isConnected ( epicsGuard < epicsMutex > & ) const -{ - return - this->listMember == cs_connected || - this->listMember == cs_subscripReqPend || - this->listMember == cs_subscripUpdateReqPend; -} - -inline bool channelNode::isInstalledInServer ( epicsGuard < epicsMutex > & ) const -{ - return - this->listMember == cs_connected || - this->listMember == cs_subscripReqPend || - this->listMember == cs_unrespCircuit || - this->listMember == cs_subscripUpdateReqPend; -} - -#endif // ifdef nciuh diff --git a/src/ca/client/netIO.h b/src/ca/client/netIO.h deleted file mode 100644 index e728d2a1a..000000000 --- a/src/ca/client/netIO.h +++ /dev/null @@ -1,306 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef netIOh -#define netIOh - -#include "nciu.h" -#include "compilerDependencies.h" - -// SUN PRO generates multiply defined symbols if the baseNMIU -// destructor is virtual (therefore it is protected). -// I assume that SUNPRO will fix this in future versions. -// With other compilers we get warnings (and -// potential problems) if we dont make the baseNMIU -// destructor virtual. -#if defined ( __SUNPRO_CC ) && ( __SUNPRO_CC <= 0x540 ) -# define NETIO_VIRTUAL_DESTRUCTOR -#else -# define NETIO_VIRTUAL_DESTRUCTOR virtual -#endif - -class privateInterfaceForIO; - -class baseNMIU : public tsDLNode < baseNMIU >, - public chronIntIdRes < baseNMIU > { -public: - virtual void destroy ( - epicsGuard < epicsMutex > &, class cacRecycle & ) = 0; // only called by cac - virtual void completion ( - epicsGuard < epicsMutex > &, cacRecycle & ) = 0; - virtual void exception ( - epicsGuard < epicsMutex > &, cacRecycle &, - int status, const char * pContext ) = 0; - virtual void exception ( - epicsGuard < epicsMutex > &, cacRecycle &, - int status, const char * pContext, unsigned type, - arrayElementCount count ) = 0; - virtual void completion ( - epicsGuard < epicsMutex > &, cacRecycle &, - unsigned type, arrayElementCount count, - const void * pData ) = 0; - virtual void forceSubscriptionUpdate ( - epicsGuard < epicsMutex > & guard, nciu & chan ) = 0; - virtual class netSubscription * isSubscription () = 0; - virtual void show ( - unsigned level ) const = 0; - virtual void show ( - epicsGuard < epicsMutex > &, - unsigned level ) const = 0; -protected: - NETIO_VIRTUAL_DESTRUCTOR ~baseNMIU (); -}; - -class netSubscription : public baseNMIU { -public: - static netSubscription * factory ( - tsFreeList < class netSubscription, 1024, epicsMutexNOOP > &, - class privateInterfaceForIO &, unsigned type, arrayElementCount count, - unsigned mask, cacStateNotify & ); - void show ( - unsigned level ) const; - void show ( - epicsGuard < epicsMutex > &, unsigned level ) const; - arrayElementCount getCount ( - epicsGuard < epicsMutex > &, bool allow_zero ) const; - unsigned getType ( - epicsGuard < epicsMutex > & ) const; - unsigned getMask ( - epicsGuard < epicsMutex > & ) const; - void subscribeIfRequired ( - epicsGuard < epicsMutex > & guard, nciu & chan ); - void unsubscribeIfRequired ( - epicsGuard < epicsMutex > & guard, nciu & chan ); -protected: - netSubscription ( - class privateInterfaceForIO &, unsigned type, - arrayElementCount count, - unsigned mask, cacStateNotify & ); - ~netSubscription (); -private: - const arrayElementCount count; - class privateInterfaceForIO & privateChanForIO; - cacStateNotify & notify; - const unsigned type; - const unsigned mask; - bool subscribed; - class netSubscription * isSubscription (); - void operator delete ( void * ); - void * operator new ( size_t, - tsFreeList < class netSubscription, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class netSubscription, 1024, epicsMutexNOOP > & )) - void destroy ( - epicsGuard < epicsMutex > &, class cacRecycle & ); - void completion ( - epicsGuard < epicsMutex > &, cacRecycle & ); - void exception ( - epicsGuard < epicsMutex > &, cacRecycle &, - int status, const char * pContext ); - void completion ( - epicsGuard < epicsMutex > &, cacRecycle &, - unsigned type, arrayElementCount count, const void * pData ); - void exception ( - epicsGuard < epicsMutex > &, cacRecycle &, - int status, const char * pContext, unsigned type, - arrayElementCount count ); - void forceSubscriptionUpdate ( - epicsGuard < epicsMutex > & guard, nciu & chan ); - netSubscription ( const netSubscription & ); - netSubscription & operator = ( const netSubscription & ); -}; - -class netReadNotifyIO : public baseNMIU { -public: - static netReadNotifyIO * factory ( - tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > &, - privateInterfaceForIO &, cacReadNotify & ); - void show ( - unsigned level ) const; - void show ( - epicsGuard < epicsMutex > &, unsigned level ) const; -protected: - netReadNotifyIO ( privateInterfaceForIO &, cacReadNotify & ); - ~netReadNotifyIO (); -private: - cacReadNotify & notify; - class privateInterfaceForIO & privateChanForIO; - void operator delete ( void * ); - void * operator new ( size_t, - tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & )) - void destroy ( - epicsGuard < epicsMutex > &, class cacRecycle & ); - void completion ( - epicsGuard < epicsMutex > &, cacRecycle & ); - void exception ( - epicsGuard < epicsMutex > &, cacRecycle &, - int status, const char * pContext ); - void completion ( - epicsGuard < epicsMutex > &, cacRecycle &, - unsigned type, arrayElementCount count, - const void * pData ); - void exception ( - epicsGuard < epicsMutex > &, cacRecycle &, - int status, const char * pContext, - unsigned type, arrayElementCount count ); - class netSubscription * isSubscription (); - void forceSubscriptionUpdate ( - epicsGuard < epicsMutex > & guard, nciu & chan ); - netReadNotifyIO ( const netReadNotifyIO & ); - netReadNotifyIO & operator = ( const netReadNotifyIO & ); -}; - -class netWriteNotifyIO : public baseNMIU { -public: - static netWriteNotifyIO * factory ( - tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > &, - privateInterfaceForIO &, cacWriteNotify & ); - void show ( - unsigned level ) const; - void show ( - epicsGuard < epicsMutex > &, unsigned level ) const; -protected: - netWriteNotifyIO ( privateInterfaceForIO &, cacWriteNotify & ); - ~netWriteNotifyIO (); -private: - cacWriteNotify & notify; - privateInterfaceForIO & privateChanForIO; - void operator delete ( void * ); - void * operator new ( size_t, - tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & )) - class netSubscription * isSubscription (); - void destroy ( - epicsGuard < epicsMutex > &, class cacRecycle & ); - void completion ( - epicsGuard < epicsMutex > &, cacRecycle & ); - void exception ( - epicsGuard < epicsMutex > &, cacRecycle &, - int status, const char * pContext ); - void completion ( - epicsGuard < epicsMutex > &, cacRecycle &, - unsigned type, arrayElementCount count, - const void * pData ); - void exception ( - epicsGuard < epicsMutex > &, cacRecycle &, - int status, const char * pContext, unsigned type, - arrayElementCount count ); - void forceSubscriptionUpdate ( - epicsGuard < epicsMutex > & guard, nciu & chan ); - netWriteNotifyIO ( const netWriteNotifyIO & ); - netWriteNotifyIO & operator = ( const netWriteNotifyIO & ); -}; - -inline void * netSubscription::operator new ( size_t size, - tsFreeList < class netSubscription, 1024, epicsMutexNOOP > &freeList ) -{ - return freeList.allocate ( size ); -} - -#if defined ( CXX_PLACEMENT_DELETE ) - inline void netSubscription::operator delete ( void *pCadaver, - tsFreeList < class netSubscription, 1024, epicsMutexNOOP > &freeList ) - { - freeList.release ( pCadaver ); - } -#endif - -inline netSubscription * netSubscription::factory ( - tsFreeList < class netSubscription, 1024, epicsMutexNOOP > & freeList, - class privateInterfaceForIO & chan, unsigned type, arrayElementCount count, - unsigned mask, cacStateNotify ¬ify ) -{ - return new ( freeList ) netSubscription ( chan, type, - count, mask, notify ); -} - -inline arrayElementCount netSubscription::getCount ( - epicsGuard < epicsMutex > & guard, bool allow_zero ) const -{ - //guard.assertIdenticalMutex ( this->mutex ); - arrayElementCount nativeCount = this->privateChanForIO.nativeElementCount ( guard ); - if ( (this->count == 0u && !allow_zero) || this->count > nativeCount ) { - return nativeCount; - } - else { - return this->count; - } -} - -inline unsigned netSubscription::getType ( epicsGuard < epicsMutex > & ) const -{ - return this->type; -} - -inline unsigned netSubscription::getMask ( epicsGuard < epicsMutex > & ) const -{ - return this->mask; -} - -inline netReadNotifyIO * netReadNotifyIO::factory ( - tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & freeList, - privateInterfaceForIO & ioComplNotifIntf, cacReadNotify & notify ) -{ - return new ( freeList ) netReadNotifyIO ( ioComplNotifIntf, notify ); -} - -inline void * netReadNotifyIO::operator new ( size_t size, - tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#if defined ( CXX_PLACEMENT_DELETE ) - inline void netReadNotifyIO::operator delete ( void *pCadaver, - tsFreeList < class netReadNotifyIO, 1024, epicsMutexNOOP > & freeList ) - { - freeList.release ( pCadaver ); - } -#endif - -inline netWriteNotifyIO * netWriteNotifyIO::factory ( - tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & freeList, - privateInterfaceForIO & ioComplNotifyIntf, cacWriteNotify & notify ) -{ - return new ( freeList ) netWriteNotifyIO ( ioComplNotifyIntf, notify ); -} - -inline void * netWriteNotifyIO::operator new ( size_t size, - tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#if defined ( CXX_PLACEMENT_DELETE ) - inline void netWriteNotifyIO::operator delete ( void *pCadaver, - tsFreeList < class netWriteNotifyIO, 1024, epicsMutexNOOP > & freeList ) - { - freeList.release ( pCadaver ); - } -#endif - -#endif // ifdef netIOh diff --git a/src/ca/client/netReadNotifyIO.cpp b/src/ca/client/netReadNotifyIO.cpp deleted file mode 100644 index 2e4b8ead6..000000000 --- a/src/ca/client/netReadNotifyIO.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include -#include - -#include "errlog.h" - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "iocinf.h" -#include "nciu.h" -#include "cac.h" - -netReadNotifyIO::netReadNotifyIO ( - privateInterfaceForIO & ioComplIntfIn, - cacReadNotify & notify ) : - notify ( notify ), privateChanForIO ( ioComplIntfIn ) -{ -} - -netReadNotifyIO::~netReadNotifyIO () -{ -} - -void netReadNotifyIO::show ( unsigned /* level */ ) const -{ - ::printf ( "netReadNotifyIO at %p\n", - static_cast < const void * > ( this ) ); -} - -void netReadNotifyIO::show ( - epicsGuard < epicsMutex > &, unsigned level ) const -{ - this->show ( level ); -} - -void netReadNotifyIO::destroy ( - epicsGuard < epicsMutex > & guard, cacRecycle & recycle ) -{ - this->~netReadNotifyIO (); - recycle.recycleReadNotifyIO ( guard, *this ); -} - -void netReadNotifyIO::completion ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle, unsigned type, - arrayElementCount count, const void * pData ) -{ - //guard.assertIdenticalMutex ( this->mutex ); - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->notify.completion ( guard, type, count, pData ); - this->~netReadNotifyIO (); - recycle.recycleReadNotifyIO ( guard, *this ); -} - -void netReadNotifyIO::completion ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle ) -{ - //guard.assertIdenticalMutex ( this->mutex ); - //this->chan.getClient().printf ( "Read response w/o data ?\n" ); - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->~netReadNotifyIO (); - recycle.recycleReadNotifyIO ( guard, *this ); -} - -void netReadNotifyIO::exception ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle, - int status, const char *pContext ) -{ - //guard.assertIdenticalMutex ( this->mutex ); - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->notify.exception ( - guard, status, pContext, UINT_MAX, 0u ); - this->~netReadNotifyIO (); - recycle.recycleReadNotifyIO ( guard, *this ); -} - -void netReadNotifyIO::exception ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle, - int status, const char *pContext, - unsigned type, arrayElementCount count ) -{ - //guard.assertIdenticalMutex ( this->mutex ) - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->notify.exception ( - guard, status, pContext, type, count ); - this->~netReadNotifyIO (); - recycle.recycleReadNotifyIO ( guard, *this ); -} - -class netSubscription * netReadNotifyIO::isSubscription () -{ - return 0; -} - -void netReadNotifyIO::forceSubscriptionUpdate ( - epicsGuard < epicsMutex > &, nciu & ) -{ -} - -void netReadNotifyIO::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - - - diff --git a/src/ca/client/netSubscription.cpp b/src/ca/client/netSubscription.cpp deleted file mode 100644 index fe2426a89..000000000 --- a/src/ca/client/netSubscription.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include -#include - -#include "errlog.h" - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "nciu.h" -#include "cac.h" -#include "db_access.h" // for dbf_type_to_text -#include "caerr.h" - -netSubscription::netSubscription ( - privateInterfaceForIO & chanIn, - unsigned typeIn, arrayElementCount countIn, - unsigned maskIn, cacStateNotify & notifyIn ) : - count ( countIn ), privateChanForIO ( chanIn ), - notify ( notifyIn ), type ( typeIn ), mask ( maskIn ), - subscribed ( false ) -{ - if ( ! dbr_type_is_valid ( typeIn ) ) { - throw cacChannel::badType (); - } - if ( this->mask == 0u ) { - throw cacChannel::badEventSelection (); - } -} - -netSubscription::~netSubscription () -{ -} - -void netSubscription::destroy ( - epicsGuard < epicsMutex > & guard, cacRecycle & recycle ) -{ - this->~netSubscription (); - recycle.recycleSubscription ( guard, *this ); -} - -class netSubscription * netSubscription::isSubscription () -{ - return this; -} - -void netSubscription::show ( unsigned /* level */ ) const -{ - ::printf ( "event subscription IO at %p, type %s, element count %lu, mask %u\n", - static_cast < const void * > ( this ), - dbf_type_to_text ( static_cast < int > ( this->type ) ), - this->count, this->mask ); -} - -void netSubscription::show ( - epicsGuard < epicsMutex > &, unsigned level ) const -{ - this->show ( level ); -} - -void netSubscription::completion ( - epicsGuard < epicsMutex > &, cacRecycle & ) -{ - errlogPrintf ( "subscription update w/o data ?\n" ); -} - -void netSubscription::exception ( - epicsGuard < epicsMutex > & guard, cacRecycle & recycle, - int status, const char * pContext ) -{ - if ( status == ECA_DISCONN ) { - this->subscribed = false; - } - if ( status == ECA_CHANDESTROY ) { - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->notify.exception ( - guard, status, pContext, UINT_MAX, 0 ); - this->~netSubscription (); - recycle.recycleSubscription ( guard, *this ); - } - else { - // guard.assertIdenticalMutex ( this->mutex ); - if ( this->privateChanForIO.connected ( guard ) ) { - this->notify.exception ( - guard, status, pContext, UINT_MAX, 0 ); - } - } -} - -void netSubscription::exception ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle, int status, const char * pContext, - unsigned typeIn, arrayElementCount countIn ) -{ - if ( status == ECA_DISCONN ) { - this->subscribed = false; - } - if ( status == ECA_CHANDESTROY ) { - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->notify.exception ( - guard, status, pContext, UINT_MAX, 0 ); - this->~netSubscription (); - recycle.recycleSubscription ( guard, *this ); - } - else { - //guard.assertIdenticalMutex ( this->mutex ); - if ( this->privateChanForIO.connected ( guard ) ) { - this->notify.exception ( - guard, status, pContext, typeIn, countIn ); - } - } -} - -void netSubscription::completion ( - epicsGuard < epicsMutex > & guard, cacRecycle &, - unsigned typeIn, arrayElementCount countIn, - const void * pDataIn ) -{ - // guard.assertIdenticalMutex ( this->mutex ); - if ( this->privateChanForIO.connected ( guard ) ) { - this->notify.current ( - guard, typeIn, countIn, pDataIn ); - } -} - -void netSubscription::subscribeIfRequired ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - if ( ! this->subscribed ) { - chan.getPIIU(guard)->subscriptionRequest ( - guard, chan, *this ); - this->subscribed = true; - } -} - -void netSubscription::unsubscribeIfRequired ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - if ( this->subscribed ) { - chan.getPIIU(guard)->subscriptionCancelRequest ( - guard, chan, *this ); - this->subscribed = false; - } -} - -void netSubscription::forceSubscriptionUpdate ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - chan.getPIIU(guard)->subscriptionUpdateRequest ( - guard, chan, *this ); -} - -void netSubscription::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - - - - - - - diff --git a/src/ca/client/netWriteNotifyIO.cpp b/src/ca/client/netWriteNotifyIO.cpp deleted file mode 100644 index afa9996d5..000000000 --- a/src/ca/client/netWriteNotifyIO.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include -#include - -#include "errlog.h" - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "iocinf.h" -#include "nciu.h" -#include "cac.h" - -netWriteNotifyIO::netWriteNotifyIO ( - privateInterfaceForIO & ioComplIntf, cacWriteNotify & notifyIn ) : - notify ( notifyIn ), privateChanForIO ( ioComplIntf ) -{ -} - -netWriteNotifyIO::~netWriteNotifyIO () -{ -} - -void netWriteNotifyIO::show ( unsigned /* level */ ) const -{ - ::printf ( "read write notify IO at %p\n", - static_cast < const void * > ( this ) ); -} - -void netWriteNotifyIO::show ( - epicsGuard < epicsMutex > &, - unsigned level ) const -{ - this->show ( level ); -} - -void netWriteNotifyIO::destroy ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle ) -{ - this->~netWriteNotifyIO (); - recycle.recycleWriteNotifyIO ( guard, *this ); -} - -void netWriteNotifyIO::completion ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle ) -{ - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->notify.completion ( guard ); - this->~netWriteNotifyIO (); - recycle.recycleWriteNotifyIO ( guard, *this ); -} - -void netWriteNotifyIO::completion ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle, - unsigned /* type */, arrayElementCount /* count */, - const void * /* pData */ ) -{ - //this->chan.getClient().printf ( "Write response with data ?\n" ); - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->~netWriteNotifyIO (); - recycle.recycleWriteNotifyIO ( guard, *this ); -} - -void netWriteNotifyIO::exception ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle, - int status, const char * pContext ) -{ - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->notify.exception ( - guard, status, pContext, UINT_MAX, 0u ); - this->~netWriteNotifyIO (); - recycle.recycleWriteNotifyIO ( guard, *this ); -} - -void netWriteNotifyIO::exception ( - epicsGuard < epicsMutex > & guard, - cacRecycle & recycle, - int status, const char *pContext, - unsigned type, arrayElementCount count ) -{ - this->privateChanForIO.ioCompletionNotify ( guard, *this ); - this->notify.exception ( - guard, status, pContext, type, count ); - this->~netWriteNotifyIO (); - recycle.recycleWriteNotifyIO ( guard, *this ); -} - -class netSubscription * netWriteNotifyIO::isSubscription () -{ - return 0; -} - -void netWriteNotifyIO::forceSubscriptionUpdate ( - epicsGuard < epicsMutex > &, nciu & ) -{ -} - -void netWriteNotifyIO::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - diff --git a/src/ca/client/net_convert.h b/src/ca/client/net_convert.h deleted file mode 100644 index bee51c0c4..000000000 --- a/src/ca/client/net_convert.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * Author: J. Hill - * - */ - -#ifndef _NET_CONVERT_H -#define _NET_CONVERT_H - -#include "db_access.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned long arrayElementCount; - -epicsShareFunc int caNetConvert ( - unsigned type, const void *pSrc, void *pDest, - int hton, arrayElementCount count ); - -#ifdef __cplusplus -} -#endif - -#endif /* define _NET_CONVERT_H */ diff --git a/src/ca/client/netiiu.cpp b/src/ca/client/netiiu.cpp deleted file mode 100644 index a81b15533..000000000 --- a/src/ca/client/netiiu.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include -#include // vxWorks 6.0 requires this include - -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "iocinf.h" -#include "cac.h" -#include "netiiu.h" - -netiiu::~netiiu () -{ -} - -bool netiiu::ca_v42_ok ( - epicsGuard < epicsMutex > & ) const -{ - return false; -} - -bool netiiu::ca_v41_ok ( - epicsGuard < epicsMutex > & ) const -{ - return false; -} - -void netiiu::writeRequest ( - epicsGuard < epicsMutex > &, nciu &, - unsigned, arrayElementCount, const void * ) -{ - throw cacChannel::notConnected(); -} - -void netiiu::writeNotifyRequest ( - epicsGuard < epicsMutex > &, - nciu &, netWriteNotifyIO &, unsigned, - arrayElementCount, const void * ) -{ - throw cacChannel::notConnected(); -} - -void netiiu::readNotifyRequest ( - epicsGuard < epicsMutex > &, - nciu &, netReadNotifyIO &, unsigned, arrayElementCount ) -{ - throw cacChannel::notConnected(); -} - -void netiiu::clearChannelRequest ( - epicsGuard < epicsMutex > &, ca_uint32_t, ca_uint32_t ) -{ -} - -void netiiu::subscriptionRequest ( - epicsGuard < epicsMutex > &, nciu &, netSubscription & ) -{ -} - -void netiiu::subscriptionCancelRequest ( - epicsGuard < epicsMutex > &, nciu &, netSubscription & ) -{ -} - -void netiiu::subscriptionUpdateRequest ( - epicsGuard < epicsMutex > &, nciu &, netSubscription & ) -{ -} - -static const char * const pHostNameNetIIU = ""; - -unsigned netiiu::getHostName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw () -{ - if ( bufLen ) { - unsigned len = strlen ( pHostNameNetIIU ); - strncpy ( pBuf, pHostNameNetIIU, bufLen ); - if ( len < bufLen ) { - return len; - } - else { - unsigned reducedSize = bufLen - 1u; - pBuf[reducedSize] = '\0'; - return reducedSize; - } - } - return 0u; -} - -const char * netiiu::pHostName ( - epicsGuard < epicsMutex > & ) const throw () -{ - return pHostNameNetIIU; -} - -osiSockAddr netiiu::getNetworkAddress ( - epicsGuard < epicsMutex > & ) const -{ - osiSockAddr addr; - addr.sa.sa_family = AF_UNSPEC; - return addr; -} - -void netiiu::flushRequest ( - epicsGuard < epicsMutex > & ) -{ -} - -unsigned netiiu::requestMessageBytesPending ( - epicsGuard < epicsMutex > & ) -{ - return 0u; -} - -void netiiu::flush ( - epicsGuard < epicsMutex > & ) -{ -} - -void netiiu::requestRecvProcessPostponedFlush ( - epicsGuard < epicsMutex > & ) -{ -} - -void netiiu::uninstallChan ( - epicsGuard < epicsMutex > &, nciu & ) -{ - throw cacChannel::notConnected(); -} - -double netiiu::receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const -{ - return - DBL_MAX; -} - -void netiiu::uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > &, nciu &, const epicsTime & ) -{ - throw std::runtime_error ( - "search response occured when not attached to udpiiu?" ); -} - -bool netiiu::searchMsg ( - epicsGuard < epicsMutex > &, ca_uint32_t /* id */, - const char * /* pName */, unsigned /* nameLength */ ) -{ - return false; -} - - diff --git a/src/ca/client/netiiu.h b/src/ca/client/netiiu.h deleted file mode 100644 index 2caa3d0fa..000000000 --- a/src/ca/client/netiiu.h +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef netiiuh -#define netiiuh - -#include "cacIO.h" -#include "caProto.h" - -class netWriteNotifyIO; -class netReadNotifyIO; -class netSubscription; -union osiSockAddr; -class cac; -class nciu; - -class netiiu { -public: - virtual ~netiiu () = 0; - virtual unsigned getHostName ( - epicsGuard < epicsMutex > &, char * pBuf, - unsigned bufLength ) const throw () = 0; - virtual const char * pHostName ( - epicsGuard < epicsMutex > & ) const throw () = 0; - virtual bool ca_v41_ok ( - epicsGuard < epicsMutex > & ) const = 0; - virtual bool ca_v42_ok ( - epicsGuard < epicsMutex > & ) const = 0; - virtual unsigned requestMessageBytesPending ( - epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0; - virtual void flush ( - epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0; - virtual void writeRequest ( - epicsGuard < epicsMutex > &, nciu &, - unsigned type, arrayElementCount nElem, - const void *pValue ) = 0; - virtual void writeNotifyRequest ( - epicsGuard < epicsMutex > &, - nciu &, netWriteNotifyIO &, - unsigned type, arrayElementCount nElem, - const void *pValue ) = 0; - virtual void readNotifyRequest ( - epicsGuard < epicsMutex > &, nciu &, - netReadNotifyIO &, unsigned type, - arrayElementCount nElem ) = 0; - virtual void clearChannelRequest ( - epicsGuard < epicsMutex > &, - ca_uint32_t sid, ca_uint32_t cid ) = 0; - virtual void subscriptionRequest ( - epicsGuard < epicsMutex > &, - nciu &, netSubscription & ) = 0; - virtual void subscriptionUpdateRequest ( - epicsGuard < epicsMutex > &, - nciu &, netSubscription & ) = 0; - virtual void subscriptionCancelRequest ( - epicsGuard < epicsMutex > &, - nciu & chan, netSubscription & subscr ) = 0; - virtual void flushRequest ( - epicsGuard < epicsMutex > & ) = 0; - virtual void requestRecvProcessPostponedFlush ( - epicsGuard < epicsMutex > & ) = 0; - virtual osiSockAddr getNetworkAddress ( - epicsGuard < epicsMutex > & ) const = 0; - virtual void uninstallChan ( - epicsGuard < epicsMutex > &, nciu & ) = 0; - virtual void uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > &, nciu &, - const class epicsTime & currentTime ) = 0; - virtual double receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const = 0; - virtual bool searchMsg ( - epicsGuard < epicsMutex > &, ca_uint32_t id, - const char * pName, unsigned nameLength ) = 0; -}; - -#endif // netiiuh diff --git a/src/ca/client/noopiiu.cpp b/src/ca/client/noopiiu.cpp deleted file mode 100644 index a3d20b59b..000000000 --- a/src/ca/client/noopiiu.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include "osiSock.h" - -#define epicsExportSharedSymbols -#include "noopiiu.h" - -noopiiu noopIIU; - -noopiiu::~noopiiu () -{ -} - -unsigned noopiiu::getHostName ( - epicsGuard < epicsMutex > & cacGuard, - char * pBuf, unsigned bufLength ) const throw () -{ - return netiiu::getHostName ( cacGuard, pBuf, bufLength ); -} - -const char * noopiiu::pHostName ( - epicsGuard < epicsMutex > & cacGuard ) const throw () -{ - return netiiu::pHostName ( cacGuard ); -} - -bool noopiiu::ca_v42_ok ( - epicsGuard < epicsMutex > & cacGuard ) const -{ - return netiiu::ca_v42_ok ( cacGuard ); -} - -bool noopiiu::ca_v41_ok ( - epicsGuard < epicsMutex > & cacGuard ) const -{ - return netiiu::ca_v41_ok ( cacGuard ); -} - -void noopiiu::writeRequest ( - epicsGuard < epicsMutex > & guard, - nciu & chan, unsigned type, - arrayElementCount nElem, const void * pValue ) -{ - netiiu::writeRequest ( guard, chan, type, nElem, pValue ); -} - -void noopiiu::writeNotifyRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, - netWriteNotifyIO & io, unsigned type, - arrayElementCount nElem, const void *pValue ) -{ - netiiu::writeNotifyRequest ( guard, chan, io, type, nElem, pValue ); -} - -void noopiiu::readNotifyRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, - netReadNotifyIO & io, unsigned type, arrayElementCount nElem ) -{ - netiiu::readNotifyRequest ( guard, chan, io, type, nElem ); -} - -void noopiiu::clearChannelRequest ( - epicsGuard < epicsMutex > & guard, - ca_uint32_t sid, ca_uint32_t cid ) -{ - netiiu::clearChannelRequest ( guard, sid, cid ); -} - -void noopiiu::subscriptionRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, - netSubscription & subscr ) -{ - netiiu::subscriptionRequest ( guard, chan, subscr ); -} - -void noopiiu::subscriptionUpdateRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, - netSubscription & subscr ) -{ - netiiu::subscriptionUpdateRequest ( - guard, chan, subscr ); -} - -void noopiiu::subscriptionCancelRequest ( - epicsGuard < epicsMutex > & guard, - nciu & chan, netSubscription & subscr ) -{ - netiiu::subscriptionCancelRequest ( guard, chan, subscr ); -} - -void noopiiu::flushRequest ( - epicsGuard < epicsMutex > & guard ) -{ - netiiu::flushRequest ( guard ); -} - -unsigned noopiiu::requestMessageBytesPending ( - epicsGuard < epicsMutex > & guard ) -{ - return netiiu::requestMessageBytesPending ( guard ); -} - -void noopiiu::flush ( - epicsGuard < epicsMutex > & guard ) -{ - netiiu::flush ( guard ); -} - -void noopiiu::requestRecvProcessPostponedFlush ( - epicsGuard < epicsMutex > & guard ) -{ - netiiu::requestRecvProcessPostponedFlush ( guard ); -} - -osiSockAddr noopiiu::getNetworkAddress ( - epicsGuard < epicsMutex > & guard ) const -{ - return netiiu::getNetworkAddress ( guard ); -} - -double noopiiu::receiveWatchdogDelay ( - epicsGuard < epicsMutex > & guard ) const -{ - return netiiu::receiveWatchdogDelay ( guard ); -} - -void noopiiu::uninstallChan ( - epicsGuard < epicsMutex > &, nciu & ) -{ - // intentionally does not call default in netiiu -} - -void noopiiu::uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > & guard, nciu & chan, - const class epicsTime & currentTime ) -{ - netiiu::uninstallChanDueToSuccessfulSearchResponse ( - guard, chan, currentTime ); -} - -bool noopiiu::searchMsg ( - epicsGuard < epicsMutex > & guard, ca_uint32_t id, - const char * pName, unsigned nameLength ) -{ - return netiiu::searchMsg ( - guard, id, pName, nameLength ); -} - diff --git a/src/ca/client/noopiiu.h b/src/ca/client/noopiiu.h deleted file mode 100644 index f373edec8..000000000 --- a/src/ca/client/noopiiu.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef noopiiuh -#define noopiiuh - -#include "netiiu.h" - -class noopiiu : public netiiu { -public: - ~noopiiu (); - unsigned getHostName ( - epicsGuard < epicsMutex > &, char * pBuf, - unsigned bufLength ) const throw (); - const char * pHostName ( - epicsGuard < epicsMutex > & ) const throw (); - bool ca_v41_ok ( - epicsGuard < epicsMutex > & ) const; - bool ca_v42_ok ( - epicsGuard < epicsMutex > & ) const; - unsigned requestMessageBytesPending ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void flush ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void writeRequest ( - epicsGuard < epicsMutex > &, nciu &, - unsigned type, arrayElementCount nElem, - const void *pValue ); - void writeNotifyRequest ( - epicsGuard < epicsMutex > &, - nciu &, netWriteNotifyIO &, - unsigned type, arrayElementCount nElem, - const void *pValue ); - void readNotifyRequest ( - epicsGuard < epicsMutex > &, nciu &, - netReadNotifyIO &, unsigned type, - arrayElementCount nElem ); - void clearChannelRequest ( - epicsGuard < epicsMutex > &, - ca_uint32_t sid, ca_uint32_t cid ); - void subscriptionRequest ( - epicsGuard < epicsMutex > &, - nciu &, netSubscription & ); - void subscriptionUpdateRequest ( - epicsGuard < epicsMutex > &, - nciu &, netSubscription & ); - void subscriptionCancelRequest ( - epicsGuard < epicsMutex > &, - nciu & chan, netSubscription & subscr ); - void flushRequest ( - epicsGuard < epicsMutex > & ); - void requestRecvProcessPostponedFlush ( - epicsGuard < epicsMutex > & ); - osiSockAddr getNetworkAddress ( - epicsGuard < epicsMutex > & ) const; - void uninstallChan ( - epicsGuard < epicsMutex > & mutex, - nciu & ); - void uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > &, nciu &, - const class epicsTime & currentTime ); - double receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const; - bool searchMsg ( - epicsGuard < epicsMutex > &, ca_uint32_t id, - const char * pName, unsigned nameLength ); -}; - -extern noopiiu noopIIU; - -#endif // ifndef noopiiuh diff --git a/src/ca/client/oldAccess.h b/src/ca/client/oldAccess.h deleted file mode 100644 index c893eeb68..000000000 --- a/src/ca/client/oldAccess.h +++ /dev/null @@ -1,612 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef oldAccessh -#define oldAccessh - -#include - -#ifdef epicsExportSharedSymbols -# define oldAccessh_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "tsFreeList.h" -#include "compilerDependencies.h" -#include "osiSock.h" - -#ifdef oldAccessh_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "caProto.h" -#include "cacIO.h" -#include "cadef.h" -#include "syncGroup.h" - -struct oldChannelNotify : private cacChannelNotify { -public: - oldChannelNotify ( - epicsGuard < epicsMutex > &, struct ca_client_context &, - const char * pName, caCh * pConnCallBackIn, - void * pPrivateIn, capri priority ); - void destructor ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & mutexGuard ); - - // legacy C API - friend unsigned epicsShareAPI ca_get_host_name ( - chid pChan, char * pBuf, unsigned bufLength ); - friend const char * epicsShareAPI ca_host_name ( - chid pChan ); - friend const char * epicsShareAPI ca_name ( - chid pChan ); - friend void epicsShareAPI ca_set_puser ( - chid pChan, void * puser ); - friend void * epicsShareAPI ca_puser ( - chid pChan ); - friend int epicsShareAPI ca_change_connection_event ( - chid pChan, caCh * pfunc ); - friend int epicsShareAPI ca_replace_access_rights_event ( - chid pChan, caArh *pfunc ); - friend int epicsShareAPI ca_array_get ( chtype type, - arrayElementCount count, chid pChan, void * pValue ); - friend int epicsShareAPI ca_array_get_callback ( chtype type, - arrayElementCount count, chid pChan, - caEventCallBackFunc *pfunc, void *arg ); - friend int epicsShareAPI ca_array_put ( - chtype type, arrayElementCount count, - chid pChan, const void * pValue ); - friend int epicsShareAPI ca_array_put_callback ( - chtype type, arrayElementCount count, - chid pChan, const void *pValue, - caEventCallBackFunc *pfunc, void *usrarg ); - friend double epicsShareAPI ca_beacon_period ( - chid pChan ); - friend unsigned epicsShareAPI ca_search_attempts ( - chid pChan ); - friend unsigned epicsShareAPI ca_write_access ( - chid pChan ); - friend unsigned epicsShareAPI ca_read_access ( - chid pChan ); - friend short epicsShareAPI ca_field_type ( - chid pChan ); - friend arrayElementCount epicsShareAPI ca_element_count ( - chid pChan ); - friend int epicsShareAPI ca_v42_ok ( - chid pChan ); - friend int epicsShareAPI ca_create_subscription ( - chtype type, arrayElementCount count, chid pChan, - long mask, caEventCallBackFunc * pCallBack, - void * pCallBackArg, evid * monixptr ); - friend enum channel_state epicsShareAPI ca_state ( - chid pChan ); - friend double epicsShareAPI ca_receive_watchdog_delay ( - chid pChan ); - - unsigned getName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw (); - void show ( - epicsGuard < epicsMutex > &, - unsigned level ) const; - void initiateConnect ( - epicsGuard < epicsMutex > & ); - void read ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, - cacReadNotify ¬ify, cacChannel::ioid *pId = 0 ); - void write ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, const void *pValue, - cacWriteNotify &, cacChannel::ioid *pId = 0 ); - void ioCancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - const cacChannel::ioid & ); - void ioShow ( - epicsGuard < epicsMutex > & guard, - const cacChannel::ioid &, unsigned level ) const; - ca_client_context & getClientCtx (); - void eliminateExcessiveSendBacklog ( - epicsGuard < epicsMutex > & ); - - void * operator new ( size_t size, - tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void * , - tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & )) -protected: - ~oldChannelNotify (); -private: - ca_client_context & cacCtx; - cacChannel & io; - caCh * pConnCallBack; - void * pPrivate; - caArh * pAccessRightsFunc; - unsigned ioSeqNo; - bool currentlyConnected; - bool prevConnected; - void connectNotify ( epicsGuard < epicsMutex > & ); - void disconnectNotify ( epicsGuard < epicsMutex > & ); - void serviceShutdownNotify ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void accessRightsNotify ( - epicsGuard < epicsMutex > &, const caAccessRights & ); - void exception ( epicsGuard < epicsMutex > &, - int status, const char * pContext ); - void readException ( epicsGuard < epicsMutex > &, - int status, const char * pContext, - unsigned type, arrayElementCount count, void *pValue ); - void writeException ( epicsGuard < epicsMutex > &, - int status, const char * pContext, - unsigned type, arrayElementCount count ); - oldChannelNotify ( const oldChannelNotify & ); - oldChannelNotify & operator = ( const oldChannelNotify & ); - void operator delete ( void * ); -}; - -class getCopy : public cacReadNotify { -public: - getCopy ( - epicsGuard < epicsMutex > & guard, - ca_client_context & cacCtx, - oldChannelNotify &, unsigned type, - arrayElementCount count, void *pValue ); - ~getCopy (); - void show ( unsigned level ) const; - void cancel (); - void * operator new ( size_t size, - tsFreeList < class getCopy, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class getCopy, 1024, epicsMutexNOOP > & )) -private: - arrayElementCount count; - ca_client_context & cacCtx; - oldChannelNotify & chan; - void * pValue; - unsigned ioSeqNo; - unsigned type; - void completion ( - epicsGuard < epicsMutex > &, unsigned type, - arrayElementCount count, const void *pData ); - void exception ( - epicsGuard < epicsMutex > &, int status, - const char *pContext, unsigned type, arrayElementCount count ); - getCopy ( const getCopy & ); - getCopy & operator = ( const getCopy & ); - void operator delete ( void * ); -}; - -class getCallback : public cacReadNotify { -public: - getCallback ( - oldChannelNotify & chanIn, - caEventCallBackFunc *pFunc, void *pPrivate ); - ~getCallback (); - void * operator new ( size_t size, - tsFreeList < class getCallback, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class getCallback, 1024, epicsMutexNOOP > & )) -private: - oldChannelNotify & chan; - caEventCallBackFunc * pFunc; - void * pPrivate; - void completion ( - epicsGuard < epicsMutex > &, unsigned type, - arrayElementCount count, const void *pData); - void exception ( - epicsGuard < epicsMutex > &, int status, - const char * pContext, unsigned type, arrayElementCount count ); - getCallback ( const getCallback & ); - getCallback & operator = ( const getCallback & ); - void operator delete ( void * ); -}; - -class putCallback : public cacWriteNotify { -public: - putCallback ( - oldChannelNotify &, - caEventCallBackFunc *pFunc, void *pPrivate ); - ~putCallback (); - void * operator new ( size_t size, - tsFreeList < class putCallback, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class putCallback, 1024, epicsMutexNOOP > & )) -private: - oldChannelNotify & chan; - caEventCallBackFunc * pFunc; - void *pPrivate; - void completion ( epicsGuard < epicsMutex > & ); - void exception ( - epicsGuard < epicsMutex > &, int status, const char *pContext, - unsigned type, arrayElementCount count ); - putCallback ( const putCallback & ); - putCallback & operator = ( const putCallback & ); - void operator delete ( void * ); -}; - -struct oldSubscription : private cacStateNotify { -public: - oldSubscription ( - epicsGuard < epicsMutex > & guard, - oldChannelNotify & chanIn, cacChannel & io, - unsigned type, arrayElementCount nElem, unsigned mask, - caEventCallBackFunc * pFuncIn, void * pPrivateIn, - evid * ); - ~oldSubscription (); - oldChannelNotify & channel () const; - // The primary mutex must be released when calling the user's - // callback, and therefore a finite interval exists when we are - // moving forward with the intent to call the users callback - // but the users IO could be deleted during this interval. - // To prevent the user's callback from being called after - // destroying his IO we must past a guard for the callback - // mutex here. - void cancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void * operator new ( size_t size, - tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & )) -private: - oldChannelNotify & chan; - cacChannel::ioid id; - caEventCallBackFunc * pFunc; - void * pPrivate; - void current ( - epicsGuard < epicsMutex > &, unsigned type, - arrayElementCount count, const void *pData ); - void exception ( - epicsGuard < epicsMutex > &, int status, - const char *pContext, unsigned type, arrayElementCount count ); - oldSubscription ( const oldSubscription & ); - oldSubscription & operator = ( const oldSubscription & ); - void operator delete ( void * ); -}; - -extern "C" void cacOnceFunc ( void * ); -extern "C" void cacExitHandler ( void *); - -struct ca_client_context : public cacContextNotify -{ -public: - ca_client_context ( bool enablePreemptiveCallback = false ); - virtual ~ca_client_context (); - void changeExceptionEvent ( - caExceptionHandler * pfunc, void * arg ); - void registerForFileDescriptorCallBack ( - CAFDHANDLER * pFunc, void * pArg ); - void replaceErrLogHandler ( caPrintfFunc * ca_printf_func ); - cacChannel & createChannel ( - epicsGuard < epicsMutex > &, const char * pChannelName, - cacChannelNotify &, cacChannel::priLev pri ); - void flush ( epicsGuard < epicsMutex > & ); - void eliminateExcessiveSendBacklog ( - epicsGuard < epicsMutex > &, cacChannel & ); - int pendIO ( const double & timeout ); - int pendEvent ( const double & timeout ); - bool ioComplete () const; - void show ( unsigned level ) const; - unsigned circuitCount () const; - unsigned sequenceNumberOfOutstandingIO ( - epicsGuard < epicsMutex > & ) const; - unsigned beaconAnomaliesSinceProgramStart () const; - void incrementOutstandingIO ( - epicsGuard < epicsMutex > &, unsigned ioSeqNo ); - void decrementOutstandingIO ( - epicsGuard < epicsMutex > &, unsigned ioSeqNo ); - void exception ( - epicsGuard < epicsMutex > &, int status, const char * pContext, - const char * pFileName, unsigned lineNo ); - void exception ( - epicsGuard < epicsMutex > &, int status, const char * pContext, - const char * pFileName, unsigned lineNo, oldChannelNotify & chan, - unsigned type, arrayElementCount count, unsigned op ); - void blockForEventAndEnableCallbacks ( - epicsEvent & event, const double & timeout ); - CASG * lookupCASG ( epicsGuard < epicsMutex > &, unsigned id ); - static void installDefaultService ( cacService & ); - void installCASG ( epicsGuard < epicsMutex > &, CASG & ); - void uninstallCASG ( epicsGuard < epicsMutex > &, CASG & ); - void selfTest () const; -// perhaps these should be eliminated in deference to the exception mechanism - int printFormated ( const char * pformat, ... ) const; - int varArgsPrintFormated ( const char * pformat, va_list args ) const; - void signal ( int ca_status, const char * pfilenm, - int lineno, const char * pFormat, ... ); - void vSignal ( int ca_status, const char * pfilenm, - int lineno, const char *pFormat, va_list args ); - bool preemptiveCallbakIsEnabled () const; - void destroyGetCopy ( epicsGuard < epicsMutex > &, getCopy & ); - void destroyGetCallback ( epicsGuard < epicsMutex > &, getCallback & ); - void destroyPutCallback ( epicsGuard < epicsMutex > &, putCallback & ); - void destroySubscription ( epicsGuard < epicsMutex > &, oldSubscription & ); - epicsMutex & mutexRef () const; - - template < class T > - void whenThereIsAnExceptionDestroySyncGroupIO ( epicsGuard < epicsMutex > &, T & ); - - // legacy C API - friend int epicsShareAPI ca_create_channel ( - const char * name_str, caCh * conn_func, void * puser, - capri priority, chid * chanptr ); - friend int epicsShareAPI ca_clear_channel ( chid pChan ); - friend int epicsShareAPI ca_array_get ( chtype type, - arrayElementCount count, chid pChan, void * pValue ); - friend int epicsShareAPI ca_array_get_callback ( chtype type, - arrayElementCount count, chid pChan, - caEventCallBackFunc *pfunc, void *arg ); - friend int epicsShareAPI ca_array_put ( chtype type, - arrayElementCount count, chid pChan, const void * pValue ); - friend int epicsShareAPI ca_array_put_callback ( chtype type, - arrayElementCount count, chid pChan, const void * pValue, - caEventCallBackFunc *pfunc, void *usrarg ); - friend int epicsShareAPI ca_create_subscription ( - chtype type, arrayElementCount count, chid pChan, - long mask, caEventCallBackFunc * pCallBack, void * pCallBackArg, - evid *monixptr ); - friend int epicsShareAPI ca_flush_io (); - friend int epicsShareAPI ca_clear_subscription ( evid pMon ); - friend int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid ); - friend int epicsShareAPI ca_sg_delete ( const CA_SYNC_GID gid ); - friend int epicsShareAPI ca_sg_block ( const CA_SYNC_GID gid, ca_real timeout ); - friend int epicsShareAPI ca_sg_reset ( const CA_SYNC_GID gid ); - friend int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid ); - friend int epicsShareAPI ca_sg_array_get ( const CA_SYNC_GID gid, - chtype type, arrayElementCount count, - chid pChan, void *pValue ); - friend int epicsShareAPI ca_sg_array_put ( const CA_SYNC_GID gid, - chtype type, arrayElementCount count, - chid pChan, const void *pValue ); - friend int ca_sync_group_destroy ( CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard, - ca_client_context & cac, const CA_SYNC_GID gid ); - friend void sync_group_reset ( ca_client_context & client, - CASG & sg ); - - // exceptions - class noSocket {}; -private: - chronIntIdResTable < CASG > sgTable; - tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > oldChannelNotifyFreeList; - tsFreeList < class getCopy, 1024, epicsMutexNOOP > getCopyFreeList; - tsFreeList < class getCallback, 1024, epicsMutexNOOP > getCallbackFreeList; - tsFreeList < class putCallback, 1024, epicsMutexNOOP > putCallbackFreeList; - tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > subscriptionFreeList; - tsFreeList < struct CASG, 128, epicsMutexNOOP > casgFreeList; - mutable epicsMutex mutex; - mutable epicsMutex cbMutex; - epicsEvent ioDone; - epicsEvent callbackThreadActivityComplete; - epicsThreadId createdByThread; - std::auto_ptr < CallbackGuard > pCallbackGuard; - std::auto_ptr < cacContext > pServiceContext; - caExceptionHandler * ca_exception_func; - void * ca_exception_arg; - caPrintfFunc * pVPrintfFunc; - CAFDHANDLER * fdRegFunc; - void * fdRegArg; - SOCKET sock; - unsigned pndRecvCnt; - unsigned ioSeqNo; - unsigned callbackThreadsPending; - ca_uint16_t localPort; - bool fdRegFuncNeedsToBeCalled; - bool noWakeupSincePend; - - void attachToClientCtx (); - void callbackProcessingInitiateNotify (); - void callbackProcessingCompleteNotify (); - cacContext & createNetworkContext ( - epicsMutex & mutualExclusion, epicsMutex & callbackControl ); - void _sendWakeupMsg (); - - ca_client_context ( const ca_client_context & ); - ca_client_context & operator = ( const ca_client_context & ); - - friend void cacOnceFunc ( void * ); - friend void cacExitHandler ( void *); - static cacService * pDefaultService; - static epicsMutex * pDefaultServiceInstallMutex; - static const unsigned flushBlockThreshold; -}; - -int fetchClientContext ( ca_client_context * * ppcac ); - -inline ca_client_context & oldChannelNotify::getClientCtx () -{ - return this->cacCtx; -} - -inline unsigned oldChannelNotify::getName ( - epicsGuard < epicsMutex > & guard, - char * pBuf, unsigned bufLen ) const throw () -{ - return this->io.getName ( guard, pBuf, bufLen ); -} - -inline void oldChannelNotify::show ( - epicsGuard < epicsMutex > & guard, - unsigned level ) const -{ - this->io.show ( guard, level ); -} - -inline void oldChannelNotify::initiateConnect ( - epicsGuard < epicsMutex > & guard ) -{ - this->io.initiateConnect ( guard ); -} - -inline void oldChannelNotify::ioCancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - const cacChannel::ioid & id ) -{ - this->io.ioCancel ( callbackGuard, mutualExclusionGuard, id ); -} - -inline void oldChannelNotify::ioShow ( - epicsGuard < epicsMutex > & guard, - const cacChannel::ioid & id, unsigned level ) const -{ - this->io.ioShow ( guard, id, level ); -} - -inline void oldChannelNotify::eliminateExcessiveSendBacklog ( - epicsGuard < epicsMutex > & guard ) -{ - this->cacCtx.eliminateExcessiveSendBacklog ( guard, this->io ); -} - -inline void * oldChannelNotify::operator new ( size_t size, - tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void oldChannelNotify::operator delete ( void *pCadaver, - tsFreeList < struct oldChannelNotify, 1024, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline void * oldSubscription::operator new ( size_t size, - tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void oldSubscription::operator delete ( void *pCadaver, - tsFreeList < struct oldSubscription, 1024, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline void oldSubscription::cancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ) -{ - this->chan.ioCancel ( callbackGuard, mutualExclusionGuard, this->id ); -} - -inline oldChannelNotify & oldSubscription::channel () const -{ - return this->chan; -} - -inline void * getCopy::operator new ( size_t size, - tsFreeList < class getCopy, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void getCopy::operator delete ( void *pCadaver, - tsFreeList < class getCopy, 1024, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline void * putCallback::operator new ( size_t size, - tsFreeList < class putCallback, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void putCallback::operator delete ( void * pCadaver, - tsFreeList < class putCallback, 1024, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline void * getCallback::operator new ( size_t size, - tsFreeList < class getCallback, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void getCallback::operator delete ( void * pCadaver, - tsFreeList < class getCallback, 1024, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline bool ca_client_context::preemptiveCallbakIsEnabled () const -{ - return this->pCallbackGuard.get () == 0; -} - -inline bool ca_client_context::ioComplete () const -{ - return ( this->pndRecvCnt == 0u ); -} - -inline unsigned ca_client_context::sequenceNumberOfOutstandingIO ( - epicsGuard < epicsMutex > & ) const -{ - // perhaps on SMP systems THERE should be lock/unlock around this - return this->ioSeqNo; -} - -template < class T > -void ca_client_context :: whenThereIsAnExceptionDestroySyncGroupIO ( - epicsGuard < epicsMutex > & guard, T & io ) -{ - if ( this->pCallbackGuard.get() && - this->createdByThread == epicsThreadGetIdSelf () ) { - io.destroy ( *this->pCallbackGuard.get(), guard ); - } - else { - // dont reverse the lock hierarchy - epicsGuardRelease < epicsMutex > guardRelease ( guard ); - { - // - // we will definately stall out here if all of the - // following are true - // - // o user creates non-preemtive mode client library context - // o user doesnt periodically call a ca function - // o user calls this function from an auxiillary thread - // - CallbackGuard cbGuard ( this->cbMutex ); - epicsGuard < epicsMutex > guard ( this->mutex ); - io.destroy ( cbGuard, guard ); - } - } -} - -#endif // ifndef oldAccessh diff --git a/src/ca/client/oldChannelNotify.cpp b/src/ca/client/oldChannelNotify.cpp deleted file mode 100644 index 5775bcc6b..000000000 --- a/src/ca/client/oldChannelNotify.cpp +++ /dev/null @@ -1,709 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#ifdef _MSC_VER -# pragma warning(disable:4355) -#endif - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "oldAccess.h" -#include "cac.h" -#include "autoPtrFreeList.h" - -extern "C" void cacNoopAccesRightsHandler ( struct access_rights_handler_args ) -{ -} - -oldChannelNotify::oldChannelNotify ( - epicsGuard < epicsMutex > & guard, ca_client_context & cacIn, - const char *pName, caCh * pConnCallBackIn, - void * pPrivateIn, capri priority ) : - cacCtx ( cacIn ), - io ( cacIn.createChannel ( guard, pName, *this, priority ) ), - pConnCallBack ( pConnCallBackIn ), - pPrivate ( pPrivateIn ), pAccessRightsFunc ( cacNoopAccesRightsHandler ), - ioSeqNo ( 0 ), currentlyConnected ( false ), prevConnected ( false ) -{ - guard.assertIdenticalMutex ( cacIn.mutexRef () ); - this->ioSeqNo = cacIn.sequenceNumberOfOutstandingIO ( guard ); - if ( pConnCallBackIn == 0 ) { - cacIn.incrementOutstandingIO ( guard, this->ioSeqNo ); - } -} - -oldChannelNotify::~oldChannelNotify () -{ -} - -void oldChannelNotify::destructor ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & mutexGuard ) -{ - mutexGuard.assertIdenticalMutex ( this->cacCtx.mutexRef () ); - this->io.destroy ( cbGuard, mutexGuard ); - // no need to worry about a connect preempting here because - // the io (the nciu) has been destroyed above - if ( this->pConnCallBack == 0 && ! this->currentlyConnected ) { - this->cacCtx.decrementOutstandingIO ( mutexGuard, this->ioSeqNo ); - } - this->~oldChannelNotify (); -} - -void oldChannelNotify::connectNotify ( - epicsGuard < epicsMutex > & guard ) -{ - this->currentlyConnected = true; - this->prevConnected = true; - if ( this->pConnCallBack ) { - struct connection_handler_args args; - args.chid = this; - args.op = CA_OP_CONN_UP; - caCh * pFunc = this->pConnCallBack; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - ( *pFunc ) ( args ); - } - } - else { - this->cacCtx.decrementOutstandingIO ( guard, this->ioSeqNo ); - } -} - -void oldChannelNotify::disconnectNotify ( - epicsGuard < epicsMutex > & guard ) -{ - this->currentlyConnected = false; - if ( this->pConnCallBack ) { - struct connection_handler_args args; - args.chid = this; - args.op = CA_OP_CONN_DOWN; - caCh * pFunc = this->pConnCallBack; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - ( *pFunc ) ( args ); - } - } - else { - this->cacCtx.incrementOutstandingIO ( - guard, this->ioSeqNo ); - } -} - -void oldChannelNotify::serviceShutdownNotify ( - epicsGuard < epicsMutex > & guard ) -{ - this->disconnectNotify ( guard ); -} - -void oldChannelNotify::accessRightsNotify ( - epicsGuard < epicsMutex > & guard, const caAccessRights & ar ) -{ - struct access_rights_handler_args args; - args.chid = this; - args.ar.read_access = ar.readPermit(); - args.ar.write_access = ar.writePermit(); - caArh * pFunc = this->pAccessRightsFunc; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - ( *pFunc ) ( args ); - } -} - -void oldChannelNotify::exception ( - epicsGuard < epicsMutex > & guard, int status, const char * pContext ) -{ - this->cacCtx.exception ( guard, status, pContext, __FILE__, __LINE__ ); -} - -void oldChannelNotify::readException ( - epicsGuard < epicsMutex > & guard, int status, const char *pContext, - unsigned type, arrayElementCount count, void * /* pValue */ ) -{ - this->cacCtx.exception ( guard, status, pContext, - __FILE__, __LINE__, *this, type, count, CA_OP_GET ); -} - -void oldChannelNotify::writeException ( - epicsGuard < epicsMutex > & guard, int status, const char *pContext, - unsigned type, arrayElementCount count ) -{ - this->cacCtx.exception ( guard, status, pContext, - __FILE__, __LINE__, *this, type, count, CA_OP_PUT ); -} - -void oldChannelNotify::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -/* - * ca_get_host_name () - */ -unsigned epicsShareAPI ca_get_host_name ( - chid pChan, char * pBuf, unsigned bufLength ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef() ); - return pChan->io.getHostName ( guard, pBuf, bufLength ); -} - -/* - * ca_host_name () - * - * !!!! not thread safe !!!! - * - */ -const char * epicsShareAPI ca_host_name ( - chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.pHostName ( guard ); -} - -/* - * ca_set_puser () - */ -void epicsShareAPI ca_set_puser ( - chid pChan, void * puser ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->pPrivate = puser; -} - -/* - * ca_get_puser () - */ -void * epicsShareAPI ca_puser ( - chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->pPrivate; -} - -/* - * Specify an event subroutine to be run for connection events - */ -int epicsShareAPI ca_change_connection_event ( chid pChan, caCh * pfunc ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - if ( ! pChan->currentlyConnected ) { - if ( pfunc ) { - if ( ! pChan->pConnCallBack ) { - pChan->cacCtx.decrementOutstandingIO ( guard, pChan->ioSeqNo ); - } - } - else { - if ( pChan->pConnCallBack ) { - pChan->cacCtx.incrementOutstandingIO ( guard, pChan->ioSeqNo ); - } - } - } - pChan->pConnCallBack = pfunc; - return ECA_NORMAL; -} - -/* - * ca_replace_access_rights_event - */ -int epicsShareAPI ca_replace_access_rights_event ( - chid pChan, caArh *pfunc ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - - // The order of the following is significant to guarantee that the - // access rights handler is always gets called even if the channel connects - // while this is running. There is some very small chance that the - // handler could be called twice here with the same access rights state, but - // that will not upset the application. - pChan->pAccessRightsFunc = pfunc ? pfunc : cacNoopAccesRightsHandler; - caAccessRights tmp = pChan->io.accessRights ( guard ); - - if ( pChan->currentlyConnected ) { - struct access_rights_handler_args args; - args.chid = pChan; - args.ar.read_access = tmp.readPermit (); - args.ar.write_access = tmp.writePermit (); - epicsGuardRelease < epicsMutex > unguard ( guard ); - ( *pChan->pAccessRightsFunc ) ( args ); - } - return ECA_NORMAL; -} - -/* - * ca_array_get () - */ -int epicsShareAPI ca_array_get ( chtype type, - arrayElementCount count, chid pChan, void *pValue ) -{ - int caStatus; - try { - if ( type < 0 ) { - return ECA_BADTYPE; - } - if ( count == 0 ) - return ECA_BADCOUNT; - - unsigned tmpType = static_cast < unsigned > ( type ); - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->eliminateExcessiveSendBacklog ( guard ); - autoPtrFreeList < getCopy, 0x400, epicsMutexNOOP > pNotify - ( pChan->getClientCtx().getCopyFreeList, - new ( pChan->getClientCtx().getCopyFreeList ) - getCopy ( guard, pChan->getClientCtx(), *pChan, - tmpType, count, pValue ) ); - pChan->io.read ( guard, type, count, *pNotify, 0 ); - pNotify.release (); - caStatus = ECA_NORMAL; - } - catch ( cacChannel::badString & ) - { - caStatus = ECA_BADSTR; - } - catch ( cacChannel::badType & ) - { - caStatus = ECA_BADTYPE; - } - catch ( cacChannel::outOfBounds & ) - { - caStatus = ECA_BADCOUNT; - } - catch ( cacChannel::noReadAccess & ) - { - caStatus = ECA_NORDACCESS; - } - catch ( cacChannel::notConnected & ) - { - caStatus = ECA_DISCONN; - } - catch ( cacChannel::unsupportedByService & ) - { - caStatus = ECA_UNAVAILINSERV; - } - catch ( cacChannel::requestTimedOut & ) - { - caStatus = ECA_TIMEOUT; - } - catch ( std::bad_alloc & ) - { - caStatus = ECA_ALLOCMEM; - } - catch ( cacChannel::msgBodyCacheTooSmall & ) { - caStatus = ECA_TOLARGE; - } - catch ( ... ) - { - caStatus = ECA_GETFAIL; - } - return caStatus; -} - -/* - * ca_array_get_callback () - */ -int epicsShareAPI ca_array_get_callback ( chtype type, - arrayElementCount count, chid pChan, - caEventCallBackFunc *pfunc, void *arg ) -{ - int caStatus; - try { - if ( type < 0 ) { - return ECA_BADTYPE; - } - if ( pfunc == NULL ) { - return ECA_BADFUNCPTR; - } - unsigned tmpType = static_cast < unsigned > ( type ); - - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->eliminateExcessiveSendBacklog ( guard ); - autoPtrFreeList < getCallback, 0x400, epicsMutexNOOP > pNotify - ( pChan->getClientCtx().getCallbackFreeList, - new ( pChan->getClientCtx().getCallbackFreeList ) - getCallback ( *pChan, pfunc, arg ) ); - pChan->io.read ( guard, tmpType, count, *pNotify, 0 ); - pNotify.release (); - caStatus = ECA_NORMAL; - } - catch ( cacChannel::badString & ) - { - caStatus = ECA_BADSTR; - } - catch ( cacChannel::badType & ) - { - caStatus = ECA_BADTYPE; - } - catch ( cacChannel::outOfBounds & ) - { - caStatus = ECA_BADCOUNT; - } - catch ( cacChannel::noReadAccess & ) - { - caStatus = ECA_NORDACCESS; - } - catch ( cacChannel::notConnected & ) - { - caStatus = ECA_DISCONN; - } - catch ( cacChannel::unsupportedByService & ) - { - caStatus = ECA_UNAVAILINSERV; - } - catch ( cacChannel::requestTimedOut & ) - { - caStatus = ECA_TIMEOUT; - } - catch ( std::bad_alloc & ) - { - caStatus = ECA_ALLOCMEM; - } - catch ( cacChannel::msgBodyCacheTooSmall ) { - caStatus = ECA_TOLARGE; - } - catch ( ... ) - { - caStatus = ECA_GETFAIL; - } - return caStatus; -} - -void oldChannelNotify::read ( - epicsGuard < epicsMutex > & guard, - unsigned type, arrayElementCount count, - cacReadNotify & notify, cacChannel::ioid * pId ) -{ - this->io.read ( guard, type, count, notify, pId ); -} - -/* - * ca_array_put_callback () - */ -int epicsShareAPI ca_array_put_callback ( chtype type, arrayElementCount count, - chid pChan, const void *pValue, caEventCallBackFunc *pfunc, void *usrarg ) -{ - int caStatus; - try { - if ( type < 0 ) { - return ECA_BADTYPE; - } - if ( pfunc == NULL ) { - return ECA_BADFUNCPTR; - } - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->eliminateExcessiveSendBacklog ( guard ); - unsigned tmpType = static_cast < unsigned > ( type ); - autoPtrFreeList < putCallback, 0x400, epicsMutexNOOP > pNotify - ( pChan->getClientCtx().putCallbackFreeList, - new ( pChan->getClientCtx().putCallbackFreeList ) - putCallback ( *pChan, pfunc, usrarg ) ); - pChan->io.write ( guard, tmpType, count, pValue, *pNotify, 0 ); - pNotify.release (); - caStatus = ECA_NORMAL; - } - catch ( cacChannel::badString & ) - { - caStatus = ECA_BADSTR; - } - catch ( cacChannel::badType & ) - { - caStatus = ECA_BADTYPE; - } - catch ( cacChannel::outOfBounds & ) - { - caStatus = ECA_BADCOUNT; - } - catch ( cacChannel::noWriteAccess & ) - { - caStatus = ECA_NOWTACCESS; - } - catch ( cacChannel::notConnected & ) - { - caStatus = ECA_DISCONN; - } - catch ( cacChannel::unsupportedByService & ) - { - caStatus = ECA_UNAVAILINSERV; - } - catch ( cacChannel::requestTimedOut & ) - { - caStatus = ECA_TIMEOUT; - } - catch ( std::bad_alloc & ) - { - caStatus = ECA_ALLOCMEM; - } - catch ( ... ) - { - caStatus = ECA_PUTFAIL; - } - return caStatus; -} - -/* - * ca_array_put () - */ -int epicsShareAPI ca_array_put ( chtype type, arrayElementCount count, - chid pChan, const void * pValue ) -{ - if ( type < 0 ) { - return ECA_BADTYPE; - } - unsigned tmpType = static_cast < unsigned > ( type ); - - int caStatus; - try { - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - pChan->eliminateExcessiveSendBacklog ( guard ); - pChan->io.write ( guard, tmpType, count, pValue ); - caStatus = ECA_NORMAL; - } - catch ( cacChannel::badString & ) - { - caStatus = ECA_BADSTR; - } - catch ( cacChannel::badType & ) - { - caStatus = ECA_BADTYPE; - } - catch ( cacChannel::outOfBounds & ) - { - caStatus = ECA_BADCOUNT; - } - catch ( cacChannel::noWriteAccess & ) - { - caStatus = ECA_NOWTACCESS; - } - catch ( cacChannel::notConnected & ) - { - caStatus = ECA_DISCONN; - } - catch ( cacChannel::unsupportedByService & ) - { - caStatus = ECA_UNAVAILINSERV; - } - catch ( cacChannel::requestTimedOut & ) - { - caStatus = ECA_TIMEOUT; - } - catch ( std::bad_alloc & ) - { - caStatus = ECA_ALLOCMEM; - } - catch ( ... ) - { - caStatus = ECA_PUTFAIL; - } - return caStatus; -} - -int epicsShareAPI ca_create_subscription ( - chtype type, arrayElementCount count, chid pChan, - long mask, caEventCallBackFunc * pCallBack, void * pCallBackArg, - evid * monixptr ) -{ - if ( type < 0 ) { - return ECA_BADTYPE; - } - unsigned tmpType = static_cast < unsigned > ( type ); - - if ( INVALID_DB_REQ (type) ) { - return ECA_BADTYPE; - } - - if ( pCallBack == NULL ) { - return ECA_BADFUNCPTR; - } - - static const long maskMask = 0xffff; - if ( ( mask & maskMask ) == 0) { - return ECA_BADMASK; - } - - if ( mask & ~maskMask ) { - return ECA_BADMASK; - } - - try { - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - try { - // if this stalls out on a live circuit then an exception - // can be forthcoming which we must ignore (this is a - // special case preserving legacy ca_create_subscription - // behavior) - pChan->eliminateExcessiveSendBacklog ( guard ); - } - catch ( cacChannel::notConnected & ) { - // intentionally ignored (its ok to subscribe when not connected) - } - new ( pChan->getClientCtx().subscriptionFreeList ) - oldSubscription ( - guard, *pChan, pChan->io, tmpType, count, mask, - pCallBack, pCallBackArg, monixptr ); - // dont touch object created after above new because - // the first callback might have canceled, and therefore - // destroyed, it - return ECA_NORMAL; - } - catch ( cacChannel::badType & ) - { - return ECA_BADTYPE; - } - catch ( cacChannel::outOfBounds & ) - { - return ECA_BADCOUNT; - } - catch ( cacChannel::badEventSelection & ) - { - return ECA_BADMASK; - } - catch ( cacChannel::noReadAccess & ) - { - return ECA_NORDACCESS; - } - catch ( cacChannel::unsupportedByService & ) - { - return ECA_UNAVAILINSERV; - } - catch ( std::bad_alloc & ) - { - return ECA_ALLOCMEM; - } - catch ( cacChannel::msgBodyCacheTooSmall & ) { - return ECA_TOLARGE; - } - catch ( ... ) - { - return ECA_INTERNAL; - } -} - -void oldChannelNotify::write ( - epicsGuard < epicsMutex > & guard, unsigned type, arrayElementCount count, - const void * pValue, cacWriteNotify & notify, cacChannel::ioid * pId ) -{ - this->io.write ( guard, type, count, pValue, notify, pId ); -} - -/* - * ca_field_type() - */ -short epicsShareAPI ca_field_type ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.nativeType ( guard ); -} - -/* - * ca_element_count () - */ -arrayElementCount epicsShareAPI ca_element_count ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.nativeElementCount ( guard ); -} - -/* - * ca_state () - */ -enum channel_state epicsShareAPI ca_state ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - if ( pChan->io.connected ( guard ) ) { - return cs_conn; - } - else if ( pChan->prevConnected ){ - return cs_prev_conn; - } - else { - return cs_never_conn; - } -} - -/* - * ca_read_access () - */ -unsigned epicsShareAPI ca_read_access ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.accessRights(guard).readPermit(); -} - -/* - * ca_write_access () - */ -unsigned epicsShareAPI ca_write_access ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.accessRights(guard).writePermit(); -} - -/* - * ca_name () - */ -const char * epicsShareAPI ca_name ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.pName ( guard ); -} - -unsigned epicsShareAPI ca_search_attempts ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.searchAttempts ( guard ); -} - -double epicsShareAPI ca_beacon_period ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.beaconPeriod ( guard ); -} - -double epicsShareAPI ca_receive_watchdog_delay ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.receiveWatchdogDelay ( guard ); -} - -/* - * ca_v42_ok(chid chan) - */ -int epicsShareAPI ca_v42_ok ( chid pChan ) -{ - epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () ); - return pChan->io.ca_v42_ok ( guard ); -} - - diff --git a/src/ca/client/oldSubscription.cpp b/src/ca/client/oldSubscription.cpp deleted file mode 100644 index 34b58a48d..000000000 --- a/src/ca/client/oldSubscription.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#include - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "oldAccess.h" - -oldSubscription::oldSubscription ( - epicsGuard < epicsMutex > & guard, - oldChannelNotify & chanIn, cacChannel & io, - unsigned type, arrayElementCount nElem, unsigned mask, - caEventCallBackFunc * pFuncIn, void * pPrivateIn, - evid * pEventId ) : - chan ( chanIn ), id ( UINT_MAX ), pFunc ( pFuncIn ), - pPrivate ( pPrivateIn ) -{ - // The users event id *must* be set prior to potentially - // calling his callback from within subscribe. - if ( pEventId ) { - *pEventId = this; - } - io.subscribe ( guard, type, nElem, mask, *this, &this->id ); - // Dont touch this pointer after this point because the - // 1st update callback might cancel the subscription and - // thereby destroy this object. -} - -oldSubscription::~oldSubscription () -{ -} - -void oldSubscription::current ( - epicsGuard < epicsMutex > & guard, - unsigned type, arrayElementCount count, const void * pData ) -{ - struct event_handler_args args; - args.usr = this->pPrivate; - args.chid = & this->chan; - args.type = static_cast < long > ( type ); - args.count = static_cast < long > ( count ); - args.status = ECA_NORMAL; - args.dbr = pData; - caEventCallBackFunc * pFuncTmp = this->pFunc; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - ( *pFuncTmp ) ( args ); - } -} - -void oldSubscription::exception ( - epicsGuard < epicsMutex > & guard, - int status, const char * /* pContext */, - unsigned type, arrayElementCount count ) -{ - if ( status == ECA_CHANDESTROY ) { - ca_client_context & cac = this->chan.getClientCtx (); - cac.destroySubscription ( guard, *this ); - } - else if ( status != ECA_DISCONN ) { - struct event_handler_args args; - args.usr = this->pPrivate; - args.chid = & this->chan; - args.type = type; - args.count = count; - args.status = status; - args.dbr = 0; - caEventCallBackFunc * pFuncTmp = this->pFunc; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - ( *pFuncTmp ) ( args ); - } - } -} - -void oldSubscription::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - diff --git a/src/ca/client/perl/CA.pm b/src/ca/client/perl/CA.pm deleted file mode 100644 index 22944172a..000000000 --- a/src/ca/client/perl/CA.pm +++ /dev/null @@ -1,671 +0,0 @@ -# Bootstrap wrapper for the Perl 5 Channel Access client module. -# This wrapper also contains the POD documentation for the module. - -use strict; -use warnings; - -my $version = '0.6'; - - -package CA; - -our $VERSION = $version; - - -package Cap5; -# This package is required because the loadable library containing the -# Perl interface code shouldn't be called CA but DynaLoader needs the -# package name to match the library name. The loadable library actually -# declares the packages for both Cap5 and CA which is why this works, -# although the only symbols in the Cap5 package are associated with the -# requirements of the DynaLoader module. - -our $VERSION = $version; -our @ISA = qw(DynaLoader); - -# Library is specific to the Perl version and archname -use Config; -my $perl_version = $Config::Config{version}; -my $perl_archname = $Config::Config{archname}; - -require DynaLoader; - -# Add our lib/ directory to the shared library search path -use File::Basename; -my $Lib = dirname(__FILE__); -push @DynaLoader::dl_library_path, "$Lib/$perl_version/$perl_archname"; - -bootstrap Cap5 $VERSION; - - -package CA; -# This END block runs the ca_context_destroy function, but we don't -# document it since the user never needs to call it explicitly. - -END { CA->context_destroy; } - - -package CA::Subscription; -# A subscription reference is a distinct object type. This package -# provides a convenience method allowing a subscription to clear itself. - -our $VERSION = $version; - -sub clear { - CA->clear_subscription(shift); -} - -1; -__END__ - -=head1 NAME - -CA - Perl 5 interface to EPICS Channel Access - -=head1 SYNOPSIS - - use lib '/path/to/cap5/lib/perl'; - use CA; - - my $chan = CA->new('pvname'); - CA->pend_io(1); - - my @access = ('no ', ''); - printf " PV name: %s\n", $chan->name; - printf " Data type: %s\n", $chan->field_type; - printf " Element count: %d\n", $chan->element_count; - printf " Host: %s\n", $chan->host_name; - printf " State: %s\n", $chan->state; - printf " Access: %sread, %swrite\n", - $access[$chan->read_access], $access[$chan->write_access]; - - die "PV not found!" unless $chan->is_connected; - - $chan->get; - CA->pend_io(1); - printf " Value: %s\n", $chan->value; - - $chan->create_subscription('v', \&callback, 'DBR_TIME_DOUBLE'); - CA->pend_event(10); - - sub callback { - my ($chan, $status, $data) = @_; - if ($status) { - printf "%-30s %s\n", $chan->name, $status; - } else { - printf " Value: %g\n", $data->{value}; - printf " Severity: %s\n", $data->{severity}; - printf " Timestamp: %.6f\n", - $data->{stamp} + $data->{stamp_fraction}; - } - } - - -=head1 DESCRIPTION - -C is an efficient interface to the EPICS Channel Access client library for -use by Perl 5 programs. It provides most of the functionality of the C library -(omitting Synchronous Groups) but only handles the three standard Perl data -types integer (long), floating point (double) and string (now including long -strings). Programmers who understand the C API will very quickly pick up how to -use this library since the calls and concepts are virtually identical. - - -=head1 FUNCTIONS - - -=head2 Constructor - -=over 4 - -=item new( I ) - -=item new( I, I ) - -Create a channel for the named PV. If given, I will be called whenever the -connection state of the channel changes. The arguments passed to I are the -channel object and a scalar value that is true if the channel is now up. - -The underlying CA channel will be cleaned up properly when the channel object is -garbage-collected by Perl. - -=back - - -=head2 Object Methods - -The following methods are provided for channel objects returned by -C<< CA->new() >>. - -=over 4 - - -=item name - -The PV name provided when this channel was created. - - -=item field_type - -Returns the native DBF type of the process variable as a string, or the string -C if unconnected. - - -=item element_count - -The maximum array element count from the server. Zero if the channel is not -connected. - - -=item host_name - -A string containing the server's hostname and port number. If the channel is -disconnected it will report C<< >>. - - -=item read_access - -=item write_access - -A true/false value that indicates whether the client has read or write access to -the specified channel. - - -=item state - -A string giving the current connection state of the channel, one of C, C, C or C. - - -=item is_connected - -Returns C if the channel is currently connected, else C. Use this -in preference to the equivalent code Sstate eq 'connected' >>>. - - -=item get - -=item value - -The C method makes a C request for a single element of the Perl -type closest to the channel's native data type; a C field will be -fetched as a DBF_STRING, and a C array with multiple elements will -converted into a Perl string. Once the server has returned the value (for which -see the C function below) it can be retrieved using the channel's -C method. Note that the C method deliberately only provides limited -capabilities; the C method must be used for more complex -requirements. - - -=item get_callback( I ) - -=item get_callback( I, I ) - -=item get_callback( I, I ) - -=item get_callback( I, I, I ) - -The C method takes a subroutine reference or name and calls that -routine when the server returns the data requested. With no other arguments the -data type requested will be the widened form of the channel's native type -(widening is discussed below), and if the channel is an array the request will -fetch all available elements. - -The element count can be overridden by providing an integer argument in the -range 0 .. C, where zero means use the current length from the -server. Note that the count argument must be an integer; add 0 to it if it is -necessary to convert it from a string. -The optional data type I should be a string naming -the desired C type; the actual type used will have the C part -widened to one of C, C, C or C. The valid type -names are listed in the L under the -section titled Channel Access Data Types; look in the CA Type Code column of the -two tables. - -The callback subroutine will be given three arguments: the channel object, a -status value from the server, and the returned data. If there were no errors -the status value will be C and the data will be valid; if an error -occurred the data will be C and the status a printable string giving more -information. The format of the data is described under L -below. - -Callback subroutines should only call Perl's C, C or similar -functions if they are expecting the program to exit at that time; attempts to -C with an exception object in the callback and catch that using C in -the main thread are not likely to succeed and will probably result in a crash. -Callbacks should not perform any operations that would block for more than a -fraction of a second as this will hold up network communications with the -relevant server and could cause the Perl program and/or the Channel Access -server to crash. Calling C<< CA->pend_event >> from within a callback is not -permitted by the underlying Channel Access library. - - -=item create_subscription( I, I ) - -=item create_subscription( I, I, I ) - -=item create_subscription( I, I, I ) - -=item create_subscription( I, I, I, I ) - -Register a state change subscription and specify a subroutine to be called -whenever the process variable undergoes a significant state change. I -must be a string containing one or more of the letters C, C, C and C

-which indicate that this subscription is for Value, Log (Archive), Alarm and -Property changes. The subroutine I is called as described for the -C method above, and the same optional I and I -arguments may be supplied to modify the data type and element count requested -from the server. - -The C method returns a C object which is -required to cancel that particular subscription. Either call the C -method on that object directly, or pass it to the C<< CA->clear_subscription >> -class method. - - -=item put( I ) - -=item put( I, I, ... ) - -The C method makes a C or C call depending on the -number of elements given in its argument list. The data type used will be the -native type of the channel, widened to one of C, array of C, -C or C. - - -=item put_callback( I, I ) - -=item put_callback( I, I, I, ... ) - -C is similar to the C method with the addition of the -subroutine reference or name I which is called when the server reports that -all actions resulting from the put have completed. For some applications this -callback can be delayed by minutes, hours or possibly even longer. The data -type is chosen the same way as for C. The arguments to the subroutine will -be the channel object and the status value from the server, which is either -C or a printable string if an error occurred. The same restrictions -apply to the callback subroutine as described in C above. - - -=item put_acks( I ) - -=item put_acks( I, I ) - -Applications that need to acknowledge alarms by doing a C with type -C can do so using the C method. The severity argument -may be provided as an integer from zero through three or as a string containing -one of the corresponding EPICS severity names C, C, C or -C. If a subroutine reference is provided it will be called after the -operation has completed on the server as described in C above. - - -=item put_ackt( I ) - -=item put_ackt( I, I ) - -This method is for applications that need to enable/disable transient alarms by -doing a C with type C. The C argument is a -true/false value, and an optional subroutine reference can be provided as -described above. - - -=item change_connection_event( I ) - -This method replaces, adds or cancels the connection handler subroutine for the -channel; see the C constructor for details. If I is C any -existing handler is removed, otherwise the new subroutine will be used for all -future connection events on this channel. - - -=item change_access_rights_event( I ) - -This method replaces, adds or cancels an access rights handler subroutine for -the channel, which will be called if the client's right to read from or write -to the channel changes. If I is C any existing handler is removed, -otherwise the new subroutine will be used for all future rights change events -on this channel. - -The arguments passed to I are the channel object and a pair of scalar -values for read and write permissions respectively, that are true when the -access is permitted, false when it is not. - -=back - - -=head2 Channel Data - -The data provided to a callback function registered with either C -or C can be a scalar value or a reference to an array or a -hash, depending on the data type that was used for the data transfer. If the -request was for a single item of one of the basic data types, the data argument -will be a Perl scalar that holds the value directly. If the request was for -multiple items of one of the basic types, the data argument will be a reference -to an array holding the data. There is one exception though; if the data type -requested was for an array of C values that array will be represented -as a single Perl string containing all the characters before the first zero -byte. - -If the request was for one of the compound data types, the data argument will be -a reference to a hash with keys as described below. Keys that are not classed -as metadata are named directly after the fields in the C C, -and are only included when the C structure contains that particular field. - - -=head3 Metadata - -These metadata will always be present in the hash: - - -=over 4 - -=item TYPE - -The C name of the data type from the server. This might have been -widened from the original type used to request or subscribe for the data. - - -=item COUNT - -The number of elements in the data returned by the server. If the data type is -C the value given for C is the number of bytes (including any -trailing zeros) returned by the server, although the value field is given as a -Perl string containing all the characters before the first zero byte. - -=back - - -=head3 Fixed Fields - -These fields are always present in the hash: - -=over 4 - - -=item value - -The actual process variable data, expressed as a Perl scalar or a reference to -an array of scalars, depending on the request. An array of C elements -will be represented as a string; to access the array elements as numeric values -the request must be for the C equivalent data type. - -If I is C or C, C can be accessed both -as the integer choice value and (if within range) as the string associated with -that particular choice. - - -=item status - -The alarm status of the PV as a printable string, or C if not in alarm. - - -=item severity - -The alarm severity of the PV, or C if not in alarm. A defined severity -can be used as a human readable string or as a number giving the numeric value -of the alarm severity (1 = C, 2 = C, 3 = C). - -=back - - -=head3 Ephemeral Fields - -These fields are only present for some values of I: - -=over 4 - - -=item strs - -A reference to an array containing all the possible choice strings for an ENUM. - -Present only when I is C or C. - - -=item no_str - -The number of choices defined for an ENUM. - -Present only when I is C or C. - - -=item stamp - -The process variable timestamp, converted to a local C. This value is -suitable for passing to the Perl C or C functions. - -Present only when I is C. - -=item stamp_fraction - -The fractional part of the process variable timestamp as a positive floating -point number less than 1.0. - -Present only when I is C. - - -=item ackt - -The value of the process variable's transient acknowledgment flag, an integer. - -Present only when I is C. - - -=item acks - -The alarm severity of the highest unacknowledged alarm for this process -variable. As with the C value, this scalar is both a string and -numeric severity. - -Present only when I is C. - - -=item precision - -The process variable's display precision, an integer giving the number of -decimal places to display. - -Present only when I is C or C. - - -=item units - -The engineering units string for the process variable. - -Present only when I is C or C where C is -not C. - - -=item upper_disp_limit - -=item lower_disp_limit - -The display range for the process variable; graphical tools often provide a way -to override these limits. - -Present only when I is C or C where C is -not C. - - -=item upper_alarm_limit - -=item upper_warning_limit - -=item lower_warning_limit - -=item lower_alarm_limit - -These items give the values at which the process variable should go into an -alarm state, although in practice the alarm severity associated with each level -is not provided. - -Present only when I is C or C where C is -not C. - - -=item upper_ctrl_limit - -=item lower_ctrl_limit - -The range over which a client can control the value of the process variable. - -Present only when I is C where C is not C. - -=back - - -=head2 Class Methods - - -The following functions are not channel methods, and should be called using the -class method syntax, e.g. C<< CA->pend_io(10) >>. - -=over 4 - -=item version - -Returns the EPICS_VERSION_STRING from the version of EPICS Base this software -was built using. - -=item flush_io - -Flush outstanding IO requests to the server. This routine is useful for users -who need to flush requests prior to performing client side labor in parallel -with labor performed in the server. Outstanding requests are also sent whenever -the buffer which holds them becomes full. Note that the routine can return -before all flush operations have completed. - - -=item test_io - -This function tests to see if all C requests are complete and channels -created without a connection callback subroutine are connected. It will return -a true value if all such operations are complete, otherwise false. - - -=item pend_io( I ) - -This function flushes the send buffer and then blocks until all outstanding -C requests complete and all channels created without a connection callback -subroutine have connected for the first time. Unlike C, this -routine does not process CA's background activities if no IO requests are -pending. - -If any I/O or connection operations remain incomplete after I seconds, -the function will die with the error C; see L -below. A I interval of zero is taken to mean wait forever if -necessary. The I value should take into account worst case network -delays such as Ethernet collision exponential back off until retransmission -delays which can be quite long on overloaded networks. - - -=item pend_event( I ) - -Flush the send buffer and process CA's background activities for I -seconds. This function always blocks for the full I period, and if a -value of zero is used it will never return. - -It is generally advisable to replace any uses of Perl's built-in function -C with calls to this routine, allowing Channel Access to make use of the -delay time to perform any necessary housekeeping operations. - - -=item poll - -Flush the send buffer and process any outstanding CA background activity. - - -=item clear_subscription( I ) - -Cancel a subscription. Note that for this to take effect immediately it is -necessary to call C<< CA->flush_io >> or one of the other class methods that -flushes the send buffer. - - -=item add_exception_event( I ) - -Trap exception events and execute I whenever they occur. The subroutine is -provided with four arguments: The channel object (if applicable), the status -value from the server, a printable context string giving more information about -the error, and a hash reference containing some additional data. If the -exception is not specific to a particular channel the channel object will be -C. The status value is a printable string. The hash may contain any of -the following members: - -=over 8 - -=item * OP - -The operation in progress when the exception occurred. This scalar when used as -a string is one of C, C, C, C, -C or C but can also be accessed as an integer (0-5). - -=item * TYPE - -The C name of the data type involved. - -=item * COUNT - -The number of elements in the request. - -=item * FILE - -=item * LINE - -These refer to the source file and line number inside the CA client library -where the exception was noticed. - -=back - -=item replace_printf_handler( I ) - -This function provides a method to trap error messages from the CA client -library and redirect them to somewhere other than the C stream. The -subroutine provided will be called with a single string argument every time the -client library wishes to output an error or warning message. Note that a single -error or warning message may result in several calls to this subroutine. - -To revert back to the original handler, call C<< CA->replace_printf_handler() >> -passing C as the subroutine reference. - -=back - - -=head1 ERROR HANDLING - -Errors in using the library will be indicated by the module throwing an -exception, i.e. calling C with an appropriate error message. These -exceptions can be caught using the standard Perl C statement and -testing the C<$@> variable afterwards; if not caught, they will cause the -running program to C with an appropriate error message pointing to the -program line that called the C library. - -Error messages reported by the underlying CA client library all start with the -string C and the remainder of the symbol for the associated CA error -number, and are followed after a space-hyphen-space by a human-readable message -describing the error. Errors that are detected by the Perl interface layer do -not follow this pattern, but are still printable strings. - - -=head1 SEE ALSO - -=over - -=item [1] R3.15 Channel Access Reference Manual by Jeffrey O. Hill - -L - -=back - - -=head1 AUTHOR - -Andrew Johnson, Eanj@aps.anl.govE - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2008-2014 UChicago Argonne LLC, as Operator of Argonne National -Laboratory. - -This software is distributed under the terms of the EPICS Open License. - -=cut diff --git a/src/ca/client/perl/Cap5.xs b/src/ca/client/perl/Cap5.xs deleted file mode 100644 index e519198ec..000000000 --- a/src/ca/client/perl/Cap5.xs +++ /dev/null @@ -1,1505 +0,0 @@ -/* Provides an EPICS Channel Access client interface for Perl5. */ - -/* This macro disables perl's reentr.inc file, which we don't need - * here and just generates unnecessary compiler warnings. */ -#define REENTRINC - -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#include "cadef.h" -#include "db_access.h" -#include "epicsVersion.h" -#include "alarm.h" - -typedef union { - dbr_long_t iv; - dbr_double_t nv; - dbr_string_t pv; -} CA_data; - -typedef struct CA_channel { - chid chan; - CA_data data; /* Value storage for CA::get */ - char *sdata; /* String storage for CA::get */ - size_t ssize; /* Length allocated for sdata, excluding nil */ - SV *chan_ref; - SV *conn_sub; - SV *rights_sub; -} CA_channel; - -static -void *p5_ctx; - -static -const char * get_error_msg(int status) { - static const char * const messages[] = { - "ECA_NORMAL - Normal successful completion", - "ECA_MAXIOC - Maximum simultaneous IOC connections exceeded", - "ECA_UKNHOST - Unknown internet host", - "ECA_UKNSERV - Unknown internet service", - "ECA_SOCK - Unable to allocate a new socket", - "ECA_CONN - Unable to connect to internet host or service", - "ECA_ALLOCMEM - Unable to allocate additional dynamic memory", - "ECA_UKNCHAN - Unknown IO channel", - "ECA_UKNFIELD - Record field specified inappropriate for channel specified", - "ECA_TOLARGE - The requested data transfer is greater than available memory or EPICS_CA_MAX_ARRAY_BYTES", - "ECA_TIMEOUT - User specified timeout on IO operation expired", - "ECA_NOSUPPORT - Sorry, that feature is planned but not supported at this time", - "ECA_STRTOBIG - The supplied string is unusually large", - "ECA_DISCONNCHID - The request was ignored because the specified channel is disconnected", - "ECA_BADTYPE - The data type specifed is invalid", - "ECA_CHIDNOTFND - Remote Channel not found", - "ECA_CHIDRETRY - Unable to locate all user specified channels", - "ECA_INTERNAL - Channel Access Internal Failure", - "ECA_DBLCLFAIL - The requested local DB operation failed", - "ECA_GETFAIL - Channel read request failed", - "ECA_PUTFAIL - Channel write request failed", - "ECA_ADDFAIL - Channel subscription request failed", - "ECA_BADCOUNT - Invalid element count requested", - "ECA_BADSTR - Invalid string", - "ECA_DISCONN - Virtual circuit disconnect", - "ECA_DBLCHNL - Identical process variable names on multiple servers", - "ECA_EVDISALLOW - Request inappropriate within subscription (monitor) update callback", - "ECA_BUILDGET - Database value get for that channel failed during channel search", - "ECA_NEEDSFP - Unable to initialize without the vxWorks VX_FP_TASK task option set", - "ECA_OVEVFAIL - Event queue overflow has prevented first pass event after event add", - "ECA_BADMONID - Bad event subscription (monitor) identifier", - "ECA_NEWADDR - Remote channel has new network address", - "ECA_NEWCONN - New or resumed network connection", - "ECA_NOCACTX - Specified task isnt a member of a CA context", - "ECA_DEFUNCT - Attempt to use defunct CA feature failed", - "ECA_EMPTYSTR - The supplied string is empty", - "ECA_NOREPEATER - Unable to spawn the CA repeater thread- auto reconnect will fail", - "ECA_NOCHANMSG - No channel id match for search reply- search reply ignored", - "ECA_DLCKREST - Reseting dead connection- will try to reconnect", - "ECA_SERVBEHIND - Server (IOC) has fallen behind or is not responding- still waiting", - "ECA_NOCAST - No internet interface with broadcast available", - "ECA_BADMASK - Invalid event selection mask", - "ECA_IODONE - IO operations have completed", - "ECA_IOINPROGRESS - IO operations are in progress", - "ECA_BADSYNCGRP - Invalid synchronous group identifier", - "ECA_PUTCBINPROG - Put callback timed out", - "ECA_NORDACCESS - Read access denied", - "ECA_NOWTACCESS - Write access denied", - "ECA_ANACHRONISM - Requested feature is no longer supported", - "ECA_NOSEARCHADDR - Empty PV search address list", - "ECA_NOCONVERT - No reasonable data conversion between client and server types", - "ECA_BADCHID - Invalid channel identifier", - "ECA_BADFUNCPTR - Invalid function pointer", - "ECA_ISATTACHED - Thread is already attached to a client context", - "ECA_UNAVAILINSERV - Not supported by attached service", - "ECA_CHANDESTROY - User destroyed channel", - "ECA_BADPRIORITY - Invalid channel priority", - "ECA_NOTTHREADED - Preemptive callback not enabled - additional threads may not join context", - "ECA_16KARRAYCLIENT - Client's protocol revision does not support transfers exceeding 16k bytes", - "ECA_CONNSEQTMO - Virtual circuit connection sequence aborted", - "ECA_UNRESPTMO - Virtual circuit unresponsive" - }; - - return messages[CA_EXTRACT_MSG_NO(status)]; -} - - -static -chtype best_type(CA_channel *pch) { - switch (ca_field_type(pch->chan)) { - case DBF_STRING: - case DBF_ENUM: - return DBF_STRING; - case DBF_CHAR: - if (ca_element_count(pch->chan) > 1) - return DBF_CHAR; - /* Fall through */ - case DBF_INT: - case DBF_LONG: - return DBF_LONG; - case DBF_FLOAT: - case DBF_DOUBLE: - return DBF_DOUBLE; - } - croak("Unexpected field type %s", - dbf_type_to_text(ca_field_type(pch->chan))); -} - - -static -SV * newSVdbf(chtype type, const void *dbr, int index) { - switch (type) { - char *pc; - size_t len; - - case DBR_STRING: - pc = (char *)dbr + index * MAX_STRING_SIZE; - len = strlen(pc); - return newSVpv(pc, len < MAX_STRING_SIZE ? len : MAX_STRING_SIZE); - case DBR_LONG: - return newSViv(((dbr_long_t *)dbr)[index]); - case DBR_DOUBLE: - return newSVnv(((dbr_double_t *)dbr)[index]); - default: - croak("Unexpected data type %s", dbf_type_to_text(type)); - } -} - - -static -SV * newSValarm(int sevr) { - SV *alarm = &PL_sv_undef; - if (sevr) { - alarm = newSViv(sevr); - sv_setpv(alarm, epicsAlarmSeverityStrings[sevr]); - SvIOK_on(alarm); - } - return alarm; -} - -static -void hashAdd(HV *hash, const char *key, I32 klen, SV *val) { - SV **result = hv_store(hash, key, klen, val, 0); - - if (result == NULL) - SvREFCNT_dec(val); -} - -static -SV * newSVdbr(struct event_handler_args *peha) { - const int is_primitive = dbr_type_is_plain(peha->type) || - (peha->type == DBR_CLASS_NAME); - HV *hash; - SV *val; - chtype value_type; - union db_access_val *u; - - if (dbr_type_is_STRING(peha->type) || - peha->type == DBR_STSACK_STRING || - peha->type == DBR_CLASS_NAME) - value_type = DBR_STRING; - else if (dbr_type_is_CHAR(peha->type)) - value_type = DBR_CHAR; - else if (dbr_type_is_LONG(peha->type)) - value_type = DBR_LONG; - else if (dbr_type_is_DOUBLE(peha->type)) - value_type = DBR_DOUBLE; - else if (dbr_type_is_ENUM(peha->type)) - /* Only seen as DBR_GR_ENUM and DBR_CTRL_ENUM */ - value_type = DBR_ENUM; - else { - croak("Unexpected data type %s", - dbf_type_to_text(peha->type)); - } - - if (is_primitive) { - if (value_type == DBR_CHAR) { - /* Long string => Perl scalar */ - ((char *)peha->dbr) [peha->count - 1] = 0; - return newSVpv(peha->dbr, 0); - } - - if (peha->count != 1) { - /* Array of values => Perl array reference */ - AV *array; - int i; - - array = newAV(); - for (i = 0; i < peha->count; i++) { - av_push(array, newSVdbf(value_type, peha->dbr, i)); - } - return newRV_noinc((SV *)array); - } - - /* Single value => Perl scalar */ - return newSVdbf(value_type, peha->dbr, 0); - } - - /* Compound => Perl hash reference */ - u = (union db_access_val *)peha->dbr; - hash = newHV(); - - /* Add basic meta-data */ - hashAdd(hash, "TYPE", 4, - newSVpv(dbr_type_to_text(peha->type), 0)); - hashAdd(hash, "COUNT", 5, newSViv(peha->count)); - - /* Alarm status and severity are always in the same place */ - if (u->slngval.status) - val = newSVpv(epicsAlarmConditionStrings[u->slngval.status], 0); - else - val = &PL_sv_undef; - hashAdd(hash, "status", 6, val); - hashAdd(hash, "severity", 8, - newSValarm(u->slngval.severity)); - - if (peha->type == DBR_GR_ENUM || - peha->type == DBR_CTRL_ENUM) { - AV *strings = newAV(); - int n = u->genmval.no_str; - int i; - - val = newSViv(u->genmval.value); - - for (i = 0; i < n; i++) { - size_t slen = strlen(u->genmval.strs[i]); - if (slen > MAX_ENUM_STRING_SIZE) - slen = MAX_ENUM_STRING_SIZE; - av_push(strings, newSVpv(u->genmval.strs[i], slen)); - if (i == u->genmval.value) { - sv_setpvn(val, u->genmval.strs[i], slen); - SvIOK_on(val); - } - } - hashAdd(hash, "strs", 4, - newRV_noinc((SV *)strings)); - hashAdd(hash, "no_str", 6, - newSViv(u->genmval.no_str)); - hashAdd(hash, "value", 5, val); - - return newRV_noinc((SV *)hash); - } - - /* Value */ - if (value_type == DBR_CHAR) { - char *str = dbr_value_ptr(peha->dbr, peha->type); - - /* Long string => Perl scalar */ - str[peha->count - 1] = 0; - val = newSVpv(str, 0); - } else if (peha->count == 1) { - /* Single value => Perl scalar */ - val = newSVdbf(value_type, - dbr_value_ptr(peha->dbr, peha->type), 0); - } else { - /* Array of values => Perl array reference */ - AV *array = newAV(); - int i; - - for (i = 0; i < peha->count; i++) { - av_push(array, newSVdbf(value_type, - dbr_value_ptr(peha->dbr, peha->type), i)); - } - val = newRV_noinc((SV *)array); - } - hashAdd(hash, "value", 5, val); - - /* Timestamp follows status and severity in DBR_TIME */ - if (dbr_type_is_TIME(peha->type)) { - struct timespec t; - - epicsTimeToTimespec(&t, &u->tlngval.stamp); - hashAdd(hash, "stamp", 5, - newSViv(t.tv_sec)); - hashAdd(hash, "stamp_fraction", 14, - newSVnv((double)t.tv_nsec / 1e9)); - } - else if (peha->type == DBR_STSACK_STRING) { - struct dbr_stsack_string *s = (struct dbr_stsack_string *)peha->dbr; - - hashAdd(hash, "ackt", 4, - newSViv(s->ackt)); - hashAdd(hash, "acks", 4, - newSValarm(s->acks)); - } - else if (value_type != DBR_STRING && - (dbr_type_is_GR(peha->type) || - dbr_type_is_CTRL(peha->type))) { - char *units; - size_t ulen; - void *limit; - int i = dbr_type_is_CTRL(peha->type) ? 7 : 5; - - if (value_type == DBR_DOUBLE) { - units = u->gdblval.units; - limit = &u->gdblval.upper_disp_limit; - hashAdd(hash, "precision", 9, - newSViv(u->gdblval.precision)); - } else { /* value_type == DBR_LONG */ - units = u->glngval.units; - limit = &u->glngval.upper_disp_limit; - } - - ulen = strlen(units); - hashAdd(hash, "units", 5, newSVpv(units, - ulen < MAX_UNITS_SIZE ? ulen : MAX_UNITS_SIZE)); - - while (i >= 0) { - static const char * const limit_name[] = { - "upper_disp_limit", "lower_disp_limit", - "upper_alarm_limit", "upper_warning_limit", - "lower_warning_limit", "lower_alarm_limit", - "upper_ctrl_limit", "lower_ctrl_limit", - }; - - hashAdd(hash, limit_name[i], strlen(limit_name[i]), - newSVdbf(value_type, limit, i)); - i--; - } - } - - return newRV_noinc((SV *)hash); -} - - -enum io_type { - IO_GET, - IO_PUT, - IO_MONITOR, -}; - -static -void io_handler(struct event_handler_args *peha, enum io_type io) { - PERL_SET_CONTEXT(p5_ctx); - { - CA_channel *pch = ca_puser(peha->chid); - SV *code = (SV *)peha->usr; - SV *status = &PL_sv_undef; - SV *data = &PL_sv_undef; - dSP; - - ENTER; - SAVETMPS; - - if (peha->status != ECA_NORMAL) { - status = sv_2mortal(newSVpv(get_error_msg(peha->status), 0)); - } else if (io != IO_PUT) { - data = sv_2mortal(newSVdbr(peha)); - } - - sv_setsv(ERRSV, &PL_sv_undef); - - PUSHMARK(SP); - XPUSHs(pch->chan_ref); - XPUSHs(status); - XPUSHs(data); - PUTBACK; - - call_sv(code, G_VOID | G_DISCARD | G_EVAL | G_KEEPERR); - - if (io != IO_MONITOR) - SvREFCNT_dec(code); - - if (SvTRUE(ERRSV)) - croak(NULL); - - FREETMPS; - LEAVE; - } -} - - -static -int replace_handler(SV * sub, SV ** ph_sub, long *phandler) { - if (SvOK(sub) && SvTRUE(sub)) { - if (*ph_sub != NULL) { - SvSetSV(*ph_sub, sub); - return FALSE; - } - *ph_sub = newSVsv(sub); - } else { - if (*ph_sub == NULL) - return FALSE; - - SvREFCNT_dec(*ph_sub); - *ph_sub = NULL; - *phandler = 0; - } - return TRUE; -} - - -/******************************************************************************/ - -/* CA::new($class, $name, [\&sub]) */ - -static -void connect_handler(struct connection_handler_args cha) { - CA_channel *pch = ca_puser(cha.chid); - - PERL_SET_CONTEXT(p5_ctx); - { - dSP; - - SvSetSV(ERRSV, &PL_sv_undef); - - PUSHMARK(SP); - XPUSHs(pch->chan_ref); - XPUSHs(cha.op == CA_OP_CONN_UP ? &PL_sv_yes : &PL_sv_no); - PUTBACK; - - call_sv(pch->conn_sub, G_EVAL | G_VOID | G_DISCARD | G_KEEPERR); - - if (SvTRUE(ERRSV)) - croak(NULL); - } -} - -SV * CA_new(const char *class, const char *name, ...) { - dXSARGS; - SV *ca_ref = newSViv(0); - SV *ca_obj = newSVrv(ca_ref, class); - CA_channel *pch; - caCh *handler; - int status; - - Newz(0, pch, 1, CA_channel); - sv_setiv(ca_obj, (IV)pch); - SvREADONLY_on(ca_obj); - - pch->chan_ref = ca_ref; - (void) SvREFCNT_inc(ca_ref); - - if (items > 2 - && SvOK(ST(2))) { - /* Connection handler provided */ - pch->conn_sub = newSVsv(ST(2)); - handler = &connect_handler; - } else - handler = NULL; - - status = ca_create_channel(name, handler, pch, 0, &pch->chan); - if (status != ECA_NORMAL) { - SvREFCNT_dec(ca_ref); - if (pch->conn_sub) - SvREFCNT_dec(pch->conn_sub); - croak("%s", get_error_msg(status)); - } - - return ca_ref; -} - -static int destroyed = 0; - -/* CA::DESTROY($ca_ref) */ - -void CA_DESTROY(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - int status; - - status = destroyed ? ECA_NORMAL : ca_clear_channel(pch->chan); - - if (pch->conn_sub) - SvREFCNT_dec(pch->conn_sub); - - if (pch->rights_sub) - SvREFCNT_dec(pch->rights_sub); - - if (pch->sdata) - Safefree(pch->sdata); - - SvREFCNT_dec(pch->chan_ref); - Safefree(pch); - - if (status != ECA_NORMAL) - croak("%s", get_error_msg(status)); -} - - -/* CA::context_destroy($class) */ - -void CA_context_destroy(const char *class) { - ca_context_destroy(); - destroyed = 1; -} - - -/* CA::change_connection_event($ca_ref, \$sub) */ - -void CA_change_connection_event(SV *ca_ref, SV *sub) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - caCh *handler = &connect_handler; - int status; - - if (! replace_handler(sub, &pch->conn_sub, (long *)&handler)) - return; - - status = ca_change_connection_event(pch->chan, handler); - - if (status != ECA_NORMAL) { - croak("%s", get_error_msg(status)); - } -} - -/* CA::replace_access_rights_event($ca_ref, \$sub) */ - -static -void rights_handler(struct access_rights_handler_args arha) { - CA_channel *pch = ca_puser(arha.chid); - - PERL_SET_CONTEXT(p5_ctx); - { - dSP; - - SvSetSV(ERRSV, &PL_sv_undef); - - PUSHMARK(SP); - XPUSHs(pch->chan_ref); - XPUSHs(arha.ar.read_access ? &PL_sv_yes : &PL_sv_no); - XPUSHs(arha.ar.write_access ? &PL_sv_yes : &PL_sv_no); - PUTBACK; - - call_sv(pch->rights_sub, G_EVAL | G_VOID | G_DISCARD | G_KEEPERR); - - if (SvTRUE(ERRSV)) - croak(NULL); - } -} - -void CA_replace_access_rights_event(SV *ca_ref, SV *sub) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - caArh *handler = &rights_handler; - int status; - - if (! replace_handler(sub, &pch->rights_sub, (long *)&handler)) - return; - - status = ca_replace_access_rights_event(pch->chan, handler); - - if (status != ECA_NORMAL) { - croak("%s", get_error_msg(status)); - } -} - - -/* CA::put($ca_ref, @values) */ - -void CA_put(SV *ca_ref, SV *val, ...) { - dXSARGS; - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - int num_values = items - 1; - int status; - - if (num_values == 1) { - if (ca_field_type(pch->chan) == DBF_CHAR && - ca_element_count(pch->chan) > 1) { - size_t len; - char *long_string = SvPV(val, len); - - status = ca_array_put(DBF_CHAR, len+1, pch->chan, long_string); - } else { - union { - dbr_long_t dbr_long; - dbr_double_t dbr_double; - dbr_string_t dbr_string; - } data; - chtype type = best_type(pch); - - switch (type) { - case DBF_LONG: - data.dbr_long = SvIV(val); - break; - case DBF_DOUBLE: - data.dbr_double = SvNV(val); - break; - case DBF_STRING: - strncpy(data.dbr_string, SvPV_nolen(val), MAX_STRING_SIZE); - break; - } - status = ca_put(type, pch->chan, &data); - } - } else { - union { - dbr_char_t *dbr_char; - dbr_long_t *dbr_long; - dbr_double_t *dbr_double; - char *dbr_string; - void *dbr; - } p; - int i; - chtype type = best_type(pch); - - switch (type) { - case DBF_CHAR: - New(0, p.dbr_char, num_values, dbr_char_t); - for (i = 0; i < num_values; i++) { - p.dbr_char[i] = SvIV(ST(i + 1)); - } - break; - case DBF_LONG: - New(0, p.dbr_long, num_values, dbr_long_t); - for (i = 0; i < num_values; i++) { - p.dbr_long[i] = SvIV(ST(i + 1)); - } - break; - case DBF_DOUBLE: - New(0, p.dbr_double, num_values, dbr_double_t); - for (i = 0; i < num_values; i++) { - p.dbr_double[i] = SvNV(ST(i + 1)); - } - break; - case DBF_STRING: - New(0, p.dbr_string, num_values * MAX_STRING_SIZE, char); - for (i = 0; i < num_values; i++) { - char * src = SvPV_nolen(ST(i + 1)); - strncpy(p.dbr_string + i, src, MAX_STRING_SIZE); - } - break; - } - - status = ca_array_put(type, num_values, pch->chan, p.dbr); - Safefree(p.dbr); - } - if (status != ECA_NORMAL) { - croak("%s", get_error_msg(status)); - } - XSRETURN(0); -} - - -/* CA::put_callback($ca_ref, \&sub, @values) */ - -static -void put_handler(struct event_handler_args eha) { - io_handler(&eha, IO_PUT); -} - -void CA_put_callback(SV *ca_ref, SV *sub, SV *val, ...) { - dXSARGS; - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - SV *put_sub = newSVsv(sub); - int num_values = items - 2; - int status; - - if (num_values == 1) { - if (ca_field_type(pch->chan) == DBF_CHAR && - ca_element_count(pch->chan) > 1) { - size_t len; - char *long_string = SvPV(val, len); - - status = ca_array_put_callback(DBF_CHAR, len+1, pch->chan, - long_string, put_handler, put_sub); - } else { - union { - dbr_long_t dbr_long; - dbr_double_t dbr_double; - dbr_string_t dbr_string; - } data; - chtype type = best_type(pch); - - switch (type) { - case DBF_LONG: - data.dbr_long = SvIV(val); - break; - case DBF_DOUBLE: - data.dbr_double = SvNV(val); - break; - case DBF_STRING: - strncpy(data.dbr_string, SvPV_nolen(val), MAX_STRING_SIZE); - break; - } - - status = ca_put_callback(type, pch->chan, &data, put_handler, put_sub); - } - } else { - union { - dbr_char_t *dbr_char; - dbr_long_t *dbr_long; - dbr_double_t *dbr_double; - char *dbr_string; - void *dbr; - } p; - int i; - chtype type = best_type(pch); - - switch (type) { - case DBF_CHAR: - New(0, p.dbr_char, num_values, dbr_char_t); - for (i = 0; i < num_values; i++) { - p.dbr_char[i] = SvIV(ST(i + 1)); - } - break; - case DBF_LONG: - New(0, p.dbr_long, num_values, dbr_long_t); - for (i = 0; i < num_values; i++) { - p.dbr_long[i] = SvIV(ST(i + 2)); - } - break; - case DBF_DOUBLE: - New(0, p.dbr_double, num_values, dbr_double_t); - for (i = 0; i < num_values; i++) { - p.dbr_double[i] = SvNV(ST(i + 2)); - } - break; - case DBF_STRING: - New(0, p.dbr_string, num_values * MAX_STRING_SIZE, char); - for (i = 0; i < num_values; i++) { - char * src = SvPV_nolen(ST(i + 2)); - strncpy(p.dbr_string + i, src, MAX_STRING_SIZE); - } - break; - } - - status = ca_array_put_callback(type, num_values, pch->chan, p.dbr, - put_handler, put_sub); - Safefree(p.dbr); - } - if (status != ECA_NORMAL) { - SvREFCNT_dec(put_sub); - croak("%s", get_error_msg(status)); - } - XSRETURN(0); -} - - -/* CA::put_acks($ca_ref, $sevr, [\&sub]) */ - -void CA_put_acks(SV *ca_ref, SV *sevr, ...) { - dXSARGS; - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - dbr_put_acks_t acks; - int status; - - if (! SvOK(sevr)) { - acks = NO_ALARM; - } else if (SvIOK(sevr)) { - acks = SvIV(sevr); - if (acks > INVALID_ALARM) - croak("Bad acknowledgement severity %d", acks); - } else { - size_t slen; - char *sname = SvPV(sevr, slen); - for (acks = NO_ALARM; acks <= INVALID_ALARM; acks++) { - if (strcmp(sname, epicsAlarmSeverityStrings[acks]) == 0) - break; - } - if (acks > INVALID_ALARM) - croak("Bad acknowledgment severity '%s'", sname); - } - - if (items > 2) { - SV *put_sub = newSVsv(ST(2)); - status = ca_put_callback(DBR_PUT_ACKS, pch->chan, &acks, - put_handler, put_sub); - if (status != ECA_NORMAL) - SvREFCNT_dec(put_sub); - } else - status = ca_put(DBR_PUT_ACKS, pch->chan, &acks); - - if (status != ECA_NORMAL) - croak("%s", get_error_msg(status)); - - XSRETURN(0); -} - - -/* CA::put_ackt($ca_ref, $trans, [\&sub]) */ - -void CA_put_ackt(SV *ca_ref, int ack, ...) { - dXSARGS; - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - dbr_put_ackt_t ackt = !! ack; /* 0 or 1 only */ - int status; - - if (items > 2) { - SV *put_sub = newSVsv(ST(2)); - status = ca_put_callback(DBR_PUT_ACKT, pch->chan, &ackt, - put_handler, put_sub); - if (status != ECA_NORMAL) - SvREFCNT_dec(put_sub); - } else - status = ca_put(DBR_PUT_ACKS, pch->chan, &ackt); - - if (status != ECA_NORMAL) - croak("%s", get_error_msg(status)); - - XSRETURN(0); -} - - -/* CA::get($ca_ref) */ - -void CA_get(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - size_t count = ca_element_count(pch->chan); - int status; - - if (ca_field_type(pch->chan) == DBF_CHAR && - count > 1) { - if (!pch->sdata) { - New(0, pch->sdata, count + 1, char); - pch->ssize = count; - } else if (pch->ssize < count) { /* Reconnected to larger array? */ - Safefree(pch->sdata); - New(0, pch->sdata, count + 1, char); - pch->ssize = count; - } - status = ca_array_get(DBF_CHAR, 0, pch->chan, pch->sdata); - } else { - status = ca_get(best_type(pch), pch->chan, &pch->data); - } - if (status != ECA_NORMAL) { - croak("%s", get_error_msg(status)); - } -} - - -/* CA::value($ca_ref) */ - -SV * CA_value(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - if (ca_field_type(pch->chan) == DBF_CHAR && - ca_element_count(pch->chan) > 1 && - pch->sdata) { - return newSVpv(pch->sdata, 0); - } - return newSVdbf(best_type(pch), &pch->data, 0); -} - - -/* CA::get_callback($ca_ref, \&sub, [$type | $count]) */ - -static -void get_handler(struct event_handler_args eha) { - io_handler(&eha, IO_GET); -} - -void CA_get_callback(SV *ca_ref, SV *sub, ...) { - dXSARGS; - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - SV *get_sub = newSVsv(sub); - int status; - chtype type = best_type(pch); - int count = 0; - int i = 2; - const char *croak_msg; - - while (items > i - && SvOK(ST(i))) { - if (SvIOK(ST(i))) { - /* Interger => Count arg, zero means current size */ - count = SvIV(ST(i)); - if (count < 0 || count > ca_element_count(pch->chan)) { - croak_msg = "Requested array size is out of range"; - goto exit_croak; - } - } else if (SvPOKp(ST(i))) { - /* String => Type arg */ - char *treq = SvPV_nolen(ST(i)); - - dbr_text_to_type(treq, type); - if (type < 0 || - type == DBR_PUT_ACKT || - type == DBR_PUT_ACKS) { - croak_msg = "Requested DBR type is invalid"; - goto exit_croak; - } else if (type == DBR_GR_ENUM || - type == DBR_CTRL_ENUM || - type == DBR_CLASS_NAME || - type == DBR_STSACK_STRING) - /* The above types are supported */ ; - else if (dbr_type_is_SHORT(type)) - type += (DBR_LONG - DBR_SHORT); - else if (dbr_type_is_FLOAT(type)) - type += (DBR_DOUBLE - DBR_FLOAT); - else if (dbr_type_is_ENUM(type)) - type += (DBR_STRING - DBR_ENUM); - } - i++; - } - - status = ca_array_get_callback(type, count, - pch->chan, get_handler, get_sub); - if (status != ECA_NORMAL) { - croak_msg = get_error_msg(status); - goto exit_croak; - } - - XSRETURN(0); - return; - -exit_croak: - SvREFCNT_dec(get_sub); - croak("%s", croak_msg); -} - - -/* CA::create_subscription($ca_ref, $mask, \&sub, [$type | $count]) */ - -static -void subscription_handler(struct event_handler_args eha) { - io_handler(&eha, IO_MONITOR); -} - -SV * CA_create_subscription(SV *ca_ref, const char *mask_str, SV *sub, ...) { - dXSARGS; - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - SV *mon_sub = newSVsv(sub); - SV *mon_ref = newSViv(0); - SV *mon_obj = newSVrv(mon_ref, "CA::Subscription"); - chtype type = best_type(pch); - int count = ca_element_count(pch->chan); - int i = 3; - int mask = 0; - evid event; - int status; - const char *croak_msg; - - if (strchr(mask_str, 'v') || strchr(mask_str, 'V')) mask |= DBE_VALUE; - if (strchr(mask_str, 'l') || strchr(mask_str, 'L')) mask |= DBE_LOG; - if (strchr(mask_str, 'a') || strchr(mask_str, 'A')) mask |= DBE_ALARM; - if (strchr(mask_str, 'p') || strchr(mask_str, 'P')) mask |= DBE_PROPERTY; - - while (items > i - && SvOK(ST(i))) { - if (SvIOK(ST(i))) { - /* Interger => Count arg, zero means current size */ - count = SvIV(ST(i)); - if (count < 0 || count > ca_element_count(pch->chan)) { - croak_msg = "Requested array size is out of range"; - goto exit_croak; - } - } else if (SvPOKp(ST(i))) { - /* String => Type arg */ - size_t tlen; - char *treq = SvPV(ST(i), tlen); - - dbr_text_to_type(treq, type); - if (type < 0) { - croak_msg = "Unknown CA data type"; - goto exit_croak; - } - if (type == DBR_PUT_ACKT || - type == DBR_PUT_ACKS) { - croak_msg = "DBR_PUT_ACK types are write-only"; - goto exit_croak; - } else if (type == DBR_GR_ENUM || - type == DBR_CTRL_ENUM || - type == DBR_CLASS_NAME || - type == DBR_STSACK_STRING) - /* These above types are supported */ ; - else if (dbr_type_is_SHORT(type)) - type += (DBR_LONG - DBR_SHORT); - else if (dbr_type_is_FLOAT(type)) - type += (DBR_DOUBLE - DBR_FLOAT); - else if (dbr_type_is_ENUM(type)) - type += (DBR_STRING - DBR_ENUM); - } - i++; - } - - status = ca_create_subscription(type, count, pch->chan, mask, - subscription_handler, mon_sub, &event); - if (status != ECA_NORMAL) { - croak_msg = get_error_msg(status); - goto exit_croak; - } - - sv_setiv(mon_obj, (IV)event); - SvREADONLY_on(mon_obj); - (void) SvREFCNT_inc(mon_ref); - - return mon_ref; - -exit_croak: - SvREFCNT_dec(mon_ref); - SvREFCNT_dec(mon_sub); - croak("%s", croak_msg); -} - - -/* CA::clear_subscription($class, $subscription) */ - -void CA_clear_subscription(const char *class, SV *mon_ref) { - evid event = (evid)SvIV(SvRV(mon_ref)); - int status; - - if (! sv_isa(mon_ref, "CA::Subscription")) { - croak("Not a CA::Subscription"); - } - - status = ca_clear_subscription(event); - - if (status != ECA_NORMAL) { - croak("%s", get_error_msg(status)); - } -} - - -/* CA::pend_io($class, $timeout) */ - -void CA_pend_io(const char *class, double timeout) { - int status = ca_pend_io(timeout); - if (status != ECA_NORMAL) { - croak("%s", get_error_msg(status)); - } -} - -/* CA::test_io($class) */ - -int CA_test_io(const char *class) { - return (ca_test_io() == ECA_IODONE); -} - -/* CA::pend_event($class, $timeout) */ - -void CA_pend_event(const char *class, double timeout) { - int status = ca_pend_event(timeout); - if (status != ECA_TIMEOUT) { - croak("%s", get_error_msg(status)); - } -} - -/* CA::poll($class) */ - -void CA_poll(const char *class) { - ca_poll(); -} - - -/* CA::flush_io($class) */ - -void CA_flush_io(const char *class) { - ca_flush_io(); -} - - -/* CA::version($class) */ - -const char * CA_version(const char *class) { - return EPICS_VERSION_STRING; -} - -/* CA::add_exception_event($class, \&sub) */ - -static -SV * exception_sub = NULL; - -static -void exception_handler(struct exception_handler_args eha) { - if (! exception_sub) - return; - - PERL_SET_CONTEXT(p5_ctx); - { - SV *channel = &PL_sv_undef; - SV *status = &PL_sv_undef; - HV *hash = newHV(); - SV *op; - const char *opString[] = { - "GET", "PUT", "CREATE_CHANNEL", "ADD_EVENT", "CLEAR_EVENT", "OTHER" - }; - dSP; - - ENTER; - SAVETMPS; - - if (eha.chid) { - CA_channel *pch = ca_puser(eha.chid); - channel = pch->chan_ref; - } - if (eha.stat != ECA_NORMAL) { - status = sv_2mortal(newSVpv(get_error_msg(eha.stat), 0)); - } - - op = newSViv(eha.op); - sv_setpv(op, opString[eha.op]); - SvIOK_on(op); - hashAdd(hash, "OP", 2, op); - hashAdd(hash, "TYPE", 4, - newSVpv(dbr_type_to_text(eha.type), 0)); - hashAdd(hash, "COUNT", 5, newSViv(eha.count)); - if (eha.pFile) - hashAdd(hash, "FILE", 4, newSVpv(eha.pFile, 0)); - if (eha.lineNo) - hashAdd(hash, "LINE", 4, newSVuv(eha.lineNo)); - - PUSHMARK(SP); - XPUSHs(channel); - XPUSHs(status); - XPUSHs(sv_2mortal(newSVpv(eha.ctx, 0))); - XPUSHs(sv_2mortal(newRV_noinc((SV *)hash))); - PUTBACK; - - call_sv(exception_sub, G_EVAL | G_VOID | G_DISCARD); - - FREETMPS; - LEAVE; - } -} - -void CA_add_exception_event(const char *class, SV *sub) { - caExceptionHandler *handler = exception_handler; - int status; - - if (! replace_handler(sub, &exception_sub, (long *)&handler)) - return; - - status = ca_add_exception_event(handler, NULL); - - if (status != ECA_NORMAL) { - SvREFCNT_dec(exception_sub); - exception_sub = NULL; - croak("%s", get_error_msg(status)); - } -} - - -/* CA::replace_printf_handler($class, \&sub) */ - -static -SV * printf_sub = NULL; - -#ifndef va_copy -# ifdef __GNUC__ -# define va_copy(d, s) __va_copy(d, s) -# else -# define va_copy(d, s) ((d) = (s)) -/* The above macro is NOT PORTABLE but works on Windows when - * stdarg.h doesn't provide va_copy(). Some architectures need - * define va_copy(d, s) ((*d) = (*s)) - * while others may be even more complicated, but hopefully the - * system stdarg.h header defines va_copy() in those cases. - */ -# endif -#endif - -static -int printf_handler(const char *format, va_list args) { - if (! printf_sub) - return 0; - - PERL_SET_CONTEXT(p5_ctx); - { - SV *printf_str; - dSP; - va_list argcopy; - - ENTER; - SAVETMPS; - - va_copy(argcopy, args); - - printf_str = NEWSV(0, strlen(format) + 32); - sv_vsetpvf(printf_str, format, &argcopy); - va_end(argcopy); - - PUSHMARK(SP); - XPUSHs(sv_2mortal(printf_str)); - PUTBACK; - - call_sv(printf_sub, G_EVAL | G_VOID | G_DISCARD); - - FREETMPS; - LEAVE; - } - return 0; -} - -void CA_replace_printf_handler(const char *class, SV *sub) { - caPrintfFunc *handler = printf_handler; - int status; - - if (! replace_handler(sub, &printf_sub, (long *)&handler)) - return; - - status = ca_replace_printf_handler(handler); - - if (status != ECA_NORMAL) { - SvREFCNT_dec(printf_sub); - printf_sub = NULL; - croak("%s", get_error_msg(status)); - } -} - - -/* CA::field_type($ca_ref) */ - -const char * CA_field_type(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - chtype t = ca_field_type(pch->chan); - if (t == TYPENOTCONN) - return "TYPENOTCONN"; - return dbr_type_to_text(t); -} - - -/* CA::element_count($ca_ref) */ - -int CA_element_count(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - return ca_element_count(pch->chan); -} - - -/* CA::name($ca_ref) */ - -const char * CA_name(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - return ca_name(pch->chan); -} - - -/* CA::state($ca_ref) */ - -const char * CA_state(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - static const char * const state_name[] = { - "never connected", "previously connected", "connected", "closed" - }; - return state_name[ca_state(pch->chan)]; -} - - -/* CA::is_connected($ca_ref) */ - -int CA_is_connected(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - return ca_state(pch->chan) == cs_conn; -} - - -/* CA::host_name($ca_ref) */ - -const char * CA_host_name(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - return ca_host_name(pch->chan); -} - - -/* CA::read_access($ca_ref) */ - -int CA_read_access(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - return ca_read_access(pch->chan); -} - - -/* CA::write_access($ca_ref) */ - -int CA_write_access(SV *ca_ref) { - CA_channel *pch = (CA_channel *)SvIV(SvRV(ca_ref)); - return ca_write_access(pch->chan); -} - -/******************************************************************************/ - -/* Ensure that the generated boot_Cap5 function is visible - * outside of the libCap5.so shared library when compiling - * with GCC4+ and -fvisibility=hidden is used. - */ -#if __GNUC__ >= 4 -XS(boot_Cap5) __attribute__ ((visibility ("default"))); -#endif - - -MODULE = Cap5 PACKAGE = Cap5 - -MODULE = Cap5 PACKAGE = CA PREFIX = CA_ - -PROTOTYPES: DISABLE - -BOOT: - p5_ctx = Perl_get_context(); - - -SV * -CA_new (class, name, ...) - const char * class - const char * name - PREINIT: - I32* temp; - CODE: - temp = PL_markstack_ptr++; - RETVAL = CA_new(class, name); - PL_markstack_ptr = temp; - OUTPUT: - RETVAL - -void -CA_DESTROY (ca_ref) - SV * ca_ref - -void -CA_context_destroy (class) - const char * class - -void -CA_change_connection_event (ca_ref, sub) - SV * ca_ref - SV * sub - -void -CA_replace_access_rights_event (ca_ref, sub) - SV * ca_ref - SV * sub - -void -CA_put (ca_ref, val, ...) - SV * ca_ref - SV * val - PREINIT: - I32* temp; - PPCODE: - temp = PL_markstack_ptr++; - CA_put(ca_ref, val); - if (PL_markstack_ptr != temp) { - /* truly void, because dXSARGS not invoked */ - PL_markstack_ptr = temp; - XSRETURN_EMPTY; /* return empty stack */ - } - /* must have used dXSARGS; list context implied */ - return; /* assume stack size is correct */ - -void -CA_put_callback (ca_ref, sub, val, ...) - SV * ca_ref - SV * sub - SV * val - PREINIT: - I32* temp; - PPCODE: - temp = PL_markstack_ptr++; - CA_put_callback(ca_ref, sub, val); - if (PL_markstack_ptr != temp) { - /* truly void, because dXSARGS not invoked */ - PL_markstack_ptr = temp; - XSRETURN_EMPTY; /* return empty stack */ - } - /* must have used dXSARGS; list context implied */ - return; /* assume stack size is correct */ - -void -CA_put_acks (ca_ref, sevr, ...) - SV * ca_ref - SV * sevr - PREINIT: - I32* temp; - PPCODE: - temp = PL_markstack_ptr++; - CA_put_acks(ca_ref, sevr); - if (PL_markstack_ptr != temp) { - /* truly void, because dXSARGS not invoked */ - PL_markstack_ptr = temp; - XSRETURN_EMPTY; /* return empty stack */ - } - /* must have used dXSARGS; list context implied */ - return; /* assume stack size is correct */ - -void -CA_put_ackt (ca_ref, ack, ...) - SV * ca_ref - int ack - PREINIT: - I32* temp; - PPCODE: - temp = PL_markstack_ptr++; - CA_put_ackt(ca_ref, ack); - if (PL_markstack_ptr != temp) { - /* truly void, because dXSARGS not invoked */ - PL_markstack_ptr = temp; - XSRETURN_EMPTY; /* return empty stack */ - } - /* must have used dXSARGS; list context implied */ - return; /* assume stack size is correct */ - -void -CA_get (ca_ref) - SV * ca_ref - -SV * -CA_value (ca_ref) - SV * ca_ref - -void -CA_get_callback (ca_ref, sub, ...) - SV * ca_ref - SV * sub - PREINIT: - I32* temp; - PPCODE: - temp = PL_markstack_ptr++; - CA_get_callback(ca_ref, sub); - if (PL_markstack_ptr != temp) { - /* truly void, because dXSARGS not invoked */ - PL_markstack_ptr = temp; - XSRETURN_EMPTY; /* return empty stack */ - } - /* must have used dXSARGS; list context implied */ - return; /* assume stack size is correct */ - -SV * -CA_create_subscription (ca_ref, mask_str, sub, ...) - SV * ca_ref - const char * mask_str - SV * sub - PREINIT: - I32* temp; - CODE: - temp = PL_markstack_ptr++; - RETVAL = CA_create_subscription(ca_ref, mask_str, sub); - PL_markstack_ptr = temp; - OUTPUT: - RETVAL - -void -CA_clear_subscription (class, mon_ref) - const char * class - SV * mon_ref - -void -CA_pend_io (class, timeout) - const char * class - double timeout - -int -CA_test_io (class) - const char * class - -void -CA_pend_event (class, timeout) - const char * class - double timeout - -void -CA_poll (class) - const char * class - -void -CA_flush_io (class) - const char * class - -const char * -CA_version (class) - const char * class - -void -CA_add_exception_event (class, sub) - const char * class - SV * sub - -void -CA_replace_printf_handler (class, sub) - const char * class - SV * sub - -const char * -CA_field_type (ca_ref) - SV * ca_ref - -int -CA_element_count (ca_ref) - SV * ca_ref - -const char * -CA_name (ca_ref) - SV * ca_ref - -const char * -CA_state (ca_ref) - SV * ca_ref - -int -CA_is_connected (ca_ref) - SV * ca_ref - -const char * -CA_host_name (ca_ref) - SV * ca_ref - -int -CA_read_access (ca_ref) - SV * ca_ref - -int -CA_write_access (ca_ref) - SV * ca_ref - diff --git a/src/ca/client/perl/Makefile b/src/ca/client/perl/Makefile deleted file mode 100644 index fb0fc96ff..000000000 --- a/src/ca/client/perl/Makefile +++ /dev/null @@ -1,73 +0,0 @@ -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -TOP=../../../.. -include $(TOP)/configure/CONFIG - -# Special settings for Darwin: -ifeq ($(OS_CLASS),Darwin) - # Use hdepends command (not GNU compiler flags) - # to generate header file dependancies for Darwin. - # Darwin has multiple -arch compiler flags. - HDEPENDS_METHOD = MKMF - - # Perl loadable libraries on Darwin have funny names - LOADABLE_SHRLIB_PREFIX = - LOADABLE_SHRLIB_SUFFIX = .$(shell $(PERL) ../perlConfig.pl dlext) -endif - -ifdef T_A - PERL_VERSION = $(shell $(PERL) ../perlConfig.pl version) - PERL_ARCHNAME = $(shell $(PERL) ../perlConfig.pl archname) - PERL_ARCHPATH := $(PERL_VERSION)/$(PERL_ARCHNAME) - - EXTUTILS := $(shell $(PERL) ../perlConfig.pl privlib)/ExtUtils - PERLBIN := $(shell $(PERL) ../perlConfig.pl bin) - XSUBPP := $(firstword $(wildcard $(PERLBIN)/xsubpp $(EXTUTILS)/xsubpp)) - -ifeq ($(strip $(XSUBPP)),) - $(warning Perl's xsubpp program was not found.) - $(warning The Perl CA module will not be built.) -else -ifeq ($(T_A),$(EPICS_HOST_ARCH)) # No cross-builds (wrong Perl!) -ifeq ($(findstring $(OS_CLASS),WIN32 cygwin32),) # Doesn't build on WIN32 - LOADABLE_LIBRARY_HOST = Cap5 - - PERL_SCRIPTS += cainfo.pl - PERL_SCRIPTS += caput.pl - PERL_SCRIPTS += caget.pl - PERL_SCRIPTS += capr.pl - PERL_SCRIPTS += camonitor.pl - - PERL_MODULES += CA.pm - PERL_MODULES += $(PERL_ARCHPATH)/$(LOADABLE_SHRLIB_PREFIX)Cap5$(LOADABLE_SHRLIB_SUFFIX) - - HTMLS_DIR = . - HTMLS = CA.html -endif -endif -endif -endif - -Cap5_SRCS = Cap5.xs -Cap5_LIBS = ca Com -Cap5_INCLUDES = -I$(shell $(PERL) ../perlConfig.pl archlib)/CORE -Cap5_CFLAGS = $(shell $(PERL) ../perlConfig.pl ccflags) - -CLEANS += Cap5.c pod2htmd.tmp pod2htmi.tmp - -include $(TOP)/configure/RULES - -ifdef T_A - %.c: ../%.xs - $(RM) $@ $@_new - $(PERL) $(XSUBPP) -typemap $(EXTUTILS)/typemap $< > $@_new && $(MV) $@_new $@ - - $(INSTALL_PERL_MODULES)/$(PERL_ARCHPATH)/%: % - $(ECHO) "Installing loadable shared library $@" - @$(INSTALL_LIBRARY) -d -m $(LIB_PERMISSIONS) $< $(INSTALL_PERL_MODULES)/$(PERL_ARCHPATH) -endif diff --git a/src/ca/client/perl/caget.pl b/src/ca/client/perl/caget.pl deleted file mode 100644 index 9d3df35b4..000000000 --- a/src/ca/client/perl/caget.pl +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env perl - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use Getopt::Std; -use Scalar::Util qw(looks_like_number); -use CA; - -our ($opt_0, $opt_a, $opt_d, $opt_e, $opt_f, $opt_g, $opt_h, $opt_n); -our ($opt_s, $opt_S, $opt_t); -our $opt_c = 0; -our $opt_F = ' '; -our $opt_w = 1; - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; - -HELP_MESSAGE() unless getopts('0:ac:d:e:f:F:g:hnsStw:'); -HELP_MESSAGE() if $opt_h; - -die "caget.pl: -c option takes a positive number\n" - unless looks_like_number($opt_c) && $opt_c >= 0; - -die "No pv name specified. ('caget.pl -h' gives help.)\n" - unless @ARGV; - -my @chans = map { CA->new($_); } grep { $_ ne '' } @ARGV; - -die "caget.pl: Please provide at least one non-empty pv name\n" - unless @chans; - -eval { CA->pend_io($opt_w); }; -if ($@) { - if ($@ =~ m/^ECA_TIMEOUT/) { - my $err = (@chans > 1) ? 'some PV(s)' : "'" . $chans[0]->name . "'"; - print "Channel connect timed out: $err not found.\n"; - @chans = grep { $_->is_connected } @chans; - } else { - die $@; - } -} - -my %rtype; - -map { - my $type; - if ($opt_d) { - $type = $opt_d; - } else { - $type = $_->field_type; - $type = 'DBR_STRING' - if $opt_s && $type =~ m/ ^ DBR_ ( DOUBLE | FLOAT ) $ /x; - $type = 'DBR_LONG' - if ($opt_n && $type eq 'DBR_ENUM') - || (!$opt_S && $type eq 'DBR_CHAR'); - $type =~ s/^DBR_/DBR_TIME_/ - if $opt_a; - } - $rtype{$_} = $type; - $_->get_callback(\&get_callback, $type, 0+$opt_c); -} @chans; - -my $incomplete = @chans; -CA->pend_event(0.1) while $incomplete; - - -sub get_callback { - my ($chan, $status, $data) = @_; - die $status if $status; - display($chan, $rtype{$chan}, $data); - $incomplete--; -} - -sub format_number { - my ($data, $type) = @_; - if ($type =~ m/_DOUBLE$/) { - return sprintf "%.${opt_e}e", $data if $opt_e; - return sprintf "%.${opt_f}f", $data if $opt_f; - return sprintf "%.${opt_g}g", $data if $opt_g; - } - if ($type =~ m/_LONG$/) { - return sprintf "%lx", $data if $opt_0 eq 'x'; - return sprintf "%lo", $data if $opt_0 eq 'o'; - if ($opt_0 eq 'b') { - my $bin = unpack "B*", pack "l", $data; - $bin =~ s/^0*//; - return $bin; - } - } - return $data; -} - -sub display { - my ($chan, $type, $data) = @_; - if (ref $data eq 'ARRAY') { - display($chan, $type, join($opt_F, scalar @{$data}, @{$data})); - } elsif (ref $data eq 'HASH') { - printf "%s\n", $chan->name; - my $dtype = $data->{TYPE}; # Can differ from request - printf " Native data type: %s\n", $chan->field_type; - printf " Request type: %s\n", $dtype; - printf " Element count: %d\n", $data->{COUNT} - if exists $data->{COUNT}; - my $val = $data->{value}; - if (ref $val eq 'ARRAY') { - printf " Value: %s\n", join($opt_F, - map { format_number($_, $dtype); } @{$val}); - } else { - printf " Value: %s\n", format_number($val, $dtype); - } - if (exists $data->{stamp}) { - my @t = localtime $data->{stamp}; - splice @t, 6; - $t[5] += 1900; - $t[0] += $data->{stamp_fraction}; - printf " Timestamp: %4d-%02d-%02d %02d:%02d:%09.6f\n", - reverse @t; - } - printf " Status: %s\n", $data->{status}; - printf " Severity: %s\n", $data->{severity}; - if (exists $data->{units}) { - printf " Units: %s\n", $data->{units}; - } - if (exists $data->{precision}) { - printf " Precision: %d\n", $data->{precision}; - } - if (exists $data->{upper_disp_limit}) { - printf " Lo disp limit: %g\n", $data->{lower_disp_limit}; - printf " Hi disp limit: %g\n", $data->{upper_disp_limit}; - } - if (exists $data->{upper_alarm_limit}) { - printf " Lo alarm limit: %g\n", $data->{lower_alarm_limit}; - printf " Lo warn limit: %g\n", $data->{lower_warning_limit}; - printf " Hi warn limit: %g\n", $data->{upper_warning_limit}; - printf " Hi alarm limit: %g\n", $data->{upper_alarm_limit}; - } - if (exists $data->{upper_ctrl_limit}) { - printf " Lo ctrl limit: %g\n", $data->{lower_ctrl_limit}; - printf " Hi ctrl limit: %g\n", $data->{upper_ctrl_limit}; - } - } else { - my $value = format_number($data, $type); - if ($opt_t) { - print "$value\n"; - } else { - printf "%s%s%s\n", $chan->name, $opt_F, $value; - } - } -} - -sub HELP_MESSAGE { - print STDERR "\nUsage: caget.pl [options] ...\n", - "\n", - " -h: Help: Print this message\n", - "Channel Access options:\n", - " -w : Wait time, specifies CA timeout, default is $opt_w second\n", - "Format options:\n", - " -t: Terse mode - print only value, without name\n", - " -a: Wide mode \"name timestamp value stat sevr\" (read PVs as DBR_TIME_xxx)\n", - " -d : Request specific dbr type from one of the following:\n", - " DBR_STRING DBR_LONG DBR_DOUBLE\n", - " DBR_STS_STRING DBR_STS_LONG DBR_STS_DOUBLE\n", - " DBR_TIME_STRING DBR_TIME_LONG DBR_TIME_DOUBLE\n", - " DBR_GR_STRING DBR_GR_LONG DBR_GR_DOUBLE DBR_GR_ENUM\n", - " DBR_CTRL_STRING DBR_CTRL_LONG DBR_CTRL_DOUBLE DBR_CTRL_ENUM\n", - " DBR_CLASS_NAME DBR_STSACK_STRING\n", - "Arrays: Value format: print number of values, then list of values\n", - " Default: Print all values\n", - " -c : Print first elements of an array\n", - " -S: Print array of char as a string (long string)\n", - "Enum format:\n", - " -n: Print DBF_ENUM value as number (default is enum string)\n", - "Floating point type format:\n", - " Default: Use %g format\n", - " -e : Use %e format, with a precision of digits\n", - " -f : Use %f format, with a precision of digits\n", - " -g : Use %g format, with a precision of digits\n", - " -s: Get value as string (may honour server-side precision)\n", - "Integer number format:\n", - " Default: Print as decimal number\n", - " -0x: Print as hex number\n", - " -0o: Print as octal number\n", - " -0b: Print as binary number\n", - "Set output field separator:\n", - " -F : Use to separate fields on output\n", - "\n", - "Base version: ", CA->version, "\n"; - exit 1; -} diff --git a/src/ca/client/perl/cainfo.pl b/src/ca/client/perl/cainfo.pl deleted file mode 100644 index ee6b6d0a2..000000000 --- a/src/ca/client/perl/cainfo.pl +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env perl - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use Getopt::Std; -use CA; - -our $opt_w = 1; -our $opt_h; - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; - -HELP_MESSAGE() unless getopts('hw:'); -HELP_MESSAGE() if $opt_h; - -die "No pv name specified. ('cainfo.pl -h' gives help.)\n" - unless @ARGV; - -my @chans = map { CA->new($_); } grep { $_ ne '' } @ARGV; - -die "cainfo.pl: Please provide at least one non-empty pv name\n" - unless @chans; - -eval { - CA->pend_io($opt_w); -}; -if ($@) { - if ($@ =~ m/^ECA_TIMEOUT/) { - my $err = (@chans > 1) ? 'some PV(s)' : "'" . $chans[0]->name . "'"; - print "Channel connect timed out: $err not found.\n"; - } else { - die $@; - } -} - -map { display($_); } @chans; - - -sub display { - my $chan = shift; - - printf "%s\n", $chan->name; - printf " State: %s\n", $chan->state; - printf " Host: %s\n", $chan->host_name; - - my @access = ('no ', ''); - printf " Access: %sread, %swrite\n", - $access[$chan->read_access], $access[$chan->write_access]; - - printf " Data type: %s\n", $chan->field_type; - printf " Element count: %d\n", $chan->element_count; -} - -sub HELP_MESSAGE { - print STDERR "\nUsage: cainfo.pl [options] ...\n", - "\n", - " -h: Help: Print this message\n", - "Channel Access options:\n", - " -w : Wait time, specifies CA timeout, default is $opt_w second\n", - "\n", - "Example: cainfo my_channel another_channel\n", - "\n", - "Base version: ", CA->version, "\n"; - exit 1; -} diff --git a/src/ca/client/perl/camonitor.pl b/src/ca/client/perl/camonitor.pl deleted file mode 100644 index d49c85d45..000000000 --- a/src/ca/client/perl/camonitor.pl +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env perl - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use Getopt::Std; -use Scalar::Util qw(looks_like_number); -use CA; - -our ($opt_0, $opt_e, $opt_f, $opt_g, $opt_h, $opt_n, $opt_s, $opt_S); -our $opt_c = 0; -our $opt_F = ' '; -our $opt_w = 1; -our $opt_m = 'va'; - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; - -HELP_MESSAGE() unless getopts('0:c:e:f:F:g:hm:nsSw:'); -HELP_MESSAGE() if $opt_h; - -die "camonitor.pl: -c option takes a positive number\n" - unless looks_like_number($opt_c) && $opt_c >= 0; - -die "No pv name specified. ('camonitor.pl -h' gives help.)\n" - unless @ARGV; - -my %monitors; -my @chans = map { CA->new($_, \&conn_callback); } grep { $_ ne '' } @ARGV; - -die "camonitor.pl: Please provide at least one non-empty pv name\n" - unless @chans; - -my $fmt = ($opt_F eq ' ') ? "%-30s %s\n" : "%s$opt_F%s\n"; - -CA->pend_event($opt_w); -map { - printf $fmt, $_->name, '*** Not connected (PV not found)' - unless $monitors{$_}; -} @chans; -CA->pend_event(0); - - -sub conn_callback { - my ($chan, $up) = @_; - if ($up && ! $monitors{$chan}) { - my $type = $chan->field_type; - $type = 'DBR_STRING' - if $opt_s && $type =~ m/ ^ DBR_ ( DOUBLE | FLOAT ) $ /x; - $type = 'DBR_LONG' - if ($opt_n && $type eq 'DBR_ENUM') - || (!$opt_S && $type eq 'DBR_CHAR'); - $type =~ s/^DBR_/DBR_TIME_/; - - $monitors{$chan} = - $chan->create_subscription($opt_m, \&mon_callback, $type, 0+$opt_c); - } -} - -sub mon_callback { - my ($chan, $status, $data) = @_; - if ($status) { - printf $fmt, $chan->name, $status; - } else { - display($chan, $data); - } -} - -sub format_number { - my ($data, $type) = @_; - if ($type =~ m/_DOUBLE$/) { - return sprintf "%.${opt_e}e", $data if $opt_e; - return sprintf "%.${opt_f}f", $data if $opt_f; - return sprintf "%.${opt_g}g", $data if $opt_g; - } - if ($type =~ m/_LONG$/) { - return sprintf "%lx", $data if $opt_0 eq 'x'; - return sprintf "%lo", $data if $opt_0 eq 'o'; - if ($opt_0 eq 'b') { - my $bin = unpack "B*", pack "l", $data; - $bin =~ s/^0*//; - return $bin; - } - } - return $data; -} - -sub display { - my ($chan, $data) = @_; - die "Internal error" - unless ref $data eq 'HASH'; - - my $type = $data->{TYPE}; - my $value = $data->{value}; - if (ref $value eq 'ARRAY') { - $value = join($opt_F, $data->{COUNT}, - map { format_number($_, $type); } @{$value}); - } else { - $value = format_number($value, $type); - } - my $stamp; - if (exists $data->{stamp}) { - my @t = localtime $data->{stamp}; - splice @t, 6; - $t[5] += 1900; - $t[0] += $data->{stamp_fraction}; - $stamp = sprintf "%4d-%02d-%02d %02d:%02d:%09.6f", reverse @t; - } - printf $fmt, $chan->name, join($opt_F, - $stamp, $value, $data->{status}, $data->{severity}); -} - -sub HELP_MESSAGE { - print STDERR "\nUsage: camonitor.pl [options] ...\n", - "\n", - " -h: Help: Print this message\n", - "Channel Access options:\n", - " -w : Wait time, specifies CA timeout, default is $opt_w second\n", - " -m : Specify CA event mask to use, with being any combination of\n", - " 'v' (value), 'a' (alarm), 'l' (log/archive), 'p' (property)", - " Default: '$opt_m'\n", -# "Timestamps:\n", -# " Default: Print absolute timestamps (as reported by CA)\n", -# " -r: Relative timestamps (time elapsed since start of program)\n", -# " -i: Incremental timestamps (time elapsed since last update)\n", -# " -I: Incremental timestamps (time elapsed since last update for this channel)\n", - "Enum format:\n", - " -n: Print DBF_ENUM values as number (default are enum string values)\n", - "Arrays: Value format: print number of values, then list of values\n", - " Default: Print all values\n", - " -c : Print first elements of an array\n", - " -S: Print array of char as a string (long string)\n", - "Floating point type format:\n", - " Default: Use %g format\n", - " -e : Use %e format, with a precision of digits\n", - " -f : Use %f format, with a precision of digits\n", - " -g : Use %g format, with a precision of digits\n", - " -s: Get value as string (may honour server-side precision)\n", - "Integer number format:\n", - " Default: Print as decimal number\n", - " -0x: Print as hex number\n", - " -0o: Print as octal number\n", - " -0b: Print as binary number\n", - "Alternate output field separator:\n", - " -F : Use to separate fields on output\n", - "\n", - "Example: camonitor -f8 my_channel another_channel\n", - " (doubles are printed as %f with 8 decimal digits)\n", - "\n", - "Base version: ", CA->version, "\n"; - exit 1; -} diff --git a/src/ca/client/perl/capr.pl b/src/ca/client/perl/capr.pl deleted file mode 100644 index cf0c4d397..000000000 --- a/src/ca/client/perl/capr.pl +++ /dev/null @@ -1,422 +0,0 @@ -#!/usr/bin/env perl - -####################################################################### -# -# capr: A program that attempts to do a "dbpr" command via channel -# access. -# -####################################################################### - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use Getopt::Std; -use EPICS::Path; -use CA; - -######### Globals ########## - -our ($opt_h, $opt_f, $opt_r); -our $opt_d = $ENV{EPICS_CAPR_DBD_FILE} || "$Bin/../../dbd/softIoc.dbd"; -our $opt_w = 1; - -my %record = (); # Empty hash to put dbd data in -my $iIdx = 0; # Array indexes for interest, data type and base -my $tIdx = 1; -my $bIdx = 2; -my %device = (); # Empty hash to record which rec types have device support - -# EPICS field types -my %fieldType = ( - DBF_CHAR => 'DBF_CHAR', - DBF_UCHAR => 'DBF_CHAR', - DBF_DOUBLE => 'DBF_FLOAT', - DBF_FLOAT => 'DBF_FLOAT', - DBF_LONG => 'DBF_LONG', - DBF_SHORT => 'DBF_LONG', - DBF_ULONG => 'DBF_LONG', - DBF_USHORT => 'DBF_LONG', - DBF_DEVICE => 'DBF_STRING', - DBF_ENUM => 'DBF_STRING', - DBF_FWDLINK => 'DBF_STRING', - DBF_INLINK => 'DBF_STRING', - DBF_MENU => 'DBF_STRING', - DBF_OUTLINK => 'DBF_STRING', - DBF_STRING => 'DBF_STRING', - DBF_NOACCESS => 'DBF_NOACCESS', -); - -# globals for sub caget -my %callback_data; -my %timed_out; -my $callback_incomplete; - -######### Main program ############ - -HELP_MESSAGE() unless getopts('hd:f:rw:'); -HELP_MESSAGE() if $opt_h; - -die "File $opt_d not found. (\"capr.pl -h\" gives help)\n" - unless -f $opt_d; - -parseDbd($opt_d); -print "Using $opt_d\n\n"; - -# Print a list of record types -if ($opt_r) { - print ("Record types found:\n"); - printList(0); - exit; -} - -# Print the fields defined for given record -if ($opt_f) { - printRecordList($opt_f); - exit; -} - -HELP_MESSAGE() unless @ARGV; - -$_ = shift; -if (@ARGV) { - # Drop any ".FIELD" part - s/\. \w+ $//x; - printRecord($_, @ARGV); -} else { - if (m/^ \s* ([]+:;<>0-9A-Za-z[-]+) (?:\. \w+)? \s* , \s* (\d+) \s* $/x) { - # Recognizes ",n" as an interest leve, drops any ".FIELD" part - printRecord($1, $2); - } else { - # Drop any ".FIELD" part - s/\. \w+ $//x; - printRecord($_, 0); - } -} - -########## End of main ########### - - - -# parseDbd -# Takes given dbd file and parses it to produce a hash table of record types -# giving their fields, and for each field its interest level and data type. -# usage: parseDbd("fileName"); -# Output goes to the global %record, a hash of references to other hashes -# containing the fields of each record type. Those hash values (keyed by -# field name) are references to arrays containing the interest level, data -# type and number base of the field. -sub parseDbd { - my $dbdFile = shift; - - open(DBD, "< $dbdFile") or die "Can't open file $dbdFile: $!\n"; - my @dbd = ; - close(DBD) or die "Can't close $dbdFile: $!\n"; - - my $i = 1; - my $level = 0; - my $isArecord = 0; - my $isAfield = 0; - my $thisRecord; - my $thisField; - my $thisType; - my $field = {}; - my $interest = 0; - my $thisBase = 'DECIMAL'; - - while (@dbd) { - $_ = shift @dbd; - chomp; - if ( m/recordtype \s* \( \s* (\w+) \)/x ) { - die "File format error at line $i of file\n $opt_d\n" - unless $level == 0; - $isArecord = 1; - $thisRecord = $1; - } - elsif ( m/field \s* \( \s* (\w+) \s* , \s* (\w+) \s* \)/x ) { - die "File format error at line $i of file\n $opt_d\n" - unless $level == 1 && $isArecord; - $thisField = $1; - $thisType = $2; - $isAfield = 1; - } - elsif ( m/interest \s* \( \s* (\w+) \s* \)/x ) { - die "File format error at line $i of file\n $opt_d\n" - unless $level == 2 && $isAfield; - $interest = $1; - } - elsif ( m/base \s* \( \s* (\w+) \s* \)/x ) { - die "File format error at line $i of file\n $opt_d\n" - unless $level == 2 && $isAfield; - $thisBase = $1; - } - elsif ( m/device \s* \( (\w+) \s* ,/x ) { - die "File format error at line $i of file\n $opt_d\n" - unless $level == 0; - $device{$1}++; - } - if ( m/\{/ ) { - $level++; - } - if ( m/\}/ ) { - if ($level == 2 && $isAfield) { - my $params = []; - $params->[$iIdx] = $interest; - $params->[$tIdx] = $thisType; - $params->[$bIdx] = $thisBase; - $field->{$thisField} = $params; - $isAfield = 0; - $interest = 0; # reset default - $thisBase = 'DECIMAL'; # reset default - } - elsif ($level == 1 && $isArecord) { - $isArecord = 0; - $record{$thisRecord} = $field; - $field = {}; # start another hash - } - $level--; - } - $i++; - } -} - - -# Given a record name, attempts to find the record and its type. -# Usage: $recordType = getRecType("recordName"); -sub getRecType { - my $arg = shift; - my $name = "$arg.RTYP"; - - my $fields_read = caget($name); - - die "Could not determine record type of $arg\n" - unless $fields_read == 1; - - return $callback_data{$name}; -} - -# Given the record type and field, returns the interest level, data type -# and number base for the field -# Usage: ($dataType, $interest, $base) = getFieldParams($recType, $field); -sub getFieldParams { - my ($recType, $field) = @_; - - my $params = $record{$recType}{$field} or - die "Can't find params for $recType.$field"; - exists($fieldType{$params->[$tIdx]}) || - die "Field data type $field for $recType not found in dbd file --"; - exists($params->[$iIdx]) || - die "Interest level for $field in $recType not found in dbd file --"; - - my $fType = $fieldType{$params->[$tIdx]}; - my $fInterest = $params->[$iIdx]; - my $fBase = $params->[$bIdx]; - return ($fType, $fInterest, $fBase); -} - -# Prints field name and data for given field. Formats output so -# that fields align in to 4 columns. Tries to imitate dbpf format -# Usage: printField( $fieldName, $data, $dataType, $base, $firstColumnPosn) -sub printField { - my ($fieldName, $fieldData, $dataType, $base, $col) = @_; - - my $screenWidth = 80; - my ($outStr, $wide); - - my $field = "$fieldName:"; - - if ( $dataType eq 'DBF_STRING' ) { - $outStr = sprintf('%-5s %s', $field, $fieldData); - } elsif ( $base eq 'HEX' ) { - my $val = ( $dataType eq 'DBF_CHAR' ) ? ord($fieldData) : $fieldData; - $outStr = sprintf('%-5s 0x%x', $field, $val); - } elsif ( $dataType eq 'DBF_DOUBLE' || $dataType eq 'DBF_FLOAT' ) { - $outStr = sprintf('%-5s %.8f', $field, $fieldData); - } elsif ( $dataType eq 'DBF_CHAR' ) { - $outStr = sprintf('%-5s %d', $field, ord($fieldData)); - }else { - # DBF_LONG, DBF_SHORT, DBF_UCHAR, DBF_ULONG, DBF_USHORT - $outStr = sprintf('%-5s %d', $field, $fieldData); - } - - my $len = length($outStr); - if ($len <= 20) { $wide = 20; } - elsif ( $len <= 40 ) { $wide = 40; } - elsif ( $len <= 60 ) { $wide = 60; } - else { $wide = 80;} - - my $pad = $wide - $len; - - $col += $wide; - if ($col > $screenWidth ) { - print("\n"); - $col = $wide; - } - - print $outStr, ' ' x $pad; - - return $col; -} - -# Query for a list of fields simultaneously. -# The results are filled in the the %callback_data global hash -# and the result of the operation is the number of read pvs -# -# NOTE: Not re-entrant because results are written to global hash -# %callback_data -# -# Usage: $fields_read = caget( @pvlist ) -sub caget { - my @chans = map { CA->new($_); } @_; - - #clear results; - %callback_data = (); - %timed_out = (); - - eval { CA->pend_io($opt_w); }; - if ($@) { - if ($@ =~ m/^ECA_TIMEOUT/) { - my $err = (@chans > 1) ? 'some PV(s)' : '"' . $chans[0]->name . '"'; - print "Channel connect timed out: $err not found.\n"; - foreach my $chan (@chans) { - $timed_out{$chan->name} = $chan->is_connected; - } - @chans = grep { $_->is_connected } @chans; - } else { - die $@; - } - } - - map { - my $type; - $type = $_->field_type; - $_->get_callback(\&caget_callback, $type); - } @chans; - - my $fields_read = @chans; - $callback_incomplete = @chans; - CA->pend_event(0.1) while $callback_incomplete; - return $fields_read; -} - -sub caget_callback { - my ($chan, $status, $data) = @_; - die $status if $status; - $callback_data{$chan->name} = $data; - $callback_incomplete--; -} - -# Given record name and interest level prints data from record fields -# that are at or below the interest level specified. -# Usage: printRecord($recordName, $interestLevel) -sub printRecord { - my ($name, $interest) = @_; - - my $recType = getRecType($name); - print("Record $name type $recType\n"); - die "Record type $recType not found\n" - unless exists $record{$recType}; - - #capture list of fields - my @readlist = (); #fields to read via CA - my @fields_pr = (); #fields for print-out - my @ftypes = (); #types, from parser - my @bases = (); #bases, from parser - foreach my $field (sort keys %{$record{$recType}}) { - # Skip DTYP field if this rec type doesn't have device support defined - if ($field eq 'DTYP' && !(exists($device{$recType}))) { next; } - - my ($fType, $fInterest, $base) = getFieldParams($recType, $field); - unless( $fType eq 'DBF_NOACCESS' ) { - if ($interest >= $fInterest ) { - my $fToGet = "$name.$field"; - push @fields_pr, $field; - push @readlist, $fToGet; - push @ftypes, $fType; - push @bases, $base; - } - } - } - my $fields_read = caget( @readlist ); - - # print while iterating over lists gathered - my $col = 0; - for (my $i=0; $i < scalar @readlist; $i++) { - my $field = $fields_pr[$i]; - my $fToGet = $readlist[$i]; - my ($fType, $data, $base); - if ($timed_out{$fToGet}) { - $fType = $fieldType{DBF_STRING}; - $data = ''; - } - else { - $fType = $ftypes[$i]; - $base = $bases[$i]; - $data = $callback_data{$fToGet}; - } - $col = printField($field, $data, $fType, $base, $col); - } - print("\n"); # Final newline -} - -# Prints list of record types found in dbd file. If level > 0 -# then the fields of that record type, their interest levels and types are -# also printed. -# Diagnostic routine, usage: void printList(level); -sub printList { - my $level = shift; - - foreach my $rkey (sort keys(%record)) { - print(" $rkey\n"); - if ($level > 0) { - foreach my $fkey (keys %{$record{$rkey}}) { - print("\tField $fkey - interest $record{$rkey}{$fkey}[$iIdx] "); - print("- type $record{$rkey}{$fkey}[$tIdx] "); - print("- base $record{$rkey}{$fkey}[$bIdx]\n"); - } - } - } -} - -# Prints list of fields with interest levels for given record type -# Diagnostic routine, usage: void printRecordList("recordType"); -sub printRecordList { - my $type = shift; - - if (exists($record{$type}) ) { - print("Record type - $type\n"); - foreach my $fkey (sort keys %{$record{$type}}) { - printf('%-4s', $fkey); - printf(" interest = $record{$type}{$fkey}[$iIdx]"); - printf(" type = %-12s ",$record{$type}{$fkey}[$tIdx]); - print (" base = $record{$type}{$fkey}[$bIdx]\n"); - } - } - else { - print("Record type $type not defined in dbd file $opt_d\n"); - } -} - -sub HELP_MESSAGE { - print STDERR "\n", - "Usage: capr.pl -h\n", - " capr.pl [options] -r\n", - " capr.pl [options] -f \n", - " capr.pl [options] []\n", - "\n", - " -h Print this help message.\n", - "Channel Access options:\n", - " -w : Wait time, specifies CA timeout, default is $opt_w second\n", - "Database Definitions:\n", - " -d : The file containing record type definitions.\n", - " This can be set using the EPICS_CAPR_DBD_FILE environment variable.\n", - " Default: ", AbsPath($opt_d), "\n", - "Output Options:\n", - " -r Lists all record types in the selected dbd file.\n", - " -f : Lists all fields with their interest level, data type\n", - " and number base for the given record_type.\n", - "\n", - "Base version: ", CA->version, "\n"; - exit 1; -} diff --git a/src/ca/client/perl/caput.pl b/src/ca/client/perl/caput.pl deleted file mode 100644 index 468c3ad7a..000000000 --- a/src/ca/client/perl/caput.pl +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env perl - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use Getopt::Std; -use CA; - -our ($opt_0, $opt_c, $opt_e, $opt_f, $opt_g, $opt_h, $opt_l, - $opt_n, $opt_s, $opt_S, $opt_t); -our $opt_w = 1; - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; - -HELP_MESSAGE() unless getopts('achlnsStw:'); -HELP_MESSAGE() if $opt_h; - -die "No pv name specified. ('caput.pl -h' gives help.)\n" - unless @ARGV; -my $pv = shift; -die "caput.pl: Empty pv name given.\n" - unless $pv ne ''; - -die "No value specified. ('caput.pl -h' gives help.)\n" - unless @ARGV; - -my $chan = CA->new($pv); -eval { - CA->pend_io($opt_w); -}; -if ($@) { - if ($@ =~ m/^ECA_TIMEOUT/) { - print "Channel connect timed out: '$pv' not found.\n"; - exit 2; - } else { - die $@; - } -} - -die "Write access denied for '$pv'.\n" unless $chan->write_access; - -my $n = $chan->element_count(); -die "Too many values given, '$pv' limit is $n\n" - unless $n >= @ARGV; - -my $type = $chan->field_type; -$type = 'DBR_STRING' - if $opt_s && $type =~ m/ ^ DBR_ (ENUM | FLOAT | DOUBLE) $ /x; -$type = 'DBR_LONG' - if ($opt_n && $type eq 'DBR_ENUM') - || (!$opt_S && $type eq 'DBR_CHAR'); -$type =~ s/^DBR_/DBR_TIME_/ - if $opt_l; - -my @values; -if ($type !~ m/ ^ DBR_ (STRING | ENUM | CHAR) $ /x) { - # Make @ARGV strings numeric - @values = map { +$_; } @ARGV; -} else { - # Use strings - @values = @ARGV; -} - -my $done = 0; -if ($opt_t) { - do_put(); -} else { - $chan->get_callback(\&old_callback, $type); -} -CA->pend_event(0.1) until $done; - - -sub old_callback { - my ($chan, $status, $data) = @_; - die $status if $status; - display($chan, $type, $data, 'Old'); - do_put(); -} - -sub do_put { - if ($opt_c) { - $chan->put_callback(\&put_callback, @values); - } else { - $chan->put(@values); - $chan->get_callback(\&new_callback, $type); - } -} - -sub put_callback { - my ($chan, $status) = @_; - die $status if $status; - $chan->get_callback(\&new_callback, $type); -} - -sub new_callback { - my ($chan, $status, $data) = @_; - die $status if $status; - display($chan, $type, $data, 'New'); - $done = 1; -} - -sub format_number { - my ($data, $type) = @_; - if ($type =~ m/_DOUBLE$/) { - return sprintf "%.${opt_e}e", $data if $opt_e; - return sprintf "%.${opt_f}f", $data if $opt_f; - return sprintf "%.${opt_g}g", $data if $opt_g; - } - if ($type =~ m/_LONG$/) { - return sprintf "%lx", $data if $opt_0 eq 'x'; - return sprintf "%lo", $data if $opt_0 eq 'o'; - if ($opt_0 eq 'b') { - my $bin = unpack "B*", pack "l", $data; - $bin =~ s/^0*//; - return $bin; - } - } - return $data; -} - -sub display { - my ($chan, $type, $data, $prefix) = @_; - if (ref $data eq 'ARRAY') { - display($chan, $type, join(' ', @{$data}), $prefix); - } elsif (ref $data eq 'HASH') { - $type = $data->{TYPE}; # Can differ from request - my $value = $data->{value}; - if (ref $value eq 'ARRAY') { - $value = join(' ', map { format_number($_, $type); } @{$value}); - } else { - $value = format_number($value, $type); - } - my $stamp; - if (exists $data->{stamp}) { - my @t = localtime $data->{stamp}; - splice @t, 6; - $t[5] += 1900; - $t[0] += $data->{stamp_fraction}; - $stamp = sprintf "%4d-%02d-%02d %02d:%02d:%09.6f", reverse @t; - } - printf "%-30s %s %s %s %s\n", $chan->name, - $stamp, $value, $data->{status}, $data->{severity}; - } else { - my $value = format_number($data, $type); - if ($opt_t) { - print "$value\n"; - } else { - printf "$prefix : %-30s %s\n", $chan->name, $value; - } - } -} - -sub HELP_MESSAGE { - print STDERR "\nUsage: caput.pl [options] ...\n", - "\n", - " -h: Help: Print this message\n", - "Channel Access options:\n", - " -w : Wait time, specifies CA timeout, default is $opt_w second\n", - " -c: Use put_callback to wait for completion\n", - "Format options:\n", - " -t: Terse mode - print only sucessfully written value, without name\n", - " -l: Long mode \"name timestamp value stat sevr\" (read PVs as DBR_TIME_xxx)\n", - " -S: Put string as an array of char (long string)\n", - "Enum format:\n", - " Default: Auto - try value as ENUM string, then as index number\n", - " -n: Force interpretation of values as numbers\n", - " -s: Force interpretation of values as strings\n", - "Floating point type format:\n", - " Default: Use %g format\n", - " -e : Use %e format, with a precision of digits\n", - " -f : Use %f format, with a precision of digits\n", - " -g : Use %g format, with a precision of digits\n", - " -s: Get value as string (may honour server-side precision)\n", - "Integer number format:\n", - " Default: Print as decimal number\n", - " -0x: Print as hex number\n", - " -0o: Print as octal number\n", - " -0b: Print as binary number\n", - "\n", - "Examples:\n", - " caput my_channel 1.2\n", - " caput my_waveform 1.2 2.4 3.6 4.8 6.0\n", - "\n", - "Base version: ", CA->version, "\n"; - exit 1; -} - diff --git a/src/ca/client/perl/perlConfig.pl b/src/ca/client/perl/perlConfig.pl deleted file mode 100644 index 5292041d1..000000000 --- a/src/ca/client/perl/perlConfig.pl +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env perl - -# This script is used to extract information about the Perl build -# configuration, so the EPICS build system uses the same settings. - -use strict; -use Config; - -my $arg = shift; -my $val = $Config{$arg}; - -$val =~ s{\\}{/}go - if $^O eq 'MSWin32'; - -print $val; diff --git a/src/ca/client/putCallback.cpp b/src/ca/client/putCallback.cpp deleted file mode 100644 index 85fcaeb7f..000000000 --- a/src/ca/client/putCallback.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "oldAccess.h" - -putCallback::putCallback ( - oldChannelNotify & chanIn, caEventCallBackFunc * pFuncIn, - void * pPrivateIn ) : - chan ( chanIn ), pFunc ( pFuncIn ), pPrivate ( pPrivateIn ) -{ -} - -putCallback::~putCallback () -{ -} - -void putCallback::completion ( epicsGuard < epicsMutex > & guard ) -{ - struct event_handler_args args; - - args.usr = this->pPrivate; - args.chid = & this->chan; - args.type = TYPENOTCONN; - args.count = 0; - args.status = ECA_NORMAL; - args.dbr = 0; - caEventCallBackFunc * pFuncTmp = this->pFunc; - // fetch client context and destroy prior to releasing - // the lock and calling cb in case they destroy channel there - this->chan.getClientCtx().destroyPutCallback ( guard, *this ); - if ( pFuncTmp ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - pFuncTmp ( args ); - } -} - -void putCallback::exception ( - epicsGuard < epicsMutex > & guard, - int status, const char * /* pContext */, - unsigned type, arrayElementCount count ) -{ - if ( status != ECA_CHANDESTROY ) { - struct event_handler_args args; - args.usr = this->pPrivate; - args.chid = & this->chan; - args.type = type; - args.count = count; - args.status = status; - args.dbr = 0; - caEventCallBackFunc * pFuncTmp = this->pFunc; - // fetch client context and destroy prior to releasing - // the lock and calling cb in case they destroy channel there - this->chan.getClientCtx().destroyPutCallback ( guard, *this ); - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - ( *pFuncTmp ) ( args ); - } - } - else { - this->chan.getClientCtx().destroyPutCallback ( guard, *this ); - } -} - -void putCallback::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - diff --git a/src/ca/client/repeater.cpp b/src/ca/client/repeater.cpp deleted file mode 100644 index 61ba33fc5..000000000 --- a/src/ca/client/repeater.cpp +++ /dev/null @@ -1,587 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * REPEATER.cpp - * - * CA broadcast repeater - * - * Author: Jeff Hill - * Date: 3-27-90 - * - * PURPOSE: - * Broadcasts fan out over the LAN, but old IP kernels do not allow - * two processes on the same machine to get the same broadcast - * (and modern IP kernels do not allow two processes on the same machine - * to receive the same unicast). - * - * This code fans out UDP messages sent to the CA repeater port - * to all CA client processes that have subscribed. - * - */ - -/* - * It would be preferable to avoid using the repeater on multicast enhanced - * IP kernels, but this is not going to work in all situations because - * (according to Steven's TCP/IP illustrated volume I) if a broadcast is - * received it goes to all sockets on the same port, but if a unicast is - * received it goes to only one of the sockets on the same port (we can only - * guess at which one it will be). - * - * I have observed this behavior under winsock II: - * o only one of the sockets on the same port receives the message if we - * send to the loopback address - * o both of the sockets on the same port receives the message if we send - * to the broadcast address - */ - -/* verifyClients() Mechanism - * - * This is required because Solaris and HPUX have half baked versions - * of sockets. - * - * As written, the repeater should be robust against situations where the - * IP kernel doesn't implement UDP disconnect on receiving ICMP port - * unreachable errors from the destination process. As I recall, this - * change was required in the repeater code when we ported from sunos4 to - * Solaris. To avoid unreasonable overhead, I decided at the time to check - * the validity of all existing connections only when a new client - * registers with the repeater (and not when fanning out each beacon - * received). -- Jeff - */ - -#include -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "tsDLList.h" -#include "envDefs.h" -#include "tsFreeList.h" -#include "osiWireFormat.h" -#include "taskwd.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "caProto.h" -#include "udpiiu.h" -#include "repeaterClient.h" - - -/* - * these can be external since there is only one instance - * per machine so we dont care about reentrancy - */ -static tsDLList < repeaterClient > client_list; - -static const unsigned short PORT_ANY = 0u; - -/* - * makeSocket() - */ -static int makeSocket ( unsigned short port, bool reuseAddr, SOCKET * pSock ) -{ - SOCKET sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, 0 ); - - if ( sock == INVALID_SOCKET ) { - *pSock = sock; - return SOCKERRNO; - } - - /* - * no need to bind if unconstrained - */ - if ( port != PORT_ANY ) { - int status; - union { - struct sockaddr_in ia; - struct sockaddr sa; - } bd; - - memset ( (char *) &bd, 0, sizeof (bd) ); - bd.ia.sin_family = AF_INET; - bd.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); - bd.ia.sin_port = htons ( port ); - status = bind ( sock, &bd.sa, (int) sizeof(bd) ); - if ( status < 0 ) { - status = SOCKERRNO; - epicsSocketDestroy ( sock ); - return status; - } - if ( reuseAddr ) { - epicsSocketEnableAddressReuseDuringTimeWaitState ( sock ); - } - } - *pSock = sock; - return 0; -} - -repeaterClient::repeaterClient ( const osiSockAddr &fromIn ) : - from ( fromIn ), sock ( INVALID_SOCKET ) -{ -#ifdef DEBUG - unsigned port = ntohs ( from.ia.sin_port ); - debugPrintf ( ( "new client %u\n", port ) ); -#endif -} - -bool repeaterClient::connect () -{ - int status; - - if ( int sockerrno = makeSocket ( PORT_ANY, false, & this->sock ) ) { - char sockErrBuf[64]; - epicsSocketConvertErrorToString ( - sockErrBuf, sizeof ( sockErrBuf ), sockerrno ); - fprintf ( stderr, "%s: no client sock because \"%s\"\n", - __FILE__, sockErrBuf ); - return false; - } - - status = ::connect ( this->sock, &this->from.sa, sizeof ( this->from.sa ) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf ( stderr, "%s: unable to connect client sock because \"%s\"\n", - __FILE__, sockErrBuf ); - return false; - } - - return true; -} - -bool repeaterClient::sendConfirm () -{ - int status; - - caHdr confirm; - memset ( (char *) &confirm, '\0', sizeof (confirm) ); - AlignedWireRef < epicsUInt16 > ( confirm.m_cmmd ) = REPEATER_CONFIRM; - confirm.m_available = this->from.ia.sin_addr.s_addr; - status = send ( this->sock, (char *) &confirm, - sizeof (confirm), 0 ); - if ( status >= 0 ) { - assert ( status == sizeof ( confirm ) ); - return true; - } - else if ( SOCKERRNO == SOCK_ECONNREFUSED ) { - return false; - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - debugPrintf ( ( "CA Repeater: confirm req err was \"%s\"\n", sockErrBuf) ); - return false; - } -} - -bool repeaterClient::sendMessage ( const void *pBuf, unsigned bufSize ) -{ - int status; - - status = send ( this->sock, (char *) pBuf, bufSize, 0 ); - if ( status >= 0 ) { - assert ( static_cast ( status ) == bufSize ); -#ifdef DEBUG - epicsUInt16 port = ntohs ( this->from.ia.sin_port ); - debugPrintf ( ("Sent to %u\n", port ) ); -#endif - return true; - } - else { - int errnoCpy = SOCKERRNO; - if ( errnoCpy == SOCK_ECONNREFUSED ) { -#ifdef DEBUG - epicsUInt16 port = ntohs ( this->from.ia.sin_port ); - debugPrintf ( ("Client refused message %u\n", port ) ); -#endif - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - debugPrintf ( ( "CA Repeater: UDP send err was \"%s\"\n", sockErrBuf) ); - } - return false; - } -} - -repeaterClient::~repeaterClient () -{ - if ( this->sock != INVALID_SOCKET ) { - epicsSocketDestroy ( this->sock ); - } -#ifdef DEBUG - epicsUInt16 port = ntohs ( this->from.ia.sin_port ); - debugPrintf ( ( "Deleted client %u\n", port ) ); -#endif -} - -void repeaterClient::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void * repeaterClient::operator new ( size_t size, - tsFreeList < repeaterClient, 0x20 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -void repeaterClient::operator delete ( void *pCadaver, - tsFreeList < repeaterClient, 0x20 > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline unsigned short repeaterClient::port () const -{ - return ntohs ( this->from.ia.sin_port ); -} - -inline bool repeaterClient::identicalAddress ( const osiSockAddr &fromIn ) -{ - if ( fromIn.sa.sa_family == this->from.sa.sa_family ) { - if ( fromIn.ia.sin_port == this->from.ia.sin_port) { - if ( fromIn.ia.sin_addr.s_addr == this->from.ia.sin_addr.s_addr ) { - return true; - } - } - } - return false; -} - -inline bool repeaterClient::identicalPort ( const osiSockAddr &fromIn ) -{ - if ( fromIn.sa.sa_family == this->from.sa.sa_family ) { - if ( fromIn.ia.sin_port == this->from.ia.sin_port) { - return true; - } - } - return false; -} - -bool repeaterClient::verify () -{ - SOCKET tmpSock; - int sockerrno = makeSocket ( this->port (), false, & tmpSock ); - - if ( sockerrno == SOCK_EADDRINUSE ) { - // Normal result, client using port - return true; - } - - if ( sockerrno == 0 ) { - // Client went away, released port - epicsSocketDestroy ( tmpSock ); - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrorToString ( - sockErrBuf, sizeof ( sockErrBuf ), sockerrno ); - fprintf ( stderr, "CA Repeater: Bind test error \"%s\"\n", - sockErrBuf ); - } - return false; -} - - -/* - * verifyClients() - */ -static void verifyClients ( tsFreeList < repeaterClient, 0x20 > & freeList ) -{ - static tsDLList < repeaterClient > theClients; - repeaterClient *pclient; - - while ( ( pclient = client_list.get () ) ) { - if ( pclient->verify () ) { - theClients.add ( *pclient ); - } - else { - pclient->~repeaterClient (); - freeList.release ( pclient ); - } - } - client_list.add ( theClients ); -} - -/* - * fanOut() - */ -static void fanOut ( const osiSockAddr & from, const void * pMsg, - unsigned msgSize, tsFreeList < repeaterClient, 0x20 > & freeList ) -{ - static tsDLList < repeaterClient > theClients; - repeaterClient *pclient; - - while ( ( pclient = client_list.get () ) ) { - theClients.add ( *pclient ); - /* Dont reflect back to sender */ - if ( pclient->identicalAddress ( from ) ) { - continue; - } - - if ( ! pclient->sendMessage ( pMsg, msgSize ) ) { - if ( ! pclient->verify () ) { - theClients.remove ( *pclient ); - pclient->~repeaterClient (); - freeList.release ( pclient ); - } - } - } - - client_list.add ( theClients ); -} - -/* - * register_new_client() - */ -static void register_new_client ( osiSockAddr & from, - tsFreeList < repeaterClient, 0x20 > & freeList ) -{ - bool newClient = false; - int status; - - if ( from.sa.sa_family != AF_INET ) { - return; - } - - /* - * the repeater and its clients must be on the same host - */ - if ( INADDR_LOOPBACK != ntohl ( from.ia.sin_addr.s_addr ) ) { - static SOCKET testSock = INVALID_SOCKET; - static bool init = false; - - if ( ! init ) { - SOCKET sock; - if ( int sockerrno = makeSocket ( PORT_ANY, true, & sock ) ) { - char sockErrBuf[64]; - epicsSocketConvertErrorToString ( - sockErrBuf, sizeof ( sockErrBuf ), sockerrno ); - fprintf ( stderr, "%s: Unable to create repeater bind test socket because \"%s\"\n", - __FILE__, sockErrBuf ); - } - else { - testSock = sock; - } - init = true; - } - - /* - * Unfortunately on 3.13 beta 11 and before the - * repeater would not always allow the loopback address - * as a local client address so current clients alternate - * between the address of the first non-loopback interface - * found and the loopback addresss when subscribing with - * the CA repeater until all CA repeaters have been updated - * to current code. - */ - if ( testSock != INVALID_SOCKET ) { - osiSockAddr addr; - - addr = from; - addr.ia.sin_port = PORT_ANY; - - /* we can only bind to a local address */ - status = bind ( testSock, &addr.sa, sizeof ( addr ) ); - if ( status ) { - return; - } - } - else { - return; - } - } - - tsDLIter < repeaterClient > pclient = client_list.firstIter (); - while ( pclient.valid () ) { - if ( pclient->identicalPort ( from ) ) { - break; - } - pclient++; - } - - repeaterClient *pNewClient; - if ( pclient.valid () ) { - pNewClient = pclient.pointer (); - } - else { - pNewClient = new ( freeList ) repeaterClient ( from ); - if ( ! pNewClient ) { - fprintf ( stderr, "%s: no memory for new client\n", __FILE__ ); - return; - } - if ( ! pNewClient->connect () ) { - pNewClient->~repeaterClient (); - freeList.release ( pNewClient ); - return; - } - client_list.add ( *pNewClient ); - newClient = true; - } - - if ( ! pNewClient->sendConfirm () ) { - client_list.remove ( *pNewClient ); - pNewClient->~repeaterClient (); - freeList.release ( pNewClient ); -# ifdef DEBUG - epicsUInt16 port = ntohs ( from.ia.sin_port ); - debugPrintf ( ( "Deleted repeater client=%u (error while sending ack)\n", - port ) ); -# endif - } - - /* - * send a noop message to all other clients so that we dont - * accumulate sockets when there are no beacons - */ - caHdr noop; - memset ( (char *) &noop, '\0', sizeof ( noop ) ); - AlignedWireRef < epicsUInt16 > ( noop.m_cmmd ) = CA_PROTO_VERSION; - fanOut ( from, &noop, sizeof ( noop ), freeList ); - - if ( newClient ) { - /* - * For HPUX and Solaris we need to verify that the clients - * have not gone away - because an ICMP error return does not - * get through to send(), which returns no error code. - * - * This is done each time that a new client is created. - * See also the note in the file header. - * - * This is done here in order to avoid deleting a client - * prior to sending its confirm message. - */ - verifyClients ( freeList ); - } -} - - -/* - * ca_repeater () - */ -void ca_repeater () -{ - tsFreeList < repeaterClient, 0x20 > freeList; - int size; - SOCKET sock; - osiSockAddr from; - unsigned short port; - char * pBuf; - - pBuf = new char [MAX_UDP_RECV]; - - { - bool success = osiSockAttach(); - assert ( success ); - } - - port = envGetInetPortConfigParam ( & EPICS_CA_REPEATER_PORT, - static_cast (CA_REPEATER_PORT) ); - if ( int sockerrno = makeSocket ( port, true, & sock ) ) { - /* - * test for server was already started - */ - if ( sockerrno == SOCK_EADDRINUSE ) { - osiSockRelease (); - debugPrintf ( ( "CA Repeater: exiting because a repeater is already running\n" ) ); - delete [] pBuf; - return; - } - char sockErrBuf[64]; - epicsSocketConvertErrorToString ( - sockErrBuf, sizeof ( sockErrBuf ), sockerrno ); - fprintf ( stderr, "%s: Unable to create repeater socket because \"%s\" - fatal\n", - __FILE__, sockErrBuf ); - osiSockRelease (); - delete [] pBuf; - return; - } - - debugPrintf ( ( "CA Repeater: Attached and initialized\n" ) ); - - while ( true ) { - osiSocklen_t from_size = sizeof ( from ); - size = recvfrom ( sock, pBuf, MAX_UDP_RECV, 0, - &from.sa, &from_size ); - if ( size < 0 ) { - int errnoCpy = SOCKERRNO; - // Avoid spurious ECONNREFUSED bug in linux - if ( errnoCpy == SOCK_ECONNREFUSED ) { - continue; - } - // Avoid ECONNRESET from connected socket in windows - if ( errnoCpy == SOCK_ECONNRESET ) { - continue; - } - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf ( stderr, "CA Repeater: unexpected UDP recv err: %s\n", - sockErrBuf ); - continue; - } - - caHdr * pMsg = ( caHdr * ) pBuf; - - /* - * both zero length message and a registration message - * will register a new client - */ - if ( ( (size_t) size) >= sizeof (*pMsg) ) { - if ( AlignedWireRef < epicsUInt16 > ( pMsg->m_cmmd ) == REPEATER_REGISTER ) { - register_new_client ( from, freeList ); - - /* - * strip register client message - */ - pMsg++; - size -= sizeof ( *pMsg ); - if ( size==0 ) { - continue; - } - } - else if ( AlignedWireRef < epicsUInt16 > ( pMsg->m_cmmd ) == CA_PROTO_RSRV_IS_UP ) { - if ( pMsg->m_available == 0u ) { - pMsg->m_available = from.ia.sin_addr.s_addr; - } - } - } - else if ( size == 0 ) { - register_new_client ( from, freeList ); - continue; - } - - fanOut ( from, pMsg, size, freeList ); - } -} - -/* - * caRepeaterThread () - */ -extern "C" void caRepeaterThread ( void * /* pDummy */ ) -{ - taskwdInsert ( epicsThreadGetIdSelf(), NULL, NULL ); - ca_repeater (); -} - - diff --git a/src/ca/client/repeaterClient.h b/src/ca/client/repeaterClient.h deleted file mode 100644 index faaf0809f..000000000 --- a/src/ca/client/repeaterClient.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef repeaterClienth -#define repeaterClienth - -#ifdef epicsExportSharedSymbols -# define repeaterClienth_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "tsDLList.h" -#include "tsFreeList.h" -#include "compilerDependencies.h" - -#ifdef repeaterClienth_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -union osiSockAddr; - -/* - * one socket per client so we will get the ECONNREFUSED - * error code (and then delete the client) - */ -class repeaterClient : public tsDLNode < repeaterClient > { -public: - repeaterClient ( const osiSockAddr & from ); - ~repeaterClient (); - bool connect (); - bool sendConfirm (); - bool sendMessage ( const void *pBuf, unsigned bufSize ); - bool verify (); - bool identicalAddress ( const osiSockAddr &from ); - bool identicalPort ( const osiSockAddr &from ); - void * operator new ( size_t size, - tsFreeList < repeaterClient, 0x20 > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < repeaterClient, 0x20 > & )) -private: - osiSockAddr from; - SOCKET sock; - unsigned short port () const; - void operator delete ( void * ); -}; - -#endif // repeaterClienth - - diff --git a/src/ca/client/repeaterSubscribeTimer.cpp b/src/ca/client/repeaterSubscribeTimer.cpp deleted file mode 100644 index 948ccebd5..000000000 --- a/src/ca/client/repeaterSubscribeTimer.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - * - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "cac.h" -#include "iocinf.h" -#include "repeaterSubscribeTimer.h" - -#define epicsExportSharedSymbols -#include "udpiiu.h" -#undef epicsExportSharedSymbols - -static const double repeaterSubscribeTimerInitialPeriod = 10.0; // sec -static const double repeaterSubscribeTimerPeriod = 1.0; // sec - -repeaterSubscribeTimer::repeaterSubscribeTimer ( - repeaterTimerNotify & iiuIn, epicsTimerQueue & queueIn, - epicsMutex & cbMutexIn, cacContextNotify & ctxNotifyIn ) : - timer ( queueIn.createTimer () ), iiu ( iiuIn ), - cbMutex ( cbMutexIn ),ctxNotify ( ctxNotifyIn ), - attempts ( 0 ), registered ( false ), once ( false ) -{ -} - -repeaterSubscribeTimer::~repeaterSubscribeTimer () -{ - this->timer.destroy (); -} - -void repeaterSubscribeTimer::start () -{ - this->timer.start ( - *this, repeaterSubscribeTimerInitialPeriod ); -} - -void repeaterSubscribeTimer::shutdown ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - epicsGuardRelease < epicsMutex > unguard ( guard ); - { - epicsGuardRelease < epicsMutex > cbUnguard ( cbGuard ); - this->timer.cancel (); - } -} - -epicsTimerNotify::expireStatus repeaterSubscribeTimer:: - expire ( const epicsTime & /* currentTime */ ) -{ - epicsGuard < epicsMutex > guard ( this->stateMutex ); - - static const unsigned nTriesToMsg = 50; - if ( this->attempts > nTriesToMsg && ! this->once ) { - callbackManager mgr ( this->ctxNotify, this->cbMutex ); - this->iiu.printFormated ( mgr.cbGuard, - "CA client library is unable to contact CA repeater after %u tries.\n", - nTriesToMsg ); - this->iiu.printFormated ( mgr.cbGuard, - "Silence this message by starting a CA repeater daemon\n") ; - this->iiu.printFormated ( mgr.cbGuard, - "or by calling ca_pend_event() and or ca_poll() more often.\n" ); - this->once = true; - } - - this->iiu.repeaterRegistrationMessage ( this->attempts ); - this->attempts++; - - if ( this->registered ) { - return noRestart; - } - else { - return expireStatus ( restart, repeaterSubscribeTimerPeriod ); - } -} - -void repeaterSubscribeTimer::show ( unsigned /* level */ ) const -{ - epicsGuard < epicsMutex > guard ( this->stateMutex ); - - ::printf ( "repeater subscribe timer: attempts=%u registered=%u once=%u\n", - this->attempts, this->registered, this->once ); -} - -void repeaterSubscribeTimer::confirmNotify () -{ - epicsGuard < epicsMutex > guard ( this->stateMutex ); - this->registered = true; -} - -repeaterTimerNotify::~repeaterTimerNotify () {} diff --git a/src/ca/client/repeaterSubscribeTimer.h b/src/ca/client/repeaterSubscribeTimer.h deleted file mode 100644 index fa4768499..000000000 --- a/src/ca/client/repeaterSubscribeTimer.h +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef repeaterSubscribeTimerh -#define repeaterSubscribeTimerh - -#include "epicsTimer.h" - -#ifdef epicsExportSharedSymbols -# define repeaterSubscribeTimerh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsTimer.h" - -#ifdef repeaterSubscribeTimerh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class epicsMutex; -class cacContextNotify; - -class repeaterTimerNotify { -public: - virtual ~repeaterTimerNotify () = 0; - virtual void repeaterRegistrationMessage ( - unsigned attemptNumber ) = 0; - virtual int printFormated ( - epicsGuard < epicsMutex > & callbackControl, - const char * pformat, ... ) = 0; -}; - -class repeaterSubscribeTimer : private epicsTimerNotify { -public: - repeaterSubscribeTimer ( - repeaterTimerNotify &, epicsTimerQueue &, - epicsMutex & cbMutex, cacContextNotify & ctxNotify ); - virtual ~repeaterSubscribeTimer (); - void start (); - void shutdown ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void confirmNotify (); - void show ( unsigned level ) const; -private: - epicsTimer & timer; - repeaterTimerNotify & iiu; - epicsMutex & cbMutex; - cacContextNotify & ctxNotify; - mutable epicsMutex stateMutex; - unsigned attempts; - bool registered; - bool once; - expireStatus expire ( const epicsTime & currentTime ); - repeaterSubscribeTimer ( const repeaterSubscribeTimer & ); - repeaterSubscribeTimer & operator = ( const repeaterSubscribeTimer & ); -}; - -#endif // ifdef repeaterSubscribeTimerh diff --git a/src/ca/client/searchTimer.cpp b/src/ca/client/searchTimer.cpp deleted file mode 100644 index e55e49eab..000000000 --- a/src/ca/client/searchTimer.cpp +++ /dev/null @@ -1,399 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// -// L O S A L A M O S -// Los Alamos National Laboratory -// Los Alamos, New Mexico 87545 -// -// Copyright, 1986, The Regents of the University of California. -// -// Author: Jeff Hill -// - -#include -#include // vxWorks 6.0 requires this include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "envDefs.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "udpiiu.h" -#include "nciu.h" - -static const unsigned initialTriesPerFrame = 1u; // initial UDP frames per search try -static const unsigned maxTriesPerFrame = 64u; // max UDP frames per search try - -// -// searchTimer::searchTimer () -// -searchTimer::searchTimer ( - searchTimerNotify & iiuIn, - epicsTimerQueue & queueIn, - const unsigned indexIn, - epicsMutex & mutexIn, - bool boostPossibleIn ) : - timeAtLastSend ( epicsTime::getCurrent () ), - timer ( queueIn.createTimer () ), - iiu ( iiuIn ), - mutex ( mutexIn ), - framesPerTry ( initialTriesPerFrame ), - framesPerTryCongestThresh ( DBL_MAX ), - retry ( 0 ), - searchAttempts ( 0u ), - searchResponses ( 0u ), - index ( indexIn ), - dgSeqNoAtTimerExpireBegin ( 0u ), - dgSeqNoAtTimerExpireEnd ( 0u ), - boostPossible ( boostPossibleIn ), - stopped ( false ) -{ -} - -void searchTimer::start ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->timer.start ( *this, this->period ( guard ) ); -} - -searchTimer::~searchTimer () -{ - assert ( this->chanListReqPending.count() == 0 ); - assert ( this->chanListRespPending.count() == 0 ); - this->timer.destroy (); -} - -void searchTimer::shutdown ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - this->stopped = true; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - { - epicsGuardRelease < epicsMutex > cbUnguard ( cbGuard ); - this->timer.cancel (); - } - } - - while ( nciu * pChan = this->chanListReqPending.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - pChan->serviceShutdownNotify ( cbGuard, guard ); - } - while ( nciu * pChan = this->chanListRespPending.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - pChan->serviceShutdownNotify ( cbGuard, guard ); - } -} - -void searchTimer::installChannel ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - this->chanListReqPending.add ( chan ); - chan.channelNode::setReqPendingState ( guard, this->index ); -} - -void searchTimer::moveChannels ( - epicsGuard < epicsMutex > & guard, searchTimer & dest ) -{ - while ( nciu * pChan = this->chanListRespPending.get () ) { - if ( this->searchAttempts > 0 ) { - this->searchAttempts--; - } - dest.installChannel ( guard, *pChan ); - } - while ( nciu * pChan = this->chanListReqPending.get () ) { - dest.installChannel ( guard, *pChan ); - } -} - -// -// searchTimer::expire () -// -epicsTimerNotify::expireStatus searchTimer::expire ( - const epicsTime & currentTime ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - while ( nciu * pChan = this->chanListRespPending.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - this->iiu.noSearchRespNotify ( - guard, *pChan, this->index ); - } - - this->timeAtLastSend = currentTime; - - // boost search period for channels not recently - // searched for if there was some success - if ( this->searchResponses && this->boostPossible ) { - while ( nciu * pChan = this->chanListReqPending.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - this->iiu.boostChannel ( guard, *pChan ); - } - } - - if ( this->searchAttempts ) { -#if 0 - // - // dynamically adjust the number of UDP frames per - // try depending how many search requests are not - // replied to - // - // The variable this->framesPerTry - // determines the number of UDP frames to be sent - // each time that expire() is called. - // If this value is too high we will waste some - // network bandwidth. If it is too low we will - // use very little of the incoming UDP message - // buffer associated with the server's port and - // will therefore take longer to connect. We - // initialize this->framesPerTry to a prime number - // so that it is less likely that the - // same channel is in the last UDP frame - // sent every time that this is called (and - // potentially discarded by a CA server with - // a small UDP input queue). - // - // increase frames per try only if we see better than - // a 93.75% success rate for one pass through the list - // - if ( this->searchResponses > - ( this->searchAttempts - (this->searchAttempts/16u) ) ) { - // increase UDP frames per try if we have a good score - if ( this->framesPerTry < maxTriesPerFrame ) { - // a congestion avoidance threshold similar to TCP is now used - if ( this->framesPerTry < this->framesPerTryCongestThresh ) { - this->framesPerTry += this->framesPerTry; - } - else { - this->framesPerTry += (this->framesPerTry/8) + 1; - } - debugPrintf ( ("Increasing frame count to %u t=%u r=%u\n", - this->framesPerTry, this->searchAttempts, this->searchResponses) ); - } - } - // if we detect congestion because we have less than a 87.5% success - // rate then gradually reduce the frames per try - else if ( this->searchResponses < - ( this->searchAttempts - (this->searchAttempts/8u) ) ) { - if ( this->framesPerTry > 1 ) { - this->framesPerTry--; - } - this->framesPerTryCongestThresh = this->framesPerTry/2 + 1; - debugPrintf ( ("Congestion detected - set frames per try to %f t=%u r=%u\n", - this->framesPerTry, this->searchAttempts, this->searchResponses) ); - } -#else - if ( this->searchResponses == this->searchAttempts ) { - // increase UDP frames per try if we have a good score - if ( this->framesPerTry < maxTriesPerFrame ) { - // a congestion avoidance threshold similar to TCP is now used - if ( this->framesPerTry < this->framesPerTryCongestThresh ) { - double doubled = 2 * this->framesPerTry; - if ( doubled > this->framesPerTryCongestThresh ) { - this->framesPerTry = this->framesPerTryCongestThresh; - } - else { - this->framesPerTry = doubled; - } - } - else { - this->framesPerTry += 1.0 / this->framesPerTry; - } - debugPrintf ( ("Increasing frame count to %g t=%u r=%u\n", - this->framesPerTry, this->searchAttempts, this->searchResponses) ); - } - } - else { - this->framesPerTryCongestThresh = this->framesPerTry / 2.0; - this->framesPerTry = 1u; - debugPrintf ( ("Congestion detected - set frames per try to %g t=%u r=%u\n", - this->framesPerTry, this->searchAttempts, this->searchResponses) ); - } -#endif - } - - this->dgSeqNoAtTimerExpireBegin = - this->iiu.datagramSeqNumber ( guard ); - - this->searchAttempts = 0; - this->searchResponses = 0; - - unsigned nFrameSent = 0u; - while ( true ) { - nciu * pChan = this->chanListReqPending.get (); - if ( ! pChan ) { - break; - } - - pChan->channelNode::listMember = - channelNode::cs_none; - - bool success = pChan->searchMsg ( guard ); - if ( ! success ) { - if ( this->iiu.datagramFlush ( guard, currentTime ) ) { - nFrameSent++; - if ( nFrameSent < this->framesPerTry ) { - success = pChan->searchMsg ( guard ); - } - } - if ( ! success ) { - this->chanListReqPending.push ( *pChan ); - pChan->channelNode::setReqPendingState ( - guard, this->index ); - break; - } - } - - this->chanListRespPending.add ( *pChan ); - pChan->channelNode::setRespPendingState ( - guard, this->index ); - - if ( this->searchAttempts < UINT_MAX ) { - this->searchAttempts++; - } - } - - // flush out the search request buffer - if ( this->iiu.datagramFlush ( guard, currentTime ) ) { - nFrameSent++; - } - - this->dgSeqNoAtTimerExpireEnd = - this->iiu.datagramSeqNumber ( guard ) - 1u; - -# ifdef DEBUG - if ( this->searchAttempts ) { - char buf[64]; - currentTime.strftime ( buf, sizeof(buf), "%M:%S.%09f"); - debugPrintf ( ("sent %u delay sec=%f Rts=%s\n", - nFrameSent, this->period(), buf ) ); - } -# endif - - return expireStatus ( restart, this->period ( guard ) ); -} - -void searchTimer :: show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - ::printf ( "searchTimer with period %f\n", this->period ( guard ) ); - if ( level > 0 ) { - ::printf ( "channels with search request pending = %u\n", - this->chanListReqPending.count () ); - if ( level > 1u ) { - tsDLIterConst < nciu > pChan = - this->chanListReqPending.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 2u ); - pChan++; - } - } - ::printf ( "channels with search response pending = %u\n", - this->chanListRespPending.count () ); - if ( level > 1u ) { - tsDLIterConst < nciu > pChan = - this->chanListRespPending.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 2u ); - pChan++; - } - } - } -} - -// -// Reset the delay to the next search request if we get -// at least one response. However, dont reset this delay if we -// get a delayed response to an old search request. -// -void searchTimer::uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > & guard, nciu & chan, - ca_uint32_t respDatagramSeqNo, bool seqNumberIsValid, - const epicsTime & currentTime ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->uninstallChan ( guard, chan ); - - if ( this->stopped ) { - return; - } - - bool validResponse = true; - if ( seqNumberIsValid ) { - validResponse = - this->dgSeqNoAtTimerExpireBegin <= respDatagramSeqNo && - this->dgSeqNoAtTimerExpireEnd >= respDatagramSeqNo; - } - - // if we receive a successful response then reset to a - // reasonable timer period - if ( validResponse ) { - double measured = currentTime - this->timeAtLastSend; - this->iiu.updateRTTE ( guard, measured ); - - if ( this->searchResponses < UINT_MAX ) { - this->searchResponses++; - if ( this->searchResponses == this->searchAttempts ) { - if ( this->chanListReqPending.count () ) { - // - // when we get 100% success immediately - // send another search request - // - debugPrintf ( ( "All requests succesful, set timer delay to zero\n" ) ); - this->timer.start ( *this, currentTime ); - } - } - } - } -} - -void searchTimer::uninstallChan ( - epicsGuard < epicsMutex > & cacGuard, nciu & chan ) -{ - cacGuard.assertIdenticalMutex ( this->mutex ); - unsigned ulistmem = - static_cast ( chan.channelNode::listMember ); - unsigned uReqBase = - static_cast ( channelNode::cs_searchReqPending0 ); - if ( ulistmem == this->index + uReqBase ) { - this->chanListReqPending.remove ( chan ); - } - else { - unsigned uRespBase = - static_cast ( - channelNode::cs_searchRespPending0 ); - if ( ulistmem == this->index + uRespBase ) { - this->chanListRespPending.remove ( chan ); - } - else { - throw std::runtime_error ( - "uninstalling channel search timer, but channel " - "state is wrong" ); - } - } - chan.channelNode::listMember = channelNode::cs_none; -} - -double searchTimer::period ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - return (1 << this->index ) * this->iiu.getRTTE ( guard ); -} - -searchTimerNotify::~searchTimerNotify () {} diff --git a/src/ca/client/searchTimer.h b/src/ca/client/searchTimer.h deleted file mode 100644 index 7b9fe1717..000000000 --- a/src/ca/client/searchTimer.h +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// -// -// L O S A L A M O S -// Los Alamos National Laboratory -// Los Alamos, New Mexico 87545 -// -// Copyright, 1986, The Regents of the University of California. -// -// -// Author Jeffrey O. Hill -// johill@lanl.gov -// 505 665 1831 -// - -#ifndef searchTimerh -#define searchTimerh - -#ifdef epicsExportSharedSymbols -# define searchTimerh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsTimer.h" - -#ifdef searchTimerh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "caProto.h" -#include "netiiu.h" - -class searchTimerNotify { -public: - virtual ~searchTimerNotify () = 0; - virtual void boostChannel ( - epicsGuard < epicsMutex > &, nciu & ) = 0; - virtual void noSearchRespNotify ( - epicsGuard < epicsMutex > &, nciu &, unsigned ) = 0; - virtual double getRTTE ( epicsGuard < epicsMutex > & ) const = 0; - virtual void updateRTTE ( epicsGuard < epicsMutex > &, double rtte ) = 0; - virtual bool datagramFlush ( - epicsGuard < epicsMutex > &, - const epicsTime & currentTime ) = 0; - virtual ca_uint32_t datagramSeqNumber ( - epicsGuard < epicsMutex > & ) const = 0; -}; - -class searchTimer : private epicsTimerNotify { -public: - searchTimer ( - class searchTimerNotify &, epicsTimerQueue &, - const unsigned index, epicsMutex &, - bool boostPossible ); - virtual ~searchTimer (); - void start ( epicsGuard < epicsMutex > & ); - void shutdown ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void moveChannels ( - epicsGuard < epicsMutex > &, searchTimer & dest ); - void installChannel ( - epicsGuard < epicsMutex > &, nciu & ); - void uninstallChan ( - epicsGuard < epicsMutex > &, nciu & ); - void uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > &, nciu &, - ca_uint32_t respDatagramSeqNo, bool seqNumberIsValid, - const epicsTime & currentTime ); - void show ( unsigned level ) const; -private: - tsDLList < nciu > chanListReqPending; - tsDLList < nciu > chanListRespPending; - epicsTime timeAtLastSend; - epicsTimer & timer; - searchTimerNotify & iiu; - epicsMutex & mutex; - double framesPerTry; /* # of UDP frames per search try */ - double framesPerTryCongestThresh; /* one half N tries w congest */ - unsigned retry; - unsigned searchAttempts; /* num search tries after last timer experation */ - unsigned searchResponses; /* num search resp after last timer experation */ - const unsigned index; - ca_uint32_t dgSeqNoAtTimerExpireBegin; - ca_uint32_t dgSeqNoAtTimerExpireEnd; - const bool boostPossible; - bool stopped; - - expireStatus expire ( const epicsTime & currentTime ); - double period ( epicsGuard < epicsMutex > & ) const; - searchTimer ( const searchTimer & ); // not implemented - searchTimer & operator = ( const searchTimer & ); // not implemented -}; - -#endif // ifdef searchTimerh diff --git a/src/ca/client/sgAutoPtr.h b/src/ca/client/sgAutoPtr.h deleted file mode 100644 index e2899468c..000000000 --- a/src/ca/client/sgAutoPtr.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef sgAutoPtrh -#define sgAutoPtrh - -template < class T > -class sgAutoPtr { -public: - sgAutoPtr ( epicsGuard < epicsMutex > &, struct CASG & ); - ~sgAutoPtr (); - sgAutoPtr < T > & operator = ( T * ); - T * operator -> (); - T & operator * (); - T * get (); - T * release (); -private: - T * pNotify; - struct CASG & sg; - epicsGuard < epicsMutex > & guard; - sgAutoPtr & operator = ( const sgAutoPtr & ); -}; - -template < class T > -inline sgAutoPtr < T > :: sgAutoPtr ( - epicsGuard < epicsMutex > & guardIn, struct CASG & sgIn ) : - pNotify ( 0 ), sg ( sgIn ), guard ( guardIn ) -{ -} - -template < class T > -inline sgAutoPtr < T > :: ~sgAutoPtr () -{ - if ( this->pNotify ) { - this->sg.ioPendingList.remove ( *this->pNotify ); - this->sg.client. - whenThereIsAnExceptionDestroySyncGroupIO ( this->guard, *this->pNotify ); - } -} - -template < class T > -inline sgAutoPtr < T > & sgAutoPtr < T > :: operator = ( T * pNotifyIn ) -{ - if ( this->pNotify ) { - this->sg.ioPendingList.remove ( *this->pNotify ); - this->sg.client. - whenThereIsAnExceptionDestroySyncGroupIO ( this->guard, *this->pNotify ); - } - this->pNotify = pNotifyIn; - this->sg.ioPendingList.add ( *this->pNotify ); - return *this; -} - -template < class T > -inline T * sgAutoPtr < T > :: operator -> () -{ - return this->pNotify; -} - -template < class T > -inline T & sgAutoPtr < T > :: operator * () -{ - assert ( this->pNotify ); - return * this->pNotify; -} - -template < class T > -inline T * sgAutoPtr < T > :: release () -{ - T * pTmp = this->pNotify; - this->pNotify = 0; - return pTmp; -} - -template < class T > -inline T * sgAutoPtr < T > :: get () -{ - return this->pNotify; -} - -#endif // sgAutoPtrh diff --git a/src/ca/client/syncGroup.h b/src/ca/client/syncGroup.h deleted file mode 100644 index 3b9c3cd4f..000000000 --- a/src/ca/client/syncGroup.h +++ /dev/null @@ -1,280 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef syncGrouph -#define syncGrouph - -#ifdef epicsExportSharedSymbols -# define syncGrouph_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "tsDLList.h" -#include "tsFreeList.h" -#include "resourceLib.h" -#include "epicsEvent.h" -#include "compilerDependencies.h" - -#ifdef syncGrouph_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "cadef.h" -#include "cacIO.h" - -static const unsigned CASG_MAGIC = 0xFAB4CAFE; - -class syncGroupNotify : public tsDLNode < syncGroupNotify > { -public: - syncGroupNotify (); - virtual void destroy ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) = 0; - virtual bool ioPending ( - epicsGuard < epicsMutex > & guard ) = 0; - virtual void cancel ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0; - virtual void show ( - epicsGuard < epicsMutex > &, - unsigned level ) const = 0; -protected: - virtual ~syncGroupNotify (); - syncGroupNotify ( const syncGroupNotify & ); - syncGroupNotify & operator = ( const syncGroupNotify & ); -}; - -struct CASG; - -class syncGroupReadNotify : public syncGroupNotify, public cacReadNotify { -public: - typedef void ( CASG :: * PRecycleFunc ) - ( epicsGuard < epicsMutex > &, syncGroupReadNotify & ); - static syncGroupReadNotify * factory ( - tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &, - CASG &, PRecycleFunc, chid, void *pValueIn ); - void destroy ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ); - bool ioPending ( - epicsGuard < epicsMutex > & guard ); - void begin ( epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count ); - void cancel ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ); - void show ( epicsGuard < epicsMutex > &, unsigned level ) const; -protected: - syncGroupReadNotify ( CASG & sgIn, PRecycleFunc, chid, void * pValueIn ); - virtual ~syncGroupReadNotify (); -private: - chid chan; - PRecycleFunc pRecycleFunc; - CASG & sg; - void * pValue; - const unsigned magic; - cacChannel::ioid id; - bool idIsValid; - bool ioComplete; - void operator delete ( void * ); - void * operator new ( size_t, - tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & )) - void completion ( - epicsGuard < epicsMutex > &, unsigned type, - arrayElementCount count, const void * pData ); - void exception ( - epicsGuard < epicsMutex > &, int status, - const char * pContext, unsigned type, arrayElementCount count ); - syncGroupReadNotify ( const syncGroupReadNotify & ); - syncGroupReadNotify & operator = ( const syncGroupReadNotify & ); -}; - -class syncGroupWriteNotify : public syncGroupNotify, public cacWriteNotify { -public: - typedef void ( CASG :: * PRecycleFunc ) - ( epicsGuard < epicsMutex > &, syncGroupWriteNotify & ); - static syncGroupWriteNotify * factory ( - tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &, - CASG &, PRecycleFunc, chid ); - void destroy ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ); - bool ioPending ( - epicsGuard < epicsMutex > & guard ); - void begin ( epicsGuard < epicsMutex > &, unsigned type, - arrayElementCount count, const void * pValueIn ); - void cancel ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ); - void show ( epicsGuard < epicsMutex > &, unsigned level ) const; -protected: - syncGroupWriteNotify ( struct CASG &, PRecycleFunc, chid ); - virtual ~syncGroupWriteNotify (); // allocate only from pool -private: - chid chan; - PRecycleFunc pRecycleFunc; - CASG & sg; - const unsigned magic; - cacChannel::ioid id; - bool idIsValid; - bool ioComplete; - void operator delete ( void * ); - void * operator new ( size_t, - tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & )) - void completion ( epicsGuard < epicsMutex > & ); - void exception ( - epicsGuard < epicsMutex > &, int status, const char *pContext, - unsigned type, arrayElementCount count ); - syncGroupWriteNotify ( const syncGroupWriteNotify & ); - syncGroupWriteNotify & operator = ( const syncGroupWriteNotify & ); -}; - -struct ca_client_context; - -template < class T > class sgAutoPtr; - -struct CASG : public chronIntIdRes < CASG > { -public: - CASG ( epicsGuard < epicsMutex > &, ca_client_context & cacIn ); - void destructor ( - CallbackGuard &, - epicsGuard < epicsMutex > & guard ); - bool ioComplete ( - CallbackGuard &, - epicsGuard < epicsMutex > & guard ); - bool verify ( epicsGuard < epicsMutex > & ) const; - int block ( epicsGuard < epicsMutex > * pcbGuard, - epicsGuard < epicsMutex > & guard, double timeout ); - void reset ( CallbackGuard &, epicsGuard < epicsMutex > & ); - void show ( epicsGuard < epicsMutex > &, unsigned level ) const; - void show ( unsigned level ) const; - void get ( epicsGuard < epicsMutex > &, chid pChan, - unsigned type, arrayElementCount count, void * pValue ); - void put ( epicsGuard < epicsMutex > &, chid pChan, - unsigned type, arrayElementCount count, const void * pValue ); - void completionNotify ( - epicsGuard < epicsMutex > &, syncGroupNotify & ); - int printFormated ( const char * pFormat, ... ); - void exception ( - epicsGuard < epicsMutex > &, int status, const char * pContext, - const char * pFileName, unsigned lineNo ); - void exception ( - epicsGuard < epicsMutex > &, int status, const char * pContext, - const char * pFileName, unsigned lineNo, oldChannelNotify & chan, - unsigned type, arrayElementCount count, unsigned op ); - void * operator new ( size_t size, - tsFreeList < struct CASG, 128, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < struct CASG, 128, epicsMutexNOOP > & )) - -private: - tsDLList < syncGroupNotify > ioPendingList; - tsDLList < syncGroupNotify > ioCompletedList; - epicsEvent sem; - ca_client_context & client; - unsigned magic; - tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > freeListReadOP; - tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > freeListWriteOP; - - void destroyPendingIO ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ); - void destroyCompletedIO ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ); - void recycleReadNotifyIO ( epicsGuard < epicsMutex > &, - syncGroupReadNotify & ); - void recycleWriteNotifyIO ( epicsGuard < epicsMutex > &, - syncGroupWriteNotify & ); - - CASG ( const CASG & ); - CASG & operator = ( const CASG & ); - - void operator delete ( void * ); - - ~CASG (); - - friend class sgAutoPtr < syncGroupWriteNotify >; - friend class sgAutoPtr < syncGroupReadNotify >; -}; - -class boolFlagManager { -public: - boolFlagManager ( bool & flag ); - ~boolFlagManager (); - void release (); -private: - bool * pBool; -}; - -inline boolFlagManager::boolFlagManager ( bool & flagIn ) : - pBool ( & flagIn ) -{ - *this->pBool = true; -} - -inline boolFlagManager::~boolFlagManager () -{ - if ( this->pBool ) { - *this->pBool = false; - } -} - -inline void boolFlagManager::release () -{ - this->pBool = 0; -} - -inline void * CASG::operator new ( size_t size, - tsFreeList < struct CASG, 128, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#if defined ( CXX_PLACEMENT_DELETE ) -inline void CASG::operator delete ( void * pCadaver, - tsFreeList < struct CASG, 128, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline bool syncGroupWriteNotify::ioPending ( - epicsGuard < epicsMutex > & /* guard */ ) -{ - return ! this->ioComplete; -} - -inline bool syncGroupReadNotify::ioPending ( - epicsGuard < epicsMutex > & /* guard */ ) -{ - return ! this->ioComplete; -} - -#endif // ifdef syncGrouph diff --git a/src/ca/client/syncGroupNotify.cpp b/src/ca/client/syncGroupNotify.cpp deleted file mode 100644 index 2780fbe89..000000000 --- a/src/ca/client/syncGroupNotify.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "syncGroup.h" -#include "oldAccess.h" - -syncGroupNotify::syncGroupNotify () -{ -} - -syncGroupNotify::~syncGroupNotify () -{ -} - - - - diff --git a/src/ca/client/syncGroupReadNotify.cpp b/src/ca/client/syncGroupReadNotify.cpp deleted file mode 100644 index 711a2fae4..000000000 --- a/src/ca/client/syncGroupReadNotify.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - */ - -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "syncGroup.h" -#include "oldAccess.h" - -syncGroupReadNotify::syncGroupReadNotify ( - CASG & sgIn, PRecycleFunc pRecycleFuncIn, - chid pChan, void * pValueIn ) : - chan ( pChan ), pRecycleFunc ( pRecycleFuncIn ), - sg ( sgIn ), pValue ( pValueIn ), - magic ( CASG_MAGIC ), id ( 0u ), - idIsValid ( false ), ioComplete ( false ) -{ -} - -void syncGroupReadNotify::begin ( - epicsGuard < epicsMutex > & guard, - unsigned type, arrayElementCount count ) -{ - this->chan->eliminateExcessiveSendBacklog ( guard ); - this->ioComplete = false; - boolFlagManager mgr ( this->idIsValid ); - this->chan->read ( guard, type, count, *this, &this->id ); - mgr.release (); -} - -void syncGroupReadNotify::cancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExcusionGuard ) -{ - if ( this->idIsValid ) { - this->chan->ioCancel ( callbackGuard, mutualExcusionGuard, this->id ); - this->idIsValid = false; - } -} - -syncGroupReadNotify * syncGroupReadNotify::factory ( - tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & freeList, - struct CASG & sg, PRecycleFunc pRecycleFunc, chid chan, void * pValueIn ) -{ - return new ( freeList ) - syncGroupReadNotify ( sg, pRecycleFunc, chan, pValueIn ); -} - -void syncGroupReadNotify::destroy ( - CallbackGuard &, - epicsGuard < epicsMutex > & guard ) -{ - CASG & sgRef ( this->sg ); - this->~syncGroupReadNotify (); - ( sgRef.*pRecycleFunc ) ( guard, *this ); -} - -syncGroupReadNotify::~syncGroupReadNotify () -{ - assert ( ! this->idIsValid ); -} - -void syncGroupReadNotify::completion ( - epicsGuard < epicsMutex > & guard, unsigned type, - arrayElementCount count, const void * pData ) -{ - if ( this->magic != CASG_MAGIC ) { - this->sg.printFormated ( - "cac: sync group io_complete(): bad sync grp op magic number?\n" ); - return; - } - - if ( this->pValue ) { - size_t size = dbr_size_n ( type, count ); - memcpy ( this->pValue, pData, size ); - } - this->sg.completionNotify ( guard, *this ); - this->idIsValid = false; - this->ioComplete = true; -} - -void syncGroupReadNotify::exception ( - epicsGuard < epicsMutex > & guard, int status, const char * pContext, - unsigned type, arrayElementCount count ) -{ - if ( this->magic != CASG_MAGIC ) { - this->sg.printFormated ( - "cac: sync group io_complete(): bad sync grp op magic number?\n" ); - return; - } - this->idIsValid = false; - this->sg.exception ( guard, status, pContext, - __FILE__, __LINE__, *this->chan, type, count, CA_OP_GET ); - // - // This notify is left installed at this point as a place holder indicating that - // all requests have not been completed. This notify is not uninstalled until - // CASG::block() times out or unit they call CASG::reset(). - // -} - -void syncGroupReadNotify::show ( - epicsGuard < epicsMutex > &, unsigned level ) const -{ - ::printf ( "pending sg read op: pVal=%p\n", this->pValue ); - if ( level > 0u ) { - ::printf ( "pending sg op: magic=%u sg=%p\n", - this->magic, static_cast < void * > ( & this->sg ) ); - } -} - -void syncGroupReadNotify::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void * syncGroupReadNotify::operator new ( size_t size, - tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#if defined ( CXX_PLACEMENT_DELETE ) -void syncGroupReadNotify::operator delete ( void *pCadaver, - tsFreeList < class syncGroupReadNotify, 128, epicsMutexNOOP > &freeList ) -{ - freeList.release ( pCadaver ); -} -#endif diff --git a/src/ca/client/syncGroupWriteNotify.cpp b/src/ca/client/syncGroupWriteNotify.cpp deleted file mode 100644 index f0bf42753..000000000 --- a/src/ca/client/syncGroupWriteNotify.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - */ - -#include -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "syncGroup.h" -#include "oldAccess.h" - -syncGroupWriteNotify::syncGroupWriteNotify ( CASG & sgIn, - PRecycleFunc pRecycleFuncIn, chid pChan ) : - chan ( pChan ), pRecycleFunc ( pRecycleFuncIn ), - sg ( sgIn ), magic ( CASG_MAGIC ), - id ( 0u ), idIsValid ( false ), ioComplete ( false ) -{ -} - -void syncGroupWriteNotify::begin ( - epicsGuard < epicsMutex > & guard, unsigned type, - arrayElementCount count, const void * pValueIn ) -{ - this->chan->eliminateExcessiveSendBacklog ( guard ); - this->ioComplete = false; - boolFlagManager mgr ( this->idIsValid ); - this->chan->write ( guard, type, count, - pValueIn, *this, &this->id ); - mgr.release (); -} - -void syncGroupWriteNotify::cancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExcusionGuard ) -{ - if ( this->idIsValid ) { - this->chan->ioCancel ( callbackGuard, mutualExcusionGuard, this->id ); - this->idIsValid = false; - } -} - -syncGroupWriteNotify * syncGroupWriteNotify::factory ( - tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &freeList, - struct CASG & sg, PRecycleFunc pRecycleFunc, chid chan ) -{ - return new ( freeList ) syncGroupWriteNotify ( sg, pRecycleFunc, chan ); -} - -void syncGroupWriteNotify::destroy ( - CallbackGuard &, - epicsGuard < epicsMutex > & guard ) -{ - CASG & sgRef ( this->sg ); - this->~syncGroupWriteNotify (); - ( sgRef.*pRecycleFunc ) ( guard, *this ); -} - -syncGroupWriteNotify::~syncGroupWriteNotify () -{ - assert ( ! this->idIsValid ); -} - -void syncGroupWriteNotify::completion ( - epicsGuard < epicsMutex > & guard ) -{ - if ( this->magic != CASG_MAGIC ) { - this->sg.printFormated ( "cac: sync group io_complete(): bad sync grp op magic number?\n" ); - return; - } - this->sg.completionNotify ( guard, *this ); - this->idIsValid = false; - this->ioComplete = true; -} - -void syncGroupWriteNotify::exception ( - epicsGuard < epicsMutex > & guard, - int status, const char *pContext, unsigned type, arrayElementCount count ) -{ - if ( this->magic != CASG_MAGIC ) { - this->sg.printFormated ( "cac: sync group io_complete(): bad sync grp op magic number?\n" ); - return; - } - this->sg.exception ( guard, status, pContext, - __FILE__, __LINE__, *this->chan, type, count, CA_OP_PUT ); - this->idIsValid = false; - // - // This notify is left installed at this point as a place holder indicating that - // all requests have not been completed. This notify is not uninstalled until - // CASG::block() times out or unit they call CASG::reset(). - // -} - -void syncGroupWriteNotify::show ( - epicsGuard < epicsMutex > &, unsigned level ) const -{ - ::printf ( "pending write sg op\n" ); - if ( level > 0u ) { - ::printf ( "pending sg op: magic=%u sg=%p\n", - this->magic, static_cast < void * > ( &this->sg ) ); - } -} - -void syncGroupWriteNotify::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void * syncGroupWriteNotify::operator new ( size_t size, - tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#if defined ( CXX_PLACEMENT_DELETE ) -void syncGroupWriteNotify::operator delete ( void *pCadaver, - tsFreeList < class syncGroupWriteNotify, 128, epicsMutexNOOP > &freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - diff --git a/src/ca/client/syncgrp.cpp b/src/ca/client/syncgrp.cpp deleted file mode 100644 index 9727ae8df..000000000 --- a/src/ca/client/syncgrp.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#define epicsExportSharedSymbols -#include "iocinf.h" -#include "oldAccess.h" -#include "syncGroup.h" - -/* - * ca_sg_create() - */ -extern "C" int epicsShareAPI ca_sg_create ( CA_SYNC_GID * pgid ) -{ - ca_client_context * pcac; - int caStatus; - CASG * pcasg; - - caStatus = fetchClientContext ( &pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - try { - epicsGuard < epicsMutex > guard ( pcac->mutexRef() ); - pcasg = new ( pcac->casgFreeList ) CASG ( guard, *pcac ); - *pgid = pcasg->getId (); - return ECA_NORMAL; - } - catch ( std::bad_alloc & ) { - return ECA_ALLOCMEM; - } - catch ( ... ) { - return ECA_INTERNAL; - } -} - -int ca_sync_group_destroy ( CallbackGuard & cbGuard, epicsGuard < epicsMutex > & guard, - ca_client_context & cac, const CA_SYNC_GID gid ) -{ - int caStatus; - CASG * pcasg = cac.lookupCASG ( guard, gid ); - if ( pcasg ) { - pcasg->destructor ( cbGuard, guard ); - cac.casgFreeList.release ( pcasg ); - caStatus = ECA_NORMAL; - } - else { - caStatus = ECA_BADSYNCGRP; - } - return caStatus; -} - -/* - * ca_sg_delete() - */ -extern "C" int epicsShareAPI ca_sg_delete ( const CA_SYNC_GID gid ) -{ - ca_client_context * pcac; - int caStatus = fetchClientContext ( & pcac ); - if ( caStatus == ECA_NORMAL ) { - if ( pcac->pCallbackGuard.get() && - pcac->createdByThread == epicsThreadGetIdSelf () ) { - epicsGuard < epicsMutex > guard ( pcac->mutex ); - caStatus = ca_sync_group_destroy ( *pcac->pCallbackGuard.get(), - guard, *pcac, gid ); - } - else { - // - // we will definately stall out here if all of the - // following are true - // - // o user creates non-preemtive mode client library context - // o user doesnt periodically call a ca function - // o user calls this function from an auxiillary thread - // - CallbackGuard cbGuard ( pcac->cbMutex ); - epicsGuard < epicsMutex > guard ( pcac->mutex ); - caStatus = ca_sync_group_destroy ( cbGuard, guard, *pcac, gid ); - } - } - return caStatus; -} - -void sync_group_reset ( ca_client_context & client, CASG & sg ) -{ - if ( client.pCallbackGuard.get() && - client.createdByThread == epicsThreadGetIdSelf () ) { - epicsGuard < epicsMutex > guard ( client.mutex ); - sg.reset ( *client.pCallbackGuard.get(), guard ); - } - else { - // - // we will definately stall out here if all of the - // following are true - // - // o user creates non-preemtive mode client library context - // o user doesnt periodically call a ca function - // o user calls this function from an auxiillary thread - // - CallbackGuard cbGuard ( client.cbMutex ); - epicsGuard < epicsMutex > guard ( client.mutex ); - sg.reset ( cbGuard, guard ); - } -} - -// -// ca_sg_block () -// -// !!!! This routine is only visible in the old interface - or in a new ST interface. -// !!!! In the old interface we restrict thread attach so that calls from threads -// !!!! other than the initializing thread are not allowed if preemptive callback -// !!!! is disabled. This prevents the preemptive callback lock from being released -// !!!! by other threads than the one that locked it. -// -extern "C" int epicsShareAPI ca_sg_block ( - const CA_SYNC_GID gid, ca_real timeout ) -{ - ca_client_context *pcac; - int status = fetchClientContext ( &pcac ); - if ( status == ECA_NORMAL ) { - CASG * pcasg; - { - epicsGuard < epicsMutex > guard ( pcac->mutex ); - pcasg = pcac->lookupCASG ( guard, gid ); - if ( pcasg ) { - status = pcasg->block ( - pcac->pCallbackGuard.get (), guard, timeout ); - } - else { - status = ECA_BADSYNCGRP; - } - } - if ( pcasg ) { - sync_group_reset ( *pcac, *pcasg ); - } - } - return status; -} - -/* - * ca_sg_reset - */ -extern "C" int epicsShareAPI ca_sg_reset ( const CA_SYNC_GID gid ) -{ - ca_client_context *pcac; - int caStatus = fetchClientContext (&pcac); - if ( caStatus == ECA_NORMAL ) { - CASG * pcasg; - { - epicsGuard < epicsMutex > guard ( pcac->mutex ); - pcasg = pcac->lookupCASG ( guard, gid ); - } - if ( pcasg ) { - sync_group_reset ( *pcac, *pcasg ); - caStatus = ECA_NORMAL; - } - else { - caStatus = ECA_BADSYNCGRP; - } - } - return caStatus; -} - -/* - * ca_sg_stat - */ -extern "C" int epicsShareAPI ca_sg_stat ( const CA_SYNC_GID gid ) -{ - ca_client_context * pcac; - int caStatus = fetchClientContext ( &pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - epicsGuard < epicsMutex > guard ( pcac->mutexRef() ); - - CASG * pcasg = pcac->lookupCASG ( guard, gid ); - if ( ! pcasg ) { - ::printf ( "Bad Sync Group Id\n"); - return ECA_BADSYNCGRP; - } - pcasg->show ( guard, 1000u ); - - return ECA_NORMAL; -} - -/* - * ca_sg_test - */ -extern "C" int epicsShareAPI ca_sg_test ( const CA_SYNC_GID gid ) -{ - ca_client_context * pcac; - int caStatus = fetchClientContext ( &pcac ); - if ( caStatus == ECA_NORMAL ) { - epicsGuard < epicsMutex > guard ( pcac->mutexRef() ); - CASG * pcasg = pcac->lookupCASG ( guard, gid ); - if ( pcasg ) { - bool isComplete; - if ( pcac->pCallbackGuard.get() && - pcac->createdByThread == epicsThreadGetIdSelf () ) { - epicsGuard < epicsMutex > guard ( pcac->mutex ); - isComplete = pcasg->ioComplete ( *pcac->pCallbackGuard.get(), guard ); - } - else { - // - // we will definately stall out here if all of the - // following are true - // - // o user creates non-preemtive mode client library context - // o user doesnt periodically call a ca function - // o user calls this function from an auxiillary thread - // - CallbackGuard cbGuard ( pcac->cbMutex ); - epicsGuard < epicsMutex > guard ( pcac->mutex ); - isComplete = pcasg->ioComplete ( cbGuard, guard ); - } - if ( isComplete ) { - caStatus = ECA_IODONE; - } - else{ - caStatus = ECA_IOINPROGRESS; - } - } - else { - caStatus = ECA_BADSYNCGRP; - } - } - return caStatus; -} - -/* - * ca_sg_array_put() - */ -extern "C" int epicsShareAPI ca_sg_array_put ( const CA_SYNC_GID gid, chtype type, - arrayElementCount count, chid pChan, const void *pValue ) -{ - ca_client_context *pcac; - - int caStatus = fetchClientContext ( &pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - epicsGuard < epicsMutex > guard ( pcac->mutexRef() ); - CASG * const pcasg = pcac->lookupCASG ( guard, gid ); - if ( ! pcasg ) { - return ECA_BADSYNCGRP; - } - - try { - pcasg->put ( guard, pChan, type, - static_cast < unsigned > ( count ), pValue ); - return ECA_NORMAL; - } - catch ( cacChannel::badString & ) - { - return ECA_BADSTR; - } - catch ( cacChannel::badType & ) - { - return ECA_BADTYPE; - } - catch ( cacChannel::outOfBounds & ) - { - return ECA_BADCOUNT; - } - catch ( cacChannel::noWriteAccess & ) - { - return ECA_NOWTACCESS; - } - catch ( cacChannel::notConnected & ) - { - return ECA_DISCONN; - } - catch ( cacChannel::unsupportedByService & ) - { - return ECA_UNAVAILINSERV; - } - catch ( cacChannel::requestTimedOut & ) - { - return ECA_TIMEOUT; - } - catch ( std::bad_alloc & ) - { - return ECA_ALLOCMEM; - } - catch ( ... ) - { - return ECA_INTERNAL; - } -} - -/* - * ca_sg_array_get() - */ -extern "C" int epicsShareAPI ca_sg_array_get ( const CA_SYNC_GID gid, chtype type, - arrayElementCount count, chid pChan, void *pValue ) -{ - ca_client_context *pcac; - - int caStatus = fetchClientContext ( &pcac ); - if ( caStatus != ECA_NORMAL ) { - return caStatus; - } - - epicsGuard < epicsMutex > guard ( pcac->mutexRef() ); - CASG * const pcasg = pcac->lookupCASG ( guard, gid ); - if ( ! pcasg ) { - return ECA_BADSYNCGRP; - } - - try { - pcasg->get ( guard, pChan, type, - static_cast < unsigned > ( count ), pValue ); - return ECA_NORMAL; - } - catch ( cacChannel::badString & ) - { - return ECA_BADSTR; - } - catch ( cacChannel::badType & ) - { - return ECA_BADTYPE; - } - catch ( cacChannel::outOfBounds & ) - { - return ECA_BADCOUNT; - } - catch ( cacChannel::noReadAccess & ) - { - return ECA_NORDACCESS; - } - catch ( cacChannel::notConnected & ) - { - return ECA_DISCONN; - } - catch ( cacChannel::unsupportedByService & ) - { - return ECA_UNAVAILINSERV; - } - catch ( std::bad_alloc & ) - { - return ECA_ALLOCMEM; - } - catch ( ... ) - { - return ECA_INTERNAL; - } -} diff --git a/src/ca/client/tcpRecvThread.cpp b/src/ca/client/tcpRecvThread.cpp deleted file mode 100644 index 34bf8ca83..000000000 --- a/src/ca/client/tcpRecvThread.cpp +++ /dev/null @@ -1,11 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - diff --git a/src/ca/client/tcpRecvWatchdog.cpp b/src/ca/client/tcpRecvWatchdog.cpp deleted file mode 100644 index 72c92968b..000000000 --- a/src/ca/client/tcpRecvWatchdog.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "iocinf.h" -#include "cac.h" -#include "virtualCircuit.h" - -// -// the recv watchdog timer is active when this object is created -// -tcpRecvWatchdog::tcpRecvWatchdog - ( epicsMutex & cbMutexIn, cacContextNotify & ctxNotifyIn, - epicsMutex & mutexIn, tcpiiu & iiuIn, - double periodIn, epicsTimerQueue & queueIn ) : - period ( periodIn ), timer ( queueIn.createTimer () ), - cbMutex ( cbMutexIn ), ctxNotify ( ctxNotifyIn ), - mutex ( mutexIn ), iiu ( iiuIn ), - probeResponsePending ( false ), beaconAnomaly ( true ), - probeTimeoutDetected ( false ), shuttingDown ( false ) -{ -} - -tcpRecvWatchdog::~tcpRecvWatchdog () -{ - this->timer.destroy (); -} - -epicsTimerNotify::expireStatus -tcpRecvWatchdog::expire ( const epicsTime & /* currentTime */ ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->shuttingDown ) { - return noRestart; - } - if ( this->probeResponsePending ) { - if ( this->iiu.receiveThreadIsBusy ( guard ) ) { - return expireStatus ( restart, CA_ECHO_TIMEOUT ); - } - - { -# ifdef DEBUG - char hostName[128]; - this->iiu.getHostName ( guard, hostName, sizeof (hostName) ); - debugPrintf ( ( "CA server \"%s\" unresponsive after %g inactive sec" - "- disconnecting.\n", - hostName, this->period ) ); -# endif - // to get the callback lock safely we must reorder - // the lock hierarchy - epicsGuardRelease < epicsMutex > unguard ( guard ); - { - // callback lock is required because channel disconnect - // state change is initiated from this thread, and - // this can cause their disconnect notify callback - // to be invoked. - callbackManager mgr ( this->ctxNotify, this->cbMutex ); - epicsGuard < epicsMutex > tmpGuard ( this->mutex ); - this->iiu.receiveTimeoutNotify ( mgr, tmpGuard ); - this->probeTimeoutDetected = true; - } - } - return noRestart; - } - else { - if ( this->iiu.receiveThreadIsBusy ( guard ) ) { - return expireStatus ( restart, this->period ); - } - this->probeTimeoutDetected = false; - this->probeResponsePending = this->iiu.setEchoRequestPending ( guard ); - debugPrintf ( ("circuit timed out - sending echo request\n") ); - return expireStatus ( restart, CA_ECHO_TIMEOUT ); - } -} - -void tcpRecvWatchdog::beaconArrivalNotify ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( ! ( this->shuttingDown || this->beaconAnomaly || this->probeResponsePending ) ) { - this->timer.start ( *this, this->period ); - debugPrintf ( ("saw a normal beacon - reseting circuit receive watchdog\n") ); - } -} - -// -// be careful about using beacons to reset the connection -// time out watchdog until we have received a ping response -// from the IOC (this makes the software detect reconnects -// faster when the server is rebooted twice in rapid -// succession before a 1st or 2nd beacon has been received) -// -void tcpRecvWatchdog::beaconAnomalyNotify ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->beaconAnomaly = true; - debugPrintf ( ("Saw an abnormal beacon\n") ); -} - -void tcpRecvWatchdog::messageArrivalNotify ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( ! ( this->shuttingDown || this->probeResponsePending ) ) { - this->beaconAnomaly = false; - this->timer.start ( *this, this->period ); - debugPrintf ( ("received a message - reseting circuit recv watchdog\n") ); - } -} - -void tcpRecvWatchdog::probeResponseNotify ( - epicsGuard < epicsMutex > & cbGuard ) -{ - bool restartNeeded = false; - double restartDelay = DBL_MAX; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->probeResponsePending && ! this->shuttingDown ) { - restartNeeded = true; - if ( this->probeTimeoutDetected ) { - this->probeTimeoutDetected = false; - this->probeResponsePending = this->iiu.setEchoRequestPending ( guard ); - restartDelay = CA_ECHO_TIMEOUT; - debugPrintf ( ("late probe response - sending another probe request\n") ); - } - else { - this->probeResponsePending = false; - restartDelay = this->period; - this->iiu.responsiveCircuitNotify ( cbGuard, guard ); - debugPrintf ( ("probe response on time - circuit was tagged reponsive if unresponsive\n") ); - } - } - } - if ( restartNeeded ) { - this->timer.start ( *this, restartDelay ); - debugPrintf ( ("recv wd restarted with delay %f\n", restartDelay) ); - } -} - -// -// The thread for outgoing requests in the client runs -// at a higher priority than the thread in the client -// that receives responses. Therefore, there could -// be considerable large array write send backlog that -// is delaying departure of an echo request and also -// interrupting delivery of an echo response. -// We must be careful not to timeout the echo response as -// long as we see indication of regular departures of -// message buffers from the client in a situation where -// we know that the TCP send queueing has been exceeded. -// The send watchdog will be responsible for detecting -// dead connections in this case. -// -void tcpRecvWatchdog::sendBacklogProgressNotify ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - // We dont set "beaconAnomaly" to be false here because, after we see a - // beacon anomaly (which could be transiently detecting a reboot) we will - // not trust the beacon as an indicator of a healthy server until we - // receive at least one message from the server. - if ( this->probeResponsePending && ! this->shuttingDown ) { - this->timer.start ( *this, CA_ECHO_TIMEOUT ); - debugPrintf ( ("saw heavy send backlog - reseting circuit recv watchdog\n") ); - } -} - -void tcpRecvWatchdog::connectNotify ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->shuttingDown ) { - return; - } - this->timer.start ( *this, this->period ); - debugPrintf ( ("connected to the server - initiating circuit recv watchdog\n") ); -} - -void tcpRecvWatchdog::sendTimeoutNotify ( - epicsGuard < epicsMutex > & /* cbGuard */, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - bool restartNeeded = false; - if ( ! ( this->probeResponsePending || this->shuttingDown ) ) { - this->probeResponsePending = this->iiu.setEchoRequestPending ( guard ); - restartNeeded = true; - } - if ( restartNeeded ) { - this->timer.start ( *this, CA_ECHO_TIMEOUT ); - } - debugPrintf ( ("TCP send timed out - sending echo request\n") ); -} - -void tcpRecvWatchdog::cancel () -{ - this->timer.cancel (); - debugPrintf ( ("canceling TCP recv watchdog\n") ); -} - -void tcpRecvWatchdog::shutdown () -{ - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->shuttingDown = true; - } - this->timer.cancel (); - debugPrintf ( ("canceling TCP recv watchdog\n") ); -} - -double tcpRecvWatchdog::delay () const -{ - return this->timer.getExpireDelay (); -} - -void tcpRecvWatchdog::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - ::printf ( "Receive virtual circuit watchdog at %p, period %f\n", - static_cast ( this ), this->period ); - if ( level > 0u ) { - ::printf ( "\t%s %s %s\n", - this->probeResponsePending ? "probe-response-pending" : "", - this->beaconAnomaly ? "beacon-anomaly-detected" : "", - this->probeTimeoutDetected ? "probe-response-timeout" : "" ); - } -} - diff --git a/src/ca/client/tcpRecvWatchdog.h b/src/ca/client/tcpRecvWatchdog.h deleted file mode 100644 index 0b15e22d8..000000000 --- a/src/ca/client/tcpRecvWatchdog.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef tcpRecvWatchdogh -#define tcpRecvWatchdogh - -#ifdef epicsExportSharedSymbols -# define tcpRecvWatchdogh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsTimer.h" - -#ifdef tcpRecvWatchdogh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class tcpiiu; - -class tcpRecvWatchdog : private epicsTimerNotify { -public: - tcpRecvWatchdog ( epicsMutex & cbMutex, - cacContextNotify & ctxNotify, - epicsMutex & mutex, tcpiiu &, - double periodIn, epicsTimerQueue & ); - virtual ~tcpRecvWatchdog (); - void sendBacklogProgressNotify ( - epicsGuard < epicsMutex > & ); - void messageArrivalNotify ( - epicsGuard < epicsMutex > & guard ); - void probeResponseNotify ( - epicsGuard < epicsMutex > & ); - void beaconArrivalNotify ( - epicsGuard < epicsMutex > & ); - void beaconAnomalyNotify ( epicsGuard < epicsMutex > & ); - void connectNotify ( - epicsGuard < epicsMutex > & ); - void sendTimeoutNotify ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void cancel (); - void shutdown (); - void show ( unsigned level ) const; - double delay () const; -private: - const double period; - epicsTimer & timer; - epicsMutex & cbMutex; - cacContextNotify & ctxNotify; - epicsMutex & mutex; - tcpiiu & iiu; - bool probeResponsePending; - bool beaconAnomaly; - bool probeTimeoutDetected; - bool shuttingDown; - expireStatus expire ( const epicsTime & currentTime ); - tcpRecvWatchdog ( const tcpRecvWatchdog & ); - tcpRecvWatchdog & operator = ( const tcpRecvWatchdog & ); -}; - -#endif // #ifndef tcpRecvWatchdogh - diff --git a/src/ca/client/tcpSendWatchdog.cpp b/src/ca/client/tcpSendWatchdog.cpp deleted file mode 100644 index 6834b39e7..000000000 --- a/src/ca/client/tcpSendWatchdog.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "iocinf.h" -#include "cac.h" -#include "virtualCircuit.h" - -tcpSendWatchdog::tcpSendWatchdog ( - epicsMutex & cbMutexIn, cacContextNotify & ctxNotifyIn, - epicsMutex & mutexIn, tcpiiu & iiuIn, - double periodIn, epicsTimerQueue & queueIn ) : - period ( periodIn ), timer ( queueIn.createTimer () ), - cbMutex ( cbMutexIn ), ctxNotify ( ctxNotifyIn ), - mutex ( mutexIn ), iiu ( iiuIn ) -{ -} - -tcpSendWatchdog::~tcpSendWatchdog () -{ - this->timer.destroy (); -} - -epicsTimerNotify::expireStatus tcpSendWatchdog::expire ( - const epicsTime & /* currentTime */ ) -{ - { - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->iiu.receiveThreadIsBusy ( guard ) ) { - return expireStatus ( restart, this->period ); - } - } - { - callbackManager mgr ( this->ctxNotify, this->cbMutex ); - epicsGuard < epicsMutex > guard ( this->mutex ); -# ifdef DEBUG - char hostName[128]; - this->iiu.getHostName ( guard, hostName, sizeof ( hostName ) ); - debugPrintf ( ( "Request not accepted by CA server %s for %g sec. Disconnecting.\n", - hostName, this->period ) ); -# endif - this->iiu.sendTimeoutNotify ( mgr, guard ); - } - return noRestart; -} - -void tcpSendWatchdog::start ( const epicsTime & /* currentTime */ ) -{ - this->timer.start ( *this, this->period ); -} - -void tcpSendWatchdog::cancel () -{ - this->timer.cancel (); -} - - diff --git a/src/ca/client/tcpSendWatchdog.h b/src/ca/client/tcpSendWatchdog.h deleted file mode 100644 index 05a2dfe75..000000000 --- a/src/ca/client/tcpSendWatchdog.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef tcpSendWatchdogh -#define tcpSendWatchdogh - - -#ifdef epicsExportSharedSymbols -# define tcpSendWatchdogh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsTimer.h" - -#ifdef tcpSendWatchdogh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class tcpSendWatchdog : private epicsTimerNotify { -public: - tcpSendWatchdog ( - epicsMutex & cbMutex, cacContextNotify & ctxNotify, - epicsMutex & mutex, tcpiiu &, - double periodIn, epicsTimerQueue & queueIn ); - virtual ~tcpSendWatchdog (); - void start ( const epicsTime & ); - void cancel (); -private: - const double period; - epicsTimer & timer; - epicsMutex & cbMutex; - cacContextNotify & ctxNotify; - epicsMutex & mutex; - tcpiiu & iiu; - expireStatus expire ( const epicsTime & currentTime ); - tcpSendWatchdog ( const tcpSendWatchdog & ); - tcpSendWatchdog & operator = ( const tcpSendWatchdog & ); -}; - -#endif // #ifndef tcpSendWatchdog diff --git a/src/ca/client/tcpiiu.cpp b/src/ca/client/tcpiiu.cpp deleted file mode 100644 index 045f8d57e..000000000 --- a/src/ca/client/tcpiiu.cpp +++ /dev/null @@ -1,2213 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - * - */ - -#ifdef _MSC_VER -# pragma warning(disable:4355) -#endif - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include -#include - -#include - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "localHostName.h" -#include "iocinf.h" -#include "virtualCircuit.h" -#include "inetAddrID.h" -#include "cac.h" -#include "netiiu.h" -#include "hostNameCache.h" -#include "net_convert.h" -#include "bhe.h" -#include "epicsSignal.h" -#include "caerr.h" -#include "udpiiu.h" - -using namespace std; - -tcpSendThread::tcpSendThread ( - class tcpiiu & iiuIn, const char * pName, - unsigned stackSize, unsigned priority ) : - thread ( *this, pName, stackSize, priority ), iiu ( iiuIn ) -{ -} - -tcpSendThread::~tcpSendThread () -{ -} - -void tcpSendThread::start () -{ - this->thread.start (); -} - -void tcpSendThread::show ( unsigned /* level */ ) const -{ -} - -void tcpSendThread::exitWait () -{ - this->thread.exitWait (); -} - -void tcpSendThread::run () -{ - try { - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - - bool laborPending = false; - - while ( true ) { - - // dont wait if there is still labor to be done below - if ( ! laborPending ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->iiu.sendThreadFlushEvent.wait (); - } - - if ( this->iiu.state != tcpiiu::iiucs_connected ) { - break; - } - - laborPending = false; - bool flowControlLaborNeeded = - this->iiu.busyStateDetected != this->iiu.flowControlActive; - bool echoLaborNeeded = this->iiu.echoRequestPending; - this->iiu.echoRequestPending = false; - - if ( flowControlLaborNeeded ) { - if ( this->iiu.flowControlActive ) { - this->iiu.disableFlowControlRequest ( guard ); - this->iiu.flowControlActive = false; - debugPrintf ( ( "fc off\n" ) ); - } - else { - this->iiu.enableFlowControlRequest ( guard ); - this->iiu.flowControlActive = true; - debugPrintf ( ( "fc on\n" ) ); - } - } - - if ( echoLaborNeeded ) { - this->iiu.echoRequest ( guard ); - } - - while ( nciu * pChan = this->iiu.createReqPend.get () ) { - this->iiu.createChannelRequest ( *pChan, guard ); - - if ( CA_V42 ( this->iiu.minorProtocolVersion ) ) { - this->iiu.createRespPend.add ( *pChan ); - pChan->channelNode::listMember = - channelNode::cs_createRespPend; - } - else { - // This wakes up the resp thread so that it can call - // the connect callback. This isnt maximally efficent - // but it has the excellent side effect of not requiring - // that the UDP thread take the callback lock. There are - // almost no V42 servers left at this point. - this->iiu.v42ConnCallbackPend.add ( *pChan ); - pChan->channelNode::listMember = - channelNode::cs_v42ConnCallbackPend; - this->iiu.echoRequestPending = true; - laborPending = true; - } - - if ( this->iiu.sendQue.flushBlockThreshold () ) { - laborPending = true; - break; - } - } - - while ( nciu * pChan = this->iiu.subscripReqPend.get () ) { - // this installs any subscriptions as needed - pChan->resubscribe ( guard ); - this->iiu.connectedList.add ( *pChan ); - pChan->channelNode::listMember = - channelNode::cs_connected; - if ( this->iiu.sendQue.flushBlockThreshold () ) { - laborPending = true; - break; - } - } - - while ( nciu * pChan = this->iiu.subscripUpdateReqPend.get () ) { - // this updates any subscriptions as needed - pChan->sendSubscriptionUpdateRequests ( guard ); - this->iiu.connectedList.add ( *pChan ); - pChan->channelNode::listMember = - channelNode::cs_connected; - if ( this->iiu.sendQue.flushBlockThreshold () ) { - laborPending = true; - break; - } - } - - if ( ! this->iiu.sendThreadFlush ( guard ) ) { - break; - } - } - if ( this->iiu.state == tcpiiu::iiucs_clean_shutdown ) { - this->iiu.sendThreadFlush ( guard ); - // this should cause the server to disconnect from - // the client - int status = ::shutdown ( this->iiu.sock, SHUT_WR ); - if ( status ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAC TCP clean socket shutdown error was %s\n", - sockErrBuf ); - } - } - } - catch ( ... ) { - errlogPrintf ( - "cac: tcp send thread received an unexpected exception " - "- disconnecting\n"); - // this should cause the server to disconnect from - // the client - int status = ::shutdown ( this->iiu.sock, SHUT_WR ); - if ( status ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAC TCP clean socket shutdown error was %s\n", - sockErrBuf ); - } - } - - this->iiu.sendDog.cancel (); - this->iiu.recvDog.shutdown (); - - while ( ! this->iiu.recvThread.exitWait ( 30.0 ) ) { - // it is possible to get stuck here if the user calls - // ca_context_destroy() when a circuit isnt known to - // be unresponsive, but is. That situation is probably - // rare, and the IP kernel might have a timeout for - // such situations, nevertheless we will attempt to deal - // with it here after waiting a reasonable amount of time - // for a clean shutdown to finish. - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - this->iiu.initiateAbortShutdown ( guard ); - } - - // user threads blocking for send backlog to be reduced - // will abort their attempt to get space if - // the state of the tcpiiu changes from connected to a - // disconnecting state. Nevertheless, we need to wait - // for them to finish prior to destroying the IIU. - { - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - while ( this->iiu.blockingForFlush ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - epicsThreadSleep ( 0.1 ); - } - } - this->iiu.cacRef.destroyIIU ( this->iiu ); -} - -unsigned tcpiiu::sendBytes ( const void *pBuf, - unsigned nBytesInBuf, const epicsTime & currentTime ) -{ - unsigned nBytes = 0u; - assert ( nBytesInBuf <= INT_MAX ); - - this->sendDog.start ( currentTime ); - - while ( true ) { - int status = ::send ( this->sock, - static_cast < const char * > (pBuf), (int) nBytesInBuf, 0 ); - if ( status > 0 ) { - nBytes = static_cast ( status ); - // printf("SEND: %u\n", nBytes ); - break; - } - else { - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->state != iiucs_connected && - this->state != iiucs_clean_shutdown ) { - break; - } - // winsock indicates disconnect by returning zero here - if ( status == 0 ) { - this->disconnectNotify ( guard ); - break; - } - - int localError = SOCKERRNO; - - if ( localError == SOCK_EINTR ) { - continue; - } - - if ( localError == SOCK_ENOBUFS ) { - errlogPrintf ( - "CAC: system low on network buffers " - "- send retry in 15 seconds\n" ); - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - epicsThreadSleep ( 15.0 ); - } - continue; - } - - if ( - localError != SOCK_EPIPE && - localError != SOCK_ECONNRESET && - localError != SOCK_ETIMEDOUT && - localError != SOCK_ECONNABORTED && - localError != SOCK_SHUTDOWN ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC: unexpected TCP send error: %s\n", - sockErrBuf ); - } - - this->disconnectNotify ( guard ); - break; - } - } - - this->sendDog.cancel (); - - return nBytes; -} - -void tcpiiu::recvBytes ( - void * pBuf, unsigned nBytesInBuf, statusWireIO & stat ) -{ - assert ( nBytesInBuf <= INT_MAX ); - - while ( true ) { - int status = ::recv ( this->sock, static_cast ( pBuf ), - static_cast ( nBytesInBuf ), 0 ); - - if ( status > 0 ) { - stat.bytesCopied = static_cast ( status ); - assert ( stat.bytesCopied <= nBytesInBuf ); - stat.circuitState = swioConnected; - return; - } - else { - epicsGuard < epicsMutex > guard ( this->mutex ); - - if ( status == 0 ) { - this->disconnectNotify ( guard ); - stat.bytesCopied = 0u; - stat.circuitState = swioPeerHangup; - return; - } - - // if the circuit was locally aborted then supress - // warning messages about bad file descriptor etc - if ( this->state != iiucs_connected && - this->state != iiucs_clean_shutdown ) { - stat.bytesCopied = 0u; - stat.circuitState = swioLocalAbort; - return; - } - - int localErrno = SOCKERRNO; - - if ( localErrno == SOCK_SHUTDOWN ) { - stat.bytesCopied = 0u; - stat.circuitState = swioPeerHangup; - return; - } - - if ( localErrno == SOCK_EINTR ) { - continue; - } - - if ( localErrno == SOCK_ENOBUFS ) { - errlogPrintf ( - "CAC: system low on network buffers " - "- receive retry in 15 seconds\n" ); - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - epicsThreadSleep ( 15.0 ); - } - continue; - } - - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - - // the replacable printf handler isnt called here - // because it reqires a callback lock which probably - // isnt appropriate here - char name[64]; - this->hostNameCacheInstance.getName ( - name, sizeof ( name ) ); - errlogPrintf ( - "Unexpected problem with CA circuit to" - " server \"%s\" was \"%s\" - disconnecting\n", - name, sockErrBuf ); - - stat.bytesCopied = 0u; - stat.circuitState = swioPeerAbort; - return; - } - } -} - -tcpRecvThread::tcpRecvThread ( - class tcpiiu & iiuIn, class epicsMutex & cbMutexIn, - cacContextNotify & ctxNotifyIn, const char * pName, - unsigned int stackSize, unsigned int priority ) : - thread ( *this, pName, stackSize, priority ), - iiu ( iiuIn ), cbMutex ( cbMutexIn ), - ctxNotify ( ctxNotifyIn ) {} - -tcpRecvThread::~tcpRecvThread () -{ -} - -void tcpRecvThread::start () -{ - this->thread.start (); -} - -void tcpRecvThread::show ( unsigned /* level */ ) const -{ -} - -bool tcpRecvThread::exitWait ( double delay ) -{ - return this->thread.exitWait ( delay ); -} - -void tcpRecvThread::exitWait () -{ - this->thread.exitWait (); -} - -bool tcpRecvThread::validFillStatus ( - epicsGuard < epicsMutex > & guard, const statusWireIO & stat ) -{ - if ( this->iiu.state != tcpiiu::iiucs_connected && - this->iiu.state != tcpiiu::iiucs_clean_shutdown ) { - return false; - } - if ( stat.circuitState == swioConnected ) { - return true; - } - if ( stat.circuitState == swioPeerHangup || - stat.circuitState == swioPeerAbort ) { - this->iiu.disconnectNotify ( guard ); - } - else if ( stat.circuitState == swioLinkFailure ) { - this->iiu.initiateAbortShutdown ( guard ); - } - else if ( stat.circuitState == swioLocalAbort ) { - // state change already occurred - } - else { - errlogMessage ( "cac: invalid fill status - disconnecting" ); - this->iiu.disconnectNotify ( guard ); - } - return false; -} - -void tcpRecvThread::run () -{ - try { - { - bool connectSuccess = false; - { - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - this->connect ( guard ); - connectSuccess = this->iiu.state == tcpiiu::iiucs_connected; - } - if ( ! connectSuccess ) { - this->iiu.recvDog.shutdown (); - this->iiu.cacRef.destroyIIU ( this->iiu ); - return; - } - if ( this->iiu.isNameService () ) { - this->iiu.pSearchDest->setCircuit ( &this->iiu ); - this->iiu.pSearchDest->enable (); - } - } - - this->iiu.sendThread.start (); - epicsThreadPrivateSet ( caClientCallbackThreadId, &this->iiu ); - this->iiu.cacRef.attachToClientCtx (); - - comBuf * pComBuf = 0; - while ( true ) { - - // - // We leave the bytes pending and fetch them after - // callbacks are enabled when running in the old preemptive - // call back disabled mode so that asynchronous wakeup via - // file manager call backs works correctly. This does not - // appear to impact performance. - // - if ( ! pComBuf ) { - pComBuf = new ( this->iiu.comBufMemMgr ) comBuf; - } - - statusWireIO stat; - pComBuf->fillFromWire ( this->iiu, stat ); - - epicsTime currentTime = epicsTime::getCurrent (); - - { - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - - if ( ! this->validFillStatus ( guard, stat ) ) { - break; - } - if ( stat.bytesCopied == 0u ) { - continue; - } - - this->iiu.recvQue.pushLastComBufReceived ( *pComBuf ); - pComBuf = 0; - - this->iiu._receiveThreadIsBusy = true; - } - - bool sendWakeupNeeded = false; - { - // only one recv thread at a time may call callbacks - // - pendEvent() blocks until threads waiting for - // this lock get a chance to run - callbackManager mgr ( this->ctxNotify, this->cbMutex ); - - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - - // route legacy V42 channel connect through the recv thread - - // the only thread that should be taking the callback lock - while ( nciu * pChan = this->iiu.v42ConnCallbackPend.first () ) { - this->iiu.connectNotify ( guard, *pChan ); - pChan->connect ( mgr.cbGuard, guard ); - } - - this->iiu.unacknowledgedSendBytes = 0u; - - bool protocolOK = false; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - // execute receive labor - protocolOK = this->iiu.processIncoming ( currentTime, mgr ); - } - - if ( ! protocolOK ) { - this->iiu.initiateAbortShutdown ( guard ); - break; - } - this->iiu._receiveThreadIsBusy = false; - // reschedule connection activity watchdog - this->iiu.recvDog.messageArrivalNotify ( guard ); - // - // if this thread has connected channels with subscriptions - // that need to be sent then wakeup the send thread - if ( this->iiu.subscripReqPend.count() ) { - sendWakeupNeeded = true; - } - } - - // - // we dont feel comfortable calling this with a lock applied - // (it might block for longer than we like) - // - // we would prefer to improve efficency by trying, first, a - // recv with the new MSG_DONTWAIT flag set, but there isnt - // universal support - // - bool bytesArePending = this->iiu.bytesArePendingInOS (); - { - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - if ( bytesArePending ) { - if ( ! this->iiu.busyStateDetected ) { - this->iiu.contigRecvMsgCount++; - if ( this->iiu.contigRecvMsgCount >= - this->iiu.cacRef.maxContiguousFrames ( guard ) ) { - this->iiu.busyStateDetected = true; - sendWakeupNeeded = true; - } - } - } - else { - // if no bytes are pending then we must immediately - // switch off flow control w/o waiting for more - // data to arrive - this->iiu.contigRecvMsgCount = 0u; - if ( this->iiu.busyStateDetected ) { - sendWakeupNeeded = true; - this->iiu.busyStateDetected = false; - } - } - } - - if ( sendWakeupNeeded ) { - this->iiu.sendThreadFlushEvent.signal (); - } - } - - if ( pComBuf ) { - pComBuf->~comBuf (); - this->iiu.comBufMemMgr.release ( pComBuf ); - } - } - catch ( std::bad_alloc & ) { - errlogPrintf ( - "CA client library tcp receive thread " - "terminating due to no space in pool " - "C++ exception\n" ); - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - this->iiu.initiateCleanShutdown ( guard ); - } - catch ( std::exception & except ) { - errlogPrintf ( - "CA client library tcp receive thread " - "terminating due to C++ exception \"%s\"\n", - except.what () ); - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - this->iiu.initiateCleanShutdown ( guard ); - } - catch ( ... ) { - errlogPrintf ( - "CA client library tcp receive thread " - "terminating due to a non-standard C++ exception\n" ); - epicsGuard < epicsMutex > guard ( this->iiu.mutex ); - this->iiu.initiateCleanShutdown ( guard ); - } -} - -/* - * tcpRecvThread::connect () - */ -void tcpRecvThread::connect ( - epicsGuard < epicsMutex > & guard ) -{ - // attempt to connect to a CA server - while ( true ) { - int status; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - osiSockAddr tmp = this->iiu.address (); - status = ::connect ( this->iiu.sock, - & tmp.sa, sizeof ( tmp.sa ) ); - } - - if ( this->iiu.state != tcpiiu::iiucs_connecting ) { - break; - } - if ( status >= 0 ) { - // put the iiu into the connected state - this->iiu.state = tcpiiu::iiucs_connected; - this->iiu.recvDog.connectNotify ( guard ); - break; - } - else { - int errnoCpy = SOCKERRNO; - - if ( errnoCpy == SOCK_EINTR ) { - continue; - } - else if ( errnoCpy == SOCK_SHUTDOWN ) { - if ( ! this->iiu.isNameService () ) { - break; - } - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC: Unable to connect because \"%s\"\n", - sockErrBuf ); - if ( ! this->iiu.isNameService () ) { - this->iiu.disconnectNotify ( guard ); - break; - } - } - { - double sleepTime = this->iiu.cacRef.connectionTimeout ( guard ); - epicsGuardRelease < epicsMutex > unguard ( guard ); - epicsThreadSleep ( sleepTime ); - } - continue; - } - } - return; -} - -// -// tcpiiu::tcpiiu () -// -tcpiiu::tcpiiu ( - cac & cac, epicsMutex & mutexIn, epicsMutex & cbMutexIn, - cacContextNotify & ctxNotifyIn, double connectionTimeout, - epicsTimerQueue & timerQueue, const osiSockAddr & addrIn, - comBufMemoryManager & comBufMemMgrIn, - unsigned minorVersion, ipAddrToAsciiEngine & engineIn, - const cacChannel::priLev & priorityIn, - SearchDestTCP * pSearchDestIn ) : - caServerID ( addrIn.ia, priorityIn ), - hostNameCacheInstance ( addrIn, engineIn ), - recvThread ( *this, cbMutexIn, ctxNotifyIn, "CAC-TCP-recv", - epicsThreadGetStackSize ( epicsThreadStackBig ), - cac::highestPriorityLevelBelow ( cac.getInitializingThreadsPriority() ) ), - sendThread ( *this, "CAC-TCP-send", - epicsThreadGetStackSize ( epicsThreadStackMedium ), - cac::lowestPriorityLevelAbove ( - cac.getInitializingThreadsPriority() ) ), - recvDog ( cbMutexIn, ctxNotifyIn, mutexIn, - *this, connectionTimeout, timerQueue ), - sendDog ( cbMutexIn, ctxNotifyIn, mutexIn, - *this, connectionTimeout, timerQueue ), - sendQue ( *this, comBufMemMgrIn ), - recvQue ( comBufMemMgrIn ), - curDataMax ( MAX_TCP ), - curDataBytes ( 0ul ), - comBufMemMgr ( comBufMemMgrIn ), - cacRef ( cac ), - pCurData ( (char*) freeListMalloc(this->cacRef.tcpSmallRecvBufFreeList) ), - pSearchDest ( pSearchDestIn ), - mutex ( mutexIn ), - cbMutex ( cbMutexIn ), - minorProtocolVersion ( minorVersion ), - state ( iiucs_connecting ), - sock ( INVALID_SOCKET ), - contigRecvMsgCount ( 0u ), - blockingForFlush ( 0u ), - socketLibrarySendBufferSize ( 0x1000 ), - unacknowledgedSendBytes ( 0u ), - channelCountTot ( 0u ), - _receiveThreadIsBusy ( false ), - busyStateDetected ( false ), - flowControlActive ( false ), - echoRequestPending ( false ), - oldMsgHeaderAvailable ( false ), - msgHeaderAvailable ( false ), - earlyFlush ( false ), - recvProcessPostponedFlush ( false ), - discardingPendingData ( false ), - socketHasBeenClosed ( false ), - unresponsiveCircuit ( false ) -{ - if(!pCurData) - throw std::bad_alloc(); - - this->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); - if ( this->sock == INVALID_SOCKET ) { - freeListFree(this->cacRef.tcpSmallRecvBufFreeList, this->pCurData); - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - std :: string reason = - "CAC: TCP circuit creation failure because \""; - reason += sockErrBuf; - reason += "\""; - throw runtime_error ( reason ); - } - - int flag = true; - int status = setsockopt ( this->sock, IPPROTO_TCP, TCP_NODELAY, - (char *) &flag, sizeof ( flag ) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC: problems setting socket option TCP_NODELAY = \"%s\"\n", - sockErrBuf ); - } - - flag = true; - status = setsockopt ( this->sock , SOL_SOCKET, SO_KEEPALIVE, - ( char * ) &flag, sizeof ( flag ) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC: problems setting socket option SO_KEEPALIVE = \"%s\"\n", - sockErrBuf ); - } - - // load message queue with messages informing server - // of version, user, and host name of client - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->versionMessage ( guard, this->priority() ); - this->userNameSetRequest ( guard ); - this->hostNameSetRequest ( guard ); - } - -# if 0 - { - int i; - - /* - * some concern that vxWorks will run out of mBuf's - * if this change is made joh 11-10-98 - */ - i = MAX_MSG_SIZE; - status = setsockopt ( this->sock, SOL_SOCKET, SO_SNDBUF, - ( char * ) &i, sizeof ( i ) ); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC: problems setting socket option SO_SNDBUF = \"%s\"\n", - sockErrBuf ); - } - i = MAX_MSG_SIZE; - status = setsockopt ( this->sock, SOL_SOCKET, SO_RCVBUF, - ( char * ) &i, sizeof ( i ) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC: problems setting socket option SO_RCVBUF = \"%s\"\n", - sockErrBuf ); - } - } -# endif - - { - int nBytes; - osiSocklen_t sizeOfParameter = static_cast < int > ( sizeof ( nBytes ) ); - status = getsockopt ( this->sock, SOL_SOCKET, SO_SNDBUF, - ( char * ) &nBytes, &sizeOfParameter ); - if ( status < 0 || nBytes < 0 || - sizeOfParameter != static_cast < int > ( sizeof ( nBytes ) ) ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAC: problems getting socket option SO_SNDBUF = \"%s\"\n", - sockErrBuf ); - } - else { - this->socketLibrarySendBufferSize = static_cast < unsigned > ( nBytes ); - } - } - - if ( isNameService() ) { - pSearchDest->setCircuit ( this ); - } - - memset ( (void *) &this->curMsg, '\0', sizeof ( this->curMsg ) ); -} - -// this must always be called by the udp thread when it holds -// the callback lock. -void tcpiiu::start ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->recvThread.start (); -} - -void tcpiiu::initiateCleanShutdown ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( this->state == iiucs_connected ) { - if ( this->unresponsiveCircuit ) { - this->initiateAbortShutdown ( guard ); - } - else { - this->state = iiucs_clean_shutdown; - this->sendThreadFlushEvent.signal (); - this->flushBlockEvent.signal (); - } - } - else if ( this->state == iiucs_clean_shutdown ) { - if ( this->unresponsiveCircuit ) { - this->initiateAbortShutdown ( guard ); - } - } - else if ( this->state == iiucs_connecting ) { - this->initiateAbortShutdown ( guard ); - } -} - -void tcpiiu::disconnectNotify ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->state = iiucs_disconnected; - this->sendThreadFlushEvent.signal (); - this->flushBlockEvent.signal (); -} - -void tcpiiu::responsiveCircuitNotify ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - cbGuard.assertIdenticalMutex ( this->cbMutex ); - guard.assertIdenticalMutex ( this->mutex ); - if ( this->unresponsiveCircuit ) { - this->unresponsiveCircuit = false; - while ( nciu * pChan = this->unrespCircuit.get() ) { - this->subscripUpdateReqPend.add ( *pChan ); - pChan->channelNode::listMember = - channelNode::cs_subscripUpdateReqPend; - pChan->connect ( cbGuard, guard ); - } - this->sendThreadFlushEvent.signal (); - } -} - -void tcpiiu::sendTimeoutNotify ( - callbackManager & mgr, - epicsGuard < epicsMutex > & guard ) -{ - mgr.cbGuard.assertIdenticalMutex ( this-> cbMutex ); - guard.assertIdenticalMutex ( this->mutex ); - this->unresponsiveCircuitNotify ( mgr.cbGuard, guard ); - // setup circuit probe sequence - this->recvDog.sendTimeoutNotify ( mgr.cbGuard, guard ); -} - -void tcpiiu::receiveTimeoutNotify ( - callbackManager & mgr, - epicsGuard < epicsMutex > & guard ) -{ - mgr.cbGuard.assertIdenticalMutex ( this->cbMutex ); - guard.assertIdenticalMutex ( this->mutex ); - this->unresponsiveCircuitNotify ( mgr.cbGuard, guard ); -} - -void tcpiiu::unresponsiveCircuitNotify ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - cbGuard.assertIdenticalMutex ( this->cbMutex ); - guard.assertIdenticalMutex ( this->mutex ); - - if ( ! this->unresponsiveCircuit ) { - this->unresponsiveCircuit = true; - this->echoRequestPending = true; - this->sendThreadFlushEvent.signal (); - this->flushBlockEvent.signal (); - - // must not hold lock when canceling timer - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - { - epicsGuardRelease < epicsMutex > cbUnguard ( cbGuard ); - this->recvDog.cancel (); - this->sendDog.cancel (); - } - } - - if ( this->connectedList.count() ) { - char hostNameTmp[128]; - this->getHostName ( guard, hostNameTmp, sizeof ( hostNameTmp ) ); - genLocalExcep ( cbGuard, guard, this->cacRef, - ECA_UNRESPTMO, hostNameTmp ); - while ( nciu * pChan = this->connectedList.get () ) { - // The cac lock is released herein so there is concern that - // the list could be changed while we are traversing it. - // However, this occurs only if a circuit disconnects, - // a user deletes a channel, or a server disconnects a - // channel. The callback lock must be taken in all of - // these situations so this code is protected. - this->unrespCircuit.add ( *pChan ); - pChan->channelNode::listMember = - channelNode::cs_unrespCircuit; - pChan->unresponsiveCircuitNotify ( cbGuard, guard ); - } - } - } -} - -void tcpiiu::initiateAbortShutdown ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( ! this->discardingPendingData ) { - // force abortive shutdown sequence - // (discard outstanding sends and receives) - struct linger tmpLinger; - tmpLinger.l_onoff = true; - tmpLinger.l_linger = 0u; - int status = setsockopt ( this->sock, SOL_SOCKET, SO_LINGER, - reinterpret_cast ( &tmpLinger ), sizeof (tmpLinger) ); - if ( status != 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC TCP socket linger set error was %s\n", - sockErrBuf ); - } - this->discardingPendingData = true; - } - - iiu_conn_state oldState = this->state; - if ( oldState != iiucs_abort_shutdown && oldState != iiucs_disconnected ) { - this->state = iiucs_abort_shutdown; - - epicsSocketSystemCallInterruptMechanismQueryInfo info = - epicsSocketSystemCallInterruptMechanismQuery (); - switch ( info ) { - case esscimqi_socketCloseRequired: - // - // on winsock and probably vxWorks shutdown() does not - // unblock a thread in recv() so we use close() and introduce - // some complexity because we must unregister the fd early - // - if ( ! this->socketHasBeenClosed ) { - epicsSocketDestroy ( this->sock ); - this->socketHasBeenClosed = true; - } - break; - case esscimqi_socketBothShutdownRequired: - { - int status = ::shutdown ( this->sock, SHUT_RDWR ); - if ( status ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAC TCP socket shutdown error was %s\n", - sockErrBuf ); - } - } - break; - case esscimqi_socketSigAlarmRequired: - this->recvThread.interruptSocketRecv (); - this->sendThread.interruptSocketSend (); - break; - default: - break; - }; - - // - // wake up the send thread if it isnt blocking in send() - // - this->sendThreadFlushEvent.signal (); - this->flushBlockEvent.signal (); - } -} - -// -// tcpiiu::~tcpiiu () -// -tcpiiu :: ~tcpiiu () -{ - if ( this->pSearchDest ) { - this->pSearchDest->disable (); - } - - this->sendThread.exitWait (); - this->recvThread.exitWait (); - this->sendDog.cancel (); - this->recvDog.shutdown (); - - if ( ! this->socketHasBeenClosed ) { - epicsSocketDestroy ( this->sock ); - } - - // free message body cache - if ( this->pCurData ) { - if ( this->curDataMax <= MAX_TCP ) { - freeListFree(this->cacRef.tcpSmallRecvBufFreeList, this->pCurData); - } - else if ( this->cacRef.tcpLargeRecvBufFreeList ) { - freeListFree(this->cacRef.tcpLargeRecvBufFreeList, this->pCurData); - } - else { - free ( this->pCurData ); - } - } -} - -void tcpiiu::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > locker ( this->mutex ); - char buf[256]; - this->hostNameCacheInstance.getName ( buf, sizeof ( buf ) ); - ::printf ( "Virtual circuit to \"%s\" at version V%u.%u state %u\n", - buf, CA_MAJOR_PROTOCOL_REVISION, - this->minorProtocolVersion, this->state ); - if ( level > 1u ) { - ::printf ( "\tcurrent data cache pointer = %p current data cache size = %lu\n", - static_cast < void * > ( this->pCurData ), this->curDataMax ); - ::printf ( "\tcontiguous receive message count=%u, busy detect bool=%u, flow control bool=%u\n", - this->contigRecvMsgCount, this->busyStateDetected, this->flowControlActive ); - ::printf ( "\receive thread is busy=%u\n", - this->_receiveThreadIsBusy ); - } - if ( level > 2u ) { - ::printf ( "\tvirtual circuit socket identifier %d\n", this->sock ); - ::printf ( "\tsend thread flush signal:\n" ); - this->sendThreadFlushEvent.show ( level-2u ); - ::printf ( "\tsend thread:\n" ); - this->sendThread.show ( level-2u ); - ::printf ( "\trecv thread:\n" ); - this->recvThread.show ( level-2u ); - ::printf ("\techo pending bool = %u\n", this->echoRequestPending ); - ::printf ( "IO identifier hash table:\n" ); - - if ( this->createReqPend.count () ) { - ::printf ( "Create request pending channels\n" ); - tsDLIterConst < nciu > pChan = this->createReqPend.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 2u ); - pChan++; - } - } - if ( this->createRespPend.count () ) { - ::printf ( "Create response pending channels\n" ); - tsDLIterConst < nciu > pChan = this->createRespPend.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 2u ); - pChan++; - } - } - if ( this->v42ConnCallbackPend.count () ) { - ::printf ( "V42 Conn Callback pending channels\n" ); - tsDLIterConst < nciu > pChan = this->v42ConnCallbackPend.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 2u ); - pChan++; - } - } - if ( this->subscripReqPend.count () ) { - ::printf ( "Subscription request pending channels\n" ); - tsDLIterConst < nciu > pChan = this->subscripReqPend.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 2u ); - pChan++; - } - } - if ( this->connectedList.count () ) { - ::printf ( "Connected channels\n" ); - tsDLIterConst < nciu > pChan = this->connectedList.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 2u ); - pChan++; - } - } - if ( this->unrespCircuit.count () ) { - ::printf ( "Unresponsive circuit channels\n" ); - tsDLIterConst < nciu > pChan = this->unrespCircuit.firstIter (); - while ( pChan.valid () ) { - pChan->show ( level - 2u ); - pChan++; - } - } - } -} - -bool tcpiiu::setEchoRequestPending ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - this->echoRequestPending = true; - this->sendThreadFlushEvent.signal (); - if ( CA_V43 ( this->minorProtocolVersion ) ) { - // we send an echo - return true; - } - else { - // we send a NOOP - return false; - } -} - -void tcpiiu::flushIfRecvProcessRequested ( - epicsGuard < epicsMutex > & guard ) -{ - if ( this->recvProcessPostponedFlush ) { - this->flushRequest ( guard ); - this->recvProcessPostponedFlush = false; - } -} - -bool tcpiiu::processIncoming ( - const epicsTime & currentTime, - callbackManager & mgr ) -{ - mgr.cbGuard.assertIdenticalMutex ( this->cbMutex ); - - while ( true ) { - - // - // fetch a complete message header - // - if ( ! this->msgHeaderAvailable ) { - if ( ! this->oldMsgHeaderAvailable ) { - this->oldMsgHeaderAvailable = - this->recvQue.popOldMsgHeader ( this->curMsg ); - if ( ! this->oldMsgHeaderAvailable ) { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->flushIfRecvProcessRequested ( guard ); - return true; - } - } - if ( this->curMsg.m_postsize == 0xffff ) { - static const unsigned annexSize = - sizeof ( this->curMsg.m_postsize ) + - sizeof ( this->curMsg.m_count ); - if ( this->recvQue.occupiedBytes () < annexSize ) { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->flushIfRecvProcessRequested ( guard ); - return true; - } - this->curMsg.m_postsize = this->recvQue.popUInt32 (); - this->curMsg.m_count = this->recvQue.popUInt32 (); - } - this->msgHeaderAvailable = true; -# ifdef DEBUG - epicsGuard < epicsMutex > guard ( this->mutex ); - debugPrintf ( - ( "%s Cmd=%3u Type=%3u Count=%8u Size=%8u", - this->pHostName ( guard ), - this->curMsg.m_cmmd, - this->curMsg.m_dataType, - this->curMsg.m_count, - this->curMsg.m_postsize) ); - debugPrintf ( - ( " Avail=%8u Cid=%8u\n", - this->curMsg.m_available, - this->curMsg.m_cid) ); -# endif - } - - // check for 8 byte aligned protocol - if ( this->curMsg.m_postsize & 0x7 ) { - this->printFormated ( mgr.cbGuard, - "CAC: server sent missaligned payload 0x%x\n", - this->curMsg.m_postsize ); - return false; - } - - // - // make sure we have a large enough message body cache - // - if ( this->curMsg.m_postsize > this->curDataMax ) { - assert (this->curMsg.m_postsize > MAX_TCP); - - char * newbuf = NULL; - arrayElementCount newsize; - - if ( !this->cacRef.tcpLargeRecvBufFreeList ) { - // round size up to multiple of 4K - newsize = ((this->curMsg.m_postsize-1)|0xfff)+1; - - if ( this->curDataMax <= MAX_TCP ) { - // small -> large - newbuf = (char*)malloc(newsize); - - } else { - // expand large to larger - newbuf = (char*)realloc(this->pCurData, newsize); - } - - } else if ( this->curMsg.m_postsize <= this->cacRef.maxRecvBytesTCP ) { - newbuf = (char*) freeListMalloc(this->cacRef.tcpLargeRecvBufFreeList); - newsize = this->cacRef.maxRecvBytesTCP; - - } - - if ( newbuf) { - if (this->curDataMax <= MAX_TCP) { - freeListFree(this->cacRef.tcpSmallRecvBufFreeList, this->pCurData ); - - } else if (this->cacRef.tcpLargeRecvBufFreeList) { - freeListFree(this->cacRef.tcpLargeRecvBufFreeList, this->pCurData ); - - } else { - // called realloc() - } - this->pCurData = newbuf; - this->curDataMax = newsize; - - } else { - this->printFormated ( mgr.cbGuard, - "CAC: not enough memory for message body cache (ignoring response message)\n"); - } - } - - if ( this->curMsg.m_postsize <= this->curDataMax ) { - if ( this->curMsg.m_postsize > 0u ) { - this->curDataBytes += this->recvQue.copyOutBytes ( - &this->pCurData[this->curDataBytes], - this->curMsg.m_postsize - this->curDataBytes ); - if ( this->curDataBytes < this->curMsg.m_postsize ) { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->flushIfRecvProcessRequested ( guard ); - return true; - } - } - bool msgOK = this->cacRef.executeResponse ( mgr, *this, - currentTime, this->curMsg, this->pCurData ); - if ( ! msgOK ) { - return false; - } - } - else { - static bool once = false; - if ( ! once ) { - this->printFormated ( mgr.cbGuard, - "CAC: response with payload size=%u > EPICS_CA_MAX_ARRAY_BYTES ignored\n", - this->curMsg.m_postsize ); - once = true; - } - this->curDataBytes += this->recvQue.removeBytes ( - this->curMsg.m_postsize - this->curDataBytes ); - if ( this->curDataBytes < this->curMsg.m_postsize ) { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->flushIfRecvProcessRequested ( guard ); - return true; - } - } - - this->oldMsgHeaderAvailable = false; - this->msgHeaderAvailable = false; - this->curDataBytes = 0u; - } -} - -void tcpiiu::hostNameSetRequest ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( ! CA_V41 ( this->minorProtocolVersion ) ) { - return; - } - - const char * pName = this->cacRef.pLocalHostName (); - unsigned size = strlen ( pName ) + 1u; - unsigned postSize = CA_MESSAGE_ALIGN ( size ); - assert ( postSize < 0xffff ); - - if ( this->sendQue.flushEarlyThreshold ( postSize + 16u ) ) { - this->flushRequest ( guard ); - } - - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - CA_PROTO_HOST_NAME, postSize, - 0u, 0u, 0u, 0u, - CA_V49 ( this->minorProtocolVersion ) ); - this->sendQue.pushString ( pName, size ); - this->sendQue.pushString ( cacNillBytes, postSize - size ); - minder.commit (); -} - -/* - * tcpiiu::userNameSetRequest () - */ -void tcpiiu::userNameSetRequest ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( ! CA_V41 ( this->minorProtocolVersion ) ) { - return; - } - - const char *pName = this->cacRef.userNamePointer (); - unsigned size = strlen ( pName ) + 1u; - unsigned postSize = CA_MESSAGE_ALIGN ( size ); - assert ( postSize < 0xffff ); - - if ( this->sendQue.flushEarlyThreshold ( postSize + 16u ) ) { - this->flushRequest ( guard ); - } - - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - CA_PROTO_CLIENT_NAME, postSize, - 0u, 0u, 0u, 0u, - CA_V49 ( this->minorProtocolVersion ) ); - this->sendQue.pushString ( pName, size ); - this->sendQue.pushString ( cacNillBytes, postSize - size ); - minder.commit (); -} - -void tcpiiu::disableFlowControlRequest ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( this->sendQue.flushEarlyThreshold ( 16u ) ) { - this->flushRequest ( guard ); - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - CA_PROTO_EVENTS_ON, 0u, - 0u, 0u, 0u, 0u, - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -void tcpiiu::enableFlowControlRequest ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( this->sendQue.flushEarlyThreshold ( 16u ) ) { - this->flushRequest ( guard ); - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - CA_PROTO_EVENTS_OFF, 0u, - 0u, 0u, 0u, 0u, - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -void tcpiiu::versionMessage ( epicsGuard < epicsMutex > & guard, - const cacChannel::priLev & priority ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - assert ( priority <= 0xffff ); - - if ( this->sendQue.flushEarlyThreshold ( 16u ) ) { - this->flushRequest ( guard ); - } - - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - CA_PROTO_VERSION, 0u, - static_cast < ca_uint16_t > ( priority ), - CA_MINOR_PROTOCOL_REVISION, 0u, 0u, - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -void tcpiiu::echoRequest ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - epicsUInt16 command = CA_PROTO_ECHO; - if ( ! CA_V43 ( this->minorProtocolVersion ) ) { - // we fake an echo to early server using a read sync - command = CA_PROTO_READ_SYNC; - } - - if ( this->sendQue.flushEarlyThreshold ( 16u ) ) { - this->flushRequest ( guard ); - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - command, 0u, - 0u, 0u, 0u, 0u, - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -void tcpiiu::writeRequest ( epicsGuard < epicsMutex > & guard, - nciu &chan, unsigned type, arrayElementCount nElem, const void *pValue ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( INVALID_DB_REQ ( type ) ) { - throw cacChannel::badType (); - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestWithPayLoad ( CA_PROTO_WRITE, - type, nElem, chan.getSID(guard), chan.getCID(guard), pValue, - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - - -void tcpiiu::writeNotifyRequest ( epicsGuard < epicsMutex > & guard, - nciu &chan, netWriteNotifyIO &io, unsigned type, - arrayElementCount nElem, const void *pValue ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( ! this->ca_v41_ok ( guard ) ) { - throw cacChannel::unsupportedByService(); - } - if ( INVALID_DB_REQ ( type ) ) { - throw cacChannel::badType (); - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestWithPayLoad ( CA_PROTO_WRITE_NOTIFY, - type, nElem, chan.getSID(guard), io.getId(), pValue, - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, - nciu & chan, netReadNotifyIO & io, - unsigned dataType, arrayElementCount nElem ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( INVALID_DB_REQ ( dataType ) ) { - throw cacChannel::badType (); - } - arrayElementCount maxBytes; - if ( CA_V49 ( this->minorProtocolVersion ) ) { - maxBytes = 0xfffffff0; - } - else { - maxBytes = MAX_TCP; - } - arrayElementCount maxElem = - ( maxBytes - dbr_size[dataType] ) / dbr_value_size[dataType]; - if ( nElem > maxElem ) { - throw cacChannel::msgBodyCacheTooSmall (); - } - if (nElem == 0 && !CA_V413(this->minorProtocolVersion)) - nElem = chan.getcount(); - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - CA_PROTO_READ_NOTIFY, 0u, - static_cast < ca_uint16_t > ( dataType ), - static_cast < ca_uint32_t > ( nElem ), - chan.getSID(guard), io.getId(), - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -void tcpiiu::createChannelRequest ( - nciu & chan, epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( this->state != iiucs_connected && - this->state != iiucs_connecting ) { - return; - } - - const char *pName; - unsigned nameLength; - ca_uint32_t identity; - if ( this->ca_v44_ok ( guard ) ) { - identity = chan.getCID ( guard ); - pName = chan.pName ( guard ); - nameLength = chan.nameLen ( guard ); - } - else { - identity = chan.getSID ( guard ); - pName = 0; - nameLength = 0u; - } - - unsigned postCnt = CA_MESSAGE_ALIGN ( nameLength ); - - if ( postCnt >= 0xffff ) { - throw cacChannel::unsupportedByService(); - } - - comQueSendMsgMinder minder ( this->sendQue, guard ); - // - // The available field is used (abused) - // here to communicate the minor version number - // starting with CA 4.1. - // - this->sendQue.insertRequestHeader ( - CA_PROTO_CREATE_CHAN, postCnt, - 0u, 0u, identity, CA_MINOR_PROTOCOL_REVISION, - CA_V49 ( this->minorProtocolVersion ) ); - if ( nameLength ) { - this->sendQue.pushString ( pName, nameLength ); - } - if ( postCnt > nameLength ) { - this->sendQue.pushString ( cacNillBytes, postCnt - nameLength ); - } - minder.commit (); -} - -void tcpiiu::clearChannelRequest ( epicsGuard < epicsMutex > & guard, - ca_uint32_t sid, ca_uint32_t cid ) -{ - guard.assertIdenticalMutex ( this->mutex ); - // there are situations where the circuit is disconnected, but - // the channel does not know this yet - if ( this->state != iiucs_connected ) { - return; - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - CA_PROTO_CLEAR_CHANNEL, 0u, - 0u, 0u, sid, cid, - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -// -// this routine return void because if this internally fails the best response -// is to try again the next time that we reconnect -// -void tcpiiu::subscriptionRequest ( - epicsGuard < epicsMutex > & guard, - nciu & chan, netSubscription & subscr ) -{ - guard.assertIdenticalMutex ( this->mutex ); - // there are situations where the circuit is disconnected, but - // the channel does not know this yet - if ( this->state != iiucs_connected && - this->state != iiucs_connecting ) { - return; - } - unsigned mask = subscr.getMask(guard); - if ( mask > 0xffff ) { - throw cacChannel::badEventSelection (); - } - arrayElementCount nElem = subscr.getCount ( - guard, CA_V413(this->minorProtocolVersion) ); - arrayElementCount maxBytes; - if ( CA_V49 ( this->minorProtocolVersion ) ) { - maxBytes = 0xfffffff0; - } - else { - maxBytes = MAX_TCP; - } - unsigned dataType = subscr.getType ( guard ); - // data type bounds checked when sunscription created - arrayElementCount maxElem = ( maxBytes - dbr_size[dataType] ) / dbr_value_size[dataType]; - if ( nElem > maxElem ) { - throw cacChannel::msgBodyCacheTooSmall (); - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - // nElement bounds checked above - this->sendQue.insertRequestHeader ( - CA_PROTO_EVENT_ADD, 16u, - static_cast < ca_uint16_t > ( dataType ), - static_cast < ca_uint32_t > ( nElem ), - chan.getSID(guard), subscr.getId(), - CA_V49 ( this->minorProtocolVersion ) ); - - // extension - this->sendQue.pushFloat32 ( 0.0f ); // m_lval - this->sendQue.pushFloat32 ( 0.0f ); // m_hval - this->sendQue.pushFloat32 ( 0.0f ); // m_toval - this->sendQue.pushUInt16 ( static_cast < ca_uint16_t > ( mask ) ); // m_mask - this->sendQue.pushUInt16 ( 0u ); // m_pad - minder.commit (); -} - -// -// this routine return void because if this internally fails the best response -// is to try again the next time that we reconnect -// -void tcpiiu::subscriptionUpdateRequest ( - epicsGuard < epicsMutex > & guard, - nciu & chan, netSubscription & subscr ) -{ - guard.assertIdenticalMutex ( this->mutex ); - // there are situations where the circuit is disconnected, but - // the channel does not know this yet - if ( this->state != iiucs_connected ) { - return; - } - arrayElementCount nElem = subscr.getCount ( - guard, CA_V413(this->minorProtocolVersion) ); - arrayElementCount maxBytes; - if ( CA_V49 ( this->minorProtocolVersion ) ) { - maxBytes = 0xfffffff0; - } - else { - maxBytes = MAX_TCP; - } - unsigned dataType = subscr.getType ( guard ); - // data type bounds checked when subscription constructed - arrayElementCount maxElem = ( maxBytes - dbr_size[dataType] ) / dbr_value_size[dataType]; - if ( nElem > maxElem ) { - throw cacChannel::msgBodyCacheTooSmall (); - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - // nElem boounds checked above - this->sendQue.insertRequestHeader ( - CA_PROTO_READ_NOTIFY, 0u, - static_cast < ca_uint16_t > ( dataType ), - static_cast < ca_uint32_t > ( nElem ), - chan.getSID (guard), subscr.getId (), - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -void tcpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard, - nciu & chan, netSubscription & subscr ) -{ - guard.assertIdenticalMutex ( this->mutex ); - // there are situations where the circuit is disconnected, but - // the channel does not know this yet - if ( this->state != iiucs_connected ) { - return; - } - comQueSendMsgMinder minder ( this->sendQue, guard ); - this->sendQue.insertRequestHeader ( - CA_PROTO_EVENT_CANCEL, 0u, - static_cast < ca_uint16_t > ( subscr.getType ( guard ) ), - static_cast < ca_uint16_t > ( subscr.getCount ( - guard, CA_V413(this->minorProtocolVersion) ) ), - chan.getSID(guard), subscr.getId(), - CA_V49 ( this->minorProtocolVersion ) ); - minder.commit (); -} - -bool tcpiiu::sendThreadFlush ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( this->sendQue.occupiedBytes() > 0 ) { - while ( comBuf * pBuf = this->sendQue.popNextComBufToSend () ) { - epicsTime current = epicsTime::getCurrent (); - - unsigned bytesToBeSent = pBuf->occupiedBytes (); - bool success = false; - { - // no lock while blocking to send - epicsGuardRelease < epicsMutex > unguard ( guard ); - success = pBuf->flushToWire ( *this, current ); - pBuf->~comBuf (); - this->comBufMemMgr.release ( pBuf ); - } - - if ( ! success ) { - while ( ( pBuf = this->sendQue.popNextComBufToSend () ) ) { - pBuf->~comBuf (); - this->comBufMemMgr.release ( pBuf ); - } - return false; - } - - // set it here with this odd order because we must have - // the lock and we must have already sent the bytes - this->unacknowledgedSendBytes += bytesToBeSent; - if ( this->unacknowledgedSendBytes > - this->socketLibrarySendBufferSize ) { - this->recvDog.sendBacklogProgressNotify ( guard ); - } - } - } - - this->earlyFlush = false; - if ( this->blockingForFlush ) { - this->flushBlockEvent.signal (); - } - - return true; -} - -void tcpiiu :: flush ( epicsGuard < epicsMutex > & guard ) -{ - this->flushRequest ( guard ); - // the process thread is not permitted to flush as this - // can result in a push / pull deadlock on the TCP pipe. - // Instead, the process thread scheduals the flush with the - // send thread which runs at a higher priority than the - // receive thread. The same applies to the UDP thread for - // locking hierarchy reasons. - if ( ! epicsThreadPrivateGet ( caClientCallbackThreadId ) ) { - // enable / disable of call back preemption must occur here - // because the tcpiiu might disconnect while waiting and its - // pointer to this cac might become invalid - assert ( this->blockingForFlush < UINT_MAX ); - this->blockingForFlush++; - while ( this->sendQue.flushBlockThreshold() ) { - - bool userRequestsCanBeAccepted = - this->state == iiucs_connected || - ( ! this->ca_v42_ok ( guard ) && - this->state == iiucs_connecting ); - // fail the users request if we have a disconnected - // or unresponsive circuit - if ( ! userRequestsCanBeAccepted || - this->unresponsiveCircuit ) { - this->decrementBlockingForFlushCount ( guard ); - throw cacChannel::notConnected (); - } - - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->flushBlockEvent.wait ( 30.0 ); - } - this->decrementBlockingForFlushCount ( guard ); - } -} - -unsigned tcpiiu::requestMessageBytesPending ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); -#if 0 - if ( ! this->earlyFlush && this->sendQue.flushEarlyThreshold(0u) ) { - this->earlyFlush = true; - this->sendThreadFlushEvent.signal (); - } -#endif - return sendQue.occupiedBytes (); -} - -void tcpiiu::decrementBlockingForFlushCount ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - assert ( this->blockingForFlush > 0u ); - this->blockingForFlush--; - if ( this->blockingForFlush > 0 ) { - this->flushBlockEvent.signal (); - } -} - -osiSockAddr tcpiiu::getNetworkAddress ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->address(); -} - -// not inline because its virtual -bool tcpiiu::ca_v42_ok ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - return CA_V42 ( this->minorProtocolVersion ); -} - -void tcpiiu::requestRecvProcessPostponedFlush ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->recvProcessPostponedFlush = true; -} - -unsigned tcpiiu::getHostName ( - epicsGuard < epicsMutex > & guard, - char * pBuf, unsigned bufLength ) const throw () -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->hostNameCacheInstance.getName ( pBuf, bufLength ); -} - -const char * tcpiiu::pHostName ( - epicsGuard < epicsMutex > & guard ) const throw () -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->hostNameCacheInstance.pointer (); -} - -void tcpiiu::disconnectAllChannels ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, - class udpiiu & discIIU ) -{ - cbGuard.assertIdenticalMutex ( this->cbMutex ); - guard.assertIdenticalMutex ( this->mutex ); - - while ( nciu * pChan = this->createReqPend.get () ) { - discIIU.installDisconnectedChannel ( guard, *pChan ); - } - - while ( nciu * pChan = this->createRespPend.get () ) { - // we dont yet know the server's id so we cant - // send a channel delete request and will instead - // trust that the server can do the proper cleanup - // when the circuit disconnects - discIIU.installDisconnectedChannel ( guard, *pChan ); - } - - while ( nciu * pChan = this->v42ConnCallbackPend.get () ) { - this->clearChannelRequest ( guard, - pChan->getSID(guard), pChan->getCID(guard) ); - discIIU.installDisconnectedChannel ( guard, *pChan ); - } - - while ( nciu * pChan = this->subscripReqPend.get () ) { - pChan->disconnectAllIO ( cbGuard, guard ); - this->clearChannelRequest ( guard, - pChan->getSID(guard), pChan->getCID(guard) ); - discIIU.installDisconnectedChannel ( guard, *pChan ); - pChan->unresponsiveCircuitNotify ( cbGuard, guard ); - } - - while ( nciu * pChan = this->connectedList.get () ) { - pChan->disconnectAllIO ( cbGuard, guard ); - this->clearChannelRequest ( guard, - pChan->getSID(guard), pChan->getCID(guard) ); - discIIU.installDisconnectedChannel ( guard, *pChan ); - pChan->unresponsiveCircuitNotify ( cbGuard, guard ); - } - - while ( nciu * pChan = this->unrespCircuit.get () ) { - // if we know that the circuit is unresponsive - // then we dont send a channel delete request and - // will instead trust that the server can do the - // proper cleanup when the circuit disconnects - pChan->disconnectAllIO ( cbGuard, guard ); - discIIU.installDisconnectedChannel ( guard, *pChan ); - } - - while ( nciu * pChan = this->subscripUpdateReqPend.get () ) { - pChan->disconnectAllIO ( cbGuard, guard ); - this->clearChannelRequest ( guard, - pChan->getSID(guard), pChan->getCID(guard) ); - discIIU.installDisconnectedChannel ( guard, *pChan ); - pChan->unresponsiveCircuitNotify ( cbGuard, guard ); - } - - this->channelCountTot = 0u; - this->initiateCleanShutdown ( guard ); -} - -void tcpiiu::unlinkAllChannels ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - cbGuard.assertIdenticalMutex ( this->cbMutex ); - guard.assertIdenticalMutex ( this->mutex ); - - while ( nciu * pChan = this->createReqPend.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - pChan->serviceShutdownNotify ( cbGuard, guard ); - } - - while ( nciu * pChan = this->createRespPend.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - // we dont yet know the server's id so we cant - // send a channel delete request and will instead - // trust that the server can do the proper cleanup - // when the circuit disconnects - pChan->serviceShutdownNotify ( cbGuard, guard ); - } - - while ( nciu * pChan = this->v42ConnCallbackPend.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - this->clearChannelRequest ( guard, - pChan->getSID(guard), pChan->getCID(guard) ); - pChan->serviceShutdownNotify ( cbGuard, guard ); - } - - while ( nciu * pChan = this->subscripReqPend.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - pChan->disconnectAllIO ( cbGuard, guard ); - this->clearChannelRequest ( guard, - pChan->getSID(guard), pChan->getCID(guard) ); - pChan->serviceShutdownNotify ( cbGuard, guard ); - } - - while ( nciu * pChan = this->connectedList.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - pChan->disconnectAllIO ( cbGuard, guard ); - this->clearChannelRequest ( guard, - pChan->getSID(guard), pChan->getCID(guard) ); - pChan->serviceShutdownNotify ( cbGuard, guard ); - } - - while ( nciu * pChan = this->unrespCircuit.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - pChan->disconnectAllIO ( cbGuard, guard ); - // if we know that the circuit is unresponsive - // then we dont send a channel delete request and - // will instead trust that the server can do the - // proper cleanup when the circuit disconnects - pChan->serviceShutdownNotify ( cbGuard, guard ); - } - - while ( nciu * pChan = this->subscripUpdateReqPend.get () ) { - pChan->channelNode::listMember = - channelNode::cs_none; - pChan->disconnectAllIO ( cbGuard, guard ); - this->clearChannelRequest ( guard, - pChan->getSID(guard), pChan->getCID(guard) ); - pChan->serviceShutdownNotify ( cbGuard, guard ); - } - - this->channelCountTot = 0u; - this->initiateCleanShutdown ( guard ); -} - -void tcpiiu::installChannel ( - epicsGuard < epicsMutex > & guard, - nciu & chan, unsigned sidIn, - ca_uint16_t typeIn, arrayElementCount countIn ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - this->createReqPend.add ( chan ); - this->channelCountTot++; - chan.channelNode::listMember = channelNode::cs_createReqPend; - chan.searchReplySetUp ( *this, sidIn, typeIn, countIn, guard ); - // The tcp send thread runs at apriority below the udp thread - // so that this will not send small packets - this->sendThreadFlushEvent.signal (); -} - -bool tcpiiu :: connectNotify ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - bool wasExpected = false; - // this improves robustness in the face of a server sending - // protocol that does not match its declared protocol revision - if ( chan.channelNode::listMember == channelNode::cs_createRespPend ) { - this->createRespPend.remove ( chan ); - this->subscripReqPend.add ( chan ); - chan.channelNode::listMember = channelNode::cs_subscripReqPend; - wasExpected = true; - } - else if ( chan.channelNode::listMember == channelNode::cs_v42ConnCallbackPend ) { - this->v42ConnCallbackPend.remove ( chan ); - this->subscripReqPend.add ( chan ); - chan.channelNode::listMember = channelNode::cs_subscripReqPend; - wasExpected = true; - } - // the TCP send thread is awakened by its receive thread whenever the receive thread - // is about to block if this->subscripReqPend has items in it - return wasExpected; -} - -void tcpiiu::uninstallChan ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - switch ( chan.channelNode::listMember ) { - case channelNode::cs_createReqPend: - this->createReqPend.remove ( chan ); - break; - case channelNode::cs_createRespPend: - this->createRespPend.remove ( chan ); - break; - case channelNode::cs_v42ConnCallbackPend: - this->v42ConnCallbackPend.remove ( chan ); - break; - case channelNode::cs_subscripReqPend: - this->subscripReqPend.remove ( chan ); - break; - case channelNode::cs_connected: - this->connectedList.remove ( chan ); - break; - case channelNode::cs_unrespCircuit: - this->unrespCircuit.remove ( chan ); - break; - case channelNode::cs_subscripUpdateReqPend: - this->subscripUpdateReqPend.remove ( chan ); - break; - default: - errlogPrintf ( - "cac: attempt to uninstall channel from tcp iiu, but it inst installed there?" ); - } - chan.channelNode::listMember = channelNode::cs_none; - this->channelCountTot--; - if ( this->channelCountTot == 0 && ! this->isNameService() ) { - this->initiateCleanShutdown ( guard ); - } -} - -int tcpiiu :: printFormated ( - epicsGuard < epicsMutex > & cbGuard, - const char *pformat, ... ) -{ - cbGuard.assertIdenticalMutex ( this->cbMutex ); - - va_list theArgs; - int status; - - va_start ( theArgs, pformat ); - - status = this->cacRef.varArgsPrintFormated ( cbGuard, pformat, theArgs ); - - va_end ( theArgs ); - - return status; -} - -void tcpiiu::flushRequest ( epicsGuard < epicsMutex > & ) -{ - if ( this->sendQue.occupiedBytes () > 0 ) { - this->sendThreadFlushEvent.signal (); - } -} - -bool tcpiiu::bytesArePendingInOS () const -{ -#if 0 - FD_SET readBits; - FD_ZERO ( & readBits ); - FD_SET ( this->sock, & readBits ); - struct timeval tmo; - tmo.tv_sec = 0; - tmo.tv_usec = 0; - int status = select ( this->sock + 1, & readBits, NULL, NULL, & tmo ); - if ( status > 0 ) { - if ( FD_ISSET ( this->sock, & readBits ) ) { - return true; - } - } - return false; -#else - osiSockIoctl_t bytesPending = 0; /* shut up purifys yapping */ - int status = socket_ioctl ( this->sock, - FIONREAD, & bytesPending ); - if ( status >= 0 ) { - if ( bytesPending > 0 ) { - return true; - } - } - return false; -#endif -} - -double tcpiiu::receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const -{ - return this->recvDog.delay (); -} - -/* - * Certain OS, such as HPUX, do not unblock a socket system call - * when another thread asynchronously calls both shutdown() and - * close(). To solve this problem we need to employ OS specific - * mechanisms. - */ -void tcpRecvThread::interruptSocketRecv () -{ - epicsThreadId threadId = this->thread.getId (); - if ( threadId ) { - epicsSignalRaiseSigAlarm ( threadId ); - } -} -void tcpSendThread::interruptSocketSend () -{ - epicsThreadId threadId = this->thread.getId (); - if ( threadId ) { - epicsSignalRaiseSigAlarm ( threadId ); - } -} - -void tcpiiu::operator delete ( void * /* pCadaver */ ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about " - "placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -unsigned tcpiiu::channelCount ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->channelCountTot; -} - -void tcpiiu::uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > & guard, nciu & chan, - const class epicsTime & currentTime ) -{ - netiiu::uninstallChanDueToSuccessfulSearchResponse ( - guard, chan, currentTime ); -} - -bool tcpiiu::searchMsg ( - epicsGuard < epicsMutex > & guard, ca_uint32_t id, - const char * pName, unsigned nameLength ) -{ - return netiiu::searchMsg ( - guard, id, pName, nameLength ); -} - -SearchDestTCP :: SearchDestTCP ( - cac & cacIn, const osiSockAddr & addrIn ) : - _ptcpiiu ( NULL ), - _cac ( cacIn ), - _addr ( addrIn ), - _active ( false ) -{ -} - -void SearchDestTCP :: disable () -{ - _active = false; - _ptcpiiu = NULL; -} - -void SearchDestTCP :: enable () -{ - _active = true; -} - -void SearchDestTCP :: searchRequest ( - epicsGuard < epicsMutex > & guard, - const char * pBuf, size_t len ) -{ - // restart circuit if it was shut down - if ( ! _ptcpiiu ) { - tcpiiu * piiu = NULL; - bool newIIU = _cac.findOrCreateVirtCircuit ( - guard, _addr, cacChannel::priorityDefault, - piiu, CA_UKN_MINOR_VERSION, this ); - if ( newIIU ) { - piiu->start ( guard ); - } - _ptcpiiu = piiu; - } - - // does this server support TCP-based name resolution? - if ( CA_V412 ( _ptcpiiu->minorProtocolVersion ) ) { - guard.assertIdenticalMutex ( _ptcpiiu->mutex ); - assert ( CA_MESSAGE_ALIGN ( len ) == len ); - comQueSendMsgMinder minder ( _ptcpiiu->sendQue, guard ); - _ptcpiiu->sendQue.pushString ( pBuf, len ); - minder.commit (); - _ptcpiiu->flushRequest ( guard ); - } -} - -void SearchDestTCP :: show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - :: printf ( "tcpiiu :: SearchDestTCP\n" ); -} - -void tcpiiu :: versionRespNotify ( const caHdrLargeArray & msg ) -{ - this->minorProtocolVersion = msg.m_count; -} - -void tcpiiu :: searchRespNotify ( - const epicsTime & currentTime, const caHdrLargeArray & msg ) -{ - /* - * the type field is abused to carry the port number - * so that we can have multiple servers on one host - */ - osiSockAddr serverAddr; - if ( msg.m_cid != INADDR_BROADCAST ) { - serverAddr.ia.sin_family = AF_INET; - serverAddr.ia.sin_addr.s_addr = htonl ( msg.m_cid ); - serverAddr.ia.sin_port = htons ( msg.m_dataType ); - } - else { - serverAddr = this->address (); - } - cacRef.transferChanToVirtCircuit - ( msg.m_available, msg.m_cid, 0xffff, - 0, minorProtocolVersion, serverAddr, currentTime ); -} diff --git a/src/ca/client/test/ca_test.c b/src/ca/client/test/ca_test.c deleted file mode 100644 index 998536843..000000000 --- a/src/ca/client/test/ca_test.c +++ /dev/null @@ -1,323 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - * Date: 07-01-91 - */ - -/* - * ANSI - */ -#include -#include -#include - -#include "cadef.h" -#include "epicsTime.h" - -int ca_test(char *pname, char *pvalue); -static int cagft(char *pname); -static void printit(struct event_handler_args args); -static int capft(char *pname, char *pvalue); -static void verify_value(chid chan_id, chtype type); - -static unsigned long outstanding; - - -/* - * ca_test - * - * find channel, write a value if supplied, and - * read back the current value - * - */ -int ca_test( -char *pname, -char *pvalue -) -{ - int status; - if(pvalue){ - status = capft(pname,pvalue); - } - else{ - status = cagft(pname); - } - ca_task_exit(); - return status; -} - - - -/* - * cagft() - * - * ca get field test - * - * test ca get over the range of CA data types - */ -static int cagft(char *pname) -{ - const unsigned maxTries = 1000ul; - unsigned ntries = 0u; - chid chan_id; - int status; - int i; - - /* - * convert name to chan id - */ - status = ca_search(pname, &chan_id); - SEVCHK(status,NULL); - status = ca_pend_io(5.0); - if(status != ECA_NORMAL){ - SEVCHK(ca_clear_channel(chan_id),NULL); - printf("Not Found %s\n", pname); - return -1; - } - - printf("name:\t%s\n", - ca_name(chan_id)); - printf("native type:\t%s\n", - dbr_type_to_text(ca_field_type(chan_id))); - printf("native count:\t%lu\n", - ca_element_count(chan_id)); - - - /* - * fetch as each type - */ - for(i=0; i<=LAST_BUFFER_TYPE; i++){ - if(ca_field_type(chan_id)==DBR_STRING) { - if( (i!=DBR_STRING) - && (i!=DBR_STS_STRING) - && (i!=DBR_TIME_STRING) - && (i!=DBR_GR_STRING) - && (i!=DBR_CTRL_STRING)) { - continue; - } - } - /* ignore write only types */ - if ( - i == DBR_PUT_ACKT || - i == DBR_PUT_ACKS ) { - continue; - } - - status = ca_array_get_callback( - i, - ca_element_count(chan_id), - chan_id, - printit, - NULL); - SEVCHK(status, NULL); - - outstanding++; - } - - /* - * wait for the operation to complete - * before returning - */ - while ( ntries < maxTries ) { - unsigned long oldOut; - - oldOut = outstanding; - ca_pend_event ( 0.05 ); - - if ( ! outstanding ) { - SEVCHK ( ca_clear_channel ( chan_id ), NULL ); - printf ( "\n\n" ); - return 0; - } - - if ( outstanding == oldOut ) { - ntries++; - } - } - - SEVCHK ( ca_clear_channel ( chan_id ), NULL ); - return -1; -} - - -/* - * PRINTIT() - */ -static void printit ( struct event_handler_args args ) -{ - if ( args.status == ECA_NORMAL ) { - ca_dump_dbr ( args.type, args.count, args.dbr ); - } - else { - printf ( "%s\t%s\n", dbr_text[args.type], ca_message(args.status) ); - } - - outstanding--; -} - -/* - * capft - * - * test ca_put() over a range of data types - * - */ -static int capft( -char *pname, -char *pvalue -) -{ - dbr_short_t shortvalue; - dbr_long_t longvalue; - dbr_float_t floatvalue; - dbr_char_t charvalue; - dbr_double_t doublevalue; - unsigned long ntries = 10ul; - int status; - chid chan_id; - - if (((*pname < ' ') || (*pname > 'z')) - || ((*pvalue < ' ') || (*pvalue > 'z'))){ - printf("\nusage \"pv name\",\"value\"\n"); - return -1; - } - - /* - * convert name to chan id - */ - status = ca_search(pname, &chan_id); - SEVCHK(status,NULL); - status = ca_pend_io(5.0); - if(status != ECA_NORMAL){ - SEVCHK(ca_clear_channel(chan_id),NULL); - printf("Not Found %s\n", pname); - return -1; - } - - printf("name:\t%s\n", ca_name(chan_id)); - printf("native type:\t%d\n", ca_field_type(chan_id)); - printf("native count:\t%lu\n", ca_element_count(chan_id)); - - /* - * string value ca_put - */ - status = ca_put( - DBR_STRING, - chan_id, - pvalue); - SEVCHK(status, NULL); - verify_value(chan_id, DBR_STRING); - - if(ca_field_type(chan_id)==0)goto skip_rest; - - if(sscanf(pvalue,"%hd",&shortvalue)==1) { - /* - * short integer ca_put - */ - status = ca_put( - DBR_SHORT, - chan_id, - &shortvalue); - SEVCHK(status, NULL); - verify_value(chan_id, DBR_SHORT); - status = ca_put( - DBR_ENUM, - chan_id, - &shortvalue); - SEVCHK(status, NULL); - verify_value(chan_id, DBR_ENUM); - charvalue=(dbr_char_t)shortvalue; - status = ca_put( - DBR_CHAR, - chan_id, - &charvalue); - SEVCHK(status, NULL); - verify_value(chan_id, DBR_CHAR); - } - if(sscanf(pvalue,"%d",&longvalue)==1) { - /* - * long integer ca_put - */ - status = ca_put( - DBR_LONG, - chan_id, - &longvalue); - SEVCHK(status, NULL); - verify_value(chan_id, DBR_LONG); - } - if(epicsScanFloat(pvalue, &floatvalue)==1) { - /* - * single precision float ca_put - */ - status = ca_put( - DBR_FLOAT, - chan_id, - &floatvalue); - SEVCHK(status, NULL); - verify_value(chan_id, DBR_FLOAT); - } - if(epicsScanDouble(pvalue, &doublevalue)==1) { - /* - * double precision float ca_put - */ - status = ca_put( - DBR_DOUBLE, - chan_id, - &doublevalue); - SEVCHK(status, NULL); - verify_value(chan_id, DBR_DOUBLE); - } - -skip_rest: - - /* - * wait for the operation to complete - * (outstabnding decrements to zero) - */ - while(ntries){ - ca_pend_event(1.0); - - if(!outstanding){ - SEVCHK(ca_clear_channel(chan_id),NULL); - printf("\n\n"); - return 0; - } - - ntries--; - } - - SEVCHK(ca_clear_channel(chan_id),NULL); - return -1; -} - - -/* - * VERIFY_VALUE - * - * initiate print out the values in a database access interface structure - */ -static void verify_value(chid chan_id, chtype type) -{ - int status; - - /* - * issue a get which calls back `printit' - * upon completion - */ - status = ca_array_get_callback( - type, - ca_element_count(chan_id), - chan_id, - printit, - NULL); - SEVCHK(status, NULL); - - outstanding++; -} diff --git a/src/ca/client/test/ca_test.h b/src/ca/client/test/ca_test.h deleted file mode 100644 index 076f8936a..000000000 --- a/src/ca/client/test/ca_test.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - * Date: 21JAN2000 - */ - -#ifdef __cplusplus -extern "C" { -#endif - -int ca_test(char *pname, char *pvalue); - -#ifdef __cplusplus -} -#endif diff --git a/src/ca/client/test/ca_test_main.c b/src/ca/client/test/ca_test_main.c deleted file mode 100644 index 85fd7ea19..000000000 --- a/src/ca/client/test/ca_test_main.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - * Date: 21JAN2000 - */ -#include -#include - -#include "ca_test.h" -#include "dbDefs.h" - -int main(int argc, char **argv) -{ - - /* - * print error and return if arguments are invalid - */ - if(argc < 2 || argc > 3){ - printf("usage: %s [optional value to be written]\n", argv[0]); - printf("the following arguments were received\n"); - while(argc>0) { - printf("%s\n",argv[0]); - argv++; argc--; - } - return -1; - } - - - /* - * check for supplied value - */ - if(argc == 2){ - return ca_test(argv[1], NULL); - } - else if(argc == 3){ - char *pt; - - /* strip leading and trailing quotes*/ - if(argv[2][1]=='"') argv[2]++; - if( (pt=strchr(argv[2],'"')) ) *pt = 0; - return ca_test(argv[1], argv[2]); - } - else{ - return -1; - } - -} diff --git a/src/ca/client/test_event.cpp b/src/ca/client/test_event.cpp deleted file mode 100644 index 8b5a8bb54..000000000 --- a/src/ca/client/test_event.cpp +++ /dev/null @@ -1,588 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * T E S T _ E V E N T . C - * Author: Jeffrey O. Hill - * simple stub for testing monitors - */ - -#include "epicsStdioRedirect.h" - -#define epicsExportSharedSymbols -#include "cadef.h" - -extern "C" void epicsShareAPI ca_test_event ( struct event_handler_args args ) -{ - chtype nativeType = ca_field_type ( args.chid ); - const char * pNativeTypeName = ""; - if ( VALID_DB_REQ ( nativeType ) ) { - pNativeTypeName = dbr_text[nativeType]; - } - else { - if ( nativeType == TYPENOTCONN ) { - pNativeTypeName = ""; - } - } - - printf ( "ca_test_event() for channel \"%s\" with native type %s\n", - ca_name(args.chid), pNativeTypeName ); - - if ( ! ( CA_M_SUCCESS & args.status ) ) { - printf ( "Invalid CA status \"%s\"\n", ca_message ( args.status ) ); - return; - } - - if ( args.dbr ) { - ca_dump_dbr ( args.type, args.count, args.dbr ); - } -} - -/* - * ca_dump_dbr() - * dump the specified dbr type to stdout - */ -extern "C" void epicsShareAPI ca_dump_dbr ( - chtype type, unsigned count, const void * pbuffer ) -{ - unsigned i; - char tsString[50]; - - if ( INVALID_DB_REQ ( type ) ) { - printf ( "bad DBR type %ld\n", type ); - } - - printf ( "%s\t", dbr_text[type] ); - - switch ( type ) { - case DBR_STRING: - { - dbr_string_t *pString = (dbr_string_t *) pbuffer; - - for(i=0; istatus,pvalue->severity); - printf("\tValue: %s",pvalue->value); - break; - } - case DBR_STS_ENUM: - { - struct dbr_sts_enum *pvalue - = (struct dbr_sts_enum *)pbuffer; - dbr_enum_t *pEnum = &pvalue->value; - printf("%2d %2d",pvalue->status,pvalue->severity); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pEnum++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%u ",*pEnum); - } - break; - } - case DBR_STS_SHORT: - { - struct dbr_sts_short *pvalue - = (struct dbr_sts_short *)pbuffer; - dbr_short_t *pshort = &pvalue->value; - printf("%2d %2d",pvalue->status,pvalue->severity); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pshort++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%u ",*pshort); - } - break; - } - case DBR_STS_FLOAT: - { - struct dbr_sts_float *pvalue - = (struct dbr_sts_float *)pbuffer; - dbr_float_t *pfloat = &pvalue->value; - printf("%2d %2d",pvalue->status,pvalue->severity); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pfloat++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%6.4f ",*pfloat); - } - break; - } - case DBR_STS_CHAR: - { - struct dbr_sts_char *pvalue - = (struct dbr_sts_char *)pbuffer; - dbr_char_t *pchar = &pvalue->value; - - printf("%2d %2d",pvalue->status,pvalue->severity); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pchar++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%u ", *pchar); - } - break; - } - case DBR_STS_LONG: - { - struct dbr_sts_long *pvalue - = (struct dbr_sts_long *)pbuffer; - dbr_long_t *plong = &pvalue->value; - printf("%2d %2d",pvalue->status,pvalue->severity); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,plong++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",*plong); - } - break; - } - case DBR_STS_DOUBLE: - { - struct dbr_sts_double *pvalue - = (struct dbr_sts_double *)pbuffer; - dbr_double_t *pdouble = &pvalue->value; - printf("%2d %2d",pvalue->status,pvalue->severity); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pdouble++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%6.4f ",(float)(*pdouble)); - } - break; - } - case DBR_TIME_STRING: - { - struct dbr_time_string *pvalue - = (struct dbr_time_string *) pbuffer; - - epicsTimeToStrftime(tsString,sizeof(tsString), - "%Y/%m/%d %H:%M:%S.%06f",&pvalue->stamp); - printf("%2d %2d",pvalue->status,pvalue->severity); - printf("\tTimeStamp: %s",tsString); - printf("\tValue: "); - printf("%s",pvalue->value); - break; - } - case DBR_TIME_ENUM: - { - struct dbr_time_enum *pvalue - = (struct dbr_time_enum *)pbuffer; - dbr_enum_t *pshort = &pvalue->value; - - epicsTimeToStrftime(tsString,sizeof(tsString), - "%Y/%m/%d %H:%M:%S.%06f",&pvalue->stamp); - printf("%2d %2d",pvalue->status,pvalue->severity); - printf("\tTimeStamp: %s",tsString); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pshort++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",*pshort); - } - break; - } - case DBR_TIME_SHORT: - { - struct dbr_time_short *pvalue - = (struct dbr_time_short *)pbuffer; - dbr_short_t *pshort = &pvalue->value; - epicsTimeToStrftime(tsString,sizeof(tsString), - "%Y/%m/%d %H:%M:%S.%06f",&pvalue->stamp); - printf("%2d %2d", - pvalue->status, - pvalue->severity); - printf("\tTimeStamp: %s",tsString); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pshort++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",*pshort); - } - break; - } - case DBR_TIME_FLOAT: - { - struct dbr_time_float *pvalue - = (struct dbr_time_float *)pbuffer; - dbr_float_t *pfloat = &pvalue->value; - - epicsTimeToStrftime(tsString,sizeof(tsString), - "%Y/%m/%d %H:%M:%S.%06f",&pvalue->stamp); - printf("%2d %2d",pvalue->status,pvalue->severity); - printf("\tTimeStamp: %s",tsString); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pfloat++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%6.4f ",*pfloat); - } - break; - } - case DBR_TIME_CHAR: - { - struct dbr_time_char *pvalue - = (struct dbr_time_char *)pbuffer; - dbr_char_t *pchar = &pvalue->value; - - epicsTimeToStrftime(tsString,sizeof(tsString), - "%Y/%m/%d %H:%M:%S.%06f",&pvalue->stamp); - printf("%2d %2d",pvalue->status,pvalue->severity); - printf("\tTimeStamp: %s",tsString); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pchar++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",(short)(*pchar)); - } - break; - } - case DBR_TIME_LONG: - { - struct dbr_time_long *pvalue - = (struct dbr_time_long *)pbuffer; - dbr_long_t *plong = &pvalue->value; - - epicsTimeToStrftime(tsString,sizeof(tsString), - "%Y/%m/%d %H:%M:%S.%06f",&pvalue->stamp); - printf("%2d %2d",pvalue->status,pvalue->severity); - printf("\tTimeStamp: %s",tsString); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,plong++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",*plong); - } - break; - } - case DBR_TIME_DOUBLE: - { - struct dbr_time_double *pvalue - = (struct dbr_time_double *)pbuffer; - dbr_double_t *pdouble = &pvalue->value; - - epicsTimeToStrftime(tsString,sizeof(tsString), - "%Y/%m/%d %H:%M:%S.%06f",&pvalue->stamp); - printf("%2d %2d",pvalue->status,pvalue->severity); - printf("\tTimeStamp: %s",tsString); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pdouble++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%6.4f ",(float)(*pdouble)); - } - break; - } - case DBR_GR_SHORT: - { - struct dbr_gr_short *pvalue - = (struct dbr_gr_short *)pbuffer; - dbr_short_t *pshort = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf("\n\t%8d %8d %8d %8d %8d %8d", - pvalue->upper_disp_limit,pvalue->lower_disp_limit, - pvalue->upper_alarm_limit,pvalue->upper_warning_limit, - pvalue->lower_warning_limit,pvalue->lower_alarm_limit); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pshort++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",*pshort); - } - break; - } - case DBR_GR_FLOAT: - { - struct dbr_gr_float *pvalue - = (struct dbr_gr_float *)pbuffer; - dbr_float_t *pfloat = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf(" %3d\n\t%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f", - pvalue->precision, - pvalue->upper_disp_limit,pvalue->lower_disp_limit, - pvalue->upper_alarm_limit,pvalue->upper_warning_limit, - pvalue->lower_warning_limit,pvalue->lower_alarm_limit); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pfloat++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%6.4f ",*pfloat); - } - break; - } - case DBR_GR_ENUM: - { - struct dbr_gr_enum *pvalue - = (struct dbr_gr_enum *)pbuffer; - printf("%2d %2d",pvalue->status, - pvalue->severity); - printf("\tValue: %d",pvalue->value); - if(pvalue->no_str>0) { - printf("\n\t%3d",pvalue->no_str); - for (i = 0; i < (unsigned) pvalue->no_str; i++) - printf("\n\t%.26s",pvalue->strs[i]); - } - break; - } - case DBR_CTRL_ENUM: - { - struct dbr_ctrl_enum *pvalue - = (struct dbr_ctrl_enum *)pbuffer; - printf("%2d %2d",pvalue->status, - pvalue->severity); - printf("\tValue: %d",pvalue->value); - if(pvalue->no_str>0) { - printf("\n\t%3d",pvalue->no_str); - for (i = 0; i < (unsigned) pvalue->no_str; i++) - printf("\n\t%.26s",pvalue->strs[i]); - } - break; - } - case DBR_GR_CHAR: - { - struct dbr_gr_char *pvalue - = (struct dbr_gr_char *)pbuffer; - dbr_char_t *pchar = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf("\n\t%8d %8d %8d %8d %8d %8d", - pvalue->upper_disp_limit,pvalue->lower_disp_limit, - pvalue->upper_alarm_limit,pvalue->upper_warning_limit, - pvalue->lower_warning_limit,pvalue->lower_alarm_limit); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pchar++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%u ",*pchar); - } - break; - } - case DBR_GR_LONG: - { - struct dbr_gr_long *pvalue - = (struct dbr_gr_long *)pbuffer; - dbr_long_t *plong = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf("\n\t%8d %8d %8d %8d %8d %8d", - pvalue->upper_disp_limit,pvalue->lower_disp_limit, - pvalue->upper_alarm_limit,pvalue->upper_warning_limit, - pvalue->lower_warning_limit,pvalue->lower_alarm_limit); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,plong++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",*plong); - } - break; - } - case DBR_GR_DOUBLE: - { - struct dbr_gr_double *pvalue - = (struct dbr_gr_double *)pbuffer; - dbr_double_t *pdouble = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf(" %3d\n\t%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f", - pvalue->precision, - (float)(pvalue->upper_disp_limit), - (float)(pvalue->lower_disp_limit), - (float)(pvalue->upper_alarm_limit), - (float)(pvalue->upper_warning_limit), - (float)(pvalue->lower_warning_limit), - (float)(pvalue->lower_alarm_limit)); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pdouble++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%6.4f ",(float)(*pdouble)); - } - break; - } - case DBR_CTRL_SHORT: - { - struct dbr_ctrl_short *pvalue - = (struct dbr_ctrl_short *)pbuffer; - dbr_short_t *pshort = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf("\n\t%8d %8d %8d %8d %8d %8d", - pvalue->upper_disp_limit,pvalue->lower_disp_limit, - pvalue->upper_alarm_limit,pvalue->upper_warning_limit, - pvalue->lower_warning_limit,pvalue->lower_alarm_limit); - printf(" %8d %8d", - pvalue->upper_ctrl_limit,pvalue->lower_ctrl_limit); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pshort++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",*pshort); - } - break; - } - case DBR_CTRL_FLOAT: - { - struct dbr_ctrl_float *pvalue - = (struct dbr_ctrl_float *)pbuffer; - dbr_float_t *pfloat = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf(" %3d\n\t%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f", - pvalue->precision, - pvalue->upper_disp_limit,pvalue->lower_disp_limit, - pvalue->upper_alarm_limit,pvalue->upper_warning_limit, - pvalue->lower_warning_limit,pvalue->lower_alarm_limit); - printf(" %8.3f %8.3f", - pvalue->upper_ctrl_limit,pvalue->lower_ctrl_limit); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pfloat++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%6.4f ",*pfloat); - } - break; - } - case DBR_CTRL_CHAR: - { - struct dbr_ctrl_char *pvalue - = (struct dbr_ctrl_char *)pbuffer; - dbr_char_t *pchar = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf("\n\t%8d %8d %8d %8d %8d %8d", - pvalue->upper_disp_limit,pvalue->lower_disp_limit, - pvalue->upper_alarm_limit,pvalue->upper_warning_limit, - pvalue->lower_warning_limit,pvalue->lower_alarm_limit); - printf(" %8d %8d", - pvalue->upper_ctrl_limit,pvalue->lower_ctrl_limit); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pchar++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%4d ",(short)(*pchar)); - } - break; - } - case DBR_CTRL_LONG: - { - struct dbr_ctrl_long *pvalue - = (struct dbr_ctrl_long *)pbuffer; - dbr_long_t *plong = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf("\n\t%8d %8d %8d %8d %8d %8d", - pvalue->upper_disp_limit,pvalue->lower_disp_limit, - pvalue->upper_alarm_limit,pvalue->upper_warning_limit, - pvalue->lower_warning_limit,pvalue->lower_alarm_limit); - printf(" %8d %8d", - pvalue->upper_ctrl_limit,pvalue->lower_ctrl_limit); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,plong++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%d ",*plong); - } - break; - } - case DBR_CTRL_DOUBLE: - { - struct dbr_ctrl_double *pvalue - = (struct dbr_ctrl_double *)pbuffer; - dbr_double_t *pdouble = &pvalue->value; - printf("%2d %2d %.8s",pvalue->status,pvalue->severity, - pvalue->units); - printf(" %3d\n\t%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f", - pvalue->precision, - (float)(pvalue->upper_disp_limit), - (float)(pvalue->lower_disp_limit), - (float)(pvalue->upper_alarm_limit), - (float)(pvalue->upper_warning_limit), - (float)(pvalue->lower_warning_limit), - (float)(pvalue->lower_alarm_limit)); - printf(" %8.3f %8.3f", - (float)(pvalue->upper_ctrl_limit), - (float)(pvalue->lower_ctrl_limit)); - if(count==1) printf("\tValue: "); - for (i = 0; i < count; i++,pdouble++){ - if(count!=1 && (i%10 == 0)) printf("\n"); - printf("%6.6f ",(float)(*pdouble)); - } - break; - } - case DBR_STSACK_STRING: - { - struct dbr_stsack_string *pvalue - = (struct dbr_stsack_string *)pbuffer; - printf("%2d %2d",pvalue->status,pvalue->severity); - printf(" %2d %2d",pvalue->ackt,pvalue->acks); - printf(" %s",pvalue->value); - break; - } - case DBR_CLASS_NAME: - { - dbr_class_name_t * pvalue = - ( dbr_class_name_t * ) pbuffer; - printf ( "%s", *pvalue ); - break; - } - default: - printf ( - "unsupported by ca_dbrDump()" ); - break; - } - printf("\n"); -} - diff --git a/src/ca/client/tools/Makefile b/src/ca/client/tools/Makefile deleted file mode 100644 index 0e14c72c9..000000000 --- a/src/ca/client/tools/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -# Synchrotronstrahlung. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -PROD_DEFAULT += caget camonitor cainfo caput -PROD_vxWorks = -nil- -PROD_RTEMS = -nil- -PROD_iOS = -nil- - -PROD_SRCS = tool_lib.c - -caget_SRCS = caget.c -caput_SRCS = caput.c -camonitor_SRCS = camonitor.c -cainfo_SRCS = cainfo.c - -PROD_LIBS = ca Com - -include $(TOP)/configure/RULES diff --git a/src/ca/client/tools/caget.c b/src/ca/client/tools/caget.c deleted file mode 100644 index 00056709e..000000000 --- a/src/ca/client/tools/caget.c +++ /dev/null @@ -1,554 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2006 Diamond Light Source Ltd. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange (BESSY) - * - * Modification History - * 2006/01/17 Malcolm Walters (Tessella/Diamond Light Source) - * Fixed problem with "-c -w 0" hanging forever - * 2008/04/16 Ralph Lange (BESSY) - * Updated usage info - * 2009/03/31 Larry Hoff (BNL) - * Added field separators - * 2009/04/01 Ralph Lange (HZB/BESSY) - * Added support for long strings (array of char) and quoting of nonprintable characters - * - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include "tool_lib.h" - -#define VALID_DOUBLE_DIGITS 18 /* Max usable precision for a double */ -#define PEND_EVENT_SLICES 5 /* No. of pend_event slices for callback requests */ - -/* Different output formats */ -typedef enum { plain, terse, all, specifiedDbr } OutputT; - -/* Different request types */ -typedef enum { get, callback } RequestT; - -static int nConn = 0; /* Number of connected PVs */ -static int nRead = 0; /* Number of channels that were read */ -static int floatAsString = 0; /* Flag: fetch floats as string */ - - -static void usage (void) -{ - fprintf (stderr, "\nUsage: caget [options] ...\n\n" - " -h: Help: Print this message\n" - "Channel Access options:\n" - " -w : Wait time, specifies CA timeout, default is %f second(s)\n" - " -c: Asynchronous get (use ca_get_callback and wait for completion)\n" - " -p : CA priority (0-%u, default 0=lowest)\n" - "Format options:\n" - " Default output format is \"name value\"\n" - " -t: Terse mode - print only value, without name\n" - " -a: Wide mode \"name timestamp value stat sevr\" (read PVs as DBR_TIME_xxx)\n" - " -d : Request specific dbr type; use string (DBR_ prefix may be omitted)\n" - " or number of one of the following types:\n" - " DBR_STRING 0 DBR_STS_FLOAT 9 DBR_TIME_LONG 19 DBR_CTRL_SHORT 29\n" - " DBR_INT 1 DBR_STS_ENUM 10 DBR_TIME_DOUBLE 20 DBR_CTRL_INT 29\n" - " DBR_SHORT 1 DBR_STS_CHAR 11 DBR_GR_STRING 21 DBR_CTRL_FLOAT 30\n" - " DBR_FLOAT 2 DBR_STS_LONG 12 DBR_GR_SHORT 22 DBR_CTRL_ENUM 31\n" - " DBR_ENUM 3 DBR_STS_DOUBLE 13 DBR_GR_INT 22 DBR_CTRL_CHAR 32\n" - " DBR_CHAR 4 DBR_TIME_STRING 14 DBR_GR_FLOAT 23 DBR_CTRL_LONG 33\n" - " DBR_LONG 5 DBR_TIME_INT 15 DBR_GR_ENUM 24 DBR_CTRL_DOUBLE 34\n" - " DBR_DOUBLE 6 DBR_TIME_SHORT 15 DBR_GR_CHAR 25 DBR_STSACK_STRING 37\n" - " DBR_STS_STRING 7 DBR_TIME_FLOAT 16 DBR_GR_LONG 26 DBR_CLASS_NAME 38\n" - " DBR_STS_SHORT 8 DBR_TIME_ENUM 17 DBR_GR_DOUBLE 27\n" - " DBR_STS_INT 8 DBR_TIME_CHAR 18 DBR_CTRL_STRING 28\n" - "Enum format:\n" - " -n: Print DBF_ENUM value as number (default is enum string)\n" - "Arrays: Value format: print number of requested values, then list of values\n" - " Default: Print all values\n" - " -# : Print first elements of an array\n" - " -S: Print array of char as a string (long string)\n" - "Floating point type format:\n" - " Default: Use %%g format\n" - " -e : Use %%e format, with a precision of digits\n" - " -f : Use %%f format, with a precision of digits\n" - " -g : Use %%g format, with a precision of digits\n" - " -s: Get value as string (honors server-side precision)\n" - " -lx: Round to long integer and print as hex number\n" - " -lo: Round to long integer and print as octal number\n" - " -lb: Round to long integer and print as binary number\n" - "Integer number format:\n" - " Default: Print as decimal number\n" - " -0x: Print as hex number\n" - " -0o: Print as octal number\n" - " -0b: Print as binary number\n" - "Alternate output field separator:\n" - " -F : Use as an alternate output field separator\n" - "\nExample: caget -a -f8 my_channel another_channel\n" - " (uses wide output format, doubles are printed as %%f with precision of 8)\n\n" - , DEFAULT_TIMEOUT, CA_PRIORITY_MAX); -} - - - -/*+************************************************************************** - * - * Function: event_handler - * - * Description: CA event_handler for request type callback - * Allocates the dbr structure and copies the data - * - * Arg(s) In: args - event handler args (see CA manual) - * - **************************************************************************-*/ - -static void event_handler (evargs args) -{ - pv* ppv = args.usr; - - ppv->status = args.status; - if (args.status == ECA_NORMAL) - { - ppv->dbrType = args.type; - ppv->value = calloc(1, dbr_size_n(args.type, args.count)); - memcpy(ppv->value, args.dbr, dbr_size_n(args.type, args.count)); - ppv->nElems = args.count; - nRead++; - } -} - - - -/*+************************************************************************** - * - * Function: caget - * - * Description: Issue read requests, wait for incoming data - * and print the data according to the selected format - * - * Arg(s) In: pvs - Pointer to an array of pv structures - * nPvs - Number of elements in the pvs array - * request - Request type - * format - Output format - * dbrType - Requested dbr type - * reqElems - Requested number of (array) elements - * - * Return(s): Error code: 0 = OK, 1 = Error - * - **************************************************************************-*/ - -static int caget (pv *pvs, int nPvs, RequestT request, OutputT format, - chtype dbrType, unsigned long reqElems) -{ - unsigned int i; - int n, result; - - for (n = 0; n < nPvs; n++) { - unsigned long nElems; - - /* Set up pvs structure */ - /* -------------------- */ - - /* Get natural type and array count */ - nElems = ca_element_count(pvs[n].chid); - pvs[n].dbfType = ca_field_type(pvs[n].chid); - pvs[n].dbrType = dbrType; - - /* Set up value structures */ - if (format != specifiedDbr) - { - pvs[n].dbrType = dbf_type_to_DBR_TIME(pvs[n].dbfType); /* Use native type */ - if (dbr_type_is_ENUM(pvs[n].dbrType)) /* Enums honour -n option */ - { - if (enumAsNr) pvs[n].dbrType = DBR_TIME_INT; - else pvs[n].dbrType = DBR_TIME_STRING; - } - else if (floatAsString && - (dbr_type_is_FLOAT(pvs[n].dbrType) || dbr_type_is_DOUBLE(pvs[n].dbrType))) - { - pvs[n].dbrType = DBR_TIME_STRING; - } - } - - /* Issue CA request */ - /* ---------------- */ - - if (ca_state(pvs[n].chid) == cs_conn) - { - nConn++; - pvs[n].onceConnected = 1; - if (request == callback) - { - /* Event handler will allocate value and set nElems */ - pvs[n].reqElems = reqElems > nElems ? nElems : reqElems; - result = ca_array_get_callback(pvs[n].dbrType, - pvs[n].reqElems, - pvs[n].chid, - event_handler, - (void*)&pvs[n]); - } else { - /* We allocate value structure and set nElems */ - pvs[n].nElems = reqElems && reqElems < nElems ? reqElems : nElems; - pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].nElems)); - if (!pvs[n].value) { - fprintf(stderr,"Memory allocation failed\n"); - return 1; - } - result = ca_array_get(pvs[n].dbrType, - pvs[n].nElems, - pvs[n].chid, - pvs[n].value); - } - pvs[n].status = result; - } else { - pvs[n].status = ECA_DISCONN; - } - } - if (!nConn) return 1; /* No connection? We're done. */ - - /* Wait for completion */ - /* ------------------- */ - - result = ca_pend_io(caTimeout); - if (result == ECA_TIMEOUT) - fprintf(stderr, "Read operation timed out: some PV data was not read.\n"); - - if (request == callback) /* Also wait for callbacks */ - { - if (caTimeout != 0) - { - double slice = caTimeout / PEND_EVENT_SLICES; - for (n = 0; n < PEND_EVENT_SLICES; n++) - { - ca_pend_event(slice); - if (nRead >= nConn) break; - } - if (nRead < nConn) - fprintf(stderr, "Read operation timed out: some PV data was not read.\n"); - } else { - /* For 0 timeout keep waiting until all are done */ - while (nRead < nConn) { - ca_pend_event(1.0); - } - } - } - - /* Print the data */ - /* -------------- */ - - for (n = 0; n < nPvs; n++) { - - switch (format) { - case plain: /* Emulate old caget behaviour */ - if (pvs[n].nElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name); - else printf("%s", pvs[n].name); - printf("%c", fieldSeparator); - case terse: - if (pvs[n].status == ECA_DISCONN) - printf("*** not connected\n"); - else if (pvs[n].status == ECA_NORDACCESS) - printf("*** no read access\n"); - else if (pvs[n].status != ECA_NORMAL) - printf("*** CA error %s\n", ca_message(pvs[n].status)); - else if (pvs[n].value == 0) - printf("*** no data available (timeout)\n"); - else - { - if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].nElems > 1)) { - dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType); - int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s)); - char *d = calloc(dlen+1, sizeof(char)); - if(d) { - epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s)); - printf("%s", d); - free(d); - } else { - fprintf(stderr,"Failed to allocate space for escaped string\n"); - } - } else { - if (reqElems || pvs[n].nElems > 1) printf("%lu%c", pvs[n].nElems, fieldSeparator); - for (i=0; i 1)) { - dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType); - int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s)); - char *d = calloc(dlen+1, sizeof(char)); - if(d) { - epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s)); - printf("%s", d); - free(d); - } else { - fprintf(stderr,"Failed to allocate space for escaped string\n"); - } - } else { - for (i=0; i DBR_DOUBLE) /* Extended type extra info */ - printf("%s\n", dbr2str(pvs[n].value, pvs[n].dbrType)); - } - } - break; - default : - break; - } - } - return 0; -} - - - -/*+************************************************************************** - * - * Function: main - * - * Description: caget main() - * Evaluate command line options, set up CA, connect the - * channels, collect and print the data as requested - * - * Arg(s) In: [options] ... - * - * Arg(s) Out: none - * - * Return(s): Standard return code (0=success, 1=error) - * - **************************************************************************-*/ - -static void complainIfNotPlainAndSet (OutputT *current, const OutputT requested) -{ - if (*current != plain) - fprintf(stderr, - "Options t,d,a are mutually exclusive. " - "('caget -h' for help.)\n"); - *current = requested; -} - -int main (int argc, char *argv[]) -{ - int n; - int result; /* CA result */ - OutputT format = plain; /* User specified format */ - RequestT request = get; /* User specified request type */ - IntFormatT outType; /* Output type */ - - int count = 0; /* 0 = not specified by -# option */ - int opt; /* getopt() current option */ - int type = -1; /* getopt() data type argument */ - int digits = 0; /* getopt() no. of float digits */ - - int nPvs; /* Number of PVs */ - pv* pvs; /* Array of PV structures */ - - LINE_BUFFER(stdout); /* Configure stdout buffering */ - - while ((opt = getopt(argc, argv, ":taicnhsSe:f:g:l:#:d:0:w:p:F:")) != -1) { - switch (opt) { - case 'h': /* Print usage */ - usage(); - return 0; - case 't': /* Terse output mode */ - complainIfNotPlainAndSet(&format, terse); - break; - case 'a': /* Wide output mode */ - complainIfNotPlainAndSet(&format, all); - break; - case 'c': /* Callback mode */ - request = callback; - break; - case 'd': /* Data type specification */ - complainIfNotPlainAndSet(&format, specifiedDbr); - /* Argument (type) may be text or number */ - if (sscanf(optarg, "%d", &type) != 1) - { - dbr_text_to_type(optarg, type); - if (type == -1) /* Invalid? Try prefix DBR_ */ - { - char str[30] = "DBR_"; - strncat(str, optarg, 25); - dbr_text_to_type(str, type); - } - } - if (type < DBR_STRING || type > DBR_CLASS_NAME - || type == DBR_PUT_ACKT || type == DBR_PUT_ACKS) - { - fprintf(stderr, "Requested dbr type out of range " - "or invalid - ignored. ('caget -h' for help.)\n"); - format = plain; - } - break; - case 'n': /* Print ENUM as index numbers */ - enumAsNr = 1; - break; - case 'w': /* Set CA timeout value */ - if(epicsScanDouble(optarg, &caTimeout) != 1) - { - fprintf(stderr, "'%s' is not a valid timeout value " - "- ignored. ('caget -h' for help.)\n", optarg); - caTimeout = DEFAULT_TIMEOUT; - } - break; - case '#': /* Array count */ - if (sscanf(optarg,"%d", &count) != 1) - { - fprintf(stderr, "'%s' is not a valid array element count " - "- ignored. ('caget -h' for help.)\n", optarg); - count = 0; - } - break; - case 'p': /* CA priority */ - if (sscanf(optarg,"%u", &caPriority) != 1) - { - fprintf(stderr, "'%s' is not a valid CA priority " - "- ignored. ('caget -h' for help.)\n", optarg); - caPriority = DEFAULT_CA_PRIORITY; - } - if (caPriority > CA_PRIORITY_MAX) caPriority = CA_PRIORITY_MAX; - break; - case 's': /* Select string dbr for floating type data */ - floatAsString = 1; - break; - case 'S': /* Treat char array as (long) string */ - charArrAsStr = 1; - break; - case 'e': /* Select %e/%f/%g format, using digits */ - case 'f': - case 'g': - if (sscanf(optarg, "%d", &digits) != 1) - fprintf(stderr, - "Invalid precision argument '%s' " - "for option '-%c' - ignored.\n", optarg, opt); - else - { - if (digits>=0 && digits<=VALID_DOUBLE_DIGITS) - sprintf(dblFormatStr, "%%-.%d%c", digits, opt); - else - fprintf(stderr, "Precision %d for option '-%c' " - "out of range - ignored.\n", digits, opt); - } - break; - case 'l': /* Convert to long and use integer format */ - case '0': /* Select integer format */ - switch ((char) *optarg) { - case 'x': outType = hex; break; /* x print Hex */ - case 'b': outType = bin; break; /* b print Binary */ - case 'o': outType = oct; break; /* o print Octal */ - default : - outType = dec; - fprintf(stderr, "Invalid argument '%s' " - "for option '-%c' - ignored.\n", optarg, opt); - } - if (outType != dec) { - if (opt == '0') { - type = DBR_LONG; - outTypeI = outType; - } else { - outTypeF = outType; - } - } - break; - case 'F': /* Store this for output and tool_lib formatting */ - fieldSeparator = (char) *optarg; - break; - case '?': - fprintf(stderr, - "Unrecognized option: '-%c'. ('caget -h' for help.)\n", - optopt); - return 1; - case ':': - fprintf(stderr, - "Option '-%c' requires an argument. ('caget -h' for help.)\n", - optopt); - return 1; - default : - usage(); - return 1; - } - } - - nPvs = argc - optind; /* Remaining arg list are PV names */ - - if (nPvs < 1) - { - fprintf(stderr, "No pv name specified. ('caget -h' for help.)\n"); - return 1; - } - /* Start up Channel Access */ - - result = ca_context_create(ca_disable_preemptive_callback); - if (result != ECA_NORMAL) { - fprintf(stderr, "CA error %s occurred while trying " - "to start channel access.\n", ca_message(result)); - return 1; - } - /* Allocate PV structure array */ - - pvs = calloc (nPvs, sizeof(pv)); - if (!pvs) - { - fprintf(stderr, "Memory allocation for channel structures failed.\n"); - return 1; - } - /* Connect channels */ - - for (n = 0; optind < argc; n++, optind++) - pvs[n].name = argv[optind] ; /* Copy PV names from command line */ - - result = connect_pvs(pvs, nPvs); - - /* Read and print data */ - if (!result) - result = caget(pvs, nPvs, request, format, type, count); - - /* Shut down Channel Access */ - ca_context_destroy(); - - return result; -} diff --git a/src/ca/client/tools/cainfo.c b/src/ca/client/tools/cainfo.c deleted file mode 100644 index ad580f473..000000000 --- a/src/ca/client/tools/cainfo.c +++ /dev/null @@ -1,224 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange (BESSY) - * - * Modification History - * 2008/04/16 Ralph Lange (BESSY) - * Updated usage info - * 2009/04/01 Ralph Lange (HZB/BESSY) - * Clarified output for native data type - * - */ - -#include -#include - -#include -#include - -#include "tool_lib.h" - -static unsigned statLevel = 0; /* ca_client_status() interest level */ - - -void usage (void) -{ - fprintf (stderr, "\nUsage: cainfo [options] ...\n\n" - " -h: Help: Print this message\n" - "Channel Access options:\n" - " -w : Wait time, specifies CA timeout, default is %f second(s)\n" - " -s : Call ca_client_status with the specified interest level\n" - " -p : CA priority (0-%u, default 0=lowest)\n" - "\nExample: cainfo my_channel another_channel\n\n" - , DEFAULT_TIMEOUT, CA_PRIORITY_MAX); -} - - - -/*+************************************************************************** - * - * Function: cainfo - * - * Description: Print CA info data or call ca_client_status - * - * Arg(s) In: pvs - Pointer to an array of pv structures - * nPvs - Number of elements in the pvs array - * - * Return(s): Error code: 0 = OK, 1 = Error - * - **************************************************************************-*/ - -int cainfo (pv *pvs, int nPvs) -{ - int n; - long dbfType; - long dbrType; - unsigned long nElems; - enum channel_state state; - char *stateStrings[] = { - "never connected", "previously connected", "connected", "closed" }; - char *boolStrings[] = { "no ", "" }; - - if (statLevel) { - ca_client_status(statLevel); - - } else { - - for (n = 0; n < nPvs; n++) { - - /* Print the status data */ - /* --------------------- */ - - state = ca_state(pvs[n].chid); - nElems = ca_element_count(pvs[n].chid); - dbfType = ca_field_type(pvs[n].chid); - dbrType = dbf_type_to_DBR(dbfType); - - printf("%s\n" - " State: %s\n" - " Host: %s\n" - " Access: %sread, %swrite\n" - " Native data type: %s\n" - " Request type: %s\n" - " Element count: %lu\n" - , pvs[n].name, - stateStrings[state], - ca_host_name(pvs[n].chid), - boolStrings[ca_read_access(pvs[n].chid)], - boolStrings[ca_write_access(pvs[n].chid)], - dbf_type_to_text(dbfType), - dbr_type_to_text(dbrType), - nElems - ); - } - } - - return 0; -} - - - -/*+************************************************************************** - * - * Function: main - * - * Description: cainfo main() - * Evaluate command line options, set up CA, connect the - * channels, print the data as requested - * - * Arg(s) In: [options] ... - * - * Arg(s) Out: none - * - * Return(s): Standard return code (0=success, 1=error) - * - **************************************************************************-*/ - -int main (int argc, char *argv[]) -{ - int n; - int result; /* CA result */ - - int opt; /* getopt() current option */ - - int nPvs; /* Number of PVs */ - pv* pvs; /* Array of PV structures */ - - LINE_BUFFER(stdout); /* Configure stdout buffering */ - - while ((opt = getopt(argc, argv, ":nhw:s:p:")) != -1) { - switch (opt) { - case 'h': /* Print usage */ - usage(); - return 0; - case 'w': /* Set CA timeout value */ - if(epicsScanDouble(optarg, &caTimeout) != 1) - { - fprintf(stderr, "'%s' is not a valid timeout value " - "- ignored. ('cainfo -h' for help.)\n", optarg); - caTimeout = DEFAULT_TIMEOUT; - } - break; - case 's': /* ca_client_status interest level */ - if (sscanf(optarg,"%du", &statLevel) != 1) - { - fprintf(stderr, "'%s' is not a valid interest level " - "- ignored. ('cainfo -h' for help.)\n", optarg); - statLevel = 0; - } - break; - case 'p': /* CA priority */ - if (sscanf(optarg,"%u", &caPriority) != 1) - { - fprintf(stderr, "'%s' is not a valid CA priority " - "- ignored. ('cainfo -h' for help.)\n", optarg); - caPriority = DEFAULT_CA_PRIORITY; - } - if (caPriority > CA_PRIORITY_MAX) caPriority = CA_PRIORITY_MAX; - break; - case '?': - fprintf(stderr, - "Unrecognized option: '-%c'. ('cainfo -h' for help.)\n", - optopt); - return 1; - case ':': - fprintf(stderr, - "Option '-%c' requires an argument. ('cainfo -h' for help.)\n", - optopt); - return 1; - default : - usage(); - return 1; - } - } - - nPvs = argc - optind; /* Remaining arg list are PV names */ - - if (!statLevel && nPvs < 1) - { - fprintf(stderr, "No pv name specified. ('cainfo -h' for help.)\n"); - return 1; - } - /* Start up Channel Access */ - - result = ca_context_create(ca_disable_preemptive_callback); - if (result != ECA_NORMAL) { - fprintf(stderr, "CA error %s occurred while trying " - "to start channel access.\n", ca_message(result)); - return 1; - } - /* Allocate PV structure array */ - - pvs = calloc (nPvs, sizeof(pv)); - if (!pvs) - { - fprintf(stderr, "Memory allocation for channel structures failed.\n"); - return 1; - } - /* Connect channels */ - - for (n = 0; optind < argc; n++, optind++) - pvs[n].name = argv[optind] ; /* Copy PV names from command line */ - - result = connect_pvs(pvs, nPvs); - - /* Print data */ - if (!result) - result = cainfo(pvs, nPvs); - - /* Shut down Channel Access */ - ca_context_destroy(); - - return result; -} diff --git a/src/ca/client/tools/camonitor.c b/src/ca/client/tools/camonitor.c deleted file mode 100644 index 307dad8d6..000000000 --- a/src/ca/client/tools/camonitor.c +++ /dev/null @@ -1,391 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange (BESSY) - * - * Modification History - * 2008/04/16 Ralph Lange (BESSY) - * Updated usage info - * 2009/03/31 Larry Hoff (BNL) - * Added field separators - * 2009/04/01 Ralph Lange (HZB/BESSY) - * Added support for long strings (array of char) and quoting of nonprintable characters - * - */ - -#include -#include -#include - -#include -#include - -#include "tool_lib.h" - -#define VALID_DOUBLE_DIGITS 18 /* Max usable precision for a double */ - -static unsigned long reqElems = 0; -static unsigned long eventMask = DBE_VALUE | DBE_ALARM; /* Event mask used */ -static int floatAsString = 0; /* Flag: fetch floats as string */ -static int nConn = 0; /* Number of connected PVs */ - - -void usage (void) -{ - fprintf (stderr, "\nUsage: camonitor [options] ...\n" - "\n" - " -h: Help; Print this message\n" - "Channel Access options:\n" - " -w : Wait time, specifies CA timeout, default is %f second(s)\n" - " -m : Specify CA event mask to use. is any combination of\n" - " 'v' (value), 'a' (alarm), 'l' (log/archive), 'p' (property).\n" - " Default event mask is 'va'\n" - " -p : CA priority (0-%u, default 0=lowest)\n" - "Timestamps:\n" - " Default: Print absolute timestamps (as reported by CA server)\n" - " -t : Specify timestamp source(s) and type, with containing\n" - " 's' = CA server (remote) timestamps\n" - " 'c' = CA client (local) timestamps (shown in '()'s)\n" - " 'n' = no timestamps\n" - " 'r' = relative timestamps (time elapsed since start of program)\n" - " 'i' = incremental timestamps (time elapsed since last update)\n" - " 'I' = incremental timestamps (time since last update, by channel)\n" - " 'r', 'i' or 'I' require 's' or 'c' to select the time source\n" - "Enum format:\n" - " -n: Print DBF_ENUM values as number (default is enum string)\n" - "Array values: Print number of elements, then list of values\n" - " Default: Request and print all elements (dynamic arrays supported)\n" - " -# : Request and print up to elements\n" - " -S: Print arrays of char as a string (long string)\n" - "Floating point format:\n" - " Default: Use %%g format\n" - " -e : Use %%e format, with a precision of digits\n" - " -f : Use %%f format, with a precision of digits\n" - " -g : Use %%g format, with a precision of digits\n" - " -s: Get value as string (honors server-side precision)\n" - " -lx: Round to long integer and print as hex number\n" - " -lo: Round to long integer and print as octal number\n" - " -lb: Round to long integer and print as binary number\n" - "Integer number format:\n" - " Default: Print as decimal number\n" - " -0x: Print as hex number\n" - " -0o: Print as octal number\n" - " -0b: Print as binary number\n" - "Alternate output field separator:\n" - " -F : Use to separate fields in output\n" - "\n" - "Example: camonitor -f8 my_channel another_channel\n" - " (doubles are printed as %%f with precision of 8)\n\n" - , DEFAULT_TIMEOUT, CA_PRIORITY_MAX); -} - - - -/*+************************************************************************** - * - * Function: event_handler - * - * Description: CA event_handler for request type callback - * Prints the event data - * - * Arg(s) In: args - event handler args (see CA manual) - * - **************************************************************************-*/ - -static void event_handler (evargs args) -{ - pv* pv = args.usr; - - pv->status = args.status; - if (args.status == ECA_NORMAL) - { - pv->dbrType = args.type; - pv->nElems = args.count; - pv->value = (void *) args.dbr; /* casting away const */ - - print_time_val_sts(pv, reqElems); - fflush(stdout); - - pv->value = NULL; - } -} - - -/*+************************************************************************** - * - * Function: connection_handler - * - * Description: CA connection_handler - * - * Arg(s) In: args - connection_handler_args (see CA manual) - * - **************************************************************************-*/ - -static void connection_handler ( struct connection_handler_args args ) -{ - pv *ppv = ( pv * ) ca_puser ( args.chid ); - if ( args.op == CA_OP_CONN_UP ) { - nConn++; - if (!ppv->onceConnected) { - ppv->onceConnected = 1; - /* Set up pv structure */ - /* ------------------- */ - - /* Get natural type and array count */ - ppv->dbfType = ca_field_type(ppv->chid); - ppv->dbrType = dbf_type_to_DBR_TIME(ppv->dbfType); /* Use native type */ - if (dbr_type_is_ENUM(ppv->dbrType)) /* Enums honour -n option */ - { - if (enumAsNr) ppv->dbrType = DBR_TIME_INT; - else ppv->dbrType = DBR_TIME_STRING; - } - else if (floatAsString && - (dbr_type_is_FLOAT(ppv->dbrType) || dbr_type_is_DOUBLE(ppv->dbrType))) - { - ppv->dbrType = DBR_TIME_STRING; - } - /* Set request count */ - ppv->nElems = ca_element_count(ppv->chid); - ppv->reqElems = reqElems > ppv->nElems ? ppv->nElems : reqElems; - - /* Issue CA request */ - /* ---------------- */ - /* install monitor once with first connect */ - ppv->status = ca_create_subscription(ppv->dbrType, - ppv->reqElems, - ppv->chid, - eventMask, - event_handler, - (void*)ppv, - NULL); - } - } - else if ( args.op == CA_OP_CONN_DOWN ) { - nConn--; - ppv->status = ECA_DISCONN; - print_time_val_sts(ppv, reqElems); - } -} - - -/*+************************************************************************** - * - * Function: main - * - * Description: camonitor main() - * Evaluate command line options, set up CA, connect the - * channels, collect and print the data as requested - * - * Arg(s) In: [options] ... - * - * Arg(s) Out: none - * - * Return(s): Standard return code (0=success, 1=error) - * - **************************************************************************-*/ - -int main (int argc, char *argv[]) -{ - int returncode = 0; - int n; - int result; /* CA result */ - IntFormatT outType; /* Output type */ - - int opt; /* getopt() current option */ - int digits = 0; /* getopt() no. of float digits */ - - int nPvs; /* Number of PVs */ - pv* pvs; /* Array of PV structures */ - - LINE_BUFFER(stdout); /* Configure stdout buffering */ - - while ((opt = getopt(argc, argv, ":nhm:sSe:f:g:l:#:0:w:t:p:F:")) != -1) { - switch (opt) { - case 'h': /* Print usage */ - usage(); - return 0; - case 'n': /* Print ENUM as index numbers */ - enumAsNr=1; - break; - case 't': /* Select timestamp source(s) and type */ - tsSrcServer = 0; - tsSrcClient = 0; - { - int i = 0; - char c; - while ((c = optarg[i++])) - switch (c) { - case 's': tsSrcServer = 1; break; - case 'c': tsSrcClient = 1; break; - case 'n': break; - case 'r': tsType = relative; break; - case 'i': tsType = incremental; break; - case 'I': tsType = incrementalByChan; break; - default : - fprintf(stderr, "Invalid argument '%c' " - "for option '-t' - ignored.\n", c); - } - } - break; - case 'w': /* Set CA timeout value */ - if(epicsScanDouble(optarg, &caTimeout) != 1) - { - fprintf(stderr, "'%s' is not a valid timeout value " - "- ignored. ('camonitor -h' for help.)\n", optarg); - caTimeout = DEFAULT_TIMEOUT; - } - break; - case '#': /* Array count */ - if (sscanf(optarg,"%ld", &reqElems) != 1) - { - fprintf(stderr, "'%s' is not a valid array element count " - "- ignored. ('camonitor -h' for help.)\n", optarg); - reqElems = 0; - } - break; - case 'p': /* CA priority */ - if (sscanf(optarg,"%u", &caPriority) != 1) - { - fprintf(stderr, "'%s' is not a valid CA priority " - "- ignored. ('camonitor -h' for help.)\n", optarg); - caPriority = DEFAULT_CA_PRIORITY; - } - if (caPriority > CA_PRIORITY_MAX) caPriority = CA_PRIORITY_MAX; - break; - case 'm': /* Select CA event mask */ - eventMask = 0; - { - int i = 0; - char c, err = 0; - while ((c = optarg[i++]) && !err) - switch (c) { - case 'v': eventMask |= DBE_VALUE; break; - case 'a': eventMask |= DBE_ALARM; break; - case 'l': eventMask |= DBE_LOG; break; - case 'p': eventMask |= DBE_PROPERTY; break; - default : - fprintf(stderr, "Invalid argument '%s' " - "for option '-m' - ignored.\n", optarg); - eventMask = DBE_VALUE | DBE_ALARM; - err = 1; - } - } - break; - case 's': /* Select string dbr for floating type data */ - floatAsString = 1; - break; - case 'S': /* Treat char array as (long) string */ - charArrAsStr = 1; - break; - case 'e': /* Select %e/%f/%g format, using digits */ - case 'f': - case 'g': - if (sscanf(optarg, "%d", &digits) != 1) - fprintf(stderr, - "Invalid precision argument '%s' " - "for option '-%c' - ignored.\n", optarg, opt); - else - { - if (digits>=0 && digits<=VALID_DOUBLE_DIGITS) - sprintf(dblFormatStr, "%%-.%d%c", digits, opt); - else - fprintf(stderr, "Precision %d for option '-%c' " - "out of range - ignored.\n", digits, opt); - } - break; - case 'l': /* Convert to long and use integer format */ - case '0': /* Select integer format */ - switch ((char) *optarg) { - case 'x': outType = hex; break; /* x print Hex */ - case 'b': outType = bin; break; /* b print Binary */ - case 'o': outType = oct; break; /* o print Octal */ - default : - outType = dec; - fprintf(stderr, "Invalid argument '%s' " - "for option '-%c' - ignored.\n", optarg, opt); - } - if (outType != dec) { - if (opt == '0') outTypeI = outType; - else outTypeF = outType; - } - break; - case 'F': /* Store this for output and tool_lib formatting */ - fieldSeparator = (char) *optarg; - break; - case '?': - fprintf(stderr, - "Unrecognized option: '-%c'. ('camonitor -h' for help.)\n", - optopt); - return 1; - case ':': - fprintf(stderr, - "Option '-%c' requires an argument. ('camonitor -h' for help.)\n", - optopt); - return 1; - default : - usage(); - return 1; - } - } - - nPvs = argc - optind; /* Remaining arg list are PV names */ - - if (nPvs < 1) - { - fprintf(stderr, "No pv name specified. ('camonitor -h' for help.)\n"); - return 1; - } - /* Start up Channel Access */ - - result = ca_context_create(ca_disable_preemptive_callback); - if (result != ECA_NORMAL) { - fprintf(stderr, "CA error %s occurred while trying " - "to start channel access.\n", ca_message(result)); - return 1; - } - /* Allocate PV structure array */ - - pvs = calloc (nPvs, sizeof(pv)); - if (!pvs) - { - fprintf(stderr, "Memory allocation for channel structures failed.\n"); - return 1; - } - /* Connect channels */ - - /* Copy PV names from command line */ - for (n = 0; optind < argc; n++, optind++) - { - pvs[n].name = argv[optind]; - } - /* Create CA connections */ - returncode = create_pvs(pvs, nPvs, connection_handler); - if ( returncode ) { - return returncode; - } - /* Check for channels that didn't connect */ - ca_pend_event(caTimeout); - for (n = 0; n < nPvs; n++) - { - if (!pvs[n].onceConnected) - print_time_val_sts(&pvs[n], reqElems); - } - - /* Read and print data forever */ - ca_pend_event(0); - - /* Shut down Channel Access */ - ca_context_destroy(); - - return result; -} diff --git a/src/ca/client/tools/caput.c b/src/ca/client/tools/caput.c deleted file mode 100644 index 9c50cd9df..000000000 --- a/src/ca/client/tools/caput.c +++ /dev/null @@ -1,562 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2006 Diamond Light Source Ltd. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange (BESSY) - * - * Modification History - * 2006/01/17 Malcolm Walters (Tessella/Diamond Light Source) - * Added put_callback option - heavily based on caget - * 2008/03/06 Andy Foster (OSL/Diamond Light Source) - * Remove timeout dependency of ca_put_callback by using an EPICS event - * (semaphore), i.e. remove ca_pend_event time slicing. - * 2008/04/16 Ralph Lange (BESSY) - * Updated usage info - * 2009/03/31 Larry Hoff (BNL) - * Added field separators - * 2009/04/01 Ralph Lange (HZB/BESSY) - * Added support for long strings (array of char) and quoting of nonprintable characters - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "tool_lib.h" - -#define VALID_DOUBLE_DIGITS 18 /* Max usable precision for a double */ - -/* Different output formats */ -typedef enum { plain, terse, all } OutputT; - -/* Different request types */ -typedef enum { get, callback } RequestT; - -/* Valid EPICS string */ -typedef char EpicsStr[MAX_STRING_SIZE]; - -static int nConn = 0; /* Number of connected PVs */ -static epicsEventId epId; - -void usage (void) -{ - fprintf (stderr, "\nUsage: caput [options] ...\n" - " caput -a [options] ...\n\n" - " -h: Help: Print this message\n" - "Channel Access options:\n" - " -w : Wait time, specifies CA timeout, default is %f second(s)\n" - " -c: Asynchronous put (use ca_put_callback and wait for completion)\n" - " -p : CA priority (0-%u, default 0=lowest)\n" - "Format options:\n" - " -t: Terse mode - print only sucessfully written value, without name\n" - " -l: Long mode \"name timestamp value stat sevr\" (read PVs as DBR_TIME_xxx)\n" - "Enum format:\n" - " Default: Auto - try value as ENUM string, then as index number\n" - " -n: Force interpretation of values as numbers\n" - " -s: Force interpretation of values as strings\n" - "Arrays:\n" - " Default: Put scalar\n" - " Value format: all value arguments concatenated with spaces\n" - " -S: Put string as an array of chars (long string)\n" - " -a: Put array\n" - " Value format: number of values, then list of values\n" - "Alternate output field separator:\n" - " -F : Use as an alternate output field separator\n" - "\nExample: caput my_channel 1.2\n" - " (puts 1.2 to my_channel)\n\n" - , DEFAULT_TIMEOUT, CA_PRIORITY_MAX); -} - - -/*+************************************************************************** - * - * Function: put_event_handler - * - * Description: CA event_handler for request type callback - * Sets status flags and marks as done. - * - * Arg(s) In: args - event handler args (see CA manual) - * - **************************************************************************-*/ - -void put_event_handler ( struct event_handler_args args ) -{ - /* Retrieve pv from event handler structure */ - pv* pPv = args.usr; - - /* Store status, then give EPICS event */ - pPv->status = args.status; - epicsEventSignal( epId ); -} - - -/*+************************************************************************** - * - * Function: caget - * - * Description: Issue read request, wait for incoming data - * and print the data - * - * Arg(s) In: pvs - Pointer to an array of pv structures - * nPvs - Number of elements in the pvs array - * format - Output format - * dbrType - Requested dbr type - * reqElems - Requested number of (array) elements - * - * Return(s): Error code: 0 = OK, 1 = Error - * - **************************************************************************-*/ - -int caget (pv *pvs, int nPvs, OutputT format, - chtype dbrType, unsigned long reqElems) -{ - unsigned int i; - int n, result; - - for (n = 0; n < nPvs; n++) { - - /* Set up pvs structure */ - /* -------------------- */ - - /* Get natural type and array count */ - pvs[n].nElems = ca_element_count(pvs[n].chid); - pvs[n].dbfType = ca_field_type(pvs[n].chid); - pvs[n].dbrType = dbrType; - - /* Set up value structures */ - pvs[n].dbrType = dbf_type_to_DBR_TIME(pvs[n].dbfType); /* Use native type */ - if (dbr_type_is_ENUM(pvs[n].dbrType)) /* Enums honour -n option */ - { - if (enumAsNr) pvs[n].dbrType = DBR_TIME_INT; - else pvs[n].dbrType = DBR_TIME_STRING; - } - - if (reqElems == 0 || pvs[n].nElems < reqElems) /* Adjust array count */ - pvs[n].reqElems = pvs[n].nElems; - else - pvs[n].reqElems = reqElems; - - /* Issue CA request */ - /* ---------------- */ - - if (ca_state(pvs[n].chid) == cs_conn) - { - nConn++; - pvs[n].onceConnected = 1; - /* Allocate value structure */ - pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].reqElems)); - if(!pvs[n].value){ - fprintf(stderr,"Allocation failed\n"); - exit(1); - } - result = ca_array_get(pvs[n].dbrType, - pvs[n].reqElems, - pvs[n].chid, - pvs[n].value); - pvs[n].status = result; - } else { - pvs[n].status = ECA_DISCONN; - } - } - if (!nConn) return 1; /* No connection? We're done. */ - - /* Wait for completion */ - /* ------------------- */ - - result = ca_pend_io(caTimeout); - if (result == ECA_TIMEOUT) - fprintf(stderr, "Read operation timed out: PV data was not read.\n"); - - /* Print the data */ - /* -------------- */ - - for (n = 0; n < nPvs; n++) { - - switch (format) { - case plain: /* Emulate old caput behaviour */ - if (pvs[n].reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name); - else printf("%s", pvs[n].name); - printf("%c", fieldSeparator); - case terse: - if (pvs[n].status == ECA_DISCONN) - printf("*** not connected\n"); - else if (pvs[n].status == ECA_NORDACCESS) - printf("*** no read access\n"); - else if (pvs[n].status != ECA_NORMAL) - printf("*** CA error %s\n", ca_message(pvs[n].status)); - else if (pvs[n].value == 0) - printf("*** no data available (timeout)\n"); - else - { - if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].reqElems > 1)) { - dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType); - int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s)); - char *d = calloc(dlen+1, sizeof(char)); - if(!d){ - fprintf(stderr,"Allocation failed\n"); - exit(1); - } - epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s)); - printf("%s", d); - free(d); - } else { - if (reqElems || pvs[n].nElems > 1) printf("%lu%c", pvs[n].reqElems, fieldSeparator); - for (i=0; i ... - * - * Arg(s) Out: none - * - * Return(s): Standard return code (0=success, 1=error) - * - **************************************************************************-*/ - -int main (int argc, char *argv[]) -{ - int i; - int result; /* CA result */ - OutputT format = plain; /* User specified format */ - RequestT request = get; /* User specified request type */ - int isArray = 0; /* Flag for array operation */ - int enumAsString = 0; /* Force ENUM values to be strings */ - - int count = 1; - int opt; /* getopt() current option */ - chtype dbrType = DBR_STRING; - char *pend; - EpicsStr *sbuf; - double *dbuf; - char *cbuf = 0; - char *ebuf = 0; - void *pbuf; - int len = 0; - int waitStatus; - struct dbr_gr_enum bufGrEnum; - - int nPvs; /* Number of PVs */ - pv* pvs; /* Array of PV structures */ - - LINE_BUFFER(stdout); /* Configure stdout buffering */ - putenv("POSIXLY_CORRECT="); /* Behave correct on GNU getopt systems */ - - while ((opt = getopt(argc, argv, ":cnlhatsS#:w:p:F:")) != -1) { - switch (opt) { - case 'h': /* Print usage */ - usage(); - return 0; - case 'n': /* Force interpret ENUM as index number */ - enumAsNr = 1; - enumAsString = 0; - break; - case 's': /* Force interpret ENUM as menu string */ - enumAsString = 1; - enumAsNr = 0; - break; - case 'S': /* Treat char array as (long) string */ - charArrAsStr = 1; - isArray = 0; - break; - case 't': /* Select terse output format */ - format = terse; - break; - case 'l': /* Select long output format */ - format = all; - break; - case 'a': /* Select array mode */ - isArray = 1; - charArrAsStr = 0; - break; - case 'c': /* Select put_callback mode */ - request = callback; - break; - case 'w': /* Set CA timeout value */ - if(epicsScanDouble(optarg, &caTimeout) != 1) - { - fprintf(stderr, "'%s' is not a valid timeout value " - "- ignored. ('caput -h' for help.)\n", optarg); - caTimeout = DEFAULT_TIMEOUT; - } - break; - case '#': /* Array count */ - if (sscanf(optarg,"%d", &count) != 1) - { - fprintf(stderr, "'%s' is not a valid array element count " - "- ignored. ('caput -h' for help.)\n", optarg); - count = 0; - } - break; - case 'p': /* CA priority */ - if (sscanf(optarg,"%u", &caPriority) != 1) - { - fprintf(stderr, "'%s' is not a valid CA priority " - "- ignored. ('caget -h' for help.)\n", optarg); - caPriority = DEFAULT_CA_PRIORITY; - } - if (caPriority > CA_PRIORITY_MAX) caPriority = CA_PRIORITY_MAX; - break; - case 'F': /* Store this for output and tool_lib formatting */ - fieldSeparator = (char) *optarg; - break; - case '?': - fprintf(stderr, - "Unrecognized option: '-%c'. ('caput -h' for help.)\n", - optopt); - return 1; - case ':': - fprintf(stderr, - "Option '-%c' requires an argument. ('caput -h' for help.)\n", - optopt); - return 1; - default : - usage(); - return 1; - } - } - - nPvs = argc - optind; /* Remaining arg list are PV names and values */ - - if (nPvs < 1) { - fprintf(stderr, "No pv name specified. ('caput -h' for help.)\n"); - return 1; - } - if (nPvs == 1) { - fprintf(stderr, "No value specified. ('caput -h' for help.)\n"); - return 1; - } - - nPvs = 1; /* One PV - the rest is value(s) */ - - epId = epicsEventCreate(epicsEventEmpty); /* Create empty EPICS event (semaphore) */ - - /* Start up Channel Access */ - - result = ca_context_create(ca_enable_preemptive_callback); - if (result != ECA_NORMAL) { - fprintf(stderr, "CA error %s occurred while trying " - "to start channel access.\n", ca_message(result)); - return 1; - } - /* Allocate PV structure array */ - - pvs = calloc (nPvs, sizeof(pv)); - if (!pvs) { - fprintf(stderr, "Memory allocation for channel structure failed.\n"); - return 1; - } - /* Connect channels */ - - pvs[0].name = argv[optind] ; /* Copy PV name from command line */ - - result = connect_pvs(pvs, nPvs); /* If the connection fails, we're done */ - if (result) { - ca_context_destroy(); - return result; - } - - /* Get values from command line */ - optind++; - - if (isArray) { - optind++; /* In case of array skip first value (nr - * of elements) - actual number of values is used */ - count = argc - optind; - - } else { /* Concatenate the remaining line to one string - * (sucks but is compatible to the former version) */ - for (i = optind; i < argc; i++) { - len += strlen(argv[i]); - len++; - } - cbuf = calloc(len, sizeof(char)); - if (!cbuf) { - fprintf(stderr, "Memory allocation failed.\n"); - return 1; - } - strcpy(cbuf, argv[optind]); - - if (argc > optind+1) { - for (i = optind + 1; i < argc; i++) { - strcat(cbuf, " "); - strcat(cbuf, argv[i]); - } - } - - if ((argc - optind) >= 1) - count = 1; - argv[optind] = cbuf; - } - - sbuf = calloc (count, sizeof(EpicsStr)); - dbuf = calloc (count, sizeof(double)); - if(!sbuf || !dbuf) { - fprintf(stderr, "Memory allocation failed\n"); - return 1; - } - - /* ENUM? Special treatment */ - - if (ca_field_type(pvs[0].chid) == DBR_ENUM) { - - /* Get the ENUM strings */ - - result = ca_array_get (DBR_GR_ENUM, 1, pvs[0].chid, &bufGrEnum); - result = ca_pend_io(caTimeout); - if (result == ECA_TIMEOUT) { - fprintf(stderr, "Read operation timed out: ENUM data was not read.\n"); - return 1; - } - - if (enumAsNr) { /* Interpret values as numbers */ - - for (i = 0; i < count; ++i) { - dbuf[i] = epicsStrtod(*(argv+optind+i), &pend); - if (*(argv+optind+i) == pend) { /* Conversion didn't work */ - fprintf(stderr, "Enum index value '%s' is not a number.\n", - *(argv+optind+i)); - return 1; - } - if (dbuf[i] >= bufGrEnum.no_str) { - fprintf(stderr, "Warning: enum index value '%s' may be too large.\n", - *(argv+optind+i)); - } - } - dbrType = DBR_DOUBLE; - - } else { /* Interpret values as strings */ - - for (i = 0; i < count; ++i) { - epicsStrnRawFromEscaped(sbuf[i], sizeof(EpicsStr), *(argv+optind+i), sizeof(EpicsStr)); - *( sbuf[i]+sizeof(EpicsStr)-1 ) = '\0'; - dbrType = DBR_STRING; - - /* Compare to ENUM strings */ - for (len = 0; len < bufGrEnum.no_str; len++) - if (!strcmp(sbuf[i], bufGrEnum.strs[len])) - break; - - if (len >= bufGrEnum.no_str) { - /* Not a string? Try as number */ - dbuf[i] = epicsStrtod(sbuf[i], &pend); - if (sbuf[i] == pend || enumAsString) { - fprintf(stderr, "Enum string value '%s' invalid.\n", sbuf[i]); - return 1; - } - if (dbuf[i] >= bufGrEnum.no_str) { - fprintf(stderr, "Warning: enum index value '%s' may be too large.\n", sbuf[i]); - } - dbrType = DBR_DOUBLE; - } - } - } - - } else { /* Not an ENUM */ - - if (charArrAsStr) { - dbrType = DBR_CHAR; - ebuf = calloc(len, sizeof(char)); - if(!ebuf) { - fprintf(stderr, "Memory allocation failed\n"); - return 1; - } - count = epicsStrnRawFromEscaped(ebuf, len, cbuf, len-1) + 1; - } else { - for (i = 0; i < count; ++i) { - epicsStrnRawFromEscaped(sbuf[i], sizeof(EpicsStr), *(argv+optind+i), sizeof(EpicsStr)); - *( sbuf[i]+sizeof(EpicsStr)-1 ) = '\0'; - } - dbrType = DBR_STRING; - } - } - - /* Read and print old data */ - if (format != terse) { - printf("Old : "); - result = caget(pvs, nPvs, format, 0, 0); - } - - /* Write new data */ - if (dbrType == DBR_STRING) pbuf = sbuf; - else if (dbrType == DBR_CHAR) pbuf = ebuf; - else pbuf = dbuf; - - if (request == callback) { - /* Use callback version of put */ - pvs[0].status = ECA_NORMAL; /* All ok at the moment */ - result = ca_array_put_callback ( - dbrType, count, pvs[0].chid, pbuf, put_event_handler, (void *) pvs); - } else { - /* Use standard put with defined timeout */ - result = ca_array_put (dbrType, count, pvs[0].chid, pbuf); - } - result = ca_pend_io(caTimeout); - if (result == ECA_TIMEOUT) { - fprintf(stderr, "Write operation timed out: Data was not written.\n"); - return 1; - } - if (request == callback) { /* Also wait for callbacks */ - waitStatus = epicsEventWaitWithTimeout( epId, caTimeout ); - if (waitStatus) - fprintf(stderr, "Write callback operation timed out\n"); - - /* retrieve status from callback */ - result = pvs[0].status; - } - - if (result != ECA_NORMAL) { - fprintf(stderr, "Error occured writing data.\n"); - return 1; - } - - /* Read and print new data */ - if (format != terse) - printf("New : "); - - result = caget(pvs, nPvs, format, 0, 0); - - /* Shut down Channel Access */ - ca_context_destroy(); - - return result; -} diff --git a/src/ca/client/tools/tool_lib.c b/src/ca/client/tools/tool_lib.c deleted file mode 100644 index db670151a..000000000 --- a/src/ca/client/tools/tool_lib.c +++ /dev/null @@ -1,640 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange (BESSY) - * - * Modification History - * 2009/03/31 Larry Hoff (BNL) - * Added field separators - * 2009/04/01 Ralph Lange (HZB/BESSY) - * Added support for long strings (array of char) and quoting of nonprintable characters - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "tool_lib.h" - -/* Time stamps for program start, first incoming monitor, - previous value (client and server stamp): - used for relative resp. incremental timestamps with monitors */ -static epicsTimeStamp tsStart, tsFirst, tsPreviousC, tsPreviousS; - -static int tsInitS = 0; /* Flag: Server timestamps init'd */ -static int tsInitC = 0; /* Flag: Client timestamps init'd */ - -TimeT tsType = absolute; /* Timestamp type flag (-t option) */ -int tsSrcServer = 1; /* Timestamp source flag (-t option) */ -int tsSrcClient = 0; /* Timestamp source flag (-t option) */ -IntFormatT outTypeI = dec; /* For -0.. output format option */ -IntFormatT outTypeF = dec; /* For -l.. output format option */ - -char dblFormatStr[30] = "%g"; /* Format string to print doubles (-efg options) */ -char timeFormatStr[30] = "%Y-%m-%d %H:%M:%S.%06f"; /* Time format string */ -char fieldSeparator = ' '; /* OFS default is whitespace */ - -int enumAsNr = 0; /* used for -n option - get DBF_ENUM as number */ -int charArrAsStr = 0; /* used for -S option - treat char array as (long) string */ -double caTimeout = 1.0; /* wait time default (see -w option) */ -capri caPriority = DEFAULT_CA_PRIORITY; /* CA Priority */ - -#define TIMETEXTLEN 28 /* Length of timestamp text buffer */ - - - -static void sprint_long (char *ret, dbr_long_t val, IntFormatT outType) -{ - if (outType == bin && val != 0) { - /* sprintf doesn't do binary; this code doesn't handle 0 */ - int i, skip = -1; - - for (i = 31; i >= 0; i--) { - int bit = (val >> i) & 1; - - if (skip < 0 && bit) { - skip = 31 - i; /* skip leading 0's */ - ret[i+1] = '\0'; - } - if (skip >= 0) { - ret[31-i-skip] = '0' + bit; - } - } - } - else { - const char *fmt[4] = { /* Order must match the enum IntFormatT */ - "%ld" /* dec */, - "0" /* bin, val is 0 */, - "0o%lo" /* oct */, - "0x%lX" /* hex */ - }; - - /* Formats have long modifier, pass value as a long */ - sprintf(ret, fmt[outType], (long) val); - } -} - - - -/*+************************************************************************** - * - * Function: val2str - * - * Description: Print (convert) value to a string - * - * Arg(s) In: v - Pointer to dbr_... structure - * type - Numeric dbr type - * index - Index of element to print (for arrays) - * - * Return(s): Pointer to static output string - * - **************************************************************************-*/ - -char *val2str (const void *v, unsigned type, int index) -{ -#define STR 500 - static char str[STR]; - char ch; - void *val_ptr; - unsigned base_type; - dbr_long_t val_long; - - if (!dbr_type_is_valid(type)) { - strcpy (str, "*** invalid type"); - return str; - } - strcpy (str, "!!!"); - - base_type = type % (LAST_TYPE+1); - - if (type == DBR_STSACK_STRING || type == DBR_CLASS_NAME) - base_type = DBR_STRING; - - val_ptr = dbr_value_ptr(v, type); - - switch (base_type) { - case DBR_STRING: - epicsStrnEscapedFromRaw(str, STR, ((dbr_string_t*) val_ptr)[index], strlen(((dbr_string_t*) val_ptr)[index])); - break; - case DBR_FLOAT: - if (outTypeF == dec) { - sprintf(str, dblFormatStr, ((dbr_float_t*) val_ptr)[index]); - } else { - if (((dbr_float_t*) val_ptr)[index] > 0.0) - val_long = ((dbr_float_t*) val_ptr)[index] + 0.5; - else - val_long = ((dbr_float_t*) val_ptr)[index] - 0.5; - sprint_long(str, val_long, outTypeF); - } - break; - case DBR_DOUBLE: - if (outTypeF == dec) { - sprintf(str, dblFormatStr, ((dbr_double_t*) val_ptr)[index]); - } else { - if (((dbr_double_t*) val_ptr)[index] > 0.0) - val_long = ((dbr_double_t*) val_ptr)[index] + 0.5; - else - val_long = ((dbr_double_t*) val_ptr)[index] - 0.5; - sprint_long(str, val_long, outTypeF); - } - break; - case DBR_CHAR: - ch = ((dbr_char_t*) val_ptr)[index]; - sprintf(str, "%d", ch); - break; - case DBR_INT: - sprint_long(str, ((dbr_int_t*) val_ptr)[index], outTypeI); - break; - case DBR_LONG: - sprint_long(str, ((dbr_long_t*) val_ptr)[index], outTypeI); - break; - case DBR_ENUM: - { - dbr_enum_t *val = (dbr_enum_t *)val_ptr; - if (dbr_type_is_GR(type) && !enumAsNr) { - if (val[index] >= MAX_ENUM_STATES) - sprintf(str, "Illegal Value (%d)", val[index]); - else if (val[index] >= ((struct dbr_gr_enum *)v)->no_str) - sprintf(str, "Enum Index Overflow (%d)", val[index]); - else - sprintf(str, "%s", ((struct dbr_gr_enum *)v)->strs[val[index]]); - } else if (dbr_type_is_CTRL(type) && !enumAsNr) { - if (val[index] >= MAX_ENUM_STATES) - sprintf(str, "Illegal Value (%d)", val[index]); - else if (val[index] >= ((struct dbr_ctrl_enum *)v)->no_str) - sprintf(str, "Enum Index Overflow (%d)", val[index]); - else - sprintf(str, "%s", ((struct dbr_ctrl_enum *)v)->strs[val[index]]); - } else - sprintf(str, "%d", val[index]); - } - } - return str; -} - - - -/*+************************************************************************** - * - * Function: dbr2str - * - * Description: Print (convert) additional information contained in dbr_... - * - * Arg(s) In: value - Pointer to dbr_... structure - * type - Numeric dbr type - * - * Return(s): Pointer to static output string - * - **************************************************************************-*/ - -/* Definitions for sprintf format strings and matching argument lists */ - -#define FMT_TIME \ - " Timestamp: %s" - -#define ARGS_TIME(T) \ - timeText - -#define FMT_STS \ - " Status: %s\n" \ - " Severity: %s" - -#define ARGS_STS(T) \ - stat_to_str(((struct T *)value)->status), \ - sevr_to_str(((struct T *)value)->severity) - -#define ARGS_STS_UNSIGNED(T) \ - stat_to_str_unsigned(((struct T *)value)->status), \ - sevr_to_str_unsigned(((struct T *)value)->severity) - -#define FMT_ACK \ - " Ack transient?: %s\n" \ - " Ack severity: %s" - -#define ARGS_ACK(T) \ - ((struct T *)value)->ackt ? "YES" : "NO", \ - sevr_to_str_unsigned(((struct T *)value)->acks) - -#define FMT_UNITS \ - " Units: %s" - -#define ARGS_UNITS(T) \ - ((struct T *)value)->units - -#define FMT_PREC \ - " Precision: %d" - -#define ARGS_PREC(T) \ - ((struct T *)value)->precision - -#define FMT_GR(FMT) \ - " Lo disp limit: " #FMT "\n" \ - " Hi disp limit: " #FMT "\n" \ - " Lo alarm limit: " #FMT "\n" \ - " Lo warn limit: " #FMT "\n" \ - " Hi warn limit: " #FMT "\n" \ - " Hi alarm limit: " #FMT - -#define ARGS_GR(T,F) \ - (F)((struct T *)value)->lower_disp_limit, \ - (F)((struct T *)value)->upper_disp_limit, \ - (F)((struct T *)value)->lower_alarm_limit, \ - (F)((struct T *)value)->lower_warning_limit, \ - (F)((struct T *)value)->upper_warning_limit, \ - (F)((struct T *)value)->upper_alarm_limit - -#define FMT_CTRL(FMT) \ - " Lo ctrl limit: " #FMT "\n" \ - " Hi ctrl limit: " #FMT - -#define ARGS_CTRL(T,F) \ - (F)((struct T *)value)->lower_ctrl_limit, \ - (F)((struct T *)value)->upper_ctrl_limit - - -/* Definitions for the actual sprintf calls */ - -#define PRN_DBR_STS(T) \ - sprintf(str, \ - FMT_STS, \ - ARGS_STS(T)) - -#define PRN_DBR_TIME(T) \ - epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, \ - &(((struct T *)value)->stamp)); \ - sprintf(str, \ - FMT_TIME "\n" FMT_STS, \ - ARGS_TIME(T), ARGS_STS(T)) - -#define PRN_DBR_GR(T,F,FMT) \ - sprintf(str, \ - FMT_STS "\n" FMT_UNITS "\n" FMT_GR(FMT), \ - ARGS_STS(T), ARGS_UNITS(T), ARGS_GR(T,F)) - -#define PRN_DBR_GR_PREC(T,F,FMT) \ - sprintf(str, \ - FMT_STS "\n" FMT_UNITS "\n" FMT_PREC "\n" FMT_GR(FMT), \ - ARGS_STS(T), ARGS_UNITS(T), ARGS_PREC(T), ARGS_GR(T,F)) - -#define PRN_DBR_CTRL(T,F,FMT) \ - sprintf(str, \ - FMT_STS "\n" FMT_UNITS "\n" FMT_GR(FMT) "\n" FMT_CTRL(FMT), \ - ARGS_STS(T), ARGS_UNITS(T), ARGS_GR(T,F), ARGS_CTRL(T,F)) - -#define PRN_DBR_CTRL_PREC(T,F,FMT) \ - sprintf(str, \ - FMT_STS "\n" FMT_UNITS "\n" FMT_PREC "\n" FMT_GR(FMT) "\n" FMT_CTRL(FMT), \ - ARGS_STS(T), ARGS_UNITS(T), ARGS_PREC(T), ARGS_GR(T,F), ARGS_CTRL(T,F)) - -#define PRN_DBR_STSACK(T) \ - sprintf(str, \ - FMT_STS "\n" FMT_ACK, \ - ARGS_STS_UNSIGNED(T), ARGS_ACK(T)) - -#define PRN_DBR_X_ENUM(T) \ - n = ((struct T *)value)->no_str; \ - PRN_DBR_STS(T); \ - sprintf(str+strlen(str), \ - "\n Enums: (%2d)", n); \ - for (i=0; istrs[i]); - - -/* Make a good guess how long the dbr_... stuff might get as worst case */ -#define DBR_PRINT_BUFFER_SIZE \ - 50 /* timestamp */ \ - + 2 * 30 /* status / Severity */ \ - + 2 * 30 /* acks / ackt */ \ - + 20 + MAX_UNITS_SIZE /* units */ \ - + 30 /* precision */ \ - + 6 * 45 /* graphic limits */ \ - + 2 * 45 /* control limits */ \ - + 30 + (MAX_ENUM_STATES * (20 + MAX_ENUM_STRING_SIZE)) /* enums */ \ - + 50 /* just to be sure */ - -char *dbr2str (const void *value, unsigned type) -{ - static char str[DBR_PRINT_BUFFER_SIZE]; - char timeText[TIMETEXTLEN]; - int n, i; - - switch (type) { - case DBR_STRING: /* no additional information for basic data types */ - case DBR_INT: - case DBR_FLOAT: - case DBR_ENUM: - case DBR_CHAR: - case DBR_LONG: - case DBR_DOUBLE: break; - - case DBR_CTRL_STRING: /* see db_access.h: not implemented */ - case DBR_GR_STRING: /* see db_access.h: not implemented */ - case DBR_STS_STRING: PRN_DBR_STS(dbr_sts_string); break; - case DBR_STS_SHORT: PRN_DBR_STS(dbr_sts_short); break; - case DBR_STS_FLOAT: PRN_DBR_STS(dbr_sts_float); break; - case DBR_STS_ENUM: PRN_DBR_STS(dbr_sts_enum); break; - case DBR_STS_CHAR: PRN_DBR_STS(dbr_sts_char); break; - case DBR_STS_LONG: PRN_DBR_STS(dbr_sts_long); break; - case DBR_STS_DOUBLE: PRN_DBR_STS(dbr_sts_double); break; - - case DBR_TIME_STRING: PRN_DBR_TIME(dbr_time_string); break; - case DBR_TIME_SHORT: PRN_DBR_TIME(dbr_time_short); break; - case DBR_TIME_FLOAT: PRN_DBR_TIME(dbr_time_float); break; - case DBR_TIME_ENUM: PRN_DBR_TIME(dbr_time_enum); break; - case DBR_TIME_CHAR: PRN_DBR_TIME(dbr_time_char); break; - case DBR_TIME_LONG: PRN_DBR_TIME(dbr_time_long); break; - case DBR_TIME_DOUBLE: PRN_DBR_TIME(dbr_time_double); break; - - case DBR_GR_CHAR: - PRN_DBR_GR(dbr_gr_char, char, %8d); break; - case DBR_GR_INT: - PRN_DBR_GR(dbr_gr_int, int, %8d); break; - case DBR_GR_LONG: - PRN_DBR_GR(dbr_gr_long, long int, %8ld); break; - case DBR_GR_FLOAT: - PRN_DBR_GR_PREC(dbr_gr_float, float, %g); break; - case DBR_GR_DOUBLE: - PRN_DBR_GR_PREC(dbr_gr_double, double, %g); break; - case DBR_GR_ENUM: - PRN_DBR_X_ENUM(dbr_gr_enum); break; - case DBR_CTRL_CHAR: - PRN_DBR_CTRL(dbr_ctrl_char, char, %8d); break; - case DBR_CTRL_INT: - PRN_DBR_CTRL(dbr_ctrl_int, int, %8d); break; - case DBR_CTRL_LONG: - PRN_DBR_CTRL(dbr_ctrl_long, long int, %8ld); break; - case DBR_CTRL_FLOAT: - PRN_DBR_CTRL_PREC(dbr_ctrl_float, float, %g); break; - case DBR_CTRL_DOUBLE: - PRN_DBR_CTRL_PREC(dbr_ctrl_double, double, %g); break; - case DBR_CTRL_ENUM: - PRN_DBR_X_ENUM(dbr_ctrl_enum); break; - case DBR_STSACK_STRING: - PRN_DBR_STSACK(dbr_stsack_string); break; - default : strcpy (str, "can't print data type"); - } - return str; -} - - - -/*+************************************************************************** - * - * Function: print_time_val_sts - * - * Description: Print (to stdout) one wide output line - * (name, timestamp, value, status, severity) - * - * Arg(s) In: pv - Pointer to pv structure - * nElems - Number of elements (array) - * - **************************************************************************-*/ - -#define PRN_TIME_VAL_STS(TYPE,TYPE_ENUM) \ - printAbs = !pv->firstStampPrinted; \ - \ - ptsNewS = &((struct TYPE *)value)->stamp; \ - ptsNewC = &tsNow; \ - \ - switch (tsType) { \ - case relative: \ - ptsRefC = &tsStart; \ - ptsRefS = &tsFirst; \ - break; \ - case incremental: \ - ptsRefC = &tsPreviousC; \ - ptsRefS = &tsPreviousS; \ - break; \ - case incrementalByChan: \ - ptsRefC = &pv->tsPreviousC; \ - ptsRefS = &pv->tsPreviousS; \ - break; \ - default : \ - printAbs = 1; \ - } \ - \ - if (printAbs) { \ - if (tsSrcServer) { \ - epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, ptsNewS); \ - printf("%s", timeText); \ - } \ - if (tsSrcClient) { \ - epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, ptsNewC); \ - printf("(%s)", timeText); \ - } \ - pv->firstStampPrinted = 1; \ - } else { \ - if (tsSrcServer) { \ - printf(" %+12.6f", epicsTimeDiffInSeconds(ptsNewS, ptsRefS) ); \ - } \ - if (tsSrcClient) { \ - printf(" (%+12.6f)", epicsTimeDiffInSeconds(ptsNewC, ptsRefC) ); \ - } \ - } \ - \ - if (tsType == incrementalByChan) { \ - pv->tsPreviousC = *ptsNewC; \ - pv->tsPreviousS = *ptsNewS; \ - } \ - \ - tsPreviousC = *ptsNewC; \ - tsPreviousS = *ptsNewS; \ - \ - if (charArrAsStr && dbr_type_is_CHAR(TYPE_ENUM) && (reqElems || pv->nElems > 1)) { \ - dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pv->value, pv->dbrType); \ - size_t len = strlen((char*)s); \ - unsigned long elems = reqElems && (reqElems < pv->nElems) ? reqElems : pv->nElems; \ - int dlen; \ - char *d; \ - if (len < elems) elems = len; \ - dlen = epicsStrnEscapedFromRawSize((char*)s, elems); \ - d = calloc(dlen+1, sizeof(char)); \ - if(d) { \ - epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, elems); \ - printf("%c%s", fieldSeparator, d); \ - free(d); \ - } else { \ - printf("Failed to allocate for print_time_val_sts\n"); \ - } \ - } else { \ - if (reqElems || pv->nElems > 1) printf("%c%lu", fieldSeparator, pv->nElems); \ - for (i=0; inElems; ++i) { \ - printf("%c%s", fieldSeparator, val2str(value, TYPE_ENUM, i)); \ - } \ - } \ - /* Print Status, Severity - if not NO_ALARM */ \ - if ( ((struct TYPE *)value)->status || ((struct TYPE *)value)->severity ) \ - { \ - printf("%c%s%c%s\n", \ - fieldSeparator, \ - stat_to_str(((struct TYPE *)value)->status), \ - fieldSeparator, \ - sevr_to_str(((struct TYPE *)value)->severity)); \ - } else { \ - printf("%c%c\n", \ - fieldSeparator, fieldSeparator); \ - } - - -void print_time_val_sts (pv* pv, unsigned long reqElems) -{ - char timeText[2*TIMETEXTLEN+2]; - int i, printAbs; - void* value = pv->value; - epicsTimeStamp *ptsRefC, *ptsRefS; /* Reference timestamps (client, server) */ - epicsTimeStamp *ptsNewC, *ptsNewS; /* Update timestamps (client, server) */ - epicsTimeStamp tsNow; - - epicsTimeGetCurrent(&tsNow); - epicsTimeToStrftime(timeText, TIMETEXTLEN, timeFormatStr, &tsNow); - - if (!tsInitS) - { - tsFirst = tsNow; - tsInitS = 1; - } - - if (pv->nElems <= 1 && fieldSeparator == ' ') printf("%-30s", pv->name); - else printf("%s", pv->name); - printf("%c", fieldSeparator); - if (!pv->onceConnected) - printf("*** Not connected (PV not found)\n"); - else if (pv->status == ECA_DISCONN) - printf("%s *** disconnected\n", timeText); - else if (pv->status == ECA_NORDACCESS) - printf("%s *** no read access\n", timeText); - else if (pv->status != ECA_NORMAL) - printf("%s *** CA error %s\n", timeText, ca_message(pv->status)); - else if (pv->value == 0) - printf("%s *** no data available (timeout)\n", timeText); - else - switch (pv->dbrType) { - case DBR_TIME_STRING: - PRN_TIME_VAL_STS(dbr_time_string, DBR_TIME_STRING); - break; - case DBR_TIME_SHORT: - PRN_TIME_VAL_STS(dbr_time_short, DBR_TIME_SHORT); - break; - case DBR_TIME_FLOAT: - PRN_TIME_VAL_STS(dbr_time_float, DBR_TIME_FLOAT); - break; - case DBR_TIME_ENUM: - PRN_TIME_VAL_STS(dbr_time_enum, DBR_TIME_ENUM); - break; - case DBR_TIME_CHAR: - PRN_TIME_VAL_STS(dbr_time_char, DBR_TIME_CHAR); - break; - case DBR_TIME_LONG: - PRN_TIME_VAL_STS(dbr_time_long, DBR_TIME_LONG); - break; - case DBR_TIME_DOUBLE: - PRN_TIME_VAL_STS(dbr_time_double, DBR_TIME_DOUBLE); - break; - default: printf("can't print data type\n"); - } -} - - -/*+************************************************************************** - * - * Function: create_pvs - * - * Description: Creates an arbitrary number of PVs - * - * Arg(s) In: pvs - Pointer to an array of pv structures - * nPvs - Number of elements in the pvs array - * pCB - Connection state change callback - * - * Arg(s) Out: none - * - * Return(s): Error code: - * 0 - All PVs created - * 1 - Some PV(s) not created - * - **************************************************************************-*/ - -int create_pvs (pv* pvs, int nPvs, caCh *pCB) -{ - int n; - int result; - int returncode = 0; - - if (!tsInitC) /* Initialize start timestamp */ - { - epicsTimeGetCurrent(&tsStart); - tsInitC = 1; - } - /* Issue channel connections */ - for (n = 0; n < nPvs; n++) { - result = ca_create_channel (pvs[n].name, - pCB, - &pvs[n], - caPriority, - &pvs[n].chid); - if (result != ECA_NORMAL) { - fprintf(stderr, "CA error %s occurred while trying " - "to create channel '%s'.\n", ca_message(result), pvs[n].name); - pvs[n].status = result; - returncode = 1; - } - } - - return returncode; -} - - -/*+************************************************************************** - * - * Function: connect_pvs - * - * Description: Connects an arbitrary number of PVs - * - * Arg(s) In: pvs - Pointer to an array of pv structures - * nPvs - Number of elements in the pvs array - * - * Arg(s) Out: none - * - * Return(s): Error code: - * 0 - All PVs connected - * 1 - Some PV(s) not connected - * - **************************************************************************-*/ - -int connect_pvs (pv* pvs, int nPvs) -{ - int returncode = create_pvs ( pvs, nPvs, 0); - if ( returncode == 0 ) { - /* Wait for channels to connect */ - int result = ca_pend_io (caTimeout); - if (result == ECA_TIMEOUT) - { - if (nPvs > 1) - { - fprintf(stderr, "Channel connect timed out: some PV(s) not found.\n"); - } else { - fprintf(stderr, "Channel connect timed out: '%s' not found.\n", - pvs[0].name); - } - returncode = 1; - } - } - return returncode; -} diff --git a/src/ca/client/tools/tool_lib.h b/src/ca/client/tools/tool_lib.h deleted file mode 100644 index fb5c4af3c..000000000 --- a/src/ca/client/tools/tool_lib.h +++ /dev/null @@ -1,105 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange (BESSY) - * - * Modification History - * 2009/03/31 Larry Hoff (BNL) - * Added field separators - * - */ - -#ifndef INCLtool_libh -#define INCLtool_libh - -#include - -/* Convert status and severity to strings */ -#define stat_to_str(stat) \ - ((stat) >= 0 && (stat) <= (signed)lastEpicsAlarmCond) ? \ - epicsAlarmConditionStrings[stat] : "??" - -#define sevr_to_str(stat) \ - ((stat) >= 0 && (stat) <= (signed)lastEpicsAlarmSev) ? \ - epicsAlarmSeverityStrings[stat] : "??" - -#define stat_to_str_unsigned(stat) \ - ((stat) <= lastEpicsAlarmCond) ? \ - epicsAlarmConditionStrings[stat] : "??" - -#define sevr_to_str_unsigned(stat) \ - ((stat) <= lastEpicsAlarmSev) ? \ - epicsAlarmSeverityStrings[stat] : "??" - -/* The different versions are necessary because stat and sevr are - * defined unsigned in CA's DBR_STSACK structure and signed in all the - * others. Some compilers generate warnings if you check an unsigned - * being >=0 */ - - -#define DEFAULT_CA_PRIORITY 0 /* Default CA priority */ -#define DEFAULT_TIMEOUT 1.0 /* Default CA timeout */ - -#ifndef _WIN32 -# define LINE_BUFFER(stream) setvbuf(stream, NULL, _IOLBF, BUFSIZ) -#else -/* Windows doesn't support line mode, turn buffering off completely */ -# define LINE_BUFFER(stream) setvbuf(stream, NULL, _IONBF, 0) -#endif - - -/* Type of timestamp */ -typedef enum { absolute, relative, incremental, incrementalByChan } TimeT; - -/* Output formats for integer data types */ -typedef enum { dec, bin, oct, hex } IntFormatT; - -/* Structure representing one PV (= channel) */ -typedef struct -{ - char* name; - chid chid; - long dbfType; - long dbrType; - unsigned long nElems; // True length of data in value - unsigned long reqElems; // Requested length of data - int status; - void* value; - epicsTimeStamp tsPreviousC; - epicsTimeStamp tsPreviousS; - char firstStampPrinted; - char onceConnected; -} pv; - - -extern TimeT tsType; /* Timestamp type flag (-t option) */ -extern int tsSrcServer; /* Timestamp source flag (-t option) */ -extern int tsSrcClient; /* Timestamp source flag (-t option) */ -extern IntFormatT outTypeI; /* Flag used for -0.. output format option */ -extern IntFormatT outTypeF; /* Flag used for -l.. output format option */ -extern int enumAsNr; /* Used for -n option (get DBF_ENUM as number) */ -extern int charArrAsStr; /* used for -S option - treat char array as (long) string */ -extern double caTimeout; /* Wait time default (see -w option) */ -extern char dblFormatStr[]; /* Format string to print doubles (see -e -f option) */ -extern char fieldSeparator; /* Output field separator */ -extern capri caPriority; /* CA priority */ - -extern char *val2str (const void *v, unsigned type, int index); -extern char *dbr2str (const void *value, unsigned type); -extern void print_time_val_sts (pv *pv, unsigned long reqElems); -extern int create_pvs (pv *pvs, int nPvs, caCh *pCB ); -extern int connect_pvs (pv *pvs, int nPvs ); - -/* - * no additions below this endif - */ -#endif /* ifndef INCLtool_libh */ diff --git a/src/ca/client/ucx.h b/src/ca/client/ucx.h deleted file mode 100644 index c164161a5..000000000 --- a/src/ca/client/ucx.h +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * - * U C X . H - * UNIX ioctl structures and defines used for VAX/UCX - * - */ -#ifndef _UCX_H_ -# define _UCX_H_ -#ifdef UCX - -#define IFF_UP 0x1 /* interface is up */ -#define IFF_BROADCAST 0x2 /* broadcast address valid */ -#define IFF_LOOPBACK 0x8 /* is a loopback net */ -#define IFF_POINTOPOINT 0x10 /* interface is point to point */ -/* - * Interface request structure used for socket - * ioctl's. All interface ioctl's must have parameter - * definitions which begin with ifr_name. The - * remainder may be interface specific. - */ -struct ifreq { -#define IFNAMSIZ 16 - char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - union { - struct sockaddr ifru_addr; - struct sockaddr ifru_dstaddr; - struct sockaddr ifru_broadaddr; - short ifru_flags; - int ifru_metric; - caddr_t ifru_data; - } ifr_ifru; -#define ifr_addr ifr_ifru.ifru_addr /* address */ -#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ -#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ -#define ifr_flags ifr_ifru.ifru_flags /* flags */ -#define ifr_metric ifr_ifru.ifru_metric /* metric */ -#define ifr_data ifr_ifru.ifru_data /* for use by interface */ -}; - -/* Structure used in SIOCGIFCONF request. - * Used to retrieve interface configuration - * for machine (useful for programs which - * must know all networks accessible). - */ -struct ifconf { - int ifc_len; /* size of associated buffer */ - union { - caddr_t ifcu_buf; - struct ifreq *ifcu_req; - } ifc_ifcu; -#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ -#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */ -}; - -#ifndef NBBY -# define NBBY 8 -#endif - - -#ifndef FD_SETSIZE -# define FD_SETSIZE 256 -#endif - -typedef long fd_mask ; -#define NFDBITS (sizeof (fd_mask) * NBBY ) /* bits per mask */ -#ifndef howmany -# define howmany(x, y) (((x)+((y)-1))/(y)) -#endif - -/* - * Both DEC C and VAX C only allow 32 fd's at once - */ -typedef int fd_set ; - -#define FD_SET(n, p) (*(p) |= (1 << ((n) % NFDBITS))) -#define FD_CLR(n, p) (*(p) &= ~(1 << ((n) % NFDBITS))) -#define FD_ISSET(n, p) (*(p) & (1 << ((n) % NFDBITS))) -#define FD_ZERO(p) memset((char *)(p), 0, sizeof (*(p))) - -#include -#define IO$_RECEIVE (IO$_WRITEVBLK) - -struct timezone { - int tz_minuteswest ; /* minutes west of Greenwich */ - int tz_dsttime ; /* type of dst correction */ -}; - -#define TWOPOWER32 4294967296.0 -#define TWOPOWER31 2147483648.0 -#define UNIX_EPOCH_AS_MJD 40587.0 -#endif -#endif - diff --git a/src/ca/client/udpiiu.cpp b/src/ca/client/udpiiu.cpp deleted file mode 100644 index 33741aad0..000000000 --- a/src/ca/client/udpiiu.cpp +++ /dev/null @@ -1,1445 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * Author: Jeff Hill - */ - -#ifdef _MSC_VER -# pragma warning(disable:4355) -#endif - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" - -#include "envDefs.h" -#include "dbDefs.h" -#include "osiProcess.h" -#include "osiWireFormat.h" -#include "epicsAlgorithm.h" -#include "errlog.h" -#include "locationException.h" - -#define epicsExportSharedSymbols -#include "addrList.h" -#include "caerr.h" // for ECA_NOSEARCHADDR -#include "udpiiu.h" -#include "iocinf.h" -#include "inetAddrID.h" -#include "cac.h" -#include "disconnectGovernorTimer.h" - -// UDP protocol dispatch table -const udpiiu::pProtoStubUDP udpiiu::udpJumpTableCAC [] = -{ - &udpiiu::versionAction, - &udpiiu::badUDPRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::searchRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::exceptionRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::beaconAction, - &udpiiu::notHereRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::badUDPRespAction, - &udpiiu::repeaterAckAction, -}; - - -static -double getMaxPeriod() -{ - double maxPeriod = maxSearchPeriodDefault; - - if ( envGetConfigParamPtr ( & EPICS_CA_MAX_SEARCH_PERIOD ) ) { - long longStatus = envGetDoubleConfigParam ( - & EPICS_CA_MAX_SEARCH_PERIOD, & maxPeriod ); - if ( ! longStatus ) { - if ( maxPeriod < maxSearchPeriodLowerLimit ) { - epicsPrintf ( "\"%s\" out of range (low)\n", - EPICS_CA_MAX_SEARCH_PERIOD.name ); - maxPeriod = maxSearchPeriodLowerLimit; - epicsPrintf ( "Setting \"%s\" = %f seconds\n", - EPICS_CA_MAX_SEARCH_PERIOD.name, maxPeriod ); - } - } - else { - epicsPrintf ( "EPICS \"%s\" wasnt a real number\n", - EPICS_CA_MAX_SEARCH_PERIOD.name ); - epicsPrintf ( "Setting \"%s\" = %f seconds\n", - EPICS_CA_MAX_SEARCH_PERIOD.name, maxPeriod ); - } - } - - return maxPeriod; -} - -static -unsigned getNTimers(double maxPeriod) -{ - unsigned nTimers = static_cast < unsigned > ( 1.0 + log ( maxPeriod / minRoundTripEstimate ) / log ( 2.0 ) ); - - if ( nTimers > channelNode::getMaxSearchTimerCount () ) { - nTimers = channelNode::getMaxSearchTimerCount (); - epicsPrintf ( "\"%s\" out of range (high)\n", - EPICS_CA_MAX_SEARCH_PERIOD.name ); - epicsPrintf ( "Setting \"%s\" = %f seconds\n", - EPICS_CA_MAX_SEARCH_PERIOD.name, - (1<<(nTimers-1)) * minRoundTripEstimate ); - } - - return nTimers; -} - -// -// udpiiu::udpiiu () -// -udpiiu::udpiiu ( - epicsGuard < epicsMutex > & cacGuard, - epicsTimerQueueActive & timerQueue, - epicsMutex & cbMutexIn, - epicsMutex & cacMutexIn, - cacContextNotify & ctxNotifyIn, - cac & cac, - unsigned port, - tsDLList < SearchDest > & searchDestListIn ) : - recvThread ( *this, ctxNotifyIn, cbMutexIn, "CAC-UDP", - epicsThreadGetStackSize ( epicsThreadStackMedium ), - cac::lowestPriorityLevelAbove ( - cac::lowestPriorityLevelAbove ( - cac.getInitializingThreadsPriority () ) ) ), - m_repeaterTimerNotify ( *this ), - repeaterSubscribeTmr ( - m_repeaterTimerNotify, timerQueue, cbMutexIn, ctxNotifyIn ), - govTmr ( *this, timerQueue, cacMutexIn ), - maxPeriod ( getMaxPeriod() ), - rtteMean ( minRoundTripEstimate ), - rtteMeanDev ( 0 ), - cacRef ( cac ), - cbMutex ( cbMutexIn ), - cacMutex ( cacMutexIn ), - nTimers ( getNTimers(maxPeriod) ), - ppSearchTmr ( nTimers ), - nBytesInXmitBuf ( 0 ), - beaconAnomalyTimerIndex ( 0 ), - sequenceNumber ( 0 ), - lastReceivedSeqNo ( 0 ), - sock ( 0 ), - repeaterPort ( 0 ), - serverPort ( port ), - localPort ( 0 ), - shutdownCmd ( false ), - lastReceivedSeqNoIsValid ( false ) -{ - cacGuard.assertIdenticalMutex ( cacMutex ); - - double powerOfTwo = log ( beaconAnomalySearchPeriod / minRoundTripEstimate ) / log ( 2.0 ); - this->beaconAnomalyTimerIndex = static_cast < unsigned > ( powerOfTwo + 1.0 ); - if ( this->beaconAnomalyTimerIndex >= this->nTimers ) { - this->beaconAnomalyTimerIndex = this->nTimers - 1; - } - - for ( unsigned i = 0; i < this->nTimers; i++ ) { - this->ppSearchTmr[i].reset ( - new searchTimer ( *this, timerQueue, i, cacMutexIn, - i > this->beaconAnomalyTimerIndex ) ); - } - - this->repeaterPort = - envGetInetPortConfigParam ( &EPICS_CA_REPEATER_PORT, - static_cast (CA_REPEATER_PORT) ); - - this->sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); - if ( this->sock == INVALID_SOCKET ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAC: unable to create datagram socket because = \"%s\"\n", - sockErrBuf ); - throwWithLocation ( noSocket () ); - } - -#ifdef IP_ADD_MEMBERSHIP - { - int flag = 1; - if ( setsockopt ( this->sock, IPPROTO_IP, IP_MULTICAST_LOOP, - (char *) &flag, sizeof ( flag ) ) == -1 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf("CAC: failed to set mcast loopback\n"); - } - } -#endif - -#ifdef IP_MULTICAST_TTL - { - int ttl; - long val; - if(envGetLongConfigParam(&EPICS_CA_MCAST_TTL, &val)) - val =1; - ttl = val; - if ( setsockopt(this->sock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ttl, sizeof(ttl))) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf("CAC: failed to set mcast ttl %d\n", ttl); - } - } -#endif - - int boolValue = true; - int status = setsockopt ( this->sock, SOL_SOCKET, SO_BROADCAST, - (char *) &boolValue, sizeof ( boolValue ) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAC: IP broadcasting enable failed because = \"%s\"\n", - sockErrBuf ); - } - -#if 0 - { - /* - * some concern that vxWorks will run out of mBuf's - * if this change is made joh 11-10-98 - * - * bump up the UDP recv buffer - */ - int size = 1u<<15u; - status = setsockopt ( this->sock, SOL_SOCKET, SO_RCVBUF, - (char *)&size, sizeof (size) ); - if (status<0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC: unable to set socket option SO_RCVBUF because \"%s\"\n", - sockErrBuf ); - } - } -#endif - - // force a bind to an unconstrained address so we can obtain - // the local port number below - static const unsigned short PORT_ANY = 0u; - osiSockAddr addr; - memset ( (char *)&addr, 0 , sizeof (addr) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); - addr.ia.sin_port = htons ( PORT_ANY ); - status = bind (this->sock, &addr.sa, sizeof (addr) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy (this->sock); - errlogPrintf ( "CAC: unable to bind to an unconstrained address because = \"%s\"\n", - sockErrBuf ); - throwWithLocation ( noSocket () ); - } - - { - osiSockAddr tmpAddr; - osiSocklen_t saddr_length = sizeof ( tmpAddr ); - status = getsockname ( this->sock, &tmpAddr.sa, &saddr_length ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - epicsSocketDestroy ( this->sock ); - errlogPrintf ( "CAC: getsockname () error was \"%s\"\n", sockErrBuf ); - throwWithLocation ( noSocket () ); - } - if ( tmpAddr.sa.sa_family != AF_INET) { - epicsSocketDestroy ( this->sock ); - errlogPrintf ( "CAC: UDP socket was not inet addr family\n" ); - throwWithLocation ( noSocket () ); - } - this->localPort = ntohs ( tmpAddr.ia.sin_port ); - } - - /* - * load user and auto configured - * broadcast address list - */ - ELLLIST dest; - ellInit ( & dest ); - configureChannelAccessAddressList ( & dest, this->sock, this->serverPort ); - while ( osiSockAddrNode * - pNode = reinterpret_cast < osiSockAddrNode * > ( ellGet ( & dest ) ) ) { - SearchDestUDP & searchDest = * - new SearchDestUDP ( pNode->addr, *this ); - _searchDestList.add ( searchDest ); - free ( pNode ); - } - - /* add list of tcp name service addresses */ - _searchDestList.add ( searchDestListIn ); - - caStartRepeaterIfNotInstalled ( this->repeaterPort ); - - this->pushVersionMsg (); - - // start timers and receive thread - for ( unsigned j =0; j < this->nTimers; j++ ) { - this->ppSearchTmr[j]->start ( cacGuard ); - } - this->govTmr.start (); - this->repeaterSubscribeTmr.start (); - this->recvThread.start (); -} - -/* - * udpiiu::~udpiiu () - */ -udpiiu::~udpiiu () -{ - { - epicsGuard < epicsMutex > cbGuard ( this->cbMutex ); - epicsGuard < epicsMutex > guard ( this->cacMutex ); - this->shutdown ( cbGuard, guard ); - } - - tsDLIter < SearchDest > iter ( _searchDestList.firstIter () ); - while ( iter.valid () ) - { - SearchDest & curr ( *iter ); - iter++; - delete & curr; - } - - epicsSocketDestroy ( this->sock ); -} - -void udpiiu::shutdown ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - // stop all of the timers - this->repeaterSubscribeTmr.shutdown ( cbGuard, guard ); - this->govTmr.shutdown ( cbGuard, guard ); - for ( unsigned i =0; i < this->nTimers; i++ ) { - this->ppSearchTmr[i]->shutdown ( cbGuard, guard ); - } - - { - this->shutdownCmd = true; - epicsGuardRelease < epicsMutex > unguard ( guard ); - { - epicsGuardRelease < epicsMutex > cbUnguard ( cbGuard ); - - if ( ! this->recvThread.exitWait ( 0.0 ) ) { - unsigned tries = 0u; - - this->wakeupMsg (); - - // wait for recv threads to exit - double shutdownDelay = 1.0; - while ( ! this->recvThread.exitWait ( shutdownDelay ) ) { - this->wakeupMsg (); - if ( shutdownDelay < 16.0 ) { - shutdownDelay += shutdownDelay; - } - if ( ++tries > 3 ) { - fprintf ( stderr, "cac: timing out waiting for UDP thread shutdown\n" ); - } - } - } - } - } -} - -udpRecvThread::udpRecvThread ( - udpiiu & iiuIn, cacContextNotify & ctxNotifyIn, epicsMutex & cbMutexIn, - const char * pName, unsigned stackSize, unsigned priority ) : - iiu ( iiuIn ), cbMutex ( cbMutexIn ), ctxNotify ( ctxNotifyIn ), - thread ( *this, pName, stackSize, priority ) {} - -udpRecvThread::~udpRecvThread () -{ -} - -void udpRecvThread::start () -{ - this->thread.start (); -} - -bool udpRecvThread::exitWait ( double delay ) -{ - return this->thread.exitWait ( delay ); -} - -void udpRecvThread::show ( unsigned /* level */ ) const -{ -} - -void udpRecvThread::run () -{ - epicsThreadPrivateSet ( caClientCallbackThreadId, &this->iiu ); - - if ( this->iiu._searchDestList.count () == 0 ) { - callbackManager mgr ( this->ctxNotify, this->cbMutex ); - epicsGuard < epicsMutex > guard ( this->iiu.cacMutex ); - genLocalExcep ( mgr.cbGuard, guard, - this->iiu.cacRef, ECA_NOSEARCHADDR, NULL ); - } - - do { - osiSockAddr src; - osiSocklen_t src_size = sizeof ( src ); - int status = recvfrom ( this->iiu.sock, - this->iiu.recvBuf, sizeof ( this->iiu.recvBuf ), 0, - & src.sa, & src_size ); - - if ( status <= 0 ) { - - if ( status < 0 ) { - int errnoCpy = SOCKERRNO; - if ( - errnoCpy != SOCK_EINTR && - errnoCpy != SOCK_SHUTDOWN && - errnoCpy != SOCK_ENOTSOCK && - errnoCpy != SOCK_EBADF && - // Avoid spurious ECONNREFUSED bug in linux - errnoCpy != SOCK_ECONNREFUSED && - // Avoid ECONNRESET from disconnected socket bug - // in windows - errnoCpy != SOCK_ECONNRESET ) { - - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAC: UDP recv error was \"%s\"\n", - sockErrBuf ); - } - } - } - else if ( status > 0 ) { - this->iiu.postMsg ( src, this->iiu.recvBuf, - (arrayElementCount) status, epicsTime::getCurrent() ); - } - - } while ( ! this->iiu.shutdownCmd ); -} - -/* for sunpro compiler */ -udpiiu::M_repeaterTimerNotify::~M_repeaterTimerNotify () -{ -} - -/* - * udpiiu::M_repeaterTimerNotify::repeaterRegistrationMessage () - * - * register with the repeater - */ -void udpiiu :: M_repeaterTimerNotify :: repeaterRegistrationMessage ( unsigned attemptNumber ) -{ - epicsGuard < epicsMutex > cbGuard ( m_udpiiu.cacMutex ); - caRepeaterRegistrationMessage ( m_udpiiu.sock, m_udpiiu.repeaterPort, attemptNumber ); -} - -/* - * caRepeaterRegistrationMessage () - * - * register with the repeater - */ -void epicsShareAPI caRepeaterRegistrationMessage ( - SOCKET sock, unsigned repeaterPort, unsigned attemptNumber ) -{ - osiSockAddr saddr; - caHdr msg; - int status; - int len; - - assert ( repeaterPort <= USHRT_MAX ); - unsigned short port = static_cast ( repeaterPort ); - - /* - * In 3.13 beta 11 and before the CA repeater calls local_addr() - * to determine a local address and does not allow registration - * messages originating from other addresses. In these - * releases local_addr() returned the address of the first enabled - * interface found, and this address may or may not have been the loop - * back address. Starting with 3.13 beta 12 local_addr() was - * changed to always return the address of the first enabled - * non-loopback interface because a valid non-loopback local - * address is required in the beacon messages. Therefore, to - * guarantee compatibility with past versions of the repeater - * we alternate between the address returned by local_addr() - * and the loopback address here. - * - * CA repeaters in R3.13 beta 12 and higher allow - * either the loopback address or the address returned - * by local address (the first non-loopback address found) - */ - if ( attemptNumber & 1 ) { - saddr = osiLocalAddr ( sock ); - if ( saddr.sa.sa_family != AF_INET ) { - /* - * use the loop back address to communicate with the CA repeater - * if this os does not have interface query capabilities - * - * this will only work with 3.13 beta 12 CA repeaters or later - */ - saddr.ia.sin_family = AF_INET; - saddr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - saddr.ia.sin_port = htons ( port ); - } - else { - saddr.ia.sin_port = htons ( port ); - } - } - else { - saddr.ia.sin_family = AF_INET; - saddr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - saddr.ia.sin_port = htons ( port ); - } - - memset ( (char *) &msg, 0, sizeof (msg) ); - AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = REPEATER_REGISTER; - msg.m_available = saddr.ia.sin_addr.s_addr; - - /* - * Intentionally sending a zero length message here - * until most CA repeater daemons have been restarted - * (and only then will they accept the above protocol) - * (repeaters began accepting this protocol - * starting with EPICS 3.12) - */ -# if defined ( DOES_NOT_ACCEPT_ZERO_LENGTH_UDP ) - len = sizeof (msg); -# else - len = 0; -# endif - - status = sendto ( sock, (char *) &msg, len, 0, - &saddr.sa, sizeof ( saddr ) ); - if ( status < 0 ) { - int errnoCpy = SOCKERRNO; - /* - * Different OS return different codes when the repeater isnt running. - * Its ok to supress these messages because I print another warning message - * if we time out registerring with the repeater. - * - * Linux returns SOCK_ECONNREFUSED - * Windows 2000 returns SOCK_ECONNRESET - */ - if ( errnoCpy != SOCK_EINTR && - errnoCpy != SOCK_ECONNREFUSED && - errnoCpy != SOCK_ECONNRESET ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf ( stderr, "error sending registration message to CA repeater daemon was \"%s\"\n", - sockErrBuf ); - } - } -} - -/* - * caStartRepeaterIfNotInstalled () - * - * Test for the repeater already installed - * - * NOTE: potential race condition here can result - * in two copies of the repeater being spawned - * however the repeater detects this, prints a message, - * and lets the other task start the repeater. - * - * QUESTION: is there a better way to test for a port in use? - * ANSWER: none that I can find. - * - * Problems with checking for the repeater installed - * by attempting to bind a socket to its address - * and port. - * - * 1) Closed socket may not release the bound port - * before the repeater wakes up and tries to grab it. - * Attempting to bind the open socket to another port - * also does not work. - * - * 072392 - problem solved by using SO_REUSEADDR - */ -void epicsShareAPI caStartRepeaterIfNotInstalled ( unsigned repeaterPort ) -{ - bool installed = false; - int status; - SOCKET tmpSock; - union { - struct sockaddr_in ia; - struct sockaddr sa; - } bd; - - if ( repeaterPort > 0xffff ) { - fprintf ( stderr, "caStartRepeaterIfNotInstalled () : strange repeater port specified\n" ); - return; - } - - tmpSock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); - if ( tmpSock != INVALID_SOCKET ) { - ca_uint16_t port = static_cast < ca_uint16_t > ( repeaterPort ); - memset ( (char *) &bd, 0, sizeof ( bd ) ); - bd.ia.sin_family = AF_INET; - bd.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); - bd.ia.sin_port = htons ( port ); - status = bind ( tmpSock, &bd.sa, sizeof ( bd ) ); - if ( status < 0 ) { - if ( SOCKERRNO == SOCK_EADDRINUSE ) { - installed = true; - } - else { - fprintf ( stderr, "caStartRepeaterIfNotInstalled () : bind failed\n" ); - } - } - } - - /* - * turn on reuse only after the test so that - * this works on kernels that support multicast - */ - epicsSocketEnableAddressReuseDuringTimeWaitState ( tmpSock ); - - epicsSocketDestroy ( tmpSock ); - - if ( ! installed ) { - - /* - * This is not called if the repeater is known to be - * already running. (in the event of a race condition - * the 2nd repeater exits when unable to attach to the - * repeater's port) - */ - osiSpawnDetachedProcessReturn osptr = - osiSpawnDetachedProcess ( "CA Repeater", "caRepeater" ); - if ( osptr == osiSpawnDetachedProcessNoSupport ) { - epicsThreadId tid; - - tid = epicsThreadCreate ( "CAC-repeater", epicsThreadPriorityLow, - epicsThreadGetStackSize ( epicsThreadStackMedium ), caRepeaterThread, 0); - if ( tid == 0 ) { - fprintf ( stderr, "caStartRepeaterIfNotInstalled : unable to create CA repeater daemon thread\n" ); - } - } - else if ( osptr == osiSpawnDetachedProcessFail ) { - fprintf ( stderr, "caStartRepeaterIfNotInstalled (): unable to start CA repeater daemon detached process\n" ); - } - } -} - -bool udpiiu::badUDPRespAction ( - const caHdr &msg, const osiSockAddr &netAddr, const epicsTime ¤tTime ) -{ - char buf[64]; - sockAddrToDottedIP ( &netAddr.sa, buf, sizeof ( buf ) ); - char date[64]; - currentTime.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S"); - errlogPrintf ( "CAC: Undecipherable ( bad msg code %u ) UDP message from %s at %s\n", - msg.m_cmmd, buf, date ); - return false; -} - -bool udpiiu::versionAction ( - const caHdr & hdr, const osiSockAddr &, const epicsTime & /* currentTime */ ) -{ - epicsGuard < epicsMutex > guard ( this->cacMutex ); - - // update the round trip time estimate - if ( hdr.m_dataType & sequenceNoIsValid ) { - this->lastReceivedSeqNo = hdr.m_cid; - this->lastReceivedSeqNoIsValid = true; - } - - return true; -} - -bool udpiiu :: searchRespAction ( - const caHdr & msg, const osiSockAddr & addr, - const epicsTime & currentTime ) -{ - /* - * we dont currently know what to do with channel's - * found to be at non-IP type addresses - */ - if ( addr.sa.sa_family != AF_INET ) { - return true; - } - - /* - * Starting with CA V4.1 the minor version number - * is appended to the end of each UDP search reply. - * This value is ignored by earlier clients. - */ - ca_uint32_t minorVersion; - if ( msg.m_postsize >= sizeof ( minorVersion ) ){ - /* - * care is taken here not to break gcc 3.2 aggressive alias - * analysis rules - */ - const ca_uint8_t * pPayLoad = - reinterpret_cast < const ca_uint8_t *> ( & msg + 1 ); - unsigned byte0 = pPayLoad[0]; - unsigned byte1 = pPayLoad[1]; - minorVersion = ( byte0 << 8u ) | byte1; - } - else { - minorVersion = CA_UKN_MINOR_VERSION; - } - - /* - * the type field is abused to carry the port number - * so that we can have multiple servers on one host - */ - osiSockAddr serverAddr; - serverAddr.ia.sin_family = AF_INET; - if ( CA_V48 ( minorVersion ) ) { - if ( msg.m_cid != INADDR_BROADCAST ) { - serverAddr.ia.sin_addr.s_addr = htonl ( msg.m_cid ); - } - else { - serverAddr.ia.sin_addr = addr.ia.sin_addr; - } - serverAddr.ia.sin_port = htons ( msg.m_dataType ); - } - else if ( CA_V45 (minorVersion) ) { - serverAddr.ia.sin_port = htons ( msg.m_dataType ); - serverAddr.ia.sin_addr = addr.ia.sin_addr; - } - else { - serverAddr.ia.sin_port = htons ( this->serverPort ); - serverAddr.ia.sin_addr = addr.ia.sin_addr; - } - - if ( CA_V42 ( minorVersion ) ) { - cacRef.transferChanToVirtCircuit - ( msg.m_available, msg.m_cid, 0xffff, - 0, minorVersion, serverAddr, currentTime ); - } - else { - cacRef.transferChanToVirtCircuit - ( msg.m_available, msg.m_cid, msg.m_dataType, - msg.m_count, minorVersion, serverAddr, currentTime ); - } - - return true; -} - -bool udpiiu::beaconAction ( - const caHdr & msg, - const osiSockAddr & net_addr, const epicsTime & currentTime ) -{ - struct sockaddr_in ina; - - memset(&ina, 0, sizeof(struct sockaddr_in)); - - if ( net_addr.sa.sa_family != AF_INET ) { - return false; - } - - /* - * this allows a fan-out server to potentially - * insert the true address of the CA server - * - * old servers: - * 1) set this field to one of the ip addresses of the host _or_ - * 2) set this field to INADDR_ANY - * new servers: - * always set this field to INADDR_ANY - * - * clients always assume that if this - * field is set to something that isnt INADDR_ANY - * then it is the overriding IP address of the server. - */ - ina.sin_family = AF_INET; - ina.sin_addr.s_addr = htonl ( msg.m_available ); - if ( msg.m_count != 0 ) { - ina.sin_port = htons ( msg.m_count ); - } - else { - /* - * old servers dont supply this and the - * default port must be assumed - */ - ina.sin_port = htons ( this->serverPort ); - } - unsigned protocolRevision = msg.m_dataType; - ca_uint32_t beaconNumber = msg.m_cid; - - this->cacRef.beaconNotify ( ina, currentTime, - beaconNumber, protocolRevision ); - - return true; -} - -bool udpiiu::repeaterAckAction ( - const caHdr &, - const osiSockAddr &, const epicsTime &) -{ - this->repeaterSubscribeTmr.confirmNotify (); - return true; -} - -bool udpiiu::notHereRespAction ( - const caHdr &, - const osiSockAddr &, const epicsTime & ) -{ - return true; -} - -bool udpiiu::exceptionRespAction ( - const caHdr &msg, - const osiSockAddr & net_addr, const epicsTime & currentTime ) -{ - const caHdr &reqMsg = * ( &msg + 1 ); - char name[64]; - sockAddrToDottedIP ( &net_addr.sa, name, sizeof ( name ) ); - char date[64]; - currentTime.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S"); - - if ( msg.m_postsize > sizeof ( caHdr ) ){ - errlogPrintf ( - "error condition \"%s\" detected by %s with context \"%s\" at %s\n", - ca_message ( msg.m_available ), - name, reinterpret_cast ( &reqMsg + 1 ), date ); - } - else{ - errlogPrintf ( - "error condition \"%s\" detected by %s at %s\n", - ca_message ( msg.m_available ), name, date ); - } - - return true; -} - -void udpiiu::postMsg ( - const osiSockAddr & net_addr, - char * pInBuf, arrayElementCount blockSize, - const epicsTime & currentTime ) -{ - caHdr *pCurMsg; - - this->lastReceivedSeqNoIsValid = false; - this->lastReceivedSeqNo = 0u; - - while ( blockSize ) { - arrayElementCount size; - - if ( blockSize < sizeof ( *pCurMsg ) ) { - char buf[64]; - sockAddrToDottedIP ( &net_addr.sa, buf, sizeof ( buf ) ); - errlogPrintf ( - "%s: Undecipherable (too small) UDP msg from %s ignored\n", - __FILE__, buf ); - return; - } - - pCurMsg = reinterpret_cast < caHdr * > ( pInBuf ); - - /* - * fix endian of bytes - */ - pCurMsg->m_postsize = AlignedWireRef < epicsUInt16 > ( pCurMsg->m_postsize ); - pCurMsg->m_cmmd = AlignedWireRef < epicsUInt16 > ( pCurMsg->m_cmmd ); - pCurMsg->m_dataType = AlignedWireRef < epicsUInt16 > ( pCurMsg->m_dataType ); - pCurMsg->m_count = AlignedWireRef < epicsUInt16 > ( pCurMsg->m_count ); - pCurMsg->m_available = AlignedWireRef < epicsUInt32 > ( pCurMsg->m_available ); - pCurMsg->m_cid = AlignedWireRef < epicsUInt32 > ( pCurMsg->m_cid ); - -#if 0 - printf ( "UDP Cmd=%3d Type=%3d Count=%4d Size=%4d", - pCurMsg->m_cmmd, - pCurMsg->m_dataType, - pCurMsg->m_count, - pCurMsg->m_postsize ); - printf (" Avail=%8x Cid=%6d\n", - pCurMsg->m_available, - pCurMsg->m_cid ); -#endif - - size = pCurMsg->m_postsize + sizeof ( *pCurMsg ); - - /* - * dont allow msg body extending beyond frame boundary - */ - if ( size > blockSize ) { - char buf[64]; - sockAddrToDottedIP ( &net_addr.sa, buf, sizeof ( buf ) ); - errlogPrintf ( - "%s: Undecipherable (payload too small) UDP msg from %s ignored\n", - __FILE__, buf ); - return; - } - - /* - * execute the response message - */ - pProtoStubUDP pStub; - if ( pCurMsg->m_cmmd < NELEMENTS ( udpJumpTableCAC ) ) { - pStub = udpJumpTableCAC [pCurMsg->m_cmmd]; - } - else { - pStub = &udpiiu::badUDPRespAction; - } - bool success = ( this->*pStub ) ( *pCurMsg, net_addr, currentTime ); - if ( ! success ) { - char buf[256]; - sockAddrToDottedIP ( &net_addr.sa, buf, sizeof ( buf ) ); - errlogPrintf ( "CAC: Undecipherable UDP message from %s\n", buf ); - return; - } - - blockSize -= size; - pInBuf += size;; - } -} - -bool udpiiu::pushVersionMsg () -{ - epicsGuard < epicsMutex > guard ( this->cacMutex ); - - this->sequenceNumber++; - - caHdr msg; - AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = CA_PROTO_VERSION; - AlignedWireRef < epicsUInt32 > ( msg.m_available ) = 0; - AlignedWireRef < epicsUInt16 > ( msg.m_dataType ) = sequenceNoIsValid; - AlignedWireRef < epicsUInt16 > ( msg.m_count ) = CA_MINOR_PROTOCOL_REVISION; - AlignedWireRef < epicsUInt32 > ( msg.m_cid ) = this->sequenceNumber; // sequence number - - return this->pushDatagramMsg ( guard, msg, 0, 0 ); -} - -bool udpiiu::pushDatagramMsg ( epicsGuard < epicsMutex > & guard, - const caHdr & msg, const void * pExt, ca_uint16_t extsize ) -{ - guard.assertIdenticalMutex ( this->cacMutex ); - - ca_uint16_t alignedExtSize = static_cast (CA_MESSAGE_ALIGN ( extsize )); - arrayElementCount msgsize = sizeof ( caHdr ) + alignedExtSize; - - /* fail out if max message size exceeded */ - if ( msgsize >= sizeof ( this->xmitBuf ) - 7 ) { - return false; - } - - if ( msgsize + this->nBytesInXmitBuf > sizeof ( this->xmitBuf ) ) { - return false; - } - - caHdr * pbufmsg = ( caHdr * ) &this->xmitBuf[this->nBytesInXmitBuf]; - *pbufmsg = msg; - if ( extsize ) { - memcpy ( pbufmsg + 1, pExt, extsize ); - if ( extsize != alignedExtSize ) { - char *pDest = (char *) ( pbufmsg + 1 ); - memset ( pDest + extsize, '\0', alignedExtSize - extsize ); - } - } - AlignedWireRef < epicsUInt16 > ( pbufmsg->m_postsize ) = alignedExtSize; - this->nBytesInXmitBuf += msgsize; - - return true; -} - -udpiiu :: SearchDestUDP :: SearchDestUDP ( - const osiSockAddr & destAddr, udpiiu & udpiiuIn ) : - _destAddr ( destAddr ), _udpiiu ( udpiiuIn ) -{ -} - -void udpiiu :: SearchDestUDP :: searchRequest ( - epicsGuard < epicsMutex > & guard, const char * pBuf, size_t bufSize ) -{ - guard.assertIdenticalMutex ( _udpiiu.cacMutex ); - assert ( bufSize <= INT_MAX ); - int bufSizeAsInt = static_cast < int > ( bufSize ); - while ( true ) { - // This const_cast is needed for vxWorks: - int status = sendto ( _udpiiu.sock, const_cast(pBuf), bufSizeAsInt, 0, - & _destAddr.sa, sizeof ( _destAddr.sa ) ); - if ( status == bufSizeAsInt ) { - break; - } - if ( status >= 0 ) { - errlogPrintf ( "CAC: UDP sendto () call returned strange xmit count?\n" ); - break; - } - else { - int localErrno = SOCKERRNO; - - if ( localErrno == SOCK_EINTR ) { - if ( _udpiiu.shutdownCmd ) { - break; - } - else { - continue; - } - } - else if ( localErrno == SOCK_SHUTDOWN ) { - break; - } - else if ( localErrno == SOCK_ENOTSOCK ) { - break; - } - else if ( localErrno == SOCK_EBADF ) { - break; - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - char buf[64]; - sockAddrToDottedIP ( &_destAddr.sa, buf, sizeof ( buf ) ); - errlogPrintf ( - "CAC: error = \"%s\" sending UDP msg to %s\n", - sockErrBuf, buf); - break; - } - } - } -} - -void udpiiu :: SearchDestUDP :: show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - guard.assertIdenticalMutex ( _udpiiu.cacMutex ); - char buf[64]; - sockAddrToDottedIP ( &_destAddr.sa, buf, sizeof ( buf ) ); - :: printf ( "UDP Search destination \"%s\"\n", buf ); -} - -udpiiu :: SearchRespCallback :: SearchRespCallback ( udpiiu & udpiiuIn ) : - _udpiiu ( udpiiuIn ) -{ -} - -void udpiiu :: SearchRespCallback :: notify ( - const caHdr & msg, const void * pPayloadUntyped, - const osiSockAddr & addr, const epicsTime & currentTime ) -{ - /* - * we dont currently know what to do with channel's - * found to be at non-IP type addresses - */ - if ( addr.sa.sa_family != AF_INET ) { - return; - } - - /* - * Starting with CA V4.1 the minor version number - * is appended to the end of each search reply. - * This value is ignored by earlier clients. - */ - ca_uint32_t minorVersion; - if ( msg.m_postsize >= sizeof ( minorVersion ) ){ - /* - * care is taken here not to break gcc 3.2 aggressive alias - * analysis rules - */ - const ca_uint8_t * pPayLoad = reinterpret_cast < const ca_uint8_t *> ( pPayloadUntyped ); - unsigned byte0 = pPayLoad[0]; - unsigned byte1 = pPayLoad[1]; - minorVersion = ( byte0 << 8u ) | byte1; - } - else { - minorVersion = CA_UKN_MINOR_VERSION; - } - - /* - * the type field is abused to carry the port number - * so that we can have multiple servers on one host - */ - osiSockAddr serverAddr; - serverAddr.ia.sin_family = AF_INET; - if ( CA_V48 ( minorVersion ) ) { - if ( msg.m_cid != INADDR_BROADCAST ) { - serverAddr.ia.sin_addr.s_addr = htonl ( msg.m_cid ); - } - else { - serverAddr.ia.sin_addr = addr.ia.sin_addr; - } - serverAddr.ia.sin_port = htons ( msg.m_dataType ); - } - else if ( CA_V45 (minorVersion) ) { - serverAddr.ia.sin_port = htons ( msg.m_dataType ); - serverAddr.ia.sin_addr = addr.ia.sin_addr; - } - else { - serverAddr.ia.sin_port = htons ( _udpiiu.serverPort ); - serverAddr.ia.sin_addr = addr.ia.sin_addr; - } - - if ( CA_V42 ( minorVersion ) ) { - _udpiiu.cacRef.transferChanToVirtCircuit - ( msg.m_available, msg.m_cid, 0xffff, - 0, minorVersion, serverAddr, currentTime ); - } - else { - _udpiiu.cacRef.transferChanToVirtCircuit - ( msg.m_available, msg.m_cid, msg.m_dataType, - msg.m_count, minorVersion, serverAddr, currentTime ); - } -} - -void udpiiu :: SearchRespCallback :: show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - guard.assertIdenticalMutex ( _udpiiu.cacMutex ); - ::printf ( "udpiiu :: SearchRespCallback\n" ); -} - -bool udpiiu :: datagramFlush ( - epicsGuard < epicsMutex > & guard, const epicsTime & currentTime ) -{ - guard.assertIdenticalMutex ( cacMutex ); - - // dont send the version header by itself - if ( this->nBytesInXmitBuf <= sizeof ( caHdr ) ) { - return false; - } - - tsDLIter < SearchDest > iter ( _searchDestList.firstIter () ); - while ( iter.valid () ) - { - iter->searchRequest ( guard, this->xmitBuf, this->nBytesInXmitBuf ); - iter++; - } - - this->nBytesInXmitBuf = 0u; - - this->pushVersionMsg (); - - return true; -} - -void udpiiu :: show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->cacMutex ); - - ::printf ( "Datagram IO circuit (and disconnected channel repository)\n"); - if ( level > 1u ) { - ::printf ("\trepeater port %u\n", this->repeaterPort ); - ::printf ("\tdefault server port %u\n", this->serverPort ); - ::printf ( "Search Destination List with %u items\n", - _searchDestList.count () ); - if ( level > 2u ) { - tsDLIterConst < SearchDest > iter ( - _searchDestList.firstIter () ); - while ( iter.valid () ) - { - iter->show ( guard, level - 2 ); - iter++; - } - } - } - if ( level > 2u ) { - ::printf ("\tsocket identifier %d\n", this->sock ); - ::printf ("\tbytes in xmit buffer %u\n", this->nBytesInXmitBuf ); - ::printf ("\tshut down command bool %u\n", this->shutdownCmd ); - ::printf ( "\trecv thread exit signal:\n" ); - this->recvThread.show ( level - 2u ); - this->repeaterSubscribeTmr.show ( level - 2u ); - this->govTmr.show ( level - 2u ); - } - if ( level > 3u ) { - for ( unsigned i =0; i < this->nTimers; i++ ) { - this->ppSearchTmr[i]->show ( level - 3u ); - } - } -} - -bool udpiiu::wakeupMsg () -{ - caHdr msg; - AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = CA_PROTO_VERSION; - AlignedWireRef < epicsUInt32 > ( msg.m_available ) = 0u; - AlignedWireRef < epicsUInt16 > ( msg.m_dataType ) = 0u; - AlignedWireRef < epicsUInt16 > ( msg.m_count ) = 0u; - AlignedWireRef < epicsUInt32 > ( msg.m_cid ) = 0u; - AlignedWireRef < epicsUInt16 > ( msg.m_postsize ) = 0u; - - osiSockAddr addr; - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - addr.ia.sin_port = htons ( this->localPort ); - - // send a wakeup msg so the UDP recv thread will exit - int status = sendto ( this->sock, reinterpret_cast < char * > ( &msg ), - sizeof (msg), 0, &addr.sa, sizeof ( addr.sa ) ); - if ( status == sizeof (msg) ) { - return true; - } - return false; -} - -void udpiiu::beaconAnomalyNotify ( - epicsGuard < epicsMutex > & cacGuard ) -{ - for ( unsigned i = this->beaconAnomalyTimerIndex+1u; - i < this->nTimers; i++ ) { - this->ppSearchTmr[i]->moveChannels ( cacGuard, - *this->ppSearchTmr[this->beaconAnomalyTimerIndex] ); - } -} - -void udpiiu::uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > & guard, nciu & chan, - const epicsTime & currentTime ) -{ - channelNode::channelState chanState = - chan.channelNode::listMember; - if ( chanState == channelNode::cs_disconnGov ) { - this->govTmr.uninstallChan ( guard, chan ); - } - else { - this->ppSearchTmr[ chan.getSearchTimerIndex ( guard ) ]-> - uninstallChanDueToSuccessfulSearchResponse ( - guard, chan, this->lastReceivedSeqNo, - this->lastReceivedSeqNoIsValid, currentTime ); - } -} - -void udpiiu::uninstallChan ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - channelNode::channelState chanState = - chan.channelNode::listMember; - if ( chanState == channelNode::cs_disconnGov ) { - this->govTmr.uninstallChan ( guard, chan ); - } - else { - this->ppSearchTmr[ chan.getSearchTimerIndex ( guard ) ]-> - uninstallChan ( guard, chan ); - } -} - -bool udpiiu::searchMsg ( - epicsGuard < epicsMutex > & guard, ca_uint32_t id, - const char * pName, unsigned nameLength ) -{ - caHdr msg; - AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = CA_PROTO_SEARCH; - AlignedWireRef < epicsUInt32 > ( msg.m_available ) = id; - AlignedWireRef < epicsUInt16 > ( msg.m_dataType ) = DONTREPLY; - AlignedWireRef < epicsUInt16 > ( msg.m_count ) = CA_MINOR_PROTOCOL_REVISION; - AlignedWireRef < epicsUInt32 > ( msg.m_cid ) = id; - return this->pushDatagramMsg ( - guard, msg, pName, (ca_uint16_t) nameLength ); -} - -void udpiiu::installNewChannel ( - epicsGuard < epicsMutex > & guard, nciu & chan, netiiu * & piiu ) -{ - piiu = this; - this->ppSearchTmr[0]->installChannel ( guard, chan ); -} - -void udpiiu::installDisconnectedChannel ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - chan.setServerAddressUnknown ( *this, guard ); - this->govTmr.installChan ( guard, chan ); -} - -void udpiiu::noSearchRespNotify ( - epicsGuard < epicsMutex > & guard, nciu & chan, unsigned index ) -{ - const unsigned nTimersMinusOne = this->nTimers - 1; - if ( index < nTimersMinusOne ) { - index++; - } - else { - index = nTimersMinusOne; - } - this->ppSearchTmr[index]->installChannel ( guard, chan ); -} - -void udpiiu::boostChannel ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - this->ppSearchTmr[this->beaconAnomalyTimerIndex]-> - installChannel ( guard, chan ); -} - -void udpiiu::govExpireNotify ( - epicsGuard < epicsMutex > & guard, nciu & chan ) -{ - this->ppSearchTmr[0]->installChannel ( guard, chan ); -} - -int udpiiu :: M_repeaterTimerNotify :: printFormated ( - epicsGuard < epicsMutex > & cbGuard, - const char * pformat, ... ) -{ - va_list theArgs; - int status; - - va_start ( theArgs, pformat ); - - status = m_udpiiu.cacRef.varArgsPrintFormated ( cbGuard, pformat, theArgs ); - - va_end ( theArgs ); - - return status; -} - -void udpiiu::updateRTTE ( epicsGuard < epicsMutex > & guard, double measured ) -{ - guard.assertIdenticalMutex ( this->cacMutex ); - if ( measured > maxRoundTripEstimate ) { - measured = maxRoundTripEstimate; - } - if ( measured < minRoundTripEstimate ) { - measured = minRoundTripEstimate; - } - double error = measured - this->rtteMean; - this->rtteMean += 0.125 * error; - if ( error < 0.0 ) { - error = - error; - } - this->rtteMeanDev = this->rtteMeanDev + .25 * ( error - this->rtteMeanDev ); -} - -double udpiiu::getRTTE ( epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->cacMutex ); - return this->rtteMean + 4 * this->rtteMeanDev; -} - -unsigned udpiiu::getHostName ( - epicsGuard < epicsMutex > & cacGuard, - char *pBuf, unsigned bufLength ) const throw () -{ - return netiiu::getHostName ( cacGuard, pBuf, bufLength ); -} - -const char * udpiiu::pHostName ( - epicsGuard < epicsMutex > & cacGuard ) const throw () -{ - return netiiu::pHostName ( cacGuard ); -} - -bool udpiiu::ca_v42_ok ( - epicsGuard < epicsMutex > & cacGuard ) const -{ - return netiiu::ca_v42_ok ( cacGuard ); -} - -bool udpiiu::ca_v41_ok ( - epicsGuard < epicsMutex > & cacGuard ) const -{ - return netiiu::ca_v41_ok ( cacGuard ); -} - -void udpiiu::writeRequest ( - epicsGuard < epicsMutex > & guard, - nciu & chan, unsigned type, - arrayElementCount nElem, const void * pValue ) -{ - netiiu::writeRequest ( guard, chan, type, nElem, pValue ); -} - -void udpiiu::writeNotifyRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, - netWriteNotifyIO & io, unsigned type, - arrayElementCount nElem, const void *pValue ) -{ - netiiu::writeNotifyRequest ( guard, chan, io, type, nElem, pValue ); -} - -void udpiiu::readNotifyRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, - netReadNotifyIO & io, unsigned type, arrayElementCount nElem ) -{ - netiiu::readNotifyRequest ( guard, chan, io, type, nElem ); -} - -void udpiiu::clearChannelRequest ( - epicsGuard < epicsMutex > & guard, - ca_uint32_t sid, ca_uint32_t cid ) -{ - netiiu::clearChannelRequest ( guard, sid, cid ); -} - -void udpiiu::subscriptionRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, - netSubscription & subscr ) -{ - netiiu::subscriptionRequest ( guard, chan, subscr ); -} - -void udpiiu::subscriptionUpdateRequest ( - epicsGuard < epicsMutex > & guard, nciu & chan, - netSubscription & subscr ) -{ - netiiu::subscriptionUpdateRequest ( - guard, chan, subscr ); -} - -void udpiiu::subscriptionCancelRequest ( - epicsGuard < epicsMutex > & guard, - nciu & chan, netSubscription & subscr ) -{ - netiiu::subscriptionCancelRequest ( guard, chan, subscr ); -} - -void udpiiu::flushRequest ( - epicsGuard < epicsMutex > & guard ) -{ - netiiu::flushRequest ( guard ); -} - -unsigned udpiiu::requestMessageBytesPending ( - epicsGuard < epicsMutex > & guard ) -{ - return netiiu::requestMessageBytesPending ( guard ); -} - -void udpiiu::flush ( - epicsGuard < epicsMutex > & guard ) -{ - netiiu::flush ( guard ); -} - -void udpiiu::requestRecvProcessPostponedFlush ( - epicsGuard < epicsMutex > & guard ) -{ - netiiu::requestRecvProcessPostponedFlush ( guard ); -} - -osiSockAddr udpiiu::getNetworkAddress ( - epicsGuard < epicsMutex > & guard ) const -{ - return netiiu::getNetworkAddress ( guard ); -} - -double udpiiu::receiveWatchdogDelay ( - epicsGuard < epicsMutex > & guard ) const -{ - return netiiu::receiveWatchdogDelay ( guard ); -} - -ca_uint32_t udpiiu::datagramSeqNumber ( - epicsGuard < epicsMutex > & ) const -{ - return this->sequenceNumber; -} - diff --git a/src/ca/client/udpiiu.h b/src/ca/client/udpiiu.h deleted file mode 100644 index 6b41e38ed..000000000 --- a/src/ca/client/udpiiu.h +++ /dev/null @@ -1,317 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef udpiiuh -#define udpiiuh - -#include - -#ifdef epicsExportSharedSymbols -# define udpiiuh_accessh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "osiSock.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "tsDLList.h" - -#ifdef udpiiuh_accessh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "netiiu.h" -#include "searchTimer.h" -#include "disconnectGovernorTimer.h" -#include "repeaterSubscribeTimer.h" -#include "SearchDest.h" - -extern "C" void cacRecvThreadUDP ( void *pParam ); - -epicsShareFunc void epicsShareAPI caStartRepeaterIfNotInstalled ( - unsigned repeaterPort ); -epicsShareFunc void epicsShareAPI caRepeaterRegistrationMessage ( - SOCKET sock, unsigned repeaterPort, unsigned attemptNumber ); -extern "C" epicsShareFunc void caRepeaterThread ( - void * pDummy ); -epicsShareFunc void ca_repeater ( void ); - -class cac; -class cacContextNotify; - -class udpRecvThread : - private epicsThreadRunable { -public: - udpRecvThread ( - class udpiiu & iiuIn, cacContextNotify &, epicsMutex &, - const char * pName, unsigned stackSize, unsigned priority ); - virtual ~udpRecvThread (); - void start (); - bool exitWait ( double delay ); - void show ( unsigned level ) const; -private: - class udpiiu & iiu; - epicsMutex & cbMutex; - cacContextNotify & ctxNotify; - epicsThread thread; - void run(); -}; - -static const double minRoundTripEstimate = 32e-3; // seconds -static const double maxRoundTripEstimate = 30; // seconds -static const double maxSearchPeriodDefault = 5.0 * 60.0; // seconds -static const double maxSearchPeriodLowerLimit = 60.0; // seconds -static const double beaconAnomalySearchPeriod = 5.0; // seconds - -class udpiiu : - private netiiu, - private searchTimerNotify, - private disconnectGovernorNotify { -public: - udpiiu ( - epicsGuard < epicsMutex > & cacGuard, - class epicsTimerQueueActive &, - epicsMutex & callbackControl, - epicsMutex & mutualExclusion, - cacContextNotify &, - class cac &, - unsigned port, - tsDLList < SearchDest > & ); - virtual ~udpiiu (); - void installNewChannel ( - epicsGuard < epicsMutex > &, nciu &, netiiu * & ); - void installDisconnectedChannel ( - epicsGuard < epicsMutex > &, nciu & ); - void beaconAnomalyNotify ( - epicsGuard < epicsMutex > & guard ); - void shutdown ( epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void show ( unsigned level ) const; - - // exceptions - class noSocket {}; - -private: - class SearchDestUDP : - public SearchDest { - public: - SearchDestUDP ( const osiSockAddr &, udpiiu & ); - void searchRequest ( - epicsGuard < epicsMutex > &, const char * pBuf, size_t bufLen ); - void show ( - epicsGuard < epicsMutex > &, unsigned level ) const; - private: - osiSockAddr _destAddr; - udpiiu & _udpiiu; - }; - class SearchRespCallback : - public SearchDest :: Callback { - public: - SearchRespCallback ( udpiiu & ); - void notify ( - const caHdr &, const void * pPayload, - const osiSockAddr &, const epicsTime & ); - void show ( - epicsGuard < epicsMutex > &, unsigned level ) const; - private: - udpiiu & _udpiiu; - }; - class M_repeaterTimerNotify : - public repeaterTimerNotify { - public: - M_repeaterTimerNotify ( udpiiu & iiu ) : - m_udpiiu ( iiu ) {} - ~M_repeaterTimerNotify (); /* for sunpro compiler */ - // repeaterTimerNotify - void repeaterRegistrationMessage ( - unsigned attemptNumber ); - int printFormated ( - epicsGuard < epicsMutex > & callbackControl, - const char * pformat, ... ); - private: - udpiiu & m_udpiiu; - }; - char xmitBuf [MAX_UDP_SEND]; - char recvBuf [MAX_UDP_RECV]; - udpRecvThread recvThread; - M_repeaterTimerNotify m_repeaterTimerNotify; - repeaterSubscribeTimer repeaterSubscribeTmr; - disconnectGovernorTimer govTmr; - tsDLList < SearchDest > _searchDestList; - const double maxPeriod; - double rtteMean; - double rtteMeanDev; - cac & cacRef; - epicsMutex & cbMutex; - epicsMutex & cacMutex; - const unsigned nTimers; - struct SearchArray { - typedef std::auto_ptr value_type; - value_type *arr; - SearchArray(size_t n) : arr(new value_type[n]) {} - ~SearchArray() { delete[] arr; } - value_type& operator[](size_t i) const { return arr[i]; } - private: - SearchArray(const SearchArray&); - SearchArray& operator=(const SearchArray&); - } ppSearchTmr; - unsigned nBytesInXmitBuf; - unsigned beaconAnomalyTimerIndex; - ca_uint32_t sequenceNumber; - ca_uint32_t lastReceivedSeqNo; - SOCKET sock; - ca_uint16_t repeaterPort; - ca_uint16_t serverPort; - ca_uint16_t localPort; - bool shutdownCmd; - bool lastReceivedSeqNoIsValid; - - bool wakeupMsg (); - - void postMsg ( - const osiSockAddr & net_addr, - char *pInBuf, arrayElementCount blockSize, - const epicsTime ¤Time ); - - bool pushDatagramMsg ( epicsGuard < epicsMutex > &, - const caHdr & hdr, const void * pExt, - ca_uint16_t extsize); - - typedef bool ( udpiiu::*pProtoStubUDP ) ( - const caHdr &, - const osiSockAddr &, const epicsTime & ); - - // UDP protocol dispatch table - static const pProtoStubUDP udpJumpTableCAC[]; - - // UDP protocol stubs - bool versionAction ( - const caHdr &, - const osiSockAddr &, const epicsTime & ); - bool badUDPRespAction ( - const caHdr &msg, - const osiSockAddr &netAddr, const epicsTime & ); - bool searchRespAction ( - const caHdr &msg, - const osiSockAddr &net_addr, const epicsTime & ); - bool exceptionRespAction ( - const caHdr &msg, - const osiSockAddr &net_addr, const epicsTime & ); - bool beaconAction ( - const caHdr &msg, - const osiSockAddr &net_addr, const epicsTime & ); - bool notHereRespAction ( - const caHdr &msg, - const osiSockAddr &net_addr, const epicsTime & ); - bool repeaterAckAction ( - const caHdr &msg, - const osiSockAddr &net_addr, const epicsTime & ); - - // netiiu stubs - unsigned getHostName ( - epicsGuard < epicsMutex > &, char * pBuf, - unsigned bufLength ) const throw (); - const char * pHostName ( - epicsGuard < epicsMutex > & ) const throw (); - bool ca_v41_ok ( - epicsGuard < epicsMutex > & ) const; - bool ca_v42_ok ( - epicsGuard < epicsMutex > & ) const; - unsigned requestMessageBytesPending ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void flush ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void writeRequest ( - epicsGuard < epicsMutex > &, nciu &, - unsigned type, arrayElementCount nElem, - const void *pValue ); - void writeNotifyRequest ( - epicsGuard < epicsMutex > &, - nciu &, netWriteNotifyIO &, - unsigned type, arrayElementCount nElem, - const void *pValue ); - void readNotifyRequest ( - epicsGuard < epicsMutex > &, nciu &, - netReadNotifyIO &, unsigned type, - arrayElementCount nElem ); - void clearChannelRequest ( - epicsGuard < epicsMutex > &, - ca_uint32_t sid, ca_uint32_t cid ); - void subscriptionRequest ( - epicsGuard < epicsMutex > &, - nciu &, netSubscription & ); - void subscriptionUpdateRequest ( - epicsGuard < epicsMutex > &, - nciu &, netSubscription & ); - void subscriptionCancelRequest ( - epicsGuard < epicsMutex > &, - nciu & chan, netSubscription & subscr ); - void flushRequest ( - epicsGuard < epicsMutex > & ); - void requestRecvProcessPostponedFlush ( - epicsGuard < epicsMutex > & ); - osiSockAddr getNetworkAddress ( - epicsGuard < epicsMutex > & ) const; - void uninstallChan ( - epicsGuard < epicsMutex > &, nciu & ); - void uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > &, nciu &, - const class epicsTime & currentTime ); - double receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const; - bool searchMsg ( - epicsGuard < epicsMutex > &, ca_uint32_t id, - const char * pName, unsigned nameLength ); - - // searchTimerNotify stubs - double getRTTE ( epicsGuard < epicsMutex > & ) const; - void updateRTTE ( epicsGuard < epicsMutex > &, double rtte ); - bool pushVersionMsg (); - void boostChannel ( - epicsGuard < epicsMutex > & guard, nciu & chan ); - void noSearchRespNotify ( - epicsGuard < epicsMutex > &, nciu & chan, unsigned index ); - bool datagramFlush ( - epicsGuard < epicsMutex > &, const epicsTime & currentTime ); - ca_uint32_t datagramSeqNumber ( - epicsGuard < epicsMutex > & ) const; - - // disconnectGovernorNotify - void govExpireNotify ( - epicsGuard < epicsMutex > &, nciu & ); - - udpiiu ( const udpiiu & ); - udpiiu & operator = ( const udpiiu & ); - - friend class udpRecvThread; - - // These are needed for the vxWorks 5.5 compiler: - friend class udpiiu::SearchDestUDP; - friend class udpiiu::SearchRespCallback; - friend class udpiiu::M_repeaterTimerNotify; -}; - -#endif // udpiiuh - diff --git a/src/ca/client/virtualCircuit.h b/src/ca/client/virtualCircuit.h deleted file mode 100644 index d06d87c60..000000000 --- a/src/ca/client/virtualCircuit.h +++ /dev/null @@ -1,421 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * - * - * L O S A L A M O S - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * - * Copyright, 1986, The Regents of the University of California. - * - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef virtualCircuith -#define virtualCircuith - -#include "tsDLList.h" - -#include "comBuf.h" -#include "caServerID.h" -#include "netiiu.h" -#include "comQueSend.h" -#include "comQueRecv.h" -#include "tcpRecvWatchdog.h" -#include "tcpSendWatchdog.h" -#include "hostNameCache.h" -#include "SearchDest.h" -#include "compilerDependencies.h" - -class callbackManager; - -// a modified ca header with capacity for large arrays -struct caHdrLargeArray { - ca_uint32_t m_postsize; // size of message extension - ca_uint32_t m_count; // operation data count - ca_uint32_t m_cid; // channel identifier - ca_uint32_t m_available; // protocol stub dependent - ca_uint16_t m_dataType; // operation data type - ca_uint16_t m_cmmd; // operation to be performed -}; - -class ipAddrToAsciiEngine; - -class tcpRecvThread : private epicsThreadRunable { -public: - tcpRecvThread ( - class tcpiiu & iiuIn, epicsMutex & cbMutexIn, cacContextNotify &, - const char * pName, unsigned int stackSize, unsigned int priority ); - virtual ~tcpRecvThread (); - void start (); - void exitWait (); - bool exitWait ( double delay ); - void interruptSocketRecv (); - void show ( unsigned level ) const; -private: - epicsThread thread; - class tcpiiu & iiu; - epicsMutex & cbMutex; - cacContextNotify & ctxNotify; - void run (); - void connect ( - epicsGuard < epicsMutex > & guard ); - bool validFillStatus ( - epicsGuard < epicsMutex > & guard, - const statusWireIO & stat ); -}; - -class tcpSendThread : private epicsThreadRunable { -public: - tcpSendThread ( - class tcpiiu & iiuIn, const char * pName, - unsigned int stackSize, unsigned int priority ); - virtual ~tcpSendThread (); - void start (); - void exitWait (); - void interruptSocketSend (); - void show ( unsigned level ) const; -private: - epicsThread thread; - class tcpiiu & iiu; - void run (); -}; - -class SearchDestTCP : public SearchDest { -public: - SearchDestTCP ( cac &, const osiSockAddr & ); - void searchRequest ( epicsGuard < epicsMutex > & guard, - const char * pbuf, size_t len ); - void show ( epicsGuard < epicsMutex > & guard, unsigned level ) const; - void setCircuit ( tcpiiu * ); - void disable (); - void enable (); -private: - tcpiiu * _ptcpiiu; - cac & _cac; - const osiSockAddr _addr; - bool _active; -}; - -class tcpiiu : - public netiiu, public tsDLNode < tcpiiu >, - public tsSLNode < tcpiiu >, public caServerID, - private wireSendAdapter, private wireRecvAdapter { - friend void SearchDestTCP::searchRequest ( epicsGuard < epicsMutex > & guard, - const char * pbuf, size_t len ); -public: - tcpiiu ( cac & cac, epicsMutex & mutualExclusion, epicsMutex & callbackControl, - cacContextNotify &, double connectionTimeout, epicsTimerQueue & timerQueue, - const osiSockAddr & addrIn, comBufMemoryManager &, unsigned minorVersion, - ipAddrToAsciiEngine & engineIn, const cacChannel::priLev & priorityIn, - SearchDestTCP * pSearchDestIn = NULL); - ~tcpiiu (); - void start ( - epicsGuard < epicsMutex > & ); - void responsiveCircuitNotify ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void sendTimeoutNotify ( - callbackManager & cbMgr, - epicsGuard < epicsMutex > & guard ); - void receiveTimeoutNotify( - callbackManager &, - epicsGuard < epicsMutex > & ); - void beaconAnomalyNotify ( - epicsGuard < epicsMutex > & ); - void beaconArrivalNotify ( - epicsGuard < epicsMutex > & ); - void probeResponseNotify ( - epicsGuard < epicsMutex > & ); - - void flushRequest ( - epicsGuard < epicsMutex > & ); - unsigned requestMessageBytesPending ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void flush ( - epicsGuard < epicsMutex > & mutualExclusionGuard ); - - void show ( unsigned level ) const; - bool setEchoRequestPending ( - epicsGuard < epicsMutex > & ); - void requestRecvProcessPostponedFlush ( - epicsGuard < epicsMutex > & ); - void clearChannelRequest ( - epicsGuard < epicsMutex > &, - ca_uint32_t sid, ca_uint32_t cid ); - - bool ca_v41_ok ( - epicsGuard < epicsMutex > & ) const; - bool ca_v42_ok ( - epicsGuard < epicsMutex > & ) const; - bool ca_v44_ok ( - epicsGuard < epicsMutex > & ) const; - bool ca_v49_ok ( - epicsGuard < epicsMutex > & ) const; - - unsigned getHostName ( - epicsGuard < epicsMutex > &, - char *pBuf, unsigned bufLength ) const throw (); - bool alive ( - epicsGuard < epicsMutex > & ) const; - bool connecting ( - epicsGuard < epicsMutex > & ) const; - bool receiveThreadIsBusy ( - epicsGuard < epicsMutex > & ); - osiSockAddr getNetworkAddress ( - epicsGuard < epicsMutex > & ) const; - int printFormated ( - epicsGuard < epicsMutex > & cbGuard, - const char *pformat, ... ); - unsigned channelCount ( - epicsGuard < epicsMutex > & ); - void disconnectAllChannels ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard, class udpiiu & ); - void unlinkAllChannels ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void installChannel ( - epicsGuard < epicsMutex > &, nciu & chan, - unsigned sidIn, ca_uint16_t typeIn, arrayElementCount countIn ); - void uninstallChan ( - epicsGuard < epicsMutex > & guard, nciu & chan ); - bool connectNotify ( - epicsGuard < epicsMutex > &, nciu & chan ); - - void searchRespNotify ( - const epicsTime &, const caHdrLargeArray & ); - void versionRespNotify ( const caHdrLargeArray & ); - - void * operator new ( size_t size, - tsFreeList < class tcpiiu, 32, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class tcpiiu, 32, epicsMutexNOOP > & )) - -private: - hostNameCache hostNameCacheInstance; - tcpRecvThread recvThread; - tcpSendThread sendThread; - tcpRecvWatchdog recvDog; - tcpSendWatchdog sendDog; - comQueSend sendQue; - comQueRecv recvQue; - // nciu state field tells us which list - // protected by the callback mutex - tsDLList < nciu > createReqPend; - tsDLList < nciu > createRespPend; - tsDLList < nciu > v42ConnCallbackPend; - tsDLList < nciu > subscripReqPend; - tsDLList < nciu > connectedList; - tsDLList < nciu > unrespCircuit; - tsDLList < nciu > subscripUpdateReqPend; - caHdrLargeArray curMsg; - arrayElementCount curDataMax; - arrayElementCount curDataBytes; - comBufMemoryManager & comBufMemMgr; - cac & cacRef; - char * pCurData; - SearchDestTCP * pSearchDest; - epicsMutex & mutex; - epicsMutex & cbMutex; - unsigned minorProtocolVersion; - enum iiu_conn_state { - iiucs_connecting, // pending circuit connect - iiucs_connected, // live circuit - iiucs_clean_shutdown, // live circuit will shutdown when flush completes - iiucs_disconnected, // socket informed us of disconnect - iiucs_abort_shutdown // socket has been closed - } state; - epicsEvent sendThreadFlushEvent; - epicsEvent flushBlockEvent; - SOCKET sock; - unsigned contigRecvMsgCount; - unsigned blockingForFlush; - unsigned socketLibrarySendBufferSize; - unsigned unacknowledgedSendBytes; - unsigned channelCountTot; - bool _receiveThreadIsBusy; - bool busyStateDetected; // only modified by the recv thread - bool flowControlActive; // only modified by the send process thread - bool echoRequestPending; - bool oldMsgHeaderAvailable; - bool msgHeaderAvailable; - bool earlyFlush; - bool recvProcessPostponedFlush; - bool discardingPendingData; - bool socketHasBeenClosed; - bool unresponsiveCircuit; - - bool processIncoming ( - const epicsTime & currentTime, callbackManager & ); - unsigned sendBytes ( const void *pBuf, - unsigned nBytesInBuf, const epicsTime & currentTime ); - void recvBytes ( - void * pBuf, unsigned nBytesInBuf, statusWireIO & ); - const char * pHostName ( - epicsGuard < epicsMutex > & ) const throw (); - double receiveWatchdogDelay ( - epicsGuard < epicsMutex > & ) const; - void unresponsiveCircuitNotify ( - epicsGuard < epicsMutex > & cbGuard, - epicsGuard < epicsMutex > & guard ); - void initiateCleanShutdown ( - epicsGuard < epicsMutex > & ); - void initiateAbortShutdown ( - epicsGuard < epicsMutex > & ); - void disconnectNotify ( - epicsGuard < epicsMutex > & ); - bool bytesArePendingInOS () const; - void decrementBlockingForFlushCount ( - epicsGuard < epicsMutex > & guard ); - bool isNameService () const; - - // send protocol stubs - void echoRequest ( - epicsGuard < epicsMutex > & ); - void versionMessage ( - epicsGuard < epicsMutex > &, const cacChannel::priLev & priority ); - void disableFlowControlRequest ( - epicsGuard < epicsMutex > & ); - void enableFlowControlRequest ( - epicsGuard < epicsMutex > & ); - void hostNameSetRequest ( - epicsGuard < epicsMutex > & ); - void userNameSetRequest ( - epicsGuard < epicsMutex > & ); - void createChannelRequest ( - nciu &, epicsGuard < epicsMutex > & ); - void writeRequest ( - epicsGuard < epicsMutex > &, nciu &, - unsigned type, arrayElementCount nElem, const void *pValue ); - void writeNotifyRequest ( - epicsGuard < epicsMutex > &, nciu &, - netWriteNotifyIO &, unsigned type, - arrayElementCount nElem, const void *pValue ); - void readNotifyRequest ( - epicsGuard < epicsMutex > &, nciu &, - netReadNotifyIO &, unsigned type, - arrayElementCount nElem ); - void subscriptionRequest ( - epicsGuard < epicsMutex > &, - nciu &, netSubscription & subscr ); - void subscriptionUpdateRequest ( - epicsGuard < epicsMutex > &, - nciu & chan, netSubscription & subscr ); - void subscriptionCancelRequest ( - epicsGuard < epicsMutex > &, - nciu & chan, netSubscription & subscr ); - void flushIfRecvProcessRequested ( - epicsGuard < epicsMutex > & ); - bool sendThreadFlush ( - epicsGuard < epicsMutex > & ); - - // netiiu stubs - void uninstallChanDueToSuccessfulSearchResponse ( - epicsGuard < epicsMutex > &, nciu &, const class epicsTime & ); - bool searchMsg ( - epicsGuard < epicsMutex > &, ca_uint32_t id, - const char * pName, unsigned nameLength ); - - friend class tcpRecvThread; - friend class tcpSendThread; - - tcpiiu ( const tcpiiu & ); - tcpiiu & operator = ( const tcpiiu & ); - void operator delete ( void * ); -}; - -inline void * tcpiiu::operator new ( size_t size, - tsFreeList < class tcpiiu, 32, epicsMutexNOOP > & mgr ) -{ - return mgr.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void tcpiiu::operator delete ( void * pCadaver, - tsFreeList < class tcpiiu, 32, epicsMutexNOOP > & mgr ) -{ - mgr.release ( pCadaver ); -} -#endif - -inline bool tcpiiu::ca_v41_ok ( - epicsGuard < epicsMutex > & ) const -{ - return CA_V41 ( this->minorProtocolVersion ); -} - -inline bool tcpiiu::ca_v44_ok ( - epicsGuard < epicsMutex > & ) const -{ - return CA_V44 ( this->minorProtocolVersion ); -} - -inline bool tcpiiu::ca_v49_ok ( - epicsGuard < epicsMutex > & ) const -{ - return CA_V49 ( this->minorProtocolVersion ); -} - -inline bool tcpiiu::alive ( - epicsGuard < epicsMutex > & ) const -{ - return ( this->state == iiucs_connecting || - this->state == iiucs_connected ); -} - -inline bool tcpiiu::connecting ( - epicsGuard < epicsMutex > & ) const -{ - return ( this->state == iiucs_connecting ); -} - -inline bool tcpiiu::receiveThreadIsBusy ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - return this->_receiveThreadIsBusy; -} - -inline void tcpiiu::beaconAnomalyNotify ( - epicsGuard < epicsMutex > & guard ) -{ - //guard.assertIdenticalMutex ( this->cacRef.mutexRef () ); - this->recvDog.beaconAnomalyNotify ( guard ); -} - -inline void tcpiiu::beaconArrivalNotify ( - epicsGuard < epicsMutex > & guard ) -{ - //guard.assertIdenticalMutex ( this->cacRef.mutexRef () ); - this->recvDog.beaconArrivalNotify ( guard ); -} - -inline void tcpiiu::probeResponseNotify ( - epicsGuard < epicsMutex > & cbGuard ) -{ - this->recvDog.probeResponseNotify ( cbGuard ); -} - -inline bool tcpiiu::isNameService () const -{ - return ( this->pSearchDest != NULL ); -} - -inline void SearchDestTCP::setCircuit ( tcpiiu * piiu ) -{ - _ptcpiiu = piiu; -} - -#endif // ifdef virtualCircuith diff --git a/src/ca/legacy/gdd/Makefile b/src/gdd/Makefile similarity index 100% rename from src/ca/legacy/gdd/Makefile rename to src/gdd/Makefile diff --git a/src/ca/legacy/gdd/README b/src/gdd/README similarity index 100% rename from src/ca/legacy/gdd/README rename to src/gdd/README diff --git a/src/ca/legacy/gdd/aitConvert.cc b/src/gdd/aitConvert.cc similarity index 100% rename from src/ca/legacy/gdd/aitConvert.cc rename to src/gdd/aitConvert.cc diff --git a/src/ca/legacy/gdd/aitConvert.h b/src/gdd/aitConvert.h similarity index 100% rename from src/ca/legacy/gdd/aitConvert.h rename to src/gdd/aitConvert.h diff --git a/src/ca/legacy/gdd/aitGen.c b/src/gdd/aitGen.c similarity index 100% rename from src/ca/legacy/gdd/aitGen.c rename to src/gdd/aitGen.c diff --git a/src/ca/legacy/gdd/aitHelpers.cc b/src/gdd/aitHelpers.cc similarity index 100% rename from src/ca/legacy/gdd/aitHelpers.cc rename to src/gdd/aitHelpers.cc diff --git a/src/ca/legacy/gdd/aitHelpers.h b/src/gdd/aitHelpers.h similarity index 100% rename from src/ca/legacy/gdd/aitHelpers.h rename to src/gdd/aitHelpers.h diff --git a/src/ca/legacy/gdd/aitTypes.c b/src/gdd/aitTypes.c similarity index 100% rename from src/ca/legacy/gdd/aitTypes.c rename to src/gdd/aitTypes.c diff --git a/src/ca/legacy/gdd/aitTypes.h b/src/gdd/aitTypes.h similarity index 100% rename from src/ca/legacy/gdd/aitTypes.h rename to src/gdd/aitTypes.h diff --git a/src/ca/legacy/gdd/dbMapper.cc b/src/gdd/dbMapper.cc similarity index 100% rename from src/ca/legacy/gdd/dbMapper.cc rename to src/gdd/dbMapper.cc diff --git a/src/ca/legacy/gdd/dbMapper.h b/src/gdd/dbMapper.h similarity index 100% rename from src/ca/legacy/gdd/dbMapper.h rename to src/gdd/dbMapper.h diff --git a/src/ca/legacy/gdd/gdd.cc b/src/gdd/gdd.cc similarity index 100% rename from src/ca/legacy/gdd/gdd.cc rename to src/gdd/gdd.cc diff --git a/src/ca/legacy/gdd/gdd.gif b/src/gdd/gdd.gif similarity index 100% rename from src/ca/legacy/gdd/gdd.gif rename to src/gdd/gdd.gif diff --git a/src/ca/legacy/gdd/gdd.h b/src/gdd/gdd.h similarity index 100% rename from src/ca/legacy/gdd/gdd.h rename to src/gdd/gdd.h diff --git a/src/ca/legacy/gdd/gdd.html b/src/gdd/gdd.html similarity index 100% rename from src/ca/legacy/gdd/gdd.html rename to src/gdd/gdd.html diff --git a/src/ca/legacy/gdd/gdd.rc b/src/gdd/gdd.rc similarity index 100% rename from src/ca/legacy/gdd/gdd.rc rename to src/gdd/gdd.rc diff --git a/src/ca/legacy/gdd/gddAppDefs.cc b/src/gdd/gddAppDefs.cc similarity index 100% rename from src/ca/legacy/gdd/gddAppDefs.cc rename to src/gdd/gddAppDefs.cc diff --git a/src/ca/legacy/gdd/gddAppFuncTable.h b/src/gdd/gddAppFuncTable.h similarity index 100% rename from src/ca/legacy/gdd/gddAppFuncTable.h rename to src/gdd/gddAppFuncTable.h diff --git a/src/ca/legacy/gdd/gddAppTable.cc b/src/gdd/gddAppTable.cc similarity index 100% rename from src/ca/legacy/gdd/gddAppTable.cc rename to src/gdd/gddAppTable.cc diff --git a/src/ca/legacy/gdd/gddAppTable.h b/src/gdd/gddAppTable.h similarity index 100% rename from src/ca/legacy/gdd/gddAppTable.h rename to src/gdd/gddAppTable.h diff --git a/src/ca/legacy/gdd/gddArray.cc b/src/gdd/gddArray.cc similarity index 100% rename from src/ca/legacy/gdd/gddArray.cc rename to src/gdd/gddArray.cc diff --git a/src/ca/legacy/gdd/gddArray.h b/src/gdd/gddArray.h similarity index 100% rename from src/ca/legacy/gdd/gddArray.h rename to src/gdd/gddArray.h diff --git a/src/ca/legacy/gdd/gddArrayI.h b/src/gdd/gddArrayI.h similarity index 100% rename from src/ca/legacy/gdd/gddArrayI.h rename to src/gdd/gddArrayI.h diff --git a/src/ca/legacy/gdd/gddContainer.cc b/src/gdd/gddContainer.cc similarity index 100% rename from src/ca/legacy/gdd/gddContainer.cc rename to src/gdd/gddContainer.cc diff --git a/src/ca/legacy/gdd/gddContainer.h b/src/gdd/gddContainer.h similarity index 100% rename from src/ca/legacy/gdd/gddContainer.h rename to src/gdd/gddContainer.h diff --git a/src/ca/legacy/gdd/gddContainerI.h b/src/gdd/gddContainerI.h similarity index 100% rename from src/ca/legacy/gdd/gddContainerI.h rename to src/gdd/gddContainerI.h diff --git a/src/ca/legacy/gdd/gddEnumStringTable.cc b/src/gdd/gddEnumStringTable.cc similarity index 100% rename from src/ca/legacy/gdd/gddEnumStringTable.cc rename to src/gdd/gddEnumStringTable.cc diff --git a/src/ca/legacy/gdd/gddEnumStringTable.h b/src/gdd/gddEnumStringTable.h similarity index 100% rename from src/ca/legacy/gdd/gddEnumStringTable.h rename to src/gdd/gddEnumStringTable.h diff --git a/src/ca/legacy/gdd/gddErrorCodes.cc b/src/gdd/gddErrorCodes.cc similarity index 100% rename from src/ca/legacy/gdd/gddErrorCodes.cc rename to src/gdd/gddErrorCodes.cc diff --git a/src/ca/legacy/gdd/gddErrorCodes.h b/src/gdd/gddErrorCodes.h similarity index 100% rename from src/ca/legacy/gdd/gddErrorCodes.h rename to src/gdd/gddErrorCodes.h diff --git a/src/ca/legacy/gdd/gddI.h b/src/gdd/gddI.h similarity index 100% rename from src/ca/legacy/gdd/gddI.h rename to src/gdd/gddI.h diff --git a/src/ca/legacy/gdd/gddNewDel.cc b/src/gdd/gddNewDel.cc similarity index 100% rename from src/ca/legacy/gdd/gddNewDel.cc rename to src/gdd/gddNewDel.cc diff --git a/src/ca/legacy/gdd/gddNewDel.h b/src/gdd/gddNewDel.h similarity index 100% rename from src/ca/legacy/gdd/gddNewDel.h rename to src/gdd/gddNewDel.h diff --git a/src/ca/legacy/gdd/gddScalar.h b/src/gdd/gddScalar.h similarity index 100% rename from src/ca/legacy/gdd/gddScalar.h rename to src/gdd/gddScalar.h diff --git a/src/ca/legacy/gdd/gddScalarI.h b/src/gdd/gddScalarI.h similarity index 100% rename from src/ca/legacy/gdd/gddScalarI.h rename to src/gdd/gddScalarI.h diff --git a/src/ca/legacy/gdd/gddTest.cc b/src/gdd/gddTest.cc similarity index 100% rename from src/ca/legacy/gdd/gddTest.cc rename to src/gdd/gddTest.cc diff --git a/src/ca/legacy/gdd/gddUtils.cc b/src/gdd/gddUtils.cc similarity index 100% rename from src/ca/legacy/gdd/gddUtils.cc rename to src/gdd/gddUtils.cc diff --git a/src/ca/legacy/gdd/gddUtils.h b/src/gdd/gddUtils.h similarity index 100% rename from src/ca/legacy/gdd/gddUtils.h rename to src/gdd/gddUtils.h diff --git a/src/ca/legacy/gdd/gddUtilsI.h b/src/gdd/gddUtilsI.h similarity index 100% rename from src/ca/legacy/gdd/gddUtilsI.h rename to src/gdd/gddUtilsI.h diff --git a/src/ca/legacy/gdd/gddref.html b/src/gdd/gddref.html similarity index 100% rename from src/ca/legacy/gdd/gddref.html rename to src/gdd/gddref.html diff --git a/src/ca/legacy/gdd/gddref2.html b/src/gdd/gddref2.html similarity index 100% rename from src/ca/legacy/gdd/gddref2.html rename to src/gdd/gddref2.html diff --git a/src/ca/legacy/gdd/genApps.cc b/src/gdd/genApps.cc similarity index 100% rename from src/ca/legacy/gdd/genApps.cc rename to src/gdd/genApps.cc diff --git a/src/ca/legacy/gdd/smartGDDPointer.h b/src/gdd/smartGDDPointer.h similarity index 100% rename from src/ca/legacy/gdd/smartGDDPointer.h rename to src/gdd/smartGDDPointer.h diff --git a/src/ioc/Makefile b/src/ioc/Makefile deleted file mode 100644 index 6dbd13b54..000000000 --- a/src/ioc/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -#************************************************************************* -# Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../.. - -include $(TOP)/configure/CONFIG - -SRC = $(TOP)/src -IOCDIR = $(SRC)/ioc - -LIBRARY_IOC += dbCore -dbCore_LIBS += ca Com -dbCore_SYS_LIBS_WIN32 += ws2_32 - -dbCore_RCS += dbCore.rc -dbStaticHost_RCS = dbStaticHost.rc - -PROD_LIBS = Com - -include $(IOCDIR)/as/Makefile -include $(IOCDIR)/bpt/Makefile -include $(IOCDIR)/db/Makefile -include $(IOCDIR)/dbStatic/Makefile -include $(IOCDIR)/dbtemplate/Makefile -include $(IOCDIR)/misc/Makefile -include $(IOCDIR)/registry/Makefile -include $(IOCDIR)/rsrv/Makefile - -include $(TOP)/configure/RULES - -include $(IOCDIR)/dbStatic/RULES -include $(IOCDIR)/bpt/RULES -include $(IOCDIR)/db/RULES -include $(IOCDIR)/dbtemplate/RULES - diff --git a/src/ioc/as/Makefile b/src/ioc/as/Makefile deleted file mode 100644 index 25237c26c..000000000 --- a/src/ioc/as/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2010 Brookhaven Science Associates, as Operator of -# Brookhaven National Lab. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(IOCDIR)/as - -INC += asDbLib.h -INC += asCa.h -INC += asIocRegister.h - -dbCore_SRCS += asDbLib.c -dbCore_SRCS += asCa.c -dbCore_SRCS += asIocRegister.c - -PROD_HOST += ascheck -ascheck_SRCS = ascheck.c -ascheck_LIBS = dbCore ca diff --git a/src/ioc/as/asCa.c b/src/ioc/as/asCa.c deleted file mode 100644 index d0180448b..000000000 --- a/src/ioc/as/asCa.c +++ /dev/null @@ -1,335 +0,0 @@ -/*asCa.c*/ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 10-15-93 */ - -/*This module is separate from asDbLib because CA uses old database access*/ -#include -#include -#include -#include - -#include "alarm.h" -#include "asLib.h" -#include "cantProceed.h" -#include "db_access.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsStdio.h" -#include "epicsThread.h" -#include "errlog.h" -#include "taskwd.h" - -#include "cadef.h" -#include "caerr.h" -#include "caeventmask.h" - -#define epicsExportSharedSymbols -#include "asCa.h" -#include "asDbLib.h" -#include "callback.h" -#include "epicsExport.h" - -int asCaDebug = 0; -epicsExportAddress(int,asCaDebug); -static int firstTime = TRUE; -static epicsThreadId threadid=0; -static int caInitializing=FALSE; -static epicsMutexId asCaTaskLock; /*lock access to task */ -static epicsEventId asCaTaskWait; /*Wait for task to respond*/ -static epicsEventId asCaTaskAddChannels; /*Tell asCaTask to add channels*/ -static epicsEventId asCaTaskClearChannels;/*Tell asCaTask to clear channels*/ - -typedef struct { - struct dbr_sts_double rtndata; - chid chid; -} CAPVT; - -static void exceptionCallback(struct exception_handler_args args) -{ - chid chid = args.chid; - long stat = args.stat; /* Channel access status code*/ - const char *channel; - const char *context; - static char *unknown = "unknown"; - const char *nativeType; - const char *requestType; - long nativeCount; - long requestCount; - int readAccess; - int writeAccess; - - channel = (chid ? ca_name(chid) : unknown); - context = (args.ctx ? args.ctx : unknown); - nativeType = dbr_type_to_text((chid ? ca_field_type(chid) : -1)); - requestType = dbr_type_to_text(args.type); - nativeCount = (chid ? ca_element_count(chid) : 0); - requestCount = args.count; - readAccess = (chid ? ca_read_access(chid) : 0); - writeAccess = (chid ? ca_write_access(chid) : 0); - - errlogPrintf("dbCa:exceptionCallback stat \"%s\" channel \"%s\"" - " context \"%s\"\n" - " nativeType %s requestType %s" - " nativeCount %ld requestCount %ld %s %s\n", - ca_message(stat),channel,context, - nativeType,requestType, - nativeCount,requestCount, - (readAccess ? "readAccess" : "noReadAccess"), - (writeAccess ? "writeAccess" : "noWriteAccess")); -} - -/*connectCallback only handles disconnects*/ -static void connectCallback(struct connection_handler_args arg) -{ - chid chid = arg.chid; - ASGINP *pasginp = (ASGINP *)ca_puser(chid); - ASG *pasg = pasginp->pasg; - - if(ca_state(chid)!=cs_conn) { - if(!(pasg->inpBad & (1<inpIndex))) { - /*was good so lets make it bad*/ - pasg->inpBad |= (1<inpIndex); - if(!caInitializing) asComputeAsg(pasg); - if(asCaDebug) printf("as connectCallback disconnect %s\n", - ca_name(chid)); - } - } -} - -static void eventCallback(struct event_handler_args arg) -{ - int caStatus = arg.status; - chid chid = arg.chid; - ASGINP *pasginp = (ASGINP *)arg.usr; - ASG *pasg; - CAPVT *pcapvt; - const struct dbr_sts_double *pdata; - - if(caStatus!=ECA_NORMAL) { - if(chid) { - epicsPrintf("asCa: eventCallback error %s channel %s\n", - ca_message(caStatus),ca_name(chid)); - } else { - epicsPrintf("asCa: eventCallback error %s chid is null\n", - ca_message(caStatus)); - } - return; - } - pasg = pasginp->pasg; - pcapvt = (CAPVT *)pasginp->capvt; - if(chid!=pcapvt->chid) { - epicsPrintf("asCa: eventCallback error pcapvt->chid != arg.chid\n"); - return; - } - if(ca_state(chid)!=cs_conn || !ca_read_access(chid)) { - if(!(pasg->inpBad & (1<inpIndex))) { - /*was good so lets make it bad*/ - pasg->inpBad |= (1<inpIndex); - if(!caInitializing) asComputeAsg(pasg); - if(asCaDebug) { - printf("as eventCallback %s inpBad ca_state %d" - " ca_read_access %d\n", - ca_name(chid),ca_state(chid),ca_read_access(chid)); - } - } - return; - } - pdata = arg.dbr; - pcapvt->rtndata = *pdata; /*structure copy*/ - if(pdata->severity==INVALID_ALARM) { - pasg->inpBad |= (1<inpIndex); - if(asCaDebug) - printf("as eventCallback %s inpBad because INVALID_ALARM\n", - ca_name(chid)); - } else { - pasg->inpBad &= ~((1<inpIndex)); - pasg->pavalue[pasginp->inpIndex] = pdata->value; - if(asCaDebug) - printf("as eventCallback %s inpGood data %f\n", - ca_name(chid),pdata->value); - } - pasg->inpChanged |= (1<inpIndex); - if(!caInitializing) asComputeAsg(pasg); -} - -static void asCaTask(void) -{ - ASG *pasg; - ASGINP *pasginp; - CAPVT *pcapvt; - int status; - - taskwdInsert(epicsThreadGetIdSelf(),NULL,NULL); - SEVCHK(ca_context_create(ca_enable_preemptive_callback), - "asCaTask calling ca_context_create"); - SEVCHK(ca_add_exception_event(exceptionCallback,NULL), - "ca_add_exception_event"); - while(TRUE) { - epicsEventMustWait(asCaTaskAddChannels); - caInitializing = TRUE; - pasg = (ASG *)ellFirst(&pasbase->asgList); - while(pasg) { - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - while(pasginp) { - pasg->inpBad |= (1<inpIndex); - pcapvt = pasginp->capvt = asCalloc(1,sizeof(CAPVT)); - /*Note calls connectCallback immediately for local Pvs*/ - status = ca_search_and_connect(pasginp->inp,&pcapvt->chid, - connectCallback,pasginp); - if(status!=ECA_NORMAL) { - epicsPrintf("asCa ca_search_and_connect error %s\n", - ca_message(status)); - } - /*Note calls eventCallback immediately for local Pvs*/ - status = ca_add_event(DBR_STS_DOUBLE,pcapvt->chid, - eventCallback,pasginp,0); - if(status!=ECA_NORMAL) { - epicsPrintf("asCa ca_add_event error %s\n", - ca_message(status)); - } - pasginp = (ASGINP *)ellNext((ELLNODE *)pasginp); - } - pasg = (ASG *)ellNext((ELLNODE *)pasg); - } - SEVCHK(ca_flush_io(),"asCaTask"); - caInitializing = FALSE; - asComputeAllAsg(); - if(asCaDebug) printf("asCaTask initialized\n"); - epicsEventSignal(asCaTaskWait); - epicsEventMustWait(asCaTaskClearChannels); - pasg = (ASG *)ellFirst(&pasbase->asgList); - while(pasg) { - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - while(pasginp) { - pcapvt = (CAPVT *)pasginp->capvt; - status = ca_clear_channel(pcapvt->chid); - if(status!=ECA_NORMAL) { - epicsPrintf("asCa ca_clear_channel error %s\n", - ca_message(status)); - } - free(pasginp->capvt); - pasginp->capvt = 0; - pasginp = (ASGINP *)ellNext((ELLNODE *)pasginp); - } - pasg = (ASG *)ellNext((ELLNODE *)pasg); - } - if(asCaDebug) printf("asCaTask has cleared all channels\n"); - epicsEventSignal(asCaTaskWait); - } -} - -void asCaStart(void) -{ - if(asCaDebug) printf("asCaStart called\n"); - if(firstTime) { - firstTime = FALSE; - asCaTaskLock=epicsMutexMustCreate(); - asCaTaskWait=epicsEventMustCreate(epicsEventEmpty); - asCaTaskAddChannels=epicsEventMustCreate(epicsEventEmpty); - asCaTaskClearChannels=epicsEventMustCreate(epicsEventEmpty); - threadid = epicsThreadCreate("asCaTask", - (epicsThreadPriorityScanLow - 3), - epicsThreadGetStackSize(epicsThreadStackBig), - (EPICSTHREADFUNC)asCaTask,0); - if(threadid==0) { - errMessage(0,"asCaStart: taskSpawn Failure\n"); - } - } - epicsMutexMustLock(asCaTaskLock); - epicsEventSignal(asCaTaskAddChannels); - epicsEventMustWait(asCaTaskWait); - if(asCaDebug) printf("asCaStart done\n"); - epicsMutexUnlock(asCaTaskLock); -} - -void asCaStop(void) -{ - if(threadid==0) return; - if(asCaDebug) printf("asCaStop called\n"); - epicsMutexMustLock(asCaTaskLock); - epicsEventSignal(asCaTaskClearChannels); - epicsEventMustWait(asCaTaskWait); - if(asCaDebug) printf("asCaStop done\n"); - epicsMutexUnlock(asCaTaskLock); -} - -int ascar(int level) { return ascarFP(stdout,level);} - -int ascarFP(FILE *fp,int level) -{ - ASG *pasg; - int n=0,nbad=0; - enum channel_state state; - - if(!pasbase) { - fprintf(fp,"access security not started\n"); - return(0); - } - pasg = (ASG *)ellFirst(&pasbase->asgList); - while(pasg) { - ASGINP *pasginp; - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - while(pasginp) { - CAPVT *pcapvt = (CAPVT *)pasginp->capvt; - chid chid = pcapvt->chid; - pcapvt = pasginp->capvt; - ++n; - state = ca_state(chid); - if(state!=cs_conn) ++nbad; - if(level>1 || (level==1 && state!=cs_conn)) { - fprintf(fp,"connected:"); - if(state==cs_never_conn) fprintf(fp,"never "); - else if(state==cs_prev_conn) fprintf(fp,"prev "); - else if(state==cs_conn) fprintf(fp,"yes "); - else if(state==cs_closed) fprintf(fp,"closed"); - else fprintf(fp,"unknown"); - fprintf(fp," read:%s write:%s", - (ca_read_access(chid) ? "yes" : "no "), - (ca_write_access(chid) ? "yes" : "no ")); - fprintf(fp," %s %s\n", ca_name(chid),ca_host_name(chid)); - } - pasginp = (ASGINP *)ellNext((ELLNODE *)pasginp); - } - pasg = (ASG *)ellNext((ELLNODE *)pasg); - } - fprintf(fp,"%d channels %d not connected\n",n,nbad); - return(0); -} - -void ascaStats(int *pchans, int *pdiscon) -{ - ASG *pasg; - int n = 0; - int nbad = 0; - - if(!pasbase) { - if (pchans) *pchans = n; - if (pdiscon) *pdiscon = nbad; - return; - } - pasg = (ASG *)ellFirst(&pasbase->asgList); - while (pasg) { - ASGINP *pasginp; - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - while (pasginp) { - CAPVT *pcapvt = (CAPVT *)pasginp->capvt; - chid chid = pcapvt->chid; - ++n; - if (ca_state(chid) != cs_conn) ++nbad; - pasginp = (ASGINP *)ellNext((ELLNODE *)pasginp); - } - pasg = (ASG *)ellNext((ELLNODE *)pasg); - } - if (pchans) *pchans = n; - if (pdiscon) *pdiscon = nbad; -} - diff --git a/src/ioc/as/asCa.h b/src/ioc/as/asCa.h deleted file mode 100644 index 360296fe2..000000000 --- a/src/ioc/as/asCa.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* asCa.h */ - -#ifndef INCasCah -#define INCasCah - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void asCaStart(void); -epicsShareFunc void asCaStop(void); -epicsShareFunc int ascar(int level); -epicsShareFunc int ascarFP(FILE *fp, int level); -epicsShareFunc void ascaStats(int *pchans, int *pdiscon); - -#ifdef __cplusplus -} -#endif - -#endif /*INCasCah*/ diff --git a/src/ioc/as/asDbLib.c b/src/ioc/as/asDbLib.c deleted file mode 100644 index c0fe192b0..000000000 --- a/src/ioc/as/asDbLib.c +++ /dev/null @@ -1,336 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 02-11-94*/ - -#include -#include -#include -#include - -#include "alarm.h" -#include "asLib.h" -#include "cantProceed.h" -#include "dbDefs.h" -#include "epicsStdio.h" -#include "epicsThread.h" -#include "errlog.h" -#include "taskwd.h" - -#include "caeventmask.h" - -#define epicsExportSharedSymbols -#include "asCa.h" -#include "asDbLib.h" -#include "callback.h" -#include "dbAccess.h" -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbEvent.h" -#include "db_field_log.h" -#include "dbStaticLib.h" -#include "recSup.h" - -static char *pacf=NULL; -static char *psubstitutions=NULL; -static epicsThreadId asInitTheadId=0; -static int firstTime = TRUE; - -static long asDbAddRecords(void) -{ - DBENTRY dbentry; - DBENTRY *pdbentry=&dbentry; - long status; - dbCommon *precord; - - dbInitEntry(pdbbase,pdbentry); - status = dbFirstRecordType(pdbentry); - while(!status) { - status = dbFirstRecord(pdbentry); - while(!status) { - precord = pdbentry->precnode->precord; - if(!precord->asp) { - status = asAddMember(&precord->asp, precord->asg); - if(status) errMessage(status,"asDbAddRecords:asAddMember"); - asPutMemberPvt(precord->asp,precord); - } - status = dbNextRecord(pdbentry); - } - status = dbNextRecordType(pdbentry); - } - dbFinishEntry(pdbentry); - return(0); -} - -int asSetFilename(const char *acf) -{ - if (pacf) - free (pacf); - if (acf) { - pacf = calloc(1, strlen(acf)+1); - if (!pacf) { - errMessage(0, "asSetFilename calloc failure"); - } else { - strcpy(pacf, acf); - if (*pacf != '/' && !strchr(pacf, ':')) { - printf("asSetFilename: Warning - relative paths won't usually " - "work\n"); - } - } - } else { - pacf = NULL; - } - return 0; -} - -int asSetSubstitutions(const char *substitutions) -{ - if(psubstitutions) free ((void *)psubstitutions); - if(substitutions) { - psubstitutions = calloc(1,strlen(substitutions)+1); - if(!psubstitutions) { - errMessage(0,"asSetSubstitutions calloc failure"); - } else { - strcpy(psubstitutions,substitutions); - } - } else { - psubstitutions = NULL; - } - return(0); -} - -static void asSpcAsCallback(struct dbCommon *precord) -{ - asChangeGroup(&precord->asp, precord->asg); -} - -static void asInitCommonOnce(void *arg) -{ - int *firstTime = (int *)arg; - *firstTime = FALSE; -} - -static long asInitCommon(void) -{ - long status; - int asWasActive = asActive; - int wasFirstTime = firstTime; - static epicsThreadOnceId asInitCommonOnceFlag = EPICS_THREAD_ONCE_INIT; - - - epicsThreadOnce(&asInitCommonOnceFlag,asInitCommonOnce,(void *)&firstTime); - if(wasFirstTime) { - if(!pacf) return(0); /*access security will NEVER be turned on*/ - } else { - if(!asActive) { - printf("Access security is NOT enabled." - " Was asSetFilename specified before iocInit?\n"); - return(S_asLib_asNotActive); - } - if(pacf) { - asCaStop(); - } else { /*Just leave everything as is */ - return(S_asLib_badConfig); - } - } - status = asInitFile(pacf,psubstitutions); - if(asActive) { - if(!asWasActive) { - dbSpcAsRegisterCallback(asSpcAsCallback); - asDbAddRecords(); - } - asCaStart(); - } - return(status); -} - -int asInit(void) -{ - return(asInitCommon()); -} - -int asShutdown(void) { - volatile ASBASE *pbase = pasbase; - pasbase = NULL; - firstTime = TRUE; - if(pbase) - asFreeAll((ASBASE*)pbase); - return 0; -} - -static void wdCallback(void *arg) -{ - ASDBCALLBACK *pcallback = (ASDBCALLBACK *)arg; - pcallback->status = S_asLib_InitFailed; - callbackRequest(&pcallback->callback); -} - -static void asInitTask(ASDBCALLBACK *pcallback) -{ - long status; - - taskwdInsert(epicsThreadGetIdSelf(), wdCallback, (void *)pcallback); - status = asInitCommon(); - taskwdRemove(epicsThreadGetIdSelf()); - asInitTheadId = 0; - if(pcallback) { - pcallback->status = status; - callbackRequest(&pcallback->callback); - } -} - -int asInitAsyn(ASDBCALLBACK *pcallback) -{ - if(!pacf) return(0); - if(asInitTheadId) { - errMessage(-1,"asInit: asInitTask already active"); - if(pcallback) { - pcallback->status = S_asLib_InitFailed; - callbackRequest(&pcallback->callback); - } - return(-1); - } - asInitTheadId = epicsThreadCreate("asInitTask", - (epicsThreadPriorityCAServerHigh + 1), - epicsThreadGetStackSize(epicsThreadStackBig), - (EPICSTHREADFUNC)asInitTask,(void *)pcallback); - if(asInitTheadId==0) { - errMessage(0,"asInit: epicsThreadCreate Error"); - if(pcallback) { - pcallback->status = S_asLib_InitFailed; - callbackRequest(&pcallback->callback); - } - asInitTheadId = 0; - } - return(0); -} - -int asDbGetAsl(struct dbChannel *chan) -{ - return dbChannelFldDes(chan)->as_level; -} - -void * asDbGetMemberPvt(struct dbChannel *chan) -{ - return dbChannelRecord(chan)->asp; -} - -static void astacCallback(ASCLIENTPVT clientPvt,asClientStatus status) -{ - char *recordname; - - recordname = (char *)asGetClientPvt(clientPvt); - printf("astac callback %s: status=%d",recordname,status); - printf(" get %s put %s\n",(asCheckGet(clientPvt) ? "Yes" : "No"), - (asCheckPut(clientPvt) ? "Yes" : "No")); -} - -int astac(const char *pname,const char *user,const char *location) -{ - DBADDR *paddr; - long status; - ASCLIENTPVT *pasclientpvt=NULL; - dbCommon *precord; - dbFldDes *pflddes; - char *puser; - char *plocation; - - paddr = dbCalloc(1,sizeof(DBADDR) + sizeof(ASCLIENTPVT)); - pasclientpvt = (ASCLIENTPVT *)(paddr + 1); - status=dbNameToAddr(pname,paddr); - if(status) { - errMessage(status,"dbNameToAddr error"); - return(1); - } - precord = paddr->precord; - pflddes = paddr->pfldDes; - puser = asCalloc(1,strlen(user)+1); - strcpy(puser,user); - plocation = asCalloc(1,strlen(location)+1); - strcpy(plocation,location); - - status = asAddClient(pasclientpvt,precord->asp, - (int)pflddes->as_level,puser,plocation); - if(status) { - errMessage(status,"asAddClient error"); - return(1); - } else { - asPutClientPvt(*pasclientpvt,(void *)precord->name); - asRegisterClientCallback(*pasclientpvt,astacCallback); - } - return(0); -} - -static void myMemberCallback(ASMEMBERPVT memPvt,FILE *fp) -{ - dbCommon *precord; - - precord = asGetMemberPvt(memPvt); - if(precord) fprintf(fp," Record:%s",precord->name); -} - -int asdbdump(void) -{ - asDumpFP(stdout,myMemberCallback,NULL,1); - return(0); -} - -int asdbdumpFP(FILE *fp) -{ - asDumpFP(fp,myMemberCallback,NULL,1); - return(0); -} - -int aspuag(const char *uagname) -{ - asDumpUagFP(stdout,uagname); - return(0); -} - -int aspuagFP(FILE *fp,const char *uagname) -{ - - asDumpUagFP(fp,uagname); - return(0); -} - -int asphag(const char *hagname) -{ - asDumpHagFP(stdout,hagname); - return(0); -} - -int asphagFP(FILE *fp,const char *hagname) -{ - asDumpHagFP(fp,hagname); - return(0); -} - -int asprules(const char *asgname) -{ - asDumpRulesFP(stdout,asgname); - return(0); -} - -int asprulesFP(FILE *fp,const char *asgname) -{ - asDumpRulesFP(fp,asgname); - return(0); -} - -int aspmem(const char *asgname,int clients) -{ - asDumpMemFP(stdout,asgname,myMemberCallback,clients); - return(0); -} - -int aspmemFP(FILE *fp,const char *asgname,int clients) -{ - asDumpMemFP(fp,asgname,myMemberCallback,clients); - return(0); -} diff --git a/src/ioc/as/asDbLib.h b/src/ioc/as/asDbLib.h deleted file mode 100644 index 65c4c6f59..000000000 --- a/src/ioc/as/asDbLib.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 02-23-94*/ - -#ifndef INCdbAsLibh -#define INCdbAsLibh - -#include "callback.h" -#include "shareLib.h" - -typedef struct { - CALLBACK callback; - long status; -} ASDBCALLBACK; - -struct dbChannel; - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int asSetFilename(const char *acf); -epicsShareFunc int asSetSubstitutions(const char *substitutions); -epicsShareFunc int asInit(void); -epicsShareFunc int asInitAsyn(ASDBCALLBACK *pcallback); -epicsShareFunc int asShutdown(void); -epicsShareFunc int asDbGetAsl(struct dbChannel *chan); -epicsShareFunc void * asDbGetMemberPvt(struct dbChannel *chan); -epicsShareFunc int asdbdump(void); -epicsShareFunc int asdbdumpFP(FILE *fp); -epicsShareFunc int aspuag(const char *uagname); -epicsShareFunc int aspuagFP(FILE *fp,const char *uagname); -epicsShareFunc int asphag(const char *hagname); -epicsShareFunc int asphagFP(FILE *fp,const char *hagname); -epicsShareFunc int asprules(const char *asgname); -epicsShareFunc int asprulesFP(FILE *fp,const char *asgname); -epicsShareFunc int aspmem(const char *asgname,int clients); -epicsShareFunc int aspmemFP( - FILE *fp,const char *asgname,int clients); -epicsShareFunc int astac( - const char *recordname,const char *user,const char *location); - -#ifdef __cplusplus -} -#endif - -#endif /*INCdbAsLibh*/ diff --git a/src/ioc/as/asIocRegister.c b/src/ioc/as/asIocRegister.c deleted file mode 100644 index 16cba90c6..000000000 --- a/src/ioc/as/asIocRegister.c +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "asLib.h" -#include "iocsh.h" - -#define epicsExportSharedSymbols -#include "asCa.h" -#include "asDbLib.h" -#include "asIocRegister.h" - -/* asSetFilename */ -static const iocshArg asSetFilenameArg0 = { "ascf",iocshArgString}; -static const iocshArg * const asSetFilenameArgs[] = {&asSetFilenameArg0}; -static const iocshFuncDef asSetFilenameFuncDef = - {"asSetFilename",1,asSetFilenameArgs}; -static void asSetFilenameCallFunc(const iocshArgBuf *args) -{ - asSetFilename(args[0].sval); -} - -/* asSetSubstitutions */ -static const iocshArg asSetSubstitutionsArg0 = { "substitutions",iocshArgString}; -static const iocshArg * const asSetSubstitutionsArgs[] = {&asSetSubstitutionsArg0}; -static const iocshFuncDef asSetSubstitutionsFuncDef = - {"asSetSubstitutions",1,asSetSubstitutionsArgs}; -static void asSetSubstitutionsCallFunc(const iocshArgBuf *args) -{ - asSetSubstitutions(args[0].sval); -} - -/* asInit */ -static const iocshFuncDef asInitFuncDef = {"asInit",0}; -static void asInitCallFunc(const iocshArgBuf *args) -{ - asInit(); -} - -/* asdbdump */ -static const iocshFuncDef asdbdumpFuncDef = {"asdbdump",0}; -static void asdbdumpCallFunc(const iocshArgBuf *args) -{ - asdbdump(); -} - -/* aspuag */ -static const iocshArg aspuagArg0 = { "uagname",iocshArgString}; -static const iocshArg * const aspuagArgs[] = {&aspuagArg0}; -static const iocshFuncDef aspuagFuncDef = {"aspuag",1,aspuagArgs}; -static void aspuagCallFunc(const iocshArgBuf *args) -{ - aspuag(args[0].sval); -} - -/* asphag */ -static const iocshArg asphagArg0 = { "hagname",iocshArgString}; -static const iocshArg * const asphagArgs[] = {&asphagArg0}; -static const iocshFuncDef asphagFuncDef = {"asphag",1,asphagArgs}; -static void asphagCallFunc(const iocshArgBuf *args) -{ - asphag(args[0].sval); -} - -/* asprules */ -static const iocshArg asprulesArg0 = { "asgname",iocshArgString}; -static const iocshArg * const asprulesArgs[] = {&asprulesArg0}; -static const iocshFuncDef asprulesFuncDef = {"asprules",1,asprulesArgs}; -static void asprulesCallFunc(const iocshArgBuf *args) -{ - asprules(args[0].sval); -} - -/* aspmem */ -static const iocshArg aspmemArg0 = { "asgname",iocshArgString}; -static const iocshArg aspmemArg1 = { "clients",iocshArgInt}; -static const iocshArg * const aspmemArgs[] = {&aspmemArg0,&aspmemArg1}; -static const iocshFuncDef aspmemFuncDef = {"aspmem",2,aspmemArgs}; -static void aspmemCallFunc(const iocshArgBuf *args) -{ - aspmem(args[0].sval,args[1].ival); -} - -/* astac */ -static const iocshArg astacArg0 = { "recordname",iocshArgString}; -static const iocshArg astacArg1 = { "user",iocshArgString}; -static const iocshArg astacArg2 = { "location",iocshArgString}; -static const iocshArg * const astacArgs[] = {&astacArg0,&astacArg1,&astacArg2}; -static const iocshFuncDef astacFuncDef = {"astac",3,astacArgs}; -static void astacCallFunc(const iocshArgBuf *args) -{ - astac(args[0].sval,args[1].sval,args[2].sval); -} - -/* ascar */ -static const iocshArg ascarArg0 = { "level",iocshArgInt}; -static const iocshArg * const ascarArgs[] = {&ascarArg0}; -static const iocshFuncDef ascarFuncDef = {"ascar",1,ascarArgs}; -static void ascarCallFunc(const iocshArgBuf *args) -{ - ascar(args[0].ival); -} - -/* asDumpHash */ -static const iocshFuncDef asDumpHashFuncDef = {"asDumpHash",0,0}; -static void asDumpHashCallFunc(const iocshArgBuf *args) -{ - asDumpHash(); -} - -void asIocRegister(void) -{ - iocshRegister(&asSetFilenameFuncDef,asSetFilenameCallFunc); - iocshRegister(&asSetSubstitutionsFuncDef,asSetSubstitutionsCallFunc); - iocshRegister(&asInitFuncDef,asInitCallFunc); - iocshRegister(&asdbdumpFuncDef,asdbdumpCallFunc); - iocshRegister(&aspuagFuncDef,aspuagCallFunc); - iocshRegister(&asphagFuncDef,asphagCallFunc); - iocshRegister(&asprulesFuncDef,asprulesCallFunc); - iocshRegister(&aspmemFuncDef,aspmemCallFunc); - iocshRegister(&astacFuncDef,astacCallFunc); - iocshRegister(&ascarFuncDef,ascarCallFunc); - iocshRegister(&asDumpHashFuncDef,asDumpHashCallFunc); -} diff --git a/src/ioc/as/asIocRegister.h b/src/ioc/as/asIocRegister.h deleted file mode 100644 index a7421cdac..000000000 --- a/src/ioc/as/asIocRegister.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_asIocRegister_H -#define INC_asIocRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void asIocRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_asIocRegister_H */ diff --git a/src/ioc/as/ascheck.c b/src/ioc/as/ascheck.c deleted file mode 100644 index 7272ef4ae..000000000 --- a/src/ioc/as/ascheck.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 03-24-94 */ - -#include -#include -#include -#include - -#include "asLib.h" -#include "dbStaticLib.h" -#include "errlog.h" - -int main(int argc,char **argv) -{ - int argn = 1; - char *sub = NULL; - int subLength = 0; - char **pstr; - char *psep; - int *len; - long status = 0; - static char *subSep = ","; - - /* Look for -Smacro=value options */ - while (argc>argn && (strncmp(argv[argn], "-S", 2)==0)) { - pstr = ⊂ - psep = subSep; - len = &subLength; - if (strlen(argv[argn])==2) { - dbCatString(pstr, len, argv[++argn], psep); - } else { - dbCatString(pstr, len, argv[argn]+2, psep); - } - argn++; - } - if (argc == argn) { - status = asInitFP(stdin, sub); - if(status) errlogPrintf("ascheck: Access Security File failed.\n"); - } else if (argc == argn+1) { - status = asInitFile(argv[argn], sub); - if(status) errlogPrintf("ascheck: Access Security File failed.\n"); - } else { - printf("usage: ascheck [-Smac=sub ...] [<] file\n"); - status = -1; - } - errlogFlush(); - return status; -} diff --git a/src/ioc/bpt/Makefile b/src/ioc/bpt/Makefile deleted file mode 100644 index b8d73345f..000000000 --- a/src/ioc/bpt/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(IOCDIR)/bpt - -INC += cvtTable.h - -DBDINC += menuConvert - -BPT_DBD += bptTypeJdegC.dbd -BPT_DBD += bptTypeJdegF.dbd -BPT_DBD += bptTypeKdegC.dbd -BPT_DBD += bptTypeKdegF.dbd -DBD += $(BPT_DBD) - -PROD_HOST += makeBpt - -makeBpt_SRCS = makeBpt - -HTMLS += menuConvert.html - diff --git a/src/ioc/bpt/RULES b/src/ioc/bpt/RULES deleted file mode 100644 index a434eb342..000000000 --- a/src/ioc/bpt/RULES +++ /dev/null @@ -1,16 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2010 Brookhaven Science Associates, as Operator of -# Brookhaven National Lab. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -$(patsubst %,$(COMMON_DIR)/%,$(BPT_DBD)) : \ - $(COMMON_DIR)/bpt%.dbd : $(EPICS_BASE_HOST_BIN)/makeBpt$(HOSTEXE) - diff --git a/src/ioc/bpt/bptTypeJdegC.data b/src/ioc/bpt/bptTypeJdegC.data deleted file mode 100644 index a2ac1928f..000000000 --- a/src/ioc/bpt/bptTypeJdegC.data +++ /dev/null @@ -1,142 +0,0 @@ -!header -"typeJdegC" 0 0 700 4095 .5 -210 760 1 -!data - --8.096 -8.076 -8.057 -8.037 -8.017 -7.996 -7.976 -7.955 -7.934 -7.912 - - --7.890 -7.868 -7.846 -7.824 -7.801 -7.778 -7.755 -7.731 -7.707 -7.683 --7.659 -7.634 -7.609 -7.584 -7.559 -7.533 -7.508 -7.482 -7.455 -7.429 --7.402 -7.375 -7.348 -7.321 -7.293 -7.265 -7.237 -7.209 -7.180 -7.151 --7.122 -7.093 -7.064 -7.034 -7.004 -6.974 -6.944 -6.914 -6.883 -6.852 --6.821 -6.790 -6.758 -6.727 -6.695 -6.663 -6.630 -6.598 -6.565 -6.532 - - --6.499 -6.466 -6.433 -6.399 -6.365 -6.331 -6.297 -6.263 -6.228 -6.194 --6.159 -6.124 -6.089 -6.053 -6.018 -5.982 -5.946 -5.910 -5.874 -5.837 --5.801 -5.764 -5.727 -5.690 -5.653 -5.615 -5.578 -5.540 -5.502 -5.464 --5.426 -5.388 -5.349 -5.311 -5.272 -5.233 -5.194 -5.155 -5.115 -5.076 --5.036 -4.996 -4.956 -4.916 -4.876 -4.836 -4.795 -4.755 -4.714 -4.673 - - --4.632 -4.591 -4.550 -4.508 -4.467 -4.425 -4.383 -4.341 -4.299 -4.257 --4.215 -4.172 -4.130 -4.087 -4.044 -4.001 -3.958 -3.915 -3.872 -3.829 --3.785 -3.742 -3.698 -3.654 -3.610 -3.566 -3.522 -3.478 -3.433 -3.389 --3.344 -3.299 -3.255 -3.210 -3.165 -3.120 -3.074 -3.029 -2.984 -2.938 --2.892 -2.847 -2.801 -2.755 -2.709 -2.663 -2.617 -2.570 -2.524 -2.478 - - --2.431 -2.384 -2.338 -2.291 -2.244 -2.197 -2.150 -2.102 -2.055 -2.008 --1.960 -1.913 -1.865 -1.818 -1.770 -1.722 -1.674 -1.626 -1.578 -1.530 --1.481 -1.433 -1.385 -1.336 -1.288 -1.239 -1.190 -1.141 -1.093 -1.044 --0.995 -0.945 -0.896 -0.847 -0.798 -0.748 -0.699 -0.650 -0.600 -0.550 --0.501 -0.451 -0.401 -0.351 -0.301 -0.251 -0.201 -0.151 -0.101 -0.050 - - -0.0 0.050 0.101 0.151 0.202 0.253 0.303 0.354 0.405 0.456 -0.507 0.558 0.609 0.660 0.711 0.762 0.813 0.865 0.916 0.967 -1.019 1.070 1.122 1.174 1.225 1.277 1.329 1.381 1.432 1.484 -1.536 1.588 1.640 1.693 1.745 1.797 1.849 1.901 1.954 2.006 -2.058 2.111 2.163 2.216 2.268 2.321 2.374 2.426 2.479 2.532 - - -2.585 2.638 2.691 2.743 2.796 2.849 2.902 2.956 3.009 3.062 -3.115 3.168 3.221 3.275 3.328 3.381 3.435 3.488 3.542 3.595 -3.649 3.702 3.756 3.809 3.863 3.917 3.971 4.024 4.078 4.132 -4.186 4.239 4.293 4.347 4.401 4.455 4.509 4.563 4.617 4.671 -4.725 4.780 4.834 4.888 4.942 4.996 5.050 5.105 5.159 5.213 - - -5.268 5.322 5.376 5.431 5.485 5.540 5.594 5.649 5.703 5.758 -5.812 5.867 5.921 5.976 6.031 6.085 6.140 6.195 6.249 6.304 -6.359 6.414 6.468 6.523 6.578 6.633 6.688 6.742 6.797 6.852 -6.907 6.962 7.017 7.072 7.127 7.182 7.237 7.292 7.347 7.402 -7.457 7.512 7.567 7.622 7.677 7.732 7.787 7.843 7.898 7.953 - - -8.008 8.063 8.118 8.174 8.229 8.284 8.339 8.394 8.450 8.505 -8.560 8.616 8.671 8.726 8.781 8.837 8.892 8.947 9.003 9.058 -9.113 9.169 9.224 9.279 9.335 9.390 9.446 9.501 9.556 9.612 -9.667 9.723 9.778 9.834 9.889 9.944 10.000 10.055 10.111 10.166 -10.222 10.277 10.333 10.388 10.444 10.499 10.555 10.610 10.666 10.721 - - -10.777 10.832 10.888 10.943 10.999 11.054 11.110 11.165 11.221 11.276 -11.332 11.387 11.443 11.498 11.554 11.609 11.665 11.720 11.776 11.831 -11.887 11.943 11.998 12.054 12.109 12.165 12.220 12.276 12.331 12.387 -12.442 12.498 12.553 12.609 12.664 12.720 12.776 12.831 12.887 12.942 -12.998 13.053 13.109 13.164 13.220 13.275 13.331 13.386 13.442 13.497 - - -13.553 13.608 13.664 13.719 13.775 13.830 13.886 13.941 13.997 14.052 -14.108 14.163 14.219 14.274 14.330 14.385 14.441 14.496 14.552 14.607 -14.663 14.718 14.774 14.829 14.885 14.940 14.995 15.051 15.106 15.162 -15.217 15.273 15.328 15.383 15.439 15.494 15.550 15.605 15.661 15.716 -15.771 15.827 15.882 15.938 15.993 16.048 16.104 16.159 16.214 16.270 - - -16.325 16.380 16.436 16.491 16.547 16.602 16.657 16.713 16.768 16.823 -16.879 16.934 16.989 17.044 17.100 17.155 17.210 17.266 17.321 17.376 -17.432 17.487 17.542 17.597 17.653 17.708 17.763 17.818 17.874 17.929 -17.984 18.039 18.095 18.150 18.205 18.260 18.316 18.371 18.426 18.481 -18.537 18.592 18.647 18.702 18.757 18.813 18.868 18.923 18.978 19.033 - - -19.089 19.144 19.199 19.254 19.309 19.364 19.420 19.475 19.530 19.585 -19.640 19.695 19.751 19.806 19.861 19.916 19.971 20.026 20.081 20.137 -20.192 20.247 20.302 20.357 20.412 20.467 20.523 20.578 20.633 20.688 -20.743 20.798 20.853 20.909 20.964 21.019 21.074 21.129 21.184 21.239 -21.295 21.350 21.405 21.460 21.515 21.570 21.625 21.680 21.736 21.791 - - -21.846 21.901 21.956 22.011 22.066 22.122 22.177 22.232 22.287 22.342 -22.397 22.453 22.508 22.563 22.618 22.673 22.728 22.784 22.839 22.894 -22.949 23.004 23.060 23.115 23.170 23.225 23.280 23.336 23.391 23.446 -23.501 23.556 23.612 23.667 23.722 23.777 23.833 23.888 23.943 23.999 -24.054 24.109 24.164 24.220 24.275 24.330 24.386 24.441 24.496 24.552 - - -24.607 24.662 24.718 24.773 24.829 24.884 24.939 24.995 25.050 25.106 -25.161 25.217 25.272 25.327 25.383 25.438 25.494 25.549 25.605 25.661 -25.716 25.772 25.827 25.883 25.938 25.994 26.050 26.105 26.161 26.216 -26.272 26.328 26.383 26.439 26.495 26.551 26.606 26.662 26.718 26.774 -26.829 26.885 26.941 26.997 27.053 27.109 27.165 27.220 27.276 27.332 - - -27.388 27.444 27.500 27.556 27.612 27.668 27.724 27.780 27.836 27.893 -27.949 28.005 28.061 28.117 28.173 28.230 28.286 28.342 28.398 28.455 -28.511 28.567 28.624 28.680 28.736 28.793 28.849 28.906 28.962 29.019 -29.075 29.132 29.188 29.245 29.301 29.358 29.415 29.471 29.528 29.585 -29.642 29.698 29.755 29.812 29.869 29.926 29.983 30.039 30.096 30.153 - - -30.210 30.267 30.324 30.381 30.439 30.496 30.553 30.610 30.667 30.724 -30.782 30.839 30.896 30.954 31.011 31.068 31.126 31.183 31.241 31.298 -31.356 31.413 31.471 31.528 31.586 31.644 31.702 31.759 31.817 31.875 -31.933 31.991 32.048 32.106 32.164 32.222 32.280 32.338 32.396 32.455 -32.513 32.571 32.629 32.687 32.746 32.804 32.862 32.921 32.979 33.038 - - -33.096 33.155 33.213 33.272 33.330 33.389 33.448 33.506 33.565 33.624 -33.683 33.742 33.800 33.859 33.918 33.977 34.036 34.095 34.155 34.214 -34.273 34.332 34.391 34.451 34.510 34.569 34.629 34.688 34.748 34.807 -34.867 34.926 34.986 35.046 35.105 35.165 35.225 35.285 35.344 35.404 -35.464 35.524 35.584 35.644 35.704 35.764 35.825 35.885 35.945 36.005 - - -36.066 36.126 36.186 36.247 36.307 36.368 36.428 36.489 36.549 36.610 -36.671 36.732 36.792 36.853 36.914 36.975 37.036 37.097 37.158 37.219 -37.280 37.341 37.402 37.463 37.525 37.586 37.647 37.709 37.770 37.831 -37.893 37.954 38.016 38.078 38.139 38.201 38.262 38.324 38.386 38.448 -38.510 38.572 38.633 38.695 38.757 38.819 38.882 38.944 39.006 39.068 - - -39.130 39.192 39.255 39.317 39.379 39.442 39.504 39.567 39.629 39.692 -39.754 39.817 39.880 39.942 40.005 40.068 40.131 40.193 40.256 40.319 -40.382 40.445 40.508 40.571 40.634 40.697 40.760 40.823 40.886 40.950 -41.013 41.076 41.139 41.203 41.266 41.329 41.393 41.456 41.520 41.583 -41.647 41.710 41.774 41.837 41.901 41.965 42.028 42.092 42.156 42.219 - - -42.283 42.347 42.411 42.475 42.538 42.602 42.666 42.730 42.794 42.858 -42.922 diff --git a/src/ioc/bpt/bptTypeJdegF.data b/src/ioc/bpt/bptTypeJdegF.data deleted file mode 100644 index f912cb87e..000000000 --- a/src/ioc/bpt/bptTypeJdegF.data +++ /dev/null @@ -1,213 +0,0 @@ -! cvtTypeJdegF.data -"typeJdegF" 32 0 1200 4095 1.0 -350 1400 1 -! --8.137 -8.127 -8.117 -8.106 -8.096 -8.085 -8.074 -8.063 -8.052 -8.041 --8.030 -8.019 -8.008 -7.996 -7.985 -7.973 -7.962 -7.950 -7.938 -7.927 --7.915 -7.903 -7.890 -7.878 -7.866 -7.854 -7.841 -7.829 -7.816 -7.803 --7.791 -7.778 -7.765 -7.752 -7.739 -7.726 -7.712 -7.699 -7.686 -7.672 --7.659 -7.645 -7.631 -7.618 -7.604 -7.590 -7.576 -7.562 -7.548 -7.533 - --7.519 -7.505 -7.490 -7.476 -7.461 -7.447 -7.432 -7.417 -7.402 -7.387 --7.372 -7.357 -7.342 -7.327 -7.311 -7.296 -7.281 -7.265 -7.250 -7.234 --7.218 -7.202 -7.187 -7.171 -7.155 -7.139 -7.122 -7.106 -7.090 -7.074 --7.057 -7.041 -7.024 -7.008 -6.991 -6.974 -6.958 -6.941 -6.924 -6.907 --6.890 -6.873 -6.856 -6.838 -6.821 -6.804 -6.786 -6.769 -6.751 -6.734 - --6.716 -6.698 -6.680 -6.663 -6.645 -6.627 -6.609 -6.591 -6.572 -6.554 --6.536 -6.518 -6.499 -6.481 -6.462 -6.444 -6.425 -6.407 -6.388 -6.369 --6.350 -6.331 -6.312 -6.293 -6.274 -6.255 -6.236 -6.217 -6.198 -6.178 --6.159 -6.139 -6.120 -6.100 -6.081 -6.061 -6.041 -6.022 -6.002 -5.982 --5.962 -5.942 -5.922 -5.902 -5.882 -5.861 -5.841 -5.821 -5.801 -5.780 - --5.760 -5.739 -5.719 -5.698 -5.678 -5.657 -5.636 -5.615 -5.594 -5.574 --5.553 -5.532 -5.511 -5.490 -5.468 -5.447 -5.426 -5.405 -5.383 -5.362 --5.341 -5.319 -5.298 -5.276 -5.255 -5.233 -5.211 -5.190 -5.168 -5.146 --5.124 -5.102 -5.080 -5.058 -5.036 -5.014 -4.992 -4.970 -4.948 -4.925 --4.903 -4.881 -4.858 -4.836 -4.813 -4.791 -4.768 -4.746 -4.723 -4.700 - --4.678 -4.655 -4.632 -4.609 -4.586 -4.563 -4.540 -4.517 -4.494 -4.471 --4.448 -4.425 -4.402 -4.379 -4.355 -4.332 -4.309 -4.285 -4.262 -4.238 --4.215 -4.191 -4.168 -4.144 -4.120 -4.097 -4.073 -4.049 -4.025 -4.001 --3.978 -3.954 -3.930 -3.906 -3.882 -3.858 -3.833 -3.809 -3.785 -3.761 --3.737 -3.712 -3.688 -3.664 -3.639 -3.615 -3.590 -3.566 -3.541 -3.517 - --3.492 -3.468 -3.443 -3.418 -3.394 -3.369 -3.344 -3.319 -3.294 -3.270 --3.245 -3.220 -3.195 -3.170 -3.145 -3.120 -3.094 -3.069 -3.044 -3.019 --2.994 -2.968 -2.943 -2.918 -2.892 -2.867 -2.842 -2.816 -2.791 -2.765 --2.740 -2.714 -2.689 -2.663 -2.637 -2.612 -2.586 -2.560 -2.534 -2.509 --2.483 -2.457 -2.431 -2.405 -2.379 -2.353 -2.327 -2.301 -2.275 -2.249 - --2.223 -2.197 -2.171 -2.144 -2.118 -2.092 -2.066 -2.039 -2.013 -1.987 --1.960 -1.934 -1.908 -1.881 -1.855 -1.828 -1.802 -1.775 -1.748 -1.722 --1.695 -1.669 -1.642 -1.615 -1.589 -1.562 -1.535 -1.508 -1.481 -1.455 --1.428 -1.401 -1.374 -1.347 -1.320 -1.293 -1.266 -1.239 -1.212 -1.185 --1.158 -1.131 -1.103 -1.076 -1.049 -1.022 -0.995 -0.967 -0.940 -0.913 - --0.885 -0.858 -0.831 -0.803 -0.776 -0.748 -0.721 -0.694 -0.666 -0.639 --0.611 -0.583 -0.556 -0.528 -0.501 -0.473 -0.445 -0.418 -0.390 -0.362 --0.334 -0.307 -0.279 -0.251 -0.223 -0.195 -0.168 -0.140 -0.112 -0.084 --0.056 -0.028 0.000 0.028 0.056 0.084 0.112 0.140 0.168 0.196 -0.224 0.253 0.281 0.309 0.337 0.365 0.394 0.422 0.450 0.478 - -0.507 0.535 0.563 0.592 0.620 0.648 0.677 0.705 0.734 0.762 -0.791 0.819 0.848 0.876 0.905 0.933 0.962 0.990 1.019 1.048 -1.076 1.105 1.134 1.162 1.191 1.220 1.248 1.277 1.306 1.335 -1.363 1.392 1.421 1.450 1.479 1.507 1.536 1.565 1.594 1.623 -1.652 1.681 1.710 1.739 1.768 1.797 1.826 1.855 1.884 1.913 - -1.942 1.971 2.000 2.029 2.058 2.088 2.117 2.146 2.175 2.204 -2.233 2.263 2.292 2.321 2.350 2.380 2.409 2.438 2.467 2.497 -2.526 2.555 2.585 2.614 2.644 2.673 2.702 2.732 2.761 2.791 -2.820 2.849 2.879 2.908 2.938 2.967 2.997 3.026 3.056 3.085 -3.115 3.145 3.174 3.204 3.233 3.263 3.293 3.322 3.352 3.381 - -3.411 3.441 3.470 3.500 3.530 3.560 3.589 3.619 3.649 3.678 -3.708 3.738 3.768 3.798 3.827 3.857 3.887 3.917 3.947 3.976 -4.006 4.036 4.066 4.096 4.126 4.156 4.186 4.216 4.245 4.275 -4.305 4.335 4.365 4.395 4.425 4.455 4.485 4.515 4.545 4.575 -4.605 4.635 4.665 4.695 4.725 4.755 4.786 4.816 4.846 4.876 - -4.906 4.936 4.966 4.996 5.026 5.057 5.087 5.117 5.147 5.177 -5.207 5.238 5.268 5.298 5.328 5.358 5.389 5.419 5.449 5.479 -5.509 5.540 5.570 5.600 5.630 5.661 5.691 5.721 5.752 5.782 -5.812 5.843 5.873 5.903 5.934 5.964 5.994 6.025 6.055 6.085 -6.116 6.146 6.176 6.207 6.237 6.268 6.298 6.328 6.359 6.389 - -6.420 6.450 6.481 6.511 6.541 6.572 6.602 6.633 6.663 6.694 -6.724 6.755 6.785 6.816 6.846 6.877 6.907 6.938 6.968 6.999 -7.029 7.060 7.090 7.121 7.151 7.182 7.212 7.243 7.274 7.304 -7.335 7.365 7.396 7.426 7.457 7.488 7.518 7.549 7.579 7.610 -7.641 7.671 7.702 7.732 7.763 7.794 7.824 7.855 7.885 7.916 - -7.947 7.977 8.008 8.039 8.069 8.100 8.131 8.161 8.192 8.223 -8.253 8.284 8.315 8.345 8.376 8.407 8.437 8.468 8.499 8.530 -8.560 8.591 8.622 8.652 8.683 8.714 8.745 8.775 8.806 8.837 -8.867 8.898 8.929 8.960 8.990 9.021 9.052 9.083 9.113 9.144 -9.175 9.206 9.236 9.267 9.298 9.329 9.359 9.390 9.421 9.452 - -9.483 9.513 9.544 9.575 9.606 9.636 9.667 9.698 9.729 9.760 -9.790 9.821 9.852 9.883 9.914 9.944 9.975 10.006 10.037 10.068 -10.098 10.129 10.160 10.191 10.222 10.252 10.283 10.314 10.345 10.376 -10.407 10.437 10.468 10.499 10.530 10.561 10.592 10.622 10.653 10.684 -10.715 10.746 10.777 10.807 10.838 10.869 10.900 10.931 10.962 10.992 - -11.023 11.054 11.085 11.116 11.147 11.177 11.208 11.239 11.270 11.301 -11.332 11.363 11.393 11.424 11.455 11.486 11.517 11.548 11.578 11.609 -11.640 11.671 11.702 11.733 11.764 11.794 11.825 11.856 11.887 11.918 -11.949 11.980 12.010 12.041 12.072 12.103 12.134 12.165 12.196 12.226 -12.257 12.288 12.319 12.350 12.381 12.411 12.442 12.473 12.504 12.535 - -12.566 12.597 12.627 12.658 12.689 12.720 12.751 12.782 12.813 12.843 -12.874 12.905 12.936 12.967 12.998 13.029 13.059 13.090 13.121 13.152 -13.183 13.214 13.244 13.275 13.306 13.337 13.368 13.399 13.430 13.460 -13.491 13.522 13.553 13.584 13.615 13.645 13.676 13.707 13.738 13.769 -13.800 13.830 13.861 13.892 13.923 13.954 13.985 14.015 14.046 14.077 - -14.108 14.139 14.170 14.200 14.231 14.262 14.293 14.324 14.355 14.385 -14.416 14.447 14.478 14.509 14.539 14.570 14.601 14.632 14.663 14.694 -14.724 14.755 14.786 14.817 14.848 14.878 14.909 14.940 14.971 15.002 -15.032 15.063 15.094 15.125 15.156 15.186 15.217 15.248 15.279 15.310 -15.340 15.371 15.402 15.433 15.464 15.494 15.525 15.556 15.587 15.617 - -15.648 15.679 15.710 15.741 15.771 15.802 15.833 15.864 15.894 15.925 -15.956 15.987 16.018 16.048 16.079 16.110 16.141 16.171 16.202 16.233 -16.264 16.294 16.325 16.356 16.387 16.417 16.448 16.479 16.510 16.540 -16.571 16.602 16.633 16.663 16.694 16.725 16.756 16.786 16.817 16.848 -16.879 16.909 16.940 16.971 17.001 17.032 17.063 17.094 17.124 17.155 - -17.186 17.217 17.247 17.278 17.309 17.339 17.370 17.401 17.432 17.462 -17.493 17.524 17.554 17.585 17.616 17.646 17.677 17.708 17.739 17.769 -17.800 17.831 17.861 17.892 17.923 17.953 17.984 18.015 18.046 18.076 -18.107 18.138 18.168 18.199 18.230 18.260 18.291 18.322 18.352 18.383 -18.414 18.444 18.475 18.506 18.537 18.567 18.598 18.629 18.659 18.690 - -18.721 18.751 18.782 18.813 18.843 18.874 18.905 18.935 18.966 18.997 -19.027 19.058 19.089 19.119 19.150 19.180 19.211 19.242 19.272 19.303 -19.334 19.364 19.395 19.426 19.456 19.487 19.518 19.548 19.579 19.610 -19.640 19.671 19.702 19.732 19.763 19.793 19.824 19.855 19.885 19.916 -19.947 19.977 20.008 20.039 20.069 20.100 20.131 20.161 20.192 20.222 - -20.253 20.284 20.314 20.345 20.376 20.406 20.437 20.467 20.498 20.529 -20.559 20.590 20.621 20.651 20.682 20.713 20.743 20.774 20.804 20.835 -20.866 20.896 20.927 20.958 20.988 21.019 21.049 21.080 21.111 21.141 -21.172 21.203 21.233 21.264 21.295 21.325 21.356 21.386 21.417 21.448 -21.478 21.509 21.540 21.570 21.601 21.631 21.662 21.693 21.723 21.754 - -21.785 21.815 21.846 21.877 21.907 21.938 21.968 21.999 22.030 22.060 -22.091 22.122 22.152 22.183 22.214 22.244 22.275 22.305 22.336 22.367 -22.397 22.428 22.459 22.489 22.520 22.551 22.581 22.612 22.643 22.673 -22.704 22.735 22.765 22.796 22.826 22.857 22.888 22.918 22.949 22.980 -23.010 23.041 23.072 23.102 23.133 23.164 23.194 23.225 23.256 23.286 - -23.317 23.348 23.378 23.409 23.440 23.471 23.501 23.532 23.563 23.593 -23.624 23.655 23.685 23.716 23.747 23.777 23.808 23.839 23.870 23.900 -23.931 23.962 23.992 24.023 24.054 24.085 24.115 24.146 24.177 24.207 -24.238 24.269 24.300 24.330 24.361 24.392 24.423 24.453 24.484 24.515 -24.546 24.576 24.607 24.638 24.669 24.699 24.730 24.761 24.792 24.822 - -24.853 24.854 24.915 24.946 24.976 25.007 25.038 25.069 25.099 25.130 -25.161 25.192 25.223 25.254 25.284 25.315 25.346 25.377 25.408 25.438 -25.469 25.500 25.531 25.562 25.593 25.623 25.654 25.685 25.716 25.747 -25.778 25.809 25.840 25.870 25.901 25.932 25.963 25.994 26.025 26.056 -26.087 26.118 26.148 26.179 26.210 26.241 26.272 26.303 26.334 26.365 - -26.396 26.427 26.458 26.489 26.520 26.551 26.582 26.613 26.644 26.675 -26.705 26.736 26.767 26.798 26.829 26.860 26.891 26.922 26.954 26.985 -27.016 27.047 27.078 27.109 27.140 27.171 27.202 27.233 27.264 27.295 -27.326 27.357 27.388 27.419 27.450 27.482 27.513 27.544 27.575 27.606 -27.637 27.668 27.699 27.731 27.762 27.793 27.824 27.855 27.886 27.917 - -27.949 27.980 28.011 28.042 28.073 28.105 28.136 28.167 28.198 28.230 -28.261 28.292 28.323 28.355 28.386 28.417 28.448 28.480 28.511 28.542 -28.573 28.605 28.636 28.667 28.699 28.730 28.761 28.793 28.824 28.855 -28.887 28.918 28.950 28.981 29.012 29.044 29.075 29.107 29.138 29.169 -29.201 29.232 29.264 29.295 29.327 29.358 29.390 29.421 29.452 29.484 - -29.515 29.547 29.578 29.610 29.642 29.673 29.705 29.736 29.768 29.799 -29.831 29.862 29.894 29.926 29.957 29.989 30.020 30.052 30.084 30.115 -30.147 30.179 30.210 30.242 30.274 30.305 30.337 30.369 30.400 30.432 -30.464 30.496 30.527 30.559 30.591 30.623 30.654 30.686 30.718 30.750 -30.782 30.813 30.845 30.877 30.909 30.941 30.973 31.005 31.036 31.068 - -31.100 31.132 31.164 31.196 31.228 31.260 31.292 31.324 31.356 31.388 -31.420 31.452 31.484 31.516 31.548 31.580 31.612 31.644 31.676 31.708 -31.740 31.772 31.804 31.836 31.868 31.901 31.933 31.965 31.997 32.029 -32.061 32.094 32.126 32.158 32.190 32.222 32.255 32.287 32.319 32.351 -32.384 32.416 32.448 32.480 32.513 32.545 32.577 32.610 32.642 32.674 - -32.707 32.739 32.772 32.804 32.836 32.869 32.901 32.934 32.966 32.999 -33.031 33.064 33.096 33.129 33.161 33.194 33.226 33.259 33.291 33.324 -33.356 33.389 33.422 33.454 33.487 33.519 33.552 33.585 33.617 33.650 -33.683 33.715 33.748 33.781 33.814 33.846 33.879 33.912 33.945 33.977 -34.010 34.043 34.076 34.109 34.141 34.174 34.207 34.240 34.273 34.306 - -34.339 34.372 34.405 34.437 34.470 34.503 34.536 34.569 34.602 34.635 -34.668 34.701 34.734 34.767 34.801 34.834 34.867 34.900 34.933 34.966 -34.999 35.032 35.065 35.099 35.132 35.165 35.198 35.231 35.265 35.298 -35.331 35.364 35.398 35.431 35.464 35.498 35.531 35.564 35.598 35.631 -35.664 35.698 35.731 35.764 35.798 35.831 35.865 35.898 35.932 35.965 - -35.999 36.032 36.066 36.099 36.133 36.166 36.200 36.233 36.267 36.301 -36.334 36.368 36.401 36.435 36.469 36.502 36.536 36.570 36.603 36.637 -36.671 36.705 36.738 36.772 36.806 36.840 36.873 36.907 36.941 36.975 -37.009 37.043 37.076 37.110 37.144 37.178 37.212 37.246 37.280 37.314 -37.348 37.382 37.416 37.450 37.484 37.518 37.552 37.586 37.620 37.654 - -37.688 37.722 37.756 37.790 37.825 37.859 37.893 37.927 37.961 37.995 -38.030 38.064 38.098 38.132 38.167 38.201 38.235 38.269 38.304 38.338 -38.372 38.407 38.441 38.475 38.510 38.544 38.578 38.613 38.647 38.682 -38.716 38.751 38.785 38.819 38.854 38.888 38.923 38.957 38.992 39.027 -39.061 39.096 39.130 39.165 39.199 39.234 39.269 39.303 39.338 39.373 - -39.407 39.442 39.477 39.511 39.546 39.581 39.615 39.650 39.685 39.720 -39.754 39.789 39.824 39.859 39.894 39.928 39.963 39.998 40.033 40.068 -40.103 40.138 40.172 40.207 40.242 40.277 40.312 40.347 40.382 40.417 -40.452 40.487 40.522 40.557 40.592 40.627 40.662 40.697 40.732 40.767 -40.802 40.837 40.872 40.908 40.943 40.978 41.013 41.048 41.083 41.118 - -41.154 41.189 41.224 41.259 41.294 41.329 41.365 41.400 41.435 41.470 -41.506 41.541 41.576 41.611 41.647 41.682 41.717 41.753 41.788 41.823 -41.859 41.894 41.929 41.965 42.000 42.035 42.071 42.106 42.142 42.177 -42.212 42.248 42.283 42.319 42.354 42.390 42.425 42.460 42.496 42.531 -42.567 42.602 42.638 42.673 42.709 42.744 42.780 42.815 42.851 42.886 -42.922 diff --git a/src/ioc/bpt/bptTypeKdegC.data b/src/ioc/bpt/bptTypeKdegC.data deleted file mode 100644 index 4136fa9b5..000000000 --- a/src/ioc/bpt/bptTypeKdegC.data +++ /dev/null @@ -1,201 +0,0 @@ -! cvtTypeKdegC.data -"typeKdegC" 0 0 1000 4095 .5 -270 1372 1 -! --6.458 -6.457 -6.456 -6.455 -6.453 -6.452 -6.450 -6.448 -6.446 -6.444 --6.441 -6.438 -6.435 -6.432 -6.429 -6.425 -6.421 -6.417 -6.413 -6.408 - --6.404 -6.399 -6.394 -6.388 -6.382 -6.377 -6.371 -6.364 -6.358 -6.351 --6.344 -6.337 -6.329 -6.322 -6.314 -6.306 -6.297 -6.289 -6.280 -6.271 --6.262 -6.253 -6.243 -6.233 -6.223 -6.213 -6.202 -6.192 -6.181 -6.170 --6.158 -6.147 -6.135 -6.123 -6.111 -6.099 -6.087 -6.074 -6.061 -6.048 --6.035 -6.021 -6.007 -5.994 -5.980 -5.965 -5.951 -5.936 -5.922 -5.907 - --5.891 -5.876 -5.860 -5.845 -5.829 -5.813 -5.796 -5.780 -5.763 -5.747 --5.730 -5.712 -5.695 -5.678 -5.660 -5.642 -5.624 -5.606 -5.587 -5.569 --5.550 -5.531 -5.512 -5.493 -5.474 -5.454 -5.434 -5.414 -5.394 -5.374 --5.354 -5.333 -5.313 -5.292 -5.271 -5.249 -5.228 -5.207 -5.185 -5.163 --5.141 -5.119 -5.097 -5.074 -5.051 -5.029 -5.006 -4.983 -4.959 -4.936 - --4.912 -4.889 -4.865 -4.841 -4.817 -4.792 -4.768 -4.743 -4.719 -4.694 --4.669 -4.644 -4.618 -4.593 -4.567 -4.541 -4.515 -4.489 -4.463 -4.437 --4.410 -4.384 -4.357 -4.330 -4.303 -4.276 -4.248 -4.221 -4.193 -4.166 --4.138 -4.110 -4.082 -4.053 -4.025 -3.997 -3.968 -3.939 -3.910 -3.881 --3.852 -3.823 -3.793 -3.764 -3.734 -3.704 -3.674 -3.644 -3.614 -3.584 - --3.553 -3.523 -3.492 -3.461 -3.430 -3.399 -3.368 -3.337 -3.305 -3.274 --3.242 -3.211 -3.179 -3.147 -3.115 -3.082 -3.050 -3.018 -2.985 -2.953 --2.920 -2.887 -2.854 -2.821 -2.788 -2.754 -2.721 -2.687 -2.654 -2.620 --2.586 -2.552 -2.518 -2.484 -2.450 -2.416 -2.381 -2.347 -2.312 -2.277 --2.243 -2.208 -2.173 -2.137 -2.102 -2.067 -2.032 -1.996 -1.961 -1.925 - --1.889 -1.853 -1.817 -1.781 -1.745 -1.709 -1.673 -1.636 -1.600 -1.563 --1.527 -1.490 -1.453 -1.416 -1.379 -1.342 -1.305 -1.268 -1.231 -1.193 --1.156 -1.118 -1.081 -1.043 -1.005 -0.968 -0.930 -0.892 -0.854 -0.816 --0.777 -0.739 -0.701 -0.662 -0.624 -0.585 -0.547 -0.508 -0.469 -0.431 --0.392 -0.353 -0.314 -0.275 -0.236 -0.197 -0.157 -0.118 -0.079 -0.039 - -0.000 0.039 0.079 0.119 0.158 0.198 0.238 0.277 0.317 0.357 -0.397 0.437 0.477 0.517 0.557 0.597 0.637 0.677 0.718 0.758 -0.798 0.838 0.879 0.919 0.960 1.000 1.041 1.081 1.122 1.162 -1.203 1.244 1.285 1.325 1.366 1.407 1.448 1.489 1.529 1.570 -1.611 1.652 1.693 1.734 1.776 1.817 1.858 1.899 1.940 1.981 - -2.022 2.064 2.105 2.146 2.188 2.229 2.270 2.312 2.353 2.394 -2.436 2.477 2.519 2.560 2.601 2.643 2.684 2.726 2.767 2.809 -2.850 2.892 2.933 2.975 3.016 3.058 3.100 3.141 3.183 3.224 -3.266 3.307 3.349 3.390 3.432 3.473 3.515 3.556 3.598 3.639 -3.681 3.722 3.764 3.805 3.847 3.888 3.930 3.971 4.012 4.054 - -4.095 4.137 4.178 4.219 4.261 4.302 4.343 4.384 4.426 4.467 -4.508 4.549 4.590 4.632 4.673 4.714 4.755 4.796 4.837 4.878 -4.919 4.960 5.001 5.042 5.083 5.124 5.164 5.205 5.246 5.287 -5.327 5.368 5.409 5.450 5.490 5.531 5.571 5.612 5.652 5.693 -5.733 5.774 5.814 5.855 5.895 5.936 5.976 6.016 6.057 6.097 - -6.137 6.177 6.218 6.258 6.298 6.338 6.378 6.419 6.459 6.499 -6.539 6.579 6.619 6.659 6.699 6.739 6.779 6.819 6.859 6.899 -6.939 6.979 7.019 7.059 7.099 7.139 7.179 7.219 7.259 7.299 -7.338 7.378 7.418 7.458 7.498 7.538 7.578 7.618 7.658 7.697 -7.737 7.777 7.817 7.857 7.897 7.937 7.977 8.017 8.057 8.097 - -8.137 8.177 8.216 8.256 8.296 8.336 8.376 8.416 8.456 8.497 -8.537 8.577 8.617 8.657 8.697 8.737 8.777 8.817 8.857 8.898 -8.938 8.978 9.018 9.058 9.099 9.139 9.179 9.220 9.260 9.300 -9.341 9.381 9.421 9.462 9.502 9.543 9.583 9.624 9.664 9.705 -9.745 9.786 9.826 9.867 9.907 9.948 9.989 10.029 10.070 10.111 - -10.151 10.192 10.233 10.274 10.315 10.355 10.396 10.437 10.478 10.519 -10.560 10.600 10.641 10.682 10.723 10.764 10.805 10.846 10.887 10.928 -10.969 11.010 11.051 11.093 11.134 11.175 11.216 11.257 11.298 11.339 -11.381 11.422 11.463 11.504 11.546 11.587 11.628 11.669 11.711 11.752 -11.793 11.835 11.876 11.918 11.959 12.000 12.042 12.083 12.125 12.166 - -12.207 12.249 12.290 12.332 12.373 12.415 12.456 12.498 12.539 12.581 -12.623 12.664 12.706 12.747 12.789 12.831 12.872 12.914 12.955 12.997 -13.039 13.080 13.122 13.164 13.205 13.247 13.289 13.331 13.372 13.414 -13.456 13.497 13.539 13.581 13.623 13.665 13.706 13.748 13.790 13.832 -13.874 13.915 13.957 13.999 14.041 14.083 14.125 14.167 14.208 14.250 - -14.292 14.334 14.376 14.418 14.460 14.502 14.544 14.586 14.628 14.670 -14.712 14.754 14.796 14.838 14.880 14.922 14.964 15.006 15.048 15.090 -15.132 15.174 15.216 15.258 15.300 15.342 15.384 15.426 15.468 15.510 -15.552 15.594 15.636 15.679 15.721 15.763 15.805 15.847 15.889 15.931 -15.974 16.016 16.058 16.100 16.142 16.184 16.227 16.269 16.311 16.353 - -16.395 16.438 16.480 16.522 16.564 16.607 16.649 16.691 16.733 16.776 -16.818 16.860 16.902 16.945 16.987 17.029 17.072 17.114 17.156 17.199 -17.241 17.283 17.326 17.368 17.410 17.453 17.495 17.537 17.580 17.622 -17.664 17.707 17.749 17.792 17.834 17.876 17.919 17.961 18.004 18.046 -18.088 18.131 18.173 18.216 18.258 18.301 18.343 18.385 18.428 18.470 - -18.513 18.555 18.598 18.640 18.683 18.725 18.768 18.810 18.853 18.895 -18.938 18.980 19.023 19.065 19.108 19.150 19.193 19.235 19.278 19.320 -19.363 19.405 19.448 19.490 19.533 19.576 19.618 19.661 19.703 19.746 -19.788 19.831 19.873 19.916 19.959 20.001 20.044 20.086 20.129 20.172 -20.214 20.257 20.299 20.342 20.385 20.427 20.470 20.512 20.555 20.598 - -20.640 20.683 20.725 20.768 20.811 20.853 20.896 20.938 20.981 21.024 -21.066 21.109 21.152 21.194 21.237 21.280 21.322 21.365 21.407 21.450 -21.493 21.535 21.578 21.621 21.663 21.706 21.749 21.791 21.834 21.876 -21.919 21.962 22.004 22.047 22.090 22.132 22.175 22.218 22.260 22.303 -22.346 22.388 22.431 22.473 22.516 22.559 22.601 22.644 22.687 22.729 - -22.772 22.815 22.857 22.900 22.942 22.985 23.028 23.070 23.113 23.156 -23.198 23.241 23.284 23.326 23.369 23.411 23.454 23.497 23.539 23.582 -23.624 23.667 23.710 23.752 23.795 23.837 23.880 23.923 23.965 24.008 -24.050 24.093 24.136 24.178 24.221 24.263 24.306 24.348 24.391 24.434 -24.476 24.519 24.561 24.604 24.646 24.689 24.731 24.774 24.817 24.859 - -24.902 24.944 24.987 25.029 25.072 25.114 25.157 25.199 25.242 25.284 -25.327 25.369 25.412 25.454 25.497 25.539 25.582 25.624 25.666 25.709 -25.751 25.794 25.836 25.879 25.921 25.964 26.006 26.048 26.091 26.133 -26.176 26.218 26.260 26.303 26.345 26.387 26.430 26.472 26.515 26.557 -26.599 26.642 26.684 26.726 26.769 26.811 26.853 26.896 26.938 26.980 - -27.022 27.065 27.107 27.149 27.192 27.234 27.276 27.318 27.361 27.403 -27.445 27.487 27.529 27.572 27.614 27.656 27.698 27.740 27.783 27.825 -27.867 27.909 27.951 27.993 28.035 28.078 28.120 28.162 28.204 28.246 -28.288 28.330 28.372 28.414 28.456 28.498 28.540 28.583 28.625 28.667 -28.709 28.751 28.793 28.835 28.877 28.919 28.961 29.002 29.044 29.086 - -29.128 29.170 29.212 29.254 29.296 29.338 29.380 29.422 29.464 29.505 -29.547 29.589 29.631 29.673 29.715 29.756 29.798 29.840 29.882 29.924 -29.965 30.007 30.049 30.091 30.132 30.174 30.216 30.257 30.299 30.341 -30.383 30.424 30.466 30.508 30.549 30.591 30.632 30.674 30.716 30.757 -30.799 30.840 30.882 30.924 30.965 31.007 31.048 31.090 31.131 31.173 - -31.214 31.256 31.297 31.339 31.380 31.422 31.463 31.504 31.546 31.587 -31.629 31.670 31.712 31.753 31.794 31.836 31.877 31.918 31.960 32.001 -32.042 32.084 32.125 32.166 32.207 32.249 32.290 32.331 32.372 32.414 -32.455 32.496 32.537 32.578 32.619 32.661 32.702 32.743 32.784 32.825 -32.866 32.907 32.948 32.990 33.031 33.072 33.113 33.154 33.195 33.236 - -33.277 33.318 33.359 33.400 33.441 33.482 33.523 33.564 33.604 33.645 -33.686 33.727 33.768 33.809 33.850 33.891 33.931 33.972 34.013 34.054 -34.095 34.136 34.176 34.217 34.258 34.299 34.339 34.380 34.421 34.461 -34.502 34.543 34.583 34.624 34.665 34.705 34.746 34.787 34.827 34.868 -34.909 34.949 34.990 35.030 35.071 35.111 35.152 35.192 35.233 35.273 - -35.314 35.354 35.395 35.435 35.476 35.516 35.557 35.597 35.637 35.678 -35.718 35.758 35.799 35.839 35.880 35.920 35.960 36.000 36.041 36.081 -36.121 36.162 36.202 36.242 36.282 36.323 36.363 36.403 36.443 36.483 -36.524 36.564 36.604 36.644 36.684 36.724 36.764 36.804 36.844 36.885 -36.925 36.965 37.005 37.045 37.085 37.125 37.165 37.205 37.245 37.285 - -37.325 37.365 37.405 37.445 37.484 37.524 37.564 37.604 37.644 37.684 -37.724 37.764 37.803 37.843 37.883 37.923 37.963 38.002 38.042 38.082 -38.122 38.162 38.201 38.241 38.281 38.320 38.360 38.400 38.439 38.479 -38.519 38.558 38.598 38.638 38.677 38.717 38.756 38.796 38.836 38.875 -38.915 38.954 38.994 39.033 39.073 39.112 39.152 39.191 39.231 39.270 - -39.310 39.349 39.388 39.428 39.467 39.507 39.546 39.585 39.625 39.644 -39.703 39.743 39.782 39.821 39.861 39.900 39.939 39.979 40.018 40.057 -40.096 40.136 40.175 40.214 40.253 40.292 40.332 40.371 40.410 40.449 -40.488 40.527 40.566 40.605 40.645 40.684 40.723 40.762 40.801 40.840 -40.879 40.918 40.957 40.996 41.035 41.074 41.113 41.152 41.191 41.230 - -41.269 41.308 41.347 41.385 41.424 41.463 41.502 41.541 41.580 41.619 -41.657 41.696 41.735 41.774 41.813 41.851 41.890 41.929 41.968 42.006 -42.045 42.084 42.123 42.161 42.200 42.239 42.277 42.316 42.355 42.393 -42.432 42.470 42.509 42.548 42.586 42.625 42.663 42.702 42.740 42.779 -42.817 42.856 42.894 42.933 42.971 43.010 43.048 43.087 43.125 43.164 - -43.202 43.240 43.279 43.317 43.356 43.394 43.432 43.471 43.509 43.547 -43.585 43.624 43.662 43.700 43.739 43.777 43.815 43.853 43.891 43.930 -43.968 44.006 44.044 44.082 44.121 44.159 44.197 44.235 44.273 44.311 -44.349 44.387 44.425 44.463 44.501 44.539 44.577 44.615 44.653 44.691 -44.729 44.767 44.805 44.843 44.881 44.919 44.957 44.995 45.033 45.070 - -45.108 45.146 45.184 45.222 45.260 45.297 45.335 45.373 45.411 45.448 -45.486 45.524 45.561 45.599 45.637 45.675 45.712 45.750 45.787 45.825 -45.863 45.900 45.938 45.975 46.013 46.051 46.088 46.126 46.163 46.201 -46.238 46.275 46.313 46.350 46.388 46.425 46.463 46.500 46.537 46.575 -46.612 46.649 46.687 46.724 46.761 46.799 46.836 46.873 46.910 46.948 - -46.985 47.022 47.059 47.096 47.134 47.171 47.208 47.245 47.282 47.319 -47.356 47.393 47.430 47.468 47.505 47.542 47.579 47.616 47.653 47.689 -47.726 47.763 47.800 47.837 47.874 47.911 47.948 47.985 48.021 48.058 -48.095 48.132 48.169 48.205 48.242 48.279 48.316 48.352 48.389 48.426 -48.462 48.499 48.536 48.572 48.609 48.645 48.682 48.718 48.755 48.792 - -48.828 48.865 48.901 48.937 48.974 49.010 49.047 49.083 49.120 49.156 -49.192 49.229 49.265 49.301 49.338 49.374 49.410 49.446 49.483 49.519 -49.555 49.591 49.627 49.663 49.700 49.736 49.772 49.808 49.844 49.880 -49.916 49.952 49.988 50.024 50.060 50.096 50.132 50.168 50.204 50.240 -50.276 50.311 50.347 50.383 50.419 50.455 50.491 50.526 50.562 50.598 - -50.633 50.669 50.705 50.741 50.776 50.812 50.847 50.883 50.919 50.954 -50.990 51.025 51.061 51.096 51.132 51.167 51.203 51.238 51.274 51.309 -51.344 51.380 51.415 51.450 51.486 51.521 51.556 51.592 51.627 51.662 -51.697 51.733 51.768 51.803 51.838 51.873 51.908 51.943 51.979 52.014 -52.049 52.084 52.119 52.154 52.189 52.224 52.259 52.294 52.329 52.364 - -52.398 52.433 52.468 52.503 52.538 52.573 52.608 52.642 52.677 52.712 -52.747 52.781 52.816 52.851 52.886 52.920 52.955 52.989 53.024 53.059 -53.093 53.128 53.162 53.197 53.232 53.266 53.301 53.335 53.370 53.404 -53.439 53.473 53.507 53.542 53.576 53.611 53.645 53.679 53.714 53.748 -53.782 53.817 53.851 53.885 53.920 53.954 53.988 54.022 54.057 54.091 - -54.125 54.159 54.193 54.228 54.262 54.296 54.330 54.364 54.398 54.432 -54.466 54.501 54.535 54.569 54.603 54.637 54.671 54.705 54.739 54.773 -54.807 54.841 54.875 diff --git a/src/ioc/bpt/bptTypeKdegF.data b/src/ioc/bpt/bptTypeKdegF.data deleted file mode 100644 index 20210cc5a..000000000 --- a/src/ioc/bpt/bptTypeKdegF.data +++ /dev/null @@ -1,360 +0,0 @@ -! cvtTypeKdegF.data -"typeKdegF" 32 0 1832 4095 1.0 -454 2500 1 -! - -6.458 -6.457 -6.457 -6.456 - --6.456 -6.455 -6.454 -6.454 -6.453 -6.452 -6.451 -6.450 -6.449 -6.448 --6.447 -6.445 -6.444 -6.443 -6.441 -6.440 -6.438 -6.436 -6.435 -6.433 --6.431 -6.429 -6.427 -6.425 -6.423 -6.421 -6.419 -6.416 -6.414 -6.411 --6.409 -6.406 -6.404 -6.401 -6.398 -6.395 -6.392 -6.389 -6.386 -6.383 --6.380 -6.377 -6.373 -6.370 -6.366 -6.363 -6.359 -6.355 -6.352 -6.348 - --6.344 -6.340 -6.336 -6.332 -6.328 -6.323 -6.319 -6.315 -6.310 -6.306 --6.301 -6.296 -6.292 -6.287 -6.282 -6.277 -6.272 -6.267 -6.262 -6.257 --6.251 -6.246 -6.241 -6.235 -6.230 -6.224 -6.219 -6.213 -6.207 -6.201 --6.195 -6.189 -6.183 -6.177 -6.171 -6.165 -6.158 -6.152 -6.146 -6.139 --6.133 -6.126 -6.119 -6.113 -6.106 -6.099 -6.092 -6.085 -6.078 -6.071 - --6.064 -6.057 -6.049 -6.042 -6.035 -6.027 -6.020 -6.012 -6.004 -5.997 --5.989 -5.981 -5.973 -5.965 -5.957 -5.949 -5.941 -5.933 -5.925 -5.917 --5.908 -5.900 -5.891 -5.883 -5.874 -5.866 -5.857 -5.848 -5.839 -5.831 --5.822 -5.813 -5.804 -5.795 -5.786 -5.776 -5.767 -5.758 -5.748 -5.739 --5.730 -5.720 -5.711 -5.701 -5.691 -5.682 -5.672 -5.662 -5.652 -5.642 - --5.632 -5.622 -5.612 -5.602 -5.592 -5.581 -5.571 -5.561 -5.550 -5.540 --5.529 -5.519 -5.508 -5.497 -5.487 -5.476 -5.465 -5.454 -5.443 -5.432 --5.421 -5.410 -5.399 -5.388 -5.376 -5.365 -5.354 -5.342 -5.331 -5.319 --5.308 -5.296 -5.285 -5.273 -5.261 -5.249 -5.238 -5.226 -5.214 -5.202 --5.190 -5.178 -5.165 -5.153 -5.141 -5.129 -5.116 -5.104 -5.092 -5.079 - --5.067 -5.054 -5.041 -5.029 -5.016 -5.003 -4.990 -4.978 -4.965 -4.952 --4.939 -4.926 -4.912 -4.899 -4.886 -4.873 -4.860 -4.846 -4.833 -4.819 --4.806 -4.792 -4.779 -4.765 -4.752 -4.738 -4.724 -4.710 -4.697 -4.683 --4.669 -4.655 -4.641 -4.627 -4.613 -4.598 -4.584 -4.570 -4.556 -4.541 --4.527 -4.512 -4.498 -4.484 -4.469 -4.454 -4.440 -4.425 -4.410 -4.396 - --4.381 -4.366 -4.351 -4.336 -4.321 -4.306 -4.291 -4.276 -4.261 -4.245 --4.230 -4.215 -4.200 -4.184 -4.169 -4.153 -4.138 -4.122 -4.107 -4.091 --4.075 -4.060 -4.044 -4.028 -4.012 -3.997 -3.981 -3.965 -3.949 -3.933 --3.917 -3.901 -3.884 -3.868 -3.852 -3.836 -3.819 -3.803 -3.787 -3.770 --3.754 -3.737 -3.721 -3.704 -3.688 -3.671 -3.654 -3.637 -3.621 -3.604 - --3.587 -3.570 -3.553 -3.536 -3.519 -3.502 -3.485 -3.468 -3.451 -3.434 --3.417 -3.399 -3.382 -3.365 -3.347 -3.330 -3.312 -3.295 -3.277 -3.260 --3.242 -3.225 -3.207 -3.189 -3.172 -3.154 -3.136 -3.118 -3.100 -3.082 --3.065 -3.047 -3.029 -3.010 -2.992 -2.974 -2.956 -2.938 -2.920 -2.902 --2.883 -2.865 -2.847 -2.828 -2.810 -2.791 -2.773 -2.754 -2.736 -2.717 - --2.699 -2.680 -2.661 -2.643 -2.624 -2.605 -2.586 -2.567 -2.549 -2.530 --2.511 -2.492 -2.473 -2.454 -2.435 -2.416 -2.397 -2.377 -2.358 -2.339 --2.320 -2.300 -2.281 -2.262 -2.243 -2.223 -2.204 -2.184 -2.165 -2.145 --2.126 -2.106 -2.087 -2.067 -2.047 -2.028 -2.008 -1.988 -1.968 -1.949 --1.929 -1.909 -1.889 -1.869 -1.849 -1.829 -1.809 -1.789 -1.769 -1.749 - --1.729 -1.709 -1.689 -1.669 -1.648 -1.628 -1.608 -1.588 -1.567 -1.547 --1.527 -1.506 -1.486 -1.465 -1.445 -1.424 -1.404 -1.383 -1.363 -1.342 --1.322 -1.301 -1.280 -1.260 -1.239 -1.218 -1.197 -1.177 -1.156 -1.135 --1.114 -1.093 -1.072 -1.051 -1.031 -1.010 -0.989 -0.968 -0.946 -0.925 --0.904 -0.883 -0.862 -0.841 -0.820 -0.799 -0.777 -0.756 -0.735 -0.714 - --0.692 -0.671 -0.650 -0.628 -0.607 -0.585 -0.564 -0.543 -0.521 -0.500 --0.478 -0.457 -0.435 -0.413 -0.392 -0.370 -0.349 -0.327 -0.305 -0.284 --0.262 -0.240 -0.218 -0.197 -0.175 -0.153 -0.131 -0.109 -0.088 -0.066 --0.044 -0.022 0.000 0.022 0.044 0.066 0.088 0.110 0.132 0.154 -0.176 0.198 0.220 0.242 0.264 0.286 0.308 0.331 0.353 0.375 - -0.397 0.419 0.441 0.464 0.486 0.508 0.530 0.553 0.575 0.597 -0.619 0.642 0.664 0.686 0.709 0.731 0.753 0.776 0.798 0.821 -0.843 0.865 0.888 0.910 0.933 0.955 0.978 1.000 1.023 1.045 -1.068 1.090 1.113 1.135 1.158 1.181 1.203 1.226 1.248 1.271 -1.294 1.316 1.339 1.362 1.384 1.407 1.430 1.452 1.475 1.498 - -1.520 1.543 1.566 1.589 1.611 1.634 1.657 1.680 1.703 1.725 -1.748 1.771 1.794 1.817 1.839 1.862 1.885 1.908 1.931 1.954 -1.977 2.000 2.022 2.045 2.068 2.091 2.114 2.137 2.160 2.183 -2.206 2.229 2.252 2.275 2.298 2.321 2.344 2.367 2.390 2.413 -2.436 2.459 2.482 2.505 2.528 2.551 2.574 2.597 2.620 2.643 - -2.666 2.689 2.712 2.735 2.758 2.781 2.804 2.827 2.850 2.873 -2.896 2.920 2.943 2.966 2.989 3.012 3.035 3.058 3.081 3.104 -3.127 3.150 3.173 3.196 3.220 3.243 3.266 3.289 3.312 3.335 -3.358 3.381 3.404 3.427 3.450 3.473 3.496 3.519 3.543 3.566 -3.589 3.612 3.635 3.658 3.681 3.704 3.727 3.750 3.773 3.796 - -3.819 3.842 3.865 3.888 3.911 3.934 3.957 3.980 4.003 4.026 -4.049 4.072 4.095 4.118 4.141 4.164 4.187 4.210 4.233 4.256 -4.279 4.302 4.325 4.348 4.371 4.394 4.417 4.439 4.462 4.485 -4.508 4.531 4.554 4.577 4.600 4.622 4.645 4.668 4.691 4.714 -4.737 4.759 4.782 4.805 4.828 4.851 4.873 4.896 4.919 4.942 - -4.964 4.987 5.010 5.033 5.055 5.078 5.101 5.124 5.146 5.169 -5.192 5.214 5.237 5.260 5.282 5.305 5.327 5.350 5.373 5.395 -5.418 5.440 5.463 5.486 5.508 5.531 5.553 5.576 5.598 5.621 -5.643 5.666 5.688 5.711 5.733 5.756 5.778 5.801 5.823 5.846 -5.868 5.891 5.913 5.936 5.958 5.980 6.003 6.025 6.048 6.070 - -6.092 6.115 6.137 6.160 6.182 6.204 6.227 6.249 6.271 6.294 -6.316 6.338 6.361 6.383 6.405 6.428 6.450 6.472 6.494 6.517 -6.539 6.561 6.583 6.606 6.628 6.650 6.672 6.695 6.717 6.739 -6.761 6.784 6.806 6.828 6.850 6.873 6.895 6.917 6.939 6.961 -6.984 7.006 7.028 7.050 7.072 7.094 7.117 7.139 7.161 7.183 - -7.205 7.228 7.250 7.272 7.294 7.316 7.338 7.361 7.383 7.405 -7.427 7.449 7.471 7.494 7.516 7.538 7.560 7.582 7.604 7.627 -7.649 7.671 7.693 7.715 7.737 7.760 7.782 7.804 7.826 7.848 -7.870 7.893 7.915 7.937 7.959 7.981 8.003 8.026 8.048 8.070 -8.092 8.114 8.137 8.159 8.181 8.203 8.225 8.248 8.270 8.292 - -8.314 8.336 8.359 8.381 8.403 8.425 8.448 8.470 8.492 8.514 -8.537 8.559 8.581 8.603 8.626 8.648 8.670 8.692 8.715 8.737 -8.759 8.782 8.804 8.826 8.849 8.871 8.893 8.916 8.938 8.960 -8.983 9.005 9.027 9.050 9.072 9.094 9.117 9.139 9.161 9.184 -9.206 9.229 9.251 9.273 9.296 9.318 9.341 9.363 9.385 9.408 - -9.430 9.453 9.475 9.498 9.520 9.543 9.565 9.588 9.610 9.633 -9.655 9.678 9.700 9.723 9.745 9.768 9.790 9.813 9.835 9.858 -9.880 9.903 9.926 9.948 9.971 9.993 10.016 10.038 10.061 10.084 -10.106 10.129 10.151 10.174 10.197 10.219 10.242 10.265 10.287 10.310 -10.333 10.355 10.378 10.401 10.423 10.446 10.469 10.491 10.514 10.537 - -10.560 10.582 10.605 10.628 10.650 10.673 10.696 10.719 10.741 10.764 -10.787 10.810 10.833 10.855 10.878 10.901 10.924 10.947 10.969 10.992 -11.015 11.038 11.061 11.083 11.106 11.129 11.152 11.175 11.198 11.221 -11.243 11.266 11.289 11.312 11.335 11.358 11.381 11.404 11.426 11.449 -11.472 11.495 11.518 11.541 11.564 11.587 11.610 11.633 11.656 11.679 - -11.702 11.725 11.748 11.770 11.793 11.816 11.839 11.862 11.885 11.908 -11.931 11.954 11.977 12.000 12.023 12.046 12.069 12.092 12.115 12.138 -12.161 12.184 12.207 12.230 12.254 12.277 12.300 12.323 12.346 12.369 -12.392 12.415 12.438 12.461 12.484 12.507 12.530 12.553 12.576 12.599 -12.623 12.646 12.669 12.692 12.715 12.738 12.761 12.784 12.807 12.831 - -12.854 12.877 12.900 12.923 12.946 12.969 12.992 13.016 13.039 13.062 -13.085 13.108 13.131 13.154 13.178 13.201 13.224 13.247 13.270 13.293 -13.317 13.340 13.363 13.386 13.409 13.433 13.456 13.479 13.502 13.525 -13.549 13.572 13.595 13.618 13.641 13.665 13.688 13.711 13.734 13.757 -13.781 13.804 13.827 13.850 13.874 13.897 13.920 13.943 13.967 13.990 - -14.013 14.036 14.060 14.083 14.106 14.129 14.153 14.176 14.199 14.222 -14.246 14.269 14.292 14.316 14.339 14.362 14.385 14.409 14.432 14.455 -14.479 14.502 14.525 14.548 14.572 14.595 14.618 14.642 14.665 14.688 -14.712 14.735 14.758 14.782 14.805 14.828 14.852 14.875 14.898 14.922 -14.945 14.968 14.992 15.015 15.038 15.062 15.085 15.108 15.132 15.155 - -15.178 15.202 15.225 15.248 15.272 15.295 15.318 15.342 15.365 15.389 -15.412 15.435 15.459 15.482 15.505 15.529 15.552 15.576 15.599 15.622 -15.646 15.669 15.693 15.716 15.739 15.763 15.786 15.810 15.833 15.856 -15.880 15.903 15.927 15.950 15.974 15.997 16.020 16.044 16.067 16.091 -16.114 16.138 16.161 16.184 16.208 16.231 16.255 16.278 16.302 16.325 - -16.349 16.372 16.395 16.419 16.442 16.466 16.489 16.513 16.536 16.560 -16.583 16.607 16.630 16.654 16.677 16.700 16.724 16.747 16.771 16.794 -16.818 16.841 16.865 16.888 16.912 16.935 16.959 16.982 17.006 17.029 -17.053 17.076 17.100 17.123 17.147 17.170 17.194 17.217 17.241 17.264 -17.288 17.311 17.335 17.358 17.382 17.406 17.429 17.453 17.476 17.500 - -17.523 17.547 17.570 17.594 17.617 17.641 17.664 17.688 17.711 17.735 -17.759 17.782 17.806 17.829 17.853 17.876 17.900 17.923 17.947 17.971 -17.994 18.018 18.041 18.065 18.088 18.112 18.136 18.159 18.183 18.206 -18.230 18.253 18.277 18.301 18.324 18.348 18.371 18.395 18.418 18.442 -18.466 18.489 18.513 18.536 18.560 18.584 18.607 18.631 18.654 18.678 - -18.702 18.725 18.749 18.772 18.796 18.820 18.843 18.867 18.890 18.914 -18.938 18.961 18.985 19.008 19.032 19.056 19.079 19.103 19.127 19.150 -19.174 19.197 19.221 19.245 19.268 19.292 19.316 19.339 19.363 19.386 -19.410 19.434 19.457 19.481 19.505 19.528 19.552 19.576 19.599 19.623 -19.646 19.670 19.694 19.717 19.741 19.765 19.788 19.812 19.836 19.859 - -19.883 19.907 19.930 19.954 19.978 20.001 20.025 20.049 20.072 20.096 -20.120 20.143 20.167 20.190 20.214 20.238 20.261 20.285 20.309 20.332 -20.356 20.380 20.403 20.427 20.451 20.474 20.498 20.522 20.545 20.569 -20.593 20.616 20.640 20.664 20.688 20.711 20.735 20.759 20.782 20.806 -20.830 20.853 20.877 20.901 20.924 20.948 20.972 20.995 21.019 21.043 - -21.066 21.090 21.114 21.137 21.161 21.185 21.208 21.232 21.256 21.280 -21.303 21.327 21.351 21.374 21.398 21.422 21.445 21.469 21.493 21.516 -21.540 21.564 21.587 21.611 21.635 21.659 21.682 21.706 21.730 21.753 -21.777 21.801 21.824 21.848 21.872 21.895 21.919 21.943 21.966 21.990 -22.014 22.038 22.061 22.085 22.109 22.132 22.156 22.180 22.203 22.227 - -22.251 22.274 22.298 22.322 22.346 22.369 22.393 22.417 22.440 22.464 -22.488 22.511 22.535 22.559 22.582 22.606 22.630 22.654 22.677 22.701 -22.725 22.748 22.772 22.796 22.819 22.843 22.867 22.890 22.914 22.938 -22.961 22.985 23.009 23.032 23.056 23.080 23.104 23.127 23.151 23.175 -23.198 23.222 23.246 23.269 23.293 23.317 23.340 23.364 23.388 23.411 - -23.435 23.459 23.482 23.506 23.530 23.553 23.577 23.601 23.624 23.648 -23.672 23.695 23.719 23.743 23.766 23.790 23.814 23.837 23.861 23.885 -23.908 23.932 23.956 23.979 24.003 24.027 24.050 24.074 24.098 24.121 -24.145 24.169 24.192 24.216 24.240 24.263 24.287 24.311 24.334 24.358 -24.382 24.405 24.429 24.453 24.476 24.500 24.523 24.547 24.571 24.594 - -24.618 24.642 24.665 24.689 24.713 24.736 24.760 24.783 24.807 24.831 -24.854 24.878 24.902 24.925 24.949 24.972 24.996 25.020 25.043 25.067 -25.091 25.114 25.138 25.161 25.185 25.209 25.232 25.256 25.279 25.303 -25.327 25.350 25.374 25.397 25.421 25.445 25.468 25.492 25.515 25.539 -25.563 25.586 25.610 25.633 25.657 25.681 25.704 25.728 25.751 25.775 - -25.799 25.822 25.846 25.869 25.893 25.916 25.940 25.964 25.987 26.011 -26.034 26.058 26.081 26.105 26.128 26.152 26.176 26.199 26.223 26.246 -26.270 26.293 26.317 26.340 26.364 26.387 26.411 26.435 26.458 26.482 -26.505 26.529 26.552 26.576 26.599 26.623 26.646 26.670 26.693 26.717 -26.740 26.764 26.787 26.811 26.834 26.858 26.881 26.905 26.928 26.952 - -26.975 26.999 27.022 27.046 27.069 27.093 27.116 27.140 27.163 27.187 -27.210 27.234 27.257 27.281 27.304 27.328 27.351 27.375 27.398 27.422 -27.445 27.468 27.492 27.515 27.539 27.562 27.586 27.609 27.633 27.656 -27.679 27.703 27.726 27.750 27.773 27.797 27.820 27.843 27.867 27.890 -27.914 27.937 27.961 27.984 28.007 28.031 28.054 28.078 28.101 28.124 - -28.148 28.171 28.195 28.218 28.241 28.265 28.288 28.311 28.335 28.358 -28.382 28.405 28.428 28.452 28.475 28.498 28.522 28.545 28.569 28.592 -28.615 28.639 28.662 28.685 28.709 28.732 28.755 28.779 28.802 28.825 -28.849 28.872 28.895 28.919 28.942 28.965 28.988 29.012 29.035 29.058 -29.082 29.105 29.128 29.152 29.175 29.198 29.221 29.245 29.268 29.291 - -29.315 29.338 29.361 29.384 29.408 29.431 29.454 29.477 29.501 29.524 -29.547 29.570 29.594 29.617 29.640 29.663 29.687 29.710 29.733 29.756 -29.780 29.803 29.826 29.849 29.872 29.896 29.919 29.942 29.965 29.989 -30.012 30.035 30.058 30.081 30.104 30.128 30.151 30.174 30.197 30.220 -30.244 30.267 30.290 30.313 30.336 30.359 30.383 30.406 30.429 30.452 - -30.475 30.498 30.521 30.545 30.568 30.591 30.614 30.637 30.660 30.683 -30.706 30.730 30.753 30.776 30.799 30.822 30.845 30.868 30.891 30.914 -30.937 30.961 30.984 31.007 31.030 31.053 31.076 31.099 31.122 31.145 -31.168 31.191 31.214 31.237 31.260 31.283 31.306 31.329 31.353 31.376 -31.399 31.422 31.445 31.468 31.491 31.514 31.537 31.560 31.583 31.606 - -31.629 31.652 31.675 31.698 31.721 31.744 31.767 31.790 31.813 31.836 -31.859 31.882 31.905 31.927 31.950 31.973 31.996 32.019 32.042 32.065 -32.088 32.111 32.134 32.157 32.180 32.203 32.226 32.249 32.272 32.294 -32.317 32.340 32.363 32.386 32.409 32.432 32.455 32.478 32.501 32.523 -32.546 32.569 32.592 32.615 32.638 32.661 32.683 32.706 32.729 32.752 - -32.775 32.798 32.821 32.843 32.866 32.889 32.912 32.935 32.958 32.980 -33.003 33.026 33.049 33.072 33.094 33.117 33.140 33.163 33.186 33.208 -33.231 33.254 33.277 33.300 33.322 33.345 33.368 33.391 33.413 33.436 -33.459 33.482 33.504 33.527 33.550 33.573 33.595 33.618 33.641 33.664 -33.686 33.709 33.732 33.754 33.777 33.800 33.823 33.845 33.868 33.891 - -33.913 33.936 33.959 33.981 34.004 34.027 34.049 34.072 34.095 34.117 -34.140 34.163 34.185 34.208 34.231 34.253 34.276 34.299 34.321 34.344 -34.366 34.389 34.412 34.434 34.457 34.480 34.502 34.525 34.547 34.570 -34.593 34.615 34.638 34.660 34.683 34.705 34.728 34.751 34.773 34.796 -34.818 34.841 34.863 34.886 34.909 34.931 34.954 34.976 34.999 35.021 - -35.044 35.066 35.089 35.111 35.134 35.156 35.179 35.201 35.224 35.246 -35.269 35.291 35.314 35.336 35.359 35.381 35.404 35.426 35.449 35.471 -35.494 35.516 35.539 35.561 35.583 35.606 35.628 35.651 35.673 35.696 -35.718 35.741 35.763 35.785 35.808 35.830 35.853 35.875 35.897 35.920 -35.942 35.965 35.987 36.009 36.032 36.054 36.077 36.099 36.121 36.144 - -36.166 36.188 36.211 36.233 36.256 36.278 36.300 36.323 36.345 36.367 -36.390 36.412 36.434 36.457 36.479 36.501 36.524 36.546 36.568 36.590 -36.613 36.635 36.657 36.680 36.702 36.724 36.746 36.769 36.791 36.813 -36.836 36.858 36.880 36.902 36.925 36.947 36.969 36.991 37.014 37.036 -37.058 37.080 37.103 37.125 37.147 37.169 37.191 37.214 37.236 37.258 - -37.280 37.303 37.325 37.347 37.369 37.391 37.413 37.436 37.458 37.480 -37.502 37.524 37.547 37.569 37.591 37.613 37.635 37.657 37.679 37.702 -37.724 37.746 37.768 37.790 37.812 37.834 37.857 37.879 37.901 37.923 -37.945 37.967 37.989 38.011 38.033 38.055 38.078 38.100 38.122 38.144 -38.166 38.188 38.210 38.232 38.254 38.276 38.298 38.320 38.342 38.364 - -38.387 38.409 38.431 38.453 38.475 38.497 38.519 38.541 38.563 38.585 -38.607 38.629 38.651 38.673 38.695 38.717 38.739 38.761 38.783 38.805 -38.827 38.849 38.871 38.893 38.915 38.937 38.959 38.981 39.003 39.024 -39.046 39.068 39.090 39.112 39.134 39.156 39.178 39.200 39.222 39.244 -39.266 39.288 39.310 39.331 39.353 39.375 39.397 39.419 39.441 39.463 - -39.485 39.507 39.529 39.550 39.572 39.594 39.616 39.638 39.660 39.682 -39.703 39.725 39.747 39.769 39.791 39.813 39.835 39.856 39.878 39.900 -39.922 39.944 39.965 39.987 40.009 40.031 40.053 40.075 40.096 40.118 -40.140 40.162 40.183 40.205 40.227 40.249 40.271 40.292 40.314 40.336 -40.358 40.379 40.401 40.423 40.445 40.466 40.488 40.510 40.532 40.553 - -40.575 40.597 40.619 40.640 40.662 40.684 40.705 40.727 40.749 40.770 -40.792 40.814 40.836 40.857 40.879 40.901 40.922 40.944 40.966 40.987 -41.009 41.031 41.052 41.074 41.096 41.117 41.139 41.161 41.182 41.204 -41.225 41.247 41.269 41.290 41.312 41.334 41.355 41.377 41.398 41.420 -41.442 41.463 41.485 41.506 41.528 41.550 41.571 41.593 41.614 41.636 - -41.657 41.679 41.701 41.722 41.744 41.765 41.787 41.808 41.830 41.851 -41.873 41.895 41.916 41.938 41.959 41.981 42.002 42.024 42.045 42.067 -42.088 42.110 42.131 42.153 42.174 42.196 42.217 42.239 42.260 42.282 -42.303 42.325 42.346 42.367 42.389 42.410 42.432 42.453 42.475 42.496 -42.518 42.539 42.560 42.582 42.603 42.625 42.646 42.668 42.689 42.710 - -42.732 42.753 42.775 42.796 42.817 42.839 42.860 42.882 42.903 42.924 -42.946 42.967 42.989 43.010 43.031 43.053 43.074 43.095 43.117 43.138 -43.159 43.181 43.202 43.223 43.245 43.266 43.287 43.309 43.330 43.351 -43.373 43.394 43.415 43.436 43.458 43.479 43.500 43.522 43.543 43.564 -43.585 43.607 43.628 43.649 43.671 43.692 43.713 43.734 43.756 43.777 - -43.798 43.819 43.841 43.862 43.883 43.904 43.925 43.947 43.968 43.989 -44.010 44.031 44.053 44.074 44.095 44.116 44.137 44.159 44.180 44.201 -44.222 44.243 44.265 44.286 44.307 44.328 44.349 44.370 44.391 44.413 -44.434 44.455 44.476 44.497 44.518 44.539 44.560 44.582 44.603 44.624 -44.645 44.666 44.687 44.708 44.729 44.750 44.771 44.793 44.814 44.835 - -44.856 44.877 44.898 44.919 44.940 44.961 44.982 45.003 45.024 45.045 -45.066 45.087 45.108 45.129 45.150 45.171 45.192 45.213 45.234 45.255 -45.276 45.297 45.318 45.339 45.360 45.381 45.402 45.423 45.444 45.465 -45.486 45.507 45.528 45.549 45.570 45.591 45.612 45.633 45.654 45.675 -45.695 45.716 45.737 45.758 45.779 45.800 45.821 45.842 45.863 45.884 - -45.904 45.925 45.946 45.967 45.988 46.009 46.030 46.051 46.071 46.092 -46.113 46.134 46.155 46.176 46.196 46.217 46.238 46.259 46.280 46.300 -46.321 46.342 46.363 46.384 46.404 46.425 46.446 46.467 46.488 46.508 -46.529 46.550 46.571 46.591 46.612 46.633 46.654 46.674 46.695 46.716 -46.737 46.757 46.778 46.799 46.819 46.840 46.861 46.881 46.902 46.923 - -46.944 46.964 46.985 47.006 47.026 47.047 47.068 47.088 47.109 47.130 -47.150 47.171 47.191 47.212 47.233 47.253 47.274 47.295 47.315 47.336 -47.356 47.377 47.398 47.418 47.439 47.459 47.480 47.500 47.521 47.542 -47.562 47.583 47.603 47.624 47.644 47.665 47.685 47.706 47.726 47.747 -47.767 47.788 47.808 47.829 47.849 47.870 47.890 47.911 47.931 47.952 - -47.972 47.993 48.013 48.034 48.054 48.075 48.095 48.116 48.136 48.156 -48.177 48.197 48.218 48.238 48.258 48.279 48.299 48.320 48.340 48.360 -48.381 48.401 48.422 48.442 48.462 48.483 48.503 48.523 48.544 48.564 -48.584 48.605 48.625 48.645 48.666 48.686 48.706 48.727 48.747 48.767 -48.787 48.808 48.828 48.848 48.869 48.889 48.909 48.929 48.950 48.970 - -48.990 49.010 49.031 49.051 49.071 49.091 49.111 49.132 49.152 49.172 -49.192 49.212 49.233 49.253 49.273 49.293 49.313 49.333 49.354 49.374 -49.394 49.414 49.434 49.454 49.474 49.495 49.515 49.535 49.555 49.575 -49.595 49.615 49.635 49.655 49.675 49.696 49.716 49.736 49.756 49.776 -49.796 49.816 49.836 49.856 49.876 49.896 49.916 49.936 49.956 49.976 - -49.996 50.016 50.036 50.056 50.076 50.096 50.116 50.136 50.156 50.176 -50.196 50.216 50.236 50.256 50.276 50.296 50.315 50.335 50.355 50.375 -50.395 50.415 50.435 50.455 50.475 50.494 50.514 50.534 50.554 50.574 -50.594 50.614 50.633 50.653 50.673 50.693 50.713 50.733 50.752 50.772 -50.792 50.812 50.832 50.851 50.871 50.891 50.911 50.930 50.950 50.970 - -50.990 51.009 51.029 51.049 51.069 51.088 51.108 51.128 51.148 51.167 -51.187 51.207 51.226 51.246 51.266 51.285 51.305 51.325 51.344 51.364 -51.384 51.403 51.423 51.443 51.462 51.482 51.501 51.521 51.541 51.560 -51.580 51.599 51.619 51.639 51.658 51.678 51.697 51.717 51.736 51.756 -51.776 51.795 51.815 51.834 51.854 51.873 51.893 51.912 51.932 51.951 - -51.971 51.990 52.010 52.029 52.049 52.068 52.088 52.107 52.127 52.146 -52.165 52.185 52.204 52.224 52.243 52.263 52.282 52.301 52.321 52.340 -52.360 52.379 52.398 52.418 52.437 52.457 52.476 52.495 52.515 52.534 -52.553 52.573 52.592 52.611 52.631 52.650 52.669 52.689 52.708 52.727 -52.747 52.766 52.785 52.805 52.824 52.843 52.862 52.882 52.901 52.920 - -52.939 52.959 52.978 52.997 53.016 53.036 53.055 53.074 53.093 53.113 -53.132 53.151 53.170 53.189 53.209 53.228 53.247 53.266 53.285 53.304 -53.324 53.343 53.362 53.381 53.400 53.419 53.439 53.458 53.477 53.496 -53.515 53.534 53.553 53.572 53.592 53.611 53.630 53.649 53.668 53.687 -53.706 53.725 53.744 53.763 53.782 53.801 53.821 53.840 53.859 53.878 - -53.897 53.916 53.935 53.954 53.973 53.992 54.011 54.030 54.049 54.068 -54.087 54.106 54.125 54.144 54.163 54.182 54.201 54.220 54.239 54.258 -54.277 54.296 54.315 54.334 54.353 54.372 54.391 54.410 54.429 54.447 -54.466 54.485 54.504 54.523 54.542 54.561 54.580 54.599 54.618 54.637 -54.656 54.675 54.694 54.712 54.731 54.750 54.769 54.788 54.807 54.826 - -54.845 diff --git a/src/ioc/bpt/cvtTable.h b/src/ioc/bpt/cvtTable.h deleted file mode 100644 index 374666450..000000000 --- a/src/ioc/bpt/cvtTable.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Breakpoint Tables - * - * Author: Marty Kraimer - * Date: 11-7-90 - */ - -#ifndef INCcvtTableh -#define INCcvtTableh 1 - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Global Routines*/ -epicsShareFunc long cvtEngToRawBpt( - double *pval,short linr,short init,void **ppbrk,short *plbrk); - -epicsShareFunc long cvtRawToEngBpt( - double *pval,short linr,short init,void **ppbrk, short *plbrk); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/ioc/bpt/makeBpt.c b/src/ioc/bpt/makeBpt.c deleted file mode 100644 index 93095f1c2..000000000 --- a/src/ioc/bpt/makeBpt.c +++ /dev/null @@ -1,427 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Marty Kraimer - * Date: 9/28/95 - * Replacement for old bldCvtTable - */ - -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "ellLib.h" -#include "cvtTable.h" - -#define MAX_LINE_SIZE 160 -#define MAX_BREAKS 100 -struct brkCreateInfo { - double engLow; /* Lowest value desired: engineering units */ - double engHigh; /* Highest value desired: engineering units */ - double rawLow; /* Raw value for EngLow */ - double rawHigh; /* Raw value for EngHigh */ - double accuracy; /* accuracy desired in engineering units */ - double tblEngFirst;/* First table value: engineering units */ - double tblEngLast; /* Last table value: engineering units */ - double tblEngDelta;/* Change per table entry: eng units */ - long nTable; /* number of table entries */ - /* (last-first)/delta + 1 */ - double *pTable; /* addr of data table */ -} brkCreateInfo; - -typedef struct brkInt { /* breakpoint interval */ - double raw; /* raw value for beginning of interval */ - double slope; /* slope for interval */ - double eng; /* converted value for beginning of interval */ -} brkInt; - -brkInt brkint[MAX_BREAKS]; - -static int create_break(struct brkCreateInfo *pbci, brkInt *pabrkInt, - int max_breaks, int *n_breaks); -static char inbuf[MAX_LINE_SIZE]; -static int linenum=0; - -typedef struct dataList{ - struct dataList *next; - double value; -}dataList; - -static int getNumber(char **pbeg, double *value) -{ - int nchars=0; - - while(isspace((int)**pbeg) && **pbeg!= '\0') (*pbeg)++; - if(**pbeg == '!' || **pbeg == '\0') return(-1); - if(sscanf(*pbeg,"%lf%n",value,&nchars)!=1) return(-1); - *pbeg += nchars; - return(0); -} - -static void errExit(char *pmessage) -{ - fprintf(stderr, "%s\n", pmessage); - fflush(stderr); - exit(-1); -} - -int main(int argc, char **argv) -{ - char *pbeg; - char *pend; - double value; - char *pname = NULL; - dataList *phead; - dataList *pdataList; - dataList *pnext; - double *pdata; - long ndata; - int nBreak,n; - size_t len; - char *outFilename; - char *pext; - FILE *outFile; - FILE *inFile; - char *plastSlash; - - - if(argc<2) { - fprintf(stderr,"usage: makeBpt file.data [outfile]\n"); - exit(-1); - } - if (argc==2) { - plastSlash = strrchr(argv[1],'/'); - plastSlash = (plastSlash ? plastSlash+1 : argv[1]); - outFilename = calloc(1,strlen(plastSlash)+2); - if(!outFilename) { - fprintf(stderr,"calloc failed\n"); - exit(-1); - } - strcpy(outFilename,plastSlash); - pext = strstr(outFilename,".data"); - if(!pext) { - fprintf(stderr,"Input file MUST have .data extension\n"); - exit(-1); - } - strcpy(pext,".dbd"); - } else { - outFilename = calloc(1,strlen(argv[2])+1); - if(!outFilename) { - fprintf(stderr,"calloc failed\n"); - exit(-1); - } - strcpy(outFilename,argv[2]); - } - inFile = fopen(argv[1],"r"); - if(!inFile) { - fprintf(stderr,"Error opening %s\n",argv[1]); - exit(-1); - } - outFile = fopen(outFilename,"w"); - if(!outFile) { - fprintf(stderr,"Error opening %s\n",outFilename); - exit(-1); - } - while(fgets(inbuf,MAX_LINE_SIZE,inFile)) { - linenum++; - pbeg = inbuf; - while(isspace((int)*pbeg) && *pbeg!= '\0') pbeg++; - if(*pbeg == '!' || *pbeg == '\0') continue; - while(*pbeg!='"' && *pbeg!= '\0') pbeg++; - if(*pbeg!='"' ) errExit("Illegal Header"); - pbeg++; pend = pbeg; - while(*pend!='"' && *pend!= '\0') pend++; - if(*pend!='"') errExit("Illegal Header"); - len = pend - pbeg; - if(len<=1) errExit("Illegal Header"); - pname = calloc(len+1,sizeof(char)); - if(!pname) { - fprintf(stderr,"calloc failed while processing line %d\n",linenum); - exit(-1); - } - strncpy(pname,pbeg,len); - pname[len]='\0'; - pbeg = pend + 1; - if(getNumber(&pbeg,&value)) errExit("Illegal Header"); - brkCreateInfo.engLow = value; - if(getNumber(&pbeg,&value)) errExit("Illegal Header"); - brkCreateInfo.rawLow = value; - if(getNumber(&pbeg,&value)) errExit("Illegal Header"); - brkCreateInfo.engHigh = value; - if(getNumber(&pbeg,&value)) errExit("Illegal Header"); - brkCreateInfo.rawHigh = value; - if(getNumber(&pbeg,&value)) errExit("Illegal Header"); - brkCreateInfo.accuracy = value; - if(getNumber(&pbeg,&value)) errExit("Illegal Header"); - brkCreateInfo.tblEngFirst = value; - if(getNumber(&pbeg,&value)) errExit("Illegal Header"); - brkCreateInfo.tblEngLast = value; - if(getNumber(&pbeg,&value)) errExit("Illegal Header"); - brkCreateInfo.tblEngDelta = value; - goto got_header; - } - errExit("Illegal Header"); -got_header: - phead = pnext = 0; - ndata = 0; - errno = 0; - while(fgets(inbuf,MAX_LINE_SIZE,inFile)) { - double value; - - linenum++; - pbeg = inbuf; - while(!getNumber(&pbeg,&value)) { - ndata++; - pdataList = (dataList *)calloc(1,sizeof(dataList)); - if(!pdataList) { - fprintf(stderr,"calloc failed (after header)" - " while processing line %d\n",linenum); - exit(-1); - } - if(!phead) - phead = pdataList; - else - pnext->next = pdataList; - pdataList->value = value; - pnext = pdataList; - } - } - if(!pname) { - errExit("create_break failed: no name specified\n"); - } - brkCreateInfo.nTable = ndata; - pdata = (double *)calloc(brkCreateInfo.nTable,sizeof(double)); - if(!pdata) { - fprintf(stderr,"calloc failed for table length %ld\n",brkCreateInfo.nTable); - exit(-1); - } - pnext = phead; - for(n=0; nvalue; - pdataList = pnext; - pnext = pnext->next; - free((void *)pdataList); - } - brkCreateInfo.pTable = pdata; - if(create_break(&brkCreateInfo,&brkint[0],MAX_BREAKS,&nBreak)) - errExit("create_break failed\n"); - fprintf(outFile,"breaktable(%s) {\n",pname); - for(n=0; npTable; - long ntable = pbci->nTable; - double ilow, - ihigh, - tbllow, - tblhigh, - slope, - offset; - int ibeg, - iend, - i, - inc, - imax, - n; - double rawBeg, - engBeg, - rawEnd, - engEnd, - engCalc, - engActual, - error; - int valid, - all_ok, - expanding; - /* make checks to ensure that brkCreateInfo makes sense */ - if (pbci->engLow >= pbci->engHigh) { - errExit("create_break: engLow >= engHigh"); - return (-1); - } - if ((pbci->engLow < pbci->tblEngFirst) - || (pbci->engHigh > pbci->tblEngLast)) { - errExit("create_break: engLow > engHigh"); - return (-1); - } - if (pbci->tblEngDelta <= 0.0) { - errExit("create_break: tblEngDelta <= 0.0"); - return (-1); - } - if (ntable < 3) { - errExit("raw data must have at least 3 elements"); - return (-1); - } -/*************************************************************************** - Convert Table to raw values - * - * raw and table values are assumed to be related by an equation of the form: - * - * raw = slope*table + offset - * - * The following algorithm converts each table value to raw units - * - * 1) Finds the locations in Table corresponding to engLow and engHigh - * Note that these locations need not be exact integers - * 2) Interpolates to obtain table values corresponding to engLow and enghigh - * we now have the equations: - * rawLow = slope*tblLow + offset - * rawHigh = slope*tblHigh + offset - * 4) Solving these equations for slope and offset gives: - * slope=(rawHigh-rawLow)/(tblHigh-tblLow) - * offset=rawHigh-slope*tblHigh - * 5) for each table value set table[i]=table[i]*slope+offset - *************************************************************************/ - /* Find engLow in Table and then compute tblLow */ - ilow = (pbci->engLow - pbci->tblEngFirst) / (pbci->tblEngDelta); - i = (int) ilow; - if (i >= ntable - 1) - i = ntable - 2; - tbllow = table[i] + (table[i + 1] - table[i]) * (ilow - (double) i); - /* Find engHigh in Table and then compute tblHigh */ - ihigh = (pbci->engHigh - pbci->tblEngFirst) / (pbci->tblEngDelta); - i = (int) ihigh; - if (i >= ntable - 1) - i = ntable - 2; - tblhigh = table[i] + (table[i + 1] - table[i]) * (ihigh - (double) i); - /* compute slope and offset */ - slope = (pbci->rawHigh - pbci->rawLow) / (tblhigh - tbllow); - offset = pbci->rawHigh - slope * tblhigh; - /* convert table to raw units */ - for (i = 0; i < ntable; i++) - table[i] = table[i] * slope + offset; - -/***************************************************************************** - * Now create break point table - * - * The algorithm does the following: - * - * It finds one breakpoint interval at a time. For each it does the following: - * - * 1) Use a relatively large portion of the remaining table as an interval - * 2) It attempts to use the entire interval as a breakpoint interval - * Success is determined by the following algorithm: - * a) compute the slope using the entire interval - * b) for each table entry in the interval determine the eng value - * using the slope just determined. - * c) compare the computed value with eng value associated with table - * d) if all table entries are within the accuracy desired then success. - * 3) If successful then attempt to expand the interval and try again. - * Note that it is expanded by up to 1/10 of the table size. - * 4) If not successful reduce the interval by 1 and try again. - * Once the interval is being decreased it will never be increased again. - * 5) The algorithm will ultimately fail or will have determined the optimum - * breakpoint interval - *************************************************************************/ - - /* Must start with table entry corresponding to engLow; */ - i = (int) ilow; - if (i >= ntable - 1) - i = ntable - 2; - rawBeg = table[i] + (table[i + 1] - table[i]) * (ilow - (double) i); - engBeg = pbci->engLow; - ibeg = (int) (ilow); /* Make sure that ibeg > ilow */ - if( ibeg < ilow ) ibeg = ibeg + 1; - /* start first breakpoint interval */ - n = 1; - pbrkInt = pabrkInt; - pbrkInt->raw = rawBeg; - pbrkInt->eng = engBeg; - /* determine next breakpoint interval */ - while ((engBeg <= pbci->engHigh) && (ibeg < ntable - 1)) { - /* determine next interval to try. Up to 1/10 full range */ - rawEnd = rawBeg; - engEnd = engBeg; - iend = ibeg; - inc = (int) ((ihigh - ilow) / 10.0); - if (inc < 1) - inc = 1; - valid = TRUE; - /* keep trying intervals until cant do better */ - expanding = TRUE; /* originally we are trying larger and larger - * intervals */ - while (valid) { - imax = iend + inc; - if (imax >= ntable) { - /* don't go past end of table */ - imax = ntable - 1; - inc = ntable - iend - 1; - expanding = FALSE; - } - if (imax > (int) (ihigh + 1.0)) { /* Don't go to far past - * engHigh */ - imax = (int) (ihigh + 1.0); - inc = (int) (ihigh + 1.0) - iend; - expanding = FALSE; - } - if (imax <= ibeg) - break; /* failure */ - rawEnd = table[imax]; - engEnd = pbci->tblEngFirst + (double) imax *(pbci->tblEngDelta); - slope = (engEnd - engBeg) / (rawEnd - rawBeg); - all_ok = TRUE; - for (i = ibeg + 1; i <= imax; i++) { - engCalc = engBeg + slope * (table[i] - rawBeg); - engActual = pbci->tblEngFirst + ((double) i) * (pbci->tblEngDelta); - error = engCalc - engActual; - if (error < 0.0) - error = -error; - if (error >= pbci->accuracy) { - /* we will be trying smaller intervals */ - expanding = FALSE; - /* just decrease inc and let while(valid) try again */ - inc--; - all_ok = FALSE; - break; - } - } /* end for */ - if (all_ok) { - iend = imax; - /* if not expanding we found interval */ - if (!expanding) - break; - /* will automatically try larger interval */ - } - } /* end while(valid) */ - /* either we failed or optimal interval has been found */ - if ((iend <= ibeg) && (iend < (int) ihigh)) { - errExit("Could not meet accuracy criteria"); - return (-1); - } - pbrkInt->slope = slope; - /* get ready for next breakpoint interval */ - if (n++ >= max_breaks) { - errExit("Break point table too large"); - return (-1); - } - ibeg = iend; - pbrkInt++; - rawBeg = rawEnd; - engBeg = engEnd; - pbrkInt->raw = rawBeg; - pbrkInt->eng = engBeg + (pbrkInt->raw - rawBeg) * slope; - } - pbrkInt->slope = 0.0; - *n_breaks = n; - return (0); -} diff --git a/src/ioc/bpt/menuConvert.dbd.pod b/src/ioc/bpt/menuConvert.dbd.pod deleted file mode 100644 index e81d4e6f2..000000000 --- a/src/ioc/bpt/menuConvert.dbd.pod +++ /dev/null @@ -1,38 +0,0 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=head1 Menu menuConvert - -This menu defines the standard analog conversions which are included with Base. -IOC applications may add choices or replace the later choices in this menu, -although the first three choices must not be renamed or moved to different -positions. The breakpoint table name must exactly match the choice string -listed here. - -=menu menuConvert - -=cut - -menu(menuConvert) { - choice(menuConvertNO_CONVERSION,"NO CONVERSION") - choice(menuConvertSLOPE,"SLOPE") - choice(menuConvertLINEAR,"LINEAR") - choice(menuConverttypeKdegF,"typeKdegF") - choice(menuConverttypeKdegC,"typeKdegC") - choice(menuConverttypeJdegF,"typeJdegF") - choice(menuConverttypeJdegC,"typeJdegC") - choice(menuConverttypeEdegF,"typeEdegF(ixe only)") - choice(menuConverttypeEdegC,"typeEdegC(ixe only)") - choice(menuConverttypeTdegF,"typeTdegF") - choice(menuConverttypeTdegC,"typeTdegC") - choice(menuConverttypeRdegF,"typeRdegF") - choice(menuConverttypeRdegC,"typeRdegC") - choice(menuConverttypeSdegF,"typeSdegF") - choice(menuConverttypeSdegC,"typeSdegC") -} diff --git a/src/ioc/db/Makefile b/src/ioc/db/Makefile deleted file mode 100644 index d28119ff7..000000000 --- a/src/ioc/db/Makefile +++ /dev/null @@ -1,101 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(IOCDIR)/db - -INC += callback.h -INC += dbAccess.h -INC += dbAccessDefs.h -INC += dbAddr.h -INC += dbBkpt.h -INC += dbCa.h -INC += dbChannel.h -INC += dbConstLink.h -INC += dbConvert.h -INC += dbConvertFast.h -INC += dbConvertJSON.h -INC += dbDbLink.h -INC += dbExtractArray.h -INC += dbEvent.h -INC += dbJLink.h -INC += dbLink.h -INC += dbLock.h -INC += dbNotify.h -INC += dbScan.h -INC += dbServer.h -INC += dbTest.h -INC += dbCaTest.h -INC += db_test.h -INC += db_field_log.h -INC += initHooks.h -INC += recGbl.h -INC += dbIocRegister.h -INC += chfPlugin.h -INC += dbState.h -INC += db_access_routines.h -INC += db_convert.h -INC += dbUnitTest.h - -# Generate menuGlobal.dbd, not really by concatenation, see RULES -DBDCAT += menuGlobal.dbd -menuGlobal_DBD += menuAlarmSevr.dbd -menuGlobal_DBD += menuAlarmStat.dbd -menuGlobal_DBD += menuFtype.dbd -menuGlobal_DBD += menuIvoa.dbd -menuGlobal_DBD += menuOmsl.dbd -menuGlobal_DBD += menuPini.dbd -menuGlobal_DBD += menuPost.dbd -menuGlobal_DBD += menuPriority.dbd -menuGlobal_DBD += menuYesNo.dbd -menuGlobal_DBD += menuSimm.dbd - -DBDINC += $(basename $(menuGlobal_DBD)) -DBDINC += menuScan -DBDINC += dbCommon - -dbMenusPod = $(notdir $(wildcard ../db/menu*.dbd.pod)) -HTMLS += $(patsubst %.dbd.pod,%.html,$(menusPod)) - -dbCore_SRCS += dbLock.c -dbCore_SRCS += dbAccess.c -dbCore_SRCS += dbBkpt.c -dbCore_SRCS += dbChannel.c -dbCore_SRCS += dbConstLink.c -dbCore_SRCS += dbConvert.c -dbCore_SRCS += dbConvertJSON.c -dbCore_SRCS += dbDbLink.c -dbCore_SRCS += dbFastLinkConv.c -dbCore_SRCS += dbExtractArray.c -dbCore_SRCS += dbJLink.c -dbCore_SRCS += dbLink.c -dbCore_SRCS += dbNotify.c -dbCore_SRCS += dbScan.c -dbCore_SRCS += dbEvent.c -dbCore_SRCS += dbTest.c -dbCore_SRCS += db_access.c -dbCore_SRCS += db_test.c -dbCore_SRCS += recGbl.c -dbCore_SRCS += callback.c -dbCore_SRCS += dbCa.c -dbCore_SRCS += dbCaTest.c -dbCore_SRCS += initHooks.c -dbCore_SRCS += cvtBpt.c -dbCore_SRCS += dbContext.cpp -dbCore_SRCS += dbChannelIO.cpp -dbCore_SRCS += dbSubscriptionIO.cpp -dbCore_SRCS += dbPutNotifyBlocker.cpp -dbCore_SRCS += dbContextReadNotifyCache.cpp -dbCore_SRCS += dbIocRegister.c -dbCore_SRCS += chfPlugin.c -dbCore_SRCS += dbState.c -dbCore_SRCS += dbUnitTest.c -dbCore_SRCS += dbServer.c - diff --git a/src/ioc/db/RULES b/src/ioc/db/RULES deleted file mode 100644 index 41b07f5af..000000000 --- a/src/ioc/db/RULES +++ /dev/null @@ -1,27 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2010 Brookhaven Science Associates, as Operator of -# Brookhaven National Lab. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -dbCommon.h$(DEP): $(IOCDIR)/db/dbCommonRecord.dbd $(IOCDIR)/db/RULES - @$(RM) $@ - @$(DBTORECORDTYPEH) -D -I ../db -o $(COMMONDEP_TARGET) $< > $@ - -$(COMMON_DIR)/dbCommon.h: $(IOCDIR)/db/dbCommonRecord.dbd $(IOCDIR)/db/RULES - @$(RM) $(notdir $@) - $(DBTORECORDTYPEH) -I ../db -o $(notdir $@) $< - @$(MV) $(notdir $@) $@ - -$(COMMON_DIR)/menuGlobal.dbd: $(IOCDIR)/db/Makefile $(IOCDIR)/db/RULES - -# This is a target-specific variable -$(COMMON_DIR)/menuGlobal.dbd: DBDCAT_COMMAND = \ - $(PERL) $(TOOLS)/makeIncludeDbd.pl $(menuGlobal_DBD) $(@F) diff --git a/src/ioc/db/callback.c b/src/ioc/db/callback.c deleted file mode 100644 index 16948e962..000000000 --- a/src/ioc/db/callback.c +++ /dev/null @@ -1,354 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* callback.c */ - -/* general purpose callback tasks */ -/* - * Original Author: Marty Kraimer - * Date: 07-18-91 -*/ - -#include -#include -#include -#include - -#include "cantProceed.h" -#include "dbDefs.h" -#include "epicsAtomic.h" -#include "epicsEvent.h" -#include "epicsInterrupt.h" -#include "epicsRingPointer.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "epicsTimer.h" -#include "errlog.h" -#include "errMdef.h" -#include "taskwd.h" - -#define epicsExportSharedSymbols -#include "callback.h" -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbCommon.h" -#include "dbFldTypes.h" -#include "dbLock.h" -#include "dbStaticLib.h" -#include "epicsExport.h" -#include "link.h" -#include "recSup.h" - - -static int callbackQueueSize = 2000; - -typedef struct cbQueueSet { - epicsEventId semWakeUp; - epicsRingPointerId queue; - int queueOverflow; - int shutdown; - int threadsConfigured; - int threadsRunning; -} cbQueueSet; - -static cbQueueSet callbackQueue[NUM_CALLBACK_PRIORITIES]; - -int callbackThreadsDefault = 1; -/* Don't know what a reasonable default is (yet). - * For the time being: parallel means 2 if not explicitly specified */ -epicsShareDef int callbackParallelThreadsDefault = 2; -epicsExportAddress(int,callbackParallelThreadsDefault); - -/* Timer for Delayed Requests */ -static epicsTimerQueueId timerQueue; - -/* Shutdown handling */ -enum ctl {ctlInit, ctlRun, ctlPause, ctlExit}; -static volatile enum ctl cbCtl; -static epicsEventId startStopEvent; - -static int callbackIsInit; - -/* Static data */ -static char *threadNamePrefix[NUM_CALLBACK_PRIORITIES] = { - "cbLow", "cbMedium", "cbHigh" -}; -static unsigned int threadPriority[NUM_CALLBACK_PRIORITIES] = { - epicsThreadPriorityScanLow - 1, - epicsThreadPriorityScanLow + 4, - epicsThreadPriorityScanHigh + 1 -}; -static int priorityValue[NUM_CALLBACK_PRIORITIES] = {0, 1, 2}; - - -int callbackSetQueueSize(int size) -{ - if (callbackIsInit) { - fprintf(stderr, "Callback system already initialized\n"); - return -1; - } - callbackQueueSize = size; - return 0; -} - -int callbackParallelThreads(int count, const char *prio) -{ - if (callbackIsInit) { - fprintf(stderr, "Callback system already initialized\n"); - return -1; - } - - if (count < 0) - count = epicsThreadGetCPUs() + count; - else if (count == 0) - count = callbackParallelThreadsDefault; - if (count < 1) count = 1; - - if (!prio || *prio == 0 || strcmp(prio, "*") == 0) { - int i; - - for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { - callbackQueue[i].threadsConfigured = count; - } - } - else { - dbMenu *pdbMenu; - int i; - - if (!pdbbase) { - fprintf(stderr, "callbackParallelThreads: pdbbase not set\n"); - return -1; - } - - /* Find prio in menuPriority */ - pdbMenu = dbFindMenu(pdbbase, "menuPriority"); - if (!pdbMenu) { - fprintf(stderr, "callbackParallelThreads: No Priority menu\n"); - return -1; - } - - for (i = 0; i < pdbMenu->nChoice; i++) { - if (epicsStrCaseCmp(prio, pdbMenu->papChoiceValue[i]) == 0) - goto found; - } - fprintf(stderr, "callbackParallelThreads: " - "Unknown priority \"%s\"\n", prio); - return -1; - -found: - callbackQueue[i].threadsConfigured = count; - } - return 0; -} - -static void callbackTask(void *arg) -{ - int prio = *(int*)arg; - cbQueueSet *mySet = &callbackQueue[prio]; - - taskwdInsert(0, NULL, NULL); - epicsEventSignal(startStopEvent); - - while(!mySet->shutdown) { - void *ptr; - if (epicsRingPointerIsEmpty(mySet->queue)) - epicsEventMustWait(mySet->semWakeUp); - - while ((ptr = epicsRingPointerPop(mySet->queue))) { - CALLBACK *pcallback = (CALLBACK *)ptr; - if(!epicsRingPointerIsEmpty(mySet->queue)) - epicsEventMustTrigger(mySet->semWakeUp); - mySet->queueOverflow = FALSE; - (*pcallback->callback)(pcallback); - } - } - - if(!epicsAtomicDecrIntT(&mySet->threadsRunning)) - epicsEventSignal(startStopEvent); - taskwdRemove(0); -} - -void callbackStop(void) -{ - int i; - - if (cbCtl == ctlExit) return; - cbCtl = ctlExit; - - for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { - callbackQueue[i].shutdown = 1; - epicsEventSignal(callbackQueue[i].semWakeUp); - } - - for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { - cbQueueSet *mySet = &callbackQueue[i]; - - while (epicsAtomicGetIntT(&mySet->threadsRunning)) { - epicsEventSignal(mySet->semWakeUp); - epicsEventWaitWithTimeout(startStopEvent, 0.1); - } - } -} - -void callbackCleanup(void) -{ - int i; - - for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { - cbQueueSet *mySet = &callbackQueue[i]; - - assert(epicsAtomicGetIntT(&mySet->threadsRunning)==0); - epicsEventDestroy(mySet->semWakeUp); - epicsRingPointerDelete(mySet->queue); - } - - epicsTimerQueueRelease(timerQueue); - callbackIsInit = 0; - memset(callbackQueue, 0, sizeof(callbackQueue)); -} - -void callbackInit(void) -{ - int i; - int j; - char threadName[32]; - - if (callbackIsInit) { - errlogMessage("Warning: callbackInit called again before callbackCleanup\n"); - return; - } - callbackIsInit = 1; - - if(!startStopEvent) - startStopEvent = epicsEventMustCreate(epicsEventEmpty); - cbCtl = ctlRun; - timerQueue = epicsTimerQueueAllocate(0, epicsThreadPriorityScanHigh); - - for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) { - epicsThreadId tid; - - callbackQueue[i].semWakeUp = epicsEventMustCreate(epicsEventEmpty); - callbackQueue[i].queue = epicsRingPointerLockedCreate(callbackQueueSize); - if (callbackQueue[i].queue == 0) - cantProceed("epicsRingPointerLockedCreate failed for %s\n", - threadNamePrefix[i]); - callbackQueue[i].queueOverflow = FALSE; - if (callbackQueue[i].threadsConfigured == 0) - callbackQueue[i].threadsConfigured = callbackThreadsDefault; - - for (j = 0; j < callbackQueue[i].threadsConfigured; j++) { - if (callbackQueue[i].threadsConfigured > 1 ) - sprintf(threadName, "%s-%d", threadNamePrefix[i], j); - else - strcpy(threadName, threadNamePrefix[i]); - tid = epicsThreadCreate(threadName, threadPriority[i], - epicsThreadGetStackSize(epicsThreadStackBig), - (EPICSTHREADFUNC)callbackTask, &priorityValue[i]); - if (tid == 0) { - cantProceed("Failed to spawn callback thread %s\n", threadName); - } else { - epicsEventWait(startStopEvent); - epicsAtomicIncrIntT(&callbackQueue[i].threadsRunning); - } - } - } -} - -/* This routine can be called from interrupt context */ -int callbackRequest(CALLBACK *pcallback) -{ - int priority; - int pushOK; - cbQueueSet *mySet; - - if (!pcallback) { - epicsInterruptContextMessage("callbackRequest: pcallback was NULL\n"); - return S_db_notInit; - } - priority = pcallback->priority; - if (priority < 0 || priority >= NUM_CALLBACK_PRIORITIES) { - epicsInterruptContextMessage("callbackRequest: Bad priority\n"); - return S_db_badChoice; - } - mySet = &callbackQueue[priority]; - if (mySet->queueOverflow) return S_db_bufFull; - - pushOK = epicsRingPointerPush(mySet->queue, pcallback); - - if (!pushOK) { - char msg[48] = "callbackRequest: "; - - strcat(msg, threadNamePrefix[priority]); - strcat(msg, " ring buffer full\n"); - epicsInterruptContextMessage(msg); - mySet->queueOverflow = TRUE; - return S_db_bufFull; - } - epicsEventSignal(mySet->semWakeUp); - return 0; -} - -static void ProcessCallback(CALLBACK *pcallback) -{ - dbCommon *pRec; - - callbackGetUser(pRec, pcallback); - if (!pRec) return; - dbScanLock(pRec); - (*pRec->rset->process)(pRec); - dbScanUnlock(pRec); -} - -void callbackSetProcess(CALLBACK *pcallback, int Priority, void *pRec) -{ - callbackSetCallback(ProcessCallback, pcallback); - callbackSetPriority(Priority, pcallback); - callbackSetUser(pRec, pcallback); -} - -int callbackRequestProcessCallback(CALLBACK *pcallback, - int Priority, void *pRec) -{ - callbackSetProcess(pcallback, Priority, pRec); - return callbackRequest(pcallback); -} - -static void notify(void *pPrivate) -{ - CALLBACK *pcallback = (CALLBACK *)pPrivate; - callbackRequest(pcallback); -} - -void callbackRequestDelayed(CALLBACK *pcallback, double seconds) -{ - epicsTimerId timer = (epicsTimerId)pcallback->timer; - - if (timer == 0) { - timer = epicsTimerQueueCreateTimer(timerQueue, notify, pcallback); - pcallback->timer = timer; - } - epicsTimerStartDelay(timer, seconds); -} - -void callbackCancelDelayed(CALLBACK *pcallback) -{ - epicsTimerId timer = (epicsTimerId)pcallback->timer; - - if (timer != 0) { - epicsTimerCancel(timer); - } -} - -void callbackRequestProcessCallbackDelayed(CALLBACK *pcallback, - int Priority, void *pRec, double seconds) -{ - callbackSetProcess(pcallback, Priority, pRec); - callbackRequestDelayed(pcallback, seconds); -} diff --git a/src/ioc/db/callback.h b/src/ioc/db/callback.h deleted file mode 100644 index d25b782c9..000000000 --- a/src/ioc/db/callback.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* includes for general purpose callback tasks */ -/* - * Original Author: Marty Kraimer - * Date: 07-18-91 -*/ - -#ifndef INCcallbackh -#define INCcallbackh 1 - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * WINDOWS also has a "CALLBACK" type def - */ -#ifdef _WIN32 -# ifdef CALLBACK -# undef CALLBACK -# endif /*CALLBACK*/ -#endif /*_WIN32*/ - -#define NUM_CALLBACK_PRIORITIES 3 -#define priorityLow 0 -#define priorityMedium 1 -#define priorityHigh 2 - -typedef struct callbackPvt { - void (*callback)(struct callbackPvt*); - int priority; - void *user; /*for use by callback user*/ - void *timer; /*for use by callback itself*/ -}CALLBACK; - -typedef void (*CALLBACKFUNC)(struct callbackPvt*); - -#define callbackSetCallback(PFUN, PCALLBACK) \ - ( (PCALLBACK)->callback = (PFUN) ) -#define callbackSetPriority(PRIORITY, PCALLBACK) \ - ( (PCALLBACK)->priority = (PRIORITY) ) -#define callbackGetPriority(PRIORITY, PCALLBACK) \ - ( (PRIORITY) = (PCALLBACK)->priority ) -#define callbackSetUser(USER, PCALLBACK) \ - ( (PCALLBACK)->user = (void *) (USER) ) -#define callbackGetUser(USER, PCALLBACK) \ - ( (USER) = (PCALLBACK)->user ) - -epicsShareFunc void callbackInit(void); -epicsShareFunc void callbackStop(void); -epicsShareFunc void callbackCleanup(void); -epicsShareFunc int callbackRequest(CALLBACK *pCallback); -epicsShareFunc void callbackSetProcess( - CALLBACK *pcallback, int Priority, void *pRec); -epicsShareFunc int callbackRequestProcessCallback( - CALLBACK *pCallback,int Priority, void *pRec); -epicsShareFunc void callbackRequestDelayed( - CALLBACK *pCallback,double seconds); -epicsShareFunc void callbackCancelDelayed(CALLBACK *pcallback); -epicsShareFunc void callbackRequestProcessCallbackDelayed( - CALLBACK *pCallback, int Priority, void *pRec, double seconds); -epicsShareFunc int callbackSetQueueSize(int size); -epicsShareFunc int callbackParallelThreads(int count, const char *prio); - -#ifdef __cplusplus -} -#endif - -#endif /*INCcallbackh*/ diff --git a/src/ioc/db/chfPlugin.c b/src/ioc/db/chfPlugin.c deleted file mode 100644 index 5a86d3a26..000000000 --- a/src/ioc/db/chfPlugin.c +++ /dev/null @@ -1,681 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* für Materialien und Energie GmbH. -* Copyright (c) 2014 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -/* Based on the linkoptions utility by Michael Davidsaver (BNL) */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsStdio.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "epicsTypes.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "chfPlugin.h" -#include "dbStaticLib.h" - -/* - * Data for a chfPlugin - */ -typedef struct chfPlugin { - const chfPluginArgDef *opts; - size_t nopts; - epicsUInt32 *required; - const chfPluginIf *pif; -} chfPlugin; - -/* - * Parser state data for a chfFilter (chfPlugin instance) - */ -typedef struct chfFilter { - const chfPlugin *plugin; - epicsUInt32 *found; - void *puser; - epicsInt16 nextParam; -} chfFilter; - -/* Data types we get from the parser */ -typedef enum chfPluginType { - chfPluginTypeBool, - chfPluginTypeInt, - chfPluginTypeDouble, - chfPluginTypeString -} chfPluginType; - -/* - * Convert the (epicsInt32) integer value 'val' to the type named in - * 'opt->optType' and store the result at 'user + opt->offset'. - */ -static int -store_integer_value(const chfPluginArgDef *opt, char *user, epicsInt32 val) -{ - epicsInt32 *ival; - int *eval; - const chfPluginEnumType *emap; - double *dval; - char *sval; - int ret; - char buff[22]; /* 2^64 = 1.8e+19, so 20 digits plus sign max */ - -#ifdef DEBUG_CHF - printf("Got an integer for %s (type %d): %ld\n", - opt->name, opt->optType, (long) val); -#endif - - if (!opt->convert && opt->optType != chfPluginArgInt32) { - return -1; - } - - switch (opt->optType) { - case chfPluginArgInt32: - ival = (epicsInt32 *) ((char *)user + opt->dataOffset); - *ival = val; - break; - case chfPluginArgBoolean: - sval = user + opt->dataOffset; - *sval = !!val; - break; - case chfPluginArgDouble: - dval = (double*) (user + opt->dataOffset); - *dval = val; - break; - case chfPluginArgString: - sval = user + opt->dataOffset; - ret = sprintf(buff, "%ld", (long)val); - if (ret < 0 || (unsigned) ret > opt->size - 1) { - return -1; - } - strncpy(sval, buff, opt->size-1); - sval[opt->size-1]='\0'; - break; - case chfPluginArgEnum: - eval = (int*) (user + opt->dataOffset); - for (emap = opt->enums; emap && emap->name; emap++) { - if (val == emap->value) { - *eval = val; - break; - } - } - if (!emap || !emap->name) { - return -1; - } - break; - case chfPluginArgInvalid: - return -1; - } - return 0; -} - -/* - * Convert the (int) boolean value 'val' to the type named in 'opt->optType' - * and store the result at 'user + opt->offset'. - */ -static int store_boolean_value(const chfPluginArgDef *opt, char *user, int val) -{ - epicsInt32 *ival; - double *dval; - char *sval; - -#ifdef DEBUG_CHF - printf("Got a boolean for %s (type %d): %d\n", - opt->name, opt->optType, val); -#endif - - if (!opt->convert && opt->optType != chfPluginArgBoolean) { - return -1; - } - - switch (opt->optType) { - case chfPluginArgInt32: - ival = (epicsInt32 *) (user + opt->dataOffset); - *ival = val; - break; - case chfPluginArgBoolean: - sval = user + opt->dataOffset; - *sval = val; - break; - case chfPluginArgDouble: - dval = (double*) (user + opt->dataOffset); - *dval = !!val; - break; - case chfPluginArgString: - sval = user + opt->dataOffset; - if ((unsigned) (val ? 4 : 5) > opt->size - 1) { - return -1; - } - strncpy(sval, val ? "true" : "false", opt->size - 1); - sval[opt->size - 1] = '\0'; - break; - case chfPluginArgEnum: - case chfPluginArgInvalid: - return -1; - } - return 0; -} - -/* - * Convert the double value 'val' to the type named in 'opt->optType' - * and store the result at 'user + opt->offset'. - */ -static int -store_double_value(const chfPluginArgDef *opt, void *vuser, double val) -{ - char *user = vuser; - epicsInt32 *ival; - double *dval; - char *sval; - int i; - -#ifdef DEBUG_CHF - printf("Got a double for %s (type %d, convert: %s): %g\n", - opt->name, opt->optType, opt->convert ? "yes" : "no", val); -#endif - - if (!opt->convert && opt->optType != chfPluginArgDouble) { - return -1; - } - - switch (opt->optType) { - case chfPluginArgInt32: - if (val < INT_MIN || val > INT_MAX) { - return -1; - } - ival = (epicsInt32 *) (user + opt->dataOffset); - *ival = (epicsInt32) val; - break; - case chfPluginArgBoolean: - sval = user + opt->dataOffset; - *sval = !!val; - break; - case chfPluginArgDouble: - dval = (double*) (user + opt->dataOffset); - *dval = val; - break; - case chfPluginArgString: - sval = user + opt->dataOffset; - if (opt->size <= 8) { /* Play it safe: 3 exp + 2 sign + 'e' + '.' */ - return -1; - } - i = epicsSnprintf(sval, opt->size, "%.*g", (int) opt->size - 7, val); - if (i < 0 || (unsigned) i >= opt->size) { - return -1; - } - break; - case chfPluginArgEnum: - case chfPluginArgInvalid: - return -1; - } - return 0; -} - -/* - * Convert the (char*) string value 'val' to the type named in 'opt->optType' - * and store the result at 'user + opt->offset'. - */ -static int -store_string_value(const chfPluginArgDef *opt, char *user, const char *val, - size_t len) -{ - epicsInt32 *ival; - int *eval; - const chfPluginEnumType *emap; - double *dval; - char *sval; - char *end; - size_t i; - -#ifdef DEBUG_CHF - printf("Got a string for %s (type %d): %.*s\n", - opt->name, opt->optType, (int) len, val); -#endif - - if (!opt->convert && opt->optType != chfPluginArgString && - opt->optType != chfPluginArgEnum) { - return -1; - } - - switch (opt->optType) { - case chfPluginArgInt32: - ival = (epicsInt32 *) (user + opt->dataOffset); - return epicsParseInt32(val, ival, 0, &end); - - case chfPluginArgBoolean: - sval = user + opt->dataOffset; - if (epicsStrnCaseCmp(val, "true", len) == 0) { - *sval = 1; - } else if (epicsStrnCaseCmp(val, "false", len) == 0) { - *sval = 0; - } else { - epicsInt8 i8; - - if (epicsParseInt8(val, &i8, 0, &end)) - return -1; - *sval = !!i8; - } - break; - case chfPluginArgDouble: - dval = (double*) (user + opt->dataOffset); - return epicsParseDouble(val, dval, &end); - - case chfPluginArgString: - i = opt->size-1 < len ? opt->size-1 : (int) len; - sval = user + opt->dataOffset; - strncpy(sval, val, i); - sval[i] = '\0'; - break; - case chfPluginArgEnum: - eval = (int*) (user + opt->dataOffset); - for (emap = opt->enums; emap && emap->name; emap++) { - if (strncmp(emap->name, val, len) == 0) { - *eval = emap->value; - break; - } - } - if( !emap || !emap->name ) { - return -1; - } - break; - case chfPluginArgInvalid: - return -1; - } - return 0; -} - -static void freeInstanceData(chfFilter *f) -{ - free(f->found); - free(f); /* FIXME: Use a free-list */ -} - -/* - * chFilterIf callbacks - */ - -/* First entry point when a new filter instance is created. - * All per-instance allocations happen here. - */ -static parse_result parse_start(chFilter *filter) -{ - chfPlugin *p = (chfPlugin*) filter->plug->puser; - chfFilter *f; - - /* Filter context */ - /* FIXME: Use a free-list */ - f = calloc(1, sizeof(chfFilter)); - if (!f) { - errlogPrintf("chfFilterCtx calloc failed\n"); - goto errfctx; - } - f->nextParam = -1; - - /* Bit array to find missing required keys */ - f->found = calloc( (p->nopts/32)+1, sizeof(epicsUInt32) ); - if (!f->found) { - errlogPrintf("chfConfigParseStart: bit array calloc failed\n"); - goto errbitarray; - } - - /* Call the plugin to allocate its structure, it returns NULL on error */ - if (p->pif->allocPvt) { - if ((f->puser = p->pif->allocPvt()) == NULL) { - errlogPrintf("chfConfigParseStart: plugin pvt alloc failed\n"); - goto errplugin; - } - } - - filter->puser = (void*) f; - - return parse_continue; - - errplugin: - free(f->found); - errbitarray: - free(f); /* FIXME: Use a free-list */ - errfctx: - return parse_stop; -} - -static void parse_abort(chFilter *filter) { - chfPlugin *p = (chfPlugin*) filter->plug->puser; - chfFilter *f = (chfFilter*) filter->puser; - - /* Call the plugin to tell it we're aborting */ - if (p->pif->parse_error) p->pif->parse_error(f->puser); - if (p->pif->freePvt) p->pif->freePvt(f->puser); - freeInstanceData(f); -} - -static parse_result parse_end(chFilter *filter) -{ - chfPlugin *p = (chfPlugin*) filter->plug->puser; - chfFilter *f = (chfFilter*) filter->puser; - int i; - - /* Check if all required arguments were supplied */ - for(i = 0; i < (p->nopts/32)+1; i++) { - if ((f->found[i] & p->required[i]) != p->required[i]) { - if (p->pif->parse_error) p->pif->parse_error(f->puser); - if (p->pif->freePvt) p->pif->freePvt(f->puser); - freeInstanceData(f); - return parse_stop; - } - } - - /* Call the plugin to tell it we're done */ - if (p->pif->parse_ok) { - if (p->pif->parse_ok(f->puser)) { - if (p->pif->freePvt) p->pif->freePvt(f->puser); - freeInstanceData(f); - return parse_stop; - } - } - - return parse_continue; -} - -static parse_result parse_boolean(chFilter *filter, int boolVal) -{ - const chfPluginArgDef *opts = ((chfPlugin*)filter->plug->puser)->opts; - chfFilter *f = (chfFilter*)filter->puser; - - if (f->nextParam < 0 || - store_boolean_value(&opts[f->nextParam], f->puser, boolVal)) { - return parse_stop; - } else { - return parse_continue; - } -} - -static parse_result parse_integer(chFilter *filter, long integerVal) -{ - const chfPluginArgDef *opts = ((chfPlugin*)filter->plug->puser)->opts; - chfFilter *f = (chfFilter*)filter->puser; - - if(sizeof(long)>sizeof(epicsInt32)) { - epicsInt32 temp=integerVal; - if(integerVal !=temp) - return parse_stop; - } - if (f->nextParam < 0 || - store_integer_value(&opts[f->nextParam], f->puser, integerVal)) { - return parse_stop; - } else { - return parse_continue; - } -} - -static parse_result parse_double(chFilter *filter, double doubleVal) -{ - const chfPluginArgDef *opts = ((chfPlugin*)filter->plug->puser)->opts; - chfFilter *f = (chfFilter*)filter->puser; - - if (f->nextParam < 0 || - store_double_value(&opts[f->nextParam], f->puser, doubleVal)) { - return parse_stop; - } else { - return parse_continue; - } -} - -static parse_result -parse_string(chFilter *filter, const char *stringVal, size_t stringLen) -{ - const chfPluginArgDef *opts = ((chfPlugin*)filter->plug->puser)->opts; - chfFilter *f = (chfFilter*)filter->puser; - - if (f->nextParam < 0 || - store_string_value(&opts[f->nextParam], f->puser, stringVal, stringLen)) { - return parse_stop; - } else { - return parse_continue; - } -} - -static parse_result parse_start_map(chFilter *filter) -{ - return parse_continue; -} - -static parse_result -parse_map_key(chFilter *filter, const char *key, size_t stringLen) -{ - const chfPluginArgDef *cur; - const chfPluginArgDef *opts = ((chfPlugin*)filter->plug->puser)->opts; - chfFilter *f = (chfFilter*)filter->puser; - int *tag; - int i; - int j; - - f->nextParam = -1; - for (cur = opts, i = 0; cur && cur->name; cur++, i++) { - if (strncmp(key, cur->name, stringLen) == 0) { - f->nextParam = i; - break; - } - } - if (f->nextParam == -1) { - return parse_stop; - } - - if (opts[i].tagged) { - tag = (int*) ((char*) f->puser + opts[i].tagOffset); - *tag = opts[i].choice; - } - - f->found[i/32] |= 1<<(i%32); - /* Mark tag and all other options pointing to the same data as found */ - for (cur = opts, j = 0; cur && cur->name; cur++, j++) { - if ((opts[i].tagged && cur->dataOffset == opts[i].tagOffset) - || cur->dataOffset == opts[i].dataOffset) - f->found[j/32] |= 1<<(j%32); - } - - return parse_continue; -} - -static parse_result parse_end_map(chFilter *filter) -{ - return parse_continue; -} - -static long channel_open(chFilter *filter) -{ - chfPlugin *p = (chfPlugin*) filter->plug->puser; - chfFilter *f = (chfFilter*) filter->puser; - - if (p->pif->channel_open) - return p->pif->channel_open(filter->chan, f->puser); - else - return 0; -} - -static void -channel_register_pre(chFilter *filter, chPostEventFunc **cb_out, - void **arg_out, db_field_log *probe) -{ - chfPlugin *p = (chfPlugin*) filter->plug->puser; - chfFilter *f = (chfFilter*) filter->puser; - - if (p->pif->channelRegisterPre) - p->pif->channelRegisterPre(filter->chan, f->puser, cb_out, arg_out, - probe); -} - -static void -channel_register_post(chFilter *filter, chPostEventFunc **cb_out, - void **arg_out, db_field_log *probe) -{ - chfPlugin *p = (chfPlugin*) filter->plug->puser; - chfFilter *f = (chfFilter*) filter->puser; - - if (p->pif->channelRegisterPost) - p->pif->channelRegisterPost(filter->chan, f->puser, cb_out, arg_out, - probe); -} - -static void channel_report(chFilter *filter, int level, - const unsigned short indent) -{ - chfPlugin *p = (chfPlugin*) filter->plug->puser; - chfFilter *f = (chfFilter*) filter->puser; - - if (p->pif->channel_report) - p->pif->channel_report(filter->chan, f->puser, level, indent); -} - -static void channel_close(chFilter *filter) -{ - chfPlugin *p = (chfPlugin*) filter->plug->puser; - chfFilter *f = (chfFilter*) filter->puser; - - if (p->pif->channel_close) p->pif->channel_close(filter->chan, f->puser); - if (p->pif->freePvt) p->pif->freePvt(f->puser); - free(f->found); - free(f); /* FIXME: Use a free-list */ -} - -static void plugin_free(void* puser) -{ - chfPlugin *p=puser; - free(p->required); - free(p); -} - -/* - * chFilterIf for the wrapper - * we just support a simple one-level map, and no arrays - */ -static chFilterIf wrapper_fif = { - plugin_free, - - parse_start, - parse_abort, - parse_end, - - NULL, /* parse_null, */ - parse_boolean, - parse_integer, - parse_double, - parse_string, - - parse_start_map, - parse_map_key, - parse_end_map, - - NULL, /* parse_start_array, */ - NULL, /* parse_end_array, */ - - channel_open, - channel_register_pre, - channel_register_post, - channel_report, - channel_close -}; - -const char* -chfPluginEnumString(const chfPluginEnumType *emap, int i, const char* def) -{ - for(; emap && emap->name; emap++) { - if ( i == emap->value ) { - return emap->name; - } - } - return def; -} - -int -chfPluginRegister(const char* key, const chfPluginIf *pif, - const chfPluginArgDef* opts) -{ - chfPlugin *p; - size_t i; - const chfPluginArgDef *cur; - epicsUInt32 *reqd; - - /* Check and count options */ - for (i = 0, cur = opts; cur && cur->name; i++, cur++) { - switch(cur->optType) { - case chfPluginArgInt32: - if (cur->size < sizeof(epicsInt32)) { - errlogPrintf("Plugin %s: %d bytes too small for epicsInt32 %s\n", - key, cur->size, cur->name); - return -1; - } - break; - case chfPluginArgBoolean: - if (cur->size < 1) { - errlogPrintf("Plugin %s: %d bytes too small for boolean %s\n", - key, cur->size, cur->name); - return -1; - } - break; - case chfPluginArgDouble: - if (cur->size < sizeof(double)) { - errlogPrintf("Plugin %s: %d bytes too small for double %s\n", - key, cur->size, cur->name); - return -1; - } - break; - case chfPluginArgString: - if (cur->size < sizeof(char*)) { - /* Catch if someone has given us a char* instead of a char[] - * Also means that char buffers must be >=4. - */ - errlogPrintf("Plugin %s: %d bytes too small for string %s\n", - key, cur->size, cur->name); - return -1; - } - break; - case chfPluginArgEnum: - if (cur->size < sizeof(int)) { - errlogPrintf("Plugin %s: %d bytes too small for enum %s\n", - key, cur->size, cur->name); - return -1; - } - break; - case chfPluginArgInvalid: - errlogPrintf("Plugin %s: storage type for %s is not defined\n", - key, cur->name); - return -1; - break; - } - } - - /* Bit array used to find missing required keys */ - reqd = dbCalloc((i/32)+1, sizeof(epicsUInt32)); - if (!reqd) { - errlogPrintf("Plugin %s: bit array calloc failed\n", key); - return -1; - } - - for (i = 0, cur = opts; cur && cur->name; i++, cur++) { - if (cur->required) reqd[i/32] |= 1 << (i%32); - } - - /* Plugin data */ - p = dbCalloc(1, sizeof(chfPlugin)); - p->pif = pif; - p->opts = opts; - p->nopts = i; - p->required = reqd; - - dbRegisterFilter(key, &wrapper_fif, p); - - return 0; -} diff --git a/src/ioc/db/chfPlugin.h b/src/ioc/db/chfPlugin.h deleted file mode 100644 index eabaa7ac3..000000000 --- a/src/ioc/db/chfPlugin.h +++ /dev/null @@ -1,318 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* für Materialien und Energie GmbH. -* Copyright (c) 2014 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -/* Based on the linkoptions utility by Michael Davidsaver (BNL) */ - -#ifndef CHFPLUGIN_H -#define CHFPLUGIN_H - -#include -#include -#include -#include - -struct db_field_log; - -/** @file chfPlugin.h - * @brief Channel filter simplified plugins. - * - * Utility layer to allow an easier (reduced) interface for - * channel filter plugins. - * - * Parsing the configuration arguments of a channel filter plugin - * is done according to an argument description table provided by the plugin. - * The parser stores the results directly into a user supplied structure - * after appropriate type conversion. - * - * To specify the arguments, a chfPluginArgDef table must be defined - * for the user structure. This table has to be specified when the plugin registers. - * - * The plugin is responsible to register an init function using - * epicsExportRegistrar() and the accompanying registrar() directive in the dbd, - * and call chfPluginRegister() from within the init function. - * - * For example: - * - * typedef struct myStruct { - * ... other stuff - * char mode; - * epicsInt32 ival; - * double dval; - * epicsInt32 ival2; - * int enumval; - * char strval[20]; - * char boolval; - * } myStruct; - * - * static const - * chfPluginEnumType colorEnum[] = { {"Red",1}, {"Green",2}, {"Blue",3}, {NULL,0} }; - * - * static const - * chfPluginDef myStructDef[] = { - * chfTagInt32(myStruct, ival, "Integer" , ival2, 3, 0, 0), - * chfInt32 (myStruct, ival2, "Second" , 1, 0), - * chfDouble (myStruct, dval, "Double" , 1, 0), - * chfString (myStruct, strval , "String" , 1, 0), - * chfEnum (myStruct, enumval, "Color" , 1, 0, colorEnum), - * chfBoolean (myStruct, boolval, "Bool" , 1, 0), - * chfPluginEnd - * }; - * - * Note: The 4th argument specifies the parameter to be required (1) or optional (0), - * the 5th whether converting to the required type is allowed (1), or - * type mismatches are an error (0). - * Note: The "Tag" version has two additional arguments. the 4th arg specifies the tag - * field (integer type) inside the structure to be set, the 5th arg specifies the - * value to set the tag field to. Arguments 6 and 7 specify "required" and - * "conversion" as described above. - * - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief Channel filter simplified plugin interface. - * - * The routines in this structure must be implemented by each filter plugin. - */ -typedef struct chfPluginIf { - - /* Memory management */ - /** @brief Allocate private resources. - * - * Called before parsing starts. - * The plugin should allocate its per-instance structures, - * returning a pointer to them or NULL requesting an abort of the operation. - * - * allocPvt may be set to NULL, if no resource allocation is needed. - * - * @return Pointer to private structure, NULL if operation is to be aborted. - */ - void * (* allocPvt) (void); - - /** @brief Free private resources. - * - * Called as part of abort or shutdown. - * The plugin should release any resources allocated for this filter; - * no further calls through this interface will be made. - * - * freePvt may be set to NULL, if no resources need to be released. - * - * @param pvt Pointer to private structure. - */ - void (* freePvt) (void *pvt); - - /* Parameter parsing results */ - /** @brief A parsing error occurred. - * - * Called after parsing failed with an error. - * - * @param pvt Pointer to private structure. - */ - void (* parse_error) (void *pvt); - - /** @brief Configuration has been parsed successfully. - * - * Called after parsing has finished ok. - * The plugin may check the validity of the parsed data, - * returning -1 to request an abort of the operation. - * - * @param pvt Pointer to private structure. - * @return 0 for success, -1 if operation is to be aborted. - */ - int (* parse_ok) (void *pvt); - - /* Channel operations */ - /** @brief Open channel. - * - * Called as part of the channel connection setup. - * - * @param chan dbChannel for which the connection is being made. - * @param pvt Pointer to private structure. - * @return 0 for success, -1 if operation is to be aborted. - */ - long (* channel_open) (dbChannel *chan, void *pvt); - - /** @brief Register callbacks for pre-event-queue operation. - * - * Called as part of the channel connection setup. - * - * This function is called to establish the stack of plugins that an event - * is passed through between the database and the event queue. - * - * The plugin must set pe_out to point to its own post-event callback in order - * to be called when a data update is sent from the database towards the - * event queue. - * - * The plugin may find out the type of data it will receive by looking at 'probe'. - * If the plugin will change the data type and/or size, it must update 'probe' - * accordingly. - * - * @param chan dbChannel for which the connection is being made. - * @param pvt Pointer to private structure. - * @param cb_out Pointer to this plugin's post-event callback (NULL to bypass - * this plugin). - * @param arg_out Argument that must be supplied when calling - * this plugin's post-event callback. - */ - void (* channelRegisterPre) (dbChannel *chan, void *pvt, - chPostEventFunc **cb_out, void **arg_out, - db_field_log *probe); - - /** @brief Register callbacks for post-event-queue operation. - * - * Called as part of the channel connection setup. - * - * This function is called to establish the stack of plugins that an event - * is passed through between the event queue and the final user (CA server or - * database access). - * - * The plugin must set pe_out to point to its own post-event callback in order - * to be called when a data update is sent from the event queue towards the - * final user. - * - * The plugin may find out the type of data it will receive by looking at 'probe'. - * If the plugin will change the data type and/or size, it must update 'probe' - * accordingly. - * - * @param chan dbChannel for which the connection is being made. - * @param pvt Pointer to private structure. - * @param cb_out Pointer to this plugin's post-event callback (NULL to bypass - * this plugin). - * @param arg_out Argument that must be supplied when calling - * this plugin's post-event callback. - */ - void (* channelRegisterPost) (dbChannel *chan, void *pvt, - chPostEventFunc **cb_out, void **arg_out, - db_field_log *probe); - - /** @brief Channel report request. - * - * Called as part of show... routines. - * - * @param chan dbChannel for which the report is requested. - * @param pvt Pointer to private structure. - * @param level Interest level. - * @param indent Number of spaces to print before each output line. - */ - void (* channel_report) (dbChannel *chan, void *pvt, int level, const unsigned short indent); - - /** @brief Channel close request. - * - * Called as part of connection shutdown. - * @param chan dbChannel for which the connection is being shut down. - * @param pvt Pointer to private structure. - */ - void (* channel_close) (dbChannel *chan, void *pvt); - -} chfPluginIf; - -typedef enum chfPluginArg { - chfPluginArgInvalid=0, - chfPluginArgBoolean, - chfPluginArgInt32, - chfPluginArgDouble, - chfPluginArgString, - chfPluginArgEnum -} chfPluginArg; - -typedef struct chfPluginEnumType { - const char *name; - const int value; -} chfPluginEnumType; - -typedef struct chfPluginArgDef { - const char * name; - chfPluginArg optType; - unsigned int required:1; - unsigned int convert:1; - unsigned int tagged:1; - epicsUInt32 tagOffset; - epicsUInt32 choice; - epicsUInt32 dataOffset; - epicsUInt32 size; - const chfPluginEnumType *enums; -} chfPluginArgDef; - -/* Simple arguments */ - -#define chfInt32(Struct, Member, Name, Req, Conv) \ - {Name, chfPluginArgInt32, Req, Conv, 0, 0, 0, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL} - -#define chfBoolean(Struct, Member, Name, Req, Conv) \ - {Name, chfPluginArgBoolean, Req, Conv, 0, 0, 0, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL} - -#define chfDouble(Struct, Member, Name, Req, Conv) \ - {Name, chfPluginArgDouble, Req, Conv, 0, 0, 0, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL} - -#define chfString(Struct, Member, Name, Req, Conv) \ - {Name, chfPluginArgString, Req, Conv, 0, 0, 0, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL} - -#define chfEnum(Struct, Member, Name, Req, Conv, Enums) \ - {Name, chfPluginArgEnum, Req, Conv, 0, 0, 0, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), Enums} - -/* Tagged arguments */ - -#define chfTagInt32(Struct, Member, Name, Tag, Choice, Req, Conv) \ - {Name, chfPluginArgInt32, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL} - -#define chfTagBoolean(Struct, Member, Name, Tag, Choice, Req, Conv) \ - {Name, chfPluginArgBoolean, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL} - -#define chfTagDouble(Struct, Member, Name, Tag, Choice, Req, Conv) \ - {Name, chfPluginArgDouble, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL} - -#define chfTagString(Struct, Member, Name, Tag, Choice, Req, Conv) \ - {Name, chfPluginArgString, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL} - -#define chfTagEnum(Struct, Member, Name, Tag, Choice, Req, Conv, Enums) \ - {Name, chfPluginArgEnum, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \ - OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), Enums} - -#define chfPluginArgEnd {0} - -/* Extra output when parsing and converting */ -#define CHFPLUGINDEBUG 1 - -/** @brief Return the string associated with Enum index 'i'. - * - * @param Enums A null-terminated array of string/integer pairs. - * @param i An Enum index. - * @param def String to be returned when 'i' isn't a valid Enum index. - * @return The string associated with 'i'. - */ -epicsShareFunc const char* chfPluginEnumString(const chfPluginEnumType *Enums, int i, const char* def); - -/** @brief Register a plugin. - * - * @param key The plugin name key that clients will use. - * @param pif Pointer to the plugin's interface. - * @param opts Pointer to the configuration argument description table. - */ -epicsShareFunc int chfPluginRegister(const char* key, const chfPluginIf *pif, const chfPluginArgDef* opts); - -#ifdef __cplusplus -} -#endif - -#endif // CHFPLUGIN_H diff --git a/src/ioc/db/cvtBpt.c b/src/ioc/db/cvtBpt.c deleted file mode 100644 index 2689483ee..000000000 --- a/src/ioc/db/cvtBpt.c +++ /dev/null @@ -1,202 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* cvtBpt.c - Convert using breakpoint table - * - * Author: Marty Kraimer - * Date: 04OCT95 - * This is adaptation of old bldCvtTable - */ - -#include "epicsPrint.h" - -#define epicsExportSharedSymbols -#include "cvtTable.h" -#include "dbAccess.h" -#include "dbBase.h" -#include "dbStaticLib.h" - -static brkTable *findBrkTable(short linr) -{ - dbMenu *pdbMenu; - - pdbMenu = dbFindMenu(pdbbase,"menuConvert"); - if (!pdbMenu) { - epicsPrintf("findBrkTable: menuConvert not loaded!\n"); - return NULL; - } - if (linr < 0 || linr >= pdbMenu->nChoice) { - epicsPrintf("findBrkTable: linr=%d but menuConvert only has %d choices\n", - linr,pdbMenu->nChoice); - return NULL; - } - return dbFindBrkTable(pdbbase,pdbMenu->papChoiceValue[linr]); -} - -/* Used by both ao and ai record types */ -long cvtRawToEngBpt(double *pval, short linr, short init, - void **ppbrk, short *plbrk) -{ - double val = *pval; - long status = 0; - brkTable *pbrkTable; - brkInt *pInt, *nInt; - short lbrk; - int number; - - if (linr < 2) - return -1; - - if (init || *ppbrk == NULL) { - pbrkTable = findBrkTable(linr); - if (!pbrkTable) - return S_dbLib_badField; - - *ppbrk = (void *)pbrkTable; - *plbrk = 0; - } else - pbrkTable = (brkTable *)*ppbrk; - - number = pbrkTable->number; - lbrk = *plbrk; - - /* Limit index to the size of the table */ - if (lbrk < 0) - lbrk = 0; - else if (lbrk > number-2) - lbrk = number-2; - - pInt = & pbrkTable->paBrkInt[lbrk]; - nInt = pInt + 1; - - if (nInt->raw > pInt->raw) { - /* raw values increase down the table */ - while (val > nInt->raw) { - lbrk++; - pInt = nInt++; - if (lbrk > number-2) { - status = 1; - break; - } - } - while (val < pInt->raw) { - if (lbrk <= 0) { - status = 1; - break; - } - lbrk--; - nInt = pInt--; - } - } else { - /* raw values decrease down the table */ - while (val <= nInt->raw) { - lbrk++; - pInt = nInt++; - if (lbrk > number-2) { - status = 1; - break; - } - } - while(val > pInt->raw) { - if (lbrk <= 0) { - status = 1; - break; - } - lbrk--; - nInt = pInt--; - } - } - - *plbrk = lbrk; - *pval = pInt->eng + (val - pInt->raw) * pInt->slope; - - return status; -} - -/* Used by the ao record type */ -long cvtEngToRawBpt(double *pval, short linr, short init, - void **ppbrk, short *plbrk) -{ - double val = *pval; - long status = 0; - brkTable *pbrkTable; - brkInt *pInt, *nInt; - short lbrk; - int number; - - if (linr < 2) - return -1; - - if (init || *ppbrk == NULL) { /*must find breakpoint table*/ - pbrkTable = findBrkTable(linr); - if (!pbrkTable) - return S_dbLib_badField; - - *ppbrk = (void *)pbrkTable; - /* start at the beginning */ - *plbrk = 0; - } else - pbrkTable = (brkTable *)*ppbrk; - - number = pbrkTable->number; - lbrk = *plbrk; - - /* Limit index to the size of the table */ - if (lbrk < 0) - lbrk = 0; - else if (lbrk > number-2) - lbrk = number-2; - - pInt = & pbrkTable->paBrkInt[lbrk]; - nInt = pInt + 1; - - if (nInt->eng > pInt->eng) { - /* eng values increase down the table */ - while (val > nInt->eng) { - lbrk++; - pInt = nInt++; - if (lbrk > number-2) { - status = 1; - break; - } - } - while (val < pInt->eng) { - if (lbrk <= 0) { - status = 1; - break; - } - lbrk--; - nInt = pInt--; - } - } else { - /* eng values decrease down the table */ - while (val <= nInt->eng) { - lbrk++; - pInt = nInt++; - if (lbrk > number-2) { - status = 1; - break; - } - } - while (val > pInt->eng) { - if (lbrk <= 0) { - status = 1; - break; - } - lbrk--; - nInt = pInt--; - } - } - - *plbrk = lbrk; - *pval = pInt->raw + (val - pInt->eng) / pInt->slope; - - return status; -} diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c deleted file mode 100644 index 973a66836..000000000 --- a/src/ioc/db/dbAccess.c +++ /dev/null @@ -1,1346 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbAccess.c */ -/* - * Original Author: Bob Dalesio - * Current Author: Marty Kraimer - * Andrew Johnson - * Ralph Lange - */ - -#include -#include -#include -#include -#include - -#include "alarm.h" -#include "cantProceed.h" -#include "cvtFast.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsMath.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "errMdef.h" - -#define epicsExportSharedSymbols -#include "caeventmask.h" -#include "callback.h" -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbBkpt.h" -#include "dbCommonPvt.h" -#include "dbConvertFast.h" -#include "dbConvert.h" -#include "dbEvent.h" -#include "db_field_log.h" -#include "dbFldTypes.h" -#include "dbFldTypes.h" -#include "dbLink.h" -#include "dbLockPvt.h" -#include "dbNotify.h" -#include "dbScan.h" -#include "dbServer.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "devSup.h" -#include "epicsEvent.h" -#include "link.h" -#include "recGbl.h" -#include "recSup.h" -#include "special.h" - -epicsShareDef struct dbBase *pdbbase = 0; -epicsShareDef volatile int interruptAccept=FALSE; - -/* Hook Routines */ - -epicsShareDef DB_LOAD_RECORDS_HOOK_ROUTINE dbLoadRecordsHook = NULL; - -static short mapDBFToDBR[DBF_NTYPES] = { - /* DBF_STRING => */ DBR_STRING, - /* DBF_CHAR => */ DBR_CHAR, - /* DBF_UCHAR => */ DBR_UCHAR, - /* DBF_SHORT => */ DBR_SHORT, - /* DBF_USHORT => */ DBR_USHORT, - /* DBF_LONG => */ DBR_LONG, - /* DBF_ULONG => */ DBR_ULONG, - /* DBF_INT64 => */ DBR_INT64, - /* DBF_UINT64 => */ DBR_UINT64, - /* DBF_FLOAT => */ DBR_FLOAT, - /* DBF_DOUBLE => */ DBR_DOUBLE, - /* DBF_ENUM, => */ DBR_ENUM, - /* DBF_MENU, => */ DBR_ENUM, - /* DBF_DEVICE => */ DBR_ENUM, - /* DBF_INLINK => */ DBR_STRING, - /* DBF_OUTLINK => */ DBR_STRING, - /* DBF_FWDLINK => */ DBR_STRING, - /* DBF_NOACCESS => */ DBR_NOACCESS -}; - -/* - * The number of consecutive attempts that can be made to process an - * active record before a SCAN_ALARM is raised. Active records - * (records with the pact flag set) cannot be processed until - * that flag becomes unset. - */ -#define MAX_LOCK 10 - -/* The following is to handle SPC_AS */ -static SPC_ASCALLBACK spcAsCallback = 0; - -void dbSpcAsRegisterCallback(SPC_ASCALLBACK func) -{ - spcAsCallback = func; -} - -long dbPutSpecial(DBADDR *paddr,int pass) -{ - long int (*pspecial)()=NULL; - rset *prset; - dbCommon *precord = paddr->precord; - long status=0; - long special=paddr->special; - - prset = dbGetRset(paddr); - if(special<100) { /*global processing*/ - if((special==SPC_NOMOD) && (pass==0)) { - status = S_db_noMod; - recGblDbaddrError(status,paddr,"dbPut"); - return(status); - }else if(special==SPC_SCAN){ - if(pass==0) - scanDelete(precord); - else - scanAdd(precord); - }else if((special==SPC_AS) && (pass==1)) { - if(spcAsCallback) (*spcAsCallback)(precord); - } - }else { - if( prset && (pspecial = (prset->special))) { - status=(*pspecial)(paddr,pass); - if(status) return(status); - } else if(pass==0){ - recGblRecSupError(S_db_noSupport,paddr,"dbPut", "special"); - return(S_db_noSupport); - } - } - return(0); -} - -static void get_enum_strs(DBADDR *paddr, char **ppbuffer, - rset *prset,long *options) -{ - short field_type=paddr->field_type; - dbFldDes *pdbFldDes = paddr->pfldDes; - dbMenu *pdbMenu; - dbDeviceMenu *pdbDeviceMenu; - char **papChoice; - unsigned long no_str; - char *ptemp; - struct dbr_enumStrs *pdbr_enumStrs=(struct dbr_enumStrs*)(*ppbuffer); - unsigned int i; - - memset(pdbr_enumStrs,'\0',dbr_enumStrs_size); - switch(field_type) { - case DBF_ENUM: - if( prset && prset->get_enum_strs ) { - (*prset->get_enum_strs)(paddr,pdbr_enumStrs); - } else { - *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/ - } - break; - case DBF_MENU: - pdbMenu = (dbMenu *)pdbFldDes->ftPvt; - no_str = pdbMenu->nChoice; - papChoice= pdbMenu->papChoiceValue; - goto choice_common; - case DBF_DEVICE: - pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt; - if(!pdbDeviceMenu) { - *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/ - break; - } - no_str = pdbDeviceMenu->nChoice; - papChoice = pdbDeviceMenu->papChoice; - goto choice_common; -choice_common: - i = sizeof(pdbr_enumStrs->strs)/ - sizeof(pdbr_enumStrs->strs[0]); - if(ino_str = no_str; - ptemp = &(pdbr_enumStrs->strs[0][0]); - for (i=0; istrs[0])); - *(ptemp+sizeof(pdbr_enumStrs->strs[0])-1) = 0; - } - ptemp += sizeof(pdbr_enumStrs->strs[0]); - } - break; - default: - *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/ - break; - } - *ppbuffer = ((char *)*ppbuffer) + dbr_enumStrs_size; - return; -} - -static void get_graphics(DBADDR *paddr, char **ppbuffer, - rset *prset,long *options) -{ - struct dbr_grDouble grd; - int got_data=FALSE; - - grd.upper_disp_limit = grd.lower_disp_limit = 0.0; - if( prset && prset->get_graphic_double ) { - (*prset->get_graphic_double)(paddr,&grd); - got_data=TRUE; - } - if( (*options) & (DBR_GR_LONG) ) { - char *pbuffer=*ppbuffer; - - if(got_data) { - struct dbr_grLong *pgr=(struct dbr_grLong*)pbuffer; - pgr->upper_disp_limit = (epicsInt32)grd.upper_disp_limit; - pgr->lower_disp_limit = (epicsInt32)grd.lower_disp_limit; - } else { - memset(pbuffer,'\0',dbr_grLong_size); - *options = (*options) ^ DBR_GR_LONG; /*Turn off option*/ - } - *ppbuffer = ((char *)*ppbuffer) + dbr_grLong_size; - } - if( (*options) & (DBR_GR_DOUBLE) ) { - char *pbuffer=*ppbuffer; - - if(got_data) { - struct dbr_grDouble *pgr=(struct dbr_grDouble*)pbuffer; - pgr->upper_disp_limit = grd.upper_disp_limit; - pgr->lower_disp_limit = grd.lower_disp_limit; - } else { - memset(pbuffer,'\0',dbr_grDouble_size); - *options = (*options) ^ DBR_GR_DOUBLE; /*Turn off option*/ - } - *ppbuffer = ((char *)*ppbuffer) + dbr_grDouble_size; - } - return; -} - -static void get_control(DBADDR *paddr, char **ppbuffer, - rset *prset,long *options) -{ - struct dbr_ctrlDouble ctrld; - int got_data=FALSE; - - ctrld.upper_ctrl_limit = ctrld.lower_ctrl_limit = 0.0; - if( prset && prset->get_control_double ) { - (*prset->get_control_double)(paddr,&ctrld); - got_data=TRUE; - } - if( (*options) & (DBR_CTRL_LONG) ) { - char *pbuffer=*ppbuffer; - - if(got_data) { - struct dbr_ctrlLong *pctrl=(struct dbr_ctrlLong*)pbuffer; - pctrl->upper_ctrl_limit = (epicsInt32)ctrld.upper_ctrl_limit; - pctrl->lower_ctrl_limit = (epicsInt32)ctrld.lower_ctrl_limit; - } else { - memset(pbuffer,'\0',dbr_ctrlLong_size); - *options = (*options) ^ DBR_CTRL_LONG; /*Turn off option*/ - } - *ppbuffer = ((char *)*ppbuffer) + dbr_ctrlLong_size; - } - if( (*options) & (DBR_CTRL_DOUBLE) ) { - char *pbuffer=*ppbuffer; - - if(got_data) { - struct dbr_ctrlDouble *pctrl=(struct dbr_ctrlDouble*)pbuffer; - pctrl->upper_ctrl_limit = ctrld.upper_ctrl_limit; - pctrl->lower_ctrl_limit = ctrld.lower_ctrl_limit; - } else { - memset(pbuffer,'\0',dbr_ctrlDouble_size); - *options = (*options) ^ DBR_CTRL_DOUBLE; /*Turn off option*/ - } - *ppbuffer = ((char *)*ppbuffer) + dbr_ctrlDouble_size; - } - return; -} - -static void get_alarm(DBADDR *paddr, char **ppbuffer, - rset *prset, long *options) -{ - char *pbuffer = *ppbuffer; - struct dbr_alDouble ald = {epicsNAN, epicsNAN, epicsNAN, epicsNAN}; - long no_data = TRUE; - - if (prset && prset->get_alarm_double) - no_data = prset->get_alarm_double(paddr, &ald); - - if (*options & DBR_AL_LONG) { - struct dbr_alLong *pal = (struct dbr_alLong*) pbuffer; - - pal->upper_alarm_limit = (epicsInt32) ald.upper_alarm_limit; - pal->upper_warning_limit = (epicsInt32) ald.upper_warning_limit; - pal->lower_warning_limit = (epicsInt32) ald.lower_warning_limit; - pal->lower_alarm_limit = (epicsInt32) ald.lower_alarm_limit; - - if (no_data) - *options ^= DBR_AL_LONG; /*Turn off option*/ - - *ppbuffer += dbr_alLong_size; - } - if (*options & DBR_AL_DOUBLE) { - struct dbr_alDouble *pal = (struct dbr_alDouble*) pbuffer; - - pal->upper_alarm_limit = ald.upper_alarm_limit; - pal->upper_warning_limit = ald.upper_warning_limit; - pal->lower_warning_limit = ald.lower_warning_limit; - pal->lower_alarm_limit = ald.lower_alarm_limit; - - if (no_data) - *options ^= DBR_AL_DOUBLE; /*Turn off option*/ - - *ppbuffer += dbr_alDouble_size; - } -} - -/* - * This code relies on *poriginal being aligned and all increments done by the - * blocks only changing the buffer pointer in a way that does not break alignment. - */ -static void getOptions(DBADDR *paddr, char **poriginal, long *options, - void *pflin) -{ - db_field_log *pfl= (db_field_log *)pflin; - rset *prset; - short field_type; - dbCommon *pcommon; - char *pbuffer = *poriginal; - - if (!pfl || pfl->type == dbfl_type_rec) - field_type = paddr->field_type; - else - field_type = pfl->field_type; - prset=dbGetRset(paddr); - /* Process options */ - pcommon = paddr->precord; - if( (*options) & DBR_STATUS ) { - unsigned short *pushort = (unsigned short *)pbuffer; - - if (!pfl || pfl->type == dbfl_type_rec) { - *pushort++ = pcommon->stat; - *pushort++ = pcommon->sevr; - } else { - *pushort++ = pfl->stat; - *pushort++ = pfl->sevr; - } - *pushort++ = pcommon->acks; - *pushort++ = pcommon->ackt; - pbuffer = (char *)pushort; - } - if( (*options) & DBR_UNITS ) { - memset(pbuffer,'\0',dbr_units_size); - if( prset && prset->get_units ){ - (*prset->get_units)(paddr, pbuffer); - pbuffer[DB_UNITS_SIZE-1] = '\0'; - } else { - *options ^= DBR_UNITS; /*Turn off DBR_UNITS*/ - } - pbuffer += dbr_units_size; - } - if( (*options) & DBR_PRECISION ) { - memset(pbuffer, '\0', dbr_precision_size); - if((field_type==DBF_FLOAT || field_type==DBF_DOUBLE) - && prset && prset->get_precision ){ - (*prset->get_precision)(paddr,(long *)pbuffer); - } else { - *options ^= DBR_PRECISION; /*Turn off DBR_PRECISION*/ - } - pbuffer += dbr_precision_size; - } - if( (*options) & DBR_TIME ) { - epicsUInt32 *ptime = (epicsUInt32 *)pbuffer; - - if (!pfl || pfl->type == dbfl_type_rec) { - *ptime++ = pcommon->time.secPastEpoch; - *ptime++ = pcommon->time.nsec; - } else { - *ptime++ = pfl->time.secPastEpoch; - *ptime++ = pfl->time.nsec; - } - pbuffer = (char *)ptime; - } - if( (*options) & DBR_ENUM_STRS ) - get_enum_strs(paddr, &pbuffer, prset, options); - if( (*options) & (DBR_GR_LONG|DBR_GR_DOUBLE )) - get_graphics(paddr, &pbuffer, prset, options); - if((*options) & (DBR_CTRL_LONG | DBR_CTRL_DOUBLE )) - get_control(paddr, &pbuffer, prset, options); - if((*options) & (DBR_AL_LONG | DBR_AL_DOUBLE )) - get_alarm(paddr, &pbuffer, prset, options); - *poriginal = pbuffer; -} - -rset * dbGetRset(const struct dbAddr *paddr) -{ - struct dbFldDes *pfldDes = paddr->pfldDes; - - if(!pfldDes) return(0); - return(pfldDes->pdbRecordType->prset); -} - -long dbPutAttribute( - const char *recordTypename, const char *name, const char *value) -{ - DBENTRY dbEntry; - DBENTRY *pdbEntry = &dbEntry; - long status = 0; - - if (!pdbbase) - return S_db_notFound; - if (!name) { - status = S_db_badField; - goto done; - } - if (!value) - value = ""; - dbInitEntry(pdbbase, pdbEntry); - status = dbFindRecordType(pdbEntry, recordTypename); - if (!status) - status = dbPutRecordAttribute(pdbEntry, name, value); - dbFinishEntry(pdbEntry); -done: - if (status) - errMessage(status, "dbPutAttribute failure"); - return status; -} - -int dbIsValueField(const struct dbFldDes *pdbFldDes) -{ - if (pdbFldDes->pdbRecordType->indvalFlddes == pdbFldDes->indRecordType) - return TRUE; - else - return FALSE; -} - -int dbGetFieldIndex(const struct dbAddr *paddr) -{ - return paddr->pfldDes->indRecordType; -} - -/* - * Process a record if its scan field is passive. - * Will notify if processing is complete by callback. - * (only if you are interested in completion) - */ -long dbScanPassive(dbCommon *pfrom, dbCommon *pto) -{ - /* if not passive just return success */ - if (pto->scan != 0) - return 0; - - if (pfrom && pfrom->ppn) - dbNotifyAdd(pfrom,pto); - return dbProcess(pto); -} - -/* - * Process the record. - * 1. Check for breakpoints. - * 2. Check the process active flag (PACT). - * 3. Check the disable link. - * 4. Check the RSET (record support entry table) exists. - * 5. Run the process routine specific to the record type. - * 6. Check to see if record contents should be automatically printed. - */ -long dbProcess(dbCommon *precord) -{ - rset *prset = precord->rset; - dbRecordType *pdbRecordType = precord->rdes; - unsigned char tpro = precord->tpro; - char context[40] = ""; - long status = 0; - int *ptrace; - int set_trace = FALSE; - dbFldDes *pdbFldDes; - int callNotifyCompletion = FALSE; - - ptrace = dbLockSetAddrTrace(precord); - /* - * Note that it is likely that if any changes are made - * to dbProcess() corresponding changes will have to - * be made in the breakpoint handler. - */ - - /* see if there are any stopped records or breakpoints */ - if (lset_stack_count != 0) { - /* - * Check to see if the record should be processed - * and activate breakpoint accordingly. If this - * function call returns non-zero, skip record - * support and fall out of dbProcess(). This is - * done so that a dbContTask() can be spawned to - * take over record processing for the lock set - * containing a breakpoint. - */ - if (dbBkpt(precord)) - goto all_done; - } - - /* check for trace processing*/ - if (tpro) { - if (!*ptrace) { - *ptrace = 1; - set_trace = TRUE; - } - } - - if (*ptrace) { - /* Identify this thread's client from server layer */ - if (dbServerClient(context, sizeof(context))) { - /* No client, use thread name */ - strncpy(context, epicsThreadGetNameSelf(), sizeof(context)); - context[sizeof(context) - 1] = 0; - } - } - - /* If already active dont process */ - if (precord->pact) { - unsigned short monitor_mask; - - if (*ptrace) - printf("%s: Active %s\n", context, precord->name); - - /* raise scan alarm after MAX_LOCK times */ - if ((precord->stat == SCAN_ALARM) || - (precord->lcnt++ < MAX_LOCK) || - (precord->sevr >= INVALID_ALARM)) goto all_done; - - recGblSetSevr(precord, SCAN_ALARM, INVALID_ALARM); - monitor_mask = recGblResetAlarms(precord); - monitor_mask |= DBE_VALUE|DBE_LOG; - pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->indvalFlddes]; - db_post_events(precord, - (void *)(((char *)precord) + pdbFldDes->offset), - monitor_mask); - goto all_done; - } - else - precord->lcnt = 0; - - /* - * Check the record disable link. A record will not be - * processed if the value retrieved through this link - * is equal to constant set in the record's disv field. - */ - status = dbGetLink(&precord->sdis, DBR_SHORT, &precord->disa, 0, 0); - - /* if disabled check disable alarm severity and return success */ - if (precord->disa == precord->disv) { - if (*ptrace) - printf("%s: Disabled %s\n", context, precord->name); - - /*take care of caching and notifyCompletion*/ - precord->rpro = FALSE; - precord->putf = FALSE; - callNotifyCompletion = TRUE; - - /* raise disable alarm */ - if (precord->stat == DISABLE_ALARM) - goto all_done; - - precord->sevr = precord->diss; - precord->stat = DISABLE_ALARM; - precord->nsev = 0; - precord->nsta = 0; - db_post_events(precord, &precord->stat, DBE_VALUE); - db_post_events(precord, &precord->sevr, DBE_VALUE); - pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->indvalFlddes]; - db_post_events(precord, - (void *)(((char *)precord) + pdbFldDes->offset), - DBE_VALUE|DBE_ALARM); - goto all_done; - } - - /* locate record processing routine */ - /* FIXME: put this in iocInit() !!! */ - if (!prset || !prset->process) { - callNotifyCompletion = TRUE; - precord->pact = 1;/*set pact so error is issued only once*/ - recGblRecordError(S_db_noRSET, (void *)precord, "dbProcess"); - status = S_db_noRSET; - if (*ptrace) - printf("%s: No RSET for %s\n", context, precord->name); - goto all_done; - } - - if (*ptrace) - printf("%s: Process %s\n", context, precord->name); - - /* process record */ - status = prset->process(precord); - - /* Print record's fields if PRINT_MASK set in breakpoint field */ - if (lset_stack_count != 0) { - dbPrint(precord); - } - -all_done: - if (set_trace) - *ptrace = 0; - if (callNotifyCompletion && precord->ppn) - dbNotifyCompletion(precord); - - return status; -} - -/* - * Fill out a database structure (*paddr) for - * a record given by the name "pname." - * - * Returns error codes from StaticLib module, not - * from dbAccess. - */ -long dbNameToAddr(const char *pname, DBADDR *paddr) -{ - DBENTRY dbEntry; - dbFldDes *pflddes; - long status = 0; - short dbfType; - - if (!pname || !*pname || !pdbbase) - return S_db_notFound; - - dbInitEntry(pdbbase, &dbEntry); - status = dbFindRecordPart(&dbEntry, &pname); - if (status) goto finish; - - if (*pname == '.') ++pname; - status = dbFindFieldPart(&dbEntry, &pname); - if (status == S_dbLib_fieldNotFound) - status = dbGetAttributePart(&dbEntry, &pname); - if (status) goto finish; - - pflddes = dbEntry.pflddes; - dbfType = pflddes->field_type; - - paddr->precord = dbEntry.precnode->precord; - paddr->pfield = dbEntry.pfield; - paddr->pfldDes = pflddes; - paddr->no_elements = 1; - paddr->field_type = dbfType; - paddr->field_size = pflddes->size; - paddr->special = pflddes->special; - paddr->dbr_field_type = mapDBFToDBR[dbfType]; - - if (paddr->special == SPC_DBADDR) { - rset *prset = dbGetRset(paddr); - - /* Let record type modify paddr */ - if (prset && prset->cvt_dbaddr) { - status = prset->cvt_dbaddr(paddr); - if (status) - goto finish; - dbfType = paddr->field_type; - } - } - - /* Handle field modifiers */ - if (*pname++ == '$') { - /* Some field types can be accessed as char arrays */ - if (dbfType == DBF_STRING) { - paddr->no_elements = paddr->field_size; - paddr->field_type = DBF_CHAR; - paddr->field_size = 1; - paddr->dbr_field_type = DBR_CHAR; - } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { - /* Clients see a char array, but keep original dbfType */ - paddr->no_elements = PVLINK_STRINGSZ; - paddr->field_size = 1; - paddr->dbr_field_type = DBR_CHAR; - } else { - status = S_dbLib_fieldNotFound; - goto finish; - } - } - -finish: - dbFinishEntry(&dbEntry); - return status; -} - -void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry) -{ - struct dbCommon *prec = paddr->precord; - dbCommonPvt *ppvt = CONTAINER(prec, dbCommonPvt, common); - - memset((char *)pdbentry,'\0',sizeof(DBENTRY)); - - pdbentry->pdbbase = pdbbase; - pdbentry->precordType = prec->rdes; - pdbentry->precnode = ppvt->recnode; - pdbentry->pflddes = paddr->pfldDes; - pdbentry->pfield = paddr->pfield; - pdbentry->indfield = paddr->pfldDes->indRecordType; -} - -void dbInitEntryFromRecord(struct dbCommon *prec, DBENTRY *pdbentry) -{ - dbCommonPvt *ppvt = CONTAINER(prec, dbCommonPvt, common); - - memset((char *)pdbentry,'\0',sizeof(DBENTRY)); - - pdbentry->pdbbase = pdbbase; - pdbentry->precordType = prec->rdes; - pdbentry->precnode = ppvt->recnode; -} - -long dbValueSize(short dbr_type) -{ - /* sizes for value associated with each DBR request type */ - static long size[] = { - MAX_STRING_SIZE, /* STRING */ - sizeof(epicsInt8), /* CHAR */ - sizeof(epicsUInt8), /* UCHAR */ - sizeof(epicsInt16), /* SHORT */ - sizeof(epicsUInt16), /* USHORT */ - sizeof(epicsInt32), /* LONG */ - sizeof(epicsUInt32), /* ULONG */ - sizeof(epicsInt64), /* INT64 */ - sizeof(epicsUInt64), /* UINT64 */ - sizeof(epicsFloat32), /* FLOAT */ - sizeof(epicsFloat64), /* DOUBLE */ - sizeof(epicsEnum16)}; /* ENUM */ - - return(size[dbr_type]); -} - - -long dbBufferSize(short dbr_type, long options, long no_elements) -{ - long nbytes=0; - - nbytes += dbValueSize(dbr_type) * no_elements; - if (options & DBR_STATUS) nbytes += dbr_status_size; - if (options & DBR_UNITS) nbytes += dbr_units_size; - if (options & DBR_PRECISION) nbytes += dbr_precision_size; - if (options & DBR_TIME) nbytes += dbr_time_size; - if (options & DBR_ENUM_STRS) nbytes += dbr_enumStrs_size; - if (options & DBR_GR_LONG) nbytes += dbr_grLong_size; - if (options & DBR_GR_DOUBLE) nbytes += dbr_grDouble_size; - if (options & DBR_CTRL_LONG) nbytes += dbr_ctrlLong_size; - if (options & DBR_CTRL_DOUBLE) nbytes += dbr_ctrlDouble_size; - if (options & DBR_AL_LONG) nbytes += dbr_alLong_size; - if (options & DBR_AL_DOUBLE) nbytes += dbr_alDouble_size; - return(nbytes); -} -int dbLoadDatabase(const char *file, const char *path, const char *subs) -{ - return dbReadDatabase(&pdbbase, file, path, subs); -} - -int dbLoadRecords(const char* file, const char* subs) -{ - int status = dbReadDatabase(&pdbbase, file, 0, subs); - - if (!status && dbLoadRecordsHook) - dbLoadRecordsHook(file, subs); - return status; -} - - -static long getLinkValue(DBADDR *paddr, short dbrType, - char *pbuf, long *nRequest) -{ - dbCommon *precord = paddr->precord; - dbFldDes *pfldDes = paddr->pfldDes; - /* size of pbuf storage in bytes, including space for trailing nil */ - int maxlen; - DBENTRY dbEntry; - long status; - long nReq = nRequest ? *nRequest : 1; - - /* dbFindRecord() below will always succeed as we have a - * valid DBADDR, so no point to check again. - * Request for zero elements always succeeds - */ - if(!nReq) - return 0; - - switch (dbrType) { - case DBR_STRING: - maxlen = MAX_STRING_SIZE; - nReq = 1; - break; - - case DBR_DOUBLE: /* Needed for dbCa links */ - if (nRequest) *nRequest = 1; - *(double *)pbuf = epicsNAN; - return 0; - - case DBR_CHAR: - case DBR_UCHAR: - maxlen = nReq; - break; - default: - return S_db_badDbrtype; - } - - dbInitEntry(pdbbase, &dbEntry); - status = dbFindRecord(&dbEntry, precord->name); - if (!status) status = dbFindField(&dbEntry, pfldDes->name); - if (!status) { - const char *rtnString = dbGetString(&dbEntry); - - strncpy(pbuf, rtnString, maxlen-1); - pbuf[maxlen-1] = 0; - if(dbrType!=DBR_STRING) - nReq = strlen(pbuf)+1; - if(nRequest) *nRequest = nReq; - } - dbFinishEntry(&dbEntry); - return status; -} - -static long getAttrValue(DBADDR *paddr, short dbrType, - char *pbuf, long *nRequest) -{ - int maxlen; - long nReq = nRequest ? *nRequest : 1; - - if (!paddr->pfield) return S_db_badField; - - switch (dbrType) { - case DBR_STRING: - maxlen = MAX_STRING_SIZE; - nReq = 1; - break; - - case DBR_CHAR: - case DBR_UCHAR: - maxlen = nReq; - break; - - /* else fall through ... */ - default: - return S_db_badDbrtype; - } - - strncpy(pbuf, paddr->pfield, maxlen-1); - pbuf[maxlen-1] = 0; - if(dbrType!=DBR_STRING) - nReq = strlen(pbuf)+1; - if(nRequest) *nRequest = nReq; - return 0; -} - -long dbGetField(DBADDR *paddr,short dbrType, - void *pbuffer, long *options, long *nRequest, void *pflin) -{ - dbCommon *precord = paddr->precord; - long status = 0; - - dbScanLock(precord); - status = dbGet(paddr, dbrType, pbuffer, options, nRequest, pflin); - dbScanUnlock(precord); - return status; -} - -long dbGet(DBADDR *paddr, short dbrType, - void *pbuffer, long *options, long *nRequest, void *pflin) -{ - char *pbuf = pbuffer; - void *pfieldsave = paddr->pfield; - db_field_log *pfl = (db_field_log *)pflin; - short field_type; - long capacity, no_elements, offset; - rset *prset; - long status = 0; - - if (options && *options) - getOptions(paddr, &pbuf, options, pflin); - if (nRequest && *nRequest == 0) - return 0; - - if (!pfl || pfl->type == dbfl_type_rec) { - field_type = paddr->field_type; - no_elements = capacity = paddr->no_elements; - - /* Update field info from record - * may modify paddr->pfield - */ - if (paddr->pfldDes->special == SPC_DBADDR && - (prset = dbGetRset(paddr)) && - prset->get_array_info) { - status = prset->get_array_info(paddr, &no_elements, &offset); - } else - offset = 0; - } else { - field_type = pfl->field_type; - no_elements = capacity = pfl->no_elements; - offset = 0; - } - - if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) { - status = getLinkValue(paddr, dbrType, pbuf, nRequest); - goto done; - } - - if (paddr->special == SPC_ATTRIBUTE) { - status = getAttrValue(paddr, dbrType, pbuf, nRequest); - goto done; - } - - /* Check for valid request */ - if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) { - char message[80]; - - sprintf(message, "dbGet: Request type is %d\n", dbrType); - recGblDbaddrError(S_db_badDbrtype, paddr, message); - status = S_db_badDbrtype; - goto done; - } - - if (offset == 0 && (!nRequest || no_elements == 1)) { - if (nRequest) - *nRequest = 1; - if (!pfl || pfl->type == dbfl_type_rec) { - status = dbFastGetConvertRoutine[field_type][dbrType] - (paddr->pfield, pbuf, paddr); - } else { - DBADDR localAddr = *paddr; /* Structure copy */ - - localAddr.field_type = pfl->field_type; - localAddr.field_size = pfl->field_size; - localAddr.no_elements = pfl->no_elements; - if (pfl->type == dbfl_type_val) - localAddr.pfield = (char *) &pfl->u.v.field; - else - localAddr.pfield = (char *) pfl->u.r.field; - status = dbFastGetConvertRoutine[field_type][dbrType] - (localAddr.pfield, pbuf, &localAddr); - } - } else { - long n; - GETCONVERTFUNC convert; - - if (nRequest) { - if (no_elements < *nRequest) - *nRequest = no_elements; - n = *nRequest; - } else { - n = 1; - } - convert = dbGetConvertRoutine[field_type][dbrType]; - if (!convert) { - char message[80]; - - sprintf(message, "dbGet: Missing conversion for [%d][%d]\n", - field_type, dbrType); - recGblDbaddrError(S_db_badDbrtype, paddr, message); - status = S_db_badDbrtype; - goto done; - } - /* convert data into the caller's buffer */ - if (n <= 0) { - ;/*do nothing*/ - } else if (!pfl || pfl->type == dbfl_type_rec) { - status = convert(paddr, pbuf, n, capacity, offset); - } else { - DBADDR localAddr = *paddr; /* Structure copy */ - - localAddr.field_type = pfl->field_type; - localAddr.field_size = pfl->field_size; - localAddr.no_elements = pfl->no_elements; - if (pfl->type == dbfl_type_val) - localAddr.pfield = (char *) &pfl->u.v.field; - else - localAddr.pfield = (char *) pfl->u.r.field; - status = convert(&localAddr, pbuf, n, capacity, offset); - } - - if(!status && dbrType==DBF_CHAR && nRequest && - paddr->pfldDes && paddr->pfldDes->field_type==DBF_STRING) - { - /* long string ensure nil and truncate to actual length */ - long nReq = *nRequest; - pbuf[nReq-1] = '\0'; - *nRequest = strlen(pbuf)+1; - } - } -done: - paddr->pfield = pfieldsave; - return status; -} - -devSup* dbDTYPtoDevSup(dbRecordType *prdes, int dtyp) { - return (devSup *)ellNth(&prdes->devList, dtyp+1); -} - -devSup* dbDSETtoDevSup(dbRecordType *prdes, struct dset *pdset) { - devSup *pdevSup = (devSup *)ellFirst(&prdes->devList); - while (pdevSup) { - if (pdset == pdevSup->pdset) return pdevSup; - pdevSup = (devSup *)ellNext(&pdevSup->node); - } - return NULL; -} - -static long dbPutFieldLink(DBADDR *paddr, - short dbrType, const void *pbuffer, long nRequest) -{ - dbLinkInfo link_info; - DBADDR *pdbaddr = NULL; - dbCommon *precord = paddr->precord; - dbCommon *lockrecs[2]; - dbLocker locker; - dbFldDes *pfldDes = paddr->pfldDes; - long special = paddr->special; - struct link *plink = (struct link *)paddr->pfield; - const char *pstring = (const char *)pbuffer; - struct dsxt *old_dsxt = NULL; - struct dset *new_dset = NULL; - struct dsxt *new_dsxt = NULL; - devSup *new_devsup = NULL; - long status; - int isDevLink; - short scan; - - STATIC_ASSERT(DBLOCKER_NALLOC>=2); - - switch (dbrType) { - case DBR_CHAR: - case DBR_UCHAR: - if (pstring[nRequest - 1] != '\0') - return S_db_badDbrtype; - break; - - case DBR_STRING: - break; - - default: - return S_db_badDbrtype; - } - - status = dbParseLink(pstring, pfldDes->field_type, &link_info, 0); - if (status) - return status; - - if (link_info.ltype == PV_LINK && - (link_info.modifiers & (pvlOptCA | pvlOptCP | pvlOptCPP)) == 0) { - DBADDR tempaddr; - - if (dbNameToAddr(link_info.target, &tempaddr)==0) { - /* This will become a DB link. */ - pdbaddr = malloc(sizeof(*pdbaddr)); - if (!pdbaddr) { - status = S_db_noMemory; - goto cleanup; - } - *pdbaddr = tempaddr; /* struct copy */ - } - } - - isDevLink = ellCount(&precord->rdes->devList) > 0 && - pfldDes->isDevLink; - - memset(&locker, 0, sizeof(locker)); - lockrecs[0] = precord; - lockrecs[1] = pdbaddr ? pdbaddr->precord : NULL; - dbLockerPrepare(&locker, lockrecs, 2); - - dbScanLockMany(&locker); - - scan = precord->scan; - - if (isDevLink) { - new_devsup = dbDTYPtoDevSup(precord->rdes, precord->dtyp); - if (new_devsup) { - new_dset = new_devsup->pdset; - new_dsxt = new_devsup->pdsxt; - } - } - - if (dbCanSetLink(plink, &link_info, new_devsup)) { - /* link type mis-match prevents assignment */ - status = S_dbLib_badField; - goto unlock; - } - - if (isDevLink) { - if (precord->dset) { - devSup *old_devsup = dbDSETtoDevSup(precord->rdes, precord->dset); - - if (old_devsup) - old_dsxt = old_devsup->pdsxt; - } - - if (new_dsxt == NULL || - new_dsxt->add_record == NULL || - (precord->dset && old_dsxt == NULL) || - (old_dsxt && old_dsxt->del_record == NULL)) { - status = S_db_noSupport; - goto unlock; - } - - if (scan == menuScanI_O_Intr) { - scanDelete(precord); - precord->scan = menuScanPassive; - } - - if (old_dsxt) { - status = old_dsxt->del_record(precord); - if (status) - goto restoreScan; - } - } - - if (dbLinkIsDefined(plink)) { - dbRemoveLink(&locker, plink); /* Clear out old link */ - } - else if (!isDevLink) { - status = S_db_badHWaddr; - goto restoreScan; - } - - if (special) status = dbPutSpecial(paddr, 0); - - if (!status) status = dbSetLink(plink, &link_info, new_devsup); - - if (!status && special) status = dbPutSpecial(paddr, 1); - - if (status) { - if (isDevLink) { - precord->dset = NULL; - precord->pact = TRUE; - } - goto postScanEvent; - } - - if (isDevLink) { - precord->dpvt = NULL; - precord->dset = new_dset; - precord->pact = FALSE; - - status = new_dsxt->add_record(precord); - if (status) { - precord->dset = NULL; - precord->pact = TRUE; - goto postScanEvent; - } - } - - switch (plink->type) { /* New link type */ - case PV_LINK: - case CONSTANT: - case JSON_LINK: - dbAddLink(&locker, plink, pfldDes->field_type, pdbaddr); - break; - - case DB_LINK: - case CA_LINK: - case MACRO_LINK: - break; /* should never get here */ - - default: /* Hardware address */ - if (!isDevLink) { - status = S_db_badHWaddr; - goto postScanEvent; - } - break; - } - db_post_events(precord, plink, DBE_VALUE | DBE_LOG); - -restoreScan: - if (isDevLink && - scan == menuScanI_O_Intr) { /* undo scanDelete() */ - precord->scan = scan; - scanAdd(precord); - } -postScanEvent: - if (scan != precord->scan) - db_post_events(precord, &precord->scan, DBE_VALUE | DBE_LOG); -unlock: - dbScanUnlockMany(&locker); - dbLockerFinalize(&locker); -cleanup: - free(link_info.target); - return status; -} - -long dbPutField(DBADDR *paddr, short dbrType, - const void *pbuffer, long nRequest) -{ - long status = 0; - long special = paddr->special; - dbFldDes *pfldDes = paddr->pfldDes; - dbCommon *precord = paddr->precord; - short dbfType = paddr->field_type; - - if (special == SPC_ATTRIBUTE) - return S_db_noMod; - - /*check for putField disabled*/ - if (precord->disp && paddr->pfield != &precord->disp) - return S_db_putDisabled; - - if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) - return dbPutFieldLink(paddr, dbrType, pbuffer, nRequest); - - dbScanLock(precord); - status = dbPut(paddr, dbrType, pbuffer, nRequest); - if (status == 0) { - if (paddr->pfield == &precord->proc || - (pfldDes->process_passive && - precord->scan == 0 && - dbrType < DBR_PUT_ACKT)) { - if (precord->pact) { - if (precord->tpro) - printf("%s: Active %s\n", - epicsThreadGetNameSelf(), precord->name); - precord->rpro = TRUE; - } else { - /* indicate that dbPutField called dbProcess */ - precord->putf = TRUE; - status = dbProcess(precord); - } - } - } - dbScanUnlock(precord); - return status; -} - -static long putAckt(DBADDR *paddr, const void *pbuffer, long nRequest, - long no_elements, long offset) -{ - dbCommon *precord = paddr->precord; - const unsigned short *ptrans = pbuffer; - - if (*ptrans == precord->ackt) return 0; - precord->ackt = *ptrans; - db_post_events(precord, &precord->ackt, DBE_VALUE | DBE_ALARM); - if (!precord->ackt && - precord->acks > precord->sevr) { - precord->acks = precord->sevr; - db_post_events(precord, &precord->acks, DBE_VALUE | DBE_ALARM); - } - db_post_events(precord, NULL, DBE_ALARM); - return 0; -} - -static long putAcks(DBADDR *paddr, const void *pbuffer, long nRequest, - long no_elements, long offset) -{ - dbCommon *precord = paddr->precord; - const unsigned short *psev = pbuffer; - - if (*psev >= precord->acks) { - precord->acks = 0; - db_post_events(precord, &precord->acks, DBE_VALUE | DBE_ALARM); - db_post_events(precord, NULL, DBE_ALARM); - } - return 0; -} - -long dbPut(DBADDR *paddr, short dbrType, - const void *pbuffer, long nRequest) -{ - dbCommon *precord = paddr->precord; - short field_type = paddr->field_type; - long no_elements = paddr->no_elements; - long special = paddr->special; - void *pfieldsave = paddr->pfield; - rset *prset = dbGetRset(paddr); - long status = 0; - long offset; - dbFldDes *pfldDes; - int isValueField; - - if (special == SPC_ATTRIBUTE) - return S_db_noMod; - - if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) { - return putAckt(paddr, pbuffer, 1, 1, 0); - } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) { - return putAcks(paddr, pbuffer, 1, 1, 0); - } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) { - char message[80]; - - sprintf(message, "dbPut: Request type is %d", dbrType); - recGblDbaddrError(S_db_badDbrtype, paddr, message); - return S_db_badDbrtype; - } - - if (special) { - status = dbPutSpecial(paddr, 0); - if (status) return status; - } - - if (paddr->pfldDes->special == SPC_DBADDR && - prset && prset->get_array_info) { - long dummy; - - status = prset->get_array_info(paddr, &dummy, &offset); - /* paddr->pfield may be modified */ - if (status) goto done; - } else - offset = 0; - - if (no_elements <= 1) { - status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer, - paddr->pfield, paddr); - nRequest = 1; - } else { - if (no_elements < nRequest) - nRequest = no_elements; - status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer, - nRequest, no_elements, offset); - } - - /* update array info */ - if (!status && - paddr->pfldDes->special == SPC_DBADDR && - prset && prset->put_array_info) { - status = prset->put_array_info(paddr, nRequest); - } - - /* Always do special processing if needed */ - if (special) { - long status2 = dbPutSpecial(paddr, 1); - if (status2) goto done; - } - if (status) goto done; - - /* Propagate monitor events for this field, */ - /* unless the field is VAL and PP is true. */ - pfldDes = paddr->pfldDes; - isValueField = dbIsValueField(pfldDes); - if (isValueField) precord->udf = FALSE; - if (precord->mlis.count && - !(isValueField && pfldDes->process_passive)) - db_post_events(precord, pfieldsave, DBE_VALUE | DBE_LOG); - /* If this field is a property (metadata) field, - * then post a property change event (even if the field - * didn't change). - */ - if (precord->mlis.count && pfldDes->prop) - db_post_events(precord, NULL, DBE_PROPERTY); -done: - paddr->pfield = pfieldsave; - return status; -} - diff --git a/src/ioc/db/dbAccess.h b/src/ioc/db/dbAccess.h deleted file mode 100644 index 96246b302..000000000 --- a/src/ioc/db/dbAccess.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbAccess.h */ - -#ifndef INCdbAccessh -#define INCdbAccessh - -#include "dbDefs.h" -#include "epicsTime.h" -#include "caeventmask.h" -#include "dbFldTypes.h" -#include "link.h" -#include "dbBase.h" -#include "shareLib.h" -#include "dbAddr.h" -#include "dbLock.h" -#include "dbAccessDefs.h" -#include "dbLink.h" -#include "dbCa.h" -#include "dbCommon.h" -#include "db_field_log.h" - -#endif /*INCdbAccessh*/ diff --git a/src/ioc/db/dbAccessDefs.h b/src/ioc/db/dbAccessDefs.h deleted file mode 100644 index cc45b17fe..000000000 --- a/src/ioc/db/dbAccessDefs.h +++ /dev/null @@ -1,252 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbAccessDefs.h */ - -#ifndef INCdbAccessDefsh -#define INCdbAccessDefsh - -#ifdef epicsExportSharedSymbols -# define INCLdb_accessh_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "epicsTypes.h" -#include "epicsTime.h" -#include "dbBase.h" -#include "dbAddr.h" -#include "recSup.h" - -#ifdef INCLdb_accessh_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -epicsShareExtern struct dbBase *pdbbase; -epicsShareExtern volatile int interruptAccept; - -/* The database field and request types are defined in dbFldTypes.h*/ -/* Data Base Request Options */ -#define DBR_STATUS 0x00000001 -#define DBR_UNITS 0x00000002 -#define DBR_PRECISION 0x00000004 -#define DBR_TIME 0x00000008 -#define DBR_ENUM_STRS 0x00000010 -#define DBR_GR_LONG 0x00000020 -#define DBR_GR_DOUBLE 0x00000040 -#define DBR_CTRL_LONG 0x00000080 -#define DBR_CTRL_DOUBLE 0x00000100 -#define DBR_AL_LONG 0x00000200 -#define DBR_AL_DOUBLE 0x00000400 - -/********************************************************************** - * The next page contains macros for defining requests. - * As an example the following defines a buffer to accept an array - * of 10 float values + DBR_STATUS and DBR_TIME options - * - * struct { - * DBRstatus - * DBRtime - * epicsFloat32 value[10] - * } buffer; - * - * IMPORTANT!! The DBRoptions must be given in the order that they - * appear in the Data Base Request Options #defines - * - * The associated dbGetField call is: - * - * long options,number_elements; - * ... - * options = DBR_STATUS|DBR_TIME; - * number_elements = 10; - * rtnval=dbGetField(paddr,DBR_FLOAT,&buffer,&options,&number_elements); - * - * When dbGetField returns: - * rtnval is error status (0 means success) - * options has a bit set for each option that was accepted - * number_elements is actual number of elements obtained - * - * The individual items can be refered to by the expressions:: - * - * buffer.status - * buffer.severity - * buffer.err_status - * buffer.epoch_seconds - * buffer.nano_seconds - * buffer.value[i] - * - * The following is also a valid declaration: - * - * typedef struct { - * DBRstatus - * DBRtime - * epicsFloat32 value[10] - * } MYBUFFER; - * - * With this definition you can give definitions such as the following: - * - * MYBUFFER *pbuf1; - * MYBUFFER buf; - *************************************************************************/ - -/* Macros for defining each option */ -#define DBRstatus \ - epicsUInt16 status; /* alarm status */\ - epicsUInt16 severity; /* alarm severity*/\ - epicsUInt16 acks; /* alarm ack severity*/\ - epicsUInt16 ackt; /* Acknowledge transient alarms?*/ -#define DB_UNITS_SIZE 16 -#define DBRunits \ - char units[DB_UNITS_SIZE]; /* units */ -#define DBRprecision union { \ - long dp; /* number of decimal places*/\ - double unused; /* for alignment */\ - } precision; - /* precision.dp must be long to match the pointer arguments to - * RSET->get_precision() and recGblGetPrec(), which it's - * too late to change now. DBRprecision must be padded to - * maintain 8-byte alignment. */ -#define DBRtime \ - epicsTimeStamp time; /* time stamp*/ -#define DBRenumStrs \ - epicsUInt32 no_str; /* number of strings*/\ - epicsInt32 padenumStrs; /*padding to force 8 byte align*/\ - char strs[DB_MAX_CHOICES][MAX_STRING_SIZE]; /* string values */ -#define DBRgrLong \ - epicsInt32 upper_disp_limit; /*upper limit of graph*/\ - epicsInt32 lower_disp_limit; /*lower limit of graph*/ -#define DBRgrDouble \ - epicsFloat64 upper_disp_limit; /*upper limit of graph*/\ - epicsFloat64 lower_disp_limit; /*lower limit of graph*/ -#define DBRctrlLong \ - epicsInt32 upper_ctrl_limit; /*upper limit of graph*/\ - epicsInt32 lower_ctrl_limit; /*lower limit of graph*/ -#define DBRctrlDouble \ - epicsFloat64 upper_ctrl_limit; /*upper limit of graph*/\ - epicsFloat64 lower_ctrl_limit; /*lower limit of graph*/ -#define DBRalLong \ - epicsInt32 upper_alarm_limit;\ - epicsInt32 upper_warning_limit;\ - epicsInt32 lower_warning_limit;\ - epicsInt32 lower_alarm_limit; -#define DBRalDouble \ - epicsFloat64 upper_alarm_limit;\ - epicsFloat64 upper_warning_limit;\ - epicsFloat64 lower_warning_limit;\ - epicsFloat64 lower_alarm_limit; - -/* structures for each option type */ -struct dbr_status {DBRstatus}; -struct dbr_units {DBRunits}; -struct dbr_precision {DBRprecision}; -struct dbr_time {DBRtime}; -struct dbr_enumStrs {DBRenumStrs}; -struct dbr_grLong {DBRgrLong}; -struct dbr_grDouble {DBRgrDouble}; -struct dbr_ctrlLong {DBRctrlLong}; -struct dbr_ctrlDouble {DBRctrlDouble}; -struct dbr_alLong {DBRalLong}; -struct dbr_alDouble {DBRalDouble}; -/* sizes for each option structure */ -#define dbr_status_size sizeof(struct dbr_status) -#define dbr_units_size sizeof(struct dbr_units) -#define dbr_precision_size sizeof(struct dbr_precision) -#define dbr_time_size sizeof(struct dbr_time) -#define dbr_enumStrs_size sizeof(struct dbr_enumStrs) -#define dbr_grLong_size sizeof(struct dbr_grLong) -#define dbr_grDouble_size sizeof(struct dbr_grDouble) -#define dbr_ctrlLong_size sizeof(struct dbr_ctrlLong) -#define dbr_ctrlDouble_size sizeof(struct dbr_ctrlDouble) -#define dbr_alLong_size sizeof(struct dbr_alLong) -#define dbr_alDouble_size sizeof(struct dbr_alDouble) - -#ifndef INCerrMdefh -#include "errMdef.h" -#endif -#define S_db_notFound (M_dbAccess| 1) /*Process Variable Not Found*/ -#define S_db_badDbrtype (M_dbAccess| 3) /*Illegal Database Request Type*/ -#define S_db_noMod (M_dbAccess| 5) /*Attempt to modify noMod field*/ -#define S_db_badLset (M_dbAccess| 7) /*Illegal Lock Set*/ -#define S_db_precision (M_dbAccess| 9) /*get precision failed */ -#define S_db_onlyOne (M_dbAccess|11) /*Only one element allowed*/ -#define S_db_badChoice (M_dbAccess|13) /*Illegal choice*/ -#define S_db_badField (M_dbAccess|15) /*Illegal field value*/ -#define S_db_lsetLogic (M_dbAccess|17) /*Logic error generating lock sets*/ -#define S_db_noLSET (M_dbAccess|21) /*No link support table or entry*/ -#define S_db_noRSET (M_dbAccess|31) /*missing record support entry table*/ -#define S_db_noSupport (M_dbAccess|33) /*RSET or DSXT routine not defined*/ -#define S_db_BadSub (M_dbAccess|35) /*Subroutine not found*/ -/*!!!! Do not change next line without changing src/rsrv/server.h!!!!!!!!*/ -#define S_db_Pending (M_dbAccess|37) /*Request is pending*/ - -#define S_db_Blocked (M_dbAccess|39) /*Request is Blocked*/ -#define S_db_putDisabled (M_dbAccess|41) /*putFields are disabled*/ -#define S_db_badHWaddr (M_dbAccess|43) /*Hardware link type not on INP/OUT*/ -#define S_db_bkptSet (M_dbAccess|53) /*Breakpoint already set*/ -#define S_db_bkptNotSet (M_dbAccess|55) /*No breakpoint set in record*/ -#define S_db_notStopped (M_dbAccess|57) /*Record not stopped*/ -#define S_db_errArg (M_dbAccess|59) /*Error in argument*/ -#define S_db_bkptLogic (M_dbAccess|61) /*Logic error in breakpoint routine*/ -#define S_db_cntSpwn (M_dbAccess|63) /*Cannot spawn dbContTask*/ -#define S_db_cntCont (M_dbAccess|65) /*Cannot resume dbContTask*/ -#define S_db_noMemory (M_dbAccess|66) /*unable to allocate data structure from pool*/ -#define S_db_notInit (M_dbAccess|67) /*Not initialized*/ -#define S_db_bufFull (M_dbAccess|68) /*Buffer full*/ - -epicsShareFunc long dbPutSpecial(struct dbAddr *paddr,int pass); -epicsShareFunc rset * dbGetRset(const struct dbAddr *paddr); -epicsShareFunc long dbPutAttribute( - const char *recordTypename,const char *name,const char*value); -epicsShareFunc int dbIsValueField(const struct dbFldDes *pdbFldDes); -epicsShareFunc int dbGetFieldIndex(const struct dbAddr *paddr); -epicsShareFunc long dbScanPassive( - struct dbCommon *pfrom,struct dbCommon *pto); -epicsShareFunc long dbProcess(struct dbCommon *precord); -epicsShareFunc long dbNameToAddr( - const char *pname,struct dbAddr *); -epicsShareFunc devSup* dbDTYPtoDevSup(dbRecordType *prdes, int dtyp); -epicsShareFunc devSup* dbDSETtoDevSup(dbRecordType *prdes, struct dset *pdset); -epicsShareFunc long dbGetField( - struct dbAddr *,short dbrType,void *pbuffer,long *options, - long *nRequest,void *pfl); -epicsShareFunc long dbGet( - struct dbAddr *,short dbrType,void *pbuffer,long *options, - long *nRequest,void *pfl); -epicsShareFunc long dbPutField( - struct dbAddr *,short dbrType,const void *pbuffer,long nRequest); -epicsShareFunc long dbPut( - struct dbAddr *,short dbrType,const void *pbuffer,long nRequest); - -typedef void(*SPC_ASCALLBACK)(struct dbCommon *); -/*dbSpcAsRegisterCallback called by access security */ -epicsShareFunc void dbSpcAsRegisterCallback(SPC_ASCALLBACK func); -epicsShareFunc long dbBufferSize( - short dbrType,long options,long nRequest); -epicsShareFunc long dbValueSize(short dbrType); - -/* Hook Routine */ - -typedef void (*DB_LOAD_RECORDS_HOOK_ROUTINE)(const char* filename, - const char* substitutions); -epicsShareExtern DB_LOAD_RECORDS_HOOK_ROUTINE dbLoadRecordsHook; - -epicsShareFunc int dbLoadDatabase( - const char *filename, const char *path, const char *substitutions); -epicsShareFunc int dbLoadRecords( - const char* filename, const char* substitutions); - -#ifdef __cplusplus -} -#endif - -#endif /*INCdbAccessDefsh*/ diff --git a/src/ioc/db/dbAddr.h b/src/ioc/db/dbAddr.h deleted file mode 100644 index 2a6e4c0e2..000000000 --- a/src/ioc/db/dbAddr.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef dbAddrh -#define dbAddrh - -struct dbCommon; -struct dbFldDes; - -typedef struct dbAddr { - struct dbCommon *precord; /* address of record */ - void *pfield; /* address of field */ - struct dbFldDes *pfldDes; /* address of struct fldDes */ - long no_elements; /* number of elements (arrays) */ - short field_type; /* type of database field */ - short field_size; /* size of the field being accessed */ - short special; /* special processing */ - short dbr_field_type; /* field type as seen by database request*/ - /* DBR_STRING,...,DBR_ENUM,DBR_NOACCESS */ -} dbAddr; - -typedef dbAddr DBADDR; - -#endif /* dbAddrh */ diff --git a/src/ioc/db/dbBkpt.c b/src/ioc/db/dbBkpt.c deleted file mode 100644 index 347e28cd4..000000000 --- a/src/ioc/db/dbBkpt.c +++ /dev/null @@ -1,970 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbBkpt.c */ -/* - * Author: Matthew Needes - * Date: 8-30-93 -*/ - -/* - * Database Breakpoint Manipulation and User Interface - * - * USER COMMANDS - * dbb(record_name) Set a breakpoint in a record - * dbd(record_name) Delete a record's breakpoint - * dbc(record_name) Resume record processing - * dbs(record_name) Step through record processing through - * IO links, forward process links, etc. - * dbstat() Display status of stopped records in lock sets. - * dbap(record_name) Toggle automatic print after processing. - * dbp(record_name) Print out fields from record currently stopped. - * dbprc(record_name) Processes a record once without printing it. - * (Unless autoprint is on) - * - * INTERNAL FUNCTIONS - * dbBkpt() Process breakpoints, called by dbProcess(). - * dbPrint() Prints record if autoprint enabled. - * dbBkptCont() The task that continues and steps through - * records that are stopped at a breakpoint. - */ - -/* #define BKPT_DIAG */ - -#include -#include -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "errMdef.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbBkpt.h" -#include "dbCommon.h" -#include "db_field_log.h" -#include "dbFldTypes.h" -#include "dbFldTypes.h" -#include "dbLink.h" -#include "dbLock.h" -#include "dbScan.h" -#include "dbTest.h" -#include "link.h" -#include "recGbl.h" -#include "recSup.h" -#include "special.h" - -/* private routines */ -static void dbBkptCont(dbCommon *precord); -static long FIND_CONT_NODE( - const char *record_name, - struct LS_LIST **ppnode, - struct dbCommon **pprecord); - -/* - * Breakpoints are used as a debugging instrument to suspend the - * processing of database records. Once suspended, record - * processing may continue if either a continue (dbc()) or a - * step (dbs()) command is then issued. The current record's - * contents may be printed either with dbp(), or immediately - * after processing (use dbap() to toggle the BKPT_PRINT bit). - * - * dbb() and dbd() add a breakpoint to a record or delete one - * from a record. dbstat() prints out comprehensive breakpoint - * status information. - * - * Breakpoints may be set on a per lockset basis. When a - * breakpoint is set in a lockset, a new task is created. A - * separate task gets created for _every_ lockset containing - * a breakpoint. Thus multiple locksets may be debugged - * simultaneously. The breakpoint handler then schedules future - * processing in that lockset to this task. The separate task is - * used so that locksets that do not have breakpoints are isolated - * from locksets that do. This allows the processing of other - * locksets to continue uninterupted, even if they exist on the same - * scan list as a lockset containing a breakpoint. - * - * An entrypoint is the first record that gets processed in a lockset. - * This type of record is the basis for subsequent recursive executions - * of dbProcess(). The breakpoint handler monitors and schedules - * these entrypoints to the breakpoint tasks. - * - * Two hooks have been inserted in dbProcess() to manage breakpoints, - * dbBkpt() and dbPrint(). The former does two things: - * - * 1. Schedule entrypoints with the breakpoint task. - * 2. Suspend record processing when a breakpoint is detected. - * - * 1 occurs only if dbProcess() is called outside of the breakpoint - * task. Number 2 only occurs when dbProcess() is called from - * _within_ the breakpoint task's context. Number 1 is used for - * detection and scheduling, while 2 is used for suspending the task. - * - * The dbPrint() hook is used to print out a record's contents immediately - * _after_ a record has been processed. - * - * The dbBkptCont, or breakpoint task, pends on a semaphore that gets - * released whenever new entrypoints are scheduled for it. When - * released, this task then runs down its entrypoint queue and - * processes each entrypoint in turn. In this context, dbProcess - * will execute the dbBkpt() hook in mode 2, allowing this task to - * be suspended whenever a breakpoint is detected. - * - * NOTE: This is not a very "real-time" implementation (even for those - * locksets not containing a breakpoint). I may fix this later. - * - * Final comment: The scary thing is, I don't think this can be done - * more simply... - * - */ - -/* - * Flag used by dbProcess() to determine if there are - * any breakpoints. This is so that there is only - * a single comparison in the critical path during - * normal record execution, i.e. when there aren't - * any breakpoints set. - */ -long lset_stack_count = 0; - -/* - * Stack--in which each entry represents a different - * lock set with either breakpoints and/or stopped - * execution. (Breakpoints may be disabled even - * though execution is stopped). The order of the - * list is maintained so that the entry on the top - * of stack is used as a default for dbc() and dbs(). - * The semaphore is used to prevent conflicts while - * operating with this stack. - */ -static ELLLIST lset_stack = ELLLIST_INIT; -static epicsMutexId bkpt_stack_sem = 0; - -/* - * Stores the last lockset continued or stepped from. - * dbs() and dbc() will print a message if the current - * lockset to be continued from differs from this - * variable. - */ -static unsigned long last_lset = 0; - -/* - * FIND_LOCKSET() finds the stack entry - * whose l_num field matches precord's - * lset field. The node that is found - * is returned in "pnode." - */ -#define FIND_LOCKSET(precord, pnode) \ - pnode = (struct LS_LIST *) ellFirst(&lset_stack); \ - while ((pnode) != NULL) { \ - if (pnode->l_num == dbLockGetLockId(precord)) break; \ - pnode = (struct LS_LIST *) ellNext((ELLNODE *)pnode); \ - } \ - -/* - * FIND_QUEUE_ENTRY() matches entries in an - * entry point queue. pep_queue is the queue - * being searched, pqe is the pointer to the - * queue entry found, and precord is the record - * being searched for in *pep_queue. - */ -#define FIND_QUEUE_ENTRY(pep_queue, pqe, precord) \ - pqe = (struct EP_LIST *) ellFirst(pep_queue); \ - while ((pqe) != NULL) { \ - if ((pqe)->entrypoint == (precord)) break; \ - pqe = (struct EP_LIST *) ellNext((ELLNODE *)pqe); \ - } \ - -/* - * Fills out pnode and precord structures for dbc() and dbs() - * MUST LOCK OUT STACK BEFORE ENTRY - */ -static long FIND_CONT_NODE( - const char *record_name, - struct LS_LIST **ppnode, - struct dbCommon **pprecord) -{ - struct dbAddr addr; - struct LS_LIST *pnode; - struct dbCommon *precord = NULL; - long status = 0; - - if (record_name == NULL) { - /* - * Search through stack, taking the first entry that - * is currently stopped at a breakpoint. - */ - pnode = (struct LS_LIST *) ellFirst(&lset_stack); - while (pnode != NULL) { - if (pnode->precord != NULL) { - precord = pnode->precord; - break; - } - pnode = (struct LS_LIST *) ellNext((ELLNODE *)pnode); - } - - if (pnode == NULL) { - printf(" BKPT> No records are currently stopped\n"); - return(S_db_notStopped); - } - } - else { - /* - * Convert name to address - */ - status = dbNameToAddr(record_name, &addr); - if (status == S_db_notFound) - printf(" BKPT> Record %s not found\n", record_name); - if (status != 0) - return(status); - - precord = addr.precord; - - FIND_LOCKSET(precord, pnode); - - if (pnode == NULL || pnode->precord == NULL) { - printf(" BKPT> Currently not stopped in this lockset\n"); - return(S_db_notStopped); - } - } - - *pprecord = precord; - *ppnode = pnode; - return(0); -} - -/* - * Initialise the breakpoint stack - */ -void dbBkptInit(void) -{ - if (! bkpt_stack_sem) { - bkpt_stack_sem = epicsMutexMustCreate(); - lset_stack_count = 0; - } -} - -/* - * Add breakpoint to a lock set - * 1. Convert name to address and check breakpoint mask. - * 2. Lock database. - * 3. If empty, initialize lock set stack and its semaphore. - * 4. Take that semaphore. - * 5. Find lockset in the list. If it doesn't exist, create it. - * 6. Turn on breakpoint field in record. - * 7. Add breakpoint to list of breakpoints in structure. - * 8. Spawn continuation task if it isn't already running. - */ -long dbb(const char *record_name) -{ - struct dbAddr addr; - struct LS_LIST *pnode; - struct BP_LIST *pbl; - struct dbCommon *precord; - long status; - - /* - * Convert name to address - */ - status = dbNameToAddr(record_name, &addr); - if (status == S_db_notFound) - printf(" BKPT> Record %s not found\n", record_name); - if (status != 0) return(status); - - precord = addr.precord; - - if (precord->bkpt & BKPT_ON_MASK) { - printf(" BKPT> Breakpoint already set in this record\n"); - return(S_db_bkptSet); - } - - dbScanLock(precord); - - /* - * Add lock set to the stack of lock sets that - * contain breakpoints and/or stopped records. - */ - - epicsMutexMustLock(bkpt_stack_sem); - - FIND_LOCKSET(precord, pnode); - - if (pnode == NULL) { - /* lockset not found, create node, add to end of list */ - pnode = (struct LS_LIST *) malloc(sizeof(struct LS_LIST)); - if (pnode == NULL) { - printf(" BKPT> Out of memory\n"); - dbScanUnlock(precord); - epicsMutexUnlock(bkpt_stack_sem); - return(1); - } - pnode->precord = NULL; - - /* initialize breakpoint list */ - ellInit(&pnode->bp_list); - - /* initialize entry point queue */ - ellInit(&pnode->ep_queue); - - /* create execution semaphore */ - pnode->ex_sem = epicsEventCreate(epicsEventEmpty); - if (pnode->ex_sem == NULL) { - printf(" BKPT> Out of memory\n"); - dbScanUnlock(precord); - epicsMutexUnlock(bkpt_stack_sem); - return(1); - } - - pnode->taskid = 0; - pnode->step = 0; - pnode->l_num = dbLockGetLockId(precord); - - ellAdd(&lset_stack, (ELLNODE *)pnode); - ++lset_stack_count; - } - - /* - * Add record to breakpoint list - */ - pbl = (struct BP_LIST *) malloc(sizeof(struct BP_LIST)); - if (pbl == NULL) { - printf(" BKPT> Out of memory\n"); - dbScanUnlock(precord); - epicsMutexUnlock(bkpt_stack_sem); - return(1); - } - pbl->precord = precord; - ellAdd(&pnode->bp_list, (ELLNODE *)pbl); - - /* - * Turn on breakpoint field in record - */ - precord->bkpt |= BKPT_ON_MASK; - - if (! pnode->taskid) { - -#ifdef BKPT_DIAG - printf(" BKPT> Spawning task: %s\n", precord->name); -#endif - /* - * Spawn continuation task - */ - pnode->taskid = epicsThreadCreate("bkptCont",epicsThreadPriorityScanLow-1, - epicsThreadGetStackSize(epicsThreadStackBig), - (EPICSTHREADFUNC)dbBkptCont,precord); - if (pnode->taskid == 0) { - printf(" BKPT> Cannot spawn task to process record\n"); - pnode->taskid = 0; - dbScanUnlock(precord); - epicsMutexUnlock(bkpt_stack_sem); - return(1); - } - } - - epicsMutexUnlock(bkpt_stack_sem); - dbScanUnlock(precord); - return(0); -} - -/* - * Remove breakpoint from a record - * 1. Convert name to address and check breakpoint mask. - * 2. Lock database and take stack semaphore. - * 3. Find structure for record's lockset (in stack). - * 4. Find and delete record from breakpoint list. - * 5. Turn off break point field. - * 6. Give up semaphore to "signal" bkptCont task to quit. - */ -long dbd(const char *record_name) -{ - struct dbAddr addr; - struct LS_LIST *pnode; - struct BP_LIST *pbl; - struct dbCommon *precord; - long status; - - /* - * Convert name to address - */ - status = dbNameToAddr(record_name, &addr); - if (status == S_db_notFound) - printf(" BKPT> Record %s not found\n", record_name); - if (status != 0) return(status); - - precord = addr.precord; - - if (! precord->bkpt & BKPT_ON_MASK) { - printf(" BKPT> No breakpoint set in this record\n"); - return(S_db_bkptNotSet); - } - - dbScanLock(precord); - - epicsMutexMustLock(bkpt_stack_sem); - - FIND_LOCKSET(precord, pnode); - - if (pnode == NULL) { - /* not found, error ! */ - printf(" BKPT> Logic Error in dbd()\n"); - precord->bkpt &= BKPT_OFF_MASK; - - epicsMutexUnlock(bkpt_stack_sem); - dbScanUnlock(precord); - return(S_db_bkptLogic); - } - - /* - * Remove record from breakpoint list - */ - - /* find record in list */ - pbl = (struct BP_LIST *) ellFirst(&pnode->bp_list); - while (pbl != NULL) { - if (pbl->precord == precord) { - ellDelete(&pnode->bp_list, (ELLNODE *)pbl); - free(pbl); - break; - } - pbl = (struct BP_LIST *) ellNext((ELLNODE *)pbl); - } - - if (pbl == NULL) { - printf(" BKPT> Logic Error in dbd()\n"); - precord->bkpt &= BKPT_OFF_MASK; - epicsMutexUnlock(bkpt_stack_sem); - dbScanUnlock(precord); - return(S_db_bkptLogic); - } - - /* - * Turn off breakpoint field in record - */ - precord->bkpt &= BKPT_OFF_MASK; - - /* - * If there are no more breakpoints, give up semaphore - * to cause the bkptCont task to quit. - */ - if (ellCount(&pnode->bp_list) == 0) - epicsEventSignal(pnode->ex_sem); - - epicsMutexUnlock(bkpt_stack_sem); - - dbScanUnlock(precord); - return(0); -} - -/* - * Continue processing in a lock set - * 1. Find top node in the lockset stack. - * 2. Turn off stepping mode. - * 2. Resume dbBkptCont. - */ -long dbc(const char *record_name) -{ - struct LS_LIST *pnode; - struct dbCommon *precord = NULL; - long status = 0; - - epicsMutexMustLock(bkpt_stack_sem); - - status = FIND_CONT_NODE(record_name, &pnode, &precord); - if (status) { - epicsMutexUnlock(bkpt_stack_sem); - return(status); - } - - if (record_name == NULL && last_lset != pnode->l_num) - printf(" BKPT> Continuing: %s\n", pnode->precord->name); - - last_lset = pnode->l_num; - - /* - * Turn off stepping mode - */ - pnode->step = 0; - - /* - * Resume dbBkptCont() until dbProcess() is executed - * for a record with a breakpoint. This occurs - * because stepping mode has been switched off. - */ - epicsThreadResume(pnode->taskid); - epicsMutexUnlock(bkpt_stack_sem); - return(0); -} - -/* - * Step through record processing - * 1. Find top node in lockset stack. - * 2. Resume dbBkptCont. - */ -long dbs(const char *record_name) -{ - struct LS_LIST *pnode; - struct dbCommon *precord = NULL; - long status = 0; - - epicsMutexMustLock(bkpt_stack_sem); - - status = FIND_CONT_NODE(record_name, &pnode, &precord); - if (status) { - epicsMutexUnlock(bkpt_stack_sem); - return(status); - } - - if (last_lset != pnode->l_num && record_name == NULL) - printf(" BKPT> Stepping: %s\n", pnode->precord->name); - - last_lset = pnode->l_num; - - epicsThreadResume(pnode->taskid); - epicsMutexUnlock(bkpt_stack_sem); - return(0); -} - -/* - * Task for continuing record processing - * 1. Find lockset in stack for precord. - * DO 2-3 while breakpoints exist in the lockset. - * 2. Wait on execution semaphore ... - * 3. Run through every entrypoint in queue, processing - * those that are scheduled. - * 4. Free resources for lockset, and exit task. - */ -static void dbBkptCont(dbCommon *precord) -{ - struct LS_LIST *pnode; - struct EP_LIST *pqe = NULL; - - /* - * Reset breakpoint, process record, and - * reset bkpt field in record - */ - epicsMutexMustLock(bkpt_stack_sem); - - FIND_LOCKSET(precord, pnode); - - if (pnode == NULL) { - printf(" BKPT> Logic error in dbBkptCont()\n"); - return; - } - - /* - * For every entrypoint scheduled, process. Run process - * until there are no more breakpoints remaining in a - * lock set. - */ - do { - /* Give up semaphore before waiting to run ... */ - epicsMutexUnlock(bkpt_stack_sem); - - /* Wait to run */ - epicsEventMustWait(pnode->ex_sem); - - /* Bkpt stack must still be stable ! */ - epicsMutexMustLock(bkpt_stack_sem); - - pqe = (struct EP_LIST *) ellFirst(&pnode->ep_queue); - - /* Run through entrypoint queue */ - while (pqe != NULL) { - /* check if entrypoint is currently scheduled */ - if (pqe->sched) { - /* save current entrypoint */ - pnode->current_ep = pqe->entrypoint; - - /* lock the lockset, process record, unlock */ - dbScanLock(precord); - dbProcess(pqe->entrypoint); - dbScanUnlock(precord); - - /* reset schedule and stepping flag - Do this AFTER processing */ - pqe->sched = 0; - pnode->step = 0; - } - pqe = (struct EP_LIST *) ellNext((ELLNODE *)pqe); - } - - /* Reset precord. (Since no records are at a breakpoint) */ - pnode->precord = NULL; - } while (ellCount(&pnode->bp_list) != 0); - - /* remove node from lockset stack */ - ellDelete(&lset_stack, (ELLNODE *)pnode); - --lset_stack_count; - - /* free entrypoint queue */ - ellFree(&pnode->ep_queue); - - /* remove execution semaphore */ - epicsEventDestroy(pnode->ex_sem); - - printf("\n BKPT> End debug of lockset %lu\n-> ", pnode->l_num); - - /* free list node */ - free(pnode); - - epicsMutexUnlock(bkpt_stack_sem); -} - -/* - * Process breakpoint - * Returns a zero if dbProcess() is to execute - * record support, a one if dbProcess() is to - * skip over record support. See dbProcess(). - * - * 1. See if there is at least a breakpoint set somewhere - * in precord's lockset. If not, return immediately. - * 2. Check the disable flag. - * 3. Add entry points to the queue for future stepping and - * schedule new entrypoints for the continuation task. - * 4. Check the pact flag. - * 5. Check to see if there is a breakpoint set in a record, and - * if so, turn on stepping mode. - * 6. If stepping mode is set, stop and report the breakpoint. - */ -int dbBkpt(dbCommon *precord) -{ - struct LS_LIST *pnode; - struct EP_LIST *pqe; - - /* - * It is crucial that operations in dbBkpt() execute - * in the correct order or certain features in the - * breakpoint handler will not work as expected. - */ - - /* - * Take and give a semaphore to check for breakpoints - * every time a record is processed. Slow. Thank - * goodness breakpoint checking is turned off during - * normal operation. - */ - epicsMutexMustLock(bkpt_stack_sem); - FIND_LOCKSET(precord, pnode); - epicsMutexUnlock(bkpt_stack_sem); - - if (pnode == NULL) { - /* no breakpoints in precord's lockset */ - return(0); - } - - /* Check disable flag */ - dbGetLink(&(precord->sdis),DBR_SHORT,&(precord->disa),0,0); - if (precord->disa == precord->disv) { - /* - * Do not process breakpoints if the record is disabled, - * but allow disable alarms. Alarms will be raised - * in dbProcess() because returning 0 allows dbProcess() - * to continue. However processing will be prevented - * because disa and disv will be examined again in - * dbProcess(). Note that checking for pact will occur - * before checking for disa and disv in dbProcess(). - */ - return(0); - } - - /* - * Queue entry points for future stepping. The taskid comparison - * is used to determine if the source of processing is the - * continuation task or an external source. If it is an external - * source, queue its execution, but dump out of dbProcess without - * calling record support. - */ - if (pnode->taskid && (epicsThreadGetIdSelf() != pnode->taskid)) { - /* CONTINUE TASK CANNOT ENTER HERE */ - - /* - * Add an entry point to queue, if it does - * not already exist. - */ - FIND_QUEUE_ENTRY(&pnode->ep_queue, pqe, precord); - - if (pqe == NULL) { - - pqe = (struct EP_LIST *) malloc(sizeof(struct EP_LIST)); - if (pqe == NULL) - return(1); - - - pqe->entrypoint = precord; - pqe->count = 1; - epicsTimeGetCurrent(&pqe->time); - pqe->sched = 0; - -#ifdef BKPT_DIAG - printf(" BKPT> Adding entrypoint %s to queue\n", precord->name); -#endif - - /* - * Take semaphore, wait on continuation task - */ - epicsMutexMustLock(bkpt_stack_sem); - - /* Add entry to queue */ - ellAdd(&pnode->ep_queue, (ELLNODE *)pqe); - - epicsMutexUnlock(bkpt_stack_sem); - } - else { - if (pqe->count < MAX_EP_COUNT) - pqe->count++; - } - - /* check pact */ - if (! precord->pact) { - /* schedule if pact not set */ - pqe->sched = 1; - - /* - * Release the semaphore, letting the continuation - * task begin execution of the new entrypoint. - */ - epicsEventSignal(pnode->ex_sem); - } - return(1); - } - - /* - * Don't mess with breakpoints if pact set! Skip - * over rest of dbProcess() since we don't want - * alarms going off. The pact flag is checked - * AFTER entry point queuing so that the record - * timing feature will work properly. - */ - if (precord->pact) - return(1); - - /* Turn on stepping mode if a breakpoint is found */ - if (precord->bkpt & BKPT_ON_MASK) { - pnode->step = 1; - -#ifdef BKPT_DIAG - printf(" BKPT> Bkpt detected: %s\n", precord->name); -#endif - } - - /* - * If we are currently stepping through the lockset, - * suspend task. - */ - if (pnode->step) { - printf("\n BKPT> Stopped at: %s within Entrypoint: %s\n-> ", - precord->name, pnode->current_ep->name); - - pnode->precord = precord; - - /* Move current lockset to top of stack */ - ellDelete(&lset_stack, (ELLNODE *)pnode); - ellInsert(&lset_stack, NULL, (ELLNODE *)pnode); - /* - * Unlock database while the task suspends itself. This - * is done so that dbb() dbd() dbc() dbs() may be used - * when the task is suspended. Scan tasks that also - * use the scan lock feature will not be hung during - * a breakpoint, so that records in other locksets will - * continue to be processed. Cross your fingers, this - * might actually work ! - */ - epicsMutexUnlock(bkpt_stack_sem); - dbScanUnlock(precord); - epicsThreadSuspendSelf(); - dbScanLock(precord); - epicsMutexMustLock(bkpt_stack_sem); - } - return(0); -} - -/* print record after processing */ -void dbPrint(dbCommon *precord ) -{ - struct LS_LIST *pnode; - - if (! (precord->bkpt & BKPT_PRINT_MASK)) - return; - - FIND_LOCKSET(precord, pnode); - - /* do not print if lockset does not currently contain breakpoints */ - if (pnode == NULL) - return; - - printf("\n"); - dbpr(precord->name, 2); - printf("-> "); -} - -/* print stopped record */ -long dbp(const char *record_name, int interest_level) -{ - struct LS_LIST *pnode; - struct dbCommon *precord = NULL; - int status; - - epicsMutexMustLock(bkpt_stack_sem); - - /* find pnode and precord pointers */ - status = FIND_CONT_NODE(record_name, &pnode, &precord); - if (status) { - epicsMutexUnlock(bkpt_stack_sem); - return(status); - } - - /* print out record's fields */ - dbpr(precord->name, (interest_level == 0) ? 2 : interest_level); - - epicsMutexUnlock(bkpt_stack_sem); - return(0); -} - -/* toggle printing after processing a certain record */ -long dbap(const char *record_name) -{ - struct dbAddr addr; - struct dbCommon *precord; - long status; - - /* - * Convert name to address - */ - status = dbNameToAddr(record_name, &addr); - if (status == S_db_notFound) - printf(" BKPT> Record %s not found\n", record_name); - if (status != 0) return(status); - - precord = addr.precord; - - /* - * Toggle print after process field in record - */ - if (precord->bkpt & BKPT_PRINT_MASK) { - printf(" BKPT> Auto print off for record %s\n", precord->name); - precord->bkpt &= BKPT_PRINT_OFF_MASK; - } - else { - printf(" BKPT> Auto print on for record %s\n", precord->name); - precord->bkpt |= BKPT_PRINT_MASK; - } - - return(0); -} - -/* print list of stopped records, and breakpoints set in locksets */ -long dbstat(void) -{ - struct LS_LIST *pnode; - struct BP_LIST *pbl; - struct EP_LIST *pqe; - epicsTimeStamp time; - - epicsMutexMustLock(bkpt_stack_sem); - - epicsTimeGetCurrent(&time); - - /* - * Traverse list, reporting stopped records - */ - pnode = (struct LS_LIST *) ellFirst(&lset_stack); - while (pnode != NULL) { - if (pnode->precord != NULL) { - - printf("LSet: %lu Stopped at: %-28.28s #B: %5.5d T: %p\n", - pnode->l_num, pnode->precord->name, ellCount(&pnode->bp_list), pnode->taskid); - - /* for each entrypoint detected, print out entrypoint statistics */ - pqe = (struct EP_LIST *) ellFirst(&pnode->ep_queue); - while (pqe != NULL) { - double diff = epicsTimeDiffInSeconds(&time,&pqe->time); - if (diff) { - printf(" Entrypoint: %-28.28s #C: %5.5lu C/S: %7.1f\n", - pqe->entrypoint->name, pqe->count,diff); - } - pqe = (struct EP_LIST *) ellNext((ELLNODE *)pqe); - } - } - else { - printf("LSet: %lu #B: %5.5d T: %p\n", - pnode->l_num, ellCount(&pnode->bp_list), pnode->taskid); - } - - /* - * Print out breakpoints set in the lock set - */ - pbl = (struct BP_LIST *) ellFirst(&pnode->bp_list); - while (pbl != NULL) { - printf(" Breakpoint: %-28.28s", pbl->precord->name); - - /* display auto print flag */ - if (pbl->precord->bkpt & BKPT_PRINT_MASK) - printf(" (ap)\n"); - else - printf("\n"); - - pbl = (struct BP_LIST *) ellNext((ELLNODE *)pbl); - } - - pnode = (struct LS_LIST *) ellNext((ELLNODE *)pnode); - } - - epicsMutexUnlock(bkpt_stack_sem); - return(0); -} - -/* - * Process a record without printing it. - */ -long dbprc(char *record_name) -{ - struct dbAddr addr; - struct dbCommon *precord; - long status; - - /* - * Convert name to address - */ - status = dbNameToAddr(record_name, &addr); - if (status == S_db_notFound) - printf(" BKPT> Record %s not found\n", record_name); - if (status != 0) return(status); - - precord = addr.precord; - - /* lock lockset, process record, unlock lockset */ - dbScanLock(precord); - status = dbProcess(precord); - dbScanUnlock(precord); - - return(status); -} - -#ifdef BKPT_DIAG - -/* Reset breakpoints */ -int dbreset() -{ - epicsMutexUnlock(bkpt_stack_sem); - - return(0); -} - -#endif - diff --git a/src/ioc/db/dbBkpt.h b/src/ioc/db/dbBkpt.h deleted file mode 100644 index 7240b701c..000000000 --- a/src/ioc/db/dbBkpt.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbBkpt.h */ -/* - * Author: Matthew Needes - * Date: 8-30-93 - */ - -#ifndef INCdbBkptsh -#define INCdbBkptsh 1 - -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "shareLib.h" -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Structure containing a list of set breakpoints - * in a lockset - */ - -struct BP_LIST { - ELLNODE *next_list; - ELLNODE *prev_list; - struct dbCommon *precord; -}; - -/* - * Structure containing queue of entrypoints - * detected for a lockset. - */ -struct EP_LIST { - ELLNODE *next_list; - ELLNODE *prev_list; - struct dbCommon *entrypoint; /* pointer to entry point in lockset */ - unsigned long count; /* number of times record processed */ - epicsTimeStamp time; /* time record first logged */ - char sched; /* schedule record for next dbContTask() pass */ -}; - -/* - * Structure for stack of lock sets that - * currently contain breakpoints. (uses ellLib) - */ -struct LS_LIST { - ELLNODE *next_list; - ELLNODE *prev_list; - struct dbCommon *precord;/* points to where execution is currently stopped */ - struct dbCommon *current_ep; /* current entrypoint */ - ELLLIST bp_list; /* list of records containing breakpoints in a lockset */ - ELLLIST ep_queue; /* queue of entrypoints found so far */ - epicsEventId ex_sem; /* semaphore for execution queue */ - epicsThreadId taskid; /* saved taskid for the task in stepping mode */ - int step; /* one if currently "stepping," else zero */ - unsigned long l_num; /* lockset number */ -}; - -/* Values for BKPT (breakpoint) field in record */ - -/* 1st bit = 0 if breakpoint is not set, */ -/* 1 if breakpoint set */ -/* 2nd bit = 0 if no printing after processing */ -/* 1 if print after processing set */ - -/* Breakpoint Masks */ -#define BKPT_ON_MASK 0x001 -#define BKPT_OFF_MASK 0x0FE -#define BKPT_PRINT_MASK 0x002 -#define BKPT_PRINT_OFF_MASK 0x0FD - -#define MAX_EP_COUNT 99999 - -epicsShareFunc void dbBkptInit(void); -epicsShareFunc long dbb(const char *recordname); -epicsShareFunc long dbd(const char *recordname); -epicsShareFunc long dbc(const char *recordname); -epicsShareFunc long dbs(const char *recordname); -epicsShareFunc long dbstat(void); -epicsShareFunc long dbp( - const char *record_name, int interest_level); -epicsShareFunc long dbap(const char *record_name); -epicsShareFunc int dbBkpt(struct dbCommon *precord); -epicsShareFunc void dbPrint(struct dbCommon *precord); -epicsShareFunc long dbprc(char *record_name); - -extern long lset_stack_count; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/ioc/db/dbCAC.h b/src/ioc/db/dbCAC.h deleted file mode 100644 index 2d97fac35..000000000 --- a/src/ioc/db/dbCAC.h +++ /dev/null @@ -1,239 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - * NOTES: - * 1) This interface is preliminary and will change in the future - */ - -#ifndef dbCACh -#define dbCACh - -#ifdef epicsExportSharedSymbols -# define dbCACh_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "stdlib.h" - -#include // std::auto_ptr - -#include "tsDLList.h" -#include "tsFreeList.h" -#include "resourceLib.h" -#include "cacIO.h" -#include "compilerDependencies.h" - -#ifdef dbCACh_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "db_access.h" -#include "dbNotify.h" -#include "dbEvent.h" -#include "dbChannel.h" -#include "dbLock.h" -#include "dbCommon.h" -#include "db_convert.h" -#include "resourceLib.h" - -extern "C" int putNotifyPut ( processNotify *ppn, notifyPutType notifyPutType ); -extern "C" void putNotifyCompletion ( processNotify *ppn ); - -class dbContext; -class dbChannelIO; -class dbPutNotifyBlocker; -class dbSubscriptionIO; - -class dbBaseIO - : public chronIntIdRes < dbBaseIO > { -public: - virtual dbSubscriptionIO * isSubscription () = 0; - virtual void show ( epicsGuard < epicsMutex > &, unsigned level ) const = 0; - virtual void show ( unsigned level ) const = 0; - dbBaseIO (); - dbBaseIO ( const dbBaseIO & ); - dbBaseIO & operator = ( const dbBaseIO & ); -protected: - virtual ~dbBaseIO() {} -}; - -extern "C" void dbSubscriptionEventCallback ( void *pPrivate, struct dbChannel *dbch, - int eventsRemaining, struct db_field_log *pfl ); - -class dbSubscriptionIO : - public tsDLNode < dbSubscriptionIO >, - public dbBaseIO { -public: - dbSubscriptionIO ( - epicsGuard < epicsMutex > &, epicsMutex &, - dbContext &, dbChannelIO &, struct dbChannel *, cacStateNotify &, - unsigned type, unsigned long count, unsigned mask, dbEventCtx ); - void destructor ( CallbackGuard &, epicsGuard < epicsMutex > & ); - void unsubscribe ( CallbackGuard &, epicsGuard < epicsMutex > & ); - void channelDeleteException ( CallbackGuard &, epicsGuard < epicsMutex > & ); - void show ( epicsGuard < epicsMutex > &, unsigned level ) const; - void show ( unsigned level ) const; - void * operator new ( size_t size, - tsFreeList < dbSubscriptionIO, 256, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < dbSubscriptionIO, 256, epicsMutexNOOP > & )) -private: - epicsMutex & mutex; - unsigned long count; - cacStateNotify & notify; - dbChannelIO & chan; - dbEventSubscription es; - unsigned type; - unsigned id; - dbSubscriptionIO * isSubscription (); - friend void dbSubscriptionEventCallback ( - void * pPrivate, struct dbChannel * dbch, - int eventsRemaining, struct db_field_log * pfl ); - dbSubscriptionIO ( const dbSubscriptionIO & ); - dbSubscriptionIO & operator = ( const dbSubscriptionIO & ); - virtual ~dbSubscriptionIO (); - void operator delete ( void * ); -}; - -class dbContext; - -class dbContextPrivateListOfIO { -public: - dbContextPrivateListOfIO (); - ~dbContextPrivateListOfIO (); -private: - tsDLList < dbSubscriptionIO > eventq; - dbPutNotifyBlocker * pBlocker; - friend class dbContext; - dbContextPrivateListOfIO ( const dbContextPrivateListOfIO & ); - dbContextPrivateListOfIO & operator = ( const dbContextPrivateListOfIO & ); -}; - -class dbContextReadNotifyCacheAllocator { -public: - dbContextReadNotifyCacheAllocator (); - ~dbContextReadNotifyCacheAllocator (); - char * alloc ( unsigned long size ); - void free ( char * pFree ); - void show ( unsigned level ) const; -private: - struct cacheElem_t { - size_t size; - struct cacheElem_t * pNext; - char buf[1]; - }; - unsigned long _readNotifyCacheSize; - cacheElem_t * _pReadNotifyCache; - void reclaimAllCacheEntries (); - dbContextReadNotifyCacheAllocator ( const dbContextReadNotifyCacheAllocator & ); - dbContextReadNotifyCacheAllocator & operator = ( const dbContextReadNotifyCacheAllocator & ); -}; - -class dbContextReadNotifyCache { -public: - dbContextReadNotifyCache ( epicsMutex & ); - void callReadNotify ( epicsGuard < epicsMutex > &, - struct dbChannel * dbch, unsigned type, unsigned long count, - cacReadNotify & notify ); - void show ( epicsGuard < epicsMutex > &, unsigned level ) const; -private: - dbContextReadNotifyCacheAllocator _allocator; - epicsMutex & _mutex; - dbContextReadNotifyCache ( const dbContextReadNotifyCache & ); - dbContextReadNotifyCache & operator = ( const dbContextReadNotifyCache & ); -}; - -class dbContext : public cacContext { -public: - dbContext ( epicsMutex & cbMutex, epicsMutex & mutex, - cacContextNotify & notify ); - virtual ~dbContext (); - void destroyChannel ( CallbackGuard &,epicsGuard < epicsMutex > &, dbChannelIO & ); - void callReadNotify ( epicsGuard < epicsMutex > &, - struct dbChannel * dbch, unsigned type, unsigned long count, - cacReadNotify & notify ); - void callStateNotify ( struct dbChannel * dbch, unsigned type, unsigned long count, - const struct db_field_log * pfl, cacStateNotify & notify ); - void subscribe ( - epicsGuard < epicsMutex > &, - struct dbChannel * dbch, dbChannelIO & chan, - unsigned type, unsigned long count, unsigned mask, - cacStateNotify & notify, cacChannel::ioid * pId ); - void initiatePutNotify ( - epicsGuard < epicsMutex > &, dbChannelIO &, struct dbChannel *, - unsigned type, unsigned long count, const void * pValue, - cacWriteNotify & notify, cacChannel::ioid * pId ); - void show ( unsigned level ) const; - void showAllIO ( const dbChannelIO & chan, unsigned level ) const; - void destroyAllIO ( CallbackGuard & cbGuard, - epicsGuard < epicsMutex > &, dbChannelIO & chan ); - void ioCancel ( CallbackGuard &, epicsGuard < epicsMutex > &, - dbChannelIO & chan, const cacChannel::ioid &id ); - void ioShow ( epicsGuard < epicsMutex > &, - const cacChannel::ioid & id, unsigned level ) const; -private: - tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP > dbPutNotifyBlockerFreeList; - tsFreeList < dbSubscriptionIO, 256, epicsMutexNOOP > dbSubscriptionIOFreeList; - tsFreeList < dbChannelIO, 256, epicsMutexNOOP > dbChannelIOFreeList; - chronIntIdResTable < dbBaseIO > ioTable; - dbContextReadNotifyCache readNotifyCache; - dbEventCtx ctx; - unsigned long stateNotifyCacheSize; - epicsMutex & mutex; - epicsMutex & cbMutex; - cacContextNotify & notify; - std::auto_ptr < cacContext > pNetContext; - char * pStateNotifyCache; - bool isolated; - - cacChannel & createChannel ( - epicsGuard < epicsMutex > &, - const char * pChannelName, cacChannelNotify &, - cacChannel::priLev ); - void flush ( - epicsGuard < epicsMutex > & ); - unsigned circuitCount ( - epicsGuard < epicsMutex > & ) const; - void selfTest ( - epicsGuard < epicsMutex > & ) const; - unsigned beaconAnomaliesSinceProgramStart ( - epicsGuard < epicsMutex > & ) const; - void show ( - epicsGuard < epicsMutex > &, unsigned level ) const; - - dbContext ( const dbContext & ); - dbContext & operator = ( const dbContext & ); -}; - -inline dbContextPrivateListOfIO::dbContextPrivateListOfIO () : - pBlocker ( 0 ) -{ -} - -inline dbContextPrivateListOfIO::~dbContextPrivateListOfIO () -{ - assert ( ! this->pBlocker ); -} - -inline void dbContext::callReadNotify ( - epicsGuard < epicsMutex > & guard, struct dbChannel * dbch, - unsigned type, unsigned long count, cacReadNotify & notifyIn ) -{ - guard.assertIdenticalMutex ( this-> mutex ); - this->readNotifyCache.callReadNotify ( guard, dbch, type, count, notifyIn ); -} - -#endif // dbCACh - diff --git a/src/ioc/db/dbCa.c b/src/ioc/db/dbCa.c deleted file mode 100644 index 72ad6cd24..000000000 --- a/src/ioc/db/dbCa.c +++ /dev/null @@ -1,1181 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Marty Kraimer - * Date: 26MAR96 - */ -#define EPICS_DBCA_PRIVATE_API -#include -#include -#include -#include -#include - -#include "alarm.h" -#include "cantProceed.h" -#include "dbDefs.h" -#include "epicsAssert.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsMutex.h" -#include "epicsPrint.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "epicsAtomic.h" -#include "epicsTime.h" -#include "errlog.h" -#include "errMdef.h" -#include "taskwd.h" - -#include "cadef.h" - -/* We can't include dbStaticLib.h here */ -#define dbCalloc(nobj,size) callocMustSucceed(nobj,size,"dbCalloc") - -#define epicsExportSharedSymbols -#include "db_access_routines.h" -#include "dbCa.h" -#include "dbCaPvt.h" -#include "dbCommon.h" -#include "db_convert.h" -#include "dbLink.h" -#include "dbLock.h" -#include "dbScan.h" -#include "link.h" -#include "recGbl.h" -#include "recSup.h" - -/* defined in dbContext.cpp - * Setup local CA access - */ -extern void dbServiceIOInit(); -extern int dbServiceIsolate; - -static ELLLIST workList = ELLLIST_INIT; /* Work list for dbCaTask */ -static epicsMutexId workListLock; /*Mutual exclusions semaphores for workList*/ -static epicsEventId workListEvent; /*wakeup event for dbCaTask*/ -static int removesOutstanding = 0; -#define removesOutstandingWarning 10000 - -static volatile enum dbCaCtl_t { - ctlInit, ctlRun, ctlPause, ctlExit -} dbCaCtl; -static epicsEventId startStopEvent; - -struct ca_client_context * dbCaClientContext; - -/* Forward declarations */ -static void dbCaTask(void *); - -static lset dbCa_lset; - -#define printLinks(pcaLink) \ - errlogPrintf("%s has DB CA link to %s\n",\ - pcaLink->plink->precord->name, pcaLink->pvname) - -static int dbca_chan_count; - -/* caLink locking - * - * Lock ordering: - * dbScanLock -> caLink.lock -> workListLock - * - * workListLock: - * Guards access to workList. - * - * dbScanLock: - * All dbCa* functions operating on a single link may only be called when - * the record containing the DBLINK is locked. Including: - * dbCaGet*() - * isConnected() - * dbCaPutLink() - * scanForward() - * dbCaAddLinkCallback() - * dbCaRemoveLink() - * - * Guard the pointer plink.value.pv_link.pvt, but not the struct caLink - * which is pointed to. - * - * caLink.lock: - * Guards the caLink structure (but not the struct DBLINK) - * - * The dbCaTask only locks caLink, and must not lock the record (a violation of lock order). - * - * During link modification or IOC shutdown the pca->plink pointer (guarded by caLink.lock) - * is used as a flag to indicate that a link is no longer active. - * - * References to the struct caLink are owned by the dbCaTask, and any scanOnceCallback() - * which is in progress. - * - * The libca and scanOnceCallback callbacks take no action if pca->plink==NULL. - * - * dbCaPutLinkCallback causes an additional complication because - * when dbCaRemoveLink is called the callback may not have occured. - * If putComplete sees plink==0 it will not call the user's code. - * If pca->putCallback is non-zero, dbCaTask will call the - * user's callback AFTER it has called ca_clear_channel. - * Thus the user's callback will get called exactly once. - */ - -static void addAction(caLink *pca, short link_action) -{ - int callAdd; - - epicsMutexMustLock(workListLock); - callAdd = (pca->link_action == 0); - if (pca->link_action & CA_CLEAR_CHANNEL) { - errlogPrintf("dbCa::addAction %d with CA_CLEAR_CHANNEL set\n", - link_action); - printLinks(pca); - link_action = 0; - } - if (link_action & CA_CLEAR_CHANNEL) { - if (++removesOutstanding >= removesOutstandingWarning) { - errlogPrintf("dbCa::addAction pausing, %d channels to clear\n", - removesOutstanding); - } - while (removesOutstanding >= removesOutstandingWarning) { - epicsMutexUnlock(workListLock); - epicsThreadSleep(1.0); - epicsMutexMustLock(workListLock); - } - } - pca->link_action |= link_action; - if (callAdd) - ellAdd(&workList, &pca->node); - epicsMutexUnlock(workListLock); - if (callAdd) - epicsEventSignal(workListEvent); -} - -static void caLinkInc(caLink *pca) -{ - assert(epicsAtomicGetIntT(&pca->refcount)>0); - epicsAtomicIncrIntT(&pca->refcount); -} - -static void caLinkDec(caLink *pca) -{ - int cnt; - dbCaCallback callback; - void *userPvt = 0; - - cnt = epicsAtomicDecrIntT(&pca->refcount); - assert(cnt>=0); - if(cnt>0) - return; - - if (pca->chid) { - ca_clear_channel(pca->chid); - --dbca_chan_count; - } - callback = pca->putCallback; - if (callback) { - userPvt = pca->putUserPvt; - pca->putCallback = 0; - pca->putType = 0; - } - free(pca->pgetNative); - free(pca->pputNative); - free(pca->pgetString); - free(pca->pputString); - free(pca->pvname); - epicsMutexDestroy(pca->lock); - free(pca); - if (callback) callback(userPvt); -} - -/* Block until worker thread has processed all previously queued actions. - * Does not prevent additional actions from being queued. - */ -void dbCaSync(void) -{ - epicsEventId wake; - caLink templink; - - /* we only partially initialize templink. - * It has no link field and no subscription - * so the worker must handle it early - */ - memset(&templink, 0, sizeof(templink)); - templink.refcount = 1; - - wake = epicsEventMustCreate(epicsEventEmpty); - templink.lock = epicsMutexMustCreate(); - - templink.userPvt = wake; - - addAction(&templink, CA_SYNC); - - epicsEventMustWait(wake); - /* Worker holds workListLock when calling epicsEventMustTrigger() - * we cycle through workListLock to ensure worker call to - * epicsEventMustTrigger() returns before we destroy the event. - */ - epicsMutexMustLock(workListLock); - epicsMutexUnlock(workListLock); - - assert(templink.refcount==1); - - epicsMutexDestroy(templink.lock); - epicsEventDestroy(wake); -} - -epicsShareFunc unsigned long dbCaGetUpdateCount(struct link *plink) -{ - caLink *pca = (caLink *)plink->value.pv_link.pvt; - unsigned long ret; - - if (!pca) return (unsigned long)-1; - - epicsMutexMustLock(pca->lock); - - ret = pca->nUpdate; - - epicsMutexUnlock(pca->lock); - - return ret; -} - -void dbCaCallbackProcess(void *userPvt) -{ - struct link *plink = (struct link *)userPvt; - - dbLinkAsyncComplete(plink); -} - -void dbCaShutdown(void) -{ - enum dbCaCtl_t cur = dbCaCtl; - assert(cur == ctlRun || cur == ctlPause); - dbCaCtl = ctlExit; - epicsEventSignal(workListEvent); - epicsEventMustWait(startStopEvent); -} - -static void dbCaLinkInitImpl(int isolate) -{ - dbServiceIsolate = isolate; - dbServiceIOInit(); - - if (!workListLock) - workListLock = epicsMutexMustCreate(); - if (!workListEvent) - workListEvent = epicsEventMustCreate(epicsEventEmpty); - - if(!startStopEvent) - startStopEvent = epicsEventMustCreate(epicsEventEmpty); - dbCaCtl = ctlPause; - - epicsThreadCreate("dbCaLink", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackBig), - dbCaTask, NULL); - epicsEventMustWait(startStopEvent); -} - -void dbCaLinkInitIsolated(void) -{ - dbCaLinkInitImpl(1); -} - -void dbCaLinkInit(void) -{ - dbCaLinkInitImpl(0); -} - -void dbCaRun(void) -{ - if (dbCaCtl == ctlPause) { - dbCaCtl = ctlRun; - epicsEventSignal(workListEvent); - } -} - -void dbCaPause(void) -{ - if (dbCaCtl == ctlRun) { - dbCaCtl = ctlPause; - epicsEventSignal(workListEvent); - } -} - -void dbCaAddLinkCallback(struct link *plink, - dbCaCallback connect, dbCaCallback monitor, void *userPvt) -{ - caLink *pca; - - assert(!plink->value.pv_link.pvt); - - pca = (caLink *)dbCalloc(1, sizeof(caLink)); - pca->refcount = 1; - pca->lock = epicsMutexMustCreate(); - pca->plink = plink; - pca->pvname = epicsStrDup(plink->value.pv_link.pvname); - pca->connect = connect; - pca->monitor = monitor; - pca->userPvt = userPvt; - - epicsMutexMustLock(pca->lock); - plink->lset = &dbCa_lset; - plink->type = CA_LINK; - plink->value.pv_link.pvt = pca; - addAction(pca, CA_CONNECT); - epicsMutexUnlock(pca->lock); -} - -long dbCaAddLink(struct dbLocker *locker, struct link *plink, short dbfType) -{ - dbCaAddLinkCallback(plink, 0, 0, NULL); - return 0; -} - -void dbCaRemoveLink(struct dbLocker *locker, struct link *plink) -{ - caLink *pca = (caLink *)plink->value.pv_link.pvt; - - if (!pca) return; - epicsMutexMustLock(pca->lock); - pca->plink = 0; - plink->value.pv_link.pvt = 0; - plink->value.pv_link.pvlMask = 0; - plink->type = PV_LINK; - plink->lset = NULL; - /* Unlock before addAction or dbCaTask might free first */ - epicsMutexUnlock(pca->lock); - addAction(pca, CA_CLEAR_CHANNEL); -} - -long dbCaGetLink(struct link *plink, short dbrType, void *pdest, - long *nelements) -{ - caLink *pca = (caLink *)plink->value.pv_link.pvt; - long status = 0; - short link_action = 0; - int newType; - - assert(pca); - epicsMutexMustLock(pca->lock); - assert(pca->plink); - if (!pca->isConnected || !pca->hasReadAccess) { - pca->sevr = INVALID_ALARM; - pca->stat = LINK_ALARM; - status = -1; - goto done; - } - if (pca->dbrType == DBR_ENUM && dbDBRnewToDBRold[dbrType] == DBR_STRING){ - long (*fConvert)(const void *from, void *to, struct dbAddr *paddr); - - /* Subscribe as DBR_STRING */ - if (!pca->pgetString) { - plink->value.pv_link.pvlMask |= pvlOptInpString; - link_action |= CA_MONITOR_STRING; - } - if (!pca->gotInString) { - pca->sevr = INVALID_ALARM; - pca->stat = LINK_ALARM; - status = -1; - goto done; - } - if (nelements) *nelements = 1; - fConvert = dbFastGetConvertRoutine[dbDBRoldToDBFnew[DBR_STRING]][dbrType]; - status = fConvert(pca->pgetString, pdest, 0); - goto done; - } - if (!pca->pgetNative) { - plink->value.pv_link.pvlMask |= pvlOptInpNative; - link_action |= CA_MONITOR_NATIVE; - } - if (!pca->gotInNative){ - pca->sevr = INVALID_ALARM; - pca->stat = LINK_ALARM; - status = -1; - goto done; - } - newType = dbDBRoldToDBFnew[pca->dbrType]; - if (!nelements || *nelements == 1) { - long (*fConvert)(const void *from, void *to, struct dbAddr *paddr); - - fConvert = dbFastGetConvertRoutine[newType][dbrType]; - assert(pca->pgetNative); - status = fConvert(pca->pgetNative, pdest, 0); - } else { - unsigned long ntoget = *nelements; - struct dbAddr dbAddr; - long (*aConvert)(struct dbAddr *paddr, void *to, long nreq, long nto, long off); - - aConvert = dbGetConvertRoutine[newType][dbrType]; - assert(pca->pgetNative); - - if (ntoget > pca->usedelements) - ntoget = pca->usedelements; - *nelements = ntoget; - - memset((void *)&dbAddr, 0, sizeof(dbAddr)); - dbAddr.pfield = pca->pgetNative; - /*Following will only be used for pca->dbrType == DBR_STRING*/ - dbAddr.field_size = MAX_STRING_SIZE; - /*Ignore error return*/ - aConvert(&dbAddr, pdest, ntoget, ntoget, 0); - } -done: - if (link_action) - addAction(pca, link_action); - if (!status) - recGblInheritSevr(plink->value.pv_link.pvlMask & pvlOptMsMode, - plink->precord, pca->stat, pca->sevr); - epicsMutexUnlock(pca->lock); - - return status; -} - -static long dbCaPutAsync(struct link *plink,short dbrType, - const void *pbuffer,long nRequest) -{ - return dbCaPutLinkCallback(plink, dbrType, pbuffer, nRequest, - dbCaCallbackProcess, plink); -} - -long dbCaPutLinkCallback(struct link *plink,short dbrType, - const void *pbuffer,long nRequest,dbCaCallback callback,void *userPvt) -{ - caLink *pca = (caLink *)plink->value.pv_link.pvt; - long status = 0; - short link_action = 0; - - assert(pca); - /* put the new value in */ - epicsMutexMustLock(pca->lock); - assert(pca->plink); - if (!pca->isConnected || !pca->hasWriteAccess) { - epicsMutexUnlock(pca->lock); - return -1; - } - if (pca->dbrType == DBR_ENUM && dbDBRnewToDBRold[dbrType] == DBR_STRING) { - long (*fConvert)(const void *from, void *to, struct dbAddr *paddr); - - /* Send as DBR_STRING */ - if (!pca->pputString) { - pca->pputString = dbCalloc(1, MAX_STRING_SIZE); -/* Disabled by ANJ, needs a link flag to allow user to control this. - * Setting these makes the reconnect callback re-do the last CA put. - plink->value.pv_link.pvlMask |= pvlOptOutString; - */ - } - fConvert = dbFastPutConvertRoutine[dbrType][dbDBRoldToDBFnew[DBR_STRING]]; - status = fConvert(pbuffer, pca->pputString, 0); - link_action |= CA_WRITE_STRING; - pca->gotOutString = TRUE; - if (pca->newOutString) pca->nNoWrite++; - pca->newOutString = TRUE; - } else { - int newType = dbDBRoldToDBFnew[pca->dbrType]; - if (!pca->pputNative) { - pca->pputNative = dbCalloc(pca->nelements, - dbr_value_size[ca_field_type(pca->chid)]); - pca->putnelements = 0; -/* Fixed and disabled by ANJ, see comment above. - plink->value.pv_link.pvlMask |= pvlOptOutNative; - */ - } - if (nRequest == 1 && pca->nelements==1){ - long (*fConvert)(const void *from, void *to, struct dbAddr *paddr); - - fConvert = dbFastPutConvertRoutine[dbrType][newType]; - status = fConvert(pbuffer, pca->pputNative, 0); - pca->putnelements = 1; - } else { - struct dbAddr dbAddr; - long (*aConvert)(struct dbAddr *paddr, const void *from, long nreq, long nfrom, long off); - - aConvert = dbPutConvertRoutine[dbrType][newType]; - memset((void *)&dbAddr, 0, sizeof(dbAddr)); - dbAddr.pfield = pca->pputNative; - /*Following only used for DBF_STRING*/ - dbAddr.field_size = MAX_STRING_SIZE; - if(nRequest>pca->nelements) - nRequest = pca->nelements; - status = aConvert(&dbAddr, pbuffer, nRequest, pca->nelements, 0); - pca->putnelements = nRequest; - } - link_action |= CA_WRITE_NATIVE; - pca->gotOutNative = TRUE; - if (pca->newOutNative) pca->nNoWrite++; - pca->newOutNative = TRUE; - } - if (callback) { - pca->putType = CA_PUT_CALLBACK; - pca->putCallback = callback; - pca->putUserPvt = userPvt; - } else { - pca->putType = CA_PUT; - pca->putCallback = 0; - } - addAction(pca, link_action); - epicsMutexUnlock(pca->lock); - return status; -} - -long dbCaPutLink(struct link *plink, short dbrType, - const void *pbuffer, long nRequest) -{ - return dbCaPutLinkCallback(plink, dbrType, pbuffer, nRequest, 0, NULL); -} - -static int isConnected(const struct link *plink) -{ - caLink *pca; - - if (!plink || plink->type != CA_LINK) return FALSE; - pca = (caLink *)plink->value.pv_link.pvt; - if (!pca || !pca->chid) return FALSE; - return pca->isConnected; -} - -static void scanForward(struct link *plink) { - short fwdLinkValue = 1; - - if (plink->value.pv_link.pvlMask & pvlOptFWD) - dbCaPutLink(plink, DBR_SHORT, &fwdLinkValue, 1); -} - -#define pcaGetCheck \ - assert(plink); \ - if (plink->type != CA_LINK) return -1; \ - pca = (caLink *)plink->value.pv_link.pvt; \ - assert(pca); \ - epicsMutexMustLock(pca->lock); \ - assert(pca->plink); \ - if (!pca->isConnected) { \ - epicsMutexUnlock(pca->lock); \ - return -1; \ - } - -static long getElements(const struct link *plink, long *nelements) -{ - caLink *pca; - - pcaGetCheck - *nelements = pca->nelements; - epicsMutexUnlock(pca->lock); - return 0; -} - -static long getAlarm(const struct link *plink, - epicsEnum16 *pstat, epicsEnum16 *psevr) -{ - caLink *pca; - - pcaGetCheck - if (pstat) *pstat = pca->stat; - if (psevr) *psevr = pca->sevr; - epicsMutexUnlock(pca->lock); - return 0; -} - -static long getTimeStamp(const struct link *plink, - epicsTimeStamp *pstamp) -{ - caLink *pca; - - pcaGetCheck - memcpy(pstamp, &pca->timeStamp, sizeof(epicsTimeStamp)); - epicsMutexUnlock(pca->lock); - return 0; -} - -static int getDBFtype(const struct link *plink) -{ - caLink *pca; - int type; - - pcaGetCheck - type = dbDBRoldToDBFnew[pca->dbrType]; - epicsMutexUnlock(pca->lock); - return type; -} - -long dbCaGetAttributes(const struct link *plink, - dbCaCallback callback,void *userPvt) -{ - caLink *pca; - int gotAttributes; - - assert(plink); - if (plink->type != CA_LINK) return -1; - pca = (caLink *)plink->value.pv_link.pvt; - assert(pca); - epicsMutexMustLock(pca->lock); - assert(pca->plink); - pca->getAttributes = callback; - pca->getAttributesPvt = userPvt; - gotAttributes = pca->gotAttributes; - epicsMutexUnlock(pca->lock); - if (gotAttributes && callback) callback(userPvt); - return 0; -} - -static long getControlLimits(const struct link *plink, - double *low, double *high) -{ - caLink *pca; - int gotAttributes; - - pcaGetCheck - gotAttributes = pca->gotAttributes; - if (gotAttributes) { - *low = pca->controlLimits[0]; - *high = pca->controlLimits[1]; - } - epicsMutexUnlock(pca->lock); - return gotAttributes ? 0 : -1; -} - -static long getGraphicLimits(const struct link *plink, - double *low, double *high) -{ - caLink *pca; - int gotAttributes; - - pcaGetCheck - gotAttributes = pca->gotAttributes; - if (gotAttributes) { - *low = pca->displayLimits[0]; - *high = pca->displayLimits[1]; - } - epicsMutexUnlock(pca->lock); - return gotAttributes ? 0 : -1; -} - -static long getAlarmLimits(const struct link *plink, - double *lolo, double *low, double *high, double *hihi) -{ - caLink *pca; - int gotAttributes; - - pcaGetCheck - gotAttributes = pca->gotAttributes; - if (gotAttributes) { - *lolo = pca->alarmLimits[0]; - *low = pca->alarmLimits[1]; - *high = pca->alarmLimits[2]; - *hihi = pca->alarmLimits[3]; - } - epicsMutexUnlock(pca->lock); - return gotAttributes ? 0 : -1; -} - -static long getPrecision(const struct link *plink, short *precision) -{ - caLink *pca; - int gotAttributes; - - pcaGetCheck - gotAttributes = pca->gotAttributes; - if (gotAttributes) *precision = pca->precision; - epicsMutexUnlock(pca->lock); - return gotAttributes ? 0 : -1; -} - -static long getUnits(const struct link *plink, - char *units, int unitsSize) -{ - caLink *pca; - int gotAttributes; - - pcaGetCheck - gotAttributes = pca->gotAttributes; - if (unitsSize > sizeof(pca->units)) unitsSize = sizeof(pca->units); - if (gotAttributes) strncpy(units, pca->units, unitsSize); - units[unitsSize-1] = 0; - epicsMutexUnlock(pca->lock); - return gotAttributes ? 0 : -1; -} - -static long doLocked(struct link *plink, dbLinkUserCallback rtn, void *priv) -{ - caLink *pca; - long status; - - pcaGetCheck - status = rtn(plink, priv); - epicsMutexUnlock(pca->lock); - return status; -} - -static void scanComplete(void *raw, dbCommon *prec) -{ - caLink *pca = raw; - epicsMutexMustLock(pca->lock); - if(!pca->plink) { - /* IOC shutdown or link re-targeted. Do nothing. */ - } else if(pca->scanningOnce==0) { - errlogPrintf("dbCa.c complete callback w/ scanningOnce==0\n"); - } else if(--pca->scanningOnce){ - /* another scan is queued */ - if(scanOnceCallback(prec, scanComplete, raw)) { - errlogPrintf("dbCa.c failed to re-queue scanOnce\n"); - } else - caLinkInc(pca); - } - epicsMutexUnlock(pca->lock); - caLinkDec(pca); -} - -/* must be called with pca->lock held */ -static void scanLinkOnce(dbCommon *prec, caLink *pca) { - if(pca->scanningOnce==0) { - if(scanOnceCallback(prec, scanComplete, pca)) { - errlogPrintf("dbCa.c failed to queue scanOnce\n"); - } else - caLinkInc(pca); - } - if(pca->scanningOnce<5) - pca->scanningOnce++; - /* else too many scans queued */ -} - -static lset dbCa_lset = { - 0, 1, /* not Constant, Volatile */ - NULL, dbCaRemoveLink, - NULL, NULL, NULL, - isConnected, - getDBFtype, getElements, - dbCaGetLink, - getControlLimits, getGraphicLimits, getAlarmLimits, - getPrecision, getUnits, - getAlarm, getTimeStamp, - dbCaPutLink, dbCaPutAsync, - scanForward, doLocked -}; - -static void connectionCallback(struct connection_handler_args arg) -{ - caLink *pca; - short link_action = 0; - struct link *plink; - - pca = ca_puser(arg.chid); - assert(pca); - epicsMutexMustLock(pca->lock); - plink = pca->plink; - if (!plink) goto done; - pca->isConnected = (ca_state(arg.chid) == cs_conn); - if (!pca->isConnected) { - struct pv_link *ppv_link = &plink->value.pv_link; - dbCommon *precord = plink->precord; - - pca->nDisconnect++; - if (precord && - ((ppv_link->pvlMask & pvlOptCP) || - ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0))) - scanLinkOnce(precord, pca); - goto done; - } - pca->hasReadAccess = ca_read_access(arg.chid); - pca->hasWriteAccess = ca_write_access(arg.chid); - - if (pca->gotFirstConnection) { - if (pca->nelements != ca_element_count(arg.chid) || - pca->dbrType != ca_field_type(arg.chid)) { - /* BUG: We have no way to clear any old subscription with the - * originally chosen data type/size. That will continue - * to send us data and will result in an assert() fail. - */ - /* Let next dbCaGetLink and/or dbCaPutLink determine options */ - plink->value.pv_link.pvlMask &= - ~(pvlOptInpNative | pvlOptInpString | - pvlOptOutNative | pvlOptOutString); - - pca->gotInNative = 0; - pca->gotOutNative = 0; - pca->gotInString = 0; - pca->gotOutString = 0; - free(pca->pgetNative); pca->pgetNative = 0; - free(pca->pgetString); pca->pgetString = 0; - free(pca->pputNative); pca->pputNative = 0; - free(pca->pputString); pca->pputString = 0; - } - } - pca->gotFirstConnection = TRUE; - pca->nelements = ca_element_count(arg.chid); - pca->usedelements = 0; - pca->dbrType = ca_field_type(arg.chid); - if ((plink->value.pv_link.pvlMask & pvlOptInpNative) && !pca->pgetNative) { - link_action |= CA_MONITOR_NATIVE; - } - if ((plink->value.pv_link.pvlMask & pvlOptInpString) && !pca->pgetString) { - link_action |= CA_MONITOR_STRING; - } - if ((plink->value.pv_link.pvlMask & pvlOptOutNative) && pca->gotOutNative) { - link_action |= CA_WRITE_NATIVE; - } - if ((plink->value.pv_link.pvlMask & pvlOptOutString) && pca->gotOutString) { - link_action |= CA_WRITE_STRING; - } - pca->gotAttributes = 0; - if (pca->dbrType != DBR_STRING) { - link_action |= CA_GET_ATTRIBUTES; - } -done: - if (link_action) addAction(pca, link_action); - epicsMutexUnlock(pca->lock); -} - -static void eventCallback(struct event_handler_args arg) -{ - caLink *pca = (caLink *)arg.usr; - struct link *plink; - size_t size; - dbCommon *precord = 0; - struct dbr_time_double *pdbr_time_double; - dbCaCallback monitor = 0; - void *userPvt = 0; - - assert(pca); - epicsMutexMustLock(pca->lock); - plink = pca->plink; - if (!plink) goto done; - pca->nUpdate++; - monitor = pca->monitor; - userPvt = pca->userPvt; - precord = plink->precord; - if (arg.status != ECA_NORMAL) { - if (precord) { - if (arg.status != ECA_NORDACCESS && - arg.status != ECA_GETFAIL) - errlogPrintf("dbCa: eventCallback record %s error %s\n", - precord->name, ca_message(arg.status)); - } else { - errlogPrintf("dbCa: eventCallback error %s\n", - ca_message(arg.status)); - } - goto done; - } - assert(arg.dbr); - assert(arg.count<=pca->nelements); - size = arg.count * dbr_value_size[arg.type]; - if (arg.type == DBR_TIME_STRING && - ca_field_type(pca->chid) == DBR_ENUM) { - assert(pca->pgetString); - memcpy(pca->pgetString, dbr_value_ptr(arg.dbr, arg.type), size); - pca->gotInString = TRUE; - } else switch (arg.type){ - case DBR_TIME_STRING: - case DBR_TIME_SHORT: - case DBR_TIME_FLOAT: - case DBR_TIME_ENUM: - case DBR_TIME_CHAR: - case DBR_TIME_LONG: - case DBR_TIME_DOUBLE: - assert(pca->pgetNative); - memcpy(pca->pgetNative, dbr_value_ptr(arg.dbr, arg.type), size); - pca->usedelements = arg.count; - pca->gotInNative = TRUE; - break; - default: - errlogPrintf("dbCa: eventCallback Logic Error. dbr=%ld dbf=%d\n", - arg.type, ca_field_type(pca->chid)); - break; - } - pdbr_time_double = (struct dbr_time_double *)arg.dbr; - pca->sevr = pdbr_time_double->severity; - pca->stat = pdbr_time_double->status; - memcpy(&pca->timeStamp, &pdbr_time_double->stamp, sizeof(epicsTimeStamp)); - if (precord) { - struct pv_link *ppv_link = &plink->value.pv_link; - - if ((ppv_link->pvlMask & pvlOptCP) || - ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0)) - scanLinkOnce(precord, pca); - } -done: - epicsMutexUnlock(pca->lock); - if (monitor) monitor(userPvt); -} - -static void exceptionCallback(struct exception_handler_args args) -{ - const char *context = (args.ctx ? args.ctx : "unknown"); - - errlogPrintf("DB CA Link Exception: \"%s\", context \"%s\"\n", - ca_message(args.stat), context); - if (args.chid) { - errlogPrintf( - "DB CA Link Exception: channel \"%s\"\n", - ca_name(args.chid)); - if (ca_state(args.chid) == cs_conn) { - errlogPrintf( - "DB CA Link Exception: native T=%s, request T=%s," - " native N=%ld, request N=%ld, " - " access rights {%s%s}\n", - dbr_type_to_text(ca_field_type(args.chid)), - dbr_type_to_text(args.type), - ca_element_count(args.chid), - args.count, - ca_read_access(args.chid) ? "R" : "", - ca_write_access(args.chid) ? "W" : ""); - } - } -} - -static void putComplete(struct event_handler_args arg) -{ - caLink *pca = (caLink *)arg.usr; - struct link *plink; - dbCaCallback callback = 0; - void *userPvt = 0; - - epicsMutexMustLock(pca->lock); - plink = pca->plink; - if (!plink) goto done; - callback = pca->putCallback; - userPvt = pca->putUserPvt; - pca->putCallback = 0; - pca->putType = 0; - pca->putUserPvt = 0; -done: - epicsMutexUnlock(pca->lock); - if (callback) callback(userPvt); -} - -static void accessRightsCallback(struct access_rights_handler_args arg) -{ - caLink *pca = (caLink *)ca_puser(arg.chid); - struct link *plink; - struct pv_link *ppv_link; - dbCommon *precord; - - assert(pca); - if (ca_state(pca->chid) != cs_conn) - return; /* connectionCallback will handle */ - epicsMutexMustLock(pca->lock); - plink = pca->plink; - if (!plink) goto done; - pca->hasReadAccess = ca_read_access(arg.chid); - pca->hasWriteAccess = ca_write_access(arg.chid); - if (pca->hasReadAccess && pca->hasWriteAccess) goto done; - ppv_link = &plink->value.pv_link; - precord = plink->precord; - if (precord && - ((ppv_link->pvlMask & pvlOptCP) || - ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0))) - scanLinkOnce(precord, pca); -done: - epicsMutexUnlock(pca->lock); -} - -static void getAttribEventCallback(struct event_handler_args arg) -{ - caLink *pca = (caLink *)arg.usr; - struct link *plink; - struct dbr_ctrl_double *pdbr; - dbCaCallback connect = 0; - void *userPvt = 0; - dbCaCallback getAttributes = 0; - void *getAttributesPvt; - - assert(pca); - epicsMutexMustLock(pca->lock); - plink = pca->plink; - if (!plink) { - epicsMutexUnlock(pca->lock); - return; - } - connect = pca->connect; - userPvt = pca->userPvt; - getAttributes = pca->getAttributes; - getAttributesPvt = pca->getAttributesPvt; - if (arg.status != ECA_NORMAL) { - dbCommon *precord = plink->precord; - if (precord) { - errlogPrintf("dbCa: getAttribEventCallback record %s error %s\n", - precord->name, ca_message(arg.status)); - } else { - errlogPrintf("dbCa: getAttribEventCallback error %s\n", - ca_message(arg.status)); - } - epicsMutexUnlock(pca->lock); - return; - } - assert(arg.dbr); - pdbr = (struct dbr_ctrl_double *)arg.dbr; - pca->gotAttributes = TRUE; - pca->controlLimits[0] = pdbr->lower_ctrl_limit; - pca->controlLimits[1] = pdbr->upper_ctrl_limit; - pca->displayLimits[0] = pdbr->lower_disp_limit; - pca->displayLimits[1] = pdbr->upper_disp_limit; - pca->alarmLimits[0] = pdbr->lower_alarm_limit; - pca->alarmLimits[1] = pdbr->lower_warning_limit; - pca->alarmLimits[2] = pdbr->upper_warning_limit; - pca->alarmLimits[3] = pdbr->upper_alarm_limit; - pca->precision = pdbr->precision; - memcpy(pca->units, pdbr->units, MAX_UNITS_SIZE); - epicsMutexUnlock(pca->lock); - if (getAttributes) getAttributes(getAttributesPvt); - if (connect) connect(userPvt); -} - -static void dbCaTask(void *arg) -{ - taskwdInsert(0, NULL, NULL); - SEVCHK(ca_context_create(ca_enable_preemptive_callback), - "dbCaTask calling ca_context_create"); - dbCaClientContext = ca_current_context (); - SEVCHK(ca_add_exception_event(exceptionCallback,NULL), - "ca_add_exception_event"); - epicsEventSignal(startStopEvent); - - /* channel access event loop */ - while (TRUE){ - do { - epicsEventMustWait(workListEvent); - } while (dbCaCtl == ctlPause); - while (TRUE) { /* process all requests in workList*/ - caLink *pca; - short link_action; - int status; - - epicsMutexMustLock(workListLock); - if (!(pca = (caLink *)ellGet(&workList))){ /* Take off list head */ - epicsMutexUnlock(workListLock); - if (dbCaCtl == ctlExit) goto shutdown; - break; /* workList is empty */ - } - link_action = pca->link_action; - if (link_action&CA_SYNC) - epicsEventMustTrigger((epicsEventId)pca->userPvt); /* dbCaSync() requires workListLock to be held here */ - pca->link_action = 0; - if (link_action & CA_CLEAR_CHANNEL) --removesOutstanding; - epicsMutexUnlock(workListLock); /* Give back immediately */ - if (link_action&CA_SYNC) - continue; - if (link_action & CA_CLEAR_CHANNEL) { /* This must be first */ - caLinkDec(pca); - /* No alarm is raised. Since link is changing so what? */ - continue; /* No other link_action makes sense */ - } - if (link_action & CA_CONNECT) { - status = ca_create_channel( - pca->pvname,connectionCallback,(void *)pca, - CA_PRIORITY_DB_LINKS, &(pca->chid)); - if (status != ECA_NORMAL) { - errlogPrintf("dbCaTask ca_create_channel %s\n", - ca_message(status)); - printLinks(pca); - continue; - } - dbca_chan_count++; - status = ca_replace_access_rights_event(pca->chid, - accessRightsCallback); - if (status != ECA_NORMAL) { - errlogPrintf("dbCaTask replace_access_rights_event %s\n", - ca_message(status)); - printLinks(pca); - } - continue; /*Other options must wait until connect*/ - } - if (ca_state(pca->chid) != cs_conn) continue; - if (link_action & CA_WRITE_NATIVE) { - assert(pca->pputNative); - if (pca->putType == CA_PUT) { - status = ca_array_put( - pca->dbrType, pca->putnelements, - pca->chid, pca->pputNative); - } else if (pca->putType==CA_PUT_CALLBACK) { - status = ca_array_put_callback( - pca->dbrType, pca->putnelements, - pca->chid, pca->pputNative, - putComplete, pca); - } else { - status = ECA_PUTFAIL; - } - if (status != ECA_NORMAL) { - errlogPrintf("dbCaTask ca_array_put %s\n", - ca_message(status)); - printLinks(pca); - } - epicsMutexMustLock(pca->lock); - if (status == ECA_NORMAL) pca->newOutNative = FALSE; - epicsMutexUnlock(pca->lock); - } - if (link_action & CA_WRITE_STRING) { - assert(pca->pputString); - if (pca->putType == CA_PUT) { - status = ca_array_put( - DBR_STRING, 1, - pca->chid, pca->pputString); - } else if (pca->putType==CA_PUT_CALLBACK) { - status = ca_array_put_callback( - DBR_STRING, 1, - pca->chid, pca->pputString, - putComplete, pca); - } else { - status = ECA_PUTFAIL; - } - if (status != ECA_NORMAL) { - errlogPrintf("dbCaTask ca_array_put %s\n", - ca_message(status)); - printLinks(pca); - } - epicsMutexMustLock(pca->lock); - if (status == ECA_NORMAL) pca->newOutString = FALSE; - epicsMutexUnlock(pca->lock); - } - /*CA_GET_ATTRIBUTES before CA_MONITOR so that attributes available - * before the first monitor callback */ - if (link_action & CA_GET_ATTRIBUTES) { - status = ca_get_callback(DBR_CTRL_DOUBLE, - pca->chid, getAttribEventCallback, pca); - if (status != ECA_NORMAL) { - errlogPrintf("dbCaTask ca_get_callback %s\n", - ca_message(status)); - printLinks(pca); - } - } - if (link_action & CA_MONITOR_NATIVE) { - - epicsMutexMustLock(pca->lock); - pca->elementSize = dbr_value_size[ca_field_type(pca->chid)]; - pca->pgetNative = dbCalloc(pca->nelements, pca->elementSize); - epicsMutexUnlock(pca->lock); - - status = ca_add_array_event( - dbf_type_to_DBR_TIME(ca_field_type(pca->chid)), - 0, /* dynamic size */ - pca->chid, eventCallback, pca, 0.0, 0.0, 0.0, 0); - if (status != ECA_NORMAL) { - errlogPrintf("dbCaTask ca_add_array_event %s\n", - ca_message(status)); - printLinks(pca); - } - } - if (link_action & CA_MONITOR_STRING) { - epicsMutexMustLock(pca->lock); - pca->pgetString = dbCalloc(1, MAX_STRING_SIZE); - epicsMutexUnlock(pca->lock); - status = ca_add_array_event(DBR_TIME_STRING, 1, - pca->chid, eventCallback, pca, 0.0, 0.0, 0.0, 0); - if (status != ECA_NORMAL) { - errlogPrintf("dbCaTask ca_add_array_event %s\n", - ca_message(status)); - printLinks(pca); - } - } - } - SEVCHK(ca_flush_io(), "dbCaTask"); - } -shutdown: - taskwdRemove(0); - if (dbca_chan_count == 0) - ca_context_destroy(); - else - fprintf(stderr, "dbCa: chan_count = %d at shutdown\n", dbca_chan_count); - epicsEventSignal(startStopEvent); -} diff --git a/src/ioc/db/dbCa.h b/src/ioc/db/dbCa.h deleted file mode 100644 index de25ef59f..000000000 --- a/src/ioc/db/dbCa.h +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbCa.h */ - -#ifndef INCdbCah -#define INCdbCah - -#include "dbLink.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*dbCaCallback)(void *userPvt); -epicsShareFunc void dbCaCallbackProcess(void *usrPvt); - -epicsShareFunc void dbCaLinkInit(void); /* internal initialization for iocBuild() */ -epicsShareFunc void dbCaLinkInitIsolated(void); /* internal initialization for iocBuildIsolated() */ -epicsShareFunc void dbCaRun(void); -epicsShareFunc void dbCaPause(void); -epicsShareFunc void dbCaShutdown(void); - -struct dbLocker; -epicsShareFunc void dbCaAddLinkCallback(struct link *plink, - dbCaCallback connect, dbCaCallback monitor, void *userPvt); -epicsShareFunc long dbCaAddLink(struct dbLocker *locker, struct link *plink, short dbfType); -epicsShareFunc void dbCaRemoveLink(struct dbLocker *locker, struct link *plink); - -epicsShareFunc long dbCaGetLink(struct link *plink, - short dbrType, void *pbuffer, long *nRequest); - -epicsShareFunc long dbCaGetAttributes(const struct link *plink, - dbCaCallback callback, void *userPvt); - -epicsShareFunc long dbCaPutLinkCallback(struct link *plink, - short dbrType, const void *pbuffer,long nRequest, - dbCaCallback callback, void *userPvt); -epicsShareFunc long dbCaPutLink(struct link *plink,short dbrType, - const void *pbuffer,long nRequest); - -extern struct ca_client_context * dbCaClientContext; - -#ifdef EPICS_DBCA_PRIVATE_API -epicsShareFunc void dbCaSync(void); -epicsShareFunc unsigned long dbCaGetUpdateCount(struct link *plink); -#endif - -/* These macros are for backwards compatibility */ - -#define dbCaIsLinkConnected(link) \ - dbIsLinkConnected(link) - -#define dbCaGetLinkDBFtype(link) \ - dbGetLinkDBFtype(link) -#define dbCaGetNelements(link, nelements) \ - dbGetNelements(link, nelements) -#define dbCaGetSevr(link, sevr) \ - dbGetAlarm(link, NULL, sevr) -#define dbCaGetAlarm(link, stat, sevr) \ - dbGetAlarm(link, stat, sevr) -#define dbCaGetTimeStamp(link, pstamp) \ - dbGetTimeStamp(link, pstamp) -#define dbCaGetControlLimits(link, low, high) \ - dbGetControlLimits(link, low, high) -#define dbCaGetGraphicLimits(link, low, high) \ - dbGetGraphicLimits(link, low, high) -#define dbCaGetAlarmLimits(link, lolo, low, high, hihi) \ - dbGetAlarmLimits(link, lolo, low, high, hihi) -#define dbCaGetPrecision(link, prec) \ - dbGetPrecision(link, prec) -#define dbCaGetUnits(link, units, unitSize) \ - dbGetUnits(link, units, unitSize) - -#define dbCaScanFwdLink(link) \ - dbScanFwdLink(link) - -#ifdef __cplusplus -} -#endif - -#endif /*INCdbCah*/ diff --git a/src/ioc/db/dbCaPvt.h b/src/ioc/db/dbCaPvt.h deleted file mode 100644 index 454ead5ac..000000000 --- a/src/ioc/db/dbCaPvt.h +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbCaPvt.h - * - * Original Authors: Bob Dalesio, Marty Kraimer - * - */ - -#ifndef INC_dbCaPvt_H -#define INC_dbCaPvt_H - -#include "dbCa.h" -#include "ellLib.h" -#include "epicsMutex.h" -#include "epicsTypes.h" -#include "link.h" - -/* link_action mask */ -#define CA_CLEAR_CHANNEL 0x1 -#define CA_CONNECT 0x2 -#define CA_WRITE_NATIVE 0x4 -#define CA_WRITE_STRING 0x8 -#define CA_MONITOR_NATIVE 0x10 -#define CA_MONITOR_STRING 0x20 -#define CA_GET_ATTRIBUTES 0x40 -#define CA_SYNC 0x1000 -/* write type */ -#define CA_PUT 0x1 -#define CA_PUT_CALLBACK 0x2 - -typedef struct caLink -{ - ELLNODE node; - int refcount; - epicsMutexId lock; - struct link *plink; - char *pvname; - chid chid; - short link_action; - /* The following have new values after each data event*/ - epicsEnum16 sevr; - epicsEnum16 stat; - epicsTimeStamp timeStamp; - /* The following have values after connection*/ - short dbrType; - size_t elementSize; /* size of one element in pgetNative */ - unsigned long nelements; /* PVs max array size */ - unsigned long usedelements; /* currently used in pgetNative */ - unsigned long putnelements; /* currently used in pputNative */ - char hasReadAccess; - char hasWriteAccess; - char isConnected; - char gotFirstConnection; - /* The following are for dbCaAddLinkCallback */ - dbCaCallback connect; - dbCaCallback monitor; - void *userPvt; - /* The following are for write request */ - short putType; - dbCaCallback putCallback; - void *putUserPvt; - /* The following are for access to additional attributes*/ - char gotAttributes; - dbCaCallback getAttributes; - void *getAttributesPvt; - /* The following have values after getAttribEventCallback*/ - double controlLimits[2]; - double displayLimits[2]; - double alarmLimits[4]; - short precision; - char units[MAX_UNITS_SIZE]; /* units of value */ - /* The following are for handling data*/ - void *pgetNative; - char *pgetString; - void *pputNative; - char *pputString; - char gotInNative; - char gotInString; - char gotOutNative; - char gotOutString; - char newOutNative; - char newOutString; - unsigned char scanningOnce; - /* The following are for dbcar*/ - unsigned long nDisconnect; - unsigned long nNoWrite; /*only modified by dbCaPutLink*/ - unsigned long nUpdate; -}caLink; - -#endif /* INC_dbCaPvt_H */ diff --git a/src/ioc/db/dbCaTest.c b/src/ioc/db/dbCaTest.c deleted file mode 100644 index 18ef393ca..000000000 --- a/src/ioc/db/dbCaTest.c +++ /dev/null @@ -1,206 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbCaTest.c */ - -/**************************************************************** -* -* Author: Marty Kraimer -* Date: 10APR96 -* -****************************************************************/ - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsEvent.h" -#include "epicsPrint.h" -#include "epicsStdio.h" - -#define epicsExportSharedSymbols -#include "dbStaticLib.h" -#undef epicsExportSharedSymbols -/*definitions needed because of old vs new database access*/ -#undef DBR_SHORT -#undef DBR_PUT_ACKT -#undef DBR_PUT_ACKS -#undef VALID_DB_REQ -#undef INVALID_DB_REQ -/*end of conflicting definitions*/ - -#include "cadef.h" - -/*define DB_CONVERT_GBLSOURCE because db_access.c does not include db_access.h*/ -#define DB_CONVERT_GBLSOURCE - -#define epicsExportSharedSymbols -#include "db_access.h" -#include "db_access_routines.h" -#include "dbCa.h" -#include "dbCaPvt.h" -#include "dbCaTest.h" -#include "dbCommon.h" -#include "db_convert.h" -#include "dbLock.h" -#include "link.h" - - -long dbcar(char *precordname, int level) -{ - DBENTRY dbentry; - DBENTRY *pdbentry=&dbentry; - long status; - dbCommon *precord; - dbRecordType *pdbRecordType; - dbFldDes *pdbFldDes; - DBLINK *plink; - int ncalinks=0; - int nconnected=0; - int noReadAccess=0; - int noWriteAccess=0; - unsigned long nDisconnect=0; - unsigned long nNoWrite=0; - caLink *pca; - int j; - - if (!precordname || precordname[0] == '\0' || !strcmp(precordname, "*")) { - precordname = NULL; - printf("CA links in all records\n\n"); - } else { - printf("CA links in record named '%s'\n\n", precordname); - } - dbInitEntry(pdbbase,pdbentry); - status = dbFirstRecordType(pdbentry); - while (!status) { - status = dbFirstRecord(pdbentry); - while (!status) { - if (precordname ? - !strcmp(precordname, dbGetRecordName(pdbentry)) : - !dbIsAlias(pdbentry)) { - pdbRecordType = pdbentry->precordType; - precord = (dbCommon *)pdbentry->precnode->precord; - dbScanLock(precord); - for (j=0; jno_links; j++) { - pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->link_ind[j]]; - plink = (DBLINK *)((char *)precord + pdbFldDes->offset); - if (plink->type == CA_LINK) { - ncalinks++; - pca = (caLink *)plink->value.pv_link.pvt; - if (pca - && pca->chid - && (ca_field_type(pca->chid) != TYPENOTCONN)) { - nconnected++; - nDisconnect += pca->nDisconnect; - nNoWrite += pca->nNoWrite; - if (!ca_read_access(pca->chid)) noReadAccess++; - if (!ca_write_access(pca->chid)) noWriteAccess++; - if (level>1) { - int rw = ca_read_access(pca->chid) | - ca_write_access(pca->chid) << 1; - static const char *rights[4] = { - "No Access", "Read Only", - "Write Only", "Read/Write" - }; - int mask = plink->value.pv_link.pvlMask; - printf("%28s.%-4s ==> %-28s (%lu, %lu)\n", - precord->name, - pdbFldDes->name, - plink->value.pv_link.pvname, - pca->nDisconnect, - pca->nNoWrite); - printf("%21s [%s%s%s%s] host %s, %s\n", "", - mask & pvlOptInpNative ? "IN" : " ", - mask & pvlOptInpString ? "IS" : " ", - mask & pvlOptOutNative ? "ON" : " ", - mask & pvlOptOutString ? "OS" : " ", - ca_host_name(pca->chid), - rights[rw]); - } - } else { - if (level>0) { - printf("%28s.%-4s --> %-28s (%lu, %lu)\n", - precord->name, - pdbFldDes->name, - plink->value.pv_link.pvname, - pca ? pca->nDisconnect : 0, - pca ? pca->nNoWrite : 0); - } - } - } - } - dbScanUnlock(precord); - if (precordname) goto done; - } - status = dbNextRecord(pdbentry); - } - status = dbNextRecordType(pdbentry); - } -done: - if ((level > 1 && nconnected > 0) || - (level > 0 && ncalinks != nconnected)) printf("\n"); - printf("Total %d CA link%s; ", - ncalinks, (ncalinks != 1) ? "s" : ""); - printf("%d connected, %d not connected.\n", - nconnected, (ncalinks - nconnected)); - printf(" %d can't read, %d can't write.", - noReadAccess, noWriteAccess); - printf(" (%lu disconnects, %lu writes prohibited)\n\n", - nDisconnect, nNoWrite); - dbFinishEntry(pdbentry); - - if ( level > 2 && dbCaClientContext != 0 ) { - ca_context_status ( dbCaClientContext, level - 2 ); - } - - return(0); -} - -void dbcaStats(int *pchans, int *pdiscon) -{ - DBENTRY dbentry; - DBENTRY *pdbentry = &dbentry; - long status; - DBLINK *plink; - long ncalinks = 0; - long nconnected = 0; - - dbInitEntry(pdbbase,pdbentry); - status = dbFirstRecordType(pdbentry); - while (!status) { - dbRecordType *pdbRecordType = pdbentry->precordType; - - status = dbFirstRecord(pdbentry); - while (!status) { - dbCommon *precord = (dbCommon *)pdbentry->precnode->precord; - int j; - - if (!dbIsAlias(pdbentry)) { - for (j=0; jno_links; j++) { - int i = pdbRecordType->link_ind[j]; - - dbFldDes *pdbFldDes = pdbRecordType->papFldDes[i]; - plink = (DBLINK *)((char *)precord + pdbFldDes->offset); - if (plink->type == CA_LINK) { - ncalinks++; - if (dbCaIsLinkConnected(plink)) { - nconnected++; - } - } - } - } - status = dbNextRecord(pdbentry); - } - status = dbNextRecordType(pdbentry); - } - dbFinishEntry(pdbentry); - if (pchans) *pchans = ncalinks; - if (pdiscon) *pdiscon = ncalinks - nconnected; -} diff --git a/src/ioc/db/dbCaTest.h b/src/ioc/db/dbCaTest.h deleted file mode 100644 index ed501df2d..000000000 --- a/src/ioc/db/dbCaTest.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_dbCaTest_H -#define INC_dbCaTest_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc long dbcar(char *recordname,int level); -epicsShareFunc void dbcaStats(int *pchans, int *pdiscon); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbCaTest_H */ diff --git a/src/ioc/db/dbChannel.c b/src/ioc/db/dbChannel.c deleted file mode 100644 index 5ce1be4ef..000000000 --- a/src/ioc/db/dbChannel.c +++ /dev/null @@ -1,827 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - * Ralph Lange - */ - -#include -#include -#include - -#include "cantProceed.h" -#include "epicsAssert.h" -#include "epicsString.h" -#include "errlog.h" -#include "freeList.h" -#include "gpHash.h" -#include "yajl_parse.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbBase.h" -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbEvent.h" -#include "dbLock.h" -#include "dbStaticLib.h" -#include "link.h" -#include "recSup.h" -#include "special.h" - -typedef struct parseContext { - dbChannel *chan; - chFilter *filter; - int depth; -} parseContext; - -#define CALLIF(rtn) !rtn ? parse_stop : rtn - -static void *dbChannelFreeList; -static void *chFilterFreeList; -static void *dbchStringFreeList; - -void dbChannelExit(void) -{ - freeListCleanup(dbChannelFreeList); - freeListCleanup(chFilterFreeList); - freeListCleanup(dbchStringFreeList); - dbChannelFreeList = chFilterFreeList = dbchStringFreeList = NULL; -} - -void dbChannelInit (void) -{ - if(dbChannelFreeList) - return; - - freeListInitPvt(&dbChannelFreeList, sizeof(dbChannel), 128); - freeListInitPvt(&chFilterFreeList, sizeof(chFilter), 64); - freeListInitPvt(&dbchStringFreeList, sizeof(epicsOldString), 128); -} - -static void chf_value(parseContext *parser, parse_result *presult) -{ - chFilter *filter = parser->filter; - - if (*presult == parse_stop || parser->depth > 0) - return; - - parser->filter = NULL; - if (filter->plug->fif->parse_end(filter) == parse_continue) { - ellAdd(&parser->chan->filters, &filter->list_node); - } else { - freeListFree(chFilterFreeList, filter); - *presult = parse_stop; - } -} - -static int chf_null(void * ctx) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - parse_result result; - - assert(filter); - result = CALLIF(filter->plug->fif->parse_null)(filter ); - chf_value(parser, &result); - return result; -} - -static int chf_boolean(void * ctx, int boolVal) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - parse_result result; - - assert(filter); - result = CALLIF(filter->plug->fif->parse_boolean)(filter , boolVal); - chf_value(parser, &result); - return result; -} - -static int chf_integer(void * ctx, long integerVal) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - parse_result result; - - assert(filter); - result = CALLIF(filter->plug->fif->parse_integer)(filter , integerVal); - chf_value(parser, &result); - return result; -} - -static int chf_double(void * ctx, double doubleVal) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - parse_result result; - - assert(filter); - result = CALLIF(filter->plug->fif->parse_double)(filter , doubleVal); - chf_value(parser, &result); - return result; -} - -static int chf_string(void * ctx, const unsigned char * stringVal, - unsigned int stringLen) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - parse_result result; - - assert(filter); - result = CALLIF(filter->plug->fif->parse_string)(filter , (const char *) stringVal, stringLen); - chf_value(parser, &result); - return result; -} - -static int chf_start_map(void * ctx) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - - if (!filter) { - assert(parser->depth == 0); - return parse_continue; /* Opening '{' */ - } - - ++parser->depth; - return CALLIF(filter->plug->fif->parse_start_map)(filter ); -} - -static int chf_map_key(void * ctx, const unsigned char * key, - unsigned int stringLen) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - const chFilterPlugin *plug; - parse_result result; - - if (filter) { - assert(parser->depth > 0); - return CALLIF(filter->plug->fif->parse_map_key)(filter , (const char *) key, stringLen); - } - - assert(parser->depth == 0); - plug = dbFindFilter((const char *) key, stringLen); - if (!plug) { - errlogPrintf("dbChannelCreate: Channel filter '%.*s' not found\n", - (int) stringLen, key); - return parse_stop; - } - - filter = freeListCalloc(chFilterFreeList); - if (!filter) { - errlogPrintf("dbChannelCreate: Out of memory\n"); - return parse_stop; - } - filter->chan = parser->chan; - filter->plug = plug; - filter->puser = NULL; - - result = plug->fif->parse_start(filter); - if (result == parse_continue) { - parser->filter = filter; - } else { - freeListFree(chFilterFreeList, filter); - } - return result; -} - -static int chf_end_map(void * ctx) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - parse_result result; - - if (!filter) { - assert(parser->depth == 0); - return parse_continue; /* Final closing '}' */ - } - - assert(parser->depth > 0); - result = CALLIF(filter->plug->fif->parse_end_map)(filter ); - - --parser->depth; - chf_value(parser, &result); - return result; -} - -static int chf_start_array(void * ctx) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - - assert(filter); - ++parser->depth; - return CALLIF(filter->plug->fif->parse_start_array)(filter ); -} - -static int chf_end_array(void * ctx) -{ - parseContext *parser = (parseContext *) ctx; - chFilter *filter = parser->filter; - parse_result result; - - assert(filter); - result = CALLIF(filter->plug->fif->parse_end_array)(filter ); - --parser->depth; - chf_value(parser, &result); - return result; -} - -static const yajl_callbacks chf_callbacks = - { chf_null, chf_boolean, chf_integer, chf_double, NULL, chf_string, - chf_start_map, chf_map_key, chf_end_map, chf_start_array, chf_end_array }; - -static const yajl_parser_config chf_config = - { 0, 1 }; /* allowComments = NO , checkUTF8 = YES */ - -static void * chf_malloc(void *ctx, unsigned int sz) -{ - return malloc(sz); -} - -static void * chf_realloc(void *ctx, void *ptr, unsigned int sz) -{ - return realloc(ptr, sz); -} - -static void chf_free(void *ctx, void *ptr) -{ - free(ptr); -} - -static const yajl_alloc_funcs chf_alloc = - { chf_malloc, chf_realloc, chf_free }; - -static long chf_parse(dbChannel *chan, const char **pjson) -{ - parseContext parser = - { chan, NULL, 0 }; - yajl_handle yh = yajl_alloc(&chf_callbacks, &chf_config, &chf_alloc, &parser); - const char *json = *pjson; - size_t jlen = strlen(json); - yajl_status ys; - long status; - - if (!yh) - return S_db_noMemory; - - ys = yajl_parse(yh, (const unsigned char *) json, (unsigned int) jlen); - if (ys == yajl_status_insufficient_data) - ys = yajl_parse_complete(yh); - - switch (ys) { - case yajl_status_ok: - status = 0; - *pjson += yajl_get_bytes_consumed(yh); - break; - - case yajl_status_error: { - unsigned char *err; - - err = yajl_get_error(yh, 1, (const unsigned char *) json, (unsigned int) jlen); - printf("dbChannelCreate: %s\n", err); - yajl_free_error(yh, err); - } /* fall through */ - default: - status = S_db_notFound; - } - - if (parser.filter) { - assert(status); - parser.filter->plug->fif->parse_abort(parser.filter); - freeListFree(chFilterFreeList, parser.filter); - } - yajl_free(yh); - return status; -} - -static long pvNameLookup(DBENTRY *pdbe, const char **ppname) -{ - long status; - - dbInitEntry(pdbbase, pdbe); - - status = dbFindRecordPart(pdbe, ppname); - if (status) - return status; - - if (**ppname == '.') - ++*ppname; - - status = dbFindFieldPart(pdbe, ppname); - if (status == S_dbLib_fieldNotFound) - status = dbGetAttributePart(pdbe, ppname); - - return status; -} - -long dbChannelTest(const char *name) -{ - DBENTRY dbEntry; - long status; - - if (!name || !*name || !pdbbase) - return S_db_notFound; - - status = pvNameLookup(&dbEntry, &name); - - dbFinishEntry(&dbEntry); - return status; -} - -#define TRY(Func, Arg) \ -if (Func) { \ - result = Func Arg; \ - if (result != parse_continue) goto failure; \ -} - -static long parseArrayRange(dbChannel* chan, const char *pname, const char **ppnext) { - epicsInt32 start = 0; - epicsInt32 end = -1; - epicsInt32 incr = 1; - epicsInt32 l; - char *pnext; - ptrdiff_t exist; - chFilter *filter; - const chFilterPlugin *plug; - parse_result result; - long status = 0; - - /* If no number is present, strtol() returns 0 and sets pnext=pname, - else pnext points to the first char after the number */ - pname++; - l = strtol(pname, &pnext, 0); - exist = pnext - pname; - if (exist) start = l; - pname = pnext; - if (*pname == ']' && exist) { - end = start; - goto insertplug; - } - if (*pname != ':') { - status = S_dbLib_fieldNotFound; - goto finish; - } - pname++; - l = strtol(pname, &pnext, 0); - exist = pnext - pname; - pname = pnext; - if (*pname == ']') { - if (exist) end = l; - goto insertplug; - } - if (exist) incr = l; - if (*pname != ':') { - status = S_dbLib_fieldNotFound; - goto finish; - } - pname++; - l = strtol(pname, &pnext, 0); - exist = pnext - pname; - if (exist) end = l; - pname = pnext; - if (*pname != ']') { - status = S_dbLib_fieldNotFound; - goto finish; - } - - insertplug: - pname++; - *ppnext = pname; - - plug = dbFindFilter("arr", 3); - if (!plug) { - status = S_dbLib_fieldNotFound; - goto finish; - } - - filter = freeListCalloc(chFilterFreeList); - if (!filter) { - status = S_db_noMemory; - goto finish; - } - filter->chan = chan; - filter->plug = plug; - filter->puser = NULL; - - TRY(filter->plug->fif->parse_start, (filter)); - TRY(filter->plug->fif->parse_start_map, (filter)); - if (start != 0) { - TRY(filter->plug->fif->parse_map_key, (filter, "s", 1)); - TRY(filter->plug->fif->parse_integer, (filter, start)); - } - if (incr != 1) { - TRY(filter->plug->fif->parse_map_key, (filter, "i", 1)); - TRY(filter->plug->fif->parse_integer, (filter, incr)); - } - if (end != -1) { - TRY(filter->plug->fif->parse_map_key, (filter, "e", 1)); - TRY(filter->plug->fif->parse_integer, (filter, end)); - } - TRY(filter->plug->fif->parse_end_map, (filter)); - TRY(filter->plug->fif->parse_end, (filter)); - - ellAdd(&chan->filters, &filter->list_node); - return 0; - - failure: - freeListFree(chFilterFreeList, filter); - status = S_dbLib_fieldNotFound; - - finish: - return status; -} - -/* Stolen from dbAccess.c: */ -static short mapDBFToDBR[DBF_NTYPES] = - { - /* DBF_STRING => */DBR_STRING, - /* DBF_CHAR => */DBR_CHAR, - /* DBF_UCHAR => */DBR_UCHAR, - /* DBF_SHORT => */DBR_SHORT, - /* DBF_USHORT => */DBR_USHORT, - /* DBF_LONG => */DBR_LONG, - /* DBF_ULONG => */DBR_ULONG, - /* DBF_INT64 => */DBR_INT64, - /* DBF_UINT64 => */DBR_UINT64, - /* DBF_FLOAT => */DBR_FLOAT, - /* DBF_DOUBLE => */DBR_DOUBLE, - /* DBF_ENUM, => */DBR_ENUM, - /* DBF_MENU, => */DBR_ENUM, - /* DBF_DEVICE => */DBR_ENUM, - /* DBF_INLINK => */DBR_STRING, - /* DBF_OUTLINK => */DBR_STRING, - /* DBF_FWDLINK => */DBR_STRING, - /* DBF_NOACCESS => */DBR_NOACCESS }; - -dbChannel * dbChannelCreate(const char *name) -{ - const char *pname = name; - DBENTRY dbEntry; - dbChannel *chan = NULL; - char *cname; - dbAddr *paddr; - dbFldDes *pflddes; - long status; - short dbfType; - - if (!name || !*name || !pdbbase) - return NULL; - - status = pvNameLookup(&dbEntry, &pname); - if (status) - goto finish; - - chan = freeListCalloc(dbChannelFreeList); - if (!chan) - goto finish; - cname = malloc(strlen(name) + 1); - if (!cname) - goto finish; - - strcpy(cname, name); - chan->name = cname; - ellInit(&chan->filters); - ellInit(&chan->pre_chain); - ellInit(&chan->post_chain); - - paddr = &chan->addr; - pflddes = dbEntry.pflddes; - dbfType = pflddes->field_type; - - paddr->precord = dbEntry.precnode->precord; - paddr->pfield = dbEntry.pfield; - paddr->pfldDes = pflddes; - paddr->no_elements = 1; - paddr->field_type = dbfType; - paddr->field_size = pflddes->size; - paddr->special = pflddes->special; - paddr->dbr_field_type = mapDBFToDBR[dbfType]; - - if (paddr->special == SPC_DBADDR) { - rset *prset = dbGetRset(paddr); - - /* Let record type modify paddr */ - if (prset && prset->cvt_dbaddr) { - status = prset->cvt_dbaddr(paddr); - if (status) - goto finish; - dbfType = paddr->field_type; - } - } - - /* Handle field modifiers */ - if (*pname) { - if (*pname == '$') { - /* Some field types can be accessed as char arrays */ - if (dbfType == DBF_STRING) { - paddr->no_elements = paddr->field_size; - paddr->field_type = DBF_CHAR; - paddr->field_size = 1; - paddr->dbr_field_type = DBR_CHAR; - } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) { - /* Clients see a char array, but keep original dbfType */ - paddr->no_elements = PVLINK_STRINGSZ; - paddr->field_size = 1; - paddr->dbr_field_type = DBR_CHAR; - } else { - status = S_dbLib_fieldNotFound; - goto finish; - } - pname++; - } - - if (*pname == '[') { - status = parseArrayRange(chan, pname, &pname); - if (status) goto finish; - } - - /* JSON may follow */ - if (*pname == '{') { - status = chf_parse(chan, &pname); - if (status) goto finish; - } - - /* Make sure there's nothing else */ - if (*pname) { - status = S_dbLib_fieldNotFound; - goto finish; - } - } - -finish: - if (status && chan) { - dbChannelDelete(chan); - chan = NULL; - } - dbFinishEntry(&dbEntry); - return chan; -} - -db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn) { - chFilter *filter; - ELLNODE *node; - db_field_log *pLog = pLogIn; - - for (node = ellFirst(&chan->pre_chain); node && pLog; node = ellNext(node)) { - filter = CONTAINER(node, chFilter, pre_node); - pLog = filter->pre_func(filter->pre_arg, chan, pLog); - } - return pLog; -} - -db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn) { - chFilter *filter; - ELLNODE *node; - db_field_log *pLog = pLogIn; - - for (node = ellFirst(&chan->post_chain); node && pLog; node = ellNext(node)) { - filter = CONTAINER(node, chFilter, post_node); - pLog = filter->post_func(filter->post_arg, chan, pLog); - } - return pLog; -} - -long dbChannelOpen(dbChannel *chan) -{ - chFilter *filter; - chPostEventFunc *func; - void *arg; - long status; - ELLNODE *node; - db_field_log probe; - db_field_log p; - - for (node = ellFirst(&chan->filters); node; node = ellNext(node)) { - filter = CONTAINER(node, chFilter, list_node); - /* Call channel_open */ - status = 0; - if (filter->plug->fif->channel_open) - status = filter->plug->fif->channel_open(filter); - if (status) return status; - } - - /* Set up type probe */ - probe.type = dbfl_type_val; - probe.ctx = dbfl_context_read; - probe.field_type = dbChannelExportType(chan); - probe.no_elements = dbChannelElements(chan); - probe.field_size = dbChannelFieldSize(chan); - p = probe; - - /* - * Build up the pre- and post-event-queue filter chains - * Separate loops because the probe must reach the filters in the right order. - */ - for (node = ellFirst(&chan->filters); node; node = ellNext(node)) { - filter = CONTAINER(node, chFilter, list_node); - func = NULL; - arg = NULL; - if (filter->plug->fif->channel_register_pre) { - filter->plug->fif->channel_register_pre(filter, &func, &arg, &p); - if (func) { - ellAdd(&chan->pre_chain, &filter->pre_node); - filter->pre_func = func; - filter->pre_arg = arg; - probe = p; - } - } - } - for (node = ellFirst(&chan->filters); node; node = ellNext(node)) { - filter = CONTAINER(node, chFilter, list_node); - func = NULL; - arg = NULL; - if (filter->plug->fif->channel_register_post) { - filter->plug->fif->channel_register_post(filter, &func, &arg, &p); - if (func) { - ellAdd(&chan->post_chain, &filter->post_node); - filter->post_func = func; - filter->post_arg = arg; - probe = p; - } - } - } - - /* Save probe results */ - chan->final_no_elements = probe.no_elements; - chan->final_field_size = probe.field_size; - chan->final_type = probe.field_type; - - return 0; -} - -/* Only use dbChannelGet() if the record is already locked. */ -long dbChannelGet(dbChannel *chan, short type, void *pbuffer, - long *options, long *nRequest, void *pfl) -{ - return dbGet(&chan->addr, type, pbuffer, options, nRequest, pfl); -} - -long dbChannelGetField(dbChannel *chan, short dbrType, void *pbuffer, - long *options, long *nRequest, void *pfl) -{ - dbCommon *precord = chan->addr.precord; - long status = 0; - - dbScanLock(precord); - status = dbChannelGet(chan, dbrType, pbuffer, options, nRequest, pfl); - dbScanUnlock(precord); - return status; -} - -/* Only use dbChannelPut() if the record is already locked. - * This routine doesn't work on link fields, ignores DISP, and - * doesn't trigger record processing on PROC or pp(TRUE). - */ -long dbChannelPut(dbChannel *chan, short type, const void *pbuffer, - long nRequest) -{ - return dbPut(&chan->addr, type, pbuffer, nRequest); -} - -long dbChannelPutField(dbChannel *chan, short type, const void *pbuffer, - long nRequest) -{ - return dbPutField(&chan->addr, type, pbuffer, nRequest); -} - -void dbChannelShow(dbChannel *chan, int level, const unsigned short indent) -{ - long elems = chan->addr.no_elements; - long felems = chan->final_no_elements; - int count = ellCount(&chan->filters); - int pre = ellCount(&chan->pre_chain); - int post = ellCount(&chan->post_chain); - - printf("%*sChannel: '%s'\n", indent, "", chan->name); - if (level > 0) { - printf("%*sfield_type=%s (%d bytes), dbr_type=%s, %ld element%s", - indent + 4, "", - dbGetFieldTypeString(chan->addr.field_type), - chan->addr.field_size, - dbGetFieldTypeString(chan->addr.dbr_field_type), - elems, elems == 1 ? "" : "s"); - if (count) - printf("\n%*s%d filter%s (%d pre eventq, %d post eventq)\n", - indent + 4, "", count, count == 1 ? "" : "s", pre, post); - else - printf(", no filters\n"); - if (level > 1) - dbChannelFilterShow(chan, level - 2, indent + 8); - if (count) { - printf("%*sfinal field_type=%s (%dB), %ld element%s\n", indent + 4, "", - dbGetFieldTypeString(chan->final_type), - chan->final_field_size, - felems, felems == 1 ? "" : "s"); - } - } -} - -void dbChannelFilterShow(dbChannel *chan, int level, const unsigned short indent) -{ - chFilter *filter = (chFilter *) ellFirst(&chan->filters); - while (filter) { - filter->plug->fif->channel_report(filter, level, indent); - filter = (chFilter *) ellNext(&filter->list_node); - } -} - -void dbChannelDelete(dbChannel *chan) -{ - chFilter *filter; - - /* Close filters in reverse order */ - while ((filter = (chFilter *) ellPop(&chan->filters))) { - filter->plug->fif->channel_close(filter); - freeListFree(chFilterFreeList, filter); - } - free((char *) chan->name); - freeListFree(dbChannelFreeList, chan); -} - -static void freeArray(db_field_log *pfl) { - if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) { - freeListFree(dbchStringFreeList, pfl->u.r.field); - } else { - free(pfl->u.r.field); - } -} - -void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan) -{ - void *p; - struct dbCommon *prec = dbChannelRecord(chan); - - if (pfl->type != dbfl_type_rec) return; - - pfl->type = dbfl_type_ref; - pfl->stat = prec->stat; - pfl->sevr = prec->sevr; - pfl->time = prec->time; - pfl->field_type = chan->addr.field_type; - pfl->no_elements = chan->addr.no_elements; - pfl->field_size = chan->addr.field_size; - pfl->u.r.dtor = freeArray; - pfl->u.r.pvt = pvt; - if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) { - p = freeListCalloc(dbchStringFreeList); - } else { - p = calloc(pfl->no_elements, pfl->field_size); - } - if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL); - pfl->u.r.field = p; -} - -/* FIXME: Do these belong in a different file? */ - -void dbRegisterFilter(const char *name, const chFilterIf *fif, void *puser) -{ - GPHENTRY *pgph; - chFilterPlugin *pfilt; - - if (!pdbbase) { - printf("dbRegisterFilter: pdbbase not set!\n"); - return; - } - - pgph = gphFind(pdbbase->pgpHash, name, &pdbbase->filterList); - if (pgph) - return; - - pfilt = dbCalloc(1, sizeof(chFilterPlugin)); - pfilt->name = epicsStrDup(name); - pfilt->fif = fif; - pfilt->puser = puser; - - ellAdd(&pdbbase->filterList, &pfilt->node); - pgph = gphAdd(pdbbase->pgpHash, pfilt->name, &pdbbase->filterList); - if (!pgph) { - free((void *) pfilt->name); - free(pfilt); - printf("dbRegisterFilter: gphAdd failed\n"); - return; - } - pgph->userPvt = pfilt; -} - -const chFilterPlugin * dbFindFilter(const char *name, size_t len) -{ - GPHENTRY *pgph = gphFindParse(pdbbase->pgpHash, name, len, - &pdbbase->filterList); - - if (!pgph) - return NULL; - return (chFilterPlugin *) pgph->userPvt; -} diff --git a/src/ioc/db/dbChannel.h b/src/ioc/db/dbChannel.h deleted file mode 100644 index fab9c6627..000000000 --- a/src/ioc/db/dbChannel.h +++ /dev/null @@ -1,233 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - * Ralph Lange - */ - -#ifndef INC_dbChannel_H -#define INC_dbChannel_H - -#include "dbDefs.h" -#include "dbAddr.h" -#include "ellLib.h" -#include "epicsTypes.h" -#include "errMdef.h" -#include "shareLib.h" -#include "db_field_log.h" -#include "dbEvent.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * event subscription - */ -typedef struct evSubscrip { - ELLNODE node; - struct dbChannel *chan; - EVENTFUNC *user_sub; - void *user_arg; - struct event_que *ev_que; - db_field_log **pLastLog; - unsigned long npend; /* n times this event is on the queue */ - unsigned long nreplace; /* n times replacing event on the queue */ - unsigned char select; - char useValque; - char callBackInProgress; - char enabled; -} evSubscrip; - -typedef struct chFilter chFilter; - -/* A dbChannel points to a record field, and can have multiple filters */ -typedef struct dbChannel { - const char *name; - dbAddr addr; /* address structure for record/field */ - long final_no_elements; /* final number of elements (arrays) */ - short final_field_size; /* final size of element */ - short final_type; /* final type of database field */ - ELLLIST filters; /* list of filters as created from JSON */ - ELLLIST pre_chain; /* list of filters to be called pre-event-queue */ - ELLLIST post_chain; /* list of filters to be called post-event-queue */ -} dbChannel; - -/* Prototype for the channel event function that is called in filter stacks - * - * When invoked the scan lock for the record associated with 'chan' _may_ be locked. - * If pLog->type==dbfl_type_rec then dbScanLock() must be called before copying - * data out of the associated record. - * - * This function has ownership of the field log pLog, if it wishes to discard - * this update it should free the field log with db_delete_field_log() and - * then return NULL. - */ -typedef db_field_log* (chPostEventFunc)(void *pvt, dbChannel *chan, db_field_log *pLog); - -/* Return values from chFilterIf->parse_* routines: */ -typedef enum { - parse_stop, parse_continue -} parse_result; - -/* These routines must be implemented by each filter plug-in */ -typedef struct chFilterIf { - /* cleanup pointer passed to dbRegisterFilter(). - * Called during DB shutdown - */ - void (* priv_free)(void *puser); - /* Parsing event handlers: */ - parse_result (* parse_start)(chFilter *filter); - /* If parse_start() returns parse_continue for a filter, one of - * parse_abort() or parse_end() will later be called for that same - * filter. - */ - void (* parse_abort)(chFilter *filter); - /* If parse_abort() is called it should release any memory allocated - * for this filter; no further parse_...() calls will be made; - */ - parse_result (* parse_end)(chFilter *filter); - /* If parse_end() returns parse_stop it should have released any - * memory allocated for this filter; no further parse_...() calls will - * be made in this case. - */ - - parse_result (* parse_null)(chFilter *filter); - parse_result (* parse_boolean)(chFilter *filter, int boolVal); - parse_result (* parse_integer)(chFilter *filter, long integerVal); - parse_result (* parse_double)(chFilter *filter, double doubleVal); - parse_result (* parse_string)(chFilter *filter, const char *stringVal, - size_t stringLen); /* NB: stringVal is not zero-terminated: */ - - parse_result (* parse_start_map)(chFilter *filter); - parse_result (* parse_map_key)(chFilter *filter, const char *key, - size_t stringLen); /* NB: key is not zero-terminated: */ - parse_result (* parse_end_map)(chFilter *filter); - - parse_result (* parse_start_array)(chFilter *filter); - parse_result (* parse_end_array)(chFilter *filter); - - /* Channel operations: */ - long (* channel_open)(chFilter *filter); - void (* channel_register_pre) (chFilter *filter, chPostEventFunc **cb_out, void **arg_out, db_field_log *probe); - void (* channel_register_post)(chFilter *filter, chPostEventFunc **cb_out, void **arg_out, db_field_log *probe); - void (* channel_report)(chFilter *filter, int level, const unsigned short indent); - void (* channel_close)(chFilter *filter); -} chFilterIf; - -/* A chFilterPlugin holds data for a filter plugin */ -typedef struct chFilterPlugin { - ELLNODE node; - const char *name; - const chFilterIf *fif; - void *puser; -} chFilterPlugin; - -/* A chFilter holds data for a single filter instance */ -struct chFilter { - ELLNODE list_node; - ELLNODE pre_node; - ELLNODE post_node; - dbChannel *chan; - const chFilterPlugin *plug; - chPostEventFunc *pre_func; - void *pre_arg; - chPostEventFunc *post_func; - void *post_arg; - void *puser; -}; - -struct dbCommon; -struct dbFldDes; - -epicsShareFunc void dbChannelInit (void); -epicsShareFunc void dbChannelExit(void); -epicsShareFunc long dbChannelTest(const char *name); -epicsShareFunc dbChannel * dbChannelCreate(const char *name); -epicsShareFunc long dbChannelOpen(dbChannel *chan); - -/*Following is also defined in db_convert.h*/ -epicsShareExtern unsigned short dbDBRnewToDBRold[]; - -/* In the following macros pChan is dbChannel* */ - -/* evaluates to const char* */ -#define dbChannelName(pChan) ((pChan)->name) - -/* evaluates to struct dbCommon* */ -#define dbChannelRecord(pChan) ((pChan)->addr.precord) - -/* evaluates to struct dbFldDes* */ -#define dbChannelFldDes(pChan) ((pChan)->addr.pfldDes) - -/* evaluates to long */ -#define dbChannelElements(pChan) ((pChan)->addr.no_elements) - -/* evaluates to short */ -#define dbChannelFieldType(pChan) ((pChan)->addr.field_type) - -/* evaluates to short */ -#define dbChannelExportType(pChan) ((pChan)->addr.dbr_field_type) - -/* evaluates to short */ -#define dbChannelExportCAType(pChan) (dbDBRnewToDBRold[dbChannelExportType(pChan)]) - -/* evaluates to short */ -#define dbChannelFieldSize(pChan) ((pChan)->addr.field_size) - -/* evaluates to long */ -#define dbChannelFinalElements(pChan) ((pChan)->final_no_elements) - -/* evaluates to short */ -#define dbChannelFinalFieldType(pChan) ((pChan)->final_type) - -/* evaluates to short */ -#define dbChannelFinalCAType(pChan) (dbDBRnewToDBRold[(pChan)->final_type]) - -/* evaluates to short */ -#define dbChannelFinalFieldSize(pChan) ((pChan)->final_field_size) - -/* evaluates to short */ -#define dbChannelSpecial(pChan) ((pChan)->addr.special) - -/* Channel filters do not get to interpose here since there are many - * places where the field pointer is compared with the address of a - * specific record field, so they can't modify the pointer value. - */ -/* evaluates to void* */ -#define dbChannelField(pChan) ((pChan)->addr.pfield) - - -epicsShareFunc long dbChannelGet(dbChannel *chan, short type, - void *pbuffer, long *options, long *nRequest, void *pfl); -epicsShareFunc long dbChannelGetField(dbChannel *chan, short type, - void *pbuffer, long *options, long *nRequest, void *pfl); -epicsShareFunc long dbChannelPut(dbChannel *chan, short type, - const void *pbuffer, long nRequest); -epicsShareFunc long dbChannelPutField(dbChannel *chan, short type, - const void *pbuffer, long nRequest); -epicsShareFunc void dbChannelShow(dbChannel *chan, int level, - const unsigned short indent); -epicsShareFunc void dbChannelFilterShow(dbChannel *chan, int level, - const unsigned short indent); -epicsShareFunc void dbChannelDelete(dbChannel *chan); - -epicsShareFunc void dbRegisterFilter(const char *key, const chFilterIf *fif, void *puser); -epicsShareFunc db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn); -epicsShareFunc db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn); -epicsShareFunc const chFilterPlugin * dbFindFilter(const char *key, size_t len); -epicsShareFunc void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbChannel_H */ diff --git a/src/ioc/db/dbChannelIO.cpp b/src/ioc/db/dbChannelIO.cpp deleted file mode 100644 index a086d3e56..000000000 --- a/src/ioc/db/dbChannelIO.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#include - -#include "tsFreeList.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "db_access.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "db_access_routines.h" -#include "dbCAC.h" -#include "dbChannelIO.h" -#include "dbPutNotifyBlocker.h" - -dbChannelIO::dbChannelIO ( - epicsMutex & mutexIn, cacChannelNotify & notify, - dbChannel * dbchIn, dbContext & serviceIO ) : - cacChannel ( notify ), mutex ( mutexIn ), serviceIO ( serviceIO ), - dbch ( dbchIn ) -{ -} - -void dbChannelIO::initiateConnect ( epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->notify().connectNotify ( guard ); -} - -dbChannelIO::~dbChannelIO () -{ -} - -void dbChannelIO::destructor ( CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->serviceIO.destroyAllIO ( cbGuard, guard, *this ); - dbChannelDelete ( this->dbch ); - this->~dbChannelIO (); -} - -void dbChannelIO::destroy ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->serviceIO.destroyChannel ( cbGuard, guard, *this ); - // don't access this pointer after above call because - // object no longer exists -} - -cacChannel::ioStatus dbChannelIO::read ( - epicsGuard < epicsMutex > & guard, unsigned type, - unsigned long count, cacReadNotify & notify, ioid * ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->serviceIO.callReadNotify ( guard, this->dbch, - type, count, notify ); - return iosSynch; -} - -void dbChannelIO::write ( - epicsGuard < epicsMutex > & guard, unsigned type, - unsigned long count, const void *pValue ) -{ - epicsGuardRelease < epicsMutex > unguard ( guard ); - if ( count > LONG_MAX ) { - throw outOfBounds(); - } - int status = dbChannel_put ( this->dbch, type, pValue, - static_cast (count) ); - if ( status ) { - throw std::logic_error ( - "db_put_field() completed unsuccessfully" ); - } -} - -cacChannel::ioStatus dbChannelIO::write ( - epicsGuard < epicsMutex > & guard, unsigned type, - unsigned long count, const void * pValue, - cacWriteNotify & notify, ioid * pId ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( count > LONG_MAX ) { - throw outOfBounds(); - } - - this->serviceIO.initiatePutNotify ( - guard, *this, this->dbch, - type, count, pValue, notify, pId ); - - return iosAsynch; -} - -void dbChannelIO::subscribe ( - epicsGuard < epicsMutex > & guard, unsigned type, unsigned long count, - unsigned mask, cacStateNotify & notify, ioid * pId ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->serviceIO.subscribe ( - guard, this->dbch, *this, - type, count, mask, notify, pId ); -} - -void dbChannelIO::ioCancel ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - const ioid & id ) -{ - mutualExclusionGuard.assertIdenticalMutex ( this->mutex ); - this->serviceIO.ioCancel ( cbGuard, mutualExclusionGuard, *this, id ); -} - -void dbChannelIO::ioShow ( - epicsGuard < epicsMutex > & guard, - const ioid & id, unsigned level ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - this->serviceIO.ioShow ( guard, id, level ); -} - -void dbChannelIO::show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - - printf ("channel at %p attached to local database record %s\n", - static_cast ( this ), - dbChannelRecord ( this->dbch ) -> name ); - - if ( level > 0u ) { - printf ( " type %s, element count %li, field at %p\n", - dbf_type_to_text ( dbChannelExportCAType ( this->dbch ) ), - dbChannelElements ( this->dbch ), - dbChannelField ( this->dbch ) ); - if ( level > 1u ) { - dbChannelFilterShow ( this->dbch, level - 2u, 8 ); - this->serviceIO.show ( level - 2u ); - this->serviceIO.showAllIO ( *this, level - 2u ); - } - } -} - -unsigned long dbChannelIO::nativeElementCount ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - long elements = dbChannelElements ( this->dbch ); - if ( elements >= 0u ) { - return static_cast < unsigned long > ( elements ); - } - return 0u; -} - -// hopefully to be eventually phased out -const char * dbChannelIO::pName ( - epicsGuard < epicsMutex > & guard ) const throw () -{ - guard.assertIdenticalMutex ( this->mutex ); - return dbChannelName ( this->dbch ); -} - -unsigned dbChannelIO::getName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw () -{ - const char *name = dbChannelName ( this->dbch ); - size_t len = strlen ( name ); - strncpy ( pBuf, name, bufLen ); - if (len < bufLen) - return (unsigned) len; - pBuf[--bufLen] = '\0'; - return bufLen; -} - -short dbChannelIO::nativeType ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - return dbChannelExportCAType( this->dbch ); -} - -void * dbChannelIO::operator new ( size_t size, - tsFreeList < dbChannelIO, 256, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -void dbChannelIO::operator delete ( void *pCadaver, - tsFreeList < dbChannelIO, 256, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -void dbChannelIO::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void dbChannelIO::flush ( - epicsGuard < epicsMutex > & ) -{ -} - -unsigned dbChannelIO::requestMessageBytesPending ( - epicsGuard < epicsMutex > & ) -{ - return 0u; -} - diff --git a/src/ioc/db/dbChannelIO.h b/src/ioc/db/dbChannelIO.h deleted file mode 100644 index 5eb7c4eb2..000000000 --- a/src/ioc/db/dbChannelIO.h +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - * NOTES: - * 1) This interface is preliminary and will change in the future - */ - -#ifndef dbChannelIOh -#define dbChannelIOh - -#ifdef epicsExportSharedSymbols -# define dbChannelIOh_restore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "compilerDependencies.h" - -#ifdef dbChannelIOh_restore_epicsExportSharedSymbols -# define epicsExportSharedSymbols -#endif - -class dbChannelIO : public cacChannel, public dbContextPrivateListOfIO { -public: - dbChannelIO ( - epicsMutex &, cacChannelNotify &, - dbChannel *, dbContext & ); - void destructor ( - CallbackGuard &, - epicsGuard < epicsMutex > & ); - void destroy ( - CallbackGuard &, - epicsGuard < epicsMutex > & mutualExclusionGuard ); - void callReadNotify ( - epicsGuard < epicsMutex > &, - unsigned type, unsigned long count, - cacReadNotify & notify ); - void callStateNotify ( - unsigned type, unsigned long count, - const struct db_field_log * pfl, cacStateNotify & notify ); - void show ( - epicsGuard < epicsMutex > &, unsigned level ) const; - unsigned getName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw (); - const char * pName ( - epicsGuard < epicsMutex > & ) const throw (); - void * operator new ( size_t size, - tsFreeList < dbChannelIO, 256, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < dbChannelIO, 256, epicsMutexNOOP > & )) -protected: - ~dbChannelIO (); -private: - epicsMutex & mutex; - dbContext & serviceIO; - dbChannel * dbch; - - void initiateConnect ( - epicsGuard < epicsMutex > & ); - unsigned requestMessageBytesPending ( - epicsGuard < epicsMutex > & ); - void flush ( - epicsGuard < epicsMutex > & ); - ioStatus read ( - epicsGuard < epicsMutex > &, - unsigned type, unsigned long count, - cacReadNotify &, ioid * ); - void write ( - epicsGuard < epicsMutex > &, - unsigned type, unsigned long count, - const void * pvalue ); - ioStatus write ( - epicsGuard < epicsMutex > &, - unsigned type, unsigned long count, - const void * pvalue, cacWriteNotify &, ioid * ); - void subscribe ( - epicsGuard < epicsMutex > &, - unsigned type, unsigned long count, - unsigned mask, cacStateNotify ¬ify, ioid * ); - void ioCancel ( - CallbackGuard &, - epicsGuard < epicsMutex > &, - const ioid & ); - void ioShow ( - epicsGuard < epicsMutex > &, - const ioid &, unsigned level ) const; - short nativeType ( - epicsGuard < epicsMutex > & ) const; - unsigned long nativeElementCount ( - epicsGuard < epicsMutex > & ) const; - dbChannelIO ( const dbChannelIO & ); - dbChannelIO & operator = ( const dbChannelIO & ); - void operator delete ( void * ); -}; - -inline void dbChannelIO::callReadNotify ( - epicsGuard < epicsMutex > & guard, unsigned type, unsigned long count, - cacReadNotify & notify ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->serviceIO.callReadNotify ( guard, this->dbch, type, count, notify ); -} - -inline void dbChannelIO::callStateNotify ( unsigned type, unsigned long count, - const struct db_field_log *pfl, cacStateNotify ¬ify ) -{ - this->serviceIO.callStateNotify ( this->dbch, type, count, pfl, notify ); -} - - -#endif // dbChannelIOh - diff --git a/src/ioc/db/dbChannelNOOP.h b/src/ioc/db/dbChannelNOOP.h deleted file mode 100644 index d48540d88..000000000 --- a/src/ioc/db/dbChannelNOOP.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef DBCHANNELNOOP_H -#define DBCHANNELNOOP_H - -#include -#include - -#include "cacIO.h" -#include "caerr.h" - -/** @brief A channel which never connects - * - * Used when dbCa is placed in isolated mode for unittests - */ -class dbChannelNOOP : public cacChannel -{ - std::string myname; -public: - dbChannelNOOP(const char *name, cacChannelNotify ¬ify) - :cacChannel(notify) - ,myname(name) - {} - - virtual void destroy ( - CallbackGuard & /*callbackGuard*/, - epicsGuard < epicsMutex > & /*mutualExclusionGuard*/ ) - { - delete this; // goodbye cruel world - } - - virtual unsigned getName ( - epicsGuard < epicsMutex > &, - char * pBuf, unsigned bufLen ) const throw () - { - const char* name = myname.c_str(); - if(bufLen>myname.size()+1) { - bufLen=myname.size()+1; - } - memcpy(pBuf, name, bufLen); - pBuf[--bufLen] = '\0'; - return bufLen; - } - - // !! deprecated, avoid use !! - virtual const char * pName ( - epicsGuard < epicsMutex > & guard ) const throw () - {return myname.c_str();} - - virtual void show ( - epicsGuard < epicsMutex > &, - unsigned level ) const - {} - - virtual void initiateConnect ( - epicsGuard < epicsMutex > & ) - {} - - virtual unsigned requestMessageBytesPending ( - epicsGuard < epicsMutex > & /*mutualExclusionGuard*/ ) - {return 0;} - - virtual void flush ( - epicsGuard < epicsMutex > & /*mutualExclusionGuard*/ ) - {} - - virtual ioStatus read ( - epicsGuard < epicsMutex > &mut, - unsigned type, arrayElementCount count, - cacReadNotify ¬ify, ioid * = 0 ) - { - notify.exception(mut, ECA_NORDACCESS, "dbChannelNOOP", type, count); - return iosSynch; - } - - virtual void write ( - epicsGuard < epicsMutex > &, - unsigned type, arrayElementCount count, - const void *pValue ) - {} - - virtual ioStatus write ( - epicsGuard < epicsMutex > &mut, - unsigned type, arrayElementCount count, - const void */*pValue*/, cacWriteNotify & notify, ioid * = 0 ) - { - notify.exception(mut, ECA_NOWTACCESS, "dbChannelNOOP", type, count); - return iosSynch; - } - - virtual void subscribe ( - epicsGuard < epicsMutex > &mut, unsigned type, - arrayElementCount count, unsigned /*mask*/, cacStateNotify & notify, - ioid * = 0 ) - { - // should never subscribe - notify.exception(mut, ECA_BADMASK, "dbChannelNOOP", type, count); - } - - virtual void ioCancel ( - CallbackGuard & callbackGuard, - epicsGuard < epicsMutex > & mutualExclusionGuard, - const ioid & ) - {} - - virtual void ioShow ( - epicsGuard < epicsMutex > &, - const ioid &, unsigned level ) const - {} - - virtual short nativeType ( - epicsGuard < epicsMutex > & ) const - {return 0;} // DBR_STRING - - virtual arrayElementCount nativeElementCount ( - epicsGuard < epicsMutex > & ) const - {return 1;} -}; - -#endif // DBCHANNELNOOP_H diff --git a/src/ioc/db/dbCommon.dbd b/src/ioc/db/dbCommon.dbd deleted file mode 100644 index 1b093e6a8..000000000 --- a/src/ioc/db/dbCommon.dbd +++ /dev/null @@ -1,267 +0,0 @@ -#************************************************************************* -# Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - %#include "epicsTypes.h" - %#include "link.h" - field(NAME,DBF_STRING) { - prompt("Record Name") - special(SPC_NOMOD) - size(61) - } - field(DESC,DBF_STRING) { - prompt("Descriptor") - promptgroup("10 - Common") - size(41) - } - field(ASG,DBF_STRING) { - prompt("Access Security Group") - promptgroup("10 - Common") - special(SPC_AS) - size(29) - } - field(SCAN,DBF_MENU) { - prompt("Scan Mechanism") - promptgroup("20 - Scan") - special(SPC_SCAN) - interest(1) - menu(menuScan) - } - field(PINI,DBF_MENU) { - prompt("Process at iocInit") - promptgroup("20 - Scan") - interest(1) - menu(menuPini) - } - field(PHAS,DBF_SHORT) { - prompt("Scan Phase") - promptgroup("20 - Scan") - special(SPC_SCAN) - interest(1) - } - field(EVNT,DBF_STRING) { - prompt("Event Name") - promptgroup("20 - Scan") - special(SPC_SCAN) - size(40) - interest(1) - } - field(TSE,DBF_SHORT) { - prompt("Time Stamp Event") - promptgroup("20 - Scan") - interest(1) - } - field(TSEL,DBF_INLINK) { - prompt("Time Stamp Link") - promptgroup("20 - Scan") - interest(1) - } - field(DTYP,DBF_DEVICE) { - prompt("Device Type") - promptgroup("10 - Common") - interest(1) - } - field(DISV,DBF_SHORT) { - prompt("Disable Value") - promptgroup("20 - Scan") - initial("1") - } - field(DISA,DBF_SHORT) { - prompt("Disable") - } - field(SDIS,DBF_INLINK) { - prompt("Scanning Disable") - promptgroup("20 - Scan") - interest(1) - } - %#include "epicsMutex.h" - field(MLOK,DBF_NOACCESS) { - prompt("Monitor lock") - special(SPC_NOMOD) - interest(4) - extra("epicsMutexId mlok") - } - %#include "ellLib.h" - field(MLIS,DBF_NOACCESS) { - prompt("Monitor List") - special(SPC_NOMOD) - interest(4) - extra("ELLLIST mlis") - } - field(BKLNK,DBF_NOACCESS) { - prompt("Backwards link tracking") - special(SPC_NOMOD) - interest(4) - extra("ELLLIST bklnk") - } - field(DISP,DBF_UCHAR) { - prompt("Disable putField") - } - field(PROC,DBF_UCHAR) { - prompt("Force Processing") - pp(TRUE) - interest(3) - } - field(STAT,DBF_MENU) { - prompt("Alarm Status") - special(SPC_NOMOD) - menu(menuAlarmStat) - initial("UDF") - } - field(SEVR,DBF_MENU) { - prompt("Alarm Severity") - special(SPC_NOMOD) - menu(menuAlarmSevr) - } - field(NSTA,DBF_MENU) { - prompt("New Alarm Status") - special(SPC_NOMOD) - interest(2) - menu(menuAlarmStat) - } - field(NSEV,DBF_MENU) { - prompt("New Alarm Severity") - special(SPC_NOMOD) - interest(2) - menu(menuAlarmSevr) - } - field(ACKS,DBF_MENU) { - prompt("Alarm Ack Severity") - special(SPC_NOMOD) - interest(2) - menu(menuAlarmSevr) - } - field(ACKT,DBF_MENU) { - prompt("Alarm Ack Transient") - promptgroup("70 - Alarm") - special(SPC_NOMOD) - interest(2) - menu(menuYesNo) - initial("YES") - } - field(DISS,DBF_MENU) { - prompt("Disable Alarm Sevrty") - promptgroup("70 - Alarm") - interest(1) - menu(menuAlarmSevr) - } - field(LCNT,DBF_UCHAR) { - prompt("Lock Count") - special(SPC_NOMOD) - interest(2) - } - field(PACT,DBF_UCHAR) { - prompt("Record active") - special(SPC_NOMOD) - interest(1) - } - field(PUTF,DBF_UCHAR) { - prompt("dbPutField process") - special(SPC_NOMOD) - interest(1) - } - field(RPRO,DBF_UCHAR) { - prompt("Reprocess ") - special(SPC_NOMOD) - interest(1) - } - field(ASP,DBF_NOACCESS) { - prompt("Access Security Pvt") - special(SPC_NOMOD) - interest(4) - extra("struct asgMember *asp") - } - field(PPN,DBF_NOACCESS) { - prompt("pprocessNotify") - special(SPC_NOMOD) - interest(4) - extra("struct processNotify *ppn") - } - field(PPNR,DBF_NOACCESS) { - prompt("pprocessNotifyRecord") - special(SPC_NOMOD) - interest(4) - extra("struct processNotifyRecord *ppnr") - } - field(SPVT,DBF_NOACCESS) { - prompt("Scan Private") - special(SPC_NOMOD) - interest(4) - extra("struct scan_element *spvt") - } - field(RSET,DBF_NOACCESS) { - prompt("Address of RSET") - special(SPC_NOMOD) - interest(4) - extra("struct typed_rset *rset") - } - field(DSET,DBF_NOACCESS) { - prompt("DSET address") - special(SPC_NOMOD) - interest(4) - extra("struct dset *dset") - } - field(DPVT,DBF_NOACCESS) { - prompt("Device Private") - special(SPC_NOMOD) - interest(4) - extra("void *dpvt") - } - field(RDES,DBF_NOACCESS) { - prompt("Address of dbRecordType") - special(SPC_NOMOD) - interest(4) - extra("struct dbRecordType *rdes") - } - field(LSET,DBF_NOACCESS) { - prompt("Lock Set") - special(SPC_NOMOD) - interest(4) - extra("struct lockRecord *lset") - } - field(PRIO,DBF_MENU) { - prompt("Scheduling Priority") - promptgroup("20 - Scan") - special(SPC_SCAN) - interest(1) - menu(menuPriority) - } - field(TPRO,DBF_UCHAR) { - prompt("Trace Processing") - } - field(BKPT,DBF_NOACCESS) { - prompt("Break Point") - special(SPC_NOMOD) - interest(1) - extra("char bkpt") - } - field(UDF,DBF_UCHAR) { - prompt("Undefined") - promptgroup("10 - Common") - pp(TRUE) - interest(1) - initial("1") - } - field(UDFS,DBF_MENU) { - prompt("Undefined Alarm Sevrty") - promptgroup("70 - Alarm") - interest(1) - menu(menuAlarmSevr) - initial("INVALID") - } - %#include "epicsTime.h" - field(TIME,DBF_NOACCESS) { - prompt("Time") - special(SPC_NOMOD) - interest(2) - extra("epicsTimeStamp time") - } - field(FLNK,DBF_FWDLINK) { - prompt("Forward Process Link") - promptgroup("20 - Scan") - interest(1) - } diff --git a/src/ioc/db/dbCommonPvt.h b/src/ioc/db/dbCommonPvt.h deleted file mode 100644 index 3dfce8b27..000000000 --- a/src/ioc/db/dbCommonPvt.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef DBCOMMONPVT_H -#define DBCOMMONPVT_H - -#include "dbCommon.h" - -/** Base internal additional information for every record - */ -typedef struct dbCommonPvt { - struct dbRecordNode *recnode; - - struct dbCommon common; -} dbCommonPvt; - -#endif // DBCOMMONPVT_H diff --git a/src/ioc/db/dbCommonRecord.dbd b/src/ioc/db/dbCommonRecord.dbd deleted file mode 100644 index a988619ae..000000000 --- a/src/ioc/db/dbCommonRecord.dbd +++ /dev/null @@ -1,12 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(dbCommon) { - include "dbCommon.dbd" -} diff --git a/src/ioc/db/dbConstLink.c b/src/ioc/db/dbConstLink.c deleted file mode 100644 index 0bdc70f92..000000000 --- a/src/ioc/db/dbConstLink.c +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbConstLink.c - * - * Original Authors: Bob Dalesio, Marty Kraimer - * Current Author: Andrew Johnson - */ - -#include -#include - -#include "dbDefs.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbCommon.h" -#include "dbConstLink.h" -#include "dbConvertFast.h" -#include "dbConvertJSON.h" -#include "dbFldTypes.h" -#include "dbLink.h" -#include "link.h" - -/***************************** Constant Links *****************************/ - -/* Forward definition */ -static lset dbConst_lset; - -void dbConstInitLink(struct link *plink) -{ - plink->lset = &dbConst_lset; -} - -void dbConstAddLink(struct link *plink) -{ - plink->lset = &dbConst_lset; -} - -/**************************** Member functions ****************************/ - -static long dbConstLoadScalar(struct link *plink, short dbrType, void *pbuffer) -{ - const char *pstr = plink->value.constantStr; - size_t len; - - if (!pstr) - return S_db_badField; - len = strlen(pstr); - - /* Choice values must be numeric */ - if (dbrType == DBF_MENU || dbrType == DBF_ENUM || dbrType == DBF_DEVICE) - dbrType = DBF_USHORT; - - if (*pstr == '[' && pstr[len-1] == ']') { - /* Convert from JSON array */ - long nReq = 1; - - return dbPutConvertJSON(pstr, dbrType, pbuffer, &nReq); - } - - return dbFastPutConvertRoutine[DBR_STRING][dbrType] - (pstr, pbuffer, NULL); -} - -static long dbConstLoadLS(struct link *plink, char *pbuffer, epicsUInt32 size, - epicsUInt32 *plen) -{ - const char *pstr = plink->value.constantStr; - - if (!pstr) - return S_db_badField; - - return dbLSConvertJSON(pstr, pbuffer, size, plen); -} - -static long dbConstLoadArray(struct link *plink, short dbrType, void *pbuffer, - long *pnReq) -{ - const char *pstr = plink->value.constantStr; - - if (!pstr) - return S_db_badField; - - /* Choice values must be numeric */ - if (dbrType == DBF_MENU || dbrType == DBF_ENUM || dbrType == DBF_DEVICE) - dbrType = DBF_USHORT; - - return dbPutConvertJSON(pstr, dbrType, pbuffer, pnReq); -} - -static long dbConstGetNelements(const struct link *plink, long *nelements) -{ - *nelements = 0; - return 0; -} - -static long dbConstGetValue(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest) -{ - if (pnRequest) - *pnRequest = 0; - return 0; -} - -static lset dbConst_lset = { - 1, 0, /* Constant, not Volatile */ - NULL, NULL, - dbConstLoadScalar, - dbConstLoadLS, - dbConstLoadArray, - NULL, - NULL, dbConstGetNelements, - dbConstGetValue, - NULL, NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL -}; diff --git a/src/ioc/db/dbConstLink.h b/src/ioc/db/dbConstLink.h deleted file mode 100644 index c187f9fc5..000000000 --- a/src/ioc/db/dbConstLink.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbConstLink.h - * - * Created on: April 3rd, 2016 - * Author: Andrew Johnson - */ - -#ifndef INC_dbConstLink_H -#define INC_dbConstLink_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct link; - -epicsShareFunc void dbConstInitLink(struct link *plink); -epicsShareFunc void dbConstAddLink(struct link *plink); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbConstLink_H */ - diff --git a/src/ioc/db/dbContext.cpp b/src/ioc/db/dbContext.cpp deleted file mode 100644 index 832820206..000000000 --- a/src/ioc/db/dbContext.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -#include "epicsMutex.h" -#include "tsFreeList.h" - -#include "cadef.h" // this can be eliminated when the callbacks use the new interface -#include "db_access.h" // should be eliminated here in the future -#include "caerr.h" // should be eliminated here in the future -#include "epicsEvent.h" -#include "epicsThread.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "db_access_routines.h" -#include "dbCAC.h" -#include "dbChannel.h" -#include "dbChannelIO.h" -#include "dbChannelNOOP.h" -#include "dbPutNotifyBlocker.h" - -class dbService : public cacService { -public: - ~dbService () {} - cacContext & contextCreate ( - epicsMutex & mutualExclusion, - epicsMutex & callbackControl, - cacContextNotify & ); -}; - -static dbService dbs; - -cacContext & dbService::contextCreate ( - epicsMutex & mutualExclusion, - epicsMutex & callbackControl, - cacContextNotify & notify ) -{ - return * new dbContext ( callbackControl, - mutualExclusion, notify ); -} - -extern "C" int dbServiceIsolate; -int dbServiceIsolate = 0; - -extern "C" void dbServiceIOInit () -{ - static int init=0; - if(!init) { - caInstallDefaultService ( dbs ); - init=1; - } -} - -dbBaseIO::dbBaseIO () {} - -dbContext::dbContext ( epicsMutex & cbMutexIn, - epicsMutex & mutexIn, cacContextNotify & notifyIn ) : - readNotifyCache ( mutexIn ), ctx ( 0 ), - stateNotifyCacheSize ( 0 ), mutex ( mutexIn ), cbMutex ( cbMutexIn ), - notify ( notifyIn ), pNetContext ( 0 ), pStateNotifyCache ( 0 ), - isolated(dbServiceIsolate) -{ -} - -dbContext::~dbContext () -{ - delete [] this->pStateNotifyCache; - if ( this->ctx ) { - db_close_events ( this->ctx ); - } -} - -cacChannel & dbContext::createChannel ( - epicsGuard < epicsMutex > & guard, const char * pName, - cacChannelNotify & notifyIn, cacChannel::priLev priority ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - dbChannel *dbch = dbChannel_create ( pName ); - if ( ! dbch ) { - if ( isolated ) { - return *new dbChannelNOOP(pName, notifyIn); - - } else if ( ! this->pNetContext.get() ) { - this->pNetContext.reset ( - & this->notify.createNetworkContext ( - this->mutex, this->cbMutex ) ); - } - return this->pNetContext->createChannel ( - guard, pName, notifyIn, priority ); - } - - if ( ! ca_preemtive_callback_is_enabled () ) { - dbChannelDelete ( dbch ); - errlogPrintf ( - "dbContext: preemptive callback required for direct in\n" - "memory interfacing of CA channels to the DB.\n" ); - throw cacChannel::unsupportedByService (); - } - - try { - return * new ( this->dbChannelIOFreeList ) - dbChannelIO ( this->mutex, notifyIn, dbch, *this ); - } - catch (...) { - dbChannelDelete ( dbch ); - throw; - } -} - -void dbContext::destroyChannel ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard, - dbChannelIO & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - if ( chan.dbContextPrivateListOfIO::pBlocker ) { - this->ioTable.remove ( *chan.dbContextPrivateListOfIO::pBlocker ); - chan.dbContextPrivateListOfIO::pBlocker->destructor ( cbGuard, guard ); - this->dbPutNotifyBlockerFreeList.release ( chan.dbContextPrivateListOfIO::pBlocker ); - chan.dbContextPrivateListOfIO::pBlocker = 0; - } - - chan.destructor ( cbGuard, guard ); - this->dbChannelIOFreeList.release ( & chan ); -} - -void dbContext::callStateNotify ( struct dbChannel * dbch, - unsigned type, unsigned long count, - const struct db_field_log * pfl, - cacStateNotify & notifyIn ) -{ - long realcount = (count==0)?dbChannelElements(dbch):count; - unsigned long size = dbr_size_n ( type, realcount ); - - if ( type > INT_MAX ) { - epicsGuard < epicsMutex > guard ( this->mutex ); - notifyIn.exception ( guard, ECA_BADTYPE, - "type code out of range (high side)", - type, count ); - return; - } - - if ( count > INT_MAX ) { - epicsGuard < epicsMutex > guard ( this->mutex ); - notifyIn.exception ( guard, ECA_BADCOUNT, - "element count out of range (high side)", - type, count); - return; - } - - // no need to lock this because state notify is - // called from only one event queue consumer thread - if ( this->stateNotifyCacheSize < size) { - char * pTmp = new char [size]; - delete [] this->pStateNotifyCache; - this->pStateNotifyCache = pTmp; - this->stateNotifyCacheSize = size; - } - void *pvfl = (void *) pfl; - int status; - if(count==0) /* fetch actual number of elements (dynamic array) */ - status = dbChannel_get_count( dbch, static_cast ( type ), - this->pStateNotifyCache, &realcount, pvfl ); - else /* fetch requested number of elements, truncated or zero padded */ - status = dbChannel_get( dbch, static_cast ( type ), - this->pStateNotifyCache, realcount, pvfl ); - if ( status ) { - epicsGuard < epicsMutex > guard ( this->mutex ); - notifyIn.exception ( guard, ECA_GETFAIL, - "dbChannel_get() completed unsuccessfully", type, count ); - } - else { - epicsGuard < epicsMutex > guard ( this->mutex ); - notifyIn.current ( guard, type, realcount, this->pStateNotifyCache ); - } -} - -extern "C" void cacAttachClientCtx ( void * pPrivate ) -{ - int status = ca_attach_context ( (ca_client_context *) pPrivate ); - assert ( status == ECA_NORMAL ); -} - -void dbContext::subscribe ( - epicsGuard < epicsMutex > & guard, - struct dbChannel * dbch, dbChannelIO & chan, - unsigned type, unsigned long count, unsigned mask, - cacStateNotify & notifyIn, cacChannel::ioid * pId ) -{ - guard.assertIdenticalMutex ( this->mutex ); - - /* - * the database uses type "int" to store these parameters - */ - if ( type > INT_MAX ) { - throw cacChannel::badType(); - } - if ( count > INT_MAX ) { - throw cacChannel::outOfBounds(); - } - - if ( ! this->ctx ) { - dbEventCtx tmpctx = 0; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - tmpctx = db_init_events (); - if ( ! tmpctx ) { - throw std::bad_alloc (); - } - - unsigned selfPriority = epicsThreadGetPrioritySelf (); - unsigned above; - epicsThreadBooleanStatus tbs = - epicsThreadLowestPriorityLevelAbove ( selfPriority, &above ); - if ( tbs != epicsThreadBooleanStatusSuccess ) { - above = selfPriority; - } - int status = db_start_events ( tmpctx, "CAC-event", - cacAttachClientCtx, ca_current_context (), above ); - if ( status ) { - db_close_events ( tmpctx ); - throw std::bad_alloc (); - } - } - if ( this->ctx ) { - // another thread tried to simultaneously setup - // the event system - db_close_events ( tmpctx ); - } - else { - this->ctx = tmpctx; - } - } - - dbSubscriptionIO & subscr = - * new ( this->dbSubscriptionIOFreeList ) - dbSubscriptionIO ( guard, this->mutex, *this, chan, - dbch, notifyIn, type, count, mask, this->ctx ); - chan.dbContextPrivateListOfIO::eventq.add ( subscr ); - this->ioTable.idAssignAdd ( subscr ); - - if ( pId ) { - *pId = subscr.getId (); - } -} - -void dbContext::initiatePutNotify ( - epicsGuard < epicsMutex > & guard, - dbChannelIO & chan, struct dbChannel * dbch, - unsigned type, unsigned long count, const void * pValue, - cacWriteNotify & notifyIn, cacChannel::ioid * pId ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( ! chan.dbContextPrivateListOfIO::pBlocker ) { - chan.dbContextPrivateListOfIO::pBlocker = - new ( this->dbPutNotifyBlockerFreeList ) - dbPutNotifyBlocker ( this->mutex ); - this->ioTable.idAssignAdd ( *chan.dbContextPrivateListOfIO::pBlocker ); - } - chan.dbContextPrivateListOfIO::pBlocker->initiatePutNotify ( - guard, notifyIn, dbch, type, count, pValue ); - if ( pId ) { - *pId = chan.dbContextPrivateListOfIO::pBlocker->getId (); - } -} - -void dbContext::destroyAllIO ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard, - dbChannelIO & chan ) -{ - guard.assertIdenticalMutex ( this->mutex ); - dbSubscriptionIO * pIO; - tsDLList < dbSubscriptionIO > tmp; - - while ( ( pIO = chan.dbContextPrivateListOfIO::eventq.get() ) ) { - this->ioTable.remove ( *pIO ); - tmp.add ( *pIO ); - } - if ( chan.dbContextPrivateListOfIO::pBlocker ) { - this->ioTable.remove ( *chan.dbContextPrivateListOfIO::pBlocker ); - } - - while ( ( pIO = tmp.get() ) ) { - // This prevents a db event callback from coming - // through after the notify IO is deleted - pIO->unsubscribe ( cbGuard, guard ); - // If they call ioCancel() here it will be ignored - // because the IO has been unregistered above. - pIO->channelDeleteException ( cbGuard, guard ); - pIO->destructor ( cbGuard, guard ); - this->dbSubscriptionIOFreeList.release ( pIO ); - } - - if ( chan.dbContextPrivateListOfIO::pBlocker ) { - chan.dbContextPrivateListOfIO::pBlocker->destructor ( cbGuard, guard ); - this->dbPutNotifyBlockerFreeList.release ( chan.dbContextPrivateListOfIO::pBlocker ); - chan.dbContextPrivateListOfIO::pBlocker = 0; - } -} - -void dbContext::ioCancel ( - CallbackGuard & cbGuard, epicsGuard < epicsMutex > & guard, - dbChannelIO & chan, const cacChannel::ioid &id ) -{ - guard.assertIdenticalMutex ( this->mutex ); - dbBaseIO * pIO = this->ioTable.remove ( id ); - if ( pIO ) { - dbSubscriptionIO *pSIO = pIO->isSubscription (); - if ( pSIO ) { - chan.dbContextPrivateListOfIO::eventq.remove ( *pSIO ); - pSIO->unsubscribe ( cbGuard, guard ); - pSIO->channelDeleteException ( cbGuard, guard ); - pSIO->destructor ( cbGuard, guard ); - this->dbSubscriptionIOFreeList.release ( pSIO ); - } - else if ( pIO == chan.dbContextPrivateListOfIO::pBlocker ) { - chan.dbContextPrivateListOfIO::pBlocker->cancel ( cbGuard, guard ); - } - else { - errlogPrintf ( "dbContext::ioCancel() unrecognized IO was probably leaked or not canceled\n" ); - } - } -} - -void dbContext::ioShow ( - epicsGuard < epicsMutex > & guard, const cacChannel::ioid &id, - unsigned level ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - const dbBaseIO * pIO = this->ioTable.lookup ( id ); - if ( pIO ) { - pIO->show ( guard, level ); - } -} - -void dbContext::showAllIO ( const dbChannelIO & chan, unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - tsDLIterConst < dbSubscriptionIO > pItem = - chan.dbContextPrivateListOfIO::eventq.firstIter (); - while ( pItem.valid () ) { - pItem->show ( guard, level ); - pItem++; - } - if ( chan.dbContextPrivateListOfIO::pBlocker ) { - chan.dbContextPrivateListOfIO::pBlocker->show ( guard, level ); - } -} - -void dbContext::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->show ( guard, level ); -} - -void dbContext::show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - printf ( "dbContext at %p\n", - static_cast ( this ) ); - if ( level > 0u ) { - printf ( "\tevent call back cache location %p, and its size %lu\n", - static_cast ( this->pStateNotifyCache ), this->stateNotifyCacheSize ); - this->readNotifyCache.show ( guard, level - 1 ); - } - if ( level > 1u ) { - this->mutex.show ( level - 2u ); - } - if ( this->pNetContext.get() ) { - this->pNetContext.get()->show ( guard, level ); - } -} - -void dbContext::flush ( - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->pNetContext.get() ) { - this->pNetContext.get()->flush ( guard ); - } -} - -unsigned dbContext::circuitCount ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->pNetContext.get() ) { - return this->pNetContext.get()->circuitCount ( guard ); - } - else { - return 0u; - } -} - -void dbContext::selfTest ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - this->ioTable.verify (); - - if ( this->pNetContext.get() ) { - this->pNetContext.get()->selfTest ( guard ); - } -} - -unsigned dbContext::beaconAnomaliesSinceProgramStart ( - epicsGuard < epicsMutex > & guard ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->pNetContext.get() ) { - return this->pNetContext.get()->beaconAnomaliesSinceProgramStart ( guard ); - } - else { - return 0u; - } -} - - diff --git a/src/ioc/db/dbContextReadNotifyCache.cpp b/src/ioc/db/dbContextReadNotifyCache.cpp deleted file mode 100644 index e3196b25d..000000000 --- a/src/ioc/db/dbContextReadNotifyCache.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Auther Jeff Hill - */ - -#include - -#include "epicsMutex.h" -#include "dbDefs.h" - -#include "cadef.h" // this can be eliminated when the callbacks use the new interface -#include "db_access.h" // should be eliminated here in the future - -#define epicsExportSharedSymbols - -#include "db_access_routines.h" -#include "dbCAC.h" - -#include "epicsAssert.h" - -dbContextReadNotifyCache::dbContextReadNotifyCache ( epicsMutex & mutexIn ) : - _mutex ( mutexIn ) -{ -} - -class privateAutoDestroyPtr { -public: - privateAutoDestroyPtr ( - dbContextReadNotifyCacheAllocator & allocator, unsigned long size ) : - _allocator ( allocator ), _p ( allocator.alloc ( size ) ) {} - ~privateAutoDestroyPtr () { _allocator.free ( _p ); } - char * get () const { return _p; } -private: - dbContextReadNotifyCacheAllocator & _allocator; - char * _p; - privateAutoDestroyPtr ( const privateAutoDestroyPtr & ); - privateAutoDestroyPtr & operator = ( const privateAutoDestroyPtr & ); -}; - -// extra effort taken here to not hold the lock when calling the callback -void dbContextReadNotifyCache::callReadNotify ( - epicsGuard < epicsMutex > & guard, struct dbChannel * dbch, - unsigned type, unsigned long count, cacReadNotify & notify ) -{ - guard.assertIdenticalMutex ( _mutex ); - - if ( type > INT_MAX ) { - notify.exception ( guard, ECA_BADTYPE, - "type code out of range (high side)", - type, count ); - return; - } - - const long maxcount = dbChannelElements(dbch); - - if ( maxcount < 0 ) { - notify.exception ( guard, ECA_BADCOUNT, - "database has negetive element count", - type, count); - return; - - } else if ( count > (unsigned long)maxcount ) { - notify.exception ( guard, ECA_BADCOUNT, - "element count out of range (high side)", - type, count); - return; - } - - long realcount = (count==0)?maxcount:count; - unsigned long size = dbr_size_n ( type, realcount ); - - privateAutoDestroyPtr ptr ( _allocator, size ); - int status; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - if ( count==0 ) - status = dbChannel_get_count ( dbch, (int)type, ptr.get(), &realcount, 0); - else - status = dbChannel_get ( dbch, (int)type, ptr.get (), realcount, 0 ); - } - if ( status ) { - notify.exception ( guard, ECA_GETFAIL, - "db_get_field() completed unsuccessfuly", - type, count ); - } - else { - notify.completion ( - guard, type, realcount, ptr.get () ); - } -} - -void dbContextReadNotifyCache::show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - guard.assertIdenticalMutex ( _mutex ); - - printf ( "dbContextReadNotifyCache\n" ); - if ( level > 0 ) { - this->_allocator.show ( level - 1 ); - } -} - -dbContextReadNotifyCacheAllocator::dbContextReadNotifyCacheAllocator () : - _readNotifyCacheSize ( 0 ), _pReadNotifyCache ( 0 ) -{ -} - -dbContextReadNotifyCacheAllocator::~dbContextReadNotifyCacheAllocator () -{ - this->reclaimAllCacheEntries (); -} - -void dbContextReadNotifyCacheAllocator::reclaimAllCacheEntries () -{ - while ( _pReadNotifyCache ) { - cacheElem_t * pNext = _pReadNotifyCache->pNext; - assert(_pReadNotifyCache->size == _readNotifyCacheSize); - ::free(_pReadNotifyCache); - _pReadNotifyCache = pNext; - } -} - -char * dbContextReadNotifyCacheAllocator::alloc ( unsigned long size ) -{ - if ( size > _readNotifyCacheSize ) { - this->reclaimAllCacheEntries (); - _readNotifyCacheSize = size; - } - - cacheElem_t * pAlloc = _pReadNotifyCache; - if ( pAlloc ) { - assert(pAlloc->size == _readNotifyCacheSize); - _pReadNotifyCache = pAlloc->pNext; - } - else { - pAlloc = (cacheElem_t*)calloc(1, sizeof(cacheElem_t)+_readNotifyCacheSize); - if(!pAlloc) throw std::bad_alloc(); - pAlloc->size = _readNotifyCacheSize; - } - return pAlloc->buf; -} - -void dbContextReadNotifyCacheAllocator::free ( char * pFree ) -{ - cacheElem_t * pAlloc = (cacheElem_t*)(pFree - offsetof(cacheElem_t, buf)); - if (pAlloc->size == _readNotifyCacheSize) { - pAlloc->pNext = _pReadNotifyCache; - _pReadNotifyCache = pAlloc; - } else { - ::free(pAlloc); - } -} - -void dbContextReadNotifyCacheAllocator::show ( unsigned level ) const -{ - printf ( "dbContextReadNotifyCacheAlocator\n" ); - if ( level > 0 ) { - size_t count =0; - cacheElem_t * pNext = _pReadNotifyCache; - while ( pNext ) { - assert(pNext->size == _readNotifyCacheSize); - pNext = _pReadNotifyCache->pNext; - count++; - } - printf ( "\tcount %lu and size %lu\n", - static_cast < unsigned long > ( count ), - _readNotifyCacheSize ); - } -} - - diff --git a/src/ioc/db/dbConvert.c b/src/ioc/db/dbConvert.c deleted file mode 100644 index 5d2c71f4c..000000000 --- a/src/ioc/db/dbConvert.c +++ /dev/null @@ -1,1839 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbConvert.c */ -/* - * Original Author: Bob Dalesio - * Date: 11-7-90 -*/ - -#include -#include -#include -#include -#include - -#include "cvtFast.h" -#include "dbDefs.h" -#include "epicsConvert.h" -#include "epicsStdlib.h" -#include "errlog.h" -#include "errMdef.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbConvert.h" -#include "dbFldTypes.h" -#include "dbStaticLib.h" -#include "link.h" -#include "recGbl.h" -#include "recSup.h" - -/* Helper for copy as bytes with no type conversion. - * Assumes nRequest <= no_bytes - * nRequest, no_bytes, and offset should be given in bytes. - */ -static void copyNoConvert(const void *pfrom, - void *pto, long nRequest, long no_bytes, long offset) -{ - const void *pfrom_offset = (const char *) pfrom + offset; - - if (offset > 0 && offset < no_bytes && offset + nRequest > no_bytes) { - const size_t N = no_bytes - offset; - void *pto_N = (char *) pto + N; - - /* copy with wrap */ - memmove(pto, pfrom_offset, N); - memmove(pto_N, pfrom, nRequest - N); - } else { - /* no wrap, just copy */ - memmove(pto, pfrom_offset, nRequest); - } -} -#define COPYNOCONVERT(N, FROM, TO, NREQ, NO_ELEM, OFFSET) \ - copyNoConvert(FROM, TO, (N)*(NREQ), (N)*(NO_ELEM), (N)*(OFFSET)) - -#define GET(typea, typeb) (const dbAddr *paddr, \ - void *pto, long nRequest, long no_elements, long offset) \ -{ \ - typea *psrc = (typea *) paddr->pfield; \ - typeb *pdst = (typeb *) pto; \ - \ - if (nRequest==1 && offset==0) { \ - *pdst = (typeb) *psrc; \ - return 0; \ - } \ - psrc += offset; \ - while (nRequest--) { \ - *pdst++ = (typeb) *psrc++; \ - if (++offset == no_elements) \ - psrc = (typea *) paddr->pfield; \ - } \ - return 0; \ -} - -#define GET_NOCONVERT(typea, typeb) (const dbAddr *paddr, \ - void *pto, long nRequest, long no_elements, long offset) \ -{ \ - if (nRequest==1 && offset==0) { \ - typea *psrc = (typea *) paddr->pfield; \ - typeb *pdst = (typeb *) pto; \ - \ - *pdst = (typeb) *psrc; \ - return 0; \ - } \ - COPYNOCONVERT(sizeof(typeb), paddr->pfield, pto, nRequest, no_elements, offset); \ - return 0; \ -} - -#define PUT(typea, typeb) (dbAddr *paddr, \ - const void *pfrom, long nRequest, long no_elements, long offset) \ -{ \ - const typea *psrc = (const typea *) pfrom; \ - typeb *pdst = (typeb *) paddr->pfield; \ - \ - if (nRequest==1 && offset==0) { \ - *pdst = (typeb) *psrc; \ - return 0; \ - } \ - pdst += offset; \ - while (nRequest--) { \ - *pdst++ = (typeb) *psrc++; \ - if (++offset == no_elements) \ - pdst = (typeb *) paddr->pfield; \ - } \ - return 0; \ -} - -#define PUT_NOCONVERT(typea, typeb) (dbAddr *paddr, \ - const void *pfrom, long nRequest, long no_elements, long offset) \ -{ \ - if (nRequest==1 && offset==0) { \ - const typea *psrc = (const typea *) pfrom; \ - typeb *pdst = (typeb *) paddr->pfield; \ - \ - *pdst = (typeb) *psrc; \ - return 0; \ - } \ - COPYNOCONVERT(sizeof(typeb), pfrom, paddr->pfield, nRequest, no_elements, offset); \ - return 0; \ -} - - -/* dbAccess Get conversion support routines */ - -static long getStringString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = paddr->pfield; - char *pdst = (char *) pto; - short size = paddr->field_size; - short sizeto; - - /* always force result string to be null terminated*/ - sizeto = size; - if (sizeto >= MAX_STRING_SIZE) - sizeto = MAX_STRING_SIZE - 1; - - if (nRequest==1 && offset==0) { - strncpy(pdst, psrc, sizeto); - pdst[sizeto] = 0; - return 0; - } - psrc += size * offset; - while (nRequest--) { - strncpy(pdst, psrc, sizeto); - pdst[sizeto] = 0; - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += size; - } - return 0; -} - -static long getStringChar(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsInt8 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseInt8(psrc, pdst++, 10, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringUchar(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsUInt8 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseUInt8(psrc, pdst++, 10, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringShort(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsInt16 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseInt16(psrc, pdst++, 10, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringUshort(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsUInt16 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseUInt16(psrc, pdst++, 10, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringLong(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsInt32 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseInt32(psrc, pdst++, 10, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringUlong(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsUInt32 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseUInt32(psrc, pdst, 10, &end); - - if (status == S_stdlib_noConversion || - (!status && (*end == '.' || *end == 'e' || *end == 'E'))) { - /* - * Convert via double so numbers like 1.0e3 convert properly. - * db_access pretends unsigned long is double. - */ - epicsFloat64 dval; - - status = epicsParseFloat64(psrc, &dval, &end); - if (!status && 0 <= dval && dval <= ULONG_MAX) - *pdst = dval; - } - if (status) - return status; - pdst++; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringInt64(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsInt64 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseInt64(psrc, pdst++, 10, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringUInt64(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsUInt64 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseUInt64(psrc, pdst++, 0, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringFloat(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsFloat32 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseFloat32(psrc, pdst++, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - -static long getStringDouble(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset; - epicsFloat64 *pdst = pto; - - while (nRequest--) { - if (*psrc == 0) - *pdst++ = 0; - else { - char *end; - long status = epicsParseFloat64(psrc, pdst++, &end); - - if (status) - return status; - } - if (++offset == no_elements) - psrc = paddr->pfield; - else - psrc += MAX_STRING_SIZE; - } - return 0; -} - - -static long getCharString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield; - char *pdst = (char *) pto; - - if (nRequest==1 && offset==0) { - cvtCharToString(*psrc, pdst); - return 0; - } - psrc += offset; - while (nRequest--) { - cvtCharToString(*psrc, pdst); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (char *) paddr->pfield; - else - psrc++; - } - return 0; -} - -static long getCharChar(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield; - char *pdst = (char *) pto; - - if (paddr->pfldDes && paddr->pfldDes->field_type == DBF_STRING) { - /* This is a DBF_STRING field being read as a long string. - * The buffer we return must be zero-terminated. - */ - pdst[--nRequest] = 0; - if (nRequest == 0) - return 0; - } - if (nRequest==1 && offset==0) { - *pdst = *psrc; - return 0; - } - COPYNOCONVERT(sizeof(char), paddr->pfield, pto, nRequest, no_elements, offset); - return 0; -} - -static long getCharUchar(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *psrc = (char *) paddr->pfield; - epicsUInt8 *pdst = (epicsUInt8 *) pto; - - if (paddr->pfldDes && paddr->pfldDes->field_type == DBF_STRING) { - /* This is a DBF_STRING field being read as a long string. - * The buffer we return must be zero-terminated. - */ - pdst[--nRequest] = 0; - if (nRequest == 0) - return 0; - } - if (nRequest==1 && offset==0) { - *pdst = *psrc; - return 0; - } - COPYNOCONVERT(sizeof(char), paddr->pfield, pto, nRequest, no_elements, offset); - return 0; -} - -static long getCharShort GET(char, epicsInt16) -static long getCharUshort GET(char, epicsUInt16) -static long getCharLong GET(char, epicsInt32) -static long getCharUlong GET(char, epicsUInt32) -static long getCharInt64 GET(char, epicsInt64) -static long getCharUInt64 GET(char, epicsUInt64) -static long getCharFloat GET(char, epicsFloat32) -static long getCharDouble GET(char, epicsFloat64) -static long getCharEnum GET(char, epicsEnum16) - -static long getUcharString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield; - char *pdst = (char *) pto; - - if (nRequest==1 && offset==0) { - cvtUcharToString(*psrc, pdst); - return 0; - } - psrc += offset; - while (nRequest--) { - cvtUcharToString(*psrc, pdst); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsUInt8 *) paddr->pfield; - else - psrc++; - } - return 0; -} - -static long getUcharChar GET_NOCONVERT(epicsUInt8, char) -static long getUcharUchar GET_NOCONVERT(epicsUInt8, epicsUInt8) -static long getUcharShort GET(epicsUInt8, epicsInt16) -static long getUcharUshort GET(epicsUInt8, epicsUInt16) -static long getUcharLong GET(epicsUInt8, epicsInt32) -static long getUcharUlong GET(epicsUInt8, epicsUInt32) -static long getUcharInt64 GET(epicsUInt8, epicsInt64) -static long getUcharUInt64 GET(epicsUInt8, epicsUInt64) -static long getUcharFloat GET(epicsUInt8, epicsFloat32) -static long getUcharDouble GET(epicsUInt8, epicsFloat64) -static long getUcharEnum GET(epicsUInt8, epicsEnum16) - -static long getShortString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsInt16 *psrc = (epicsInt16 *) paddr->pfield; - char *pdst = (char *) pto; - - if (nRequest==1 && offset==0) { - cvtShortToString(*psrc, pdst); - return 0; - } - psrc += offset; - while (nRequest--) { - cvtShortToString(*psrc, pdst); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsInt16 *) paddr->pfield; - else - psrc++; - } - return 0; -} - -static long getShortChar GET(epicsInt16, char) -static long getShortUchar GET(epicsInt16, epicsUInt8) -static long getShortShort GET_NOCONVERT(epicsInt16, epicsInt16) -static long getShortUshort GET_NOCONVERT(epicsInt16, epicsUInt16) -static long getShortLong GET(epicsInt16, epicsInt32) -static long getShortUlong GET(epicsInt16, epicsUInt32) -static long getShortInt64 GET(epicsInt16, epicsInt64) -static long getShortUInt64 GET(epicsInt16, epicsUInt64) -static long getShortFloat GET(epicsInt16, epicsFloat32) -static long getShortDouble GET(epicsInt16, epicsFloat64) -static long getShortEnum GET(epicsInt16, epicsEnum16) - -static long getUshortString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield; - char *pdst = (char *) pto; - - if (nRequest==1 && offset==0) { - cvtUshortToString(*psrc, pdst); - return 0; - } - psrc += offset; - while (nRequest--) { - cvtUshortToString(*psrc, pdst); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsUInt16 *) paddr->pfield; - else - psrc++; - } - return 0; -} - -static long getUshortChar GET(epicsUInt16, char) -static long getUshortUchar GET(epicsUInt16, epicsUInt8) -static long getUshortShort GET_NOCONVERT(epicsUInt16, epicsInt16) -static long getUshortUshort GET_NOCONVERT(epicsUInt16, epicsUInt16) -static long getUshortLong GET(epicsUInt16, epicsInt32) -static long getUshortUlong GET(epicsUInt16, epicsUInt32) -static long getUshortInt64 GET(epicsUInt16, epicsInt64) -static long getUshortUInt64 GET(epicsUInt16, epicsUInt64) -static long getUshortFloat GET(epicsUInt16, epicsFloat32) -static long getUshortDouble GET(epicsUInt16, epicsFloat64) -static long getUshortEnum GET(epicsUInt16, epicsEnum16) - -static long getLongString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsInt32 *psrc = (epicsInt32 *) paddr->pfield; - char *pdst = (char *) pto; - - if (nRequest==1 && offset==0) { - cvtLongToString(*psrc, pdst); - return 0; - } - psrc += offset; - while (nRequest--) { - cvtLongToString(*psrc, pdst); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsInt32 *) paddr->pfield; - else - psrc++; - } - return 0; -} - -static long getLongChar GET(epicsInt32, char) -static long getLongUchar GET(epicsInt32, epicsUInt8) -static long getLongShort GET(epicsInt32, epicsInt16) -static long getLongUshort GET(epicsInt32, epicsUInt16) -static long getLongLong GET_NOCONVERT(epicsInt32, epicsInt32) -static long getLongUlong GET_NOCONVERT(epicsInt32, epicsUInt32) -static long getLongInt64 GET(epicsInt32, epicsInt64) -static long getLongUInt64 GET(epicsInt32, epicsUInt64) -static long getLongFloat GET(epicsInt32, epicsFloat32) -static long getLongDouble GET(epicsInt32, epicsFloat64) -static long getLongEnum GET(epicsInt32, epicsEnum16) - -static long getUlongString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield; - char *pdst = (char *) pto; - - if (nRequest==1 && offset==0) { - cvtUlongToString(*psrc, pdst); - return 0; - } - psrc += offset; - while (nRequest--) { - cvtUlongToString(*psrc, pdst); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsUInt32 *) paddr->pfield; - else - psrc++; - } - return 0; -} - -static long getUlongChar GET(epicsUInt32, char) -static long getUlongUchar GET(epicsUInt32, epicsUInt8) -static long getUlongShort GET(epicsUInt32, epicsInt16) -static long getUlongUshort GET(epicsUInt32, epicsUInt16) -static long getUlongLong GET_NOCONVERT(epicsUInt32, epicsInt32) -static long getUlongUlong GET_NOCONVERT(epicsUInt32, epicsUInt32) -static long getUlongInt64 GET(epicsUInt32, epicsInt64) -static long getUlongUInt64 GET(epicsUInt32, epicsUInt64) -static long getUlongFloat GET(epicsUInt32, epicsFloat32) -static long getUlongDouble GET(epicsUInt32, epicsFloat64) -static long getUlongEnum GET(epicsUInt32, epicsEnum16) - -static long getInt64String(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsInt64 *psrc = (epicsInt64 *) paddr->pfield; - char *pdst = (char *) pto; - - if (nRequest==1 && offset==0) { - cvtInt64ToString(*psrc, pdst); - return 0; - } - psrc += offset; - while (nRequest--) { - cvtInt64ToString(*psrc, pdst); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsInt64 *) paddr->pfield; - else - psrc++; - } - return 0; -} - -static long getInt64Char GET(epicsInt64, char) -static long getInt64Uchar GET(epicsInt64, epicsUInt8) -static long getInt64Short GET(epicsInt64, epicsInt16) -static long getInt64Ushort GET(epicsInt64, epicsUInt16) -static long getInt64Long GET(epicsInt64, epicsInt32) -static long getInt64Ulong GET(epicsInt64, epicsUInt32) -static long getInt64Int64 GET_NOCONVERT(epicsInt64, epicsInt64) -static long getInt64UInt64 GET_NOCONVERT(epicsInt64, epicsUInt64) -static long getInt64Float GET(epicsInt64, epicsFloat32) -static long getInt64Double GET(epicsInt64, epicsFloat64) -static long getInt64Enum GET(epicsInt64, epicsEnum16) - -static long getUInt64String(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsUInt64 *psrc = (epicsUInt64 *) paddr->pfield; - char *pdst = (char *) pto; - - if (nRequest==1 && offset==0) { - cvtUInt64ToString(*psrc, pdst); - return 0; - } - psrc += offset; - while (nRequest--) { - cvtUInt64ToString(*psrc, pdst); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsUInt64 *) paddr->pfield; - else - psrc++; - } - return 0; -} - -static long getUInt64Char GET(epicsUInt64, char) -static long getUInt64Uchar GET(epicsUInt64, epicsUInt8) -static long getUInt64Short GET(epicsUInt64, epicsInt16) -static long getUInt64Ushort GET(epicsUInt64, epicsUInt16) -static long getUInt64Long GET(epicsUInt64, epicsInt32) -static long getUInt64Ulong GET(epicsUInt64, epicsUInt32) -static long getUInt64Int64 GET_NOCONVERT(epicsUInt64, epicsInt64) -static long getUInt64UInt64 GET_NOCONVERT(epicsUInt64, epicsUInt64) -static long getUInt64Float GET(epicsUInt64, epicsFloat32) -static long getUInt64Double GET(epicsUInt64, epicsFloat64) -static long getUInt64Enum GET(epicsUInt64, epicsEnum16) - -static long getFloatString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsFloat32 *psrc = (epicsFloat32 *) paddr->pfield; - char *pdst = (char *) pto; - long status = 0; - long precision = 6; - rset *prset = 0; - - if (paddr) - prset = dbGetRset(paddr); - if (prset && prset->get_precision) - status = prset->get_precision(paddr, &precision); - if (nRequest==1 && offset==0) { - cvtFloatToString(*psrc, pdst, precision); - return(status); - } - psrc += offset; - while (nRequest--) { - cvtFloatToString(*psrc, pdst, precision); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsFloat32 *) paddr->pfield; - else - psrc++; - } - return(status); -} - -static long getFloatChar GET(epicsFloat32, char) -static long getFloatUchar GET(epicsFloat32, epicsUInt8) -static long getFloatShort GET(epicsFloat32, epicsInt16) -static long getFloatUshort GET(epicsFloat32, epicsUInt16) -static long getFloatLong GET(epicsFloat32, epicsInt32) -static long getFloatUlong GET(epicsFloat32, epicsUInt32) -static long getFloatInt64 GET(epicsFloat32, epicsInt64) -static long getFloatUInt64 GET(epicsFloat32, epicsUInt64) -static long getFloatFloat GET_NOCONVERT(epicsFloat32, epicsFloat32) -static long getFloatDouble GET(epicsFloat32, epicsFloat64) -static long getFloatEnum GET(epicsFloat32, epicsEnum16) - -static long getDoubleString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsFloat64 *psrc = (epicsFloat64 *) paddr->pfield; - char *pdst = (char *) pto; - long status = 0; - long precision = 6; - rset *prset = 0; - - if (paddr) - prset = dbGetRset(paddr); - if (prset && prset->get_precision) - status = prset->get_precision(paddr, &precision); - if (nRequest==1 && offset==0) { - cvtDoubleToString(*psrc, pdst, precision); - return(status); - } - psrc += offset; - while (nRequest--) { - cvtDoubleToString(*psrc, pdst, precision); - pdst += MAX_STRING_SIZE; - if (++offset == no_elements) - psrc = (epicsFloat64 *) paddr->pfield; - else - psrc++; - } - return(status); -} - -static long getDoubleChar GET(epicsFloat64, char) -static long getDoubleUchar GET(epicsFloat64, epicsUInt8) -static long getDoubleShort GET(epicsFloat64, epicsInt16) -static long getDoubleUshort GET(epicsFloat64, epicsUInt16) -static long getDoubleLong GET(epicsFloat64, epicsInt32) -static long getDoubleUlong GET(epicsFloat64, epicsUInt32) -static long getDoubleInt64 GET(epicsFloat64, epicsInt64) -static long getDoubleUInt64 GET(epicsFloat64, epicsUInt64) - -static long getDoubleFloat(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - epicsFloat64 *psrc = (epicsFloat64 *) paddr->pfield; - epicsFloat32 *pdst = (epicsFloat32 *) pto; - - if (nRequest==1 && offset==0) { - *pdst = epicsConvertDoubleToFloat(*psrc); - return 0; - } - psrc += offset; - while (nRequest--) { - *pdst = epicsConvertDoubleToFloat(*psrc); - ++psrc; ++pdst; - if (++offset == no_elements) - psrc = (epicsFloat64 *) paddr->pfield; - } - return 0; -} - -static long getDoubleDouble GET_NOCONVERT(epicsFloat64, epicsFloat64) -static long getDoubleEnum GET(epicsFloat64, epicsEnum16) - -static long getEnumString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *pdst = (char *) pto; - rset *prset; - long status; - - prset = dbGetRset(paddr); - if (prset && prset->get_enum_str) - return prset->get_enum_str(paddr, pdst); - - status = S_db_noRSET; - recGblRecSupError(status, paddr, "dbGet", "get_enum_str"); - return S_db_badDbrtype; -} - -static long getEnumChar GET(epicsEnum16, char) -static long getEnumUchar GET(epicsEnum16, epicsUInt8) -static long getEnumShort GET(epicsEnum16, epicsInt16) -static long getEnumUshort GET(epicsEnum16, epicsUInt16) -static long getEnumLong GET(epicsEnum16, epicsInt32) -static long getEnumUlong GET(epicsEnum16, epicsUInt32) -static long getEnumInt64 GET(epicsEnum16, epicsInt64) -static long getEnumUInt64 GET(epicsEnum16, epicsUInt64) -static long getEnumFloat GET(epicsEnum16, epicsFloat32) -static long getEnumDouble GET(epicsEnum16, epicsFloat64) -static long getEnumEnum GET_NOCONVERT(epicsEnum16, epicsEnum16) - -static long getMenuString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *pdst = (char *) pto; - dbFldDes *pdbFldDes = paddr->pfldDes; - dbMenu *pdbMenu; - char **papChoiceValue; - char *pchoice; - epicsEnum16 choice_ind= *((epicsEnum16*) paddr->pfield); - - if (no_elements!=1){ - recGblDbaddrError(S_db_onlyOne, paddr, "dbGet(getMenuString)"); - return(S_db_onlyOne); - } - if (!pdbFldDes - || !(pdbMenu = (dbMenu *) pdbFldDes->ftPvt) - || (choice_ind>=pdbMenu->nChoice) - || !(papChoiceValue = pdbMenu->papChoiceValue) - || !(pchoice=papChoiceValue[choice_ind])) { - recGblDbaddrError(S_db_badChoice, paddr, "dbGet(getMenuString)"); - return(S_db_badChoice); - } - strncpy(pdst, pchoice, MAX_STRING_SIZE); - return 0; -} - -static long getDeviceString(const dbAddr *paddr, - void *pto, long nRequest, long no_elements, long offset) -{ - char *pdst = (char *) pto; - dbFldDes *pdbFldDes = paddr->pfldDes; - dbDeviceMenu *pdbDeviceMenu; - char **papChoice; - char *pchoice; - epicsEnum16 choice_ind= *((epicsEnum16*) paddr->pfield); - - if (no_elements!=1){ - recGblDbaddrError(S_db_onlyOne, paddr, "dbGet(getDeviceString)"); - return(S_db_onlyOne); - } - if (!pdbFldDes - || !(pdbDeviceMenu = (dbDeviceMenu *) pdbFldDes->ftPvt) - || (choice_ind>=pdbDeviceMenu->nChoice ) - || !(papChoice = pdbDeviceMenu->papChoice) - || !(pchoice=papChoice[choice_ind])) { - recGblDbaddrError(S_db_badChoice, paddr, "dbGet(getDeviceString)"); - return(S_db_badChoice); - } - strncpy(pdst, pchoice, MAX_STRING_SIZE); - return 0; -} - - -/* dbAccess put conversion support routines */ - -static long putStringString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = (const char *) pfrom; - char *pdst = paddr->pfield; - short size = paddr->field_size; - - if (nRequest==1 && offset==0) { - strncpy(pdst, psrc, size); - *(pdst+size-1) = 0; - return 0; - } - pdst+= (size*offset); - while (nRequest--) { - strncpy(pdst, psrc, size); - pdst[size-1] = 0; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putStringChar(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsInt8 *pdst = (epicsInt8 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseInt8(psrc, pdst++, 10, &end); - - if (status) - return status; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - } - return 0; -} - -static long putStringUchar(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsUInt8 *pdst = (epicsUInt8 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseUInt8(psrc, pdst++, 10, &end); - - if (status) - return status; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - } - return 0; -} - -static long putStringShort(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsInt16 *pdst = (epicsInt16 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseInt16(psrc, pdst++, 10, &end); - - if (status) - return status; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - } - return 0; -} - -static long putStringUshort(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsUInt16 *pdst = (epicsUInt16 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseUInt16(psrc, pdst++, 10, &end); - - if (status) - return status; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - } - return 0; -} - -static long putStringLong(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsInt32 *pdst = (epicsInt32 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseInt32(psrc, pdst++, 10, &end); - - if (status) - return status; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - } - return 0; -} - -static long putStringUlong(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsUInt32 *pdst = (epicsUInt32 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseUInt32(psrc, pdst, 10, &end); - - if (status == S_stdlib_noConversion || - (!status && (*end == '.' || *end == 'e' || *end == 'E'))) { - /* - * Convert via double so numbers like 1.0e3 convert properly. - * db_access pretends unsigned long is double. - */ - epicsFloat64 dval; - - status = epicsParseFloat64(psrc, &dval, &end); - if (!status && 0 <= dval && dval <= ULONG_MAX) - *pdst = dval; - } - if (status) - return status; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - else - pdst++; - } - return 0; -} - -static long putStringInt64(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsInt64 *pdst = (epicsInt64 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseInt64(psrc, pdst++, 10, &end); - - if (status) - return status; - - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - } - return 0; -} - -static long putStringUInt64(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsUInt64 *pdst = (epicsUInt64 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseUInt64(psrc, pdst, 0, &end); - - if (status) - return status; - - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - else - pdst++; - } - return 0; -} - -static long putStringFloat(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsFloat32 *pdst = (epicsFloat32 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseFloat32(psrc, pdst++, &end); - - if (status) - return status; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - } - return 0; -} - -static long putStringDouble(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = pfrom; - epicsFloat64 *pdst = (epicsFloat64 *) paddr->pfield + offset; - - while (nRequest--) { - char *end; - long status = epicsParseFloat64(psrc, pdst++, &end); - - if (status) - return status; - psrc += MAX_STRING_SIZE; - if (++offset == no_elements) - pdst = paddr->pfield; - } - return 0; -} - -static long putStringEnum(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - epicsEnum16 *pfield = paddr->pfield; - rset *prset = dbGetRset(paddr); - long status = S_db_noRSET; - struct dbr_enumStrs enumStrs; - - if (no_elements != 1) { - recGblDbaddrError(S_db_onlyOne, paddr, "dbPut(putStringEnum)"); - return S_db_onlyOne; - } - - if (!prset || !prset->put_enum_str) { - recGblRecSupError(status, paddr, "dbPut(putStringEnum)", "put_enum_str"); - return status; - } - - status = prset->put_enum_str(paddr, pfrom); - if (!status) - return status; - - if (!prset->get_enum_strs) { - recGblRecSupError(status, paddr, "dbPut(putStringEnum)", "get_enum_strs"); - return status; - } - - status = prset->get_enum_strs(paddr, &enumStrs); - if (!status) { - epicsEnum16 val; - char *end; - - status = epicsParseUInt16(pfrom, &val, 10, &end); - if (!status && val < enumStrs.no_str) { - *pfield = val; - return 0; - } - status = S_db_badChoice; - } - - recGblRecordError(status, paddr->precord, pfrom); - return status; -} - -static long putStringMenu(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - dbFldDes *pdbFldDes = paddr->pfldDes; - epicsEnum16 *pfield = paddr->pfield; - dbMenu *pdbMenu; - char **pchoices, *pchoice; - - if (no_elements != 1) { - recGblDbaddrError(S_db_onlyOne, paddr, "dbPut(putStringMenu)"); - return S_db_onlyOne; - } - - if (pdbFldDes && - (pdbMenu = pdbFldDes->ftPvt) && - (pchoices = pdbMenu->papChoiceValue)) { - int i, nChoice = pdbMenu->nChoice; - epicsEnum16 val; - - for (i = 0; i < nChoice; i++) { - pchoice = pchoices[i]; - if (!pchoice) - continue; - if (strcmp(pchoice, pfrom) == 0) { - *pfield = i; - return 0; - } - } - - if (!epicsParseUInt16(pfrom, &val, 10, NULL) - && val < nChoice) { - *pfield = val; - return 0; - } - } - recGblDbaddrError(S_db_badChoice, paddr, "dbPut(putStringMenu)"); - return S_db_badChoice; -} - -static long putStringDevice(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - dbFldDes *pdbFldDes = paddr->pfldDes; - dbDeviceMenu *pdbDeviceMenu = pdbFldDes->ftPvt; - epicsEnum16 *pfield = paddr->pfield; - char **pchoices, *pchoice; - - if (no_elements != 1) { - recGblDbaddrError(S_db_onlyOne, paddr, "dbPut(putStringDevice)"); - return S_db_onlyOne; - } - - if (pdbFldDes && - (pdbDeviceMenu = pdbFldDes->ftPvt) && - (pchoices = pdbDeviceMenu->papChoice)) { - int i, nChoice = pdbDeviceMenu->nChoice; - epicsEnum16 val; - - for (i = 0; i < nChoice; i++) { - pchoice = pchoices[i]; - if (!pchoice) - continue; - if (strcmp(pchoice, pfrom) == 0) { - *pfield = i; - return 0; - } - } - - if (!epicsParseUInt16(pfrom, &val, 10, NULL) && val < nChoice) { - *pfield = val; - return 0; - } - } - recGblDbaddrError(S_db_badChoice, paddr, "dbPut(putStringDevice)"); - return S_db_badChoice; -} - - -static long putCharString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const char *psrc = (const char *) pfrom; - char *pdst = (char *) paddr->pfield; - short size = paddr->field_size; - - if (nRequest==1 && offset==0) { - cvtCharToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtCharToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putCharChar PUT_NOCONVERT(char, char) -static long putCharUchar PUT_NOCONVERT(char, epicsUInt8) -static long putCharShort PUT(char, epicsInt16) -static long putCharUshort PUT(char, epicsUInt16) -static long putCharLong PUT(char, epicsInt32) -static long putCharUlong PUT(char, epicsUInt32) -static long putCharInt64 PUT(char, epicsInt64) -static long putCharUInt64 PUT(char, epicsUInt64) -static long putCharFloat PUT(char, epicsFloat32) -static long putCharDouble PUT(char, epicsFloat64) -static long putCharEnum PUT(char, epicsEnum16) - -static long putUcharString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsUInt8 *psrc = (const epicsUInt8 *) pfrom; - char *pdst = (char *) paddr->pfield; - short size = paddr->field_size; - - - if (nRequest==1 && offset==0) { - cvtUcharToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtUcharToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putUcharChar PUT_NOCONVERT(epicsUInt8, char) -static long putUcharUchar PUT_NOCONVERT(epicsUInt8, epicsUInt8) -static long putUcharShort PUT(epicsUInt8, epicsInt16) -static long putUcharUshort PUT(epicsUInt8, epicsUInt16) -static long putUcharLong PUT(epicsUInt8, epicsInt32) -static long putUcharUlong PUT(epicsUInt8, epicsUInt32) -static long putUcharInt64 PUT(epicsUInt8, epicsInt64) -static long putUcharUInt64 PUT(epicsUInt8, epicsUInt64) -static long putUcharFloat PUT(epicsUInt8, epicsFloat32) -static long putUcharDouble PUT(epicsUInt8, epicsFloat64) -static long putUcharEnum PUT(epicsUInt8, epicsEnum16) - -static long putShortString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsInt16 *psrc = (const epicsInt16 *) pfrom; - char *pdst = (char *) paddr->pfield; - short size = paddr->field_size; - - - if (nRequest==1 && offset==0) { - cvtShortToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtShortToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putShortChar PUT(epicsInt16, char) -static long putShortUchar PUT(epicsInt16, epicsUInt8) -static long putShortShort PUT_NOCONVERT(epicsInt16, epicsInt16) -static long putShortUshort PUT_NOCONVERT(epicsInt16, epicsUInt16) -static long putShortLong PUT(epicsInt16, epicsInt32) -static long putShortUlong PUT(epicsInt16, epicsUInt32) -static long putShortInt64 PUT(epicsInt16, epicsInt64) -static long putShortUInt64 PUT(epicsInt16, epicsUInt64) -static long putShortFloat PUT(epicsInt16, epicsFloat32) -static long putShortDouble PUT(epicsInt16, epicsFloat64) -static long putShortEnum PUT(epicsInt16, epicsEnum16) - -static long putUshortString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsUInt16 *psrc = (const epicsUInt16 *) pfrom; - char *pdst = (char *) paddr->pfield; - short size = paddr->field_size; - - - if (nRequest==1 && offset==0) { - cvtUshortToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtUshortToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putUshortChar PUT(epicsUInt16, char) -static long putUshortUchar PUT(epicsUInt16, epicsUInt8) -static long putUshortShort PUT_NOCONVERT(epicsUInt16, epicsInt16) -static long putUshortUshort PUT_NOCONVERT(epicsUInt16, epicsUInt16) -static long putUshortLong PUT(epicsUInt16, epicsInt32) -static long putUshortUlong PUT(epicsUInt16, epicsUInt32) -static long putUshortInt64 PUT(epicsUInt16, epicsInt64) -static long putUshortUInt64 PUT(epicsUInt16, epicsUInt64) -static long putUshortFloat PUT(epicsUInt16, epicsFloat32) -static long putUshortDouble PUT(epicsUInt16, epicsFloat64) -static long putUshortEnum PUT(epicsUInt16, epicsEnum16) - -static long putLongString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsInt32 *psrc = (const epicsInt32 *) pfrom; - char *pdst = (char *) paddr->pfield; - short size = paddr->field_size; - - - if (nRequest==1 && offset==0) { - cvtLongToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtLongToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putLongChar PUT(epicsInt32, char) -static long putLongUchar PUT(epicsInt32, epicsUInt8) -static long putLongShort PUT(epicsInt32, epicsInt16) -static long putLongUshort PUT(epicsInt32, epicsUInt16) -static long putLongLong PUT_NOCONVERT(epicsInt32, epicsInt32) -static long putLongUlong PUT_NOCONVERT(epicsInt32, epicsUInt32) -static long putLongInt64 PUT(epicsInt32, epicsInt64) -static long putLongUInt64 PUT(epicsInt32, epicsUInt64) -static long putLongFloat PUT(epicsInt32, epicsFloat32) -static long putLongDouble PUT(epicsInt32, epicsFloat64) -static long putLongEnum PUT(epicsInt32, epicsEnum16) - -static long putUlongString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsUInt32 *psrc = (const epicsUInt32 *) pfrom; - char *pdst = (char *) paddr->pfield; - short size = paddr->field_size; - - - if (nRequest==1 && offset==0) { - cvtUlongToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtUlongToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putUlongChar PUT(epicsUInt32, char) -static long putUlongUchar PUT(epicsUInt32, epicsUInt8) -static long putUlongShort PUT(epicsUInt32, epicsInt16) -static long putUlongUshort PUT(epicsUInt32, epicsUInt16) -static long putUlongLong PUT_NOCONVERT(epicsUInt32, epicsInt32) -static long putUlongUlong PUT_NOCONVERT(epicsUInt32, epicsUInt32) -static long putUlongInt64 PUT(epicsUInt32, epicsInt64) -static long putUlongUInt64 PUT(epicsUInt32, epicsUInt64) -static long putUlongFloat PUT(epicsUInt32, epicsFloat32) -static long putUlongDouble PUT(epicsUInt32, epicsFloat64) -static long putUlongEnum PUT(epicsUInt32, epicsEnum16) - -static long putInt64String(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsInt64 *psrc = (const epicsInt64 *) pfrom; - char *pdst = (char *) paddr->pfield; - short size=paddr->field_size; - - - if (nRequest==1 && offset==0) { - cvtInt64ToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtInt64ToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putInt64Char PUT(epicsInt64, char) -static long putInt64Uchar PUT(epicsInt64, epicsUInt8) -static long putInt64Short PUT(epicsInt64, epicsInt16) -static long putInt64Ushort PUT(epicsInt64, epicsUInt16) -static long putInt64Long PUT(epicsInt64, epicsInt32) -static long putInt64Ulong PUT(epicsInt64, epicsUInt32) -static long putInt64Int64 PUT_NOCONVERT(epicsInt64, epicsInt64) -static long putInt64UInt64 PUT_NOCONVERT(epicsInt64, epicsUInt64) -static long putInt64Float PUT(epicsInt64, epicsFloat32) -static long putInt64Double PUT(epicsInt64, epicsFloat64) -static long putInt64Enum PUT(epicsInt64, epicsEnum16) - -static long putUInt64String(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsUInt64 *psrc = (const epicsUInt64 *) pfrom; - char *pdst = (char *) paddr->pfield; - short size=paddr->field_size; - - - if (nRequest==1 && offset==0) { - cvtUlongToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtUlongToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putUInt64Char PUT(epicsUInt64, char) -static long putUInt64Uchar PUT(epicsUInt64, epicsUInt8) -static long putUInt64Short PUT(epicsUInt64, epicsInt16) -static long putUInt64Ushort PUT(epicsUInt64, epicsUInt16) -static long putUInt64Long PUT(epicsUInt64, epicsInt32) -static long putUInt64Ulong PUT(epicsUInt64, epicsUInt32) -static long putUInt64Int64 PUT_NOCONVERT(epicsUInt64, epicsInt64) -static long putUInt64UInt64 PUT_NOCONVERT(epicsUInt64, epicsUInt64) -static long putUInt64Float PUT(epicsUInt64, epicsFloat32) -static long putUInt64Double PUT(epicsUInt64, epicsFloat64) -static long putUInt64Enum PUT(epicsUInt64, epicsEnum16) - -static long putFloatString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsFloat32 *psrc = (const epicsFloat32 *) pfrom; - char *pdst = (char *) paddr->pfield; - long status = 0; - long precision = 6; - rset *prset = 0; - short size = paddr->field_size; - - if (paddr) - prset = dbGetRset(paddr); - if (prset && prset->get_precision) - status = prset->get_precision(paddr, &precision); - if (nRequest==1 && offset==0) { - cvtFloatToString(*psrc, pdst, precision); - return(status); - } - pdst += (size*offset); - while (nRequest--) { - cvtFloatToString(*psrc, pdst, precision); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return(status); -} - -static long putFloatChar PUT(epicsFloat32, char) -static long putFloatUchar PUT(epicsFloat32, epicsUInt8) -static long putFloatShort PUT(epicsFloat32, epicsInt16) -static long putFloatUshort PUT(epicsFloat32, epicsUInt16) -static long putFloatLong PUT(epicsFloat32, epicsInt32) -static long putFloatUlong PUT(epicsFloat32, epicsUInt32) -static long putFloatInt64 PUT(epicsFloat32, epicsInt64) -static long putFloatUInt64 PUT(epicsFloat32, epicsUInt64) -static long putFloatFloat PUT_NOCONVERT(epicsFloat32, epicsFloat32) -static long putFloatDouble PUT(epicsFloat32, epicsFloat64) -static long putFloatEnum PUT(epicsFloat32, epicsEnum16) - -static long putDoubleString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsFloat64 *psrc = (const epicsFloat64 *) pfrom; - char *pdst = (char *) paddr->pfield; - long status = 0; - long precision = 6; - rset *prset = 0; - short size = paddr->field_size; - - if (paddr) - prset = dbGetRset(paddr); - if (prset && prset->get_precision) - status = prset->get_precision(paddr, &precision); - if (nRequest==1 && offset==0) { - cvtDoubleToString(*psrc, pdst, precision); - return status; - } - pdst += (size*offset); - while (nRequest--) { - cvtDoubleToString(*psrc, pdst, precision); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return status; -} - -static long putDoubleChar PUT(epicsFloat64, char) -static long putDoubleUchar PUT(epicsFloat64, epicsUInt8) -static long putDoubleShort PUT(epicsFloat64, epicsInt16) -static long putDoubleUshort PUT(epicsFloat64, epicsUInt16) -static long putDoubleLong PUT(epicsFloat64, epicsInt32) -static long putDoubleUlong PUT(epicsFloat64, epicsUInt32) -static long putDoubleInt64 PUT(epicsFloat64, epicsInt64) -static long putDoubleUInt64 PUT(epicsFloat64, epicsUInt64) - -static long putDoubleFloat(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsFloat64 *psrc = (const epicsFloat64 *) pfrom; - epicsFloat32 *pdst = (epicsFloat32 *) paddr->pfield; - - if (nRequest==1 && offset==0) { - *pdst = epicsConvertDoubleToFloat(*psrc); - return 0; - } - pdst += offset; - while (nRequest--) { - *pdst++ = epicsConvertDoubleToFloat(*psrc++); - if (++offset == no_elements) - pdst = (epicsFloat32 *) paddr->pfield; - } - return 0; -} - -static long putDoubleDouble PUT_NOCONVERT(epicsFloat64, epicsFloat64) -static long putDoubleEnum PUT(epicsFloat64, epicsEnum16) - -static long putEnumString(dbAddr *paddr, - const void *pfrom, long nRequest, long no_elements, long offset) -{ - const epicsEnum16 *psrc = (const epicsEnum16 *) pfrom; - char *pdst = (char *) paddr->pfield; - short size = paddr->field_size; - - - if (nRequest==1 && offset==0) { - cvtUshortToString(*psrc, pdst); - return 0; - } - pdst += (size*offset); - while (nRequest--) { - cvtUshortToString(*psrc, pdst); - psrc++; - if (++offset == no_elements) - pdst = (char *) paddr->pfield; - else - pdst += size; - } - return 0; -} - -static long putEnumChar PUT(epicsEnum16, char) -static long putEnumUchar PUT(epicsEnum16, epicsUInt8) -static long putEnumShort PUT(epicsEnum16, epicsInt16) -static long putEnumUshort PUT(epicsEnum16, epicsUInt16) -static long putEnumLong PUT(epicsEnum16, epicsInt32) -static long putEnumUlong PUT(epicsEnum16, epicsUInt32) -static long putEnumInt64 PUT(epicsEnum16, epicsInt64) -static long putEnumUInt64 PUT(epicsEnum16, epicsUInt64) -static long putEnumFloat PUT(epicsEnum16, epicsFloat32) -static long putEnumDouble PUT(epicsEnum16, epicsFloat64) -static long putEnumEnum PUT_NOCONVERT(epicsEnum16, epicsEnum16) - -/* This is the table of routines for converting database fields */ -/* the rows represent the field type of the database field */ -/* the columns represent the types of the buffer in which they are placed */ - -/* buffer types are******************************************************** - DBR_STRING, DBR_CHR, DBR_UCHAR, DBR_SHORT, DBR_USHORT, - DBR_LONG, DBR_ULONG, DBR_INT64, DBR_UINT64, - DBR_FLOAT, DBR_DOUBLE, DBR_ENUM - ***************************************************************************/ - -epicsShareDef GETCONVERTFUNC dbGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1] = { - -/* source is a DBF_STRING */ -{getStringString, getStringChar, getStringUchar, getStringShort, getStringUshort, - getStringLong, getStringUlong, getStringInt64, getStringUInt64, - getStringFloat, getStringDouble, getStringUshort}, -/* source is a DBF_CHAR */ -{getCharString, getCharChar, getCharUchar, getCharShort, getCharUshort, - getCharLong, getCharUlong, getCharInt64, getCharUInt64, - getCharFloat, getCharDouble, getCharEnum}, -/* source is a DBF_UCHAR */ -{getUcharString, getUcharChar, getUcharUchar, getUcharShort, getUcharUshort, - getUcharLong, getUcharUlong, getUcharInt64, getUcharUInt64, - getUcharFloat, getUcharDouble, getUcharEnum}, -/* source is a DBF_SHORT */ -{getShortString, getShortChar, getShortUchar, getShortShort, getShortUshort, - getShortLong, getShortUlong, getShortInt64, getShortUInt64, - getShortFloat, getShortDouble, getShortEnum}, -/* source is a DBF_USHORT */ -{getUshortString, getUshortChar, getUshortUchar, getUshortShort, getUshortUshort, - getUshortLong, getUshortUlong, getUshortInt64, getUshortUInt64, - getUshortFloat, getUshortDouble, getUshortEnum}, -/* source is a DBF_LONG */ -{getLongString, getLongChar, getLongUchar, getLongShort, getLongUshort, - getLongLong, getLongUlong, getLongInt64, getLongUInt64, - getLongFloat, getLongDouble, getLongEnum}, -/* source is a DBF_ULONG */ -{getUlongString, getUlongChar, getUlongUchar, getUlongShort, getUlongUshort, - getUlongLong, getUlongUlong, getUlongInt64, getUlongUInt64, - getUlongFloat, getUlongDouble, getUlongEnum}, -/* source is a DBF_INT64 */ -{getInt64String, getInt64Char, getInt64Uchar, getInt64Short, getInt64Ushort, - getInt64Long, getInt64Ulong, getInt64Int64, getInt64UInt64, - getInt64Float, getInt64Double, getInt64Enum}, -/* source is a DBF_UINT64 */ -{getUInt64String, getUInt64Char, getUInt64Uchar, getUInt64Short, getUInt64Ushort, - getUInt64Long, getUInt64Ulong, getUInt64Int64, getUInt64UInt64, - getUInt64Float, getUInt64Double, getUInt64Enum}, -/* source is a DBF_FLOAT */ -{getFloatString, getFloatChar, getFloatUchar, getFloatShort, getFloatUshort, - getFloatLong, getFloatUlong, getFloatInt64, getFloatUInt64, - getFloatFloat, getFloatDouble, getFloatEnum}, -/* source is a DBF_DOUBLE */ -{getDoubleString, getDoubleChar, getDoubleUchar, getDoubleShort, getDoubleUshort, - getDoubleLong, getDoubleUlong, getDoubleInt64, getDoubleUInt64, - getDoubleFloat, getDoubleDouble, getDoubleEnum}, -/* source is a DBF_ENUM */ -{getEnumString, getEnumChar, getEnumUchar, getEnumShort, getEnumUshort, - getEnumLong, getEnumUlong, getEnumInt64, getEnumUInt64, - getEnumFloat, getEnumDouble, getEnumEnum}, -/* source is a DBF_MENU */ -{getMenuString, getEnumChar, getEnumUchar, getEnumShort, getEnumUshort, - getEnumLong, getEnumUlong, getEnumInt64, getEnumUInt64, - getEnumFloat, getEnumDouble, getEnumEnum}, -/* source is a DBF_DEVICE */ -{getDeviceString, getEnumChar, getEnumUchar, getEnumShort, getEnumUshort, - getEnumLong, getEnumUlong, getEnumInt64, getEnumUInt64, - getEnumFloat, getEnumDouble, getEnumEnum}, -}; - -/* This is the table of routines for converting database fields */ -/* the rows represent the buffer types */ -/* the columns represent the field types */ - -/* field types are******************************************************** - DBF_STRING, DBF_CHAR, DBF_UCHAR, DBF_SHORT, DBF_USHORT, - DBF_LONG, DBF_ULONG, DBF_INT64, DBF_UINT64, - DBF_FLOAT, DBF_DOUBLE, DBF_ENUM - DBF_MENU, DBF_DEVICE - ***************************************************************************/ - -epicsShareDef PUTCONVERTFUNC dbPutConvertRoutine[DBR_ENUM+1][DBF_DEVICE+1] = { -/* source is a DBR_STRING */ -{putStringString, putStringChar, putStringUchar, putStringShort, putStringUshort, - putStringLong, putStringUlong, putStringInt64, putStringUInt64, - putStringFloat, putStringDouble, putStringEnum, - putStringMenu, putStringDevice}, -/* source is a DBR_CHAR */ -{putCharString, putCharChar, putCharUchar, putCharShort, putCharUshort, - putCharLong, putCharUlong, putCharInt64, putCharUInt64, - putCharFloat, putCharDouble, putCharEnum, - putCharEnum, putCharEnum}, -/* source is a DBR_UCHAR */ -{putUcharString, putUcharChar, putUcharUchar, putUcharShort, putUcharUshort, - putUcharLong, putUcharUlong, putUcharInt64, putUcharUInt64, - putUcharFloat, putUcharDouble, putUcharEnum, - putUcharEnum, putUcharEnum}, -/* source is a DBR_SHORT */ -{putShortString, putShortChar, putShortUchar, putShortShort, putShortUshort, - putShortLong, putShortUlong, putShortInt64, putShortUInt64, - putShortFloat, putShortDouble, putShortEnum, - putShortEnum, putShortEnum}, -/* source is a DBR_USHORT */ -{putUshortString, putUshortChar, putUshortUchar, putUshortShort, putUshortUshort, - putUshortLong, putUshortUlong, putUshortInt64, putUshortUInt64, - putUshortFloat, putUshortDouble, putUshortEnum, - putUshortEnum, putUshortEnum}, -/* source is a DBR_LONG */ -{putLongString, putLongChar, putLongUchar, putLongShort, putLongUshort, - putLongLong, putLongUlong, putLongInt64, putLongUInt64, - putLongFloat, putLongDouble, putLongEnum, - putLongEnum, putLongEnum}, -/* source is a DBR_ULONG */ -{putUlongString, putUlongChar, putUlongUchar, putUlongShort, putUlongUshort, - putUlongLong, putUlongUlong, putUlongInt64, putUlongUInt64, - putUlongFloat, putUlongDouble, putUlongEnum, - putUlongEnum, putUlongEnum}, -/* source is a DBR_INT64 */ -{putInt64String, putInt64Char, putInt64Uchar, putInt64Short, putInt64Ushort, - putInt64Long, putInt64Ulong, putInt64Int64, putInt64UInt64, - putInt64Float, putInt64Double, putInt64Enum, - putInt64Enum, putInt64Enum}, -/* source is a DBR_UINT64 */ -{putUInt64String, putUInt64Char, putUInt64Uchar, putUInt64Short, putUInt64Ushort, - putUInt64Long, putUInt64Ulong, putUInt64Int64, putUInt64UInt64, - putUInt64Float, putUInt64Double, putUInt64Enum, - putUInt64Enum, putUInt64Enum}, -/* source is a DBR_FLOAT */ -{putFloatString, putFloatChar, putFloatUchar, putFloatShort, putFloatUshort, - putFloatLong, putFloatUlong, putFloatInt64, putFloatUInt64, - putFloatFloat, putFloatDouble, putFloatEnum, - putFloatEnum, putFloatEnum}, -/* source is a DBR_DOUBLE */ -{putDoubleString, putDoubleChar, putDoubleUchar, putDoubleShort, putDoubleUshort, - putDoubleLong, putDoubleUlong, putDoubleInt64, putDoubleUInt64, - putDoubleFloat, putDoubleDouble, putDoubleEnum, - putDoubleEnum, putDoubleEnum}, -/* source is a DBR_ENUM */ -{putEnumString, putEnumChar, putEnumUchar, putEnumShort, putEnumUshort, - putEnumLong, putEnumUlong, putEnumInt64, putEnumUInt64, - putEnumFloat, putEnumDouble, putEnumEnum, - putEnumEnum, putEnumEnum} -}; diff --git a/src/ioc/db/dbConvert.h b/src/ioc/db/dbConvert.h deleted file mode 100644 index afd13c7c2..000000000 --- a/src/ioc/db/dbConvert.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbConvert.h */ - -#ifndef INCdbConverth -#define INCdbConverth - -#include "dbFldTypes.h" -#include "dbAddr.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef long (*GETCONVERTFUNC)(const DBADDR *paddr, void *pbuffer, - long nRequest, long no_elements, long offset); -typedef long (*PUTCONVERTFUNC)(DBADDR *paddr, const void *pbuffer, - long nRequest, long no_elements, long offset); - -epicsShareExtern GETCONVERTFUNC dbGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1]; -epicsShareExtern PUTCONVERTFUNC dbPutConvertRoutine[DBR_ENUM+1][DBF_DEVICE+1]; - -#ifdef __cplusplus -} -#endif - -#endif /*INCdbConverth*/ diff --git a/src/ioc/db/dbConvertFast.h b/src/ioc/db/dbConvertFast.h deleted file mode 100644 index cd9f4f963..000000000 --- a/src/ioc/db/dbConvertFast.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbConvertFast.h */ - -#ifndef INCdbConvertFasth -#define INCdbConvertFasth - -#include "dbFldTypes.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern long (*dbFastGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1])(); -epicsShareExtern long (*dbFastPutConvertRoutine[DBR_ENUM+1][DBF_DEVICE+1])(); - -#ifdef __cplusplus -} -#endif - -#endif /*INCdbConvertFasth*/ diff --git a/src/ioc/db/dbConvertJSON.c b/src/ioc/db/dbConvertJSON.c deleted file mode 100644 index e2a453549..000000000 --- a/src/ioc/db/dbConvertJSON.c +++ /dev/null @@ -1,257 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbConvertJSON.c */ - -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "yajl_alloc.h" -#include "yajl_parse.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbConvertFast.h" -#include "dbConvertJSON.h" - -typedef long (*FASTCONVERT)(); - -typedef struct parseContext { - int depth; - short dbrType; - short dbrSize; - char *pdest; - int elems; -} parseContext; - -static int dbcj_null(void *ctx) { - return 0; /* Illegal */ -} - -static int dbcj_boolean(void *ctx, int val) { - return 0; /* Illegal */ -} - -static int dbcj_integer(void *ctx, long num) { - parseContext *parser = (parseContext *) ctx; - epicsInt32 val32 = num; - FASTCONVERT conv = dbFastPutConvertRoutine[DBF_LONG][parser->dbrType]; - - if (parser->elems > 0) { - conv(&val32, parser->pdest, NULL); - parser->pdest += parser->dbrSize; - parser->elems--; - } - return 1; -} - -static int dblsj_integer(void *ctx, long num) { - return 0; /* Illegal */ -} - -static int dbcj_double(void *ctx, double num) { - parseContext *parser = (parseContext *) ctx; - FASTCONVERT conv = dbFastPutConvertRoutine[DBF_DOUBLE][parser->dbrType]; - - if (parser->elems > 0) { - conv(&num, parser->pdest, NULL); - parser->pdest += parser->dbrSize; - parser->elems--; - } - return 1; -} - -static int dblsj_double(void *ctx, double num) { - return 0; /* Illegal */ -} - -static int dbcj_string(void *ctx, const unsigned char *val, unsigned int len) { - parseContext *parser = (parseContext *) ctx; - char *pdest = parser->pdest; - - /* Not attempting to handle char-array fields here, they need more - * metadata about the field than we have available at the moment. - */ - if (parser->dbrType != DBF_STRING) { - errlogPrintf("dbConvertJSON: String provided, numeric value(s) expected\n"); - return 0; /* Illegal */ - } - - if (parser->elems > 0) { - if (len > parser->dbrSize - 1) - len = parser->dbrSize - 1; - strncpy(pdest, (const char *) val, len); - pdest[len] = 0; - parser->pdest += parser->dbrSize; - parser->elems--; - } - return 1; -} - -static int dblsj_string(void *ctx, const unsigned char *val, unsigned int len) { - parseContext *parser = (parseContext *) ctx; - char *pdest = parser->pdest; - - if (parser->dbrType != DBF_STRING) { - errlogPrintf("dbConvertJSON: dblsj_string dbrType error\n"); - return 0; /* Illegal */ - } - - if (parser->elems > 0) { - if (len > parser->dbrSize - 1) - len = parser->dbrSize - 1; - strncpy(pdest, (const char *) val, len); - pdest[len] = 0; - parser->pdest = pdest + len; - parser->elems = 0; - } - return 1; -} - -static int dbcj_start_map(void *ctx) { - errlogPrintf("dbConvertJSON: Map type not supported\n"); - return 0; /* Illegal */ -} - -static int dbcj_map_key(void *ctx, const unsigned char *key, unsigned int len) { - return 0; /* Illegal */ -} - -static int dbcj_end_map(void *ctx) { - return 0; /* Illegal */ -} - -static int dbcj_start_array(void *ctx) { - parseContext *parser = (parseContext *) ctx; - - if (++parser->depth > 1) - errlogPrintf("dbConvertJSON: Embedded arrays not supported\n"); - - return (parser->depth == 1); -} - -static int dbcj_end_array(void *ctx) { - parseContext *parser = (parseContext *) ctx; - - parser->depth--; - return (parser->depth == 0); -} - - -static yajl_callbacks dbcj_callbacks = { - dbcj_null, dbcj_boolean, dbcj_integer, dbcj_double, NULL, dbcj_string, - dbcj_start_map, dbcj_map_key, dbcj_end_map, - dbcj_start_array, dbcj_end_array -}; - -static const yajl_parser_config dbcj_config = - { 0, 0 }; /* allowComments = NO, checkUTF8 = NO */ - -long dbPutConvertJSON(const char *json, short dbrType, - void *pdest, long *pnRequest) -{ - parseContext context, *parser = &context; - yajl_alloc_funcs dbcj_alloc; - yajl_handle yh; - yajl_status ys; - size_t jlen = strlen(json); - long status; - - parser->depth = 0; - parser->dbrType = dbrType; - parser->dbrSize = dbValueSize(dbrType); - parser->pdest = pdest; - parser->elems = *pnRequest; - - yajl_set_default_alloc_funcs(&dbcj_alloc); - yh = yajl_alloc(&dbcj_callbacks, &dbcj_config, &dbcj_alloc, parser); - if (!yh) - return S_db_noMemory; - - ys = yajl_parse(yh, (const unsigned char *) json, (unsigned int) jlen); - if (ys == yajl_status_insufficient_data) - ys = yajl_parse_complete(yh); - - switch (ys) { - case yajl_status_ok: - *pnRequest -= parser->elems; - status = 0; - break; - - case yajl_status_error: { - unsigned char *err = yajl_get_error(yh, 1, - (const unsigned char *) json, (unsigned int) jlen); - fprintf(stderr, "dbConvertJSON: %s\n", err); - yajl_free_error(yh, err); - } - /* fall through */ - default: - status = S_db_badField; - } - - yajl_free(yh); - return status; -} - - -static yajl_callbacks dblsj_callbacks = { - dbcj_null, dbcj_boolean, dblsj_integer, dblsj_double, NULL, dblsj_string, - dbcj_start_map, dbcj_map_key, dbcj_end_map, - dbcj_start_array, dbcj_end_array -}; - -long dbLSConvertJSON(const char *json, char *pdest, epicsUInt32 size, - epicsUInt32 *plen) -{ - parseContext context, *parser = &context; - yajl_alloc_funcs dbcj_alloc; - yajl_handle yh; - yajl_status ys; - size_t jlen = strlen(json); - long status; - - if (!size) { - *plen = 0; - return 0; - } - - parser->depth = 0; - parser->dbrType = DBF_STRING; - parser->dbrSize = size; - parser->pdest = pdest; - parser->elems = 1; - - yajl_set_default_alloc_funcs(&dbcj_alloc); - yh = yajl_alloc(&dblsj_callbacks, &dbcj_config, &dbcj_alloc, parser); - if (!yh) - return S_db_noMemory; - - ys = yajl_parse(yh, (const unsigned char *) json, (unsigned int) jlen); - if (ys == yajl_status_insufficient_data) - ys = yajl_parse_complete(yh); - - switch (ys) { - case yajl_status_ok: - *plen = (char *) parser->pdest - pdest + 1; - status = 0; - break; - - case yajl_status_error: { - unsigned char *err = yajl_get_error(yh, 1, - (const unsigned char *) json, (unsigned int) jlen); - fprintf(stderr, "dbLoadLS_JSON: %s\n", err); - yajl_free_error(yh, err); - } - /* fall through */ - default: - status = S_db_badField; - } - - yajl_free(yh); - return status; -} diff --git a/src/ioc/db/dbConvertJSON.h b/src/ioc/db/dbConvertJSON.h deleted file mode 100644 index 7dd8e4aed..000000000 --- a/src/ioc/db/dbConvertJSON.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbConvertJSON.h */ - -#ifndef INC_dbConvertJSON_H -#define INC_dbConvertJSON_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* This name should probably be changed to inclue "array" */ -epicsShareFunc long dbPutConvertJSON(const char *json, short dbrType, - void *pdest, long *psize); -epicsShareFunc long dbLSConvertJSON(const char *json, char *pdest, - epicsUInt32 size, epicsUInt32 *plen); -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbConvertJSON_H */ - diff --git a/src/ioc/db/dbDbLink.c b/src/ioc/db/dbDbLink.c deleted file mode 100644 index 8f0e3ed03..000000000 --- a/src/ioc/db/dbDbLink.c +++ /dev/null @@ -1,358 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbDbLink.c - * - * Original Authors: Bob Dalesio, Marty Kraimer - * Current Author: Andrew Johnson - */ - -#include -#include -#include -#include -#include - -#include "alarm.h" -#include "cantProceed.h" -#include "cvtFast.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsTime.h" -#include "errlog.h" - -#include "caeventmask.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbBkpt.h" -#include "dbCommon.h" -#include "dbConvertFast.h" -#include "dbConvert.h" -#include "db_field_log.h" -#include "dbFldTypes.h" -#include "dbLink.h" -#include "dbLockPvt.h" -#include "dbNotify.h" -#include "dbScan.h" -#include "dbStaticLib.h" -#include "devSup.h" -#include "link.h" -#include "recGbl.h" -#include "recSup.h" -#include "special.h" - -/***************************** Database Links *****************************/ - -/* Forward definition */ -static lset dbDb_lset; - -long dbDbInitLink(struct link *plink, short dbfType) -{ - DBADDR dbaddr; - long status; - DBADDR *pdbAddr; - - status = dbNameToAddr(plink->value.pv_link.pvname, &dbaddr); - if (status) - return status; - - plink->lset = &dbDb_lset; - plink->type = DB_LINK; - pdbAddr = dbCalloc(1, sizeof(struct dbAddr)); - *pdbAddr = dbaddr; /* structure copy */ - plink->value.pv_link.pvt = pdbAddr; - ellAdd(&dbaddr.precord->bklnk, &plink->value.pv_link.backlinknode); - /* merging into the same lockset is deferred to the caller. - * cf. initPVLinks() - */ - dbLockSetMerge(NULL, plink->precord, dbaddr.precord); - assert(plink->precord->lset->plockSet == dbaddr.precord->lset->plockSet); - return 0; -} - -void dbDbAddLink(struct dbLocker *locker, struct link *plink, short dbfType, - DBADDR *ptarget) -{ - plink->lset = &dbDb_lset; - plink->type = DB_LINK; - plink->value.pv_link.pvt = ptarget; - ellAdd(&ptarget->precord->bklnk, &plink->value.pv_link.backlinknode); - - /* target record is already locked in dbPutFieldLink() */ - dbLockSetMerge(locker, plink->precord, ptarget->precord); -} - -static void dbDbRemoveLink(struct dbLocker *locker, struct link *plink) -{ - DBADDR *pdbAddr = (DBADDR *) plink->value.pv_link.pvt; - - plink->type = PV_LINK; - - /* locker is NULL when an isolated IOC is closing its links */ - if (locker) { - plink->value.pv_link.pvt = 0; - plink->value.pv_link.getCvt = 0; - plink->value.pv_link.pvlMask = 0; - plink->value.pv_link.lastGetdbrType = 0; - ellDelete(&pdbAddr->precord->bklnk, &plink->value.pv_link.backlinknode); - dbLockSetSplit(locker, plink->precord, pdbAddr->precord); - } - free(pdbAddr); -} - -static int dbDbIsConnected(const struct link *plink) -{ - return TRUE; -} - -static int dbDbGetDBFtype(const struct link *plink) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - - return paddr->field_type; -} - -static long dbDbGetElements(const struct link *plink, long *nelements) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - - *nelements = paddr->no_elements; - return 0; -} - -static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest) -{ - struct pv_link *ppv_link = &plink->value.pv_link; - DBADDR *paddr = ppv_link->pvt; - dbCommon *precord = plink->precord; - long status; - - /* scan passive records if link is process passive */ - if (ppv_link->pvlMask & pvlOptPP) { - unsigned char pact = precord->pact; - - precord->pact = TRUE; - status = dbScanPassive(precord, paddr->precord); - precord->pact = pact; - if (status) - return status; - } - - if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) { - status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr); - } else { - unsigned short dbfType = paddr->field_type; - - if (dbrType < 0 || dbrType > DBR_ENUM || dbfType > DBF_DEVICE) - return S_db_badDbrtype; - - if (paddr->no_elements == 1 && (!pnRequest || *pnRequest == 1) - && paddr->special != SPC_DBADDR - && paddr->special != SPC_ATTRIBUTE) { - ppv_link->getCvt = dbFastGetConvertRoutine[dbfType][dbrType]; - status = ppv_link->getCvt(paddr->pfield, pbuffer, paddr); - } else { - ppv_link->getCvt = NULL; - status = dbGet(paddr, dbrType, pbuffer, NULL, pnRequest, NULL); - } - ppv_link->lastGetdbrType = dbrType; - } - - if (!status) - recGblInheritSevr(plink->value.pv_link.pvlMask & pvlOptMsMode, - plink->precord, paddr->precord->stat, paddr->precord->sevr); - return status; -} - -static long dbDbGetControlLimits(const struct link *plink, double *low, - double *high) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRctrlDouble - double value; - } buffer; - long options = DBR_CTRL_DOUBLE; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - NULL); - - if (status) - return status; - - *low = buffer.lower_ctrl_limit; - *high = buffer.upper_ctrl_limit; - return 0; -} - -static long dbDbGetGraphicLimits(const struct link *plink, double *low, - double *high) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRgrDouble - double value; - } buffer; - long options = DBR_GR_DOUBLE; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - NULL); - - if (status) - return status; - - *low = buffer.lower_disp_limit; - *high = buffer.upper_disp_limit; - return 0; -} - -static long dbDbGetAlarmLimits(const struct link *plink, double *lolo, - double *low, double *high, double *hihi) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRalDouble - double value; - } buffer; - long options = DBR_AL_DOUBLE; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - 0); - - if (status) - return status; - - *lolo = buffer.lower_alarm_limit; - *low = buffer.lower_warning_limit; - *high = buffer.upper_warning_limit; - *hihi = buffer.upper_alarm_limit; - return 0; -} - -static long dbDbGetPrecision(const struct link *plink, short *precision) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRprecision - double value; - } buffer; - long options = DBR_PRECISION; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - 0); - - if (status) - return status; - - *precision = (short) buffer.precision.dp; - return 0; -} - -static long dbDbGetUnits(const struct link *plink, char *units, int unitsSize) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - struct buffer { - DBRunits - double value; - } buffer; - long options = DBR_UNITS; - long number_elements = 0; - long status = dbGet(paddr, DBR_DOUBLE, &buffer, &options, &number_elements, - 0); - - if (status) - return status; - - strncpy(units, buffer.units, unitsSize); - return 0; -} - -static long dbDbGetAlarm(const struct link *plink, epicsEnum16 *status, - epicsEnum16 *severity) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - - if (status) - *status = paddr->precord->stat; - if (severity) - *severity = paddr->precord->sevr; - return 0; -} - -static long dbDbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp) -{ - DBADDR *paddr = (DBADDR *) plink->value.pv_link.pvt; - - *pstamp = paddr->precord->time; - return 0; -} - -static long dbDbPutValue(struct link *plink, short dbrType, - const void *pbuffer, long nRequest) -{ - struct pv_link *ppv_link = &plink->value.pv_link; - struct dbCommon *psrce = plink->precord; - DBADDR *paddr = (DBADDR *) ppv_link->pvt; - dbCommon *pdest = paddr->precord; - long status = dbPut(paddr, dbrType, pbuffer, nRequest); - - recGblInheritSevr(ppv_link->pvlMask & pvlOptMsMode, pdest, psrce->nsta, - psrce->nsev); - if (status) - return status; - - if (paddr->pfield == (void *) &pdest->proc || - (ppv_link->pvlMask & pvlOptPP && pdest->scan == 0)) { - /* if dbPutField caused asyn record to process */ - /* ask for reprocessing*/ - if (pdest->putf) { - pdest->rpro = TRUE; - } else { /* process dest record with source's PACT true */ - unsigned char pact; - - if (psrce && psrce->ppn) - dbNotifyAdd(psrce, pdest); - pact = psrce->pact; - psrce->pact = TRUE; - status = dbProcess(pdest); - psrce->pact = pact; - } - } - return status; -} - -static void dbDbScanFwdLink(struct link *plink) -{ - dbCommon *precord = plink->precord; - dbAddr *paddr = (dbAddr *) plink->value.pv_link.pvt; - - dbScanPassive(precord, paddr->precord); -} - -static long doLocked(struct link *plink, dbLinkUserCallback rtn, void *priv) -{ - return rtn(plink, priv); -} - -static lset dbDb_lset = { - 0, 0, /* not Constant, not Volatile */ - NULL, dbDbRemoveLink, - NULL, NULL, NULL, - dbDbIsConnected, - dbDbGetDBFtype, dbDbGetElements, - dbDbGetValue, - dbDbGetControlLimits, dbDbGetGraphicLimits, dbDbGetAlarmLimits, - dbDbGetPrecision, dbDbGetUnits, - dbDbGetAlarm, dbDbGetTimeStamp, - dbDbPutValue, NULL, - dbDbScanFwdLink, doLocked -}; diff --git a/src/ioc/db/dbDbLink.h b/src/ioc/db/dbDbLink.h deleted file mode 100644 index c36772004..000000000 --- a/src/ioc/db/dbDbLink.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbDbLink.h - * - * Created on: April 3rd, 2016 - * Author: Andrew Johnson - */ - -#ifndef INC_dbDbLink_H -#define INC_dbDbLink_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct link; -struct dbLocker; - -epicsShareFunc long dbDbInitLink(struct link *plink, short dbfType); -epicsShareFunc void dbDbAddLink(struct dbLocker *locker, struct link *plink, - short dbfType, DBADDR *ptarget); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbDbLink_H */ diff --git a/src/ioc/db/dbEvent.c b/src/ioc/db/dbEvent.c deleted file mode 100644 index a5830881f..000000000 --- a/src/ioc/db/dbEvent.c +++ /dev/null @@ -1,1164 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbEvent.c */ - -/* - * Author: Jeffrey O. Hill - * - * Ralph Lange - */ - -#include -#include -#include -#include -#include -#include - -#include "cantProceed.h" -#include "dbDefs.h" -#include "epicsAssert.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsThread.h" -#include "errlog.h" -#include "freeList.h" -#include "taskwd.h" - -#include "caeventmask.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbEvent.h" -#include "db_field_log.h" -#include "dbFldTypes.h" -#include "dbLock.h" -#include "link.h" -#include "special.h" - -#define EVENTSPERQUE 32 -#define EVENTENTRIES 4 /* the number of que entries for each event */ -#define EVENTQUESIZE (EVENTENTRIES * EVENTSPERQUE) -#define EVENTQEMPTY ((struct evSubscrip *)NULL) - -/* - * really a ring buffer - */ -struct event_que { - /* lock writers to the ring buffer only */ - /* readers must never slow up writers */ - epicsMutexId writelock; - db_field_log *valque[EVENTQUESIZE]; - struct evSubscrip *evque[EVENTQUESIZE]; - struct event_que *nextque; /* in case que quota exceeded */ - struct event_user *evUser; /* event user parent struct */ - unsigned short putix; - unsigned short getix; - unsigned short quota; /* the number of assigned entries*/ - unsigned short nDuplicates; /* N events duplicated on this q */ - unsigned short nCanceled; /* the number of canceled entries */ -}; - -struct event_user { - struct event_que firstque; /* the first event que */ - - epicsMutexId lock; - epicsEventId ppendsem; /* Wait while empty */ - epicsEventId pflush_sem; /* wait for flush */ - epicsEventId pexitsem; /* wait for event task to join */ - - EXTRALABORFUNC *extralabor_sub;/* off load to event task */ - void *extralabor_arg;/* parameter to above */ - - epicsThreadId taskid; /* event handler task id */ - struct evSubscrip *pSuicideEvent; /* event that is deleteing itself */ - unsigned queovr; /* event que overflow count */ - unsigned char pendexit; /* exit pend task */ - unsigned char extra_labor; /* if set call extra labor func */ - unsigned char flowCtrlMode; /* replace existing monitor */ - unsigned char extraLaborBusy; - void (*init_func)(); - epicsThreadId init_func_arg; -}; - -/* - * Reliable intertask communication requires copying the current value of the - * channel for later queing so 3 stepper motor steps of 10 each do not turn - * into only 10 or 20 total steps part of the time. - */ - -#define RNGINC(OLD)\ -( (unsigned short) ( (OLD) >= (EVENTQUESIZE-1) ? 0 : (OLD)+1 ) ) - -#define LOCKEVQUE(EV_QUE) epicsMutexMustLock((EV_QUE)->writelock) -#define UNLOCKEVQUE(EV_QUE) epicsMutexUnlock((EV_QUE)->writelock) -#define LOCKREC(RECPTR) epicsMutexMustLock((RECPTR)->mlok) -#define UNLOCKREC(RECPTR) epicsMutexUnlock((RECPTR)->mlok) - -static void *dbevEventUserFreeList; -static void *dbevEventQueueFreeList; -static void *dbevEventSubscriptionFreeList; -static void *dbevFieldLogFreeList; - -static char *EVENT_PEND_NAME = "eventTask"; - -static struct evSubscrip canceledEvent; - -static unsigned short ringSpace ( const struct event_que *pevq ) -{ - if ( pevq->evque[pevq->putix] == EVENTQEMPTY ) { - if ( pevq->getix > pevq->putix ) { - return ( unsigned short ) ( pevq->getix - pevq->putix ); - } - else { - return ( unsigned short ) ( ( EVENTQUESIZE + pevq->getix ) - pevq->putix ); - } - } - return 0; -} - -/* - * db_event_list () - */ -int db_event_list ( const char *pname, unsigned level ) -{ - return dbel ( pname, level ); -} - -/* - * dbel () - */ -int dbel ( const char *pname, unsigned level ) -{ - DBADDR addr; - long status; - struct evSubscrip *pevent; - dbFldDes *pdbFldDes; - - if ( ! pname ) return DB_EVENT_OK; - status = dbNameToAddr ( pname, &addr ); - if ( status != 0 ) { - errMessage ( status, " dbNameToAddr failed" ); - return DB_EVENT_ERROR; - } - - LOCKREC (addr.precord); - - pevent = (struct evSubscrip *) ellFirst ( &addr.precord->mlis ); - - if ( ! pevent ) { - printf ( "\"%s\": No PV event subscriptions ( monitors ).\n", pname ); - UNLOCKREC (addr.precord); - return DB_EVENT_OK; - } - - printf ( "%u PV Event Subscriptions ( monitors ).\n", - ellCount ( &addr.precord->mlis ) ); - - while ( pevent ) { - pdbFldDes = dbChannelFldDes(pevent->chan); - - if ( level > 0 ) { - printf ( "%4.4s", pdbFldDes->name ); - - printf ( " { " ); - if ( pevent->select & DBE_VALUE ) printf( "VALUE " ); - if ( pevent->select & DBE_LOG ) printf( "LOG " ); - if ( pevent->select & DBE_ALARM ) printf( "ALARM " ); - if ( pevent->select & DBE_PROPERTY ) printf( "PROPERTY " ); - printf ( "}" ); - - if ( pevent->npend ) { - printf ( " undelivered=%ld", pevent->npend ); - } - - if ( level > 1 ) { - unsigned nEntriesFree; - const void * taskId; - LOCKEVQUE(pevent->ev_que); - nEntriesFree = ringSpace ( pevent->ev_que ); - taskId = ( void * ) pevent->ev_que->evUser->taskid; - UNLOCKEVQUE(pevent->ev_que); - if ( nEntriesFree == 0u ) { - printf ( ", thread=%p, queue full", - (void *) taskId ); - } - else if ( nEntriesFree == EVENTQUESIZE ) { - printf ( ", thread=%p, queue empty", - (void *) taskId ); - } - else { - printf ( ", thread=%p, unused entries=%u", - (void *) taskId, nEntriesFree ); - } - } - - if ( level > 2 ) { - unsigned nDuplicates; - unsigned nCanceled; - if ( pevent->nreplace ) { - printf (", discarded by replacement=%ld", pevent->nreplace); - } - if ( ! pevent->useValque ) { - printf (", queueing disabled" ); - } - LOCKEVQUE(pevent->ev_que); - nDuplicates = pevent->ev_que->nDuplicates; - nCanceled = pevent->ev_que->nCanceled; - UNLOCKEVQUE(pevent->ev_que); - if ( nDuplicates ) { - printf (", duplicate count =%u\n", nDuplicates ); - } - if ( nCanceled ) { - printf (", canceled count =%u\n", nCanceled ); - } - } - - if ( level > 3 ) { - printf ( ", ev %p, ev que %p, ev user %p", - ( void * ) pevent, - ( void * ) pevent->ev_que, - ( void * ) pevent->ev_que->evUser ); - } - - printf( "\n" ); - } - - pevent = (struct evSubscrip *) ellNext ( &pevent->node ); - } - - UNLOCKREC (addr.precord); - - return DB_EVENT_OK; -} - -/* - * DB_INIT_EVENTS() - * - * - * Initialize the event facility for this task. Must be called at least once - * by each task which uses the db event facility - * - * returns: ptr to event user block or NULL if memory can't be allocated - */ -dbEventCtx db_init_events (void) -{ - struct event_user * evUser; - - if (!dbevEventUserFreeList) { - freeListInitPvt(&dbevEventUserFreeList, - sizeof(struct event_user),8); - } - if (!dbevEventQueueFreeList) { - freeListInitPvt(&dbevEventQueueFreeList, - sizeof(struct event_que),8); - } - if (!dbevEventSubscriptionFreeList) { - freeListInitPvt(&dbevEventSubscriptionFreeList, - sizeof(struct evSubscrip),256); - } - if (!dbevFieldLogFreeList) { - freeListInitPvt(&dbevFieldLogFreeList, - sizeof(struct db_field_log),2048); - } - - evUser = (struct event_user *) - freeListCalloc(dbevEventUserFreeList); - if (!evUser) { - return NULL; - } - - /* Flag will be cleared when event task starts */ - evUser->pendexit = TRUE; - - evUser->firstque.evUser = evUser; - evUser->firstque.writelock = epicsMutexCreate(); - if (!evUser->firstque.writelock) - goto fail; - - evUser->ppendsem = epicsEventCreate(epicsEventEmpty); - if (!evUser->ppendsem) - goto fail; - evUser->pflush_sem = epicsEventCreate(epicsEventEmpty); - if (!evUser->pflush_sem) - goto fail; - evUser->lock = epicsMutexCreate(); - if (!evUser->lock) - goto fail; - evUser->pexitsem = epicsEventCreate(epicsEventEmpty); - if (!evUser->pexitsem) - goto fail; - - evUser->flowCtrlMode = FALSE; - evUser->extraLaborBusy = FALSE; - evUser->pSuicideEvent = NULL; - return (dbEventCtx) evUser; -fail: - if(evUser->lock) - epicsMutexDestroy (evUser->lock); - if(evUser->firstque.writelock) - epicsMutexDestroy (evUser->firstque.writelock); - if(evUser->ppendsem) - epicsEventDestroy (evUser->ppendsem); - if(evUser->pflush_sem) - epicsEventDestroy (evUser->pflush_sem); - if(evUser->pexitsem) - epicsEventDestroy (evUser->pexitsem); - freeListFree(dbevEventUserFreeList,evUser); - return NULL; -} - - -epicsShareFunc void db_cleanup_events(void) -{ - freeListCleanup(dbevEventUserFreeList); - dbevEventUserFreeList = NULL; - - freeListCleanup(dbevEventQueueFreeList); - dbevEventQueueFreeList = NULL; - - freeListCleanup(dbevEventSubscriptionFreeList); - dbevEventSubscriptionFreeList = NULL; - - freeListCleanup(dbevFieldLogFreeList); - dbevFieldLogFreeList = NULL; -} - -/* - * DB_CLOSE_EVENTS() - * - * evUser block and additional event queues - * deallocated when the event thread terminates - * itself - * - */ -void db_close_events (dbEventCtx ctx) -{ - struct event_user * const evUser = (struct event_user *) ctx; - - /* - * Exit not forced on event blocks for now - this is left to channel - * access and any other tasks using this facility which can find them - * more efficiently. - * - * NOTE: not deleting events before calling this routine could be - * hazardous to the system's health. - */ - epicsMutexMustLock ( evUser->lock ); - if(!evUser->pendexit) { /* event task running */ - evUser->pendexit = TRUE; - epicsMutexUnlock ( evUser->lock ); - - /* notify the waiting task */ - epicsEventSignal(evUser->ppendsem); - /* wait for task to exit */ - epicsEventMustWait(evUser->pexitsem); - - epicsMutexMustLock ( evUser->lock ); - } - - epicsMutexUnlock ( evUser->lock ); - - epicsEventDestroy(evUser->pexitsem); - epicsEventDestroy(evUser->ppendsem); - epicsEventDestroy(evUser->pflush_sem); - epicsMutexDestroy(evUser->lock); - - freeListFree(dbevEventUserFreeList, evUser); -} - -/* - * create_ev_que() - */ -static struct event_que * create_ev_que ( struct event_user * const evUser ) -{ - struct event_que * const ev_que = (struct event_que *) - freeListCalloc ( dbevEventQueueFreeList ); - if ( ! ev_que ) { - return NULL; - } - ev_que->writelock = epicsMutexCreate(); - if ( ! ev_que->writelock ) { - freeListFree ( dbevEventQueueFreeList, ev_que ); - return NULL; - } - ev_que->evUser = evUser; - return ev_que; -} - -/* - * DB_ADD_EVENT() - */ -dbEventSubscription db_add_event ( - dbEventCtx ctx, struct dbChannel *chan, - EVENTFUNC *user_sub, void *user_arg, unsigned select) -{ - struct event_user * const evUser = (struct event_user *) ctx; - struct event_que * ev_que; - struct evSubscrip * pevent; - - /* - * Don't add events which will not be triggered - */ - if ( select==0 || select > UCHAR_MAX ) { - return NULL; - } - - pevent = freeListCalloc (dbevEventSubscriptionFreeList); - if ( ! pevent ) { - return NULL; - } - - /* find an event que block with enough quota */ - /* otherwise add a new one to the list */ - epicsMutexMustLock ( evUser->lock ); - ev_que = & evUser->firstque; - while ( TRUE ) { - int success = 0; - LOCKEVQUE ( ev_que ); - success = ( ev_que->quota + ev_que->nCanceled < - EVENTQUESIZE - EVENTENTRIES ); - if ( success ) { - ev_que->quota += EVENTENTRIES; - } - UNLOCKEVQUE ( ev_que ); - if ( success ) { - break; - } - if ( ! ev_que->nextque ) { - ev_que->nextque = create_ev_que ( evUser ); - if ( ! ev_que->nextque ) { - ev_que = NULL; - break; - } - } - ev_que = ev_que->nextque; - } - epicsMutexUnlock ( evUser->lock ); - - if ( ! ev_que ) { - freeListFree ( dbevEventSubscriptionFreeList, pevent ); - return NULL; - } - - pevent->npend = 0ul; - pevent->nreplace = 0ul; - pevent->user_sub = user_sub; - pevent->user_arg = user_arg; - pevent->chan = chan; - pevent->select = (unsigned char) select; - pevent->pLastLog = NULL; /* not yet in the queue */ - pevent->callBackInProgress = FALSE; - pevent->enabled = FALSE; - pevent->ev_que = ev_que; - - /* - * Simple types values queued up for reliable interprocess - * communication (for other types they get whatever happens to be - * there upon wakeup) - */ - if (dbChannelElements(chan) == 1 && - dbChannelSpecial(chan) != SPC_DBADDR && - dbChannelFieldSize(chan) <= sizeof(union native_value)) { - pevent->useValque = TRUE; - } - else { - pevent->useValque = FALSE; - } - - return pevent; -} - -/* - * db_event_enable() - */ -void db_event_enable (dbEventSubscription event) -{ - struct evSubscrip * const pevent = (struct evSubscrip *) event; - struct dbCommon * const precord = dbChannelRecord(pevent->chan); - - LOCKREC (precord); - if ( ! pevent->enabled ) { - ellAdd (&precord->mlis, &pevent->node); - pevent->enabled = TRUE; - } - UNLOCKREC (precord); -} - -/* - * db_event_disable() - */ -void db_event_disable (dbEventSubscription event) -{ - struct evSubscrip * const pevent = (struct evSubscrip *) event; - struct dbCommon * const precord = dbChannelRecord(pevent->chan); - - LOCKREC (precord); - if ( pevent->enabled ) { - ellDelete(&precord->mlis, &pevent->node); - pevent->enabled = FALSE; - } - UNLOCKREC (precord); -} - -/* - * event_remove() - * event queue lock _must_ be applied - * this nulls the entry in the queue, but doesn't delete the db_field_log chunk - */ -static void event_remove ( struct event_que *ev_que, - unsigned short index, struct evSubscrip *placeHolder ) -{ - struct evSubscrip * const pevent = ev_que->evque[index]; - - ev_que->evque[index] = placeHolder; - ev_que->valque[index] = NULL; - if ( pevent->npend == 1u ) { - pevent->pLastLog = NULL; - } - else { - assert ( pevent->npend > 1u ); - assert ( ev_que->nDuplicates >= 1u ); - ev_que->nDuplicates--; - } - pevent->npend--; -} - -/* - * DB_CANCEL_EVENT() - * - * This routine does not prevent two threads from deleting - * the same block at the same time. - * - */ -void db_cancel_event (dbEventSubscription event) -{ - struct evSubscrip * const pevent = (struct evSubscrip *) event; - unsigned short getix; - - db_event_disable ( event ); - - /* - * flag the event as canceled by NULLing out the callback handler - * - * make certain that the event isnt being accessed while - * its call back changes - */ - LOCKEVQUE (pevent->ev_que); - - pevent->user_sub = NULL; - - /* - * purge this event from the queue - * - * Its better to take this approach rather than waiting - * for the event thread to finish removing this event - * from the queue because the event thread will not - * process if we are in flow control mode. Since blocking - * here will block CA's TCP input queue then a dead lock - * would be possible. - */ - for ( getix = pevent->ev_que->getix; - pevent->ev_que->evque[getix] != EVENTQEMPTY; ) { - if ( pevent->ev_que->evque[getix] == pevent ) { - assert ( pevent->ev_que->nCanceled < USHRT_MAX ); - pevent->ev_que->nCanceled++; - event_remove ( pevent->ev_que, getix, &canceledEvent ); - } - getix = RNGINC ( getix ); - if ( getix == pevent->ev_que->getix ) { - break; - } - } - assert ( pevent->npend == 0u ); - - if ( pevent->ev_que->evUser->taskid == epicsThreadGetIdSelf() ) { - pevent->ev_que->evUser->pSuicideEvent = pevent; - } - else { - while ( pevent->callBackInProgress ) { - UNLOCKEVQUE (pevent->ev_que); - epicsEventMustWait ( pevent->ev_que->evUser->pflush_sem ); - LOCKEVQUE (pevent->ev_que); - } - } - - pevent->ev_que->quota -= EVENTENTRIES; - - UNLOCKEVQUE (pevent->ev_que); - - freeListFree ( dbevEventSubscriptionFreeList, pevent ); - - return; -} - -/* - * DB_FLUSH_EXTRA_LABOR_EVENT() - * - * waits for extra labor in progress to finish - */ -void db_flush_extra_labor_event (dbEventCtx ctx) -{ - struct event_user * const evUser = (struct event_user *) ctx; - - epicsMutexMustLock ( evUser->lock ); - while ( evUser->extraLaborBusy ) { - epicsMutexUnlock ( evUser->lock ); - epicsThreadSleep(0.1); - epicsMutexMustLock ( evUser->lock ); - } - epicsMutexUnlock ( evUser->lock ); -} - -/* - * DB_ADD_EXTRA_LABOR_EVENT() - * - * Specify a routine to be called - * when labor is offloaded to the - * event task - */ -int db_add_extra_labor_event ( - dbEventCtx ctx, EXTRALABORFUNC *func, void *arg) -{ - struct event_user * const evUser = (struct event_user *) ctx; - - epicsMutexMustLock ( evUser->lock ); - evUser->extralabor_sub = func; - evUser->extralabor_arg = arg; - epicsMutexUnlock ( evUser->lock ); - - return DB_EVENT_OK; -} - -/* - * DB_POST_EXTRA_LABOR() - */ -int db_post_extra_labor (dbEventCtx ctx) -{ - struct event_user * const evUser = (struct event_user *) ctx; - int doit; - - epicsMutexMustLock ( evUser->lock ); - if ( ! evUser->extra_labor ) { - evUser->extra_labor = TRUE; - doit = TRUE; - } - else { - doit = FALSE; - } - epicsMutexUnlock ( evUser->lock ); - - if ( doit ) { - epicsEventSignal(evUser->ppendsem); - } - - return DB_EVENT_OK; -} - -/* - * DB_CREATE_EVENT_LOG() - * - * NOTE: This assumes that the db scan lock is already applied - * (as it copies data from the record) - */ -db_field_log* db_create_event_log (struct evSubscrip *pevent) -{ - db_field_log *pLog = (db_field_log *) freeListCalloc(dbevFieldLogFreeList); - - if (pLog) { - struct dbChannel *chan = pevent->chan; - struct dbCommon *prec = dbChannelRecord(chan); - pLog->ctx = dbfl_context_event; - if (pevent->useValque) { - pLog->type = dbfl_type_val; - pLog->stat = prec->stat; - pLog->sevr = prec->sevr; - pLog->time = prec->time; - pLog->field_type = dbChannelFieldType(chan); - pLog->no_elements = dbChannelElements(chan); - /* - * use memcpy to avoid a bus error on - * union copy of char in the db at an odd - * address - */ - memcpy(&pLog->u.v.field, - dbChannelField(chan), - dbChannelFieldSize(chan)); - } else { - pLog->type = dbfl_type_rec; - } - } - return pLog; -} - -/* - * DB_CREATE_READ_LOG() - * - */ -db_field_log* db_create_read_log (struct dbChannel *chan) -{ - db_field_log *pLog = (db_field_log *) freeListCalloc(dbevFieldLogFreeList); - - if (pLog) { - pLog->ctx = dbfl_context_read; - pLog->type = dbfl_type_rec; - } - return pLog; -} - -/* - * DB_QUEUE_EVENT_LOG() - * - */ -static void db_queue_event_log (evSubscrip *pevent, db_field_log *pLog) -{ - struct event_que *ev_que; - int firstEventFlag; - unsigned rngSpace; - - ev_que = pevent->ev_que; - /* - * evUser ring buffer must be locked for the multiple - * threads writing/reading it - */ - - LOCKEVQUE (ev_que); - - /* - * if we have an event on the queue and both the last - * event on the queue and the current event are emtpy - * (i.e. of type dbfl_type_rec), simply ignore duplicate - * events (saving empty events serves no purpose) - */ - if (pevent->npend > 0u && - (*pevent->pLastLog)->type == dbfl_type_rec && - pLog->type == dbfl_type_rec) { - db_delete_field_log(pLog); - UNLOCKEVQUE (ev_que); - return; - } - - /* - * add to task local event que - */ - - /* - * if an event is on the queue and one of - * {flowCtrlMode, not room for one more of each monitor attached} - * then replace the last event on the queue (for this monitor) - */ - rngSpace = ringSpace ( ev_que ); - if ( pevent->npend>0u && - (ev_que->evUser->flowCtrlMode || rngSpace<=EVENTSPERQUE) ) { - /* - * replace last event if no space is left - */ - if (*pevent->pLastLog) { - db_delete_field_log(*pevent->pLastLog); - *pevent->pLastLog = pLog; - } - pevent->nreplace++; - /* - * the event task has already been notified about - * this so we dont need to post the semaphore - */ - firstEventFlag = 0; - } - /* - * Otherwise, the current entry must be available. - * Fill it in and advance the ring buffer. - */ - else { - assert ( ev_que->evque[ev_que->putix] == EVENTQEMPTY ); - ev_que->evque[ev_que->putix] = pevent; - ev_que->valque[ev_que->putix] = pLog; - pevent->pLastLog = &ev_que->valque[ev_que->putix]; - if (pevent->npend>0u) { - ev_que->nDuplicates++; - } - pevent->npend++; - /* - * if the ring buffer was empty before - * adding this event - */ - if (rngSpace==EVENTQUESIZE) { - firstEventFlag = 1; - } - else { - firstEventFlag = 0; - } - ev_que->putix = RNGINC ( ev_que->putix ); - } - - UNLOCKEVQUE (ev_que); - - /* - * its more efficent to notify the event handler - * only after the event is ready and the lock - * is off in case it runs at a higher priority - * than the caller here. - */ - if (firstEventFlag) { - /* - * notify the event handler - */ - epicsEventSignal(ev_que->evUser->ppendsem); - } -} - -/* - * DB_POST_EVENTS() - * - * NOTE: This assumes that the db scan lock is already applied - * - */ -int db_post_events( -void *pRecord, -void *pField, -unsigned int caEventMask -) -{ - struct dbCommon * const prec = (struct dbCommon *) pRecord; - struct evSubscrip *pevent; - - if (prec->mlis.count == 0) return DB_EVENT_OK; /* no monitors set */ - - LOCKREC (prec); - - for (pevent = (struct evSubscrip *) prec->mlis.node.next; - pevent; pevent = (struct evSubscrip *) pevent->node.next){ - - /* - * Only send event msg if they are waiting on the field which - * changed or pval==NULL, and are waiting on matching event - */ - if ( (dbChannelField(pevent->chan) == (void *)pField || pField==NULL) && - (caEventMask & pevent->select)) { - db_field_log *pLog = db_create_event_log(pevent); - pLog = dbChannelRunPreChain(pevent->chan, pLog); - if (pLog) db_queue_event_log(pevent, pLog); - } - } - - UNLOCKREC (prec); - return DB_EVENT_OK; - -} - -/* - * DB_POST_SINGLE_EVENT() - */ -void db_post_single_event (dbEventSubscription event) -{ - struct evSubscrip * const pevent = (struct evSubscrip *) event; - struct dbCommon * const prec = dbChannelRecord(pevent->chan); - db_field_log *pLog; - - dbScanLock (prec); - - pLog = db_create_event_log(pevent); - pLog = dbChannelRunPreChain(pevent->chan, pLog); - if(pLog) db_queue_event_log(pevent, pLog); - - dbScanUnlock (prec); -} - -/* - * EVENT_READ() - */ -static int event_read ( struct event_que *ev_que ) -{ - db_field_log *pfl; - void ( *user_sub ) ( void *user_arg, struct dbChannel *chan, - int eventsRemaining, db_field_log *pfl ); - - /* - * evUser ring buffer must be locked for the multiple - * threads writing/reading it - */ - LOCKEVQUE (ev_que); - - /* - * if in flow control mode drain duplicates and then - * suspend processing events until flow control - * mode is over - */ - if ( ev_que->evUser->flowCtrlMode && ev_que->nDuplicates == 0u ) { - UNLOCKEVQUE (ev_que); - return DB_EVENT_OK; - } - - while ( ev_que->evque[ev_que->getix] != EVENTQEMPTY ) { - struct evSubscrip *pevent = ev_que->evque[ev_que->getix]; - - pfl = ev_que->valque[ev_que->getix]; - if ( pevent == &canceledEvent ) { - ev_que->evque[ev_que->getix] = EVENTQEMPTY; - if (ev_que->valque[ev_que->getix]) { - db_delete_field_log(ev_que->valque[ev_que->getix]); - ev_que->valque[ev_que->getix] = NULL; - } - ev_que->getix = RNGINC ( ev_que->getix ); - assert ( ev_que->nCanceled > 0 ); - ev_que->nCanceled--; - continue; - } - - /* - * Simple type values queued up for reliable interprocess - * communication. (for other types they get whatever happens - * to be there upon wakeup) - */ - - event_remove ( ev_que, ev_que->getix, EVENTQEMPTY ); - ev_que->getix = RNGINC ( ev_que->getix ); - - /* - * create a local copy of the call back parameters while - * we still have the lock - */ - user_sub = pevent->user_sub; - - /* - * Next event pointer can be used by event tasks to determine - * if more events are waiting in the queue - * - * Must remove the lock here so that we dont deadlock if - * this calls dbGetField() and blocks on the record lock, - * dbPutField() is in progress in another task, it has the - * record lock, and it is calling db_post_events() waiting - * for the event queue lock (which this thread now has). - */ - if ( user_sub ) { - /* - * This provides a way to test to see if an event is in use - * despite the fact that the event queue does not point to - * it. - */ - pevent->callBackInProgress = TRUE; - UNLOCKEVQUE (ev_que); - /* Run post-event-queue filter chain */ - if (ellCount(&pevent->chan->post_chain)) { - pfl = dbChannelRunPostChain(pevent->chan, pfl); - } - if (pfl) { - /* Issue user callback */ - ( *user_sub ) ( pevent->user_arg, pevent->chan, - ev_que->evque[ev_que->getix] != EVENTQEMPTY, pfl ); - } - LOCKEVQUE (ev_que); - - /* - * check to see if this event has been canceled each - * time that the callBackInProgress flag is set to false - * while we have the event queue lock, and post the flush - * complete sem if there are no longer any events on the - * queue - */ - if ( ev_que->evUser->pSuicideEvent == pevent ) { - ev_que->evUser->pSuicideEvent = NULL; - } - else { - if ( pevent->user_sub==NULL && pevent->npend==0u ) { - pevent->callBackInProgress = FALSE; - epicsEventSignal ( ev_que->evUser->pflush_sem ); - } - else { - pevent->callBackInProgress = FALSE; - } - } - } - db_delete_field_log(pfl); - } - - UNLOCKEVQUE (ev_que); - - return DB_EVENT_OK; -} - -/* - * EVENT_TASK() - */ -static void event_task (void *pParm) -{ - struct event_user * const evUser = (struct event_user *) pParm; - struct event_que * ev_que; - unsigned char pendexit; - - /* init hook */ - if (evUser->init_func) { - (*evUser->init_func)(evUser->init_func_arg); - } - - taskwdInsert ( epicsThreadGetIdSelf(), NULL, NULL ); - - do { - void (*pExtraLaborSub) (void *); - void *pExtraLaborArg; - epicsEventMustWait(evUser->ppendsem); - - /* - * check to see if the caller has offloaded - * labor to this task - */ - epicsMutexMustLock ( evUser->lock ); - evUser->extraLaborBusy = TRUE; - if ( evUser->extra_labor && evUser->extralabor_sub ) { - evUser->extra_labor = FALSE; - pExtraLaborSub = evUser->extralabor_sub; - pExtraLaborArg = evUser->extralabor_arg; - } - else { - pExtraLaborSub = NULL; - pExtraLaborArg = NULL; - } - if ( pExtraLaborSub ) { - epicsMutexUnlock ( evUser->lock ); - (*pExtraLaborSub)(pExtraLaborArg); - epicsMutexMustLock ( evUser->lock ); - } - evUser->extraLaborBusy = FALSE; - - for ( ev_que = &evUser->firstque; ev_que; - ev_que = ev_que->nextque ) { - epicsMutexUnlock ( evUser->lock ); - event_read (ev_que); - epicsMutexMustLock ( evUser->lock ); - } - pendexit = evUser->pendexit; - epicsMutexUnlock ( evUser->lock ); - - } while( ! pendexit ); - - epicsMutexDestroy(evUser->firstque.writelock); - - { - struct event_que *nextque; - - ev_que = evUser->firstque.nextque; - while (ev_que) { - nextque = ev_que->nextque; - epicsMutexDestroy(ev_que->writelock); - freeListFree(dbevEventQueueFreeList, ev_que); - ev_que = nextque; - } - } - - taskwdRemove(epicsThreadGetIdSelf()); - - epicsEventSignal(evUser->pexitsem); - - return; -} - -/* - * DB_START_EVENTS() - */ -int db_start_events ( - dbEventCtx ctx,const char *taskname, void (*init_func)(void *), - void *init_func_arg, unsigned osiPriority ) -{ - struct event_user * const evUser = (struct event_user *) ctx; - - epicsMutexMustLock ( evUser->lock ); - - /* - * only one ca_pend_event thread may be - * started for each evUser - */ - if (evUser->taskid) { - epicsMutexUnlock ( evUser->lock ); - return DB_EVENT_OK; - } - - evUser->init_func = init_func; - evUser->init_func_arg = init_func_arg; - if (!taskname) { - taskname = EVENT_PEND_NAME; - } - evUser->taskid = epicsThreadCreate ( - taskname, osiPriority, - epicsThreadGetStackSize(epicsThreadStackMedium), - event_task, (void *)evUser); - if (!evUser->taskid) { - epicsMutexUnlock ( evUser->lock ); - return DB_EVENT_ERROR; - } - evUser->pendexit = FALSE; - epicsMutexUnlock ( evUser->lock ); - return DB_EVENT_OK; -} - -/* - * db_event_change_priority() - */ -void db_event_change_priority ( dbEventCtx ctx, - unsigned epicsPriority ) -{ - struct event_user * const evUser = ( struct event_user * ) ctx; - epicsThreadSetPriority ( evUser->taskid, epicsPriority ); -} - -/* - * db_event_flow_ctrl_mode_on() - */ -void db_event_flow_ctrl_mode_on (dbEventCtx ctx) -{ - struct event_user * const evUser = (struct event_user *) ctx; - - epicsMutexMustLock ( evUser->lock ); - evUser->flowCtrlMode = TRUE; - epicsMutexUnlock ( evUser->lock ); - /* - * notify the event handler task - */ - epicsEventSignal(evUser->ppendsem); -#ifdef DEBUG - printf("fc on %lu\n", tickGet()); -#endif -} - -/* - * db_event_flow_ctrl_mode_off() - */ -void db_event_flow_ctrl_mode_off (dbEventCtx ctx) -{ - struct event_user * const evUser = (struct event_user *) ctx; - - epicsMutexMustLock ( evUser->lock ); - evUser->flowCtrlMode = FALSE; - epicsMutexUnlock ( evUser->lock ); - /* - * notify the event handler task - */ - epicsEventSignal (evUser->ppendsem); -#ifdef DEBUG - printf("fc off %lu\n", tickGet()); -#endif -} - -/* - * db_delete_field_log() - */ -void db_delete_field_log (db_field_log *pfl) -{ - if (pfl) { - /* Free field if reference type field log and dtor is set */ - if (pfl->type == dbfl_type_ref && pfl->u.r.dtor) pfl->u.r.dtor(pfl); - /* Free the field log chunk */ - freeListFree(dbevFieldLogFreeList, pfl); - } -} diff --git a/src/ioc/db/dbEvent.h b/src/ioc/db/dbEvent.h deleted file mode 100644 index 8ee109373..000000000 --- a/src/ioc/db/dbEvent.h +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * - * Ralph Lange - */ - -#ifndef INCLdbEventh -#define INCLdbEventh - -#ifdef epicsExportSharedSymbols -# undef epicsExportSharedSymbols -# define INCLdbEventhExporting -#endif - -#include "epicsThread.h" - -#ifdef INCLdbEventhExporting -# define epicsExportSharedSymbols -#endif - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct dbChannel; -struct db_field_log; -struct evSubscrip; - -epicsShareFunc int db_event_list ( - const char *name, unsigned level); -epicsShareFunc int dbel ( - const char *name, unsigned level); -epicsShareFunc int db_post_events ( - void *pRecord, void *pField, unsigned caEventMask ); - -typedef void * dbEventCtx; - -typedef void EXTRALABORFUNC (void *extralabor_arg); -epicsShareFunc dbEventCtx db_init_events (void); -epicsShareFunc int db_start_events ( - dbEventCtx ctx, const char *taskname, void (*init_func)(void *), - void *init_func_arg, unsigned osiPriority ); -epicsShareFunc void db_close_events (dbEventCtx ctx); -epicsShareFunc void db_event_flow_ctrl_mode_on (dbEventCtx ctx); -epicsShareFunc void db_event_flow_ctrl_mode_off (dbEventCtx ctx); -epicsShareFunc int db_add_extra_labor_event ( - dbEventCtx ctx, EXTRALABORFUNC *func, void *arg); -epicsShareFunc void db_flush_extra_labor_event (dbEventCtx); -epicsShareFunc int db_post_extra_labor (dbEventCtx ctx); -epicsShareFunc void db_event_change_priority ( dbEventCtx ctx, unsigned epicsPriority ); - -#ifdef EPICS_PRIVATE_API -epicsShareFunc void db_cleanup_events(void); -#endif - -typedef void EVENTFUNC (void *user_arg, struct dbChannel *chan, - int eventsRemaining, struct db_field_log *pfl); - -typedef void * dbEventSubscription; -epicsShareFunc dbEventSubscription db_add_event ( - dbEventCtx ctx, struct dbChannel *chan, - EVENTFUNC *user_sub, void *user_arg, unsigned select); -epicsShareFunc void db_cancel_event (dbEventSubscription es); -epicsShareFunc void db_post_single_event (dbEventSubscription es); -epicsShareFunc void db_event_enable (dbEventSubscription es); -epicsShareFunc void db_event_disable (dbEventSubscription es); - -epicsShareFunc struct db_field_log* db_create_event_log (struct evSubscrip *pevent); -epicsShareFunc struct db_field_log* db_create_read_log (struct dbChannel *chan); -epicsShareFunc void db_delete_field_log (struct db_field_log *pfl); - -#define DB_EVENT_OK 0 -#define DB_EVENT_ERROR (-1) - -#ifdef __cplusplus -} -#endif - -#endif /*INCLdbEventh*/ - diff --git a/src/ioc/db/dbExtractArray.c b/src/ioc/db/dbExtractArray.c deleted file mode 100644 index e16ab4cd2..000000000 --- a/src/ioc/db/dbExtractArray.c +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - * - * based on dbConvert.c - * written by: Bob Dalesio, Marty Kraimer - */ - -#include - -#include "epicsTypes.h" - -#define epicsExportSharedSymbols -#include "dbAddr.h" -#include "dbExtractArray.h" - -void dbExtractArrayFromRec(const dbAddr *paddr, void *pto, - long nRequest, long no_elements, long offset, long increment) -{ - char *pdst = (char *) pto; - char *psrc = (char *) paddr->pfield; - long nUpperPart; - int i; - short srcSize = paddr->field_size; - short dstSize = srcSize; - char isString = (paddr->field_type == DBF_STRING); - - if (nRequest > no_elements) nRequest = no_elements; - if (isString && srcSize > MAX_STRING_SIZE) dstSize = MAX_STRING_SIZE; - - if (increment == 1 && dstSize == srcSize) { - nUpperPart = nRequest < no_elements - offset ? nRequest : no_elements - offset; - memcpy(pdst, &psrc[offset * srcSize], dstSize * nUpperPart); - if (nRequest > nUpperPart) - memcpy(&pdst[dstSize * nUpperPart], psrc, dstSize * (nRequest - nUpperPart)); - if (isString) - for (i = 1; i <= nRequest; i++) - pdst[dstSize*i-1] = '\0'; - } else { - for (; nRequest > 0; nRequest--, pdst += dstSize, offset += increment) { - offset %= no_elements; - memcpy(pdst, &psrc[offset*srcSize], dstSize); - if (isString) pdst[dstSize-1] = '\0'; - } - } -} - -void dbExtractArrayFromBuf(const void *pfrom, void *pto, - short field_size, short field_type, - long nRequest, long no_elements, long offset, long increment) -{ - char *pdst = (char *) pto; - char *psrc = (char *) pfrom; - int i; - short srcSize = field_size; - short dstSize = srcSize; - char isString = (field_type == DBF_STRING); - - if (nRequest > no_elements) nRequest = no_elements; - if (offset > no_elements - 1) offset = no_elements - 1; - if (isString && dstSize >= MAX_STRING_SIZE) dstSize = MAX_STRING_SIZE - 1; - - if (increment == 1) { - memcpy(pdst, &psrc[offset * srcSize], dstSize * nRequest); - if (isString) - for (i = 1; i <= nRequest; i++) - pdst[dstSize*i] = '\0'; - } else { - for (; nRequest > 0; nRequest--, pdst += srcSize, offset += increment) { - memcpy(pdst, &psrc[offset*srcSize], dstSize); - if (isString) pdst[dstSize] = '\0'; - } - } -} diff --git a/src/ioc/db/dbExtractArray.h b/src/ioc/db/dbExtractArray.h deleted file mode 100644 index 7ed35847f..000000000 --- a/src/ioc/db/dbExtractArray.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_dbExtractArray_H -#define INC_dbExtractArray_H - -#include "dbFldTypes.h" -#include "dbAddr.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void dbExtractArrayFromRec(const DBADDR *paddr, void *pto, - long nRequest, long no_elements, long offset, long increment); -epicsShareFunc void dbExtractArrayFromBuf(const void *pfrom, void *pto, - short field_size, short field_type, - long nRequest, long no_elements, long offset, long increment); - -#ifdef __cplusplus -} -#endif - -#endif // INC_dbExtractArray_H diff --git a/src/ioc/db/dbFastLinkConv.c b/src/ioc/db/dbFastLinkConv.c deleted file mode 100644 index 00a37f710..000000000 --- a/src/ioc/db/dbFastLinkConv.c +++ /dev/null @@ -1,1490 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbFastLinkConv.c */ -/* - * Author: Matthew Needes - * Date: 12-9-93 - */ - -#include -#include -#include -#include -#include - -#include "alarm.h" -#include "cvtFast.h" -#include "dbDefs.h" -#include "epicsConvert.h" -#include "epicsStdlib.h" -#include "errlog.h" -#include "errMdef.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbCommon.h" -#include "dbConvertFast.h" -#include "dbFldTypes.h" -#include "dbStaticLib.h" -#include "link.h" -#include "recGbl.h" -#include "recSup.h" -#include "special.h" - - -/* - * In the following functions: - * - * cvt_y_z(ARGS) - * - * converts from type y to type z. If - * type y and z are the same, it merely copies. - * - * where st - string - * c - epicsInt8 - * uc - epicsUInt8 - * s - epicsInt16 - * us - epicsUInt16 - * l - epicsInt32 - * ul - epicsUInt32 - * q - epicsInt64 - * uq - epicsUInt64 - * f - epicsFloat32 - * d - epicsFloat64 - * e - enum - * - * These functions are _single_ value functions, - * i.e.: do not deal with array types. - */ - -/* - * A DB_LINK that is not initialized with recGblInitFastXXXLink() - * will have this conversion. - */ - -/* Convert String to String */ -static long cvt_st_st( - char *from, - char *to, - const dbAddr *paddr) -{ - size_t size; - - if (paddr && paddr->field_size < MAX_STRING_SIZE) { - size = paddr->field_size - 1; - } else { - size = MAX_STRING_SIZE - 1; - } - strncpy(to, from, size); - to[size] = 0; - return 0; -} - -/* Convert String to Char */ -static long cvt_st_c( - char *from, - epicsInt8 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0; - return 0; - } - return epicsParseInt8(from, to, 10, &end); -} - -/* Convert String to Unsigned Char */ -static long cvt_st_uc( - char *from, - epicsUInt8 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0; - return 0; - } - return epicsParseUInt8(from, to, 10, &end); -} - -/* Convert String to Short */ -static long cvt_st_s( - char *from, - epicsInt16 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0; - return 0; - } - return epicsParseInt16(from, to, 10, &end); -} - -/* Convert String to Unsigned Short */ -static long cvt_st_us( - char *from, - epicsUInt16 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0; - return 0; - } - return epicsParseUInt16(from, to, 10, &end); -} - -/* Convert String to Long */ -static long cvt_st_l( - char *from, - epicsInt32 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0; - return 0; - } - return epicsParseInt32(from, to, 10, &end); -} - -/* Convert String to Unsigned Long */ -static long cvt_st_ul( - char *from, - epicsUInt32 *to, - const dbAddr *paddr) -{ - char *end; - long status; - - if (*from == 0) { - *to = 0; - return 0; - } - status = epicsParseUInt32(from, to, 10, &end); - if (status == S_stdlib_noConversion || - (!status && (*end == '.' || *end == 'e' || *end == 'E'))) { - /* - * Convert via double so numbers like 1.0e3 convert properly. - * db_access pretends unsigned long is double. - */ - double dval; - - status = epicsParseFloat64(from, &dval, &end); - if (!status && - dval >=0 && - dval <= ULONG_MAX) - *to = dval; - } - return status; -} - -/* Convert String to Int64 */ -static long cvt_st_q( - char *from, - epicsInt64 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0; - return 0; - } - return epicsParseInt64(from, to, 10, &end); -} - -/* Convert String to UInt64 */ -static long cvt_st_uq( - char *from, - epicsUInt64 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0; - return 0; - } - return epicsParseUInt64(from, to, 0, &end); -} - -/* Convert String to Float */ -static long cvt_st_f( - char *from, - epicsFloat32 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0; - return 0; - } - return epicsParseFloat32(from, to, &end); -} - -/* Convert String to Double */ -static long cvt_st_d( - char *from, - epicsFloat64 *to, - const dbAddr *paddr) -{ - char *end; - - if (*from == 0) { - *to = 0.0; - return 0; - } - return epicsParseFloat64(from, to, &end); -} - -/* Convert String to Enumerated */ -static long cvt_st_e( - char *from, - epicsEnum16 *to, - const dbAddr *paddr) -{ - rset *prset = dbGetRset(paddr); - long status = S_db_noRSET; - struct dbr_enumStrs enumStrs; - - if (!prset || !prset->put_enum_str) { - recGblRecSupError(status, paddr, "dbPutField", "put_enum_str"); - return status; - } - - status = prset->put_enum_str(paddr, from); - if (!status) return 0; - - if (!prset->get_enum_strs) { - recGblRecSupError(status, paddr, "dbPutField", "get_enum_strs"); - return status; - } - - status = prset->get_enum_strs(paddr, &enumStrs); - if (!status) { - epicsEnum16 val; - - status = epicsParseUInt16(from, &val, 10, NULL); - if (!status && val < enumStrs.no_str) { - *to = val; - return 0; - } - status = S_db_badChoice; - } - - recGblRecordError(status, paddr->precord, from); - return status; -} - -/* Convert String to Menu */ -static long cvt_st_menu( - char *from, - epicsEnum16 *to, - const dbAddr *paddr) -{ - dbFldDes *pdbFldDes = paddr->pfldDes; - dbMenu *pdbMenu; - char **pchoices; - char *pchoice; - - if (pdbFldDes && - (pdbMenu = pdbFldDes->ftPvt) && - (pchoices = pdbMenu->papChoiceValue)) { - int i, nChoice = pdbMenu->nChoice; - epicsEnum16 val; - - for (i = 0; i < nChoice; i++) { - pchoice = pchoices[i]; - if (!pchoice) continue; - if (strcmp(pchoice, from) == 0) { - *to = i; - return 0; - } - } - - if (!epicsParseUInt16(from, &val, 10, NULL) && val < nChoice) { - *to = val; - return 0; - } - } - recGblDbaddrError(S_db_badChoice, paddr, "dbFastLinkConv(cvt_st_menu)"); - return(S_db_badChoice); -} - -/* Convert String to Device */ -static long cvt_st_device( - char *from, - epicsEnum16 *to, - const dbAddr *paddr) -{ - dbFldDes *pdbFldDes = paddr->pfldDes; - dbDeviceMenu *pdbDeviceMenu = pdbFldDes->ftPvt; - char **pchoices, *pchoice; - - if (pdbFldDes && - (pdbDeviceMenu = pdbFldDes->ftPvt) && - (pchoices = pdbDeviceMenu->papChoice)) { - int i, nChoice = pdbDeviceMenu->nChoice; - epicsEnum16 val; - - for (i = 0; i < nChoice; i++) { - pchoice = pchoices[i]; - if (!pchoice) continue; - if (strcmp(pchoice, from) == 0) { - *to = i; - return 0; - } - } - - if (!epicsParseUInt16(from, &val, 10, NULL) && val < nChoice) { - *to = val; - return 0; - } - } - recGblDbaddrError(S_db_badChoice, paddr, "dbFastLinkConv(cvt_st_device)"); - return S_db_badChoice; -} - -/* Convert Char to String */ -static long cvt_c_st( - epicsInt8 *from, - char *to, - const dbAddr *paddr) -{ cvtCharToString(*from, to); return(0); } - -/* Convert Char to Char */ -static long cvt_c_c( - epicsInt8 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Unsigned Char */ -static long cvt_c_uc( - epicsInt8 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Short */ -static long cvt_c_s( - epicsInt8 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Unsigned Short */ -static long cvt_c_us( - epicsInt8 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Long */ -static long cvt_c_l( - epicsInt8 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Unsigned Long */ -static long cvt_c_ul( - epicsInt8 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Int64 */ -static long cvt_c_q( - epicsInt8 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to UInt64 */ -static long cvt_c_uq( - epicsInt8 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Float */ -static long cvt_c_f( - epicsInt8 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Double */ -static long cvt_c_d( - epicsInt8 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Char to Enumerated */ -static long cvt_c_e( - epicsInt8 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to String */ -static long cvt_uc_st( - epicsUInt8 *from, - char *to, - const dbAddr *paddr) -{ cvtUcharToString(*from, to); return(0); } - -/* Convert Unsigned Char to Char */ -static long cvt_uc_c( - epicsUInt8 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Unsigned Char */ -static long cvt_uc_uc( - epicsUInt8 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Short */ -static long cvt_uc_s( - epicsUInt8 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Unsigned Short */ -static long cvt_uc_us( - epicsUInt8 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Long */ -static long cvt_uc_l( - epicsUInt8 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Unsigned Long */ -static long cvt_uc_ul( - epicsUInt8 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Int64 */ -static long cvt_uc_q( - epicsUInt8 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to UInt64 */ -static long cvt_uc_uq( - epicsUInt8 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Float */ -static long cvt_uc_f( - epicsUInt8 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Double */ -static long cvt_uc_d( - epicsUInt8 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Char to Enumerated */ -static long cvt_uc_e( - epicsUInt8 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to String */ -static long cvt_s_st( - epicsInt16 *from, - char *to, - const dbAddr *paddr) -{ cvtShortToString(*from, to); return(0); } - -/* Convert Short to Char */ -static long cvt_s_c( - epicsInt16 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=(epicsInt8)*from; return(0); } - -/* Convert Short to Unsigned Char */ -static long cvt_s_uc( - epicsInt16 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=(epicsUInt8)*from; return(0); } - -/* Convert Short to Short */ -static long cvt_s_s( - epicsInt16 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to Unsigned Short */ -static long cvt_s_us( - epicsInt16 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to Long */ -static long cvt_s_l( - epicsInt16 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to Unsigned Long */ -static long cvt_s_ul( - epicsInt16 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to Int64 */ -static long cvt_s_q( - epicsInt16 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to UInt64 */ -static long cvt_s_uq( - epicsInt16 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to Float */ -static long cvt_s_f( - epicsInt16 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to Double */ -static long cvt_s_d( - epicsInt16 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Short to Enumerated */ -static long cvt_s_e( - epicsInt16 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to String */ -static long cvt_us_st( - epicsUInt16 *from, - char *to, - const dbAddr *paddr) -{ cvtUshortToString(*from, to); return(0); } - -/* Convert Unsigned Short to Char */ -static long cvt_us_c( - epicsUInt16 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=(epicsInt8)*from; return(0); } - -/* Convert Unsigned Short to Unsigned Char */ -static long cvt_us_uc( - epicsUInt16 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=(epicsUInt8)*from; return(0); } - -/* Convert Unsigned Short to Short */ -static long cvt_us_s( - epicsUInt16 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to Unsigned Short */ -static long cvt_us_us( - epicsUInt16 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to Long */ -static long cvt_us_l( - epicsUInt16 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to Unsigned Long */ -static long cvt_us_ul( - epicsUInt16 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to Int64 */ -static long cvt_us_q( - epicsUInt16 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to UInt64 */ -static long cvt_us_uq( - epicsUInt16 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to Float */ -static long cvt_us_f( - epicsUInt16 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to Double */ -static long cvt_us_d( - epicsUInt16 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Short to Enumerated */ -static long cvt_us_e( - epicsUInt16 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to String */ -static long cvt_l_st( - epicsInt32 *from, - char *to, - const dbAddr *paddr) -{ cvtLongToString(*from, to); return(0); } - -/* Convert Long to Char */ -static long cvt_l_c( - epicsInt32 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to Unsigned Char */ -static long cvt_l_uc( - epicsInt32 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to Short */ -static long cvt_l_s( - epicsInt32 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to Unsigned Short */ -static long cvt_l_us( - epicsInt32 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to Long */ -static long cvt_l_l( - epicsInt32 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to Unsigned Long */ -static long cvt_l_ul( - epicsInt32 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to Int64 */ -static long cvt_l_q( - epicsInt32 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to UInt64 */ -static long cvt_l_uq( - epicsInt32 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to Float */ -static long cvt_l_f( - epicsInt32 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=(epicsFloat32)*from; return(0); } - -/* Convert Long to Double */ -static long cvt_l_d( - epicsInt32 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Long to Enumerated */ -static long cvt_l_e( - epicsInt32 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to String */ -static long cvt_ul_st( - epicsUInt32 *from, - char *to, - const dbAddr *paddr) -{ cvtUlongToString(*from, to); return(0); } - -/* Convert Unsigned Long to Char */ -static long cvt_ul_c( - epicsUInt32 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to Unsigned Char */ -static long cvt_ul_uc( - epicsUInt32 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to Short */ -static long cvt_ul_s( - epicsUInt32 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to Unsigned Short */ -static long cvt_ul_us( - epicsUInt32 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to Long */ -static long cvt_ul_l( - epicsUInt32 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to Unsigned Long */ -static long cvt_ul_ul( - epicsUInt32 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to Int64 */ -static long cvt_ul_q( - epicsUInt32 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to UInt64 */ -static long cvt_ul_uq( - epicsUInt32 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to Float */ -static long cvt_ul_f( - epicsUInt32 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=(epicsFloat32)*from; return(0); } - -/* Convert Unsigned Long to Double */ -static long cvt_ul_d( - epicsUInt32 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Unsigned Long to Enumerated */ -static long cvt_ul_e( - epicsUInt32 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to String */ -static long cvt_q_st( - epicsInt64 *from, - char *to, - const dbAddr *paddr) -{ cvtInt64ToString(*from, to); return(0); } - -/* Convert Int64 to Char */ -static long cvt_q_c( - epicsInt64 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to Unsigned Char */ -static long cvt_q_uc( - epicsInt64 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to Short */ -static long cvt_q_s( - epicsInt64 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to Unsigned Short */ -static long cvt_q_us( - epicsInt64 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to Long */ -static long cvt_q_l( - epicsInt64 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to Unsigned Long */ -static long cvt_q_ul( - epicsInt64 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to Int64 */ -static long cvt_q_q( - epicsInt64 *from, - epicsInt64 *to, - const dbAddr *paddr) - { - - *to=*from; return(0); } - -/* Convert Int64 to UInt64 */ -static long cvt_q_uq( - epicsInt64 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { - - *to=*from; return(0); } - -/* Convert Int64 to Float */ -static long cvt_q_f( - epicsInt64 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to Double */ -static long cvt_q_d( - epicsInt64 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Int64 to Enumerated */ -static long cvt_q_e( - epicsInt32 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to String */ -static long cvt_uq_st( - epicsUInt64 *from, - char *to, - const dbAddr *paddr) -{ cvtUInt64ToString(*from, to); return(0); } - -/* Convert UInt64 to Char */ -static long cvt_uq_c( - epicsUInt64 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Unsigned Char */ -static long cvt_uq_uc( - epicsUInt64 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Short */ -static long cvt_uq_s( - epicsUInt64 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Unsigned Short */ -static long cvt_uq_us( - epicsUInt64 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Long */ -static long cvt_uq_l( - epicsUInt64 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Unsigned Long */ -static long cvt_uq_ul( - epicsUInt64 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Int64 */ -static long cvt_uq_q( - epicsUInt64 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to UInt64 */ -static long cvt_uq_uq( - epicsUInt64 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Float */ -static long cvt_uq_f( - epicsUInt64 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Double */ -static long cvt_uq_d( - epicsUInt64 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert UInt64 to Enumerated */ -static long cvt_uq_e( - epicsUInt64 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Float to String */ -static long cvt_f_st( - epicsFloat32 *from, - char *to, - const dbAddr *paddr) - { - rset *prset = 0; - long status = 0; - long precision = 6; - - if(paddr) prset = dbGetRset(paddr); - - if (prset && prset->get_precision) - status = (*prset->get_precision)(paddr, &precision); - cvtFloatToString(*from, to, (unsigned short)precision); - return(status); - } - -/* Convert Float to Char */ -static long cvt_f_c( - epicsFloat32 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=(epicsInt8)*from; return(0); } - -/* Convert Float to Unsigned Char */ -static long cvt_f_uc( - epicsFloat32 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=(epicsUInt8)*from; return(0); } - -/* Convert Float to Short */ -static long cvt_f_s( - epicsFloat32 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=(epicsInt16)*from; return(0); } - -/* Convert Float to Unsigned Short */ -static long cvt_f_us( - epicsFloat32 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=(epicsUInt16)*from; return(0); } - -/* Convert Float to Long */ -static long cvt_f_l( - epicsFloat32 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=(epicsInt32)*from; return(0); } - -/* Convert Float to Unsigned Long */ -static long cvt_f_ul( - epicsFloat32 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=(epicsUInt32)*from; return(0); } - -/* Convert Float to Int64 */ -static long cvt_f_q( - epicsFloat32 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Float to UInt64 */ -static long cvt_f_uq( - epicsFloat32 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Float to Float */ -static long cvt_f_f( - epicsFloat32 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Float to Double */ -static long cvt_f_d( - epicsFloat32 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Float to Enumerated */ -static long cvt_f_e( - epicsFloat32 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=(epicsEnum16)*from; return(0); } - -/* Convert Double to String */ -static long cvt_d_st( - epicsFloat64 *from, - char *to, - const dbAddr *paddr) - { - rset *prset = 0; - long status = 0; - long precision = 6; - - if(paddr) prset = dbGetRset(paddr); - - if (prset && prset->get_precision) - status = (*prset->get_precision)(paddr, &precision); - cvtDoubleToString(*from, to, (unsigned short)precision); - return(status); - } - -/* Convert Double to Char */ -static long cvt_d_c( - epicsFloat64 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=(epicsInt8)*from; return(0); } - -/* Convert Double to Unsigned Char */ -static long cvt_d_uc( - epicsFloat64 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=(epicsUInt8)*from; return(0); } - -/* Convert Double to Short */ -static long cvt_d_s( - epicsFloat64 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=(epicsInt16)*from; return(0); } - -/* Convert Double to Unsigned Short */ -static long cvt_d_us( - epicsFloat64 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=(epicsUInt16)*from; return(0); } - -/* Convert Double to Long */ -static long cvt_d_l( - epicsFloat64 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Double to Unsigned Long */ -static long cvt_d_ul( - epicsFloat64 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Double to Int64 */ -static long cvt_d_q( - epicsFloat64 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Double to UInt64 */ -static long cvt_d_uq( - epicsFloat64 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Double to Float */ -static long cvt_d_f( - epicsFloat64 *from, - epicsFloat32 *to, - const dbAddr *paddr) -{ *to = epicsConvertDoubleToFloat(*from); return 0;} - -/* Convert Double to Double */ -static long cvt_d_d( - epicsFloat64 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Double to Enumerated */ -static long cvt_d_e( - epicsFloat64 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=(epicsEnum16)*from; return(0); } - -/* Convert Enumerated to Char */ -static long cvt_e_c( - epicsEnum16 *from, - epicsInt8 *to, - const dbAddr *paddr) - { *to=(epicsInt8)*from; return(0); } - -/* Convert Enumerated to Unsigned Char */ -static long cvt_e_uc( - epicsEnum16 *from, - epicsUInt8 *to, - const dbAddr *paddr) - { *to=(epicsUInt8)*from; return(0); } - -/* Convert Enumerated to Short */ -static long cvt_e_s( - epicsEnum16 *from, - epicsInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Enumerated to Unsigned Short */ -static long cvt_e_us( - epicsEnum16 *from, - epicsUInt16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Enumerated to Long */ -static long cvt_e_l( - epicsEnum16 *from, - epicsInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Enumerated to Unsigned Long */ -static long cvt_e_ul( - epicsEnum16 *from, - epicsUInt32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Enumerated to Int64 */ -static long cvt_e_q( - epicsEnum16 *from, - epicsInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Enumerated to UInt64 */ -static long cvt_e_uq( - epicsEnum16 *from, - epicsUInt64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Enumerated to Float */ -static long cvt_e_f( - epicsEnum16 *from, - epicsFloat32 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Enumerated to Double */ -static long cvt_e_d( - epicsEnum16 *from, - epicsFloat64 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Enumerated to Enumerated */ -static long cvt_e_e( - epicsEnum16 *from, - epicsEnum16 *to, - const dbAddr *paddr) - { *to=*from; return(0); } - -/* Convert Choices And Enumerated Types To String ... */ - -/* Get Enumerated to String */ -static long cvt_e_st_get( - epicsEnum16 *from, - char *to, - const dbAddr *paddr) - { - rset *prset = 0; - long status; - - if(paddr) prset = dbGetRset(paddr); - - if (prset && prset->get_enum_str) - return (*prset->get_enum_str)(paddr, to); - - status = S_db_noRSET; - recGblRecSupError(status, paddr, "dbGetField", "get_enum_str"); - - return(S_db_badDbrtype); - } - -/* Put Enumerated to String */ -static long cvt_e_st_put( - epicsEnum16 *from, - char *to, - const dbAddr *paddr) - { cvtUshortToString(*from, to); return(0); } - -/* Get Menu to String */ -static long cvt_menu_st( - epicsEnum16 *from, - char *to, - const dbAddr *paddr) - { - dbFldDes *pdbFldDes; - dbMenu *pdbMenu; - char **papChoiceValue; - char *pchoice; - - if(! paddr - || !(pdbFldDes = paddr->pfldDes) - || !(pdbMenu = (dbMenu *)pdbFldDes->ftPvt) - || *from>=pdbMenu->nChoice - || !(papChoiceValue = pdbMenu->papChoiceValue) - || !(pchoice=papChoiceValue[*from])) { - recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_menu_st)"); - return(S_db_badChoice); - } - strncpy(to,pchoice,MAX_STRING_SIZE); - return(0); - } - - -/* Get Device to String */ -static long cvt_device_st( - epicsEnum16 *from, - char *to, - const dbAddr *paddr) - { - dbFldDes *pdbFldDes; - dbDeviceMenu *pdbDeviceMenu; - char **papChoice; - char *pchoice; - - if(!paddr - || !(pdbFldDes = paddr->pfldDes) - || !(pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt) - || *from>=pdbDeviceMenu->nChoice - || !(papChoice= pdbDeviceMenu->papChoice) - || !(pchoice=papChoice[*from])) { - recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_device_st)"); - return(S_db_badChoice); - } - strncpy(to,pchoice,MAX_STRING_SIZE); - return(0); - } - -/* - * Get conversion routine lookup table - * - * Converts type X to ... - * - * DBR_STRING, DBR_CHR, DBR_UCHAR, DBR_SHORT, DBR_USHORT, - * DBR_LONG, DBR_ULONG, DBR_INT64, DBR_UINT64, DBR_FLOAT, DBR_DOUBLE, DBR_ENUM - * - * NULL implies the conversion is not supported. - */ - -epicsShareDef long (*dbFastGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1])() = { - - /* Convert DBF_STRING to ... */ -{ cvt_st_st, cvt_st_c, cvt_st_uc, cvt_st_s, cvt_st_us, cvt_st_l, cvt_st_ul, cvt_st_q, cvt_st_uq, cvt_st_f, cvt_st_d, cvt_st_e }, - - /* Convert DBF_CHAR to ... */ -{ cvt_c_st, cvt_c_c, cvt_c_uc, cvt_c_s, cvt_c_us, cvt_c_l, cvt_c_ul, cvt_c_q, cvt_c_uq, cvt_c_f, cvt_c_d, cvt_c_e }, - - /* Convert DBF_UCHAR to ... */ -{ cvt_uc_st, cvt_uc_c, cvt_uc_uc, cvt_uc_s, cvt_uc_us, cvt_uc_l, cvt_uc_ul, cvt_uc_q, cvt_uc_uq, cvt_uc_f, cvt_uc_d, cvt_uc_e }, - - /* Convert DBF_SHORT to ... */ -{ cvt_s_st, cvt_s_c, cvt_s_uc, cvt_s_s, cvt_s_us, cvt_s_l, cvt_s_ul, cvt_s_q, cvt_s_uq, cvt_s_f, cvt_s_d, cvt_s_e }, - - /* Convert DBF_USHORT to ... */ -{ cvt_us_st, cvt_us_c, cvt_us_uc, cvt_us_s, cvt_us_us, cvt_us_l, cvt_us_ul, cvt_us_q, cvt_us_uq, cvt_us_f, cvt_us_d, cvt_us_e }, - - /* Convert DBF_LONG to ... */ -{ cvt_l_st, cvt_l_c, cvt_l_uc, cvt_l_s, cvt_l_us, cvt_l_l, cvt_l_ul, cvt_l_q, cvt_l_uq, cvt_l_f, cvt_l_d, cvt_l_e }, - - /* Convert DBF_ULONG to ... */ -{ cvt_ul_st, cvt_ul_c, cvt_ul_uc, cvt_ul_s, cvt_ul_us, cvt_ul_l, cvt_ul_ul, cvt_ul_q, cvt_ul_uq, cvt_ul_f, cvt_ul_d, cvt_ul_e }, - - /* Convert DBF_INT64 to ... */ -{ cvt_q_st, cvt_q_c, cvt_q_uc, cvt_q_s, cvt_q_us, cvt_q_l, cvt_q_ul, cvt_q_q, cvt_q_uq, cvt_q_f, cvt_q_d, cvt_q_e }, - - /* Convert DBF_UINT64 to ... */ -{ cvt_uq_st, cvt_uq_c, cvt_uq_uc, cvt_uq_s, cvt_uq_us, cvt_uq_l, cvt_uq_ul, cvt_uq_q, cvt_uq_uq, cvt_uq_f, cvt_uq_d, cvt_uq_e }, - - /* Convert DBF_FLOAT to ... */ -{ cvt_f_st, cvt_f_c, cvt_f_uc, cvt_f_s, cvt_f_us, cvt_f_l, cvt_f_ul, cvt_f_q, cvt_f_uq, cvt_f_f, cvt_f_d, cvt_f_e }, - - /* Convert DBF_DOUBLE to ... */ -{ cvt_d_st, cvt_d_c, cvt_d_uc, cvt_d_s, cvt_d_us, cvt_d_l, cvt_d_ul, cvt_d_q, cvt_d_uq, cvt_d_f, cvt_d_d, cvt_d_e }, - - /* Convert DBF_ENUM to ... */ -{ cvt_e_st_get, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_q, cvt_e_uq, cvt_e_f, cvt_e_d, cvt_e_e }, - - /* Convert DBF_MENU to ... */ -{ cvt_menu_st, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_q, cvt_e_uq, cvt_e_f, cvt_e_d, cvt_e_e }, - - /* Convert DBF_DEVICE to ... */ -{ cvt_device_st, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_q, cvt_e_uq, cvt_e_f, cvt_e_d, cvt_e_e } }; - -/* - * Put conversion routine lookup table - * - * Converts type X to ... - * - * DBF_STRING DBF_CHAR DBF_UCHAR DBF_SHORT DBF_USHORT - * DBF_LONG DBF_ULONG DBF_INT64 DBF_UINT64 DBF_FLOAT DBF_DOUBLE DBF_ENUM - * DBF_MENU DBF_DEVICE - * - * NULL implies the conversion is not supported. - */ - -epicsShareDef long (*dbFastPutConvertRoutine[DBR_ENUM+1][DBF_DEVICE+1])() = { - - /* Convert DBR_STRING to ... */ -{ cvt_st_st, cvt_st_c, cvt_st_uc, cvt_st_s, cvt_st_us, cvt_st_l, cvt_st_ul, cvt_st_q, cvt_st_uq, cvt_st_f, cvt_st_d, cvt_st_e, cvt_st_menu, cvt_st_device}, - - /* Convert DBR_CHAR to ... */ -{ cvt_c_st, cvt_c_c, cvt_c_uc, cvt_c_s, cvt_c_us, cvt_c_l, cvt_c_ul, cvt_c_q, cvt_c_uq, cvt_c_f, cvt_c_d, cvt_c_e, cvt_c_e, cvt_c_e}, - - /* Convert DBR_UCHAR to ... */ -{ cvt_uc_st, cvt_uc_c, cvt_uc_uc, cvt_uc_s, cvt_uc_us, cvt_uc_l, cvt_uc_ul, cvt_uc_q, cvt_uc_uq, cvt_uc_f, cvt_uc_d, cvt_uc_e, cvt_uc_e, cvt_uc_e}, - - /* Convert DBR_SHORT to ... */ -{ cvt_s_st, cvt_s_c, cvt_s_uc, cvt_s_s, cvt_s_us, cvt_s_l, cvt_s_ul, cvt_s_q, cvt_s_uq, cvt_s_f, cvt_s_d, cvt_s_e, cvt_s_e, cvt_s_e}, - - /* Convert DBR_USHORT to ... */ -{ cvt_us_st, cvt_us_c, cvt_us_uc, cvt_us_s, cvt_us_us, cvt_us_l, cvt_us_ul, cvt_us_q, cvt_us_uq, cvt_us_f, cvt_us_d, cvt_us_e, cvt_us_e, cvt_us_e}, - - /* Convert DBR_LONG to ... */ -{ cvt_l_st, cvt_l_c, cvt_l_uc, cvt_l_s, cvt_l_us, cvt_l_l, cvt_l_ul, cvt_l_q, cvt_l_uq, cvt_l_f, cvt_l_d, cvt_l_e, cvt_l_e, cvt_l_e}, - - /* Convert DBR_ULONG to ... */ -{ cvt_ul_st, cvt_ul_c, cvt_ul_uc, cvt_ul_s, cvt_ul_us, cvt_ul_l, cvt_ul_ul, cvt_ul_q, cvt_ul_uq, cvt_ul_f, cvt_ul_d, cvt_ul_e, cvt_ul_e, cvt_ul_e}, - - /* Convert DBR_INT64 to ... */ -{ cvt_q_st, cvt_q_c, cvt_q_uc, cvt_q_s, cvt_q_us, cvt_q_l, cvt_q_ul, cvt_q_q, cvt_q_uq, cvt_q_f, cvt_q_d, cvt_q_e, cvt_q_e, cvt_q_e}, - - /* Convert DBR_UINT64 to ... */ -{ cvt_uq_st, cvt_uq_c, cvt_uq_uc, cvt_uq_s, cvt_uq_us, cvt_uq_l, cvt_uq_ul, cvt_uq_q, cvt_uq_uq, cvt_uq_f, cvt_uq_d, cvt_uq_e, cvt_uq_e, cvt_uq_e}, - - /* Convert DBR_FLOAT to ... */ -{ cvt_f_st, cvt_f_c, cvt_f_uc, cvt_f_s, cvt_f_us, cvt_f_l, cvt_f_ul, cvt_f_q, cvt_f_uq, cvt_f_f, cvt_f_d, cvt_f_e, cvt_f_e, cvt_f_e}, - - /* Convert DBR_DOUBLE to ... */ -{ cvt_d_st, cvt_d_c, cvt_d_uc, cvt_d_s, cvt_d_us, cvt_d_l, cvt_d_ul, cvt_d_q, cvt_d_uq, cvt_d_f, cvt_d_d, cvt_d_e, cvt_d_e, cvt_d_e}, - - /* Convert DBR_ENUM to ... */ -{ cvt_e_st_put, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_q, cvt_e_uq, cvt_e_f, cvt_e_d, cvt_e_e, cvt_e_e, cvt_e_e} }; - diff --git a/src/ioc/db/dbIocRegister.c b/src/ioc/db/dbIocRegister.c deleted file mode 100644 index 07c9836c2..000000000 --- a/src/ioc/db/dbIocRegister.c +++ /dev/null @@ -1,453 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "iocsh.h" - -#define epicsExportSharedSymbols -#include "callback.h" -#include "dbAccess.h" -#include "dbBkpt.h" -#include "dbCaTest.h" -#include "dbEvent.h" -#include "dbIocRegister.h" -#include "dbJLink.h" -#include "dbLock.h" -#include "dbNotify.h" -#include "dbScan.h" -#include "dbServer.h" -#include "dbState.h" -#include "db_test.h" -#include "dbTest.h" - -epicsShareExtern int callbackParallelThreadsDefault; - -/* dbLoadDatabase */ -static const iocshArg dbLoadDatabaseArg0 = { "file name",iocshArgString}; -static const iocshArg dbLoadDatabaseArg1 = { "path",iocshArgString}; -static const iocshArg dbLoadDatabaseArg2 = { "substitutions",iocshArgString}; -static const iocshArg * const dbLoadDatabaseArgs[3] = -{ - &dbLoadDatabaseArg0,&dbLoadDatabaseArg1,&dbLoadDatabaseArg2 -}; -static const iocshFuncDef dbLoadDatabaseFuncDef = - {"dbLoadDatabase",3,dbLoadDatabaseArgs}; -static void dbLoadDatabaseCallFunc(const iocshArgBuf *args) -{ - dbLoadDatabase(args[0].sval,args[1].sval,args[2].sval); -} - -/* dbLoadRecords */ -static const iocshArg dbLoadRecordsArg0 = { "file name",iocshArgString}; -static const iocshArg dbLoadRecordsArg1 = { "substitutions",iocshArgString}; -static const iocshArg * const dbLoadRecordsArgs[2] = {&dbLoadRecordsArg0,&dbLoadRecordsArg1}; -static const iocshFuncDef dbLoadRecordsFuncDef = {"dbLoadRecords",2,dbLoadRecordsArgs}; -static void dbLoadRecordsCallFunc(const iocshArgBuf *args) -{ - dbLoadRecords(args[0].sval,args[1].sval); -} - -/* dbb */ -static const iocshArg dbbArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbbArgs[1] = {&dbbArg0}; -static const iocshFuncDef dbbFuncDef = {"dbb",1,dbbArgs}; -static void dbbCallFunc(const iocshArgBuf *args) { dbb(args[0].sval);} - -/* dbd */ -static const iocshArg dbdArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbdArgs[1] = {&dbdArg0}; -static const iocshFuncDef dbdFuncDef = {"dbd",1,dbdArgs}; -static void dbdCallFunc(const iocshArgBuf *args) { dbd(args[0].sval);} - -/* dbc */ -static const iocshArg dbcArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbcArgs[1] = {&dbcArg0}; -static const iocshFuncDef dbcFuncDef = {"dbc",1,dbcArgs}; -static void dbcCallFunc(const iocshArgBuf *args) { dbc(args[0].sval);} - -/* dbs */ -static const iocshArg dbsArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbsArgs[1] = {&dbsArg0}; -static const iocshFuncDef dbsFuncDef = {"dbs",1,dbsArgs}; -static void dbsCallFunc(const iocshArgBuf *args) { dbs(args[0].sval);} - -/* dbstat */ -static const iocshFuncDef dbstatFuncDef = {"dbstat",0}; -static void dbstatCallFunc(const iocshArgBuf *args) { dbstat();} - -/* dbp */ -static const iocshArg dbpArg0 = { "record name",iocshArgString}; -static const iocshArg dbpArg1 = { "interest level",iocshArgInt}; -static const iocshArg * const dbpArgs[2] = {&dbpArg0,&dbpArg1}; -static const iocshFuncDef dbpFuncDef = {"dbp",2,dbpArgs}; -static void dbpCallFunc(const iocshArgBuf *args) -{ dbp(args[0].sval,args[1].ival);} - -/* dbap */ -static const iocshArg dbapArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbapArgs[1] = {&dbapArg0}; -static const iocshFuncDef dbapFuncDef = {"dbap",1,dbapArgs}; -static void dbapCallFunc(const iocshArgBuf *args) { dbap(args[0].sval);} - -/* dbsr */ -static const iocshArg dbsrArg0 = { "interest level",iocshArgInt}; -static const iocshArg * const dbsrArgs[1] = {&dbsrArg0}; -static const iocshFuncDef dbsrFuncDef = {"dbsr",1,dbsrArgs}; -static void dbsrCallFunc(const iocshArgBuf *args) { dbsr(args[0].ival);} - -/* dbcar */ -static const iocshArg dbcarArg0 = { "record name",iocshArgString}; -static const iocshArg dbcarArg1 = { "level",iocshArgInt}; -static const iocshArg * const dbcarArgs[2] = {&dbcarArg0,&dbcarArg1}; -static const iocshFuncDef dbcarFuncDef = {"dbcar",2,dbcarArgs}; -static void dbcarCallFunc(const iocshArgBuf *args) -{ - dbcar(args[0].sval,args[1].ival); -} - -/* dbjlr */ -static const iocshArg dbjlrArg0 = { "record name",iocshArgString}; -static const iocshArg dbjlrArg1 = { "level",iocshArgInt}; -static const iocshArg * const dbjlrArgs[2] = {&dbjlrArg0,&dbjlrArg1}; -static const iocshFuncDef dbjlrFuncDef = {"dbjlr",2,dbjlrArgs}; -static void dbjlrCallFunc(const iocshArgBuf *args) -{ - dbjlr(args[0].sval,args[1].ival); -} - -/* dbel */ -static const iocshArg dbelArg0 = { "record name",iocshArgString}; -static const iocshArg dbelArg1 = { "level",iocshArgInt}; -static const iocshArg * const dbelArgs[2] = {&dbelArg0,&dbelArg1}; -static const iocshFuncDef dbelFuncDef = {"dbel",2,dbelArgs}; -static void dbelCallFunc(const iocshArgBuf *args) -{ - dbel(args[0].sval, args[1].ival); -} - -/* dba */ -static const iocshArg dbaArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbaArgs[1] = {&dbaArg0}; -static const iocshFuncDef dbaFuncDef = {"dba",1,dbaArgs}; -static void dbaCallFunc(const iocshArgBuf *args) { dba(args[0].sval);} - -/* dbl */ -static const iocshArg dblArg0 = { "record type",iocshArgString}; -static const iocshArg dblArg1 = { "fields",iocshArgString}; -static const iocshArg * const dblArgs[] = {&dblArg0,&dblArg1}; -static const iocshFuncDef dblFuncDef = {"dbl",2,dblArgs}; -static void dblCallFunc(const iocshArgBuf *args) -{ - dbl(args[0].sval,args[1].sval); -} - -/* dbnr */ -static const iocshArg dbnrArg0 = { "verbose",iocshArgInt}; -static const iocshArg * const dbnrArgs[1] = {&dbnrArg0}; -static const iocshFuncDef dbnrFuncDef = {"dbnr",1,dbnrArgs}; -static void dbnrCallFunc(const iocshArgBuf *args) { dbnr(args[0].ival);} - -/* dbla */ -static const iocshArg dblaArg0 = { "pattern",iocshArgString}; -static const iocshArg * const dblaArgs[1] = {&dblaArg0}; -static const iocshFuncDef dblaFuncDef = {"dbla",1,dblaArgs}; -static void dblaCallFunc(const iocshArgBuf *args) { dbla(args[0].sval);} - -/* dbgrep */ -static const iocshArg dbgrepArg0 = { "pattern",iocshArgString}; -static const iocshArg * const dbgrepArgs[1] = {&dbgrepArg0}; -static const iocshFuncDef dbgrepFuncDef = {"dbgrep",1,dbgrepArgs}; -static void dbgrepCallFunc(const iocshArgBuf *args) { dbgrep(args[0].sval);} - -/* dbgf */ -static const iocshArg dbgfArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbgfArgs[1] = {&dbgfArg0}; -static const iocshFuncDef dbgfFuncDef = {"dbgf",1,dbgfArgs}; -static void dbgfCallFunc(const iocshArgBuf *args) { dbgf(args[0].sval);} - -/* dbpf */ -static const iocshArg dbpfArg0 = { "record name",iocshArgString}; -static const iocshArg dbpfArg1 = { "value",iocshArgString}; -static const iocshArg * const dbpfArgs[2] = {&dbpfArg0,&dbpfArg1}; -static const iocshFuncDef dbpfFuncDef = {"dbpf",2,dbpfArgs}; -static void dbpfCallFunc(const iocshArgBuf *args) -{ dbpf(args[0].sval,args[1].sval);} - -/* dbpr */ -static const iocshArg dbprArg0 = { "record name",iocshArgString}; -static const iocshArg dbprArg1 = { "interest level",iocshArgInt}; -static const iocshArg * const dbprArgs[2] = {&dbprArg0,&dbprArg1}; -static const iocshFuncDef dbprFuncDef = {"dbpr",2,dbprArgs}; -static void dbprCallFunc(const iocshArgBuf *args) -{ dbpr(args[0].sval,args[1].ival);} - -/* dbtr */ -static const iocshArg dbtrArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbtrArgs[1] = {&dbtrArg0}; -static const iocshFuncDef dbtrFuncDef = {"dbtr",1,dbtrArgs}; -static void dbtrCallFunc(const iocshArgBuf *args) { dbtr(args[0].sval);} - -/* dbtgf */ -static const iocshArg dbtgfArg0 = { "record name",iocshArgString}; -static const iocshArg * const dbtgfArgs[1] = {&dbtgfArg0}; -static const iocshFuncDef dbtgfFuncDef = {"dbtgf",1,dbtgfArgs}; -static void dbtgfCallFunc(const iocshArgBuf *args) { dbtgf(args[0].sval);} - -/* dbtpf */ -static const iocshArg dbtpfArg0 = { "record name",iocshArgString}; -static const iocshArg dbtpfArg1 = { "value",iocshArgString}; -static const iocshArg * const dbtpfArgs[2] = {&dbtpfArg0,&dbtpfArg1}; -static const iocshFuncDef dbtpfFuncDef = {"dbtpf",2,dbtpfArgs}; -static void dbtpfCallFunc(const iocshArgBuf *args) -{ dbtpf(args[0].sval,args[1].sval);} - -/* dbior */ -static const iocshArg dbiorArg0 = { "driver name",iocshArgString}; -static const iocshArg dbiorArg1 = { "interest level",iocshArgInt}; -static const iocshArg * const dbiorArgs[] = {&dbiorArg0,&dbiorArg1}; -static const iocshFuncDef dbiorFuncDef = {"dbior",2,dbiorArgs}; -static void dbiorCallFunc(const iocshArgBuf *args) -{ dbior(args[0].sval,args[1].ival);} - -/* dbhcr */ -static const iocshFuncDef dbhcrFuncDef = {"dbhcr",0,0}; -static void dbhcrCallFunc(const iocshArgBuf *args) { dbhcr();} - -/* gft */ -static const iocshArg gftArg0 = { "record name",iocshArgString}; -static const iocshArg * const gftArgs[1] = {&gftArg0}; -static const iocshFuncDef gftFuncDef = {"gft",1,gftArgs}; -static void gftCallFunc(const iocshArgBuf *args) { gft(args[0].sval);} - -/* pft */ -static const iocshArg pftArg0 = { "record name",iocshArgString}; -static const iocshArg pftArg1 = { "value",iocshArgString}; -static const iocshArg * const pftArgs[2] = {&pftArg0,&pftArg1}; -static const iocshFuncDef pftFuncDef = {"pft",2,pftArgs}; -static void pftCallFunc(const iocshArgBuf *args) -{ pft(args[0].sval,args[1].sval);} - -/* dbtpn */ -static const iocshArg dbtpnArg0 = { "record name",iocshArgString}; -static const iocshArg dbtpnArg1 = { "value",iocshArgString}; -static const iocshArg * const dbtpnArgs[2] = {&dbtpnArg0,&dbtpnArg1}; -static const iocshFuncDef dbtpnFuncDef = {"dbtpn",2,dbtpnArgs}; -static void dbtpnCallFunc(const iocshArgBuf *args) -{ dbtpn(args[0].sval,args[1].sval);} - -/* dbNotifyDump */ -static const iocshFuncDef dbNotifyDumpFuncDef = {"dbNotifyDump",0,0}; -static void dbNotifyDumpCallFunc(const iocshArgBuf *args) { dbNotifyDump();} - -/* dbPutAttribute */ -static const iocshArg dbPutAttrArg0 = { "record type",iocshArgString}; -static const iocshArg dbPutAttrArg1 = { "attribute name",iocshArgString}; -static const iocshArg dbPutAttrArg2 = { "value",iocshArgString}; -static const iocshArg * const dbPutAttrArgs[] = - {&dbPutAttrArg0, &dbPutAttrArg1, &dbPutAttrArg2}; -static const iocshFuncDef dbPutAttrFuncDef = - {"dbPutAttribute",3,dbPutAttrArgs}; -static void dbPutAttrCallFunc(const iocshArgBuf *args) -{ dbPutAttribute(args[0].sval,args[1].sval,args[2].sval);} - -/* tpn */ -static const iocshArg tpnArg0 = { "record name",iocshArgString}; -static const iocshArg tpnArg1 = { "value",iocshArgString}; -static const iocshArg * const tpnArgs[2] = {&tpnArg0,&tpnArg1}; -static const iocshFuncDef tpnFuncDef = {"tpn",2,tpnArgs}; -static void tpnCallFunc(const iocshArgBuf *args) -{ tpn(args[0].sval,args[1].sval);} - -/* dblsr */ -static const iocshArg dblsrArg0 = { "record name",iocshArgString}; -static const iocshArg dblsrArg1 = { "interest level",iocshArgInt}; -static const iocshArg * const dblsrArgs[2] = {&dblsrArg0,&dblsrArg1}; -static const iocshFuncDef dblsrFuncDef = {"dblsr",2,dblsrArgs}; -static void dblsrCallFunc(const iocshArgBuf *args) -{ dblsr(args[0].sval,args[1].ival);} - -/* dbLockShowLocked */ -static const iocshArg dbLockShowLockedArg0 = { "interest level",iocshArgInt}; -static const iocshArg * const dbLockShowLockedArgs[1] = {&dbLockShowLockedArg0}; -static const iocshFuncDef dbLockShowLockedFuncDef = - {"dbLockShowLocked",1,dbLockShowLockedArgs}; -static void dbLockShowLockedCallFunc(const iocshArgBuf *args) -{ dbLockShowLocked(args[0].ival);} - -/* scanOnceSetQueueSize */ -static const iocshArg scanOnceSetQueueSizeArg0 = { "size",iocshArgInt}; -static const iocshArg * const scanOnceSetQueueSizeArgs[1] = - {&scanOnceSetQueueSizeArg0}; -static const iocshFuncDef scanOnceSetQueueSizeFuncDef = - {"scanOnceSetQueueSize",1,scanOnceSetQueueSizeArgs}; -static void scanOnceSetQueueSizeCallFunc(const iocshArgBuf *args) -{ - scanOnceSetQueueSize(args[0].ival); -} - -/* scanppl */ -static const iocshArg scanpplArg0 = { "rate",iocshArgDouble}; -static const iocshArg * const scanpplArgs[1] = {&scanpplArg0}; -static const iocshFuncDef scanpplFuncDef = {"scanppl",1,scanpplArgs}; -static void scanpplCallFunc(const iocshArgBuf *args) -{ scanppl(args[0].dval);} - -/* scanpel */ -static const iocshArg scanpelArg0 = { "event name",iocshArgString}; -static const iocshArg * const scanpelArgs[1] = {&scanpelArg0}; -static const iocshFuncDef scanpelFuncDef = {"scanpel",1,scanpelArgs}; -static void scanpelCallFunc(const iocshArgBuf *args) -{ scanpel(args[0].sval);} - -/* postEvent */ -static const iocshArg postEventArg0 = { "event name",iocshArgString}; -static const iocshArg * const postEventArgs[1] = {&postEventArg0}; -static const iocshFuncDef postEventFuncDef = {"postEvent",1,postEventArgs}; -static void postEventCallFunc(const iocshArgBuf *args) -{ - EVENTPVT pel = eventNameToHandle(args[0].sval); - postEvent(pel); -} - -/* scanpiol */ -static const iocshFuncDef scanpiolFuncDef = {"scanpiol",0}; -static void scanpiolCallFunc(const iocshArgBuf *args) { scanpiol();} - -/* callbackSetQueueSize */ -static const iocshArg callbackSetQueueSizeArg0 = { "bufsize",iocshArgInt}; -static const iocshArg * const callbackSetQueueSizeArgs[1] = - {&callbackSetQueueSizeArg0}; -static const iocshFuncDef callbackSetQueueSizeFuncDef = - {"callbackSetQueueSize",1,callbackSetQueueSizeArgs}; -static void callbackSetQueueSizeCallFunc(const iocshArgBuf *args) -{ - callbackSetQueueSize(args[0].ival); -} - -/* callbackParallelThreads */ -static const iocshArg callbackParallelThreadsArg0 = { "no of threads", iocshArgInt}; -static const iocshArg callbackParallelThreadsArg1 = { "priority", iocshArgString}; -static const iocshArg * const callbackParallelThreadsArgs[2] = - {&callbackParallelThreadsArg0,&callbackParallelThreadsArg1}; -static const iocshFuncDef callbackParallelThreadsFuncDef = - {"callbackParallelThreads",2,callbackParallelThreadsArgs}; -static void callbackParallelThreadsCallFunc(const iocshArgBuf *args) -{ - callbackParallelThreads(args[0].ival, args[1].sval); -} - -/* dbStateCreate */ -static const iocshArg dbStateArgName = { "name", iocshArgString }; -static const iocshArg * const dbStateCreateArgs[] = { &dbStateArgName }; -static const iocshFuncDef dbStateCreateFuncDef = { "dbStateCreate", 1, dbStateCreateArgs }; -static void dbStateCreateCallFunc (const iocshArgBuf *args) -{ - dbStateCreate(args[0].sval); -} - -/* dbStateSet */ -static const iocshArg * const dbStateSetArgs[] = { &dbStateArgName }; -static const iocshFuncDef dbStateSetFuncDef = { "dbStateSet", 1, dbStateSetArgs }; -static void dbStateSetCallFunc (const iocshArgBuf *args) -{ - dbStateId sid = dbStateFind(args[0].sval); - - if (sid) - dbStateSet(sid); -} - -/* dbStateClear */ -static const iocshArg * const dbStateClearArgs[] = { &dbStateArgName }; -static const iocshFuncDef dbStateClearFuncDef = { "dbStateClear", 1, dbStateClearArgs }; -static void dbStateClearCallFunc (const iocshArgBuf *args) -{ - dbStateId sid = dbStateFind(args[0].sval); - - if (sid) - dbStateClear(sid); -} - -/* dbStateShow */ -static const iocshArg dbStateShowArg1 = { "level", iocshArgInt }; -static const iocshArg * const dbStateShowArgs[] = { &dbStateArgName, &dbStateShowArg1 }; -static const iocshFuncDef dbStateShowFuncDef = { "dbStateShow", 2, dbStateShowArgs }; -static void dbStateShowCallFunc (const iocshArgBuf *args) -{ - dbStateId sid = dbStateFind(args[0].sval); - - if (sid) - dbStateShow(sid, args[1].ival); -} - -/* dbStateShowAll */ -static const iocshArg dbStateShowAllArg0 = { "level", iocshArgInt }; -static const iocshArg * const dbStateShowAllArgs[] = { &dbStateShowAllArg0 }; -static const iocshFuncDef dbStateShowAllFuncDef = { "dbStateShowAll", 1, dbStateShowAllArgs }; -static void dbStateShowAllCallFunc (const iocshArgBuf *args) -{ - dbStateShowAll(args[0].ival); -} - -void dbIocRegister(void) -{ - iocshRegister(&dbbFuncDef,dbbCallFunc); - iocshRegister(&dbdFuncDef,dbdCallFunc); - iocshRegister(&dbcFuncDef,dbcCallFunc); - iocshRegister(&dbsFuncDef,dbsCallFunc); - iocshRegister(&dbstatFuncDef,dbstatCallFunc); - iocshRegister(&dbpFuncDef,dbpCallFunc); - iocshRegister(&dbapFuncDef,dbapCallFunc); - - iocshRegister(&dbsrFuncDef,dbsrCallFunc); - iocshRegister(&dbcarFuncDef,dbcarCallFunc); - iocshRegister(&dbelFuncDef,dbelCallFunc); - iocshRegister(&dbjlrFuncDef,dbjlrCallFunc); - - iocshRegister(&dbLoadDatabaseFuncDef,dbLoadDatabaseCallFunc); - iocshRegister(&dbLoadRecordsFuncDef,dbLoadRecordsCallFunc); - - iocshRegister(&dbaFuncDef,dbaCallFunc); - iocshRegister(&dblFuncDef,dblCallFunc); - iocshRegister(&dbnrFuncDef,dbnrCallFunc); - iocshRegister(&dblaFuncDef,dblaCallFunc); - iocshRegister(&dbgrepFuncDef,dbgrepCallFunc); - iocshRegister(&dbgfFuncDef,dbgfCallFunc); - iocshRegister(&dbpfFuncDef,dbpfCallFunc); - iocshRegister(&dbprFuncDef,dbprCallFunc); - iocshRegister(&dbtrFuncDef,dbtrCallFunc); - iocshRegister(&dbtgfFuncDef,dbtgfCallFunc); - iocshRegister(&dbtpfFuncDef,dbtpfCallFunc); - iocshRegister(&dbiorFuncDef,dbiorCallFunc); - iocshRegister(&dbhcrFuncDef,dbhcrCallFunc); - iocshRegister(&gftFuncDef,gftCallFunc); - iocshRegister(&pftFuncDef,pftCallFunc); - iocshRegister(&dbtpnFuncDef,dbtpnCallFunc); - iocshRegister(&dbNotifyDumpFuncDef,dbNotifyDumpCallFunc); - iocshRegister(&dbPutAttrFuncDef,dbPutAttrCallFunc); - iocshRegister(&tpnFuncDef,tpnCallFunc); - iocshRegister(&dblsrFuncDef,dblsrCallFunc); - iocshRegister(&dbLockShowLockedFuncDef,dbLockShowLockedCallFunc); - - iocshRegister(&scanOnceSetQueueSizeFuncDef,scanOnceSetQueueSizeCallFunc); - iocshRegister(&scanpplFuncDef,scanpplCallFunc); - iocshRegister(&scanpelFuncDef,scanpelCallFunc); - iocshRegister(&postEventFuncDef,postEventCallFunc); - iocshRegister(&scanpiolFuncDef,scanpiolCallFunc); - - iocshRegister(&callbackSetQueueSizeFuncDef,callbackSetQueueSizeCallFunc); - iocshRegister(&callbackParallelThreadsFuncDef,callbackParallelThreadsCallFunc); - - /* Needed before callback system is initialized */ - callbackParallelThreadsDefault = epicsThreadGetCPUs(); - - iocshRegister(&dbStateCreateFuncDef, dbStateCreateCallFunc); - iocshRegister(&dbStateSetFuncDef, dbStateSetCallFunc); - iocshRegister(&dbStateClearFuncDef, dbStateClearCallFunc); - iocshRegister(&dbStateShowFuncDef, dbStateShowCallFunc); - iocshRegister(&dbStateShowAllFuncDef, dbStateShowAllCallFunc); -} diff --git a/src/ioc/db/dbIocRegister.h b/src/ioc/db/dbIocRegister.h deleted file mode 100644 index 973009c5b..000000000 --- a/src/ioc/db/dbIocRegister.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_dbIocRegister_H -#define INC_dbIocRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void dbIocRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbIocRegister_H */ diff --git a/src/ioc/db/dbJLink.c b/src/ioc/db/dbJLink.c deleted file mode 100644 index b68432f6e..000000000 --- a/src/ioc/db/dbJLink.c +++ /dev/null @@ -1,540 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbJLink.c */ - -#include -#include - -#include "epicsAssert.h" -#include "dbmf.h" -#include "errlog.h" -#include "yajl_alloc.h" -#include "yajl_parse.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbCommon.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "dbLink.h" -#include "dbJLink.h" -#include "dbLock.h" -#include "dbStaticLib.h" -#include "link.h" - -#define IFDEBUG(n) if(parser->parse_debug) - -typedef struct parseContext { - jlink *pjlink; - jlink *product; - short dbfType; - short jsonDepth; - unsigned key_is_link:1; - unsigned parse_debug:1; - unsigned lset_debug:1; -} parseContext; - -#define CALL_OR_STOP(routine) !(routine) ? jlif_stop : (routine) - -static int dbjl_return(parseContext *parser, jlif_result result) { - jlink *pjlink = parser->pjlink; - - IFDEBUG(10) { - printf("dbjl_return(%s@%p, %d)\t", pjlink ? pjlink->pif->name : "", pjlink, result); - printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n", - parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link); - } - - if (result == jlif_stop && pjlink) { - jlink *parent; - - while ((parent = pjlink->parent)) { - pjlink->pif->free_jlink(pjlink); - pjlink = parent; - } - pjlink->pif->free_jlink(pjlink); - } - - return result; -} - -static int dbjl_value(parseContext *parser, jlif_result result) { - jlink *pjlink = parser->pjlink; - jlink *parent; - - IFDEBUG(10) { - printf("dbjl_value(%s@%p, %d)\t", pjlink ? pjlink->pif->name : "", pjlink, result); - printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n", - parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link); - } - - if (result == jlif_stop || pjlink->parseDepth > 0) - return dbjl_return(parser, result); - - parent = pjlink->parent; - if (!parent) { - parser->product = pjlink; - } else if (parent->pif->end_child) { - parent->pif->end_child(parent, pjlink); - } - pjlink->debug = 0; - - parser->pjlink = parent; - - IFDEBUG(8) - printf("dbjl_value: product = %p\n", pjlink); - - return jlif_continue; -} - -static int dbjl_null(void *ctx) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - - IFDEBUG(10) - printf("dbjl_null(%s@%p)\n", pjlink ? pjlink->pif->name : "", pjlink); - - assert(pjlink); - return dbjl_value(parser, - CALL_OR_STOP(pjlink->pif->parse_null)(pjlink)); -} - -static int dbjl_boolean(void *ctx, int val) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - - assert(pjlink); - return dbjl_value(parser, - CALL_OR_STOP(pjlink->pif->parse_boolean)(pjlink, val)); -} - -static int dbjl_integer(void *ctx, long num) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - - IFDEBUG(10) - printf("dbjl_integer(%s@%p, %ld)\n", - pjlink->pif->name, pjlink, num); - - assert(pjlink); - return dbjl_value(parser, - CALL_OR_STOP(pjlink->pif->parse_integer)(pjlink, num)); -} - -static int dbjl_double(void *ctx, double num) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - - IFDEBUG(10) - printf("dbjl_double(%s@%p, %g)\n", - pjlink->pif->name, pjlink, num); - - assert(pjlink); - return dbjl_value(parser, - CALL_OR_STOP(pjlink->pif->parse_double)(pjlink, num)); -} - -static int dbjl_string(void *ctx, const unsigned char *val, unsigned len) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - - IFDEBUG(10) - printf("dbjl_string(%s@%p, \"%.*s\")\n", - pjlink->pif->name, pjlink, len, val); - - assert(pjlink); - return dbjl_value(parser, - CALL_OR_STOP(pjlink->pif->parse_string)(pjlink, (const char *) val, len)); -} - -static int dbjl_start_map(void *ctx) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - int result; - - if (!pjlink) { - IFDEBUG(10) { - printf("dbjl_start_map(NULL)\t"); - printf(" jsonDepth=%d, parseDepth=00, key_is_link=%d\n", - parser->jsonDepth, parser->key_is_link); - } - - assert(parser->jsonDepth == 0); - parser->jsonDepth++; - parser->key_is_link = 1; - return jlif_continue; /* Opening '{' */ - } - - IFDEBUG(10) { - printf("dbjl_start_map(%s@%p)\t", pjlink ? pjlink->pif->name : "", pjlink); - printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n", - parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link); - } - - pjlink->parseDepth++; - parser->jsonDepth++; - - result = CALL_OR_STOP(pjlink->pif->parse_start_map)(pjlink); - if (result == jlif_key_child_link) { - parser->key_is_link = 1; - result = jlif_continue; - } - - IFDEBUG(10) - printf("dbjl_start_map -> %d\n", result); - - return dbjl_return(parser, result); -} - -static int dbjl_map_key(void *ctx, const unsigned char *key, unsigned len) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - char *link_name; - linkSup *linkSup; - jlif *pjlif; - - if (!parser->key_is_link) { - if (!pjlink) { - errlogPrintf("dbJLinkInit: Illegal second link key '%.*s'\n", - len, key); - return dbjl_return(parser, jlif_stop); - } - - IFDEBUG(10) { - printf("dbjl_map_key(%s@%p, \"%.*s\")\t", - pjlink->pif->name, pjlink, len, key); - printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n", - parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link); - } - - assert(pjlink->parseDepth > 0); - return dbjl_return(parser, - CALL_OR_STOP(pjlink->pif->parse_map_key)(pjlink, - (const char *) key, len)); - } - - IFDEBUG(10) { - printf("dbjl_map_key(NULL, \"%.*s\")\t", len, key); - printf(" jsonDepth=%d, parseDepth=00, key_is_link=%d\n", - parser->jsonDepth, parser->key_is_link); - } - - link_name = dbmfStrndup((const char *) key, len); - - linkSup = dbFindLinkSup(pdbbase, link_name); - if (!linkSup) { - errlogPrintf("dbJLinkInit: Link type '%s' not found\n", - link_name); - dbmfFree(link_name); - return dbjl_return(parser, jlif_stop); - } - - pjlif = linkSup->pjlif; - if (!pjlif) { - errlogPrintf("dbJLinkInit: Support for Link type '%s' not loaded\n", - link_name); - dbmfFree(link_name); - return dbjl_return(parser, jlif_stop); - } - - dbmfFree(link_name); - - pjlink = pjlif->alloc_jlink(parser->dbfType); - if (!pjlink) { - errlogPrintf("dbJLinkInit: Out of memory\n"); - return dbjl_return(parser, jlif_stop); - } - pjlink->pif = pjlif; - pjlink->parent = NULL; - pjlink->parseDepth = 0; - pjlink->debug = !!parser->lset_debug; - - if (parser->pjlink) { - /* We're starting a child link, save its parent */ - pjlink->parent = parser->pjlink; - } - parser->pjlink = pjlink; - parser->key_is_link = 0; - - IFDEBUG(8) - printf("dbjl_map_key: New %s@%p\n", pjlink ? pjlink->pif->name : "", pjlink); - - return jlif_continue; -} - -static int dbjl_end_map(void *ctx) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - jlif_result result; - - IFDEBUG(10) { - printf("dbjl_end_map(%s@%p)\t", - pjlink ? pjlink->pif->name : "NULL", pjlink); - printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n", - parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, - parser->key_is_link); - } - - parser->jsonDepth--; - if (pjlink) { - pjlink->parseDepth--; - - result = dbjl_value(parser, - CALL_OR_STOP(pjlink->pif->parse_end_map)(pjlink)); - } - else { - result = jlif_continue; - } - return result; -} - -static int dbjl_start_array(void *ctx) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - - IFDEBUG(10) { - printf("dbjl_start_array(%s@%p)\t", pjlink ? pjlink->pif->name : "", pjlink); - printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n", - parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link); - } - - assert(pjlink); - pjlink->parseDepth++; - parser->jsonDepth++; - - return dbjl_return(parser, - CALL_OR_STOP(pjlink->pif->parse_start_array)(pjlink)); -} - -static int dbjl_end_array(void *ctx) { - parseContext *parser = (parseContext *) ctx; - jlink *pjlink = parser->pjlink; - - IFDEBUG(10) { - printf("dbjl_end_array(%s@%p)\t", pjlink ? pjlink->pif->name : "", pjlink); - printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n", - parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link); - } - - assert(pjlink); - pjlink->parseDepth--; - parser->jsonDepth--; - - return dbjl_value(parser, - CALL_OR_STOP(pjlink->pif->parse_end_array)(pjlink)); -} - - -static yajl_callbacks dbjl_callbacks = { - dbjl_null, dbjl_boolean, dbjl_integer, dbjl_double, NULL, dbjl_string, - dbjl_start_map, dbjl_map_key, dbjl_end_map, dbjl_start_array, dbjl_end_array -}; - -static const yajl_parser_config dbjl_config = - { 0, 0 }; /* allowComments = NO, checkUTF8 = NO */ - -long dbJLinkParse(const char *json, size_t jlen, short dbfType, - jlink **ppjlink, unsigned opts) -{ - parseContext context, *parser = &context; - yajl_alloc_funcs dbjl_allocs; - yajl_handle yh; - yajl_status ys; - long status; - - parser->pjlink = NULL; - parser->product = NULL; - parser->dbfType = dbfType; - parser->jsonDepth = 0; - parser->key_is_link = 0; - parser->parse_debug = !!(opts&LINK_DEBUG_JPARSE); - parser->lset_debug = !!(opts&LINK_DEBUG_LSET); - - IFDEBUG(10) - printf("dbJLinkInit(\"%.*s\", %d, %p)\n", - (int) jlen, json, dbfType, ppjlink); - - IFDEBUG(10) - printf("dbJLinkInit: jsonDepth=%d, key_is_link=%d\n", - parser->jsonDepth, parser->key_is_link); - - yajl_set_default_alloc_funcs(&dbjl_allocs); - yh = yajl_alloc(&dbjl_callbacks, &dbjl_config, &dbjl_allocs, parser); - if (!yh) - return S_db_noMemory; - - ys = yajl_parse(yh, (const unsigned char *) json, (unsigned) jlen); - if (ys == yajl_status_insufficient_data) - ys = yajl_parse_complete(yh); - - switch (ys) { - unsigned char *err; - - case yajl_status_ok: - assert(parser->jsonDepth == 0); - *ppjlink = parser->product; - status = 0; - break; - - case yajl_status_error: - err = yajl_get_error(yh, 1, (const unsigned char *) json, (unsigned) jlen); - errlogPrintf("dbJLinkInit: %s\n", err); - yajl_free_error(yh, err); - dbJLinkFree(parser->pjlink); - /* fall through */ - default: - status = S_db_badField; - } - - yajl_free(yh); - return status; -} - -long dbJLinkInit(struct link *plink) -{ - jlink *pjlink; - - assert(plink); - pjlink = plink->value.json.jlink; - - if (pjlink) - plink->lset = pjlink->pif->get_lset(pjlink); - - dbLinkOpen(plink); - return 0; -} - -void dbJLinkFree(jlink *pjlink) -{ - if (pjlink) - pjlink->pif->free_jlink(pjlink); -} - -void dbJLinkReport(jlink *pjlink, int level, int indent) { - if (pjlink && pjlink->pif->report) - pjlink->pif->report(pjlink, level, indent); -} - -long dbJLinkMapChildren(struct link *plink, jlink_map_fn rtn, void *ctx) -{ - jlink *pjlink; - long status; - - if (!plink || plink->type != JSON_LINK) - return 0; - - pjlink = plink->value.json.jlink; - if (!pjlink) - return 0; - - status = rtn(pjlink, ctx); - if (!status && pjlink->pif->map_children) - status = pjlink->pif->map_children(pjlink, rtn, ctx); - - return status; -} - -long dbjlr(const char *recname, int level) -{ - DBENTRY dbentry; - DBENTRY * const pdbentry = &dbentry; - long status; - - if (!recname || recname[0] == '\0' || !strcmp(recname, "*")) { - recname = NULL; - printf("JSON links in all records\n\n"); - } - else - printf("JSON links in record '%s'\n\n", recname); - - dbInitEntry(pdbbase, pdbentry); - for (status = dbFirstRecordType(pdbentry); - status == 0; - status = dbNextRecordType(pdbentry)) { - for (status = dbFirstRecord(pdbentry); - status == 0; - status = dbNextRecord(pdbentry)) { - dbRecordType *pdbRecordType = pdbentry->precordType; - dbCommon *precord = pdbentry->precnode->precord; - char *prec = (char *) precord; - int i; - - if (recname && strcmp(recname, dbGetRecordName(pdbentry))) - continue; - if (dbIsAlias(pdbentry)) - continue; - - printf(" %s record '%s':\n", pdbRecordType->name, precord->name); - - dbScanLock(precord); - for (i = 0; i < pdbRecordType->no_links; i++) { - int idx = pdbRecordType->link_ind[i]; - dbFldDes *pdbFldDes = pdbRecordType->papFldDes[idx]; - DBLINK *plink = (DBLINK *) (prec + pdbFldDes->offset); - - if (plink->type != JSON_LINK) - continue; - if (!dbLinkIsDefined(plink)) - continue; - - printf(" Link field '%s':\n", pdbFldDes->name); - dbJLinkReport(plink->value.json.jlink, level, 6); - } - dbScanUnlock(precord); - if (recname) - goto done; - } - } -done: - return 0; -} - -long dbJLinkMapAll(char *recname, jlink_map_fn rtn, void *ctx) -{ - DBENTRY dbentry; - DBENTRY * const pdbentry = &dbentry; - long status; - - if (recname && (recname[0] = '\0' || !strcmp(recname, "*"))) - recname = NULL; - - dbInitEntry(pdbbase, pdbentry); - for (status = dbFirstRecordType(pdbentry); - status == 0; - status = dbNextRecordType(pdbentry)) { - for (status = dbFirstRecord(pdbentry); - status == 0; - status = dbNextRecord(pdbentry)) { - dbRecordType *pdbRecordType = pdbentry->precordType; - dbCommon *precord = pdbentry->precnode->precord; - char *prec = (char *) precord; - int i; - - if (recname && strcmp(recname, dbGetRecordName(pdbentry))) - continue; - if (dbIsAlias(pdbentry)) - continue; - - dbScanLock(precord); - for (i = 0; i < pdbRecordType->no_links; i++) { - int idx = pdbRecordType->link_ind[i]; - dbFldDes *pdbFldDes = pdbRecordType->papFldDes[idx]; - DBLINK *plink = (DBLINK *) (prec + pdbFldDes->offset); - - status = dbJLinkMapChildren(plink, rtn, ctx); - if (status) - goto unlock; - } -unlock: - dbScanUnlock(precord); - if (status || recname) - goto done; - } - } -done: - return status; -} diff --git a/src/ioc/db/dbJLink.h b/src/ioc/db/dbJLink.h deleted file mode 100644 index 61b59670b..000000000 --- a/src/ioc/db/dbJLink.h +++ /dev/null @@ -1,133 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbJLink.h */ - -#ifndef INC_dbJLink_H -#define INC_dbJLink_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - jlif_stop = 0, - jlif_continue = 1 -} jlif_result; - -typedef enum { - jlif_key_stop = jlif_stop, - jlif_key_continue = jlif_continue, - jlif_key_child_link -} jlif_key_result; - -struct link; -struct lset; -struct jlif; - -typedef struct jlink { - struct jlif *pif; /* Link methods */ - struct jlink *parent; /* NULL for top-level links */ - int parseDepth; /* Used by parser, unused afterwards */ - unsigned debug:1; /* set by caller of jlif operations to request debug output to console */ - /* Link types extend or embed this structure for private storage */ -} jlink; - -typedef long (*jlink_map_fn)(jlink *, void *ctx); - -typedef struct jlif { - /* Optional parser methods below given as NULL are equivalent to - * providing a routine that always returns jlif_stop, meaning that - * this JSON construct is not allowed at this point in the parse. - */ - - const char *name; - /* Name for the link type, used in link value */ - - jlink* (*alloc_jlink)(short dbfType); - /* Required, allocate new link structure */ - - void (*free_jlink)(jlink *); - /* Required, release all resources allocated for link */ - - jlif_result (*parse_null)(jlink *); - /* Optional, parser saw a null value */ - - jlif_result (*parse_boolean)(jlink *, int val); - /* Optional, parser saw a boolean value */ - - jlif_result (*parse_integer)(jlink *, long long num); - /* Optional, parser saw an integer value */ - - jlif_result (*parse_double)(jlink *, double num); - /* Optional, parser saw a double value */ - - jlif_result (*parse_string)(jlink *, const char *val, size_t len); - /* Optional, parser saw a string value */ - - jlif_key_result (*parse_start_map)(jlink *); - /* Optional, parser saw an open-brace '{'. Return jlif_key_child_link - * to expect a child link next (extra key/value pairs may follow). - */ - - jlif_result (*parse_map_key)(jlink *, const char *key, size_t len); - /* Optional, parser saw a map key */ - - jlif_result (*parse_end_map)(jlink *); - /* Optional, parser saw a close-brace '}' */ - - jlif_result (*parse_start_array)(jlink *); - /* Optional, parser saw an open-bracket */ - - jlif_result (*parse_end_array)(jlink *); - /* Optional, parser saw a close-bracket */ - - void (*end_child)(jlink *parent, jlink *child); - /* Optional, called with pointer to the new child link after - * parse_start_map() returned jlif_key_child_link */ - - struct lset* (*get_lset)(const jlink *); - /* Required, return lset for this link instance */ - - void (*report)(const jlink *, int level, int indent); - /* Optional, print status information about this link instance, then - * if (level > 0) print a link identifier (at indent+2) and call - * dbJLinkReport(child, level-1, indent+4) - * for each child. - */ - - long (*map_children)(jlink *, jlink_map_fn rtn, void *ctx); - /* Optional, call dbJLinkMapChildren() on all embedded links. - * Stop immediately and return status if non-zero. - */ - - /* Link types must NOT extend this table with their own routines, - * this space is reserved for extensions to the jlink interface. - */ -} jlif; - -epicsShareFunc long dbJLinkParse(const char *json, size_t len, short dbfType, - jlink **ppjlink, unsigned opts); -epicsShareFunc long dbJLinkInit(struct link *plink); - -epicsShareFunc void dbJLinkFree(jlink *); -epicsShareFunc void dbJLinkReport(jlink *, int level, int indent); - -epicsShareFunc long dbJLinkMapChildren(struct link *, - jlink_map_fn rtn, void *ctx); - -epicsShareFunc long dbjlr(const char *recname, int level); -epicsShareFunc long dbJLinkMapAll(char *recname, jlink_map_fn rtn, void *ctx); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbJLink_H */ - diff --git a/src/ioc/db/dbLink.c b/src/ioc/db/dbLink.c deleted file mode 100644 index 9279b91fb..000000000 --- a/src/ioc/db/dbLink.c +++ /dev/null @@ -1,473 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - \*************************************************************************/ -/* dbLink.c */ -/* - * Original Authors: Bob Dalesio, Marty Kraimer - * Current Author: Andrew Johnson - */ - -#include -#include -#include -#include -#include - -#include "alarm.h" -#include "cvtFast.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsTime.h" -#include "errlog.h" - -#include "caeventmask.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbCa.h" -#include "dbCommon.h" -#include "dbConstLink.h" -#include "dbDbLink.h" -#include "db_field_log.h" -#include "dbFldTypes.h" -#include "dbJLink.h" -#include "dbLink.h" -#include "dbLock.h" -#include "dbScan.h" -#include "dbStaticLib.h" -#include "devSup.h" -#include "link.h" -#include "recGbl.h" -#include "recSup.h" -#include "special.h" - -/* How to identify links in error messages */ -static const char * link_field_name(const struct link *plink) -{ - const struct dbCommon *precord = plink->precord; - const dbRecordType *pdbRecordType = precord->rdes; - dbFldDes * const *papFldDes = pdbRecordType->papFldDes; - const short *link_ind = pdbRecordType->link_ind; - int i; - - for (i = 0; i < pdbRecordType->no_links; i++) { - const dbFldDes *pdbFldDes = papFldDes[link_ind[i]]; - - if (plink == (DBLINK *)((char *)precord + pdbFldDes->offset)) - return pdbFldDes->name; - } - return "????"; -} - - -/***************************** Generic Link API *****************************/ - -void dbInitLink(struct link *plink, short dbfType) -{ - struct dbCommon *precord = plink->precord; - - /* Only initialize link once */ - if (plink->flags & DBLINK_FLAG_INITIALIZED) - return; - else - plink->flags |= DBLINK_FLAG_INITIALIZED; - - if (plink->type == CONSTANT) { - dbConstInitLink(plink); - return; - } - - if (plink->type == JSON_LINK) { - dbJLinkInit(plink); - return; - } - - if (plink->type != PV_LINK) - return; - - if (plink == &precord->tsel) - recGblTSELwasModified(plink); - - if (!(plink->value.pv_link.pvlMask & (pvlOptCA | pvlOptCP | pvlOptCPP))) { - /* Make it a DB link if possible */ - if (!dbDbInitLink(plink, dbfType)) - return; - } - - /* Make it a CA link */ - if (dbfType == DBF_INLINK) - plink->value.pv_link.pvlMask |= pvlOptInpNative; - - dbCaAddLink(NULL, plink, dbfType); - if (dbfType == DBF_FWDLINK) { - char *pperiod = strrchr(plink->value.pv_link.pvname, '.'); - - if (pperiod && strstr(pperiod, "PROC")) { - plink->value.pv_link.pvlMask |= pvlOptFWD; - } - else { - errlogPrintf("Forward-link uses Channel Access " - "without pointing to PROC field\n" - " %s.%s => %s\n", - precord->name, link_field_name(plink), - plink->value.pv_link.pvname); - } - } -} - -void dbAddLink(struct dbLocker *locker, struct link *plink, short dbfType, - DBADDR *ptarget) -{ - struct dbCommon *precord = plink->precord; - - if (plink->type == CONSTANT) { - dbConstAddLink(plink); - return; - } - - if (plink->type == JSON_LINK) { - /* - * FIXME: Can't create DB links as dbJLink types yet, - * dbLock.c doesn't have any way to find/track them. - */ - dbJLinkInit(plink); - return; - } - - if (plink->type != PV_LINK) - return; - - if (plink == &precord->tsel) - recGblTSELwasModified(plink); - - if (ptarget) { - /* It's a DB link */ - dbDbAddLink(locker, plink, dbfType, ptarget); - return; - } - - /* Make it a CA link */ - if (dbfType == DBF_INLINK) - plink->value.pv_link.pvlMask |= pvlOptInpNative; - - dbCaAddLink(locker, plink, dbfType); - if (dbfType == DBF_FWDLINK) { - char *pperiod = strrchr(plink->value.pv_link.pvname, '.'); - - if (pperiod && strstr(pperiod, "PROC")) - plink->value.pv_link.pvlMask |= pvlOptFWD; - } -} - -void dbLinkOpen(struct link *plink) -{ - lset *plset = plink->lset; - - if (plset && plset->openLink) - plset->openLink(plink); -} - -void dbRemoveLink(struct dbLocker *locker, struct link *plink) -{ - lset *plset = plink->lset; - - if (plset) { - if (plset->removeLink) - plset->removeLink(locker, plink); - plink->lset = NULL; - } - if (plink->type == JSON_LINK) - plink->value.json.jlink = NULL; -} - -int dbLinkIsDefined(const struct link *plink) -{ - return (plink->lset != 0); -} - -int dbLinkIsConstant(const struct link *plink) -{ - lset *plset = plink->lset; - - return !plset || plset->isConstant; -} - -int dbLinkIsVolatile(const struct link *plink) -{ - lset *plset = plink->lset; - - return plset && plset->isVolatile; -} - -long dbLoadLink(struct link *plink, short dbrType, void *pbuffer) -{ - lset *plset = plink->lset; - - if (plset && plset->loadScalar) - return plset->loadScalar(plink, dbrType, pbuffer); - - return S_db_noLSET; -} - -long dbLoadLinkLS(struct link *plink, char *pbuffer, epicsUInt32 size, - epicsUInt32 *plen) -{ - lset *plset = plink->lset; - - if (plset && plset->loadLS) - return plset->loadLS(plink, pbuffer, size, plen); - - return S_db_noLSET; -} - -long dbLoadLinkArray(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest) -{ - lset *plset = plink->lset; - - if (plset && plset->loadArray) - return plset->loadArray(plink, dbrType, pbuffer, pnRequest); - - return S_db_noLSET; -} - -int dbIsLinkConnected(const struct link *plink) -{ - lset *plset = plink->lset; - - if (!plset || !plset->isConnected) - return FALSE; - - return plset->isConnected(plink); -} - -int dbGetLinkDBFtype(const struct link *plink) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getDBFtype) - return -1; - - return plset->getDBFtype(plink); -} - -long dbGetNelements(const struct link *plink, long *nelements) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getElements) - return S_db_noLSET; - - return plset->getElements(plink, nelements); -} - -long dbGetLink(struct link *plink, short dbrType, void *pbuffer, - long *poptions, long *pnRequest) -{ - struct dbCommon *precord = plink->precord; - lset *plset = plink->lset; - long status; - - if (poptions && *poptions) { - printf("dbGetLink: Use of poptions no longer supported\n"); - *poptions = 0; - } - - if (!plset || !plset->getValue) - return -1; - - status = plset->getValue(plink, dbrType, pbuffer, pnRequest); - if (status) - recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM); - return status; -} - -long dbGetControlLimits(const struct link *plink, double *low, double *high) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getControlLimits) - return S_db_noLSET; - - return plset->getControlLimits(plink, low, high); -} - -long dbGetGraphicLimits(const struct link *plink, double *low, double *high) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getGraphicLimits) - return S_db_noLSET; - - return plset->getGraphicLimits(plink, low, high); -} - -long dbGetAlarmLimits(const struct link *plink, double *lolo, double *low, - double *high, double *hihi) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getAlarmLimits) - return S_db_noLSET; - - return plset->getAlarmLimits(plink, lolo, low, high, hihi); -} - -long dbGetPrecision(const struct link *plink, short *precision) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getPrecision) - return S_db_noLSET; - - return plset->getPrecision(plink, precision); -} - -long dbGetUnits(const struct link *plink, char *units, int unitsSize) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getUnits) - return S_db_noLSET; - - return plset->getUnits(plink, units, unitsSize); -} - -long dbGetAlarm(const struct link *plink, epicsEnum16 *status, - epicsEnum16 *severity) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getAlarm) - return S_db_noLSET; - - return plset->getAlarm(plink, status, severity); -} - -long dbGetTimeStamp(const struct link *plink, epicsTimeStamp *pstamp) -{ - lset *plset = plink->lset; - - if (!plset || !plset->getTimeStamp) - return S_db_noLSET; - - return plset->getTimeStamp(plink, pstamp); -} - -long dbPutLink(struct link *plink, short dbrType, const void *pbuffer, - long nRequest) -{ - lset *plset = plink->lset; - long status; - - if (!plset || !plset->putValue) - return S_db_noLSET; - - status = plset->putValue(plink, dbrType, pbuffer, nRequest); - if (status) { - struct dbCommon *precord = plink->precord; - - recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM); - } - return status; -} - -void dbLinkAsyncComplete(struct link *plink) -{ - dbCommon *pdbCommon = plink->precord; - - dbScanLock(pdbCommon); - pdbCommon->rset->process(pdbCommon); - dbScanUnlock(pdbCommon); -} - -long dbPutLinkAsync(struct link *plink, short dbrType, const void *pbuffer, - long nRequest) -{ - lset *plset = plink->lset; - long status; - - if (!plset || !plset->putAsync) - return S_db_noLSET; - - status = plset->putAsync(plink, dbrType, pbuffer, nRequest); - if (status) { - struct dbCommon *precord = plink->precord; - - recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM); - } - return status; -} - -void dbScanFwdLink(struct link *plink) -{ - lset *plset = plink->lset; - - if (plset && plset->scanForward) - plset->scanForward(plink); -} - -long dbLinkDoLocked(struct link *plink, dbLinkUserCallback rtn, - void *priv) -{ - lset *plset = plink->lset; - - if (!rtn || !plset || !plset->doLocked) - return S_db_noLSET; - - return plset->doLocked(plink, rtn, priv); -} - - -/* Helper functions for long string support */ - -long dbGetLinkLS(struct link *plink, char *pbuffer, epicsUInt32 size, - epicsUInt32 *plen) -{ - int dtyp = dbGetLinkDBFtype(plink); - long len = size; - long status; - - if (dtyp < 0) /* Not connected */ - return 0; - - if (dtyp == DBR_CHAR || dtyp == DBF_UCHAR) { - status = dbGetLink(plink, dtyp, pbuffer, 0, &len); - } - else if (size >= MAX_STRING_SIZE) - status = dbGetLink(plink, DBR_STRING, pbuffer, 0, 0); - else { - /* pbuffer is too small to fetch using DBR_STRING */ - char tmp[MAX_STRING_SIZE]; - - status = dbGetLink(plink, DBR_STRING, tmp, 0, 0); - if (!status) - strncpy(pbuffer, tmp, len - 1); - } - if (!status) { - pbuffer[--len] = 0; - *plen = (epicsUInt32) strlen(pbuffer) + 1; - } - return status; -} - -long dbPutLinkLS(struct link *plink, char *pbuffer, epicsUInt32 len) -{ - int dtyp = dbGetLinkDBFtype(plink); - - if (dtyp < 0) - return 0; /* Not connected */ - - if (dtyp == DBR_CHAR || dtyp == DBF_UCHAR) - return dbPutLink(plink, dtyp, pbuffer, len); - - return dbPutLink(plink, DBR_STRING, pbuffer, 1); -} - diff --git a/src/ioc/db/dbLink.h b/src/ioc/db/dbLink.h deleted file mode 100644 index ad4ac2f45..000000000 --- a/src/ioc/db/dbLink.h +++ /dev/null @@ -1,139 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 The UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbLink.h - * - * Created on: Mar 21, 2010 - * Author: Andrew Johnson - */ - -#ifndef INC_dbLink_H -#define INC_dbLink_H - -#include "link.h" -#include "shareLib.h" -#include "epicsTypes.h" -#include "epicsTime.h" -#include "dbAddr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct dbLocker; - -typedef long (*dbLinkUserCallback)(struct link *plink, void *priv); - -typedef struct lset { - /* Characteristics of the link type */ - const unsigned isConstant:1; - const unsigned isVolatile:1; - - /* Activation */ - void (*openLink)(struct link *plink); - - /* Destructor */ - void (*removeLink)(struct dbLocker *locker, struct link *plink); - - /* Const init, data type hinting */ - long (*loadScalar)(struct link *plink, short dbrType, void *pbuffer); - long (*loadLS)(struct link *plink, char *pbuffer, epicsUInt32 size, - epicsUInt32 *plen); - long (*loadArray)(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest); - - /* Metadata */ - int (*isConnected)(const struct link *plink); - int (*getDBFtype)(const struct link *plink); - long (*getElements)(const struct link *plink, long *nelements); - - /* Get data */ - long (*getValue)(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest); - long (*getControlLimits)(const struct link *plink, double *lo, double *hi); - long (*getGraphicLimits)(const struct link *plink, double *lo, double *hi); - long (*getAlarmLimits)(const struct link *plink, double *lolo, double *lo, - double *hi, double *hihi); - long (*getPrecision)(const struct link *plink, short *precision); - long (*getUnits)(const struct link *plink, char *units, int unitsSize); - long (*getAlarm)(const struct link *plink, epicsEnum16 *status, - epicsEnum16 *severity); - long (*getTimeStamp)(const struct link *plink, epicsTimeStamp *pstamp); - - /* Put data */ - long (*putValue)(struct link *plink, short dbrType, - const void *pbuffer, long nRequest); - long (*putAsync)(struct link *plink, short dbrType, - const void *pbuffer, long nRequest); - - /* Process */ - void (*scanForward)(struct link *plink); - - /* Atomicity */ - long (*doLocked)(struct link *plink, dbLinkUserCallback rtn, void *priv); -} lset; - -#define dbGetSevr(link, sevr) \ - dbGetAlarm(link, NULL, sevr) - -epicsShareFunc void dbInitLink(struct link *plink, short dbfType); -epicsShareFunc void dbAddLink(struct dbLocker *locker, struct link *plink, - short dbfType, DBADDR *ptarget); - -epicsShareFunc void dbLinkOpen(struct link *plink); -epicsShareFunc void dbRemoveLink(struct dbLocker *locker, struct link *plink); - -epicsShareFunc int dbLinkIsDefined(const struct link *plink); /* 0 or 1 */ -epicsShareFunc int dbLinkIsConstant(const struct link *plink); /* 0 or 1 */ -epicsShareFunc int dbLinkIsVolatile(const struct link *plink); /* 0 or 1 */ - -epicsShareFunc long dbLoadLink(struct link *plink, short dbrType, - void *pbuffer); -epicsShareFunc long dbLoadLinkArray(struct link *, short dbrType, void *pbuffer, - long *pnRequest); - -epicsShareFunc long dbGetNelements(const struct link *plink, long *nelements); -epicsShareFunc int dbIsLinkConnected(const struct link *plink); /* 0 or 1 */ -epicsShareFunc int dbGetLinkDBFtype(const struct link *plink); -epicsShareFunc long dbGetLink(struct link *, short dbrType, void *pbuffer, - long *options, long *nRequest); -epicsShareFunc long dbGetControlLimits(const struct link *plink, double *low, - double *high); -epicsShareFunc long dbGetGraphicLimits(const struct link *plink, double *low, - double *high); -epicsShareFunc long dbGetAlarmLimits(const struct link *plink, double *lolo, - double *low, double *high, double *hihi); -epicsShareFunc long dbGetPrecision(const struct link *plink, short *precision); -epicsShareFunc long dbGetUnits(const struct link *plink, char *units, - int unitsSize); -epicsShareFunc long dbGetAlarm(const struct link *plink, epicsEnum16 *status, - epicsEnum16 *severity); -epicsShareFunc long dbGetTimeStamp(const struct link *plink, - epicsTimeStamp *pstamp); -epicsShareFunc long dbPutLink(struct link *plink, short dbrType, - const void *pbuffer, long nRequest); -epicsShareFunc void dbLinkAsyncComplete(struct link *plink); -epicsShareFunc long dbPutLinkAsync(struct link *plink, short dbrType, - const void *pbuffer, long nRequest); -epicsShareFunc void dbScanFwdLink(struct link *plink); - -epicsShareFunc long dbLinkDoLocked(struct link *plink, dbLinkUserCallback rtn, - void *priv); - -epicsShareFunc long dbLoadLinkLS(struct link *plink, char *pbuffer, - epicsUInt32 size, epicsUInt32 *plen); -epicsShareFunc long dbGetLinkLS(struct link *plink, char *pbuffer, - epicsUInt32 buffer_size, epicsUInt32 *plen); -epicsShareFunc long dbPutLinkLS(struct link *plink, char *pbuffer, - epicsUInt32 len); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbLink_H */ diff --git a/src/ioc/db/dbLock.c b/src/ioc/db/dbLock.c deleted file mode 100644 index 8df755b2c..000000000 --- a/src/ioc/db/dbLock.c +++ /dev/null @@ -1,990 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include - -#include "cantProceed.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsAssert.h" -#include "epicsAtomic.h" -#include "epicsMutex.h" -#include "epicsPrint.h" -#include "epicsSpin.h" -#include "epicsStdio.h" -#include "epicsThread.h" -#include "errMdef.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbLink.h" -#include "dbCommon.h" -#include "dbFldTypes.h" -#include "dbLockPvt.h" -#include "dbStaticLib.h" -#include "link.h" - -typedef struct dbScanLockNode dbScanLockNode; - -static epicsThreadOnceId dbLockOnceInit = EPICS_THREAD_ONCE_INIT; - -static ELLLIST lockSetsActive; /* in use */ -#ifndef LOCKSET_NOFREE -static ELLLIST lockSetsFree; /* free list */ -#endif - -/* Guard the global list */ -static epicsMutexId lockSetsGuard; - -#ifndef LOCKSET_NOCNT -/* Counter which we increment whenever - * any lockRecord::plockSet is changed. - * An optimization to avoid checking lockSet - * associations when no links have changed. - */ -static size_t recomputeCnt; -#endif - -/*private routines */ -static void dbLockOnce(void* ignore) -{ - lockSetsGuard = epicsMutexMustCreate(); -} - -/* global ID number assigned to each lockSet on creation. - * When the free-list is in use will never exceed - * the number of records +1. - * Without the free-list it can roll over, potentially - * leading to duplicate IDs. - */ -static size_t next_id = 1; - -static lockSet* makeSet(void) -{ - lockSet *ls; - int iref; - epicsMutexMustLock(lockSetsGuard); -#ifndef LOCKSET_NOFREE - ls = (lockSet*)ellGet(&lockSetsFree); - if(!ls) { - epicsMutexUnlock(lockSetsGuard); -#endif - - ls=dbCalloc(1,sizeof(*ls)); - ellInit(&ls->lockRecordList); - ls->lock = epicsMutexMustCreate(); - ls->id = epicsAtomicIncrSizeT(&next_id); - -#ifndef LOCKSET_NOFREE - epicsMutexMustLock(lockSetsGuard); - } -#endif - /* the initial reference for the first lockRecord */ - iref = epicsAtomicIncrIntT(&ls->refcount); - ellAdd(&lockSetsActive, &ls->node); - epicsMutexUnlock(lockSetsGuard); - - assert(ls->id>0); - assert(iref>0); - assert(ellCount(&ls->lockRecordList)==0); - - return ls; -} - -unsigned long dbLockGetRefs(struct dbCommon* prec) -{ - return (unsigned long)epicsAtomicGetIntT(&prec->lset->plockSet->refcount); -} - -unsigned long dbLockCountSets(void) -{ - unsigned long count; - epicsMutexMustLock(lockSetsGuard); - count = (unsigned long)ellCount(&lockSetsActive); - epicsMutexUnlock(lockSetsGuard); - return count; -} - -/* caller must lock accessLock.*/ -void dbLockIncRef(lockSet* ls) -{ - int cnt = epicsAtomicIncrIntT(&ls->refcount); - if(cnt<=1) { - errlogPrintf("dbLockIncRef(%p) on dead lockSet. refs: %d\n", ls, cnt); - cantProceed(NULL); - } -} - -/* caller must lock accessLock. - * lockSet must *not* be locked - */ -void dbLockDecRef(lockSet *ls) -{ - int cnt = epicsAtomicDecrIntT(&ls->refcount); - assert(cnt>=0); - - if(cnt) - return; - - /* lockSet is unused and will be free'd */ - - /* not necessary as no one else (should) hold a reference, - * but lock anyway to quiet valgrind - */ - epicsMutexMustLock(ls->lock); - - if(ellCount(&ls->lockRecordList)!=0) { - errlogPrintf("dbLockDecRef(%p) would free lockSet with %d records\n", - ls, ellCount(&ls->lockRecordList)); - cantProceed(NULL); - } - - epicsMutexUnlock(ls->lock); - - epicsMutexMustLock(lockSetsGuard); - ellDelete(&lockSetsActive, &ls->node); -#ifndef LOCKSET_NOFREE - ellAdd(&lockSetsFree, &ls->node); -#else - epicsMutexDestroy(ls->lock); - memset(ls, 0, sizeof(*ls)); /* paranoia */ - free(ls); -#endif - epicsMutexUnlock(lockSetsGuard); -} - -lockSet* dbLockGetRef(lockRecord *lr) -{ - lockSet *ls; - epicsSpinLock(lr->spin); - ls = lr->plockSet; - dbLockIncRef(ls); - epicsSpinUnlock(lr->spin); - return ls; -} - -unsigned long dbLockGetLockId(dbCommon *precord) -{ - unsigned long id=0; - epicsSpinLock(precord->lset->spin); - id = precord->lset->plockSet->id; - epicsSpinUnlock(precord->lset->spin); - return id; -} - -void dbScanLock(dbCommon *precord) -{ - int cnt; - lockRecord * const lr = precord->lset; - lockSet *ls; - - assert(lr); - - ls = dbLockGetRef(lr); - assert(epicsAtomicGetIntT(&ls->refcount)>0); - -retry: - epicsMutexMustLock(ls->lock); - - epicsSpinLock(lr->spin); - if(ls!=lr->plockSet) { - /* oops, collided with recompute. - * take a reference to the new lockSet. - */ - lockSet *ls2 = lr->plockSet; - int newcnt = epicsAtomicIncrIntT(&ls2->refcount); - assert(newcnt>=2); /* at least lockRecord and us */ - epicsSpinUnlock(lr->spin); - - epicsMutexUnlock(ls->lock); - dbLockDecRef(ls); - - ls = ls2; - goto retry; - } - epicsSpinUnlock(lr->spin); - - /* Release reference taken within this - * function. The count will *never* fall to zero - * as the lockRecords can't be changed while - * we hold the lock. - */ - cnt = epicsAtomicDecrIntT(&ls->refcount); - assert(cnt>0); - -#ifdef LOCKSET_DEBUG - if(ls->owner) { - assert(ls->owner==epicsThreadGetIdSelf()); - assert(ls->ownercount>=1); - ls->ownercount++; - } else { - assert(ls->ownercount==0); - ls->owner = epicsThreadGetIdSelf(); - ls->ownercount = 1; - } -#endif -} - -void dbScanUnlock(dbCommon *precord) -{ - lockSet *ls = precord->lset->plockSet; - dbLockIncRef(ls); -#ifdef LOCKSET_DEBUG - assert(ls->owner==epicsThreadGetIdSelf()); - assert(ls->ownercount>=1); - ls->ownercount--; - if(ls->ownercount==0) - ls->owner = NULL; -#endif - epicsMutexUnlock(ls->lock); - dbLockDecRef(ls); -} - -static -int lrrcompare(const void *rawA, const void *rawB) -{ - const lockRecordRef *refA=rawA, *refB=rawB; - const lockSet *A=refA->plockSet, *B=refB->plockSet; - if(!A && !B) - return 0; /* NULL == NULL */ - else if(!A) - return 1; /* NULL > !NULL */ - else if(!B) - return -1; /* !NULL < NULL */ - else if(A < B) - return -1; - else if(A > B) - return 1; - else - return 0; -} - -/* Call w/ update=1 before locking to update cached lockSet entries. - * Call w/ update=0 after locking to verify that lockRecord weren't updated - */ -static -int dbLockUpdateRefs(dbLocker *locker, int update) -{ - int changed = 0; - size_t i, nlock = locker->maxrefs; - -#ifndef LOCKSET_NOCNT - const size_t recomp = epicsAtomicGetSizeT(&recomputeCnt); - if(locker->recomp!=recomp) { -#endif - /* some lockset recompute happened. - * must re-check our references. - */ - - for(i=0; irefs[i]; - lockSet *oldref = NULL; - if(!ref->plr) { /* this lockRecord slot not used */ - assert(!ref->plockSet); - continue; - } - - epicsSpinLock(ref->plr->spin); - if(ref->plockSet!=ref->plr->plockSet) { - changed = 1; - if(update) { - /* exchange saved lockSet reference */ - oldref = ref->plockSet; /* will be NULL on first iteration */ - ref->plockSet = ref->plr->plockSet; - dbLockIncRef(ref->plockSet); - } - } - epicsSpinUnlock(ref->plr->spin); - if(oldref) - dbLockDecRef(oldref); - if(!update && changed) - return changed; - } -#ifndef LOCKSET_NOCNT - /* Use the value captured before we started. - * If it has changed in the intrim we will catch this later - * during the update==0 pass (which triggers a re-try) - */ - if(update) - locker->recomp = recomp; - } -#endif - - if(changed && update) { - qsort(locker->refs, nlock, sizeof(lockRecordRef), - &lrrcompare); - } - return changed; -} - -void dbLockerPrepare(struct dbLocker *locker, - struct dbCommon * const *precs, - size_t nrecs) -{ - size_t i; - locker->maxrefs = nrecs; - /* intentionally spoil the recomp count to ensure that - * references will be updated this first time - */ -#ifndef LOCKSET_NOCNT - locker->recomp = epicsAtomicGetSizeT(&recomputeCnt)-1; -#endif - - for(i=0; irefs[i].plr = precs[i] ? precs[i]->lset : NULL; - } - - /* acquire a reference to all lockRecords */ - dbLockUpdateRefs(locker, 1); -} - -dbLocker *dbLockerAlloc(dbCommon * const *precs, - size_t nrecs, - unsigned int flags) -{ - size_t Nextra = nrecs>DBLOCKER_NALLOC ? nrecs-DBLOCKER_NALLOC : 0; - dbLocker *locker = calloc(1, sizeof(*locker)+Nextra*sizeof(lockRecordRef)); - - if(locker) - dbLockerPrepare(locker, precs, nrecs); - - return locker; -} - -void dbLockerFinalize(dbLocker *locker) -{ - size_t i; - assert(ellCount(&locker->locked)==0); - - /* release references taken in dbLockUpdateRefs() */ - for(i=0; imaxrefs; i++) { - if(locker->refs[i].plockSet) - dbLockDecRef(locker->refs[i].plockSet); - } -} - -void dbLockerFree(dbLocker *locker) -{ - dbLockerFinalize(locker); - free(locker); -} - -/* Lock the given list of records. - * This function modifies its arguments. - */ -void dbScanLockMany(dbLocker* locker) -{ - size_t i, nlock = locker->maxrefs; - lockSet *plock; -#ifdef LOCKSET_DEBUG - const epicsThreadId myself = epicsThreadGetIdSelf(); -#endif - - if(ellCount(&locker->locked)!=0) { - cantProceed("dbScanLockMany(%p) already locked. Recursive locking not allowed", locker); - return; - } - -retry: - assert(ellCount(&locker->locked)==0); - dbLockUpdateRefs(locker, 1); - - for(i=0, plock=NULL; irefs[i]; - - /* skip duplicates (same lockSet - * referenced by more than one lockRecord). - * Sorting will group these together. - */ - if(!ref->plr || (plock && plock==ref->plockSet)) - continue; - plock = ref->plockSet; - - epicsMutexMustLock(plock->lock); - assert(plock->ownerlocker==NULL); - plock->ownerlocker = locker; - ellAdd(&locker->locked, &plock->lockernode); - /* An extra ref for the locked list */ - dbLockIncRef(plock); - -#ifdef LOCKSET_DEBUG - if(plock->owner) { - if(plock->owner!=myself || plock->ownercount<1) { - errlogPrintf("dbScanLockMany(%p) ownership violation %p (%p) %u\n", - locker, plock->owner, myself, plock->ownercount); - cantProceed(NULL); - } - plock->ownercount++; - } else { - assert(plock->ownercount==0); - plock->owner = myself; - plock->ownercount = 1; - } -#endif - - } - - if(dbLockUpdateRefs(locker, 0)) { - /* oops, collided with recompute */ - dbScanUnlockMany(locker); - goto retry; - } - if(nlock!=0 && ellCount(&locker->locked)<=0) { - /* if we have at least one lockRecord, then we will always lock - * at least its present lockSet - */ - errlogPrintf("dbScanLockMany(%p) didn't lock anything\n", locker); - cantProceed(NULL); - } -} - -void dbScanUnlockMany(dbLocker* locker) -{ - ELLNODE *cur; -#ifdef LOCKSET_DEBUG - const epicsThreadId myself = epicsThreadGetIdSelf(); -#endif - - while((cur=ellGet(&locker->locked))!=NULL) { - lockSet *plock = CONTAINER(cur, lockSet, lockernode); - - assert(plock->ownerlocker==locker); - plock->ownerlocker = NULL; -#ifdef LOCKSET_DEBUG - assert(plock->owner==myself); - assert(plock->ownercount>=1); - plock->ownercount--; - if(plock->ownercount==0) - plock->owner = NULL; -#endif - - epicsMutexUnlock(plock->lock); - /* release ref for locked list */ - dbLockDecRef(plock); - } -} - -typedef int (*reciter)(void*, DBENTRY*); -static int forEachRecord(void *priv, dbBase *pdbbase, reciter fn) -{ - long status; - int ret = 0; - DBENTRY dbentry; - dbInitEntry(pdbbase,&dbentry); - status = dbFirstRecordType(&dbentry); - while(!status) - { - status = dbFirstRecord(&dbentry); - while(!status) - { - /* skip alias names */ - if(!dbentry.precnode->recordname[0] || dbentry.precnode->flags & DBRN_FLAGS_ISALIAS) { - /* skip */ - } else { - ret = fn(priv, &dbentry); - if(ret) - goto done; - } - - status = dbNextRecord(&dbentry); - } - - status = dbNextRecordType(&dbentry); - } -done: - dbFinishEntry(&dbentry); - return ret; -} - -static int createLockRecord(void* junk, DBENTRY* pdbentry) -{ - dbCommon *prec = pdbentry->precnode->precord; - lockRecord *lrec; - assert(!prec->lset); - - /* TODO: one allocation for all records? */ - lrec = callocMustSucceed(1, sizeof(*lrec), "lockRecord"); - lrec->spin = epicsSpinCreate(); - if(!lrec->spin) - cantProceed("no memory for spinlock in lockRecord"); - - lrec->precord = prec; - - prec->lset = lrec; - - prec->lset->plockSet = makeSet(); - ellAdd(&prec->lset->plockSet->lockRecordList, &prec->lset->node); - return 0; -} - -void dbLockInitRecords(dbBase *pdbbase) -{ - epicsThreadOnce(&dbLockOnceInit, &dbLockOnce, NULL); - - /* create all lockRecords and lockSets */ - forEachRecord(NULL, pdbbase, &createLockRecord); -} - -static int freeLockRecord(void* junk, DBENTRY* pdbentry) -{ - dbCommon *prec = pdbentry->precnode->precord; - lockRecord *lr = prec->lset; - lockSet *ls = lr->plockSet; - - prec->lset = NULL; - lr->precord = NULL; - - assert(ls->refcount>0); - assert(ellCount(&ls->lockRecordList)>0); - ellDelete(&ls->lockRecordList, &lr->node); - dbLockDecRef(ls); - - epicsSpinDestroy(lr->spin); - free(lr); - return 0; -} - -void dbLockCleanupRecords(dbBase *pdbbase) -{ -#ifndef LOCKSET_NOFREE - ELLNODE *cur; -#endif - epicsThreadOnce(&dbLockOnceInit, &dbLockOnce, NULL); - - forEachRecord(NULL, pdbbase, &freeLockRecord); - if(ellCount(&lockSetsActive)) { - printf("Warning: dbLockCleanupRecords() leaking lockSets\n"); - dblsr(NULL,2); - } - -#ifndef LOCKSET_NOFREE - while((cur=ellGet(&lockSetsFree))!=NULL) { - lockSet *ls = (lockSet*)cur; - - assert(ls->refcount==0); - assert(ellCount(&ls->lockRecordList)==0); - epicsMutexDestroy(ls->lock); - free(ls); - } -#endif -} - -/* Called in two modes. - * During dbLockInitRecords w/ locker==NULL, then no mutex are locked. - * After dbLockInitRecords w/ locker!=NULL, then - * the caller must lock both pfirst and psecond. - * - * Assumes that pfirst has been modified - * to link to psecond. - */ -void dbLockSetMerge(dbLocker *locker, dbCommon *pfirst, dbCommon *psecond) -{ - ELLNODE *cur; - lockSet *A=pfirst->lset->plockSet, - *B=psecond->lset->plockSet; - int Nb; -#ifdef LOCKSET_DEBUG - const epicsThreadId myself = epicsThreadGetIdSelf(); -#endif - - assert(A && B); - -#ifdef LOCKSET_DEBUG - if(locker && (A->owner!=myself || B->owner!=myself)) { - errlogPrintf("dbLockSetMerge(%p,\"%s\",\"%s\") ownership violation %p %p (%p)\n", - locker, pfirst->name, psecond->name, - A->owner, B->owner, myself); - cantProceed(NULL); - } -#endif - if(locker && (A->ownerlocker!=locker || B->ownerlocker!=locker)) { - errlogPrintf("dbLockSetMerge(%p,\"%s\",\"%s\") locker ownership violation %p %p (%p)\n", - locker, pfirst->name, psecond->name, - A->ownerlocker, B->ownerlocker, locker); - cantProceed(NULL); - } - - if(A==B) - return; /* already in the same lockSet */ - - Nb = ellCount(&B->lockRecordList); - assert(Nb>0); - - /* move all records from B to A */ - while((cur=ellGet(&B->lockRecordList))!=NULL) - { - lockRecord *lr = CONTAINER(cur, lockRecord, node); - assert(lr->plockSet==B); - ellAdd(&A->lockRecordList, cur); - - epicsSpinLock(lr->spin); - lr->plockSet = A; -#ifndef LOCKSET_NOCNT - epicsAtomicIncrSizeT(&recomputeCnt); -#endif - epicsSpinUnlock(lr->spin); - } - - /* there are at minimum, 1 ref for each lockRecord, - * and one for the locker's locked list - * (and perhaps another for its refs cache) - */ - assert(epicsAtomicGetIntT(&B->refcount)>=Nb+(locker?1:0)); - - /* update ref counters. for lockRecords */ - epicsAtomicAddIntT(&A->refcount, Nb); - epicsAtomicAddIntT(&B->refcount, -Nb+1); /* drop all but one ref, see below */ - - if(locker) { - /* at least two refs, possibly three, remain. - * # One ref from above - * # locker->locked list, which is released now. - * # locker->refs array, assuming it is directly referenced, - * and not added as the result of a dbLockSetSplit, - * which will be cleaned when the locker is free'd (not here). - */ -#ifdef LOCKSET_DEBUG - B->owner = NULL; - B->ownercount = 0; -#endif - assert(B->ownerlocker==locker); - ellDelete(&locker->locked, &B->lockernode); - B->ownerlocker = NULL; - epicsAtomicDecrIntT(&B->refcount); - - epicsMutexUnlock(B->lock); - } - - dbLockDecRef(B); /* last ref we hold */ - - assert(A==psecond->lset->plockSet); -} - -/* recompute assuming a link from pfirst to psecond - * may have been removed. - * pfirst and psecond must currently be in the same lockset, - * which the caller must lock before calling this function. - * If a new lockset is created, then it is locked - * when this function returns. - */ -void dbLockSetSplit(dbLocker *locker, dbCommon *pfirst, dbCommon *psecond) -{ - lockSet *ls = pfirst->lset->plockSet; - ELLLIST toInspect, newLS; -#ifdef LOCKSET_DEBUG - const epicsThreadId myself = epicsThreadGetIdSelf(); -#endif - -#ifdef LOCKSET_DEBUG - if(ls->owner!=myself || psecond->lset->plockSet->owner!=myself) { - errlogPrintf("dbLockSetSplit(%p,\"%s\",\"%s\") ownership violation %p %p (%p)\n", - locker, pfirst->name, psecond->name, - ls->owner, psecond->lset->plockSet->owner, myself); - cantProceed(NULL); - } -#endif - - /* lockset consistency violation */ - if(ls!=psecond->lset->plockSet) { - errlogPrintf("dbLockSetSplit(%p,\"%s\",\"%s\") consistency violation %p %p\n", - locker, pfirst->name, psecond->name, - pfirst->lset->plockSet, psecond->lset->plockSet); - cantProceed(NULL); - } - - - if(pfirst==psecond) - return; - - /* at least 1 ref for each lockRecord, - * and one for the locker - */ - assert(epicsAtomicGetIntT(&ls->refcount)>=ellCount(&ls->lockRecordList)+1); - - ellInit(&toInspect); - ellInit(&newLS); - - /* strategy is to start with psecond and do - * a breadth first traversal until all records are - * visited. If we encounter pfirst, then there - * is no need to create a new lockset so we abort - * early. - */ - ellAdd(&toInspect, &psecond->lset->compnode); - psecond->lset->compflag = 1; - - { - lockSet *splitset; - ELLNODE *cur; - while((cur=ellGet(&toInspect))!=NULL) - { - lockRecord *lr=CONTAINER(cur,lockRecord,compnode); - dbCommon *prec=lr->precord; - dbRecordType *rtype = prec->rdes; - size_t i; - ELLNODE *bcur; - - ellAdd(&newLS, cur); - prec->lset->compflag = 2; - - /* Visit all the links originating from prec */ - for(i=0; ino_links; i++) { - dbFldDes *pdesc = rtype->papFldDes[rtype->link_ind[i]]; - DBLINK *plink = (DBLINK*)((char*)prec + pdesc->offset); - DBADDR *ptarget; - lockRecord *lr; - - if(plink->type!=DB_LINK) - continue; - - ptarget = plink->value.pv_link.pvt; - lr = ptarget->precord->lset; - assert(lr); - - if(lr->precord==pfirst) { - /* so pfirst is still reachable from psecond, - * no new lock set should be created. - */ - goto nosplit; - } - - /* have we already visited this record? */ - if(lr->compflag) - continue; - - ellAdd(&toInspect, &lr->compnode); - lr->compflag = 1; - } - - /* Visit all links terminating at prec */ - for(bcur=ellFirst(&prec->bklnk); bcur; bcur=ellNext(bcur)) - { - struct pv_link *plink1 = CONTAINER(bcur, struct pv_link, backlinknode); - union value *plink2 = CONTAINER(plink1, union value, pv_link); - DBLINK *plink = CONTAINER(plink2, DBLINK, value); - lockRecord *lr = plink->precord->lset; - - /* plink->type==DB_LINK is implied. Only DB_LINKs are tracked from BKLNK */ - - if(lr->precord==pfirst) { - goto nosplit; - } - - if(lr->compflag) - continue; - - ellAdd(&toInspect, &lr->compnode); - lr->compflag = 1; - } - } - /* All links involving psecond were traversed without finding - * pfirst. So we must create a new lockset. - * newLS contains the nodes which will - * make up this new lockset. - */ - /* newLS will have at least psecond in it */ - assert(ellCount(&newLS) > 0); - /* If we didn't find pfirst, then it must be in the - * original lockset, and not the new one - */ - assert(ellCount(&newLS) < ellCount(&ls->lockRecordList)); - assert(ellCount(&newLS) < ls->refcount); - - splitset = makeSet(); /* reference for locker->locked */ - - epicsMutexMustLock(splitset->lock); - - assert(splitset->ownerlocker==NULL); - ellAdd(&locker->locked, &splitset->lockernode); - splitset->ownerlocker = locker; - - assert(splitset->refcount==1); - -#ifdef LOCKSET_DEBUG - splitset->owner = ls->owner; - splitset->ownercount = 1; - assert(ls->ownercount==1); -#endif - - while((cur=ellGet(&newLS))!=NULL) - { - lockRecord *lr=CONTAINER(cur,lockRecord,compnode); - - lr->compflag = 0; /* reset for next time */ - - assert(lr->plockSet == ls); - ellDelete(&ls->lockRecordList, &lr->node); - ellAdd(&splitset->lockRecordList, &lr->node); - - epicsSpinLock(lr->spin); - lr->plockSet = splitset; -#ifndef LOCKSET_NOCNT - epicsAtomicIncrSizeT(&recomputeCnt); -#endif - epicsSpinUnlock(lr->spin); - /* new lockSet is "live" at this point - * as other threads may find it. - */ - } - - /* refcount of ls can't go to zero as the locker - * holds at least one reference (its locked list) - */ - epicsAtomicAddIntT(&ls->refcount, -ellCount(&splitset->lockRecordList)); - assert(ls->refcount>0); - epicsAtomicAddIntT(&splitset->refcount, ellCount(&splitset->lockRecordList)); - - assert(splitset->refcount>=ellCount(&splitset->lockRecordList)+1); - - assert(psecond->lset->plockSet==splitset); - - /* must have refs from pfirst lockRecord, - * and the locked list. - */ - assert(epicsAtomicGetIntT(&ls->refcount)>=2); - - return; - } - -nosplit: - { - /* reset compflag for all nodes visited - * during the aborted search - */ - ELLNODE *cur; - while((cur=ellGet(&toInspect))!=NULL) - { - lockRecord *lr=CONTAINER(cur,lockRecord,compnode); - lr->compflag = 0; - } - while((cur=ellGet(&newLS))!=NULL) - { - lockRecord *lr=CONTAINER(cur,lockRecord,compnode); - lr->compflag = 0; - } - return; - } -} - -static char *msstring[4]={"NMS","MS","MSI","MSS"}; - -long dblsr(char *recordname,int level) -{ - int link; - DBENTRY dbentry; - DBENTRY *pdbentry=&dbentry; - long status; - dbCommon *precord; - lockSet *plockSet; - lockRecord *plockRecord; - dbRecordType *pdbRecordType; - dbFldDes *pdbFldDes; - DBLINK *plink; - - if (recordname && ((*recordname == '\0') || !strcmp(recordname,"*"))) - recordname = NULL; - if(recordname) { - dbInitEntry(pdbbase,pdbentry); - status = dbFindRecord(pdbentry,recordname); - if(status) { - printf("Record not found\n"); - dbFinishEntry(pdbentry); - return 0; - } - precord = pdbentry->precnode->precord; - dbFinishEntry(pdbentry); - plockRecord = precord->lset; - if (!plockRecord) return 0; /* before iocInit */ - plockSet = plockRecord->plockSet; - } else { - plockSet = (lockSet *)ellFirst(&lockSetsActive); - } - for( ; plockSet; plockSet = (lockSet *)ellNext(&plockSet->node)) { - printf("Lock Set %lu %d members %d refs epicsMutexId %p\n", - plockSet->id,ellCount(&plockSet->lockRecordList),plockSet->refcount,plockSet->lock); - - if(level==0) { if(recordname) break; continue; } - for(plockRecord = (lockRecord *)ellFirst(&plockSet->lockRecordList); - plockRecord; plockRecord = (lockRecord *)ellNext(&plockRecord->node)) { - precord = plockRecord->precord; - pdbRecordType = precord->rdes; - printf("%s\n",precord->name); - if(level<=1) continue; - for(link=0; (linkno_links) ; link++) { - DBADDR *pdbAddr; - pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->link_ind[link]]; - plink = (DBLINK *)((char *)precord + pdbFldDes->offset); - if(plink->type != DB_LINK) continue; - pdbAddr = (DBADDR *)(plink->value.pv_link.pvt); - printf("\t%s",pdbFldDes->name); - if(pdbFldDes->field_type==DBF_INLINK) { - printf("\t INLINK"); - } else if(pdbFldDes->field_type==DBF_OUTLINK) { - printf("\tOUTLINK"); - } else if(pdbFldDes->field_type==DBF_FWDLINK) { - printf("\tFWDLINK"); - } - printf(" %s %s", - ((plink->value.pv_link.pvlMask&pvlOptPP)?" PP":"NPP"), - msstring[plink->value.pv_link.pvlMask&pvlOptMsMode]); - printf(" %s\n",pdbAddr->precord->name); - } - } - if(recordname) break; - } - return 0; -} - -long dbLockShowLocked(int level) -{ - int indListType; - lockSet *plockSet; - - printf("Active lockSets: %d\n", ellCount(&lockSetsActive)); -#ifndef LOCKSET_NOFREE - printf("Free lockSets: %d\n", ellCount(&lockSetsFree)); -#endif - - /*Even if failure on lockSetModifyLock will continue */ - for(indListType=0; indListType <= 1; ++indListType) { - plockSet = (lockSet *)ellFirst(&lockSetsActive); - if(plockSet) { - if (indListType==0) - printf("listTypeScanLock\n"); - else - printf("listTypeRecordLock\n"); - } - while(plockSet) { - epicsMutexLockStatus status; - - status = epicsMutexTryLock(plockSet->lock); - if(status==epicsMutexLockOK) epicsMutexUnlock(plockSet->lock); - if(status!=epicsMutexLockOK || indListType==1) { - - epicsMutexShow(plockSet->lock,level); - } - plockSet = (lockSet *)ellNext(&plockSet->node); - } - } - return 0; -} - -int * dbLockSetAddrTrace(dbCommon *precord) -{ - lockRecord *plockRecord = precord->lset; - lockSet *plockSet = plockRecord->plockSet; - - return(&plockSet->trace); -} diff --git a/src/ioc/db/dbLock.h b/src/ioc/db/dbLock.h deleted file mode 100644 index 1d6388ed3..000000000 --- a/src/ioc/db/dbLock.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbLock.h */ -/* Author: Marty Kraimer Date: 12MAR96 */ - -#ifndef INCdbLockh -#define INCdbLockh - -#include "ellLib.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct dbCommon; -struct dbBase; -typedef struct dbLocker dbLocker; - -epicsShareFunc void dbScanLock(struct dbCommon *precord); -epicsShareFunc void dbScanUnlock(struct dbCommon *precord); - -epicsShareFunc dbLocker *dbLockerAlloc(struct dbCommon * const *precs, - size_t nrecs, - unsigned int flags); - -epicsShareFunc void dbLockerFree(dbLocker *); - -epicsShareFunc void dbScanLockMany(dbLocker*); -epicsShareFunc void dbScanUnlockMany(dbLocker*); - -epicsShareFunc unsigned long dbLockGetLockId( - struct dbCommon *precord); - -epicsShareFunc void dbLockInitRecords(struct dbBase *pdbbase); -epicsShareFunc void dbLockCleanupRecords(struct dbBase *pdbbase); - - -/* Lock Set Report */ -epicsShareFunc long dblsr(char *recordname,int level); -/* If recordname NULL then all records*/ -/* level = (0,1,2) (lock set state, + recordname, +DB links) */ - -epicsShareFunc long dbLockShowLocked(int level); - -/*KLUDGE to support field TPRO*/ -epicsShareFunc int * dbLockSetAddrTrace(struct dbCommon *precord); - -/* debugging */ -epicsShareFunc unsigned long dbLockGetRefs(struct dbCommon*); -epicsShareFunc unsigned long dbLockCountSets(void); - -#ifdef __cplusplus -} -#endif - -#endif /*INCdbLockh*/ diff --git a/src/ioc/db/dbLockPvt.h b/src/ioc/db/dbLockPvt.h deleted file mode 100644 index f90d00617..000000000 --- a/src/ioc/db/dbLockPvt.h +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc., as Operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef DBLOCKPVT_H -#define DBLOCKPVT_H - -#include "dbLock.h" -#include "epicsSpin.h" - -/* Define to enable additional error checking */ -#undef LOCKSET_DEBUG - -/* Define to disable the free list for lockSets */ -#undef LOCKSET_NOFREE - -/* Define to disable use of recomputeCnt optimization */ -#undef LOCKSET_NOCNT - -/* except for refcount (and lock), all members of dbLockSet - * are guarded by its lock. - */ -typedef struct dbLockSet { - ELLNODE node; - ELLLIST lockRecordList; /* holds lockRecord::node */ - epicsMutexId lock; - unsigned long id; - - int refcount; -#ifdef LOCKSET_DEBUG - int ownercount; - epicsThreadId owner; -#endif - dbLocker *ownerlocker; - ELLNODE lockernode; - - int trace; /*For field TPRO*/ -} lockSet; - -struct lockRecord; - -/* dbCommon.LSET is a plockRecord. - * Except for spin and plockSet, all members of lockRecord are guarded - * by the present lockset lock. - * plockSet is guarded by spin. - */ -typedef struct lockRecord { - ELLNODE node; /* in lockSet::lockRecordList */ - /* The association between lockRecord and lockSet - * can only be changed while the lockSet is held, - * and the lockRecord's spinlock is held. - * It may be read which either lock is held. - */ - lockSet *plockSet; - /* the association between lockRecord and dbCommon never changes */ - dbCommon *precord; - epicsSpinId spin; - - /* temp used during lockset split. - * lockSet must be locked for access - */ - ELLNODE compnode; - unsigned int compflag; -} lockRecord; - -typedef struct { - lockRecord *plr; - /* the last lock found associated with the ref. - * not stable unless lock is locked, or ref spin - * is locked. - */ - lockSet *plockSet; -} lockRecordRef; - -#define DBLOCKER_NALLOC 2 -/* a dbLocker can only be used by a single thread. */ -struct dbLocker { - ELLLIST locked; -#ifndef LOCKSET_NOCNT - size_t recomp; /* snapshot of recomputeCnt when refs[] cache updated */ -#endif - size_t maxrefs; - lockRecordRef refs[DBLOCKER_NALLOC]; /* actual length is maxrefs */ -}; - -/* These are exported for testing only */ -epicsShareFunc lockSet* dbLockGetRef(lockRecord *lr); /* lookup lockset and increment ref count */ -epicsShareFunc void dbLockIncRef(lockSet* ls); -epicsShareFunc void dbLockDecRef(lockSet *ls); - -/* Calling dbLockerPrepare directly is an internal - * optimization used when dbLocker on the stack. - * nrecs must be <=DBLOCKER_NALLOC. - */ -void dbLockerPrepare(struct dbLocker *locker, - struct dbCommon * const *precs, - size_t nrecs); -void dbLockerFinalize(dbLocker *); - -void dbLockSetMerge(struct dbLocker *locker, - struct dbCommon *pfirst, - struct dbCommon *psecond); -void dbLockSetSplit(struct dbLocker *locker, - struct dbCommon *psource, - struct dbCommon *psecond); - -#endif /* DBLOCKPVT_H */ diff --git a/src/ioc/db/dbNotify.c b/src/ioc/db/dbNotify.c deleted file mode 100644 index c718d3740..000000000 --- a/src/ioc/db/dbNotify.c +++ /dev/null @@ -1,686 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbNotify.c */ -/* - * Author: Marty Kraimer - * Andrew Johnson - * - * Extracted from dbLink.c - */ - -#include -#include -#include -#include -#include - -#include "cantProceed.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsAssert.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "errMdef.h" - -#define epicsExportSharedSymbols -#include "callback.h" -#include "dbAccessDefs.h" -#include "dbBase.h" -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbFldTypes.h" -#include "dbLock.h" -#include "dbNotify.h" -#include "dbScan.h" -#include "dbStaticLib.h" -#include "link.h" -#include "recGbl.h" - -/*notify state values */ -typedef enum { - notifyNotActive, - notifyWaitForRestart, - notifyRestartCallbackRequested, - notifyRestartInProgress, - notifyProcessInProgress, - notifyUserCallbackRequested, - notifyUserCallbackActive -} notifyState; - -/*structure attached to ppnr field of each record*/ -typedef struct processNotifyRecord { - ellCheckNode waitNode; - ELLLIST restartList; /*list of processNotifys to restart*/ - dbCommon *precord; -} processNotifyRecord; - -#define MAGIC 0xfedc0123 -typedef struct notifyPvt { - ELLNODE node; /*For free list*/ - long magic; - short state; - CALLBACK callback; - ELLLIST waitList; /*list of records for current processNotify*/ - short cancelWait; - short userCallbackWait; - epicsEventId cancelEvent; - epicsEventId userCallbackEvent; -} notifyPvt; - -/* processNotify groups can span locksets if links are dynamically modified*/ -/* Thus a global lock is taken while processNotify fields are accessed */ -typedef struct notifyGlobal { - epicsMutexId lock; - ELLLIST freeList; -} notifyGlobal; - -static notifyGlobal *pnotifyGlobal = 0; - -/*Local routines*/ -static void notifyInit(processNotify *ppn); -static void notifyCleanup(processNotify *ppn); -static void restartCheck(processNotifyRecord *ppnr); -static void callDone(dbCommon *precord,processNotify *ppn); -static void processNotifyCommon(processNotify *ppn,dbCommon *precord); -static void notifyCallback(CALLBACK *pcallback); - -#define ellSafeAdd(list,listnode) \ -{ \ - assert((listnode)->isOnList==0); \ - ellAdd((list),&((listnode)->node)); \ - (listnode)->isOnList=1; \ -} - -#define ellSafeDelete(list,listnode) \ -{ \ - assert((listnode)->isOnList); \ - ellDelete((list),&((listnode)->node)); \ - (listnode)->isOnList=0; \ -} - -static void notifyFree(void *raw) -{ - notifyPvt *pnotifyPvt = raw; - assert(pnotifyPvt->magic==MAGIC); - epicsEventDestroy(pnotifyPvt->cancelEvent); - epicsEventDestroy(pnotifyPvt->userCallbackEvent); - free(pnotifyPvt); -} - -static void notifyInit(processNotify *ppn) -{ - notifyPvt *pnotifyPvt; - - pnotifyPvt = (notifyPvt *) ellFirst(&pnotifyGlobal->freeList); - if (pnotifyPvt) { - ellDelete(&pnotifyGlobal->freeList, &pnotifyPvt->node); - } else { - pnotifyPvt = dbCalloc(1,sizeof(notifyPvt)); - pnotifyPvt->cancelEvent = epicsEventCreate(epicsEventEmpty); - pnotifyPvt->userCallbackEvent = epicsEventCreate(epicsEventEmpty); - pnotifyPvt->magic = MAGIC; - pnotifyPvt->state = notifyNotActive; - } - pnotifyPvt->state = notifyNotActive; - callbackSetCallback(notifyCallback,&pnotifyPvt->callback); - callbackSetUser(ppn,&pnotifyPvt->callback); - callbackSetPriority(priorityLow,&pnotifyPvt->callback); - ellInit(&pnotifyPvt->waitList); - ppn->status = notifyOK; - ppn->wasProcessed = 0; - pnotifyPvt->state = notifyNotActive; - pnotifyPvt->cancelWait = pnotifyPvt->userCallbackWait = 0; - ppn->pnotifyPvt = pnotifyPvt; -} - -static void notifyCleanup(processNotify *ppn) -{ - notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - - pnotifyPvt->state = notifyNotActive; - ellAdd(&pnotifyGlobal->freeList, &pnotifyPvt->node); - ppn->pnotifyPvt = 0; -} - -static void restartCheck(processNotifyRecord *ppnr) -{ - dbCommon *precord = ppnr->precord; - processNotify *pfirst; - notifyPvt *pnotifyPvt; - - assert(precord->ppn); - pfirst = (processNotify *) ellFirst(&ppnr->restartList); - if (!pfirst) { - precord->ppn = 0; - return; - } - pnotifyPvt = (notifyPvt *) pfirst->pnotifyPvt; - assert(pnotifyPvt->state == notifyWaitForRestart); - /* remove pfirst from restartList */ - ellSafeDelete(&ppnr->restartList, &pfirst->restartNode); - /*make pfirst owner of the record*/ - precord->ppn = pfirst; - /* request callback for pfirst */ - pnotifyPvt->state = notifyRestartCallbackRequested; - callbackRequest(&pnotifyPvt->callback); -} - -static void callDone(dbCommon *precord, processNotify *ppn) -{ - notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - - epicsMutexUnlock(pnotifyGlobal->lock); - if (ppn->requestType == processGetRequest || - ppn->requestType == putProcessGetRequest) { - ppn->getCallback(ppn, getFieldType); - } - dbScanUnlock(precord); - ppn->doneCallback(ppn); - epicsMutexMustLock(pnotifyGlobal->lock); - if (pnotifyPvt->cancelWait && pnotifyPvt->userCallbackWait) { - errlogPrintf("%s processNotify: both cancelWait and userCallbackWait true." - "This is illegal\n", precord->name); - pnotifyPvt->cancelWait = pnotifyPvt->userCallbackWait = 0; - } - if (!pnotifyPvt->cancelWait && !pnotifyPvt->userCallbackWait) { - notifyCleanup(ppn); - epicsMutexUnlock(pnotifyGlobal->lock); - return; - } - if (pnotifyPvt->cancelWait) { - pnotifyPvt->cancelWait = 0; - epicsEventSignal(pnotifyPvt->cancelEvent); - epicsMutexUnlock(pnotifyGlobal->lock); - return; - } - assert(pnotifyPvt->userCallbackWait); - pnotifyPvt->userCallbackWait = 0; - epicsEventSignal(pnotifyPvt->userCallbackEvent); - epicsMutexUnlock(pnotifyGlobal->lock); - return; -} - -static void processNotifyCommon(processNotify *ppn,dbCommon *precord) -{ - notifyPvt *pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - int didPut = 0; - int doProcess = 0; - - if (precord->ppn && - pnotifyPvt->state != notifyRestartCallbackRequested) { - /* Another processNotify owns the record */ - pnotifyPvt->state = notifyWaitForRestart; - ellSafeAdd(&precord->ppnr->restartList, &ppn->restartNode); - epicsMutexUnlock(pnotifyGlobal->lock); - dbScanUnlock(precord); - return; - } else if (precord->ppn) { - assert(precord->ppn == ppn); - assert(pnotifyPvt->state == notifyRestartCallbackRequested); - } - if (precord->pact) { - precord->ppn = ppn; - ellSafeAdd(&pnotifyPvt->waitList, &precord->ppnr->waitNode); - pnotifyPvt->state = notifyRestartInProgress; - epicsMutexUnlock(pnotifyGlobal->lock); - dbScanUnlock(precord); - return; - } - if (ppn->requestType == putProcessRequest || - ppn->requestType == putProcessGetRequest) { - /* Check if puts disabled */ - if (precord->disp && (dbChannelField(ppn->chan) != (void *) &precord->disp)) { - ppn->putCallback(ppn, putDisabledType); - } else { - didPut = ppn->putCallback(ppn, putType); - } - } - /* Check if dbProcess should be called */ - if (didPut && - ((dbChannelField(ppn->chan) == (void *) &precord->proc) || - (dbChannelFldDes(ppn->chan)->process_passive && precord->scan == 0))) - doProcess = 1; - else - if (ppn->requestType == processGetRequest && - precord->scan == 0) - doProcess = 1; - - if (doProcess) { - ppn->wasProcessed = 1; - precord->ppn = ppn; - ellSafeAdd(&pnotifyPvt->waitList, &precord->ppnr->waitNode); - pnotifyPvt->state = notifyProcessInProgress; - epicsMutexUnlock(pnotifyGlobal->lock); - dbProcess(precord); - dbScanUnlock(precord); - return; - } - if (pnotifyPvt->state == notifyRestartCallbackRequested) { - restartCheck(precord->ppnr); - } - pnotifyPvt->state = notifyUserCallbackActive; - assert(precord->ppn!=ppn); - callDone(precord, ppn); -} - -static void notifyCallback(CALLBACK *pcallback) -{ - processNotify *ppn = NULL; - dbCommon *precord; - notifyPvt *pnotifyPvt; - - callbackGetUser(ppn,pcallback); - pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - precord = dbChannelRecord(ppn->chan); - dbScanLock(precord); - epicsMutexMustLock(pnotifyGlobal->lock); - assert(precord->ppnr); - assert(pnotifyPvt->state == notifyRestartCallbackRequested || - pnotifyPvt->state == notifyUserCallbackRequested); - assert(ellCount(&pnotifyPvt->waitList) == 0); - if (pnotifyPvt->cancelWait) { - if (pnotifyPvt->state == notifyRestartCallbackRequested) { - restartCheck(precord->ppnr); - } - epicsEventSignal(pnotifyPvt->cancelEvent); - epicsMutexUnlock(pnotifyGlobal->lock); - dbScanUnlock(precord); - return; - } - if(pnotifyPvt->state == notifyRestartCallbackRequested) { - processNotifyCommon(ppn, precord); - return; - } - /* All done. Clean up and call userCallback */ - pnotifyPvt->state = notifyUserCallbackActive; - assert(precord->ppn!=ppn); - callDone(precord, ppn); -} - -void dbProcessNotifyExit(void) -{ - ellFree2(&pnotifyGlobal->freeList, ¬ifyFree); - epicsMutexDestroy(pnotifyGlobal->lock); - free(pnotifyGlobal); - pnotifyGlobal = NULL; -} - -void dbProcessNotifyInit(void) -{ - if (pnotifyGlobal) - return; - pnotifyGlobal = dbCalloc(1,sizeof(notifyGlobal)); - pnotifyGlobal->lock = epicsMutexMustCreate(); - ellInit(&pnotifyGlobal->freeList); -} - -void dbProcessNotify(processNotify *ppn) -{ - struct dbChannel *chan = ppn->chan; - dbCommon *precord = dbChannelRecord(chan); - short dbfType = dbChannelFieldType(chan); - notifyPvt *pnotifyPvt; - - /* Must handle DBF_XXXLINKs as special case. - * Only dbPutField will change link fields. - * Also the record is not processed as a result - */ - ppn->status = notifyOK; - ppn->wasProcessed = 0; - if (dbfType>=DBF_INLINK && dbfType<=DBF_FWDLINK) { - if (ppn->requestType == putProcessRequest || - ppn->requestType == putProcessGetRequest) { - /* Check if puts disabled */ - if (precord->disp && (dbChannelField(ppn->chan) != (void *) &precord->disp)) { - ppn->putCallback(ppn, putDisabledType); - } else { - ppn->putCallback(ppn, putFieldType); - } - } - if (ppn->requestType == processGetRequest || - ppn->requestType == putProcessGetRequest) { - ppn->getCallback(ppn, getFieldType); - - } - ppn->doneCallback(ppn); - return; - } - dbScanLock(precord); - epicsMutexMustLock(pnotifyGlobal->lock); - pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - if (pnotifyPvt && (pnotifyPvt->magic != MAGIC)) { - printf("dbPutNotify:pnotifyPvt was not initialized\n"); - pnotifyPvt = 0; - } - if (pnotifyPvt) { - assert(pnotifyPvt->state == notifyUserCallbackActive); - pnotifyPvt->userCallbackWait = 1; - epicsMutexUnlock(pnotifyGlobal->lock); - dbScanUnlock(precord); - epicsEventWait(pnotifyPvt->userCallbackEvent); - dbScanLock(precord); - epicsMutexMustLock(pnotifyGlobal->lock); - notifyCleanup(ppn); - } - pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - assert(!pnotifyPvt); - notifyInit(ppn); - pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - if (!precord->ppnr) { - /* make sure record has a processNotifyRecord*/ - precord->ppnr = dbCalloc(1, sizeof(processNotifyRecord)); - precord->ppnr->precord = precord; - ellInit(&precord->ppnr->restartList); - } - processNotifyCommon(ppn, precord); -} - -void dbNotifyCancel(processNotify *ppn) -{ - dbCommon *precord = dbChannelRecord(ppn->chan); - notifyState state; - notifyPvt *pnotifyPvt; - - dbScanLock(precord); - epicsMutexMustLock(pnotifyGlobal->lock); - ppn->status = notifyCanceled; - pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - if (!pnotifyPvt || pnotifyPvt->state == notifyNotActive) { - epicsMutexUnlock(pnotifyGlobal->lock); - dbScanUnlock(precord); - return; - } - - state = pnotifyPvt->state; - switch (state) { - case notifyUserCallbackRequested: - case notifyRestartCallbackRequested: - case notifyUserCallbackActive: - /* Callback is scheduled or active, wait for it to complete */ - pnotifyPvt->cancelWait = 1; - epicsMutexUnlock(pnotifyGlobal->lock); - dbScanUnlock(precord); - epicsEventWait(pnotifyPvt->cancelEvent); - epicsMutexMustLock(pnotifyGlobal->lock); - notifyCleanup(ppn); - epicsMutexUnlock(pnotifyGlobal->lock); - return; - case notifyNotActive: - break; - case notifyWaitForRestart: - assert(precord->ppn); - assert(precord->ppn!=ppn); - ellSafeDelete(&precord->ppnr->restartList,&ppn->restartNode); - break; - case notifyRestartInProgress: - case notifyProcessInProgress: - { /*Take all records out of wait list */ - processNotifyRecord *ppnrWait; - - while ((ppnrWait = (processNotifyRecord *) - ellFirst(&pnotifyPvt->waitList))) { - ellSafeDelete(&pnotifyPvt->waitList, &ppnrWait->waitNode); - restartCheck(ppnrWait); - } - } - if (precord->ppn == ppn) - restartCheck(precord->ppnr); - break; - default: - printf("dbNotify: illegal state for notifyCallback\n"); - } - pnotifyPvt->state = notifyNotActive; - notifyCleanup(ppn); - epicsMutexUnlock(pnotifyGlobal->lock); - dbScanUnlock(precord); -} - -void dbNotifyCompletion(dbCommon *precord) -{ - processNotify *ppn = precord->ppn; - notifyPvt *pnotifyPvt; - - epicsMutexMustLock(pnotifyGlobal->lock); - assert(ppn); - assert(precord->ppnr); - pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - if (pnotifyPvt->state != notifyRestartInProgress && - pnotifyPvt->state != notifyProcessInProgress) { - epicsMutexUnlock(pnotifyGlobal->lock); - return; - } - ellSafeDelete(&pnotifyPvt->waitList, &precord->ppnr->waitNode); - if ((ellCount(&pnotifyPvt->waitList) != 0)) { - restartCheck(precord->ppnr); - } - else if (pnotifyPvt->state == notifyProcessInProgress) { - pnotifyPvt->state = notifyUserCallbackRequested; - restartCheck(precord->ppnr); - callbackRequest(&pnotifyPvt->callback); - } - else if(pnotifyPvt->state == notifyRestartInProgress) { - pnotifyPvt->state = notifyRestartCallbackRequested; - callbackRequest(&pnotifyPvt->callback); - } else { - cantProceed("dbNotifyCompletion illegal state"); - } - epicsMutexUnlock(pnotifyGlobal->lock); -} - -void dbNotifyAdd(dbCommon *pfrom, dbCommon *pto) -{ - processNotify *ppn = pfrom->ppn; - notifyPvt *pnotifyPvt; - - if (pto->pact) - return; /*if active it will not be processed*/ - epicsMutexMustLock(pnotifyGlobal->lock); - if (!pto->ppnr) {/* make sure record has a processNotifyRecord*/ - pto->ppnr = dbCalloc(1, sizeof(processNotifyRecord)); - pto->ppnr->precord = pto; - ellInit(&pto->ppnr->restartList); - } - assert(ppn); - pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - if (!pto->ppn && - (pnotifyPvt->state == notifyProcessInProgress) && - (pto != dbChannelRecord(ppn->chan))) { - notifyPvt *pnotifyPvt; - pto->ppn = pfrom->ppn; - pnotifyPvt = (notifyPvt *) pfrom->ppn->pnotifyPvt; - ellSafeAdd(&pnotifyPvt->waitList, &pto->ppnr->waitNode); - } - epicsMutexUnlock(pnotifyGlobal->lock); -} - -typedef struct tpnInfo { - epicsEventId callbackDone; - processNotify *ppn; - char buffer[80]; -} tpnInfo; - -static int putCallback(processNotify *ppn, notifyPutType type) -{ - tpnInfo *ptpnInfo = (tpnInfo *) ppn->usrPvt; - int status = 0; - - if (ppn->status == notifyCanceled) - return 0; - ppn->status = notifyOK; - switch (type) { - case putDisabledType: - ppn->status = notifyError; - return 0; - case putFieldType: - status = dbChannelPutField(ppn->chan, DBR_STRING, ptpnInfo->buffer, 1); - break; - case putType: - status = dbChannelPut(ppn->chan, DBR_STRING, ptpnInfo->buffer, 1); - break; - } - if (status) - ppn->status = notifyError; - return 1; -} - -static void getCallback(processNotify *ppn,notifyGetType type) -{ - tpnInfo *ptpnInfo = (tpnInfo *)ppn->usrPvt; - int status = 0; - long no_elements = 1; - long options = 0; - - if(ppn->status==notifyCanceled) { - printf("dbtpn:getCallback notifyCanceled\n"); - return; - } - switch(type) { - case getFieldType: - status = dbChannelGetField(ppn->chan, DBR_STRING, ptpnInfo->buffer, - &options, &no_elements, 0); - break; - case getType: - status = dbChannelGet(ppn->chan, DBR_STRING, ptpnInfo->buffer, - &options, &no_elements, 0); - break; - } - if (status) { - ppn->status = notifyError; - printf("dbtpn:getCallback error\n"); - } else { - printf("dbtpn:getCallback value %s\n", ptpnInfo->buffer); - } -} - -static void doneCallback(processNotify *ppn) -{ - notifyStatus status = ppn->status; - tpnInfo *ptpnInfo = (tpnInfo *) ppn->usrPvt; - const char *pname = dbChannelRecord(ppn->chan)->name; - - if (status == 0) - printf("dbtpnCallback: success record=%s\n", pname); - else - printf("%s dbtpnCallback processNotify.status %d\n", - pname, (int) status); - epicsEventSignal(ptpnInfo->callbackDone); -} - -static void tpnThread(void *pvt) -{ - tpnInfo *ptpnInfo = (tpnInfo *) pvt; - processNotify *ppn = (processNotify *) ptpnInfo->ppn; - - dbProcessNotify(ppn); - epicsEventWait(ptpnInfo->callbackDone); - dbNotifyCancel(ppn); - epicsEventDestroy(ptpnInfo->callbackDone); - dbChannelDelete(ppn->chan); - free(ppn); - free(ptpnInfo); -} - -long dbtpn(char *pname, char *pvalue) -{ - struct dbChannel *chan; - tpnInfo *ptpnInfo; - processNotify *ppn=NULL; - - chan = dbChannelCreate(pname); - if (!chan) { - printf("dbtpn: No such channel"); - return -1; - } - - ppn = dbCalloc(1, sizeof(processNotify)); - ppn->requestType = pvalue ? putProcessRequest : processGetRequest; - ppn->chan = chan; - ppn->putCallback = putCallback; - ppn->getCallback = getCallback; - ppn->doneCallback = doneCallback; - - ptpnInfo = dbCalloc(1, sizeof(tpnInfo)); - ptpnInfo->ppn = ppn; - ptpnInfo->callbackDone = epicsEventCreate(epicsEventEmpty); - strncpy(ptpnInfo->buffer, pvalue, 80); - ptpnInfo->buffer[79] = 0; - - ppn->usrPvt = ptpnInfo; - epicsThreadCreate("dbtpn", epicsThreadPriorityHigh, - epicsThreadGetStackSize(epicsThreadStackMedium), tpnThread, ptpnInfo); - return 0; -} - -int dbNotifyDump(void) -{ - epicsMutexLockStatus lockStatus; - dbRecordType *pdbRecordType; - processNotify *ppnRestart; - processNotifyRecord *ppnr; - int itry; - - for (itry = 0; itry < 100; itry++) { - lockStatus = epicsMutexTryLock(pnotifyGlobal->lock); - if (lockStatus == epicsMutexLockOK) - break; - epicsThreadSleep(.05); - } - - for (pdbRecordType = (dbRecordType *) ellFirst(&pdbbase->recordTypeList); - pdbRecordType; - pdbRecordType = (dbRecordType *) ellNext(&pdbRecordType->node)) { - dbRecordNode *pdbRecordNode; - - for (pdbRecordNode = (dbRecordNode *) ellFirst(&pdbRecordType->recList); - pdbRecordNode; - pdbRecordNode = (dbRecordNode *) ellNext(&pdbRecordNode->node)) { - dbCommon *precord = pdbRecordNode->precord; - processNotify *ppn; - notifyPvt *pnotifyPvt; - - if (!precord->name[0] || pdbRecordNode->flags & DBRN_FLAGS_ISALIAS) - continue; - ppn = precord->ppn; - if (!ppn || !precord->ppnr) - continue; - if (dbChannelRecord(precord->ppn->chan) != precord) - continue; - - pnotifyPvt = (notifyPvt *) ppn->pnotifyPvt; - printf("%s state %d ppn %p\n waitList\n", - precord->name, pnotifyPvt->state, (void*) ppn); - ppnr = (processNotifyRecord *) ellFirst(&pnotifyPvt->waitList); - while (ppnr) { - printf(" %s pact %d\n", - ppnr->precord->name, ppnr->precord->pact); - ppnr = (processNotifyRecord *) ellNext(&ppnr->waitNode.node); - } - ppnr = precord->ppnr; - if (ppnr) { - ppnRestart = (processNotify *)ellFirst( - &precord->ppnr->restartList); - if (ppnRestart) - printf("%s restartList\n", precord->name); - while (ppnRestart) { - printf(" %s\n", dbChannelRecord(ppnRestart->chan)->name); - ppnRestart = (processNotify *) ellNext( - &ppnRestart->restartNode.node); - } - } - } - } - if (lockStatus == epicsMutexLockOK) - epicsMutexUnlock(pnotifyGlobal->lock); - return 0; -} - diff --git a/src/ioc/db/dbNotify.h b/src/ioc/db/dbNotify.h deleted file mode 100644 index 4b7c3e4dd..000000000 --- a/src/ioc/db/dbNotify.h +++ /dev/null @@ -1,168 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbNotify.h */ - -#ifndef INCdbNotifyh -#define INCdbNotifyh - -#include "shareLib.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "callback.h" - -#ifdef __cplusplus - extern "C" { -#endif - -struct dbCommon; -struct processNotify; - -typedef struct ellCheckNode{ - ELLNODE node; - int isOnList; -} ellCheckNode; - -typedef enum { - processRequest, - putProcessRequest, - processGetRequest, - putProcessGetRequest -} notifyRequestType; - -typedef enum { - putDisabledType, - putFieldType, - putType -} notifyPutType; - -typedef enum { - getFieldType, - getType /* FIXME: Never used? */ -} notifyGetType; - -typedef enum { - notifyOK, - notifyCanceled, - notifyError, - notifyPutDisabled -} notifyStatus; - -typedef struct processNotify { - /* following fields are for private use by dbNotify implementation */ - ellCheckNode restartNode; - void *pnotifyPvt; - /* The following fields are set by dbNotify. */ - notifyStatus status; - int wasProcessed; /* (0,1) => (no,yes) */ - /*The following members are set by user*/ - notifyRequestType requestType; - struct dbChannel *chan; /*dbChannel*/ - int (*putCallback)(struct processNotify *,notifyPutType type); - void (*getCallback)(struct processNotify *,notifyGetType type); - void (*doneCallback)(struct processNotify *); - void *usrPvt; /*for private use of user*/ -} processNotify; - - -/* dbProcessNotify and dbNotifyCancel are called by user*/ -epicsShareFunc void dbProcessNotify(processNotify *pprocessNotify); -epicsShareFunc void dbNotifyCancel(processNotify *pprocessNotify); - -/* dbProcessNotifyInit called by iocInit */ -epicsShareFunc void dbProcessNotifyInit(void); -epicsShareFunc void dbProcessNotifyExit(void); - -/*dbNotifyAdd called by dbScanPassive and dbScanLink*/ -epicsShareFunc void dbNotifyAdd( - struct dbCommon *pfrom,struct dbCommon *pto); -/*dbNotifyCompletion called by recGblFwdLink or dbAccess*/ -epicsShareFunc void dbNotifyCompletion(struct dbCommon *precord); - -/* db_put_process defined here since it requires dbNotify. - * src_type is the old DBR type - * This is called by a dbNotify putCallback that uses oldDbr types - */ -epicsShareFunc int db_put_process( - processNotify *processNotify,notifyPutType type, - int src_type,const void *psrc, int no_elements); - -/* dbtpn is test routine for dbNotify putProcessRequest */ -epicsShareFunc long dbtpn(char *recordname,char *value); - -/* dbNotifyDump is an INVASIVE debug utility. Don't use this needlessly*/ -epicsShareFunc int dbNotifyDump(void); - -/* This module provides code to handle process notify. - * client code semantics are: - * 1) The client code allocates storage for a processNotify structure. - * This structure can be used for multiple calls to dbProcessNotify. - * The client is responsible for setting the following fields : - * requestType - The type of request. - * chan - This is typically set via a call to dbChannelCreate. - * putCallback - If requestType is putProcessRequest or putProcessGetRequest - * getCallback - If request is processGetRequest or putProcessGetRequest - * doneCallback - Must be set - * usrPvt - For exclusive use of client. dbNotify does not access this field - * 2) The client calls dbProcessNotify. - * 3) putCallback is called after dbNotify has claimed the record instance - * but before a potential process is requested. - * The putCallback MUST issue the correct put request - * specified by notifyPutType - * 4) getCallback is called after a possible process is complete - * (including asynchronous completion) but before dbNotify has - * released the record. - * The getCallback MUST issue the correct get request - * specified by notifyGetType - * 5) doneCallback is called when dbNotify has released the record. - * The client can issue a new dbProcessNotify request from - * doneCallback or anytime after doneCallback returns. - * 6) The client can call dbNotifyCancel at any time. - * If a dbProcessNotify is active, dbNotifyCancel will not return until - * the dbNotifyRequest is actually canceled. The client must be prepared - * for a callback to be called while dbNotifyCancel is active. - * - * dbProcessNotify handles the semantics of record locking and deciding - * if a process request is issued and also calls the client callbacks. - * - * A process request is issued if any of the following is true. - * 1) The requester has issued a processs request and record is passive. - * 2) The requester is doing a put, the record is passive, and either - * a) The field description is process passive. - * b) The field is PROC. - * 3) The requester has requested processGet and the record is passive. - * - * iocInit calls processNotifyInit. - * - * The other global routines (dbNotifyAdd and dbNotifyCompletion) are called by: - * - * dbAccess.c - * dbScanPassive and dbScanLink - * call dbNotifyAdd just before calling dbProcess - * dbProcess - * Calls dbNotifyCompletion if dbProcess does not call process - * Unless pact is already true. - * recGbl - * recGblFwdLink calls dbNotifyCompletion - * - * Two fields in dbCommon are used for put notify. - * ppn pointer to processNotify - * If a record is part of a put notify group, - * This field is the address of the associated processNotify. - * As soon as a record completes processing the field is set NULL - * ppnr pointer to processNotifyRecord, which is a private structure - * owned by dbNotify. - * dbNotify is reponsible for this structure. - * - */ -#ifdef __cplusplus -} -#endif - -#endif /*INCdbNotifyh*/ - diff --git a/src/ioc/db/dbPutNotifyBlocker.cpp b/src/ioc/db/dbPutNotifyBlocker.cpp deleted file mode 100644 index 1a796cdbd..000000000 --- a/src/ioc/db/dbPutNotifyBlocker.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: - * Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#include -#include - -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsTime.h" -#include "tsFreeList.h" -#include "errMdef.h" -#include "errlog.h" - -#include "caerr.h" // this needs to be eliminated -#include "db_access.h" // this needs to be eliminated - -#define epicsExportSharedSymbols -#include "dbCAC.h" -#include "dbChannelIO.h" -#include "dbPutNotifyBlocker.h" - -dbPutNotifyBlocker::dbPutNotifyBlocker ( epicsMutex & mutexIn ) : - mutex ( mutexIn ), pNotify ( 0 ), - maxValueSize ( sizeof ( this->dbrScalarValue ) ) -{ - memset ( & this->pn, '\0', sizeof ( this->pn ) ); - memset ( & this->dbrScalarValue, '\0', sizeof ( this->dbrScalarValue ) ); - this->pbuffer = & this->dbrScalarValue; -} - -dbPutNotifyBlocker::~dbPutNotifyBlocker () -{ -} - -void dbPutNotifyBlocker::destructor ( CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->cancel ( cbGuard, guard ); - if ( this->maxValueSize > sizeof ( this->dbrScalarValue ) ) { - char * pBuf = static_cast < char * > ( this->pbuffer ); - delete [] pBuf; - } - this->~dbPutNotifyBlocker (); -} - -void dbPutNotifyBlocker::cancel ( - CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->pNotify ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - dbNotifyCancel ( &this->pn ); - } - this->pNotify = 0; - this->block.signal (); -} - -void dbPutNotifyBlocker::expandValueBuf ( - epicsGuard < epicsMutex > & guard, unsigned long newSize ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->maxValueSize < newSize ) { - if ( this->maxValueSize > sizeof ( this->dbrScalarValue ) ) { - char * pBuf = static_cast < char * > ( this->pbuffer ); - delete [] pBuf; - this->maxValueSize = sizeof ( this->dbrScalarValue ); - this->pbuffer = & this->dbrScalarValue; - } - this->pbuffer = new char [newSize]; - this->maxValueSize = newSize; - } -} - -extern "C" int putNotifyPut ( processNotify *ppn, notifyPutType type ) -{ - if(ppn->status==notifyCanceled) return 0; -/* - * No locking in this method because only a dbNotifyCancel could interrupt - * and it does not return until cancel is done. - */ - dbPutNotifyBlocker * pBlocker = static_cast < dbPutNotifyBlocker * > ( ppn->usrPvt ); - return db_put_process(ppn,type, - pBlocker->dbrType,pBlocker->pbuffer,pBlocker->nRequest); -} - -extern "C" void putNotifyCompletion ( processNotify *ppn ) -{ - dbPutNotifyBlocker * const pBlocker = - static_cast < dbPutNotifyBlocker * > ( ppn->usrPvt ); - epicsGuard < epicsMutex > guard ( pBlocker->mutex ); - cacWriteNotify * const pNtfy = pBlocker->pNotify; - if ( pNtfy ) { - pBlocker->pNotify = 0; - // Its necessary to signal the initiators now before we call - // the user callback. This is less efficent, and potentially - // causes more thread context switching, but its probably - // unavoidable because its possible that the use callback - // might destroy this object. - pBlocker->block.signal (); - if ( pBlocker->pn.status != notifyOK ) { - pNtfy->exception ( - guard, ECA_PUTFAIL, "put notify unsuccessful", - static_cast < unsigned > (pBlocker->dbrType), - static_cast < unsigned > (pBlocker->nRequest) ); - } - else { - pNtfy->completion ( guard ); - } - } - else { - errlogPrintf ( "put notify completion with nill pNotify?\n" ); - } -} - -void dbPutNotifyBlocker::initiatePutNotify ( - epicsGuard < epicsMutex > & guard, cacWriteNotify & notify, - struct dbChannel * dbch, unsigned type, unsigned long count, - const void * pValue ) -{ - guard. assertIdenticalMutex ( this->mutex ); - epicsTime begin; - bool beginTimeInit = false; - while ( true ) { - if ( this->pNotify == 0 ) { - this->pNotify = & notify; - break; - } - if ( beginTimeInit ) { - if ( epicsTime::getCurrent () - begin > 30.0 ) { - throw cacChannel::requestTimedOut (); - } - } - else { - begin = epicsTime::getCurrent (); - beginTimeInit = true; - } - { - epicsGuardRelease < epicsMutex > autoRelease ( guard ); - this->block.wait ( 1.0 ); - } - } - - if ( count > LONG_MAX ) { - throw cacChannel::outOfBounds(); - } - - if ( type > SHRT_MAX ) { - throw cacChannel::badType(); - } - - this->dbrType = type; - this->nRequest = static_cast < unsigned > ( count ); - this->pn.requestType = putProcessRequest; - this->pn.chan = dbch; - this->pn.putCallback = putNotifyPut; - this->pn.doneCallback = putNotifyCompletion; - this->pn.usrPvt = this; - - unsigned long size = dbr_size_n ( type, count ); - this->expandValueBuf ( guard, size ); - memcpy ( this->pbuffer, pValue, size ); - - { - epicsGuardRelease < epicsMutex > autoRelease ( guard ); - ::dbProcessNotify ( &this->pn ); - } -} - -void dbPutNotifyBlocker::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->show ( guard, level ); -} - -void dbPutNotifyBlocker::show ( - epicsGuard < epicsMutex > &, unsigned level ) const -{ - printf ( "put notify blocker at %p\n", - static_cast ( this ) ); - if ( level > 0u ) { - this->block.show ( level - 1u ); - } -} - -dbSubscriptionIO * dbPutNotifyBlocker::isSubscription () -{ - return 0; -} - -void * dbPutNotifyBlocker::operator new ( size_t size, - tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -void dbPutNotifyBlocker::operator delete ( void *pCadaver, - tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -void dbPutNotifyBlocker::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} diff --git a/src/ioc/db/dbPutNotifyBlocker.h b/src/ioc/db/dbPutNotifyBlocker.h deleted file mode 100644 index 6ca11cc5d..000000000 --- a/src/ioc/db/dbPutNotifyBlocker.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef dbPutNotifyBlockerh -#define dbPutNotifyBlockerh - -#ifdef epicsExportSharedSymbols -#define dbPutNotifyBlockerh_restore_epicsExportSharedSymbols -#undef epicsExportSharedSymbols -#endif - -#include "tsFreeList.h" -#include "compilerDependencies.h" - -#ifdef dbPutNotifyBlockerh_restore_epicsExportSharedSymbols -#define epicsExportSharedSymbols -#endif - -class dbPutNotifyBlocker : public dbBaseIO { -public: - dbPutNotifyBlocker ( epicsMutex & ); - void destructor ( CallbackGuard &, epicsGuard < epicsMutex > & ); - void initiatePutNotify ( epicsGuard < epicsMutex > &, - cacWriteNotify &, struct dbChannel *, - unsigned type, unsigned long count, const void * pValue ); - void cancel ( CallbackGuard &, epicsGuard < epicsMutex > & ); - void show ( epicsGuard < epicsMutex > &, unsigned level ) const; - void show ( unsigned level ) const; - void * operator new ( size_t size, - tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < dbPutNotifyBlocker, 64, epicsMutexNOOP > & )) -private: - processNotify pn; - // - // Include a union of all scalar types - // including fixed length strings so - // that in many cases we can avoid - // allocating another buffer - // - union { - dbr_string_t strval; - dbr_short_t shrtval; - dbr_short_t intval; - dbr_float_t fltval; - dbr_enum_t enmval; - dbr_char_t charval; - dbr_long_t longval; - dbr_double_t doubleval; - } dbrScalarValue; - epicsEvent block; - epicsMutex & mutex; - cacWriteNotify * pNotify; - unsigned long maxValueSize; - // arguments for db_put_field - void *pbuffer; - long nRequest; - short dbrType; - // end arguments for db_put_field - dbSubscriptionIO * isSubscription (); - void expandValueBuf ( - epicsGuard < epicsMutex > &, unsigned long newSize ); - friend void putNotifyCompletion ( processNotify * ppn ); - friend int putNotifyPut ( processNotify *ppn, notifyPutType type ); - dbPutNotifyBlocker ( const dbPutNotifyBlocker & ); - dbPutNotifyBlocker & operator = ( const dbPutNotifyBlocker & ); - virtual ~dbPutNotifyBlocker (); - void operator delete ( void * ); -}; - -#endif // ifndef dbPutNotifyBlockerh - diff --git a/src/ioc/db/dbScan.c b/src/ioc/db/dbScan.c deleted file mode 100644 index 9f7df4c17..000000000 --- a/src/ioc/db/dbScan.c +++ /dev/null @@ -1,1069 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 Helmholtz-Zentrum Berlin -* für Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbScan.c */ -/* tasks and subroutines to scan the database */ -/* - * Original Authors: Bob Dalesio & Marty Kraimer - */ - -#include -#include -#include -#include -#include -#include - -#include "cantProceed.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsPrint.h" -#include "epicsRingBytes.h" -#include "epicsStdio.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "taskwd.h" - -#define epicsExportSharedSymbols -#include "callback.h" -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbCommon.h" -#include "dbFldTypes.h" -#include "dbLock.h" -#include "dbScan.h" -#include "dbStaticLib.h" -#include "devSup.h" -#include "link.h" -#include "recGbl.h" - - -/* Task Control */ -enum ctl {ctlInit, ctlRun, ctlPause, ctlExit}; - -/* Task Startup/Shutdown Synchronization */ -static epicsEventId startStopEvent; - -static volatile enum ctl scanCtl; - -/* SCAN ONCE */ - -static int onceQueueSize = 1000; -static epicsEventId onceSem; -static epicsRingBytesId onceQ; -static epicsThreadId onceTaskId; -static void *exitOnce; - - -/* All other scan types */ -typedef struct scan_list{ - epicsMutexId lock; - ELLLIST list; - short modified;/*has list been modified?*/ -} scan_list; -/*scan_elements are allocated and the address stored in dbCommon.spvt*/ -typedef struct scan_element{ - ELLNODE node; - scan_list *pscan_list; - struct dbCommon *precord; -} scan_element; - - -/* PERIODIC */ - -#define OVERRUN_REPORT_DELAY 10.0 /* Time between initial reports */ -#define OVERRUN_REPORT_MAX 3600.0 /* Maximum time between reports */ -typedef struct periodic_scan_list { - scan_list scan_list; - double period; - const char *name; - unsigned long overruns; - volatile enum ctl scanCtl; - epicsEventId loopEvent; -} periodic_scan_list; - -static int nPeriodic = 0; -static periodic_scan_list **papPeriodic; /* pointer to array of pointers */ -static epicsThreadId *periodicTaskId; /* array of thread ids */ - - -static char *priorityName[NUM_CALLBACK_PRIORITIES] = { - "Low", "Medium", "High" -}; - - -/* EVENT */ - -typedef struct event_list { - CALLBACK callback[NUM_CALLBACK_PRIORITIES]; - scan_list scan_list[NUM_CALLBACK_PRIORITIES]; - struct event_list *next; - char event_name[MAX_STRING_SIZE]; -} event_list; -static event_list * volatile pevent_list[256]; -static epicsMutexId event_lock; - -/* IO_EVENT*/ - -typedef struct io_scan_list { - CALLBACK callback; - scan_list scan_list; -} io_scan_list; - -typedef struct ioscan_head { - struct ioscan_head *next; - struct io_scan_list iosl[NUM_CALLBACK_PRIORITIES]; - io_scan_complete cb; - void *arg; -} ioscan_head; - -static ioscan_head *pioscan_list = NULL; -static epicsMutexId ioscan_lock; - -/* Private routines */ -static void onceTask(void *); -static void initOnce(void); -static void periodicTask(void *arg); -static void initPeriodic(void); -static void deletePeriodic(void); -static void spawnPeriodic(int ind); -static void eventCallback(CALLBACK *pcallback); -static void ioscanInit(void); -static void ioscanCallback(CALLBACK *pcallback); -static void ioscanDestroy(void); -static void printList(scan_list *psl, char *message); -static void scanList(scan_list *psl); -static void buildScanLists(void); -static void addToList(struct dbCommon *precord, scan_list *psl); -static void deleteFromList(struct dbCommon *precord, scan_list *psl); - -void scanStop(void) -{ - int i; - - if (scanCtl == ctlExit) return; - scanCtl = ctlExit; - - interruptAccept = FALSE; - - for (i = 0; i < nPeriodic; i++) { - periodic_scan_list *ppsl = papPeriodic[i]; - - if (!ppsl) continue; - ppsl->scanCtl = ctlExit; - epicsEventSignal(ppsl->loopEvent); - epicsEventWait(startStopEvent); - } - - scanOnce((dbCommon *)&exitOnce); - epicsEventWait(startStopEvent); -} - -void scanCleanup(void) -{ - - deletePeriodic(); - ioscanDestroy(); - - epicsRingBytesDelete(onceQ); - - free(periodicTaskId); - papPeriodic = NULL; - periodicTaskId = NULL; -} - -long scanInit(void) -{ - int i; - - if(!startStopEvent) - startStopEvent = epicsEventMustCreate(epicsEventEmpty); - scanCtl = ctlPause; - - initPeriodic(); - initOnce(); - buildScanLists(); - for (i = 0; i < nPeriodic; i++) - spawnPeriodic(i); - - return 0; -} - -void scanRun(void) -{ - int i; - - interruptAccept = TRUE; - scanCtl = ctlRun; - - for (i = 0; i < nPeriodic; i++) { - periodic_scan_list *ppsl = papPeriodic[i]; - - if (!ppsl) continue; - ppsl->scanCtl = ctlRun; - } -} - -void scanPause(void) -{ - int i; - - for (i = nPeriodic - 1; i >= 0; --i) { - periodic_scan_list *ppsl = papPeriodic[i]; - - if (!ppsl) continue; - ppsl->scanCtl = ctlPause; - } - - scanCtl = ctlPause; - interruptAccept = FALSE; -} - -void scanAdd(struct dbCommon *precord) -{ - int scan; - - /* get the list on which this record belongs */ - scan = precord->scan; - if (scan == menuScanPassive) return; - if (scan < 0 || scan >= nPeriodic + SCAN_1ST_PERIODIC) { - recGblRecordError(-1, (void *)precord, - "scanAdd detected illegal SCAN value"); - } else if (scan == menuScanEvent) { - char* eventname; - int prio; - event_list *pel; - - eventname = precord->evnt; - if (strlen(eventname) >= MAX_STRING_SIZE) { - recGblRecordError(S_db_badField, (void *)precord, - "scanAdd: too long EVNT value"); - return; - } - prio = precord->prio; - if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { - recGblRecordError(-1, (void *)precord, - "scanAdd: illegal prio field"); - return; - } - pel = eventNameToHandle(eventname); - if (pel) addToList(precord, &pel->scan_list[prio]); - } else if (scan == menuScanI_O_Intr) { - ioscan_head *piosh = NULL; - int prio; - DEVSUPFUN get_ioint_info; - - if (precord->dset == NULL){ - recGblRecordError(-1, (void *)precord, - "scanAdd: I/O Intr not valid (no DSET) "); - precord->scan = menuScanPassive; - return; - } - get_ioint_info = precord->dset->get_ioint_info; - if (get_ioint_info == NULL) { - recGblRecordError(-1, (void *)precord, - "scanAdd: I/O Intr not valid (no get_ioint_info)"); - precord->scan = menuScanPassive; - return; - } - if (get_ioint_info(0, precord, &piosh)) { - precord->scan = menuScanPassive; - return; - } - if (piosh == NULL) { - recGblRecordError(-1, (void *)precord, - "scanAdd: I/O Intr not valid"); - precord->scan = menuScanPassive; - return; - } - prio = precord->prio; - if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { - recGblRecordError(-1, (void *)precord, - "scanAdd: illegal prio field"); - precord->scan = menuScanPassive; - return; - } - addToList(precord, &piosh->iosl[prio].scan_list); - } else if (scan >= SCAN_1ST_PERIODIC) { - periodic_scan_list *ppsl = papPeriodic[scan - SCAN_1ST_PERIODIC]; - - if (ppsl) - addToList(precord, &ppsl->scan_list); - } -} - -void scanDelete(struct dbCommon *precord) -{ - short scan; - - /* get the list on which this record belongs */ - scan = precord->scan; - if (scan == menuScanPassive) return; - if (scan < 0 || scan >= nPeriodic + SCAN_1ST_PERIODIC) { - recGblRecordError(-1, (void *)precord, - "scanDelete detected illegal SCAN value"); - } else if (scan == menuScanEvent) { - char* eventname; - int prio; - event_list *pel; - scan_list *psl = 0; - - eventname = precord->evnt; - prio = precord->prio; - if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { - recGblRecordError(-1, (void *)precord, - "scanDelete detected illegal PRIO field"); - return; - } - do /* multithreading: make sure pel is consistent */ - pel = pevent_list[0]; - while (pel != pevent_list[0]); - for (; pel; pel=pel->next) { - if (strcmp(pel->event_name, eventname) == 0) break; - } - if (pel && (psl = &pel->scan_list[prio])) - deleteFromList(precord, psl); - } else if (scan == menuScanI_O_Intr) { - ioscan_head *piosh = NULL; - int prio; - DEVSUPFUN get_ioint_info; - - if (precord->dset==NULL) { - recGblRecordError(-1, (void *)precord, - "scanDelete: I/O Intr not valid (no DSET)"); - return; - } - get_ioint_info=precord->dset->get_ioint_info; - if (get_ioint_info == NULL) { - recGblRecordError(-1, (void *)precord, - "scanDelete: I/O Intr not valid (no get_ioint_info)"); - return; - } - if (get_ioint_info(1, precord, &piosh)) return; - if (piosh == NULL) { - recGblRecordError(-1, (void *)precord, - "scanDelete: I/O Intr not valid"); - return; - } - prio = precord->prio; - if (prio < 0 || prio >= NUM_CALLBACK_PRIORITIES) { - recGblRecordError(-1, (void *)precord, - "scanDelete: get_ioint_info returned illegal priority"); - return; - } - deleteFromList(precord, &piosh->iosl[prio].scan_list); - } else if (scan >= SCAN_1ST_PERIODIC) { - periodic_scan_list *ppsl = papPeriodic[scan - SCAN_1ST_PERIODIC]; - - if (ppsl) - deleteFromList(precord, &ppsl->scan_list); - } -} - -double scanPeriod(int scan) { - periodic_scan_list *ppsl; - - scan -= SCAN_1ST_PERIODIC; - if (scan < 0 || scan >= nPeriodic) - return 0.0; - ppsl = papPeriodic[scan]; - return ppsl ? ppsl->period : 0.0; -} - -int scanppl(double period) /* print periodic scan list(s) */ -{ - dbMenu *pmenu = dbFindMenu(pdbbase, "menuScan"); - char message[80]; - int i; - - if (!pmenu || !papPeriodic) { - printf("scanppl: dbScan subsystem not initialized\n"); - return -1; - } - - for (i = 0; i < nPeriodic; i++) { - periodic_scan_list *ppsl = papPeriodic[i]; - - if (!ppsl) { - const char *choice = pmenu->papChoiceValue[i + SCAN_1ST_PERIODIC]; - - printf("Periodic scan list for SCAN = '%s' not initialized\n", - choice); - continue; - } - if (period > 0.0 && - (fabs(period - ppsl->period) > 0.05)) - continue; - - sprintf(message, "Records with SCAN = '%s' (%lu over-runs):", - ppsl->name, ppsl->overruns); - printList(&ppsl->scan_list, message); - } - return 0; -} - -int scanpel(const char* eventname) /* print event list */ -{ - char message[80]; - int prio; - event_list *pel; - - do /* multithreading: make sure pel is consistent */ - pel = pevent_list[0]; - while (pel != pevent_list[0]); - for (; pel; pel = pel->next) { - if (!eventname || strcmp(pel->event_name, eventname) == 0) { - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - if (ellCount(&pel->scan_list[prio].list) == 0) continue; - sprintf(message, "Event \"%s\" Priority %s", pel->event_name, priorityName[prio]); - printList(&pel->scan_list[prio], message); - } - } - } - return 0; -} - -int scanpiol(void) /* print pioscan_list */ -{ - ioscan_head *piosh; - - ioscanInit(); - epicsMutexMustLock(ioscan_lock); - piosh = pioscan_list; - - while (piosh) { - int prio; - - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - io_scan_list *piosl = &piosh->iosl[prio]; - char message[80]; - - sprintf(message, "IO Event %p: Priority %s", - piosh, priorityName[prio]); - printList(&piosl->scan_list, message); - } - piosh = piosh->next; - } - epicsMutexUnlock(ioscan_lock); - return 0; -} - -static void eventCallback(CALLBACK *pcallback) -{ - scan_list *psl; - - callbackGetUser(psl, pcallback); - scanList(psl); -} - -static void eventOnce(void *arg) -{ - event_lock = epicsMutexMustCreate(); -} - -event_list *eventNameToHandle(const char *eventname) -{ - int prio; - event_list *pel; - static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - - if (!eventname || eventname[0] == 0) - return NULL; - - epicsThreadOnce(&onceId, eventOnce, NULL); - epicsMutexMustLock(event_lock); - for (pel = pevent_list[0]; pel; pel=pel->next) { - if (strcmp(pel->event_name, eventname) == 0) break; - } - if (pel == NULL) { - pel = calloc(1, sizeof(event_list)); - if (!pel) - goto done; - strcpy(pel->event_name, eventname); - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - callbackSetUser(&pel->scan_list[prio], &pel->callback[prio]); - callbackSetPriority(prio, &pel->callback[prio]); - callbackSetCallback(eventCallback, &pel->callback[prio]); - pel->scan_list[prio].lock = epicsMutexMustCreate(); - ellInit(&pel->scan_list[prio].list); - } - pel->next=pevent_list[0]; - pevent_list[0]=pel; - { /* backward compatibility */ - char* p; - long e = strtol(eventname, &p, 0); - if (*p == 0 && e > 0 && e <= 255) - pevent_list[e] = pel; - } - } -done: - epicsMutexUnlock(event_lock); - return pel; -} - -void postEvent(event_list *pel) -{ - int prio; - - if (scanCtl != ctlRun) return; - if (!pel) return; - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - if (ellCount(&pel->scan_list[prio].list) >0) - callbackRequest(&pel->callback[prio]); - } -} - -/* backward compatibility */ -void post_event(int event) -{ - event_list* pel; - - if (event <= 0 || event > 255) return; - do { /* multithreading: make sure pel is consistent */ - pel = pevent_list[event]; - } while (pel != pevent_list[event]); - postEvent(pel); -} - -static void ioscanOnce(void *arg) -{ - ioscan_lock = epicsMutexMustCreate(); -} - -static void ioscanInit(void) -{ - static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - - epicsThreadOnce(&onceId, ioscanOnce, NULL); -} - -static void ioscanDestroy(void) -{ - ioscan_head *piosh; - - ioscanInit(); - epicsMutexMustLock(ioscan_lock); - piosh = pioscan_list; - pioscan_list = NULL; - epicsMutexUnlock(ioscan_lock); - while (piosh) { - ioscan_head *pnext = piosh->next; - int prio; - - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - epicsMutexDestroy(piosh->iosl[prio].scan_list.lock); - ellFree(&piosh->iosl[prio].scan_list.list); - } - free(piosh); - piosh = pnext; - } -} - -void scanIoInit(IOSCANPVT *pioscanpvt) -{ - ioscan_head *piosh = dbCalloc(1, sizeof(ioscan_head)); - int prio; - - ioscanInit(); - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - io_scan_list *piosl = &piosh->iosl[prio]; - - callbackSetCallback(ioscanCallback, &piosl->callback); - callbackSetPriority(prio, &piosl->callback); - callbackSetUser(piosh, &piosl->callback); - ellInit(&piosl->scan_list.list); - piosl->scan_list.lock = epicsMutexMustCreate(); - } - epicsMutexMustLock(ioscan_lock); - piosh->next = pioscan_list; - pioscan_list = piosh; - epicsMutexUnlock(ioscan_lock); - *pioscanpvt = piosh; -} - -/* Return a bit mask indicating each priority level - * in which a callback request was successfully queued. - */ -unsigned int scanIoRequest(IOSCANPVT piosh) -{ - int prio; - unsigned int queued = 0; - - if (scanCtl != ctlRun) - return 0; - - for (prio = 0; prio < NUM_CALLBACK_PRIORITIES; prio++) { - io_scan_list *piosl = &piosh->iosl[prio]; - - if (ellCount(&piosl->scan_list.list) > 0) - if (!callbackRequest(&piosl->callback)) - queued |= 1 << prio; - } - - return queued; -} - -unsigned int scanIoImmediate(IOSCANPVT piosh, int prio) -{ - io_scan_list *piosl; - - if (prio<0 || prio>=NUM_CALLBACK_PRIORITIES) - return S_db_errArg; - else if (scanCtl != ctlRun) - return 0; - - piosl = &piosh->iosl[prio]; - - if (ellCount(&piosl->scan_list.list) == 0) - return 0; - - scanList(&piosl->scan_list); - - if (piosh->cb) - piosh->cb(piosh->arg, piosh, prio); - - return 1 << prio; -} - -/* May not be called while a scan request is queued or running */ -void scanIoSetComplete(IOSCANPVT piosh, io_scan_complete cb, void *arg) -{ - piosh->cb = cb; - piosh->arg = arg; -} - -int scanOnce(struct dbCommon *precord) { - return scanOnceCallback(precord, NULL, NULL); -} - -typedef struct { - struct dbCommon *prec; - once_complete cb; - void *usr; -} onceEntry; - -int scanOnceCallback(struct dbCommon *precord, once_complete cb, void *usr) -{ - static int newOverflow = TRUE; - onceEntry ent; - int pushOK; - - ent.prec = precord; - ent.cb = cb; - ent.usr = usr; - - pushOK = epicsRingBytesPut(onceQ, (void*)&ent, sizeof(ent)); - - if (!pushOK) { - if (newOverflow) errlogPrintf("scanOnce: Ring buffer overflow\n"); - newOverflow = FALSE; - } else { - newOverflow = TRUE; - } - epicsEventSignal(onceSem); - - return !pushOK; -} - -static void onceTask(void *arg) -{ - taskwdInsert(0, NULL, NULL); - epicsEventSignal(startStopEvent); - - while (TRUE) { - - epicsEventMustWait(onceSem); - while(1) { - onceEntry ent; - int bytes = epicsRingBytesGet(onceQ, (void*)&ent, sizeof(ent)); - if(bytes==0) - break; - if(bytes!=sizeof(ent)) { - errlogPrintf("onceTask: received incomplete %d of %u\n", - bytes, (unsigned)sizeof(ent)); - continue; /* what to do? */ - } else if (ent.prec == (void*)&exitOnce) goto shutdown; - - dbScanLock(ent.prec); - dbProcess(ent.prec); - dbScanUnlock(ent.prec); - if(ent.cb) - ent.cb(ent.usr, ent.prec); - } - } - -shutdown: - taskwdRemove(0); - epicsEventSignal(startStopEvent); -} - -int scanOnceSetQueueSize(int size) -{ - onceQueueSize = size; - return 0; -} - -static void initOnce(void) -{ - if ((onceQ = epicsRingBytesLockedCreate(sizeof(onceEntry)*onceQueueSize)) == NULL) { - cantProceed("initOnce: Ring buffer create failed\n"); - } - if(!onceSem) - onceSem = epicsEventMustCreate(epicsEventEmpty); - onceTaskId = epicsThreadCreate("scanOnce", - epicsThreadPriorityScanLow + nPeriodic, - epicsThreadGetStackSize(epicsThreadStackBig), onceTask, 0); - - epicsEventWait(startStopEvent); -} - -static void periodicTask(void *arg) -{ - periodic_scan_list *ppsl = (periodic_scan_list *)arg; - epicsTimeStamp next, reported; - unsigned int overruns = 0; - double report_delay = OVERRUN_REPORT_DELAY; - double overtime = 0.0; - double over_min = 0.0; - double over_max = 0.0; - const double penalty = (ppsl->period >= 2) ? 1 : (ppsl->period / 2); - - taskwdInsert(0, NULL, NULL); - epicsEventSignal(startStopEvent); - - epicsTimeGetCurrent(&next); - reported = next; - - while (ppsl->scanCtl != ctlExit) { - double delay; - epicsTimeStamp now; - - if (ppsl->scanCtl == ctlRun) - scanList(&ppsl->scan_list); - - epicsTimeAddSeconds(&next, ppsl->period); - epicsTimeGetCurrent(&now); - delay = epicsTimeDiffInSeconds(&next, &now); - if (delay <= 0.0) { - if (overtime == 0.0) { - overtime = over_min = over_max = -delay; - } - else { - overtime -= delay; - if (over_min + delay > 0) - over_min = -delay; - if (over_max + delay < 0) - over_max = -delay; - } - delay = penalty; - ppsl->overruns++; - next = now; - epicsTimeAddSeconds(&next, delay); - if (++overruns >= 10 && - epicsTimeDiffInSeconds(&now, &reported) > report_delay) { - errlogPrintf("\ndbScan warning from '%s' scan thread:\n" - "\tScan processing averages %.3f seconds (%.3f .. %.3f).\n" - "\tOver-runs have now happened %u times in a row.\n" - "\tTo fix this, move some records to a slower scan rate.\n", - ppsl->name, ppsl->period + overtime / overruns, - ppsl->period + over_min, ppsl->period + over_max, overruns); - - reported = now; - if (report_delay < (OVERRUN_REPORT_MAX / 2)) - report_delay *= 2; - else - report_delay = OVERRUN_REPORT_MAX; - } - } - else { - overruns = 0; - report_delay = OVERRUN_REPORT_DELAY; - overtime = 0.0; - } - - epicsEventWaitWithTimeout(ppsl->loopEvent, delay); - } - - taskwdRemove(0); - epicsEventSignal(startStopEvent); -} - - -static void initPeriodic(void) -{ - dbMenu *pmenu = dbFindMenu(pdbbase, "menuScan"); - double quantum = epicsThreadSleepQuantum(); - int i; - - if (!pmenu) { - errlogPrintf("initPeriodic: menuScan not present\n"); - return; - } - nPeriodic = pmenu->nChoice - SCAN_1ST_PERIODIC; - papPeriodic = dbCalloc(nPeriodic, sizeof(periodic_scan_list*)); - periodicTaskId = dbCalloc(nPeriodic, sizeof(void *)); - for (i = 0; i < nPeriodic; i++) { - periodic_scan_list *ppsl = dbCalloc(1, sizeof(periodic_scan_list)); - const char *choice = pmenu->papChoiceValue[i + SCAN_1ST_PERIODIC]; - double number; - char *unit; - int status = epicsParseDouble(choice, &number, &unit); - - if (status || number <= 0) { - errlogPrintf("initPeriodic: Bad menuScan choice '%s'\n", choice); - } - else if (!*unit || - !epicsStrCaseCmp(unit, "second") || - !epicsStrCaseCmp(unit, "seconds")) { - ppsl->period = number; - } - else if (!epicsStrCaseCmp(unit, "minute") || - !epicsStrCaseCmp(unit, "minutes")) { - ppsl->period = number * 60; - } - else if (!epicsStrCaseCmp(unit, "hour") || - !epicsStrCaseCmp(unit, "hours")) { - ppsl->period = number * 60 * 60; - } - else if (!epicsStrCaseCmp(unit, "Hz") || - !epicsStrCaseCmp(unit, "Hertz")) { - ppsl->period = 1 / number; - } - else { - errlogPrintf("initPeriodic: Bad menuScan choice '%s'\n", choice); - } - if (ppsl->period == 0) { - free(ppsl); - continue; - } - - ppsl->scan_list.lock = epicsMutexMustCreate(); - ellInit(&ppsl->scan_list.list); - ppsl->name = choice; - ppsl->scanCtl = ctlPause; - ppsl->loopEvent = epicsEventMustCreate(epicsEventEmpty); - - number = ppsl->period / quantum; - if ((ppsl->period < 2 * quantum) || - (number / floor(number) > 1.1)) { - errlogPrintf("initPeriodic: Scan rate '%s' is not achievable.\n", - choice); - } - - papPeriodic[i] = ppsl; - } -} - -static void deletePeriodic(void) -{ - int i; - - for (i = 0; i < nPeriodic; i++) { - periodic_scan_list *ppsl = papPeriodic[i]; - - if (!ppsl) continue; - ellFree(&ppsl->scan_list.list); - epicsEventDestroy(ppsl->loopEvent); - epicsMutexDestroy(ppsl->scan_list.lock); - free(ppsl); - } - - free(papPeriodic); - papPeriodic = NULL; -} - -static void spawnPeriodic(int ind) -{ - periodic_scan_list *ppsl = papPeriodic[ind]; - char taskName[20]; - - if (!ppsl) return; - - sprintf(taskName, "scan-%g", ppsl->period); - periodicTaskId[ind] = epicsThreadCreate( - taskName, epicsThreadPriorityScanLow + ind, - epicsThreadGetStackSize(epicsThreadStackBig), - periodicTask, (void *)ppsl); - - epicsEventWait(startStopEvent); -} - -static void ioscanCallback(CALLBACK *pcallback) -{ - ioscan_head *piosh; - int prio; - - callbackGetUser(piosh, pcallback); - callbackGetPriority(prio, pcallback); - scanList(&piosh->iosl[prio].scan_list); - if (piosh->cb) - piosh->cb(piosh->arg, piosh, prio); -} - -static void printList(scan_list *psl, char *message) -{ - scan_element *pse; - - epicsMutexMustLock(psl->lock); - pse = (scan_element *)ellFirst(&psl->list); - epicsMutexUnlock(psl->lock); - - if (!pse) - return; - - printf("%s\n", message); - while (pse) { - printf(" %-28s\n", pse->precord->name); - epicsMutexMustLock(psl->lock); - if (pse->pscan_list != psl) { - epicsMutexUnlock(psl->lock); - printf(" Scan list changed while printing, try again.\n"); - return; - } - pse = (scan_element *)ellNext(&pse->node); - epicsMutexUnlock(psl->lock); - } -} - -static void scanList(scan_list *psl) -{ - /* When reading this code remember that the call to dbProcess can result - * in the SCAN field being changed in an arbitrary number of records. - */ - - scan_element *pse; - scan_element *prev = NULL; - scan_element *next = NULL; - - epicsMutexMustLock(psl->lock); - psl->modified = FALSE; - pse = (scan_element *)ellFirst(&psl->list); - if (pse) next = (scan_element *)ellNext(&pse->node); - epicsMutexUnlock(psl->lock); - - while (pse) { - struct dbCommon *precord = pse->precord; - - dbScanLock(precord); - dbProcess(precord); - dbScanUnlock(precord); - - epicsMutexMustLock(psl->lock); - if (!psl->modified) { - prev = pse; - pse = (scan_element *)ellNext(&pse->node); - if (pse) next = (scan_element *)ellNext(&pse->node); - } else if (pse->pscan_list == psl) { - /*This scan element is still in same scan list*/ - prev = pse; - pse = (scan_element *)ellNext(&pse->node); - if (pse) next = (scan_element *)ellNext(&pse->node); - psl->modified = FALSE; - } else if (prev && prev->pscan_list == psl) { - /*Previous scan element is still in same scan list*/ - pse = (scan_element *)ellNext(&prev->node); - if (pse) { - prev = (scan_element *)ellPrevious(&pse->node); - next = (scan_element *)ellNext(&pse->node); - } - psl->modified = FALSE; - } else if (next && next->pscan_list == psl) { - /*Next scan element is still in same scan list*/ - pse = next; - prev = (scan_element *)ellPrevious(&pse->node); - next = (scan_element *)ellNext(&pse->node); - psl->modified = FALSE; - } else { - /*Too many changes. Just wait till next period*/ - epicsMutexUnlock(psl->lock); - return; - } - epicsMutexUnlock(psl->lock); - } -} - -static void buildScanLists(void) -{ - dbRecordType *pdbRecordType; - - for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; - pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - dbRecordNode *pdbRecordNode; - - for (pdbRecordNode = (dbRecordNode *)ellFirst(&pdbRecordType->recList); - pdbRecordNode; - pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) { - dbCommon *precord = pdbRecordNode->precord; - - if (!precord->name[0] || - pdbRecordNode->flags & DBRN_FLAGS_ISALIAS) - continue; - - scanAdd(precord); - } - } -} - -static void addToList(struct dbCommon *precord, scan_list *psl) -{ - scan_element *pse, *ptemp; - - epicsMutexMustLock(psl->lock); - pse = precord->spvt; - if (pse == NULL) { - pse = dbCalloc(1, sizeof(scan_element)); - precord->spvt = pse; - pse->precord = precord; - } - pse->pscan_list = psl; - ptemp = (scan_element *)ellLast(&psl->list); - while (ptemp) { - if (ptemp->precord->phas <= precord->phas) { - ellInsert(&psl->list, &ptemp->node, &pse->node); - break; - } - ptemp = (scan_element *)ellPrevious(&ptemp->node); - } - if (ptemp == NULL) ellAdd(&psl->list, (void *)pse); - psl->modified = TRUE; - epicsMutexUnlock(psl->lock); -} - -static void deleteFromList(struct dbCommon *precord, scan_list *psl) -{ - scan_element *pse; - - epicsMutexMustLock(psl->lock); - pse = precord->spvt; - if (pse == NULL) { - epicsMutexUnlock(psl->lock); - errlogPrintf("dbScan: Tried to delete record from wrong scan list!\n" - "\t%s.SPVT = NULL, but psl = %p\n", - precord->name, (void *)psl); - return; - } - if (pse->pscan_list != psl) { - epicsMutexUnlock(psl->lock); - errlogPrintf("dbScan: Tried to delete record from wrong scan list!\n" - "\t%s.SPVT->pscan_list = %p but psl = %p\n", - precord->name, (void *)pse, (void *)psl); - return; - } - pse->pscan_list = NULL; - ellDelete(&psl->list, (void *)pse); - psl->modified = TRUE; - epicsMutexUnlock(psl->lock); -} diff --git a/src/ioc/db/dbScan.h b/src/ioc/db/dbScan.h deleted file mode 100644 index 4ec6dda60..000000000 --- a/src/ioc/db/dbScan.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Marty Kraimer - * Date: 07-17-91 - */ - -#ifndef INCdbScanH -#define INCdbScanH - -#include - -#include "menuScan.h" -#include "shareLib.h" -#include "compilerDependencies.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SCAN_PASSIVE menuScanPassive -#define SCAN_EVENT menuScanEvent -#define SCAN_IO_EVENT menuScanI_O_Intr -#define SCAN_1ST_PERIODIC (menuScanI_O_Intr + 1) - -#define MAX_PHASE SHRT_MAX -#define MIN_PHASE SHRT_MIN - -/*definitions for I/O Interrupt Scanning */ -struct ioscan_head; - -typedef struct ioscan_head *IOSCANPVT; -typedef struct event_list *EVENTPVT; - -struct dbCommon; - -typedef void (*io_scan_complete)(void *usr, IOSCANPVT, int prio); -typedef void (*once_complete)(void *usr, struct dbCommon*); - -epicsShareFunc long scanInit(void); -epicsShareFunc void scanRun(void); -epicsShareFunc void scanPause(void); -epicsShareFunc void scanStop(void); -epicsShareFunc void scanCleanup(void); - -epicsShareFunc EVENTPVT eventNameToHandle(const char* event); -epicsShareFunc void postEvent(EVENTPVT epvt); -epicsShareFunc void post_event(int event) EPICS_DEPRECATED; -epicsShareFunc void scanAdd(struct dbCommon *); -epicsShareFunc void scanDelete(struct dbCommon *); -epicsShareFunc double scanPeriod(int scan); -epicsShareFunc int scanOnce(struct dbCommon *); -epicsShareFunc int scanOnceCallback(struct dbCommon *, once_complete cb, void *usr); -epicsShareFunc int scanOnceSetQueueSize(int size); - -/*print periodic lists*/ -epicsShareFunc int scanppl(double rate); - -/*print event lists*/ -epicsShareFunc int scanpel(const char *event_name); - -/*print io_event list*/ -epicsShareFunc int scanpiol(void); - -epicsShareFunc void scanIoInit(IOSCANPVT *ppios); -epicsShareFunc unsigned int scanIoRequest(IOSCANPVT pios); -epicsShareFunc unsigned int scanIoImmediate(IOSCANPVT pios, int prio); -epicsShareFunc void scanIoSetComplete(IOSCANPVT, io_scan_complete, void *usr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/ioc/db/dbServer.c b/src/ioc/db/dbServer.c deleted file mode 100644 index bc1094ce7..000000000 --- a/src/ioc/db/dbServer.c +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - */ - -#include - -#include "ellLib.h" -#include "epicsStdio.h" - -#define epicsExportSharedSymbols -#include "dbServer.h" - -static ELLLIST serverList = ELLLIST_INIT; - - -void dbRegisterServer(dbServer *psrv) -{ - if (ellNext(&psrv->node)) { - fprintf(stderr, "dbRegisterServer: '%s' registered twice?\n", - psrv->name); - return; - } - - ellAdd(&serverList, &psrv->node); -} - -void dbsr(unsigned level) -{ - dbServer *psrv = (dbServer *)ellFirst(&serverList); - - while (psrv) { - printf("Server '%s':\n", psrv->name); - if (psrv->report) - psrv->report(level); - psrv = (dbServer *)ellNext(&psrv->node); - } -} - -int dbServerClient(char *pBuf, size_t bufSize) -{ - dbServer *psrv = (dbServer *)ellFirst(&serverList); - - while (psrv) { - if (psrv->client && - psrv->client(pBuf, bufSize) == 0) - return 0; - psrv = (dbServer *)ellNext(&psrv->node); - } - return -1; -} - diff --git a/src/ioc/db/dbServer.h b/src/ioc/db/dbServer.h deleted file mode 100644 index 345468676..000000000 --- a/src/ioc/db/dbServer.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - */ - -#ifndef INC_dbServer_H -#define INC_dbServer_H - -#include - -#include "ellLib.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Server information structure */ - -typedef struct dbServer { - ELLNODE node; - const char *name; - - /* Print level-dependent status report to stdout */ - void (* report) (unsigned level); - - /* Get number of channels and clients connected */ - void (* stats) (unsigned *channels, unsigned *clients); - - /* Get identity of client initiating the calling thread */ - /* Must return 0 (OK), or -1 (ERROR) from unknown threads */ - int (* client) (char *pBuf, size_t bufSize); -} dbServer; - - -epicsShareFunc void dbRegisterServer(dbServer *psrv); - -/* Extra routines could be added if/when needed: - * - * epicsShareFunc const dbServer* dbFindServer(const char *name); - * epicsShareFunc void dbIterateServers(srvIterFunc func, void *user); - */ - -epicsShareFunc void dbsr(unsigned level); - -epicsShareFunc int dbServerClient(char *pBuf, size_t bufSize); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbServer_H */ diff --git a/src/ioc/db/dbState.c b/src/ioc/db/dbState.c deleted file mode 100644 index 6de7735cd..000000000 --- a/src/ioc/db/dbState.c +++ /dev/null @@ -1,109 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include -#include - -#include "ellLib.h" -#include "epicsMutex.h" -#include "epicsString.h" -#include "iocsh.h" - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "dbState.h" -#include "dbStaticLib.h" - -static ELLLIST states = ELLLIST_INIT; - -typedef struct dbState { - ELLNODE node; - int status; - char *name; - epicsMutexId lock; /* FIXME: Use atomic operations instead */ -} dbState; - -dbStateId dbStateFind(const char *name) -{ - ELLNODE *node; - dbStateId id; - - for (node = ellFirst(&states); node; node = ellNext(node)) { - id = CONTAINER(node, dbState, node); - if (strcmp(id->name, name) == 0) - return id; - } - return NULL; -} - -dbStateId dbStateCreate(const char *name) -{ - dbStateId id; - - if ((id = dbStateFind(name))) - return id; - - id = callocMustSucceed(1, sizeof(dbState), "createDbState"); - id->name = epicsStrDup(name); - id->lock = epicsMutexMustCreate(); - ellAdd(&states, &id->node); - - return id; -} - -void dbStateSet(dbStateId id) -{ - if (!id) - return; - epicsMutexMustLock(id->lock); - id->status = 1; - epicsMutexUnlock(id->lock); -} - -void dbStateClear(dbStateId id) -{ - if (!id) - return; - epicsMutexMustLock(id->lock); - id->status = 0; - epicsMutexUnlock(id->lock); -} - -int dbStateGet(dbStateId id) -{ - int status; - - if (!id) - return 0; - epicsMutexMustLock(id->lock); - status = id->status; - epicsMutexUnlock(id->lock); - return status; -} - -void dbStateShow(dbStateId id, unsigned int level) -{ - if (level >=1) - printf("id %p '%s' : ", id, id->name); - printf("%s\n", dbStateGet(id) ? "TRUE" : "FALSE"); -} - -void dbStateShowAll(unsigned int level) -{ - ELLNODE *node; - dbStateId id; - - for (node = ellFirst(&states); node; node = ellNext(node)) { - id = CONTAINER(node, dbState, node); - dbStateShow(id, level+1); - } -} diff --git a/src/ioc/db/dbState.h b/src/ioc/db/dbState.h deleted file mode 100644 index abd23259e..000000000 --- a/src/ioc/db/dbState.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#ifndef INCdbStateH -#define INCdbStateH - -#include "shareLib.h" - -/** @file dbState.h - * @brief Generic IOC state facility - * - * This library provides a simple global flag facility that can be used to - * synchronize e.g. plugins with IOC-wide states, that may be derived from - * events (either soft events or hard events coming from specialized timing - * and event hardware). - * - * A subset of this API is provided as IOC Shell commands to allow - * command line debugging. - * - */ - -typedef struct dbState *dbStateId; - -/** @brief Create db state. - * - * Creates a new db state with the specified 'name', returning the new id. - * If state with that name already exists, the existing state's id is returned. - * - * Also provided as an IOC Shell command. - * - * @param name Db state name. - * @return Id of db state, NULL for failure. - */ -epicsShareFunc dbStateId dbStateCreate(const char *name); - -/** @brief Find db state. - * - * @param name Db state name. - * @return Id of db state, NULL if not found. - */ -epicsShareFunc dbStateId dbStateFind(const char *name); - -/** @brief Set db state to TRUE. - * - * Also provided as an IOC Shell command. - * - * @param id Db state id. - */ -epicsShareFunc void dbStateSet(dbStateId id); - -/** @brief Set db state to FALSE. - * - * Also provided as an IOC Shell command. - * - * @param id Db state id. - */ -epicsShareFunc void dbStateClear(dbStateId id); - -/** @brief Get db state. - * - * @param id Db state id. - * @return Current db state (0|1). - */ -epicsShareFunc int dbStateGet(dbStateId id); - -/** @brief Print info about db state. - * - * Also provided as an IOC Shell command. - * - * @param id Db state id. - * @param level Interest level. - */ -epicsShareFunc void dbStateShow(dbStateId id, unsigned int level); - -/** @brief Print info about all db states. - * - * Also provided as an IOC Shell command. - * - * @param level Interest level. - */ -epicsShareFunc void dbStateShowAll(unsigned int level); - -#endif // INCdbStateH diff --git a/src/ioc/db/dbSubscriptionIO.cpp b/src/ioc/db/dbSubscriptionIO.cpp deleted file mode 100644 index 5b9b85ef5..000000000 --- a/src/ioc/db/dbSubscriptionIO.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#include - -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "tsFreeList.h" - -#include "db_access.h" // need to eliminate this -#include "cadef.h" // this can be eliminated when the callbacks use the new interface -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "dbCAC.h" -#include "dbChannelIO.h" -#include "db_access_routines.h" - -dbSubscriptionIO::dbSubscriptionIO ( - epicsGuard < epicsMutex > & guard, epicsMutex & mutexIn, - dbContext &, dbChannelIO & chanIO, - dbChannel * dbch, cacStateNotify & notifyIn, unsigned typeIn, - unsigned long countIn, unsigned maskIn, dbEventCtx ctx ) : - mutex ( mutexIn ), count ( countIn ), notify ( notifyIn ), - chan ( chanIO ), es ( 0 ), type ( typeIn ), id ( 0u ) -{ - guard.assertIdenticalMutex ( this->mutex ); - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->es = db_add_event ( ctx, dbch, - dbSubscriptionEventCallback, (void *) this, maskIn ); - if ( this->es == 0 ) { - throw std::bad_alloc(); - } - db_post_single_event ( this->es ); - db_event_enable ( this->es ); - } -} - -dbSubscriptionIO::~dbSubscriptionIO () -{ -} - -void dbSubscriptionIO::destructor ( CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->~dbSubscriptionIO (); -} - -void dbSubscriptionIO::unsubscribe ( CallbackGuard & cbGuard, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - if ( this->es ) { - dbEventSubscription tmp = this->es; - this->es = 0; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - db_cancel_event ( tmp ); - } - } -} - -void dbSubscriptionIO::channelDeleteException ( - CallbackGuard &, - epicsGuard < epicsMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - this->notify.exception ( guard, ECA_CHANDESTROY, - this->chan.pName(guard), this->type, this->count ); -} - -void dbSubscriptionIO::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void * dbSubscriptionIO::operator new ( size_t size, - tsFreeList < dbSubscriptionIO, 256, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -void dbSubscriptionIO::operator delete ( void * pCadaver, - tsFreeList < dbSubscriptionIO, 256, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -extern "C" void dbSubscriptionEventCallback ( void *pPrivate, struct dbChannel * /* dbch */, - int /* eventsRemaining */, struct db_field_log *pfl ) -{ - dbSubscriptionIO * pIO = static_cast < dbSubscriptionIO * > ( pPrivate ); - pIO->chan.callStateNotify ( pIO->type, pIO->count, pfl, pIO->notify ); -} - -void dbSubscriptionIO::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->show ( guard, level ); -} - -void dbSubscriptionIO::show ( - epicsGuard < epicsMutex > & guard, unsigned level ) const -{ - guard.assertIdenticalMutex ( this->mutex ); - - printf ( "Data base subscription IO at %p\n", - static_cast ( this ) ); - if ( level > 0u ) { - short tmpType; - if ( this->type < SHRT_MAX ) { - tmpType = static_cast < short > ( this->type ); - printf ( "\ttype %s, count %lu, channel at %p\n", - dbf_type_to_text ( tmpType ), this->count, - static_cast ( &this->chan ) ); - } - else { - printf ( "strange type !, count %lu, channel at %p\n", - this->count, static_cast ( &this->chan ) ); - } - } -} - -dbSubscriptionIO * dbSubscriptionIO::isSubscription () -{ - return this; -} - - diff --git a/src/ioc/db/dbTest.c b/src/ioc/db/dbTest.c deleted file mode 100644 index e707dab7f..000000000 --- a/src/ioc/db/dbTest.c +++ /dev/null @@ -1,1267 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* database access test subroutines */ - -#include -#include -#include - -#include "cvtFast.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsMutex.h" -#include "epicsStdio.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "callback.h" -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbCommon.h" -#include "dbEvent.h" -#include "db_field_log.h" -#include "dbFldTypes.h" -#include "dbLock.h" -#include "dbStaticLib.h" -#include "dbTest.h" -#include "devSup.h" -#include "drvSup.h" -#include "link.h" -#include "recGbl.h" -#include "recSup.h" -#include "special.h" - -#define MAXLINE 80 -struct msgBuff { /* line output structure */ - char out_buff[MAXLINE + 1]; - char *pNext; - char *pLast; - char *pNexTab; - char message[128]; -}; -typedef struct msgBuff TAB_BUFFER; - -#ifndef MIN -# define MIN(x,y) (((x) < (y)) ? (x) : (y)) -#endif -#ifndef MAX -# define MAX(x,y) (((x) < (y)) ? (x) : (y)) -#endif - -/* Local Routines */ -static long nameToAddr(const char *pname, DBADDR *paddr); -static void printDbAddr(DBADDR *paddr); -static void printBuffer(long status, short dbr_type, void *pbuffer, - long reqOptions, long retOptions, long no_elements, - TAB_BUFFER *pMsgBuff, int tab_size); -static int dbpr_report(const char *pname, DBADDR *paddr, int interest_level, - TAB_BUFFER *pMsgBuff, int tab_size); -static void dbpr_msgOut(TAB_BUFFER *pMsgBuff,int tab_size); -static void dbpr_init_msg(TAB_BUFFER *pMsgBuff,int tab_size); -static void dbpr_insert_msg(TAB_BUFFER *pMsgBuff,size_t len,int tab_size); -static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size); - -static char *dbf[DBF_NTYPES] = { - "STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG", - "INT64","UINT64","FLOAT","DOUBLE","ENUM","MENU","DEVICE", - "INLINK","OUTLINK","FWDLINK","NOACCESS" -}; - -static char *dbr[DBR_ENUM+2] = { - "STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG", - "INT64","UINT64","FLOAT","DOUBLE","ENUM","NOACCESS" -}; - -long dba(const char*pname) -{ - DBADDR addr; - - if (!pname || !*pname) { - printf("Usage: dba \"pv name\"\n"); - return 1; - } - - if (nameToAddr(pname, &addr)) - return -1; - - printDbAddr(&addr); - return 0; -} - -long dbl(const char *precordTypename, const char *fields) -{ - DBENTRY dbentry; - DBENTRY *pdbentry=&dbentry; - long status; - int nfields = 0; - int ifield; - char *fieldnames = 0; - char **papfields = 0; - - if (!pdbbase) { - printf("No database loaded\n"); - return 0; - } - - if (precordTypename && - ((*precordTypename == '\0') || !strcmp(precordTypename,"*"))) - precordTypename = NULL; - if (fields && (*fields == '\0')) - fields = NULL; - if (fields) { - char *pnext; - - fieldnames = epicsStrDup(fields); - nfields = 1; - pnext = fieldnames; - while (*pnext && (pnext = strchr(pnext,' '))) { - nfields++; - while (*pnext == ' ') pnext++; - } - papfields = dbCalloc(nfields,sizeof(char *)); - pnext = fieldnames; - for (ifield = 0; ifield < nfields; ifield++) { - papfields[ifield] = pnext; - if (ifield < nfields - 1) { - pnext = strchr(pnext, ' '); - *pnext++ = 0; - while (*pnext == ' ') pnext++; - } - } - } - dbInitEntry(pdbbase, pdbentry); - if (!precordTypename) - status = dbFirstRecordType(pdbentry); - else - status = dbFindRecordType(pdbentry,precordTypename); - if (status) { - printf("No record type\n"); - } - - while (!status) { - status = dbFirstRecord(pdbentry); - while (!status) { - printf("%s", dbGetRecordName(pdbentry)); - for (ifield = 0; ifield < nfields; ifield++) { - char *pvalue; - status = dbFindField(pdbentry, papfields[ifield]); - if (status) { - if (!strcmp(papfields[ifield], "recordType")) { - pvalue = dbGetRecordTypeName(pdbentry); - } - else { - printf(", "); - continue; - } - } - else { - pvalue = dbGetString(pdbentry); - } - printf(", \"%s\"", pvalue ? pvalue : ""); - } - printf("\n"); - status = dbNextRecord(pdbentry); - } - if (precordTypename) - break; - - status = dbNextRecordType(pdbentry); - } - if (nfields > 0) { - free((void *)papfields); - free((void *)fieldnames); - } - dbFinishEntry(pdbentry); - return 0; -} - -long dbnr(int verbose) -{ - DBENTRY dbentry; - DBENTRY *pdbentry=&dbentry; - long status; - int nrecords; - int naliases; - int trecords = 0; - int taliases = 0; - - if (!pdbbase) { - printf("No database loaded\n"); - return 0; - } - - dbInitEntry(pdbbase, pdbentry); - status = dbFirstRecordType(pdbentry); - if (status) { - printf("No record types loaded\n"); - return 0; - } - - printf("Records Aliases Record Type\n"); - while (!status) { - naliases = dbGetNAliases(pdbentry); - taliases += naliases; - nrecords = dbGetNRecords(pdbentry) - naliases; - trecords += nrecords; - if (verbose || nrecords) - printf(" %5d %5d %s\n", - nrecords, naliases, dbGetRecordTypeName(pdbentry)); - status = dbNextRecordType(pdbentry); - } - - dbFinishEntry(pdbentry); - printf("Total %d records, %d aliases\n", trecords, taliases); - return 0; -} - -long dbla(const char *pmask) -{ - DBENTRY dbentry; - DBENTRY *pdbentry = &dbentry; - long status; - - if (!pdbbase) { - printf("No database loaded\n"); - return 0; - } - - dbInitEntry(pdbbase, pdbentry); - status = dbFirstRecordType(pdbentry); - while (!status) { - for (status = dbFirstRecord(pdbentry); !status; - status = dbNextRecord(pdbentry)) { - char *palias; - - if (!dbIsAlias(pdbentry)) - continue; - - palias = dbGetRecordName(pdbentry); - if (pmask && *pmask && !epicsStrGlobMatch(palias, pmask)) - continue; - dbFindField(pdbentry, "NAME"); - printf("%s -> %s\n", palias, dbGetString(pdbentry)); - } - status = dbNextRecordType(pdbentry); - } - - dbFinishEntry(pdbentry); - return 0; -} - -long dbgrep(const char *pmask) -{ - DBENTRY dbentry; - DBENTRY *pdbentry = &dbentry; - long status; - - if (!pmask || !*pmask) { - printf("Usage: dbgrep \"pattern\"\n"); - return 1; - } - - if (!pdbbase) { - printf("No database loaded\n"); - return 0; - } - - dbInitEntry(pdbbase, pdbentry); - status = dbFirstRecordType(pdbentry); - while (!status) { - status = dbFirstRecord(pdbentry); - while (!status) { - char *pname = dbGetRecordName(pdbentry); - if (epicsStrGlobMatch(pname, pmask)) - puts(pname); - status = dbNextRecord(pdbentry); - } - status = dbNextRecordType(pdbentry); - } - - dbFinishEntry(pdbentry); - return 0; -} - -long dbgf(const char *pname) -{ - /* declare buffer long just to ensure correct alignment */ - long buffer[100]; - long *pbuffer=&buffer[0]; - DBADDR addr; - long options = 0; - long no_elements; - static TAB_BUFFER msg_Buff; - - if (!pname || !*pname) { - printf("Usage: dbgf \"pv name\"\n"); - return 1; - } - - if (nameToAddr(pname, &addr)) - return -1; - - no_elements = MIN(addr.no_elements, sizeof(buffer)/addr.field_size); - if (addr.dbr_field_type == DBR_ENUM) { - long status = dbGetField(&addr, DBR_STRING, pbuffer, - &options, &no_elements, NULL); - - printBuffer(status, DBR_STRING, pbuffer, 0L, 0L, - no_elements, &msg_Buff, 10); - } - else { - long status = dbGetField(&addr, addr.dbr_field_type, pbuffer, - &options, &no_elements, NULL); - - printBuffer(status, addr.dbr_field_type, pbuffer, 0L, 0L, - no_elements, &msg_Buff, 10); - } - - msg_Buff.message[0] = '\0'; - dbpr_msgOut(&msg_Buff, 10); - return 0; -} - -long dbpf(const char *pname,const char *pvalue) -{ - DBADDR addr; - long status; - short dbrType; - size_t n = 1; - - if (!pname || !*pname || !pvalue) { - printf("Usage: dbpf \"pv name\", \"value\"\n"); - return 1; - } - - if (nameToAddr(pname, &addr)) - return -1; - - if (addr.no_elements > 1 && - (addr.dbr_field_type == DBR_CHAR || addr.dbr_field_type == DBR_UCHAR)) { - dbrType = addr.dbr_field_type; - n = strlen(pvalue) + 1; - } - else { - dbrType = DBR_STRING; - } - - status = dbPutField(&addr, dbrType, pvalue, (long) n); - dbgf(pname); - return status; -} - -long dbpr(const char *pname,int interest_level) -{ - static TAB_BUFFER msg_Buff; - TAB_BUFFER *pMsgBuff = &msg_Buff; - DBADDR addr; - char *pmsg; - int tab_size = 20; - - if (!pname || !*pname) { - printf("Usage: dbpr \"pv name\", level\n"); - return 1; - } - - if (nameToAddr(pname, &addr)) - return -1; - - pmsg = pMsgBuff->message; - - if (dbpr_report(pname, &addr, interest_level, pMsgBuff, tab_size)) - return 1; - - pmsg[0] = '\0'; - dbpr_msgOut(pMsgBuff, tab_size); - return 0; -} - -long dbtr(const char *pname) -{ - DBADDR addr; - long status; - struct dbCommon *precord; - - if (!pname || !*pname) { - printf("Usage: dbtr \"pv name\"\n"); - return 1; - } - - if (nameToAddr(pname, &addr)) - return -1; - - precord = (struct dbCommon*)addr.precord; - if (precord->pact) { - printf("record active\n"); - return 1; - } - - dbScanLock(precord); - status = dbProcess(precord); - dbScanUnlock(precord); - - if (status) - recGblRecordError(status, precord, "dbtr(dbProcess)"); - - dbpr(pname, 3); - return 0; -} - -long dbtgf(const char *pname) -{ - /* declare buffer long just to ensure correct alignment */ - long buffer[400]; - long *pbuffer = &buffer[0]; - DBADDR addr; - long status; - long req_options, ret_options, no_elements; - short dbr_type; - static TAB_BUFFER msg_Buff; - TAB_BUFFER *pMsgBuff = &msg_Buff; - char *pmsg = pMsgBuff->message; - int tab_size = 10; - - if (pname==0 || *pname==0) { - printf("Usage: dbtgf \"pv name\"\n"); - return 1; - } - - if (nameToAddr(pname, &addr)) - return -1; - - /* try all options first */ - req_options = 0xffffffff; - ret_options = req_options; - no_elements = 0; - status = dbGetField(&addr, addr.dbr_field_type, pbuffer, - &ret_options, &no_elements, NULL); - printBuffer(status, addr.dbr_field_type, pbuffer, - req_options, ret_options, no_elements, pMsgBuff, tab_size); - - /* Now try all request types */ - ret_options=0; - - dbr_type = DBR_STRING; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/MAX_STRING_SIZE)); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_CHAR; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt8))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_UCHAR; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt8))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_SHORT; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt16))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_USHORT; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt16))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_LONG; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt32))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_ULONG; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt32))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_INT64; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt64))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_UINT64; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt64))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_FLOAT; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsFloat32))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_DOUBLE; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsFloat64))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - dbr_type = DBR_ENUM; - no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsEnum16))); - status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL); - printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size); - - pmsg[0] = '\0'; - dbpr_msgOut(pMsgBuff, tab_size); - return(0); -} - -long dbtpf(const char *pname, const char *pvalue) -{ - /* declare buffer long just to ensure correct alignment */ - long buffer[100]; - long *pbuffer = buffer; - DBADDR addr; - int put_type; - static TAB_BUFFER msg_Buff; - TAB_BUFFER *pMsgBuff = &msg_Buff; - char *pmsg = pMsgBuff->message; - int tab_size = 10; - - if (!pname || !*pname || !pvalue) { - printf("Usage: dbtpf \"pv name\", \"value\"\n"); - return 1; - } - if (nameToAddr(pname, &addr)) - return -1; - - for (put_type = DBR_STRING; put_type <= DBF_ENUM; put_type++) { - union { - epicsInt8 i8; - epicsUInt8 u8; - epicsInt16 i16; - epicsUInt16 u16; - epicsInt32 i32; - epicsUInt32 u32; - epicsInt64 i64; - epicsUInt64 u64; - epicsFloat32 f32; - epicsFloat64 f64; - epicsEnum16 e16; - } val; - const void *pval = &val; - int valid = 1; - - switch (put_type) { - case DBR_STRING: - pval = pvalue; - break; - case DBR_CHAR: - valid = !epicsParseInt8(pvalue, &val.i8, 10, NULL); - break; - case DBR_UCHAR: - valid = !epicsParseUInt8(pvalue, &val.u8, 10, NULL); - break; - case DBR_SHORT: - valid = !epicsParseInt16(pvalue, &val.i16, 10, NULL); - break; - case DBR_USHORT: - valid = !epicsParseUInt16(pvalue, &val.u16, 10, NULL); - break; - case DBR_LONG: - valid = !epicsParseInt32(pvalue, &val.i32, 10, NULL); - break; - case DBR_ULONG: - valid = !epicsParseUInt32(pvalue, &val.u32, 10, NULL); - break; - case DBR_INT64: - valid = !epicsParseInt64(pvalue, &val.i64, 10, NULL); - break; - case DBR_UINT64: - valid = !epicsParseUInt64(pvalue, &val.u64, 10, NULL); - break; - case DBR_FLOAT: - valid = !epicsParseFloat32(pvalue, &val.f32, NULL); - break; - case DBR_DOUBLE: - valid = !epicsParseFloat64(pvalue, &val.f64, NULL); - break; - case DBR_ENUM: - valid = !epicsParseUInt16(pvalue, &val.e16, 10, NULL); - break; - } - if (valid) { - long status = dbPutField(&addr, put_type, pval, 1); - - if (status) { - printf("Put as DBR_%-6s Failed.\n", dbr[put_type]); - } - else { - long options = 0; - long no_elements = MIN(addr.no_elements, - ((sizeof(buffer))/addr.field_size)); - - printf("Put as DBR_%-6s Ok, result as ", dbr[put_type]); - status = dbGetField(&addr, addr.dbr_field_type, pbuffer, - &options, &no_elements, NULL); - printBuffer(status, addr.dbr_field_type, pbuffer, 0L, 0L, - no_elements, pMsgBuff, tab_size); - } - } - else { - printf("Cvt to DBR_%s failed.\n", dbr[put_type]); - } - } - - pmsg[0] = '\0'; - dbpr_msgOut(pMsgBuff, tab_size); - return 0; -} - -long dbior(const char *pdrvName,int interest_level) -{ - drvSup *pdrvSup; - struct drvet *pdrvet; - dbRecordType *pdbRecordType; - - if (!pdbbase) { - printf("No database loaded\n"); - return 0; - } - - if (pdrvName && ((*pdrvName == '\0') || !strcmp(pdrvName,"*"))) - pdrvName = NULL; - - for (pdrvSup = (drvSup *)ellFirst(&pdbbase->drvList); - pdrvSup; - pdrvSup = (drvSup *)ellNext(&pdrvSup->node)) { - const char *pname = pdrvSup->name; - - if (pdrvName!=NULL && *pdrvName!='\0' && - (strcmp(pdrvName,pname)!=0)) - continue; - - pdrvet = pdrvSup->pdrvet ; - if (pdrvet == NULL) { - printf("No driver entry table is present for %s\n", pname); - continue; - } - - if (pdrvet->report == NULL) - printf("Driver: %s No report available\n", pname); - else { - printf("Driver: %s\n", pname); - pdrvet->report(interest_level); - } - } - - /* now check devSup reports */ - for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; - pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - devSup *pdevSup; - - for (pdevSup = (devSup *)ellFirst(&pdbRecordType->devList); - pdevSup; - pdevSup = (devSup *)ellNext(&pdevSup->node)) { - struct dset *pdset = pdevSup->pdset; - const char *pname = pdevSup->name; - - if (!pdset || !pname) - continue; - - if (pdrvName != NULL && *pdrvName != '\0' && - (strcmp(pdrvName, pname) != 0)) - continue; - - if (pdset->report != NULL) { - printf("Device Support: %s\n", pname); - pdset->report(interest_level); - } - } - } - return 0; -} - -int dbhcr(void) -{ - if (!pdbbase) { - printf("No database loaded\n"); - return 0; - } - - dbReportDeviceConfig(pdbbase, stdout); - return 0; -} - -static long nameToAddr(const char *pname, DBADDR *paddr) -{ - long status = dbNameToAddr(pname, paddr); - - if (status) { - printf("PV '%s' not found\n", pname); - } - return status; -} - -static void printDbAddr(DBADDR *paddr) -{ - dbFldDes *pdbFldDes = paddr->pfldDes; - short field_type = paddr->field_type; - short dbr_field_type = paddr->dbr_field_type; - - printf("Record Address: %p", paddr->precord); - printf(" Field Address: %p", paddr->pfield); - printf(" Field Description: %p\n", pdbFldDes); - printf(" No Elements: %ld\n", paddr->no_elements); - printf(" Record Type: %s\n", pdbFldDes->pdbRecordType->name); - printf(" Field Type: %d = DBF_%s\n", field_type, - (field_type < 0 || field_type > DBR_NOACCESS) ? "????" : - dbf[field_type]); - printf(" Field Size: %d\n", paddr->field_size); - printf(" Special: %d\n", paddr->special); - - if (dbr_field_type == DBR_NOACCESS) - dbr_field_type = DBR_ENUM + 1; - printf("DBR Field Type: %d = DBR_%s\n", paddr->dbr_field_type, - (dbr_field_type < 0 || dbr_field_type > (DBR_ENUM+1)) ? "????" : - dbr[dbr_field_type]); -} - - -static void printBuffer( - long status, short dbr_type, void *pbuffer, long reqOptions, - long retOptions, long no_elements, TAB_BUFFER *pMsgBuff, int tab_size) -{ - char *pmsg = pMsgBuff->message; - int i; - - if (reqOptions & DBR_STATUS) { - if (retOptions & DBR_STATUS) { - struct dbr_status *pdbr_status = (void *)pbuffer; - - printf("status = %u, severity = %u\n", - pdbr_status->status, - pdbr_status->severity); - } - else { - printf("status and severity not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_status_size; - } - - if (reqOptions & DBR_UNITS) { - if (retOptions & DBR_UNITS) { - struct dbr_units *pdbr_units = (void *)pbuffer; - - printf("units = \"%s\"\n", - pdbr_units->units); - } - else { - printf("units not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_units_size; - } - - if (reqOptions & DBR_PRECISION) { - if (retOptions & DBR_PRECISION){ - struct dbr_precision *pdbr_precision = (void *)pbuffer; - - printf("precision = %ld\n", - pdbr_precision->precision.dp); - } - else { - printf("precision not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_precision_size; - } - - if (reqOptions & DBR_TIME) { - if (retOptions & DBR_TIME) { - struct dbr_time *pdbr_time = (void *)pbuffer; - char time_buf[40]; - epicsTimeToStrftime(time_buf, 40, "%Y-%m-%d %H:%M:%S.%09f", - &pdbr_time->time); - printf("time = %s\n", time_buf); - } - else { - printf("time not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_time_size; - } - - if (reqOptions & DBR_ENUM_STRS) { - if (retOptions & DBR_ENUM_STRS) { - struct dbr_enumStrs *pdbr_enumStrs = (void *)pbuffer; - - printf("no_strs = %u:\n", - pdbr_enumStrs->no_str); - for (i = 0; i < pdbr_enumStrs->no_str; i++) - printf("\t\"%s\"\n", pdbr_enumStrs->strs[i]); - } - else { - printf("enum strings not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_enumStrs_size; - } - - if (reqOptions & DBR_GR_LONG) { - if (retOptions & DBR_GR_LONG) { - struct dbr_grLong *pdbr_grLong = (void *)pbuffer; - - printf("grLong: %d .. %d\n", - pdbr_grLong->lower_disp_limit, - pdbr_grLong->upper_disp_limit); - } - else { - printf("DBRgrLong not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_grLong_size; - } - - if (reqOptions & DBR_GR_DOUBLE) { - if (retOptions & DBR_GR_DOUBLE) { - struct dbr_grDouble *pdbr_grDouble = (void *)pbuffer; - - printf("grDouble: %g .. %g\n", - pdbr_grDouble->lower_disp_limit, - pdbr_grDouble->upper_disp_limit); - } - else { - printf("DBRgrDouble not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_grDouble_size; - } - - if (reqOptions & DBR_CTRL_LONG) { - if (retOptions & DBR_CTRL_LONG){ - struct dbr_ctrlLong *pdbr_ctrlLong = (void *)pbuffer; - - printf("ctrlLong: %d .. %d\n", - pdbr_ctrlLong->lower_ctrl_limit, - pdbr_ctrlLong->upper_ctrl_limit); - } - else { - printf("DBRctrlLong not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_ctrlLong_size; - } - - if (reqOptions & DBR_CTRL_DOUBLE) { - if (retOptions & DBR_CTRL_DOUBLE) { - struct dbr_ctrlDouble *pdbr_ctrlDouble = (void *)pbuffer; - - printf("ctrlDouble: %g .. %g\n", - pdbr_ctrlDouble->lower_ctrl_limit, - pdbr_ctrlDouble->upper_ctrl_limit); - } - else { - printf("DBRctrlDouble not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_ctrlDouble_size; - } - - if (reqOptions & DBR_AL_LONG) { - if (retOptions & DBR_AL_LONG) { - struct dbr_alLong *pdbr_alLong = (void *)pbuffer; - - printf("alLong: %d < %d .. %d < %d\n", - pdbr_alLong->lower_alarm_limit, - pdbr_alLong->lower_warning_limit, - pdbr_alLong->upper_warning_limit, - pdbr_alLong->upper_alarm_limit); - } - else { - printf("DBRalLong not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_alLong_size; - } - - if (reqOptions & DBR_AL_DOUBLE) { - if (retOptions & DBR_AL_DOUBLE) { - struct dbr_alDouble *pdbr_alDouble = (void *)pbuffer; - - printf("alDouble: %g < %g .. %g < %g\n", - pdbr_alDouble->lower_alarm_limit, - pdbr_alDouble->lower_warning_limit, - pdbr_alDouble->upper_warning_limit, - pdbr_alDouble->upper_alarm_limit); - } - else { - printf("DBRalDouble not returned\n"); - } - pbuffer = (char *)pbuffer + dbr_alDouble_size; - } - - /* Now print values */ - if (no_elements == 0) - return; - - if (no_elements == 1) - sprintf(pmsg, "DBF_%s: ", dbr[dbr_type]); - else - sprintf(pmsg, "DBF_%s[%ld]: ", dbr[dbr_type], no_elements); - dbpr_msgOut(pMsgBuff, tab_size); - - if (status != 0) { - strcpy(pmsg, "failed."); - dbpr_msgOut(pMsgBuff, tab_size); - } - else { - switch (dbr_type) { - case DBR_STRING: - for(i=0; i 0) { - int chunk = (len > MAXLINE - 5) ? MAXLINE - 5 : len; - - sprintf(pmsg, "\"%.*s\"", chunk, (char *)pbuffer + i); - len -= chunk; - if (len > 0) - strcat(pmsg, " +"); - dbpr_msgOut(pMsgBuff, tab_size); - } - } - break; - - case DBR_UCHAR: - for (i = 0; i < no_elements; i++) { - epicsUInt32 val = *(epicsUInt8 *) pbuffer; - - sprintf(pmsg, "%u = 0x%x", val, val); - dbpr_msgOut(pMsgBuff, tab_size); - pbuffer = (char *)pbuffer + sizeof(epicsUInt8); - } - break; - - case DBR_SHORT: - for (i = 0; i < no_elements; i++) { - epicsInt16 val = *(epicsInt16 *) pbuffer; - - sprintf(pmsg, "%hd = 0x%hx", val, val); - dbpr_msgOut(pMsgBuff, tab_size); - pbuffer = (char *)pbuffer + sizeof(epicsInt16); - } - break; - - case DBR_USHORT: - for (i = 0; i < no_elements; i++) { - epicsUInt16 val = *(epicsUInt16 *) pbuffer; - - sprintf(pmsg, "%hu = 0x%hx", val, val); - dbpr_msgOut(pMsgBuff, tab_size); - pbuffer = (char *)pbuffer + sizeof(epicsUInt16); - } - break; - - case DBR_LONG: - for (i = 0; i < no_elements; i++) { - epicsInt32 val = *(epicsInt32 *) pbuffer; - - sprintf(pmsg, "%d = 0x%x", val, val); - dbpr_msgOut(pMsgBuff, tab_size); - pbuffer = (char *)pbuffer + sizeof(epicsInt32); - } - break; - - case DBR_ULONG: - for (i = 0; i < no_elements; i++) { - epicsUInt32 val = *(epicsUInt32 *) pbuffer; - - sprintf(pmsg, "%u = 0x%x", val, val); - dbpr_msgOut(pMsgBuff, tab_size); - pbuffer = (char *)pbuffer + sizeof(epicsUInt32); - } - break; - - case DBR_INT64: - for (i = 0; i < no_elements; i++) { - epicsInt64 val = *(epicsInt64 *) pbuffer; - - pmsg += cvtInt64ToString(val, pmsg); - strcpy(pmsg, " = "); - pmsg += 3; - cvtInt64ToHexString(val, pmsg); - dbpr_msgOut(pMsgBuff, tab_size); - pmsg = pMsgBuff->message; - pbuffer = (char *)pbuffer + sizeof(epicsInt64); - } - break; - - case DBR_UINT64: - for (i = 0; i < no_elements; i++) { - epicsUInt64 val = *(epicsUInt64 *) pbuffer; - - pmsg += cvtUInt64ToString(val, pmsg); - strcpy(pmsg, " = "); - pmsg += 3; - cvtUInt64ToHexString(val, pmsg); - dbpr_msgOut(pMsgBuff, tab_size); - pmsg = pMsgBuff->message; - pbuffer = (char *)pbuffer + sizeof(epicsUInt64); - } - break; - - case DBR_FLOAT: - for (i = 0; i < no_elements; i++) { - sprintf(pmsg, "%.6g", *((epicsFloat32 *) pbuffer)); - dbpr_msgOut(pMsgBuff, tab_size); - pbuffer = (char *)pbuffer + sizeof(epicsFloat32); - } - break; - - case DBR_DOUBLE: - for (i = 0; i < no_elements; i++) { - sprintf(pmsg, "%.12g", *((epicsFloat64 *) pbuffer)); - dbpr_msgOut(pMsgBuff, tab_size); - pbuffer = (char *)pbuffer + sizeof(epicsFloat64); - } - break; - - case DBR_ENUM: - for (i = 0; i < no_elements; i++) { - sprintf(pmsg, "%u", *((epicsEnum16 *) pbuffer)); - dbpr_msgOut(pMsgBuff, tab_size); - pbuffer = (char *)pbuffer + sizeof(epicsEnum16); - } - break; - - default: - sprintf(pmsg, "Bad DBR type %d", dbr_type); - dbpr_msgOut(pMsgBuff, tab_size); - break; - } - } - - dbpr_msg_flush(pMsgBuff, tab_size); -} - -static int dbpr_report( - const char *pname, DBADDR *paddr, int interest_level, - TAB_BUFFER *pMsgBuff, int tab_size) -{ - char *pmsg; - dbFldDes *pdbFldDes = paddr->pfldDes; - dbRecordType *pdbRecordType = pdbFldDes->pdbRecordType; - short n2; - void *pfield; - char *pfield_name; - char *pfield_value; - DBENTRY dbentry; - DBENTRY *pdbentry = &dbentry; - long status; - - dbInitEntry(pdbbase,pdbentry); - status = dbFindRecord(pdbentry,pname); - if (status) { - errMessage(status,pname); - return -1; - } - - pmsg = pMsgBuff->message; - for (n2 = 0; n2 <= pdbRecordType->no_fields - 1; n2++) { - pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->sortFldInd[n2]]; - pfield_name = pdbFldDes->name; - pfield = ((char *)paddr->precord) + pdbFldDes->offset; - if (pdbFldDes->interest > interest_level ) - continue; - switch (pdbFldDes->field_type) { - case DBF_STRING: - case DBF_USHORT: - case DBF_ENUM: - case DBF_FLOAT: - case DBF_CHAR: - case DBF_UCHAR: - case DBF_SHORT: - case DBF_LONG: - case DBF_ULONG: - case DBF_INT64: - case DBF_UINT64: - case DBF_DOUBLE: - case DBF_MENU: - case DBF_DEVICE: - status = dbFindField(pdbentry,pfield_name); - pfield_value = dbGetString(pdbentry); - sprintf(pmsg, "%s: %s", pfield_name, - (pfield_value ? pfield_value : "")); - dbpr_msgOut(pMsgBuff, tab_size); - break; - - case DBF_INLINK: - case DBF_OUTLINK: - case DBF_FWDLINK: { - DBLINK *plink = (DBLINK *)pfield; - int ind; - - status = dbFindField(pdbentry,pfield_name); - for (ind=0; indtype) - break; - } - if (ind>=LINK_NTYPES) { - sprintf(pmsg,"%s: Illegal Link Type", pfield_name); - } - else { - sprintf(pmsg,"%s:%s %s", pfield_name, - pamaplinkType[ind].strvalue,dbGetString(pdbentry)); - } - dbpr_msgOut(pMsgBuff, tab_size); - } - break; - - case DBF_NOACCESS: - if (pfield == (void *)&paddr->precord->time) { - /* Special for the TIME field, make it human-readable */ - char time_buf[40]; - epicsTimeToStrftime(time_buf, 40, "%Y-%m-%d %H:%M:%S.%09f", - &paddr->precord->time); - sprintf(pmsg, "%s: %s", pfield_name, time_buf); - dbpr_msgOut(pMsgBuff, tab_size); - } - else if (pdbFldDes->size == sizeof(void *) && - strchr(pdbFldDes->extra, '*')) { - /* Special for pointers, needed on little-endian CPUs */ - sprintf(pmsg, "%s: %p", pfield_name, *(void **)pfield); - dbpr_msgOut(pMsgBuff, tab_size); - } - else { /* just print field as hex bytes */ - unsigned char *pchar = (unsigned char *)pfield; - char temp_buf[61]; - char *ptemp_buf = &temp_buf[0]; - short n = pdbFldDes->size; - short i; - unsigned int value; - - if (n > sizeof(temp_buf)/3) n = sizeof(temp_buf)/3; - for (i=0; imessage; - static int last_tabsize; - - if (!((tab_size == 10) || (tab_size == 20))) { - printf("tab_size not 10 or 20 - dbpr_msgOut()\n"); - return; - } - /* init if first time */ - if (!(pMsgBuff->pNext)) - dbpr_init_msg(pMsgBuff, tab_size); - if (tab_size != last_tabsize) - pMsgBuff->pNexTab = pMsgBuff->out_buff + tab_size; - - last_tabsize = tab_size; - /* flush output if NULL string command */ - if (*pmsg == 0) { - dbpr_msg_flush(pMsgBuff, tab_size); - return; - } - /* truncate if too long */ - len = strlen(pmsg); - if (len > MAXLINE) { - err = 1; - len = MAXLINE; - } - - dbpr_insert_msg(pMsgBuff, len, tab_size); - - /* warn if msg gt 80 */ - if (err == 1) { - len = strlen(pmsg); - sprintf(pmsg, "dbpr_msgOut: ERROR - msg length=%d limit=%d ", - (int)len, MAXLINE); - dbpr_insert_msg(pMsgBuff, len, tab_size); - } -} - -static void dbpr_init_msg(TAB_BUFFER *pMsgBuff,int tab_size) -{ - pMsgBuff->pNext = pMsgBuff->out_buff; - pMsgBuff->pLast = pMsgBuff->out_buff + MAXLINE; - pMsgBuff->pNexTab = pMsgBuff->out_buff + tab_size; -} - -static void dbpr_insert_msg(TAB_BUFFER *pMsgBuff,size_t len,int tab_size) -{ - size_t current_len; - size_t n; - size_t tot_line; - char *pmsg = pMsgBuff->message; - current_len = strlen(pMsgBuff->out_buff); - tot_line = current_len + len; - - /* flush buffer if overflow would occor */ - if (tot_line > MAXLINE) - dbpr_msg_flush(pMsgBuff, tab_size); - - /* append message to buffer */ - n = 0; - while ((*pmsg) && (n < len)) { - *pMsgBuff->pNext++ = *pmsg++; - - /* position to next tab stop */ - if (*(pMsgBuff->pNexTab - 1) != '\0') - pMsgBuff->pNexTab = pMsgBuff->pNexTab + tab_size; - n++; - } - - /* fill spaces to next tab stop */ - while (*(pMsgBuff->pNexTab - 1) != ' ' - && pMsgBuff->pNext < pMsgBuff->pLast) { - *pMsgBuff->pNext++ = ' '; - } -} - -static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size) -{ - /* skip print if buffer empty */ - if (pMsgBuff->pNext != pMsgBuff->out_buff) - printf("%s\n", pMsgBuff->out_buff); - - memset(pMsgBuff->out_buff,'\0', (int) MAXLINE + 1); - pMsgBuff->pNext = pMsgBuff->out_buff; - pMsgBuff->pNexTab = pMsgBuff->out_buff + tab_size; -} diff --git a/src/ioc/db/dbTest.h b/src/ioc/db/dbTest.h deleted file mode 100644 index 6d457b59e..000000000 --- a/src/ioc/db/dbTest.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_dbTest_H -#define INC_dbTest_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*dbAddr info */ -epicsShareFunc long dba(const char *pname); -/*list records*/ -epicsShareFunc long dbl( - const char *precordTypename,const char *fields); -/*list number of records of each type*/ -epicsShareFunc long dbnr(int verbose); -/* list aliases */ -epicsShareFunc long dbla(const char *pmask); -/*list records with mask*/ -epicsShareFunc long dbgrep(const char *pmask); -/*get field value*/ -epicsShareFunc long dbgf(const char *pname); -/*put field value*/ -epicsShareFunc long dbpf(const char *pname,const char *pvalue); -/*print record*/ -epicsShareFunc long dbpr(const char *pname,int interest_level); -/*test record*/ -epicsShareFunc long dbtr(const char *pname); -/*test get field*/ -epicsShareFunc long dbtgf(const char *pname); -/*test put field*/ -epicsShareFunc long dbtpf(const char *pname,const char *pvalue); -/*I/O report */ -epicsShareFunc long dbior( - const char *pdrvName,int interest_level); -/*Hardware Configuration Report*/ -epicsShareFunc int dbhcr(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbTest_H */ diff --git a/src/ioc/db/dbUnitTest.c b/src/ioc/db/dbUnitTest.c deleted file mode 100644 index dbd8c487e..000000000 --- a/src/ioc/db/dbUnitTest.c +++ /dev/null @@ -1,416 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 Brookhaven National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - * Ralph Lange - */ - -#include - -#define EPICS_PRIVATE_API - -#include "dbmf.h" -#include "epicsUnitTest.h" -#include "osiFileName.h" -#include "osiUnistd.h" -#include "registry.h" -#include "epicsEvent.h" - -#define epicsExportSharedSymbols -#include "dbAccess.h" -#include "dbBase.h" -#include "dbChannel.h" -#include "dbEvent.h" -#include "dbStaticLib.h" -#include "dbUnitTest.h" -#include "initHooks.h" -#include "iocInit.h" - -static dbEventCtx testEvtCtx; -static epicsMutexId testEvtLock; -static ELLLIST testEvtList; /* holds testMonitor::node */ - -struct testMonitor { - ELLNODE node; - dbEventSubscription sub; - dbChannel *chan; - epicsEventId event; - unsigned count; -}; - -void testdbPrepare(void) -{ - if(!testEvtLock) - testEvtLock = epicsMutexMustCreate(); -} - -void testdbReadDatabase(const char* file, - const char* path, - const char* substitutions) -{ - if(!path) - path = "." OSI_PATH_LIST_SEPARATOR ".." OSI_PATH_LIST_SEPARATOR - "../O.Common" OSI_PATH_LIST_SEPARATOR "O.Common"; - if(dbReadDatabase(&pdbbase, file, path, substitutions)) { - char buf[100]; - const char *cwd = getcwd(buf, sizeof(buf)); - if(!cwd) - cwd = ""; - testAbort("Failed to load test database\ndbReadDatabase(%s,%s,%s)\n from: \"%s\"", - file, path, substitutions, cwd); - } -} - -void testIocInitOk(void) -{ - if(iocBuildIsolated() || iocRun()) - testAbort("Failed to start up test database"); - if(!(testEvtCtx=db_init_events())) - testAbort("Failed to initialize test dbEvent context"); - if(DB_EVENT_OK!=db_start_events(testEvtCtx, "CAS-test", NULL, NULL, epicsThreadPriorityCAServerLow)) - testAbort("Failed to start test dbEvent context"); -} - -void testIocShutdownOk(void) -{ - epicsMutexMustLock(testEvtLock); - if(ellCount(&testEvtList)) - testDiag("Warning, testing monitors still active at testIocShutdownOk()"); - epicsMutexUnlock(testEvtLock); - - db_close_events(testEvtCtx); - testEvtCtx = NULL; - if(iocShutdown()) - testAbort("Failed to shutdown test database"); -} - -void testdbCleanup(void) -{ - dbFreeBase(pdbbase); - db_cleanup_events(); - initHookFree(); - registryFree(); - pdbbase = NULL; - dbmfFreeChunks(); -} - -union anybuf { - epicsAny val; - char valStr[MAX_STRING_SIZE]; - char bytes[sizeof(epicsAny)]; -}; - -long testdbVPutField(const char* pv, short dbrType, va_list ap) -{ - DBADDR addr; - union anybuf pod; - - if (dbNameToAddr(pv, &addr)) { - testFail("Missing PV \"%s\"", pv); - return S_dbLib_recNotFound; - } - - switch(dbrType) { - case DBR_STRING: { - const char *uarg = va_arg(ap,char*); - strncpy(pod.valStr, uarg, sizeof(pod.valStr)); - pod.valStr[sizeof(pod.valStr)-1] = '\0'; - return dbPutField(&addr, dbrType, pod.valStr, 1); - } - - /* The Type parameter takes into consideration - * the C language rules for promotion of argument types - * in variadic functions. - */ -#define OP(DBR,Type,mem) case DBR: {pod.val.mem = va_arg(ap,Type); break;} - OP(DBR_CHAR, int, int8); - OP(DBR_UCHAR, int, uInt8); - OP(DBR_SHORT, int, int16); - OP(DBR_USHORT, int, uInt16); - OP(DBR_LONG, int, int32); - OP(DBR_ULONG, unsigned int, uInt32); - OP(DBR_INT64, long long, int64); - OP(DBR_UINT64, unsigned long long, uInt64); - OP(DBR_FLOAT, double, float32); - OP(DBR_DOUBLE, double, float64); - OP(DBR_ENUM, int, enum16); -#undef OP - default: - testFail("invalid DBR: dbPutField(\"%s\", %d, ...)", - addr.precord->name, dbrType); - return S_db_badDbrtype; - } - - return dbPutField(&addr, dbrType, pod.bytes, 1); -} - -void testdbPutFieldOk(const char* pv, short dbrType, ...) -{ - long ret; - va_list ap; - - va_start(ap, dbrType); - ret = testdbVPutField(pv, dbrType, ap); - va_end(ap); - - testOk(ret==0, "dbPutField(\"%s\", %d, ...) -> %#lx (%s)", pv, dbrType, ret, errSymMsg(ret)); -} - -void testdbPutFieldFail(long status, const char* pv, short dbrType, ...) -{ - long ret; - va_list ap; - - va_start(ap, dbrType); - ret = testdbVPutField(pv, dbrType, ap); - va_end(ap); - - testOk(ret==status, "dbPutField(\"%s\", %d, ...) -> %#lx (%s) == %#lx (%s)", - pv, dbrType, status, errSymMsg(status), ret, errSymMsg(ret)); -} - -void testdbGetFieldEqual(const char* pv, short dbrType, ...) -{ - va_list ap; - - va_start(ap, dbrType); - testdbVGetFieldEqual(pv, dbrType, ap); - va_end(ap); -} - -void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap) -{ - DBADDR addr; - long nReq = 1; - union anybuf pod; - long status; - - if(dbNameToAddr(pv, &addr)) { - testFail("Missing PV \"%s\"", pv); - return; - } - - status = dbGetField(&addr, dbrType, pod.bytes, NULL, &nReq, NULL); - if (status) { - testFail("dbGetField(\"%s\", %d, ...) -> %#lx (%s)", pv, dbrType, status, errSymMsg(status)); - return; - } else if(nReq==0) { - testFail("dbGetField(\"%s\", %d, ...) -> zero length", pv, dbrType); - return; - } - - switch(dbrType) { - case DBR_STRING: { - const char *expect = va_arg(ap, char*); - testOk(strcmp(expect, pod.valStr)==0, - "dbGetField(\"%s\", %d) -> \"%s\" == \"%s\"", - pv, dbrType, expect, pod.valStr); - break; - } -#define OP(DBR,Type,mem,pat) case DBR: {Type expect = va_arg(ap,Type); \ - testOk(expect==pod.val.mem, "dbGetField(\"%s\", %d) -> " pat " == " pat, \ - pv, dbrType, expect, (Type)pod.val.mem); break;} - - OP(DBR_CHAR, int, int8, "%d"); - OP(DBR_UCHAR, int, uInt8, "%d"); - OP(DBR_SHORT, int, int16, "%d"); - OP(DBR_USHORT, int, uInt16, "%d"); - OP(DBR_LONG, int, int32, "%d"); - OP(DBR_ULONG, unsigned int, uInt32, "%u"); - OP(DBR_INT64, long long, int64, "%lld"); - OP(DBR_UINT64, unsigned long long, uInt64, "%llu"); - OP(DBR_FLOAT, double, float32, "%e"); - OP(DBR_DOUBLE, double, float64, "%e"); - OP(DBR_ENUM, int, enum16, "%d"); -#undef OP - default: - testFail("dbGetField(\"%s\", %d) -> unsupported dbf", pv, dbrType); - } -} - -void testdbPutArrFieldOk(const char* pv, short dbrType, unsigned long count, const void *pbuf) -{ - DBADDR addr; - long status; - - if (dbNameToAddr(pv, &addr)) { - testFail("Missing PV \"%s\"", pv); - return; - } - - status = dbPutField(&addr, dbrType, pbuf, count); - - testOk(status==0, "dbPutField(\"%s\", dbr=%d, count=%lu, ...) -> %ld", pv, dbrType, count, status); -} - -void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsigned long cnt, const void *pbufraw) -{ - DBADDR addr; - const long vSize = dbValueSize(dbfType); - const long nStore = vSize * nRequest; - long status; - char *gbuf, *gstore; - const char *pbuf = pbufraw; - - if(dbNameToAddr(pv, &addr)) { - testFail("Missing PV \"%s\"", pv); - return; - } - - gbuf = gstore = malloc(nStore); - if(!gbuf && nStore!=0) { /* note that malloc(0) is allowed to return NULL on success */ - testFail("Allocation failed esize=%ld total=%ld", vSize, nStore); - return; - } - - status = dbGetField(&addr, dbfType, gbuf, NULL, &nRequest, NULL); - if (status) { - testFail("dbGetField(\"%s\", %d, ...) -> %#lx", pv, dbfType, status); - - } else { - unsigned match = nRequest==cnt; - long n, N = nRequest < cnt ? nRequest : cnt; - - if(!match) - testDiag("Length mis-match. expected=%lu actual=%lu", cnt, nRequest); - - for(n=0; ncount++; - epicsMutexUnlock(testEvtLock); - epicsEventMustTrigger(mon->event); -} - -testMonitor* testMonitorCreate(const char* pvname, unsigned mask, unsigned opt) -{ - long status; - testMonitor *mon; - dbChannel *chan; - assert(testEvtCtx); - - mon = callocMustSucceed(1, sizeof(*mon), "testMonitorCreate"); - - mon->event = epicsEventMustCreate(epicsEventEmpty); - - chan = mon->chan = dbChannelCreate(pvname); - if(!chan) - testAbort("testMonitorCreate - dbChannelCreate(\"%s\") fails", pvname); - if(!!(status=dbChannelOpen(chan))) - testAbort("testMonitorCreate - dbChannelOpen(\"%s\") fails w/ %ld", pvname, status); - - mon->sub = db_add_event(testEvtCtx, chan, &testmonupdate, mon, mask); - if(!mon->sub) - testAbort("testMonitorCreate - db_add_event(\"%s\") fails", pvname); - - db_event_enable(mon->sub); - - epicsMutexMustLock(testEvtLock); - ellAdd(&testEvtList, &mon->node); - epicsMutexUnlock(testEvtLock); - - return mon; -} - -void testMonitorDestroy(testMonitor *mon) -{ - if(!mon) return; - - db_event_disable(mon->sub); - - epicsMutexMustLock(testEvtLock); - ellDelete(&testEvtList, &mon->node); - epicsMutexUnlock(testEvtLock); - - db_cancel_event(mon->sub); - - dbChannelDelete(mon->chan); - - epicsEventDestroy(mon->event); - - free(mon); -} - -void testMonitorWait(testMonitor *mon) -{ - static const double delay = 60.0; - - switch(epicsEventWaitWithTimeout(mon->event, delay)) - { - case epicsEventOK: - return; - case epicsEventWaitTimeout: - default: - testAbort("testMonitorWait() exceeded %g second timeout", delay); - } -} - -unsigned testMonitorCount(testMonitor *mon, unsigned reset) -{ - unsigned count; - epicsMutexMustLock(testEvtLock); - count = mon->count; - if(reset) { - mon->count = 0; - epicsEventWaitWithTimeout(mon->event, 0); /* clear the event */ - } - epicsMutexUnlock(testEvtLock); - return count; -} - diff --git a/src/ioc/db/dbUnitTest.h b/src/ioc/db/dbUnitTest.h deleted file mode 100644 index 8fe8011af..000000000 --- a/src/ioc/db/dbUnitTest.h +++ /dev/null @@ -1,105 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 Brookhaven National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - * Ralph Lange - */ - -#ifndef EPICSUNITTESTDB_H -#define EPICSUNITTESTDB_H - -#include - -#include "epicsUnitTest.h" -#include "dbAddr.h" -#include "dbCommon.h" - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void testdbPrepare(void); -epicsShareFunc void testdbReadDatabase(const char* file, - const char* path, - const char* substitutions); -epicsShareFunc void testIocInitOk(void); -epicsShareFunc void testIocShutdownOk(void); -epicsShareFunc void testdbCleanup(void); - -/* Correct argument types must be used with this var-arg function! - * Doing otherwise will result in corruption of argument values! - * - * int for DBR_UCHAR, DBR_CHAR, DBR_USHORT, DBR_SHORT, DBR_LONG - * unsigned int for DBR_ULONG - * long long for DBF_INT64 - * unsigned long long for DBF_UINT64 - * double for DBR_FLOAT and DBR_DOUBLE - * const char* for DBR_STRING - * - * eg. - * testdbPutFieldOk("pvname", DBF_ULONG, (unsigned int)5); - * testdbPutFieldOk("pvname", DBF_FLOAT, (double)4.1); - * testdbPutFieldOk("pvname", DBF_STRING, "hello world"); - */ -epicsShareFunc void testdbPutFieldOk(const char* pv, short dbrType, ...); -/* Tests for put failure */ -epicsShareFunc void testdbPutFieldFail(long status, const char* pv, short dbrType, ...); - -epicsShareFunc long testdbVPutField(const char* pv, short dbrType, va_list ap); - -epicsShareFunc void testdbGetFieldEqual(const char* pv, short dbrType, ...); -epicsShareFunc void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap); - -epicsShareFunc void testdbPutArrFieldOk(const char* pv, short dbrType, unsigned long count, const void *pbuf); - -/** - * @param pv PV name string - * @param dbfType One of the DBF_* macros from dbAccess.h - * @param nRequest Number of elements to request from pv - * @param pbufcnt Number of elements pointed to be pbuf - * @param pbuf Expected value buffer - * - * Execute dbGet() of nRequest elements and compare the result with - * pbuf (pbufcnt is an element count). - * Element size is derived from dbfType. - * - * nRequest > pbufcnt will detect truncation. - * nRequest < pbufcnt always fails. - * nRequest ==pbufcnt checks prefix (actual may be longer than expected) - */ -epicsShareFunc void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsigned long pbufcnt, const void *pbuf); - -epicsShareFunc dbCommon* testdbRecordPtr(const char* pv); - -typedef struct testMonitor testMonitor; - -/* Begin monitoring the named PV for changes */ -epicsShareFunc testMonitor* testMonitorCreate(const char* pvname, unsigned dbe_mask, unsigned opt); -/* End monitoring */ -epicsShareFunc void testMonitorDestroy(testMonitor*); -/* Return immediately if it has been updated since create, last wait, - * or reset (count w/ reset=1). - * Otherwise, block until the value of the target PV is updated. - */ -epicsShareFunc void testMonitorWait(testMonitor*); -/* Return the number of monitor events which have occured since create, - * or a pervious reset (called reset=1). - * Calling w/ reset=0 only returns the count. - * Calling w/ reset=1 resets the count to zero and ensures that the next - * wait will block unless subsequent events occur. Returns the previous - * count. - */ -epicsShareFunc unsigned testMonitorCount(testMonitor*, unsigned reset); - -#ifdef __cplusplus -} -#endif - -#endif // EPICSUNITTESTDB_H diff --git a/src/ioc/db/db_access.c b/src/ioc/db/db_access.c deleted file mode 100644 index 35712ddd6..000000000 --- a/src/ioc/db/db_access.c +++ /dev/null @@ -1,1031 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Interface between old database access and new - * - * Author: Marty Kraimer - * Andrew Johnson - */ - -#include -#include -#include -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsConvert.h" -#include "epicsTime.h" -#include "errlog.h" -#include "errMdef.h" - -#define db_accessHFORdb_accessC -#include "db_access.h" -#undef db_accessHFORdb_accessC - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "db_access_routines.h" -#include "dbBase.h" -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbEvent.h" -#include "dbLock.h" -#include "dbNotify.h" -#include "dbStaticLib.h" -#include "recSup.h" - - -#define oldDBF_STRING 0 -#define oldDBF_INT 1 -#define oldDBF_SHORT 1 -#define oldDBF_FLOAT 2 -#define oldDBF_ENUM 3 -#define oldDBF_CHAR 4 -#define oldDBF_LONG 5 -#define oldDBF_DOUBLE 6 - -/* data request buffer types */ -#define oldDBR_STRING oldDBF_STRING -#define oldDBR_INT oldDBF_INT -#define oldDBR_SHORT oldDBF_INT -#define oldDBR_FLOAT oldDBF_FLOAT -#define oldDBR_ENUM oldDBF_ENUM -#define oldDBR_CHAR oldDBF_CHAR -#define oldDBR_LONG oldDBF_LONG -#define oldDBR_DOUBLE oldDBF_DOUBLE -#define oldDBR_STS_STRING 7 -#define oldDBR_STS_INT 8 -#define oldDBR_STS_SHORT 8 -#define oldDBR_STS_FLOAT 9 -#define oldDBR_STS_ENUM 10 -#define oldDBR_STS_CHAR 11 -#define oldDBR_STS_LONG 12 -#define oldDBR_STS_DOUBLE 13 -#define oldDBR_TIME_STRING 14 -#define oldDBR_TIME_INT 15 -#define oldDBR_TIME_SHORT 15 -#define oldDBR_TIME_FLOAT 16 -#define oldDBR_TIME_ENUM 17 -#define oldDBR_TIME_CHAR 18 -#define oldDBR_TIME_LONG 19 -#define oldDBR_TIME_DOUBLE 20 -#define oldDBR_GR_STRING 21 -#define oldDBR_GR_INT 22 -#define oldDBR_GR_SHORT 22 -#define oldDBR_GR_FLOAT 23 -#define oldDBR_GR_ENUM 24 -#define oldDBR_GR_CHAR 25 -#define oldDBR_GR_LONG 26 -#define oldDBR_GR_DOUBLE 27 -#define oldDBR_CTRL_STRING 28 -#define oldDBR_CTRL_INT 29 -#define oldDBR_CTRL_SHORT 29 -#define oldDBR_CTRL_FLOAT 30 -#define oldDBR_CTRL_ENUM 31 -#define oldDBR_CTRL_CHAR 32 -#define oldDBR_CTRL_LONG 33 -#define oldDBR_CTRL_DOUBLE 34 -#define oldDBR_PUT_ACKT oldDBR_CTRL_DOUBLE + 1 -#define oldDBR_PUT_ACKS oldDBR_PUT_ACKT + 1 -#define oldDBR_STSACK_STRING oldDBR_PUT_ACKS + 1 -#define oldDBR_CLASS_NAME oldDBR_STSACK_STRING + 1 - -typedef char DBSTRING[MAX_STRING_SIZE]; - -struct dbChannel * dbChannel_create(const char *pname) -{ - dbChannel *chan = dbChannelCreate(pname); - - if (!chan) - return NULL; - - if (INVALID_DB_REQ(dbChannelExportType(chan)) || - dbChannelOpen(chan)) { - dbChannelDelete(chan); - return NULL; - } - - return chan; -} - -int dbChannel_get(struct dbChannel *chan, - int buffer_type, void *pbuffer, long no_elements, void *pfl) -{ - long nRequest = no_elements; - int result = dbChannel_get_count( - chan, buffer_type, pbuffer, &nRequest, pfl); - if (nRequest < no_elements) { - /* The database request returned fewer elements than requested, so - * fill the remainder of the buffer with zeros. - */ - int val_size = dbr_value_size[buffer_type]; - int offset = dbr_size[buffer_type] + (nRequest - 1) * val_size; - int nbytes = (no_elements - nRequest) * val_size; - - memset((char *)pbuffer + offset, 0, nbytes); - } - return result; -} - -/* Performs the work of the public db_get_field API, but also returns the number - * of elements actually copied to the buffer. The caller is responsible for - * zeroing the remaining part of the buffer. */ -int dbChannel_get_count( - struct dbChannel *chan, int buffer_type, - void *pbuffer, long *nRequest, void *pfl) -{ - long status; - long options; - long i; - long zero = 0; - - /* The order of the DBR* elements in the "newSt" structures below is - * very important and must correspond to the order of processing - * in the dbAccess.c dbGet() and getOptions() routines. - */ - - dbScanLock(dbChannelRecord(chan)); - - switch(buffer_type) { - case(oldDBR_STRING): - status = dbChannelGet(chan, DBR_STRING, pbuffer, &zero, nRequest, pfl); - break; -/* case(oldDBR_INT): */ - case(oldDBR_SHORT): - status = dbChannelGet(chan, DBR_SHORT, pbuffer, &zero, nRequest, pfl); - break; - case(oldDBR_FLOAT): - status = dbChannelGet(chan, DBR_FLOAT, pbuffer, &zero, nRequest, pfl); - break; - case(oldDBR_ENUM): - status = dbChannelGet(chan, DBR_ENUM, pbuffer, &zero, nRequest, pfl); - break; - case(oldDBR_CHAR): - status = dbChannelGet(chan, DBR_CHAR, pbuffer, &zero, nRequest, pfl); - break; - case(oldDBR_LONG): - status = dbChannelGet(chan, DBR_LONG, pbuffer, &zero, nRequest, pfl); - break; - case(oldDBR_DOUBLE): - status = dbChannelGet(chan, DBR_DOUBLE, pbuffer, &zero, nRequest, pfl); - break; - - case(oldDBR_STS_STRING): - case(oldDBR_GR_STRING): - case(oldDBR_CTRL_STRING): - { - struct dbr_sts_string *pold = (struct dbr_sts_string *)pbuffer; - struct { - DBRstatus - } newSt; - - options = DBR_STATUS; - status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - status = dbChannelGet(chan, DBR_STRING, pold->value, &zero, - nRequest, pfl); - } - break; -/* case(oldDBR_STS_INT): */ - case(oldDBR_STS_SHORT): - { - struct dbr_sts_int *pold = (struct dbr_sts_int *)pbuffer; - struct { - DBRstatus - } newSt; - - options = DBR_STATUS; - status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - status = dbChannelGet(chan, DBR_SHORT, &pold->value, &zero, - nRequest, pfl); - } - break; - case(oldDBR_STS_FLOAT): - { - struct dbr_sts_float *pold = (struct dbr_sts_float *)pbuffer; - struct { - DBRstatus - } newSt; - - options = DBR_STATUS; - status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &zero, - nRequest, pfl); - } - break; - case(oldDBR_STS_ENUM): - { - struct dbr_sts_enum *pold = (struct dbr_sts_enum *)pbuffer; - struct { - DBRstatus - } newSt; - - options = DBR_STATUS; - status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - status = dbChannelGet(chan, DBR_ENUM, &pold->value, &zero, - nRequest, pfl); - } - break; - case(oldDBR_STS_CHAR): - { - struct dbr_sts_char *pold = (struct dbr_sts_char *)pbuffer; - struct { - DBRstatus - } newSt; - - options = DBR_STATUS; - status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &zero, - nRequest, pfl); - } - break; - case(oldDBR_STS_LONG): - { - struct dbr_sts_long *pold = (struct dbr_sts_long *)pbuffer; - struct { - DBRstatus - } newSt; - - options = DBR_STATUS; - status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - status = dbChannelGet(chan, DBR_LONG, &pold->value, &zero, - nRequest, pfl); - } - break; - case(oldDBR_STS_DOUBLE): - { - struct dbr_sts_double *pold = (struct dbr_sts_double *)pbuffer; - struct { - DBRstatus - } newSt; - - options = DBR_STATUS; - status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - options = 0; - status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options, - nRequest, pfl); - } - break; - - case(oldDBR_TIME_STRING): - { - struct dbr_time_string *pold = (struct dbr_time_string *)pbuffer; - struct { - DBRstatus - DBRtime - } newSt; - - options = DBR_STATUS | DBR_TIME; - status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->stamp = newSt.time; /* structure copy */ - options = 0; - status = dbChannelGet(chan, DBR_STRING, pold->value, &options, - nRequest, pfl); - } - break; -/* case(oldDBR_TIME_INT): */ - case(oldDBR_TIME_SHORT): - { - struct dbr_time_short *pold = (struct dbr_time_short *)pbuffer; - struct { - DBRstatus - DBRtime - } newSt; - - options = DBR_STATUS | DBR_TIME; - status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->stamp = newSt.time; /* structure copy */ - options = 0; - status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_TIME_FLOAT): - { - struct dbr_time_float *pold = (struct dbr_time_float *)pbuffer; - struct { - DBRstatus - DBRtime - } newSt; - - options = DBR_STATUS | DBR_TIME; - status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->stamp = newSt.time; /* structure copy */ - options = 0; - status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_TIME_ENUM): - { - struct dbr_time_enum *pold = (struct dbr_time_enum *)pbuffer; - struct { - DBRstatus - DBRtime - } newSt; - - options = DBR_STATUS | DBR_TIME; - status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->stamp = newSt.time; /* structure copy */ - options = 0; - status = dbChannelGet(chan, DBR_ENUM, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_TIME_CHAR): - { - struct dbr_time_char *pold = (struct dbr_time_char *)pbuffer; - struct { - DBRstatus - DBRtime - } newSt; - - options = DBR_STATUS | DBR_TIME; - status = dbChannelGet(chan, DBR_CHAR, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->stamp = newSt.time; /* structure copy */ - options = 0; - status = dbChannelGet(chan, DBR_CHAR, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_TIME_LONG): - { - struct dbr_time_long *pold = (struct dbr_time_long *)pbuffer; - struct { - DBRstatus - DBRtime - } newSt; - - options = DBR_STATUS | DBR_TIME; - status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->stamp = newSt.time; /* structure copy */ - options = 0; - status = dbChannelGet(chan, DBR_LONG, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_TIME_DOUBLE): - { - struct dbr_time_double *pold = (struct dbr_time_double *)pbuffer; - struct { - DBRstatus - DBRtime - } newSt; - - options = DBR_STATUS | DBR_TIME; - status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->stamp = newSt.time; /* structure copy */ - options = 0; - status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options, - nRequest, pfl); - } - break; - -/* case(oldDBR_GR_STRING): NOT IMPLEMENTED - use DBR_STS_STRING */ -/* case(oldDBR_GR_INT): */ - case(oldDBR_GR_SHORT): - { - struct dbr_gr_int *pold = (struct dbr_gr_int *)pbuffer; - struct { - DBRstatus - DBRunits - DBRgrLong - DBRalLong - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG; - status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = newSt.upper_disp_limit; - pold->lower_disp_limit = newSt.lower_disp_limit; - pold->upper_alarm_limit = newSt.upper_alarm_limit; - pold->upper_warning_limit = newSt.upper_warning_limit; - pold->lower_warning_limit = newSt.lower_warning_limit; - pold->lower_alarm_limit = newSt.lower_alarm_limit; - options = 0; - status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_GR_FLOAT): - { - struct dbr_gr_float *pold = (struct dbr_gr_float *)pbuffer; - struct { - DBRstatus - DBRunits - DBRprecision - DBRgrDouble - DBRalDouble - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE | - DBR_AL_DOUBLE; - status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->precision = (dbr_short_t) newSt.precision.dp; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = epicsConvertDoubleToFloat(newSt.upper_disp_limit); - pold->lower_disp_limit = epicsConvertDoubleToFloat(newSt.lower_disp_limit); - pold->upper_alarm_limit = epicsConvertDoubleToFloat(newSt.upper_alarm_limit); - pold->lower_alarm_limit = epicsConvertDoubleToFloat(newSt.lower_alarm_limit); - pold->upper_warning_limit = epicsConvertDoubleToFloat(newSt.upper_warning_limit); - pold->lower_warning_limit = epicsConvertDoubleToFloat(newSt.lower_warning_limit); - options = 0; - status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options, - nRequest, pfl); - } - break; -/* case(oldDBR_GR_ENUM): see oldDBR_CTRL_ENUM */ - case(oldDBR_GR_CHAR): - { - struct dbr_gr_char *pold = (struct dbr_gr_char *)pbuffer; - struct { - DBRstatus - DBRunits - DBRgrLong - DBRalLong - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG; - status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = newSt.upper_disp_limit; - pold->lower_disp_limit = newSt.lower_disp_limit; - pold->upper_alarm_limit = newSt.upper_alarm_limit; - pold->upper_warning_limit = newSt.upper_warning_limit; - pold->lower_warning_limit = newSt.lower_warning_limit; - pold->lower_alarm_limit = newSt.lower_alarm_limit; - options = 0; - status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_GR_LONG): - { - struct dbr_gr_long *pold = (struct dbr_gr_long *)pbuffer; - struct { - DBRstatus - DBRunits - DBRgrLong - DBRalLong - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG; - status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = newSt.upper_disp_limit; - pold->lower_disp_limit = newSt.lower_disp_limit; - pold->upper_alarm_limit = newSt.upper_alarm_limit; - pold->upper_warning_limit = newSt.upper_warning_limit; - pold->lower_warning_limit = newSt.lower_warning_limit; - pold->lower_alarm_limit = newSt.lower_alarm_limit; - options = 0; - status = dbChannelGet(chan, DBR_LONG, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_GR_DOUBLE): - { - struct dbr_gr_double *pold = (struct dbr_gr_double *)pbuffer; - struct { - DBRstatus - DBRunits - DBRprecision - DBRgrDouble - DBRalDouble - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE | - DBR_AL_DOUBLE; - status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->precision = (dbr_short_t) newSt.precision.dp; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = newSt.upper_disp_limit; - pold->lower_disp_limit = newSt.lower_disp_limit; - pold->upper_alarm_limit = newSt.upper_alarm_limit; - pold->upper_warning_limit = newSt.upper_warning_limit; - pold->lower_warning_limit = newSt.lower_warning_limit; - pold->lower_alarm_limit = newSt.lower_alarm_limit; - options = 0; - status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options, - nRequest, pfl); - } - break; - -/* case(oldDBR_CTRL_INT): */ - case(oldDBR_CTRL_SHORT): - { - struct dbr_ctrl_int *pold = (struct dbr_ctrl_int *)pbuffer; - struct { - DBRstatus - DBRunits - DBRgrLong - DBRctrlLong - DBRalLong - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG | - DBR_AL_LONG; - status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = newSt.upper_disp_limit; - pold->lower_disp_limit = newSt.lower_disp_limit; - pold->upper_alarm_limit = newSt.upper_alarm_limit; - pold->upper_warning_limit = newSt.upper_warning_limit; - pold->lower_warning_limit = newSt.lower_warning_limit; - pold->lower_alarm_limit = newSt.lower_alarm_limit; - pold->upper_ctrl_limit = newSt.upper_ctrl_limit; - pold->lower_ctrl_limit = newSt.lower_ctrl_limit; - options = 0; - status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_CTRL_FLOAT): - { - struct dbr_ctrl_float *pold = (struct dbr_ctrl_float *)pbuffer; - struct { - DBRstatus - DBRunits - DBRprecision - DBRgrDouble - DBRctrlDouble - DBRalDouble - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE | - DBR_CTRL_DOUBLE | DBR_AL_DOUBLE; - status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->precision = (dbr_short_t) newSt.precision.dp; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = epicsConvertDoubleToFloat(newSt.upper_disp_limit); - pold->lower_disp_limit = epicsConvertDoubleToFloat(newSt.lower_disp_limit); - pold->upper_alarm_limit = epicsConvertDoubleToFloat(newSt.upper_alarm_limit); - pold->lower_alarm_limit = epicsConvertDoubleToFloat(newSt.lower_alarm_limit); - pold->upper_warning_limit = epicsConvertDoubleToFloat(newSt.upper_warning_limit); - pold->lower_warning_limit = epicsConvertDoubleToFloat(newSt.lower_warning_limit); - pold->upper_ctrl_limit = epicsConvertDoubleToFloat(newSt.upper_ctrl_limit); - pold->lower_ctrl_limit = epicsConvertDoubleToFloat(newSt.lower_ctrl_limit); - options = 0; - status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_GR_ENUM): - case(oldDBR_CTRL_ENUM): - { - struct dbr_ctrl_enum *pold = (struct dbr_ctrl_enum *)pbuffer; - struct { - DBRstatus - DBRenumStrs - } newSt; - short no_str; - - memset(pold, '\0', sizeof(struct dbr_ctrl_enum)); - /* first get status and severity */ - options = DBR_STATUS | DBR_ENUM_STRS; - status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - no_str = newSt.no_str; - if (no_str>16) no_str=16; - pold->no_str = no_str; - for (i = 0; i < no_str; i++) - strncpy(pold->strs[i], newSt.strs[i], sizeof(pold->strs[i])); - /*now get values*/ - options = 0; - status = dbChannelGet(chan, DBR_ENUM, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_CTRL_CHAR): - { - struct dbr_ctrl_char *pold = (struct dbr_ctrl_char *)pbuffer; - struct { - DBRstatus - DBRunits - DBRgrLong - DBRctrlLong - DBRalLong - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG | - DBR_AL_LONG; - status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = newSt.upper_disp_limit; - pold->lower_disp_limit = newSt.lower_disp_limit; - pold->upper_alarm_limit = newSt.upper_alarm_limit; - pold->upper_warning_limit = newSt.upper_warning_limit; - pold->lower_warning_limit = newSt.lower_warning_limit; - pold->lower_alarm_limit = newSt.lower_alarm_limit; - pold->upper_ctrl_limit = newSt.upper_ctrl_limit; - pold->lower_ctrl_limit = newSt.lower_ctrl_limit; - options = 0; - status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_CTRL_LONG): - { - struct dbr_ctrl_long *pold = (struct dbr_ctrl_long *)pbuffer; - struct { - DBRstatus - DBRunits - DBRgrLong - DBRctrlLong - DBRalLong - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG | - DBR_AL_LONG; - status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = newSt.upper_disp_limit; - pold->lower_disp_limit = newSt.lower_disp_limit; - pold->upper_alarm_limit = newSt.upper_alarm_limit; - pold->upper_warning_limit = newSt.upper_warning_limit; - pold->lower_warning_limit = newSt.lower_warning_limit; - pold->lower_alarm_limit = newSt.lower_alarm_limit; - pold->upper_ctrl_limit = newSt.upper_ctrl_limit; - pold->lower_ctrl_limit = newSt.lower_ctrl_limit; - options = 0; - status = dbChannelGet(chan, DBR_LONG, &pold->value, &options, - nRequest, pfl); - } - break; - case(oldDBR_CTRL_DOUBLE): - { - struct dbr_ctrl_double *pold = (struct dbr_ctrl_double *)pbuffer; - struct { - DBRstatus - DBRunits - DBRprecision - DBRgrDouble - DBRctrlDouble - DBRalDouble - } newSt; - - options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE | - DBR_CTRL_DOUBLE | DBR_AL_DOUBLE; - status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->precision = (dbr_short_t) newSt.precision.dp; - strncpy(pold->units, newSt.units, MAX_UNITS_SIZE); - pold->units[MAX_UNITS_SIZE-1] = '\0'; - pold->upper_disp_limit = newSt.upper_disp_limit; - pold->lower_disp_limit = newSt.lower_disp_limit; - pold->upper_alarm_limit = newSt.upper_alarm_limit; - pold->upper_warning_limit = newSt.upper_warning_limit; - pold->lower_warning_limit = newSt.lower_warning_limit; - pold->lower_alarm_limit = newSt.lower_alarm_limit; - pold->upper_ctrl_limit = newSt.upper_ctrl_limit; - pold->lower_ctrl_limit = newSt.lower_ctrl_limit; - options = 0; - status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options, - nRequest, pfl); - } - break; - - case(oldDBR_STSACK_STRING): - { - struct dbr_stsack_string *pold = (struct dbr_stsack_string *)pbuffer; - struct { - DBRstatus - } newSt; - - options = DBR_STATUS; - status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl); - pold->status = newSt.status; - pold->severity = newSt.severity; - pold->ackt = newSt.ackt; - pold->acks = newSt.acks; - options = 0; - status = dbChannelGet(chan, DBR_STRING, pold->value, - &options, nRequest, pfl); - } - break; - - case(oldDBR_CLASS_NAME): - { - DBENTRY dbEntry; - char *name = 0; - char *pto = (char *)pbuffer; - - if (!pdbbase) { - status = S_db_notFound; - break; - } - dbInitEntry(pdbbase, &dbEntry); - status = dbFindRecord(&dbEntry, dbChannelRecord(chan)->name); - if (!status) name = dbGetRecordTypeName(&dbEntry); - dbFinishEntry(&dbEntry); - if (status) break; - if (!name) { - status = S_dbLib_recordTypeNotFound; - break; - } - pto[MAX_STRING_SIZE-1] = 0; - strncpy(pto, name, MAX_STRING_SIZE-1); - } - break; - default: - status = -1; - break; - } - - dbScanUnlock(dbChannelRecord(chan)); - - if (status) return -1; - return 0; -} - -int dbChannel_put(struct dbChannel *chan, int src_type, - const void *psrc, long no_elements) -{ - long status; - - switch (src_type) { - case(oldDBR_STRING): - status = dbChannelPutField(chan, DBR_STRING, psrc, no_elements); - break; -/* case(oldDBR_INT): */ - case(oldDBR_SHORT): - status = dbChannelPutField(chan, DBR_SHORT, psrc, no_elements); - break; - case(oldDBR_FLOAT): - status = dbChannelPutField(chan, DBR_FLOAT, psrc, no_elements); - break; - case(oldDBR_ENUM): - status = dbChannelPutField(chan, DBR_ENUM, psrc, no_elements); - break; - case(oldDBR_CHAR): - status = dbChannelPutField(chan, DBR_UCHAR, psrc, no_elements); - break; - case(oldDBR_LONG): - status = dbChannelPutField(chan, DBR_LONG, psrc, no_elements); - break; - case(oldDBR_DOUBLE): - status = dbChannelPutField(chan, DBR_DOUBLE, psrc, no_elements); - break; - - case(oldDBR_STS_STRING): - status = dbChannelPutField(chan, DBR_STRING, - ((const struct dbr_sts_string *)psrc)->value, no_elements); - break; -/* case(oldDBR_STS_INT): */ - case(oldDBR_STS_SHORT): - status = dbChannelPutField(chan, DBR_SHORT, - &((const struct dbr_sts_short *)psrc)->value, no_elements); - break; - case(oldDBR_STS_FLOAT): - status = dbChannelPutField(chan, DBR_FLOAT, - &((const struct dbr_sts_float *)psrc)->value, no_elements); - break; - case(oldDBR_STS_ENUM): - status = dbChannelPutField(chan, DBR_ENUM, - &((const struct dbr_sts_enum *)psrc)->value, no_elements); - break; - case(oldDBR_STS_CHAR): - status = dbChannelPutField(chan, DBR_UCHAR, - &((const struct dbr_sts_char *)psrc)->value, no_elements); - break; - case(oldDBR_STS_LONG): - status = dbChannelPutField(chan, DBR_LONG, - &((const struct dbr_sts_long *)psrc)->value, no_elements); - break; - case(oldDBR_STS_DOUBLE): - status = dbChannelPutField(chan, DBR_DOUBLE, - &((const struct dbr_sts_double *)psrc)->value, no_elements); - break; - - case(oldDBR_TIME_STRING): - status = dbChannelPutField(chan, DBR_TIME, - ((const struct dbr_time_string *)psrc)->value, no_elements); - break; -/* case(oldDBR_TIME_INT): */ - case(oldDBR_TIME_SHORT): - status = dbChannelPutField(chan, DBR_SHORT, - &((const struct dbr_time_short *)psrc)->value, no_elements); - break; - case(oldDBR_TIME_FLOAT): - status = dbChannelPutField(chan, DBR_FLOAT, - &((const struct dbr_time_float *)psrc)->value, no_elements); - break; - case(oldDBR_TIME_ENUM): - status = dbChannelPutField(chan, DBR_ENUM, - &((const struct dbr_time_enum *)psrc)->value, no_elements); - break; - case(oldDBR_TIME_CHAR): - status = dbChannelPutField(chan, DBR_UCHAR, - &((const struct dbr_time_char *)psrc)->value, no_elements); - break; - case(oldDBR_TIME_LONG): - status = dbChannelPutField(chan, DBR_LONG, - &((const struct dbr_time_long *)psrc)->value, no_elements); - break; - case(oldDBR_TIME_DOUBLE): - status = dbChannelPutField(chan, DBR_DOUBLE, - &((const struct dbr_time_double *)psrc)->value, no_elements); - break; - - case(oldDBR_GR_STRING): - /* no struct dbr_gr_string - use dbr_sts_string instead */ - status = dbChannelPutField(chan, DBR_STRING, - ((const struct dbr_sts_string *)psrc)->value, no_elements); - break; -/* case(oldDBR_GR_INT): */ - case(oldDBR_GR_SHORT): - status = dbChannelPutField(chan, DBR_SHORT, - &((const struct dbr_gr_short *)psrc)->value, no_elements); - break; - case(oldDBR_GR_FLOAT): - status = dbChannelPutField(chan, DBR_FLOAT, - &((const struct dbr_gr_float *)psrc)->value, no_elements); - break; - case(oldDBR_GR_ENUM): - status = dbChannelPutField(chan, DBR_ENUM, - &((const struct dbr_gr_enum *)psrc)->value, no_elements); - break; - case(oldDBR_GR_CHAR): - status = dbChannelPutField(chan, DBR_UCHAR, - &((const struct dbr_gr_char *)psrc)->value, no_elements); - break; - case(oldDBR_GR_LONG): - status = dbChannelPutField(chan, DBR_LONG, - &((const struct dbr_gr_long *)psrc)->value, no_elements); - break; - case(oldDBR_GR_DOUBLE): - status = dbChannelPutField(chan, DBR_DOUBLE, - &((const struct dbr_gr_double *)psrc)->value, no_elements); - break; - - case(oldDBR_CTRL_STRING): - /* no struct dbr_ctrl_string - use dbr_sts_string instead */ - status = dbChannelPutField(chan, DBR_STRING, - ((const struct dbr_sts_string *)psrc)->value, no_elements); - break; -/* case(oldDBR_CTRL_INT): */ - case(oldDBR_CTRL_SHORT): - status = dbChannelPutField(chan, DBR_SHORT, - &((const struct dbr_ctrl_short *)psrc)->value, no_elements); - break; - case(oldDBR_CTRL_FLOAT): - status = dbChannelPutField(chan, DBR_FLOAT, - &((const struct dbr_ctrl_float *)psrc)->value, no_elements); - break; - case(oldDBR_CTRL_ENUM): - status = dbChannelPutField(chan, DBR_ENUM, - &((const struct dbr_ctrl_enum *)psrc)->value, no_elements); - break; - case(oldDBR_CTRL_CHAR): - status = dbChannelPutField(chan, DBR_UCHAR, - &((const struct dbr_ctrl_char *)psrc)->value, no_elements); - break; - case(oldDBR_CTRL_LONG): - status = dbChannelPutField(chan, DBR_LONG, - &((const struct dbr_ctrl_long *)psrc)->value, no_elements); - break; - case(oldDBR_CTRL_DOUBLE): - status = dbChannelPutField(chan, DBR_DOUBLE, - &((const struct dbr_ctrl_double *)psrc)->value, no_elements); - break; - - case(oldDBR_PUT_ACKT): - status = dbChannelPutField(chan, DBR_PUT_ACKT, psrc, no_elements); - break; - case(oldDBR_PUT_ACKS): - status = dbChannelPutField(chan, DBR_PUT_ACKS, psrc, no_elements); - break; - - default: - return -1; - } - if (status) return -1; - return 0; -} - - -static int mapOldType (short oldtype) -{ - int dbrType = -1; - - switch (oldtype) { - case oldDBR_STRING: - dbrType = DBR_STRING; - break; -/* case oldDBR_INT: */ - case oldDBR_SHORT: - dbrType = DBR_SHORT; - break; - case oldDBR_FLOAT: - dbrType = DBR_FLOAT; - break; - case oldDBR_ENUM: - dbrType = DBR_ENUM; - break; - case oldDBR_CHAR: - dbrType = DBR_UCHAR; - break; - case oldDBR_LONG: - dbrType = DBR_LONG; - break; - case oldDBR_DOUBLE: - dbrType = DBR_DOUBLE; - break; - case oldDBR_PUT_ACKT: - dbrType = DBR_PUT_ACKT; - break; - case oldDBR_PUT_ACKS: - dbrType = DBR_PUT_ACKS; - break; - default: - return -1; - } - return dbrType; -} - -int db_put_process(processNotify *ppn, notifyPutType type, - int src_type, const void *psrc, int no_elements) -{ - int status = 0; - int dbrType = mapOldType(src_type); - switch(type) { - case putDisabledType: - ppn->status = notifyError; - return 0; - case putFieldType: - status = dbChannelPutField(ppn->chan, dbrType, psrc, no_elements); - break; - case putType: - status = dbChannelPut(ppn->chan, dbrType, psrc, no_elements); - break; - } - if (status) - ppn->status = notifyError; - return 1; -} diff --git a/src/ioc/db/db_access_routines.h b/src/ioc/db/db_access_routines.h deleted file mode 100644 index f48ebb001..000000000 --- a/src/ioc/db/db_access_routines.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* This defined routines for old database access. These were broken out of - db_access.h so that ca can be build independent of db. - src/ca contains db_access, which contains that data definitions -*/ - -#ifndef INCLdb_access_routinesh -#define INCLdb_access_routinesh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -epicsShareExtern struct dbBase *pdbbase; -epicsShareExtern volatile int interruptAccept; - - -/* - * Adaptors for db_access users - */ -epicsShareFunc struct dbChannel * dbChannel_create(const char *pname); -epicsShareFunc int dbChannel_get(struct dbChannel *chan, - int buffer_type, void *pbuffer, long no_elements, void *pfl); -epicsShareFunc int dbChannel_put(struct dbChannel *chan, int src_type, - const void *psrc, long no_elements); -epicsShareFunc int dbChannel_get_count(struct dbChannel *chan, - int buffer_type, void *pbuffer, long *nRequest, void *pfl); - - -#ifdef __cplusplus -} -#endif - -#endif /* INCLdb_access_routinesh */ diff --git a/src/ioc/db/db_convert.h b/src/ioc/db/db_convert.h deleted file mode 100644 index d06164f02..000000000 --- a/src/ioc/db/db_convert.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* db_convert.h */ - -#ifndef INCLdb_converth -#define INCLdb_converth - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" -#include "dbAddr.h" - -epicsShareExtern struct dbBase *pdbbase; -epicsShareExtern volatile int interruptAccept; - -/*Definitions that allow old database access to use new conversion routines*/ -#define newDBF_DEVICE 13 -#define newDBR_ENUM 11 -epicsShareExtern long (*dbGetConvertRoutine[newDBF_DEVICE+1][newDBR_ENUM+1]) - (struct dbAddr *paddr, void *pbuffer,long nRequest, - long no_elements, long offset); -epicsShareExtern long (*dbPutConvertRoutine[newDBR_ENUM+1][newDBF_DEVICE+1]) - (struct dbAddr *paddr, const void *pbuffer,long nRequest, - long no_elements, long offset); -epicsShareExtern long (*dbFastGetConvertRoutine[newDBF_DEVICE+1][newDBR_ENUM+1]) - (const void *from, void *to, dbAddr *paddr); -epicsShareExtern long (*dbFastPutConvertRoutine[newDBR_ENUM+1][newDBF_DEVICE+1]) - (const void *from, void *to, dbAddr *paddr); - -/*Conversion between old and new DBR types*/ -epicsShareExtern unsigned short dbDBRoldToDBFnew[DBR_DOUBLE+1]; -epicsShareExtern unsigned short dbDBRnewToDBRold[newDBR_ENUM+1]; -#ifdef DB_CONVERT_GBLSOURCE -epicsShareDef unsigned short dbDBRoldToDBFnew[DBR_DOUBLE+1] = { - 0, /*DBR_STRING to DBF_STRING*/ - 3, /*DBR_INT to DBF_SHORT*/ - 9, /*DBR_FLOAT to DBF_FLOAT*/ - 11, /*DBR_ENUM to DBF_ENUM*/ - 1, /*DBR_CHAR to DBF_CHAR*/ - 5, /*DBR_LONG to DBF_LONG*/ - 10 /*DBR_DOUBLE to DBF_DOUBLE*/ -}; -epicsShareDef unsigned short dbDBRnewToDBRold[newDBR_ENUM+1] = { - 0, /*DBR_STRING to DBR_STRING*/ - 4, /*DBR_CHAR to DBR_CHAR*/ - 4, /*DBR_UCHAR to DBR_CHAR*/ - 1, /*DBR_SHORT to DBR_SHORT*/ - 5, /*DBR_USHORT to DBR_LONG*/ - 5, /*DBR_LONG to DBR_LONG*/ - 6, /*DBR_ULONG to DBR_DOUBLE*/ - 6, /*DBR_INT64 to DBR_DOUBLE*/ - 6, /*DBR_UINT64 to DBR_DOUBLE*/ - 2, /*DBR_FLOAT to DBR_FLOAT*/ - 6, /*DBR_DOUBLE to DBR_DOUBLE*/ - 3, /*DBR_ENUM to DBR_ENUM*/ -}; -#endif /*DB_CONVERT_GBLSOURCE*/ - - -#ifdef __cplusplus -} -#endif - -#endif /* INCLdb_converth */ diff --git a/src/ioc/db/db_field_log.h b/src/ioc/db/db_field_log.h deleted file mode 100644 index 1534517bb..000000000 --- a/src/ioc/db/db_field_log.h +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * - * Ralph Lange - */ - -#ifndef INCLdb_field_logh -#define INCLdb_field_logh - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Simple native types (anything which is not a string or an array for - * now) logged by db_post_events() for reliable interprocess communication. - * (for other types they get whatever happens to be there when the lower - * priority task pending on the event queue wakes up). Strings would slow down - * events for more reasonable size values. DB fields of native type string - * will most likely change infrequently. - * - * Strings can be added to the set of types for which updates will be queued - * by defining the macro DB_EVENT_LOG_STRINGS. The code in db_add_event() - * will adjust automatically, it just compares field sizes. - */ -union native_value { - epicsInt8 dbf_char; - epicsInt16 dbf_short; - epicsEnum16 dbf_enum; - epicsInt32 dbf_long; - epicsFloat32 dbf_float; - epicsFloat64 dbf_double; -#ifdef DB_EVENT_LOG_STRINGS - char dbf_string[MAX_STRING_SIZE]; -#endif -}; - -/* - * structure to log the state of a data base field at the time - * an event is triggered. - */ -struct db_field_log; -typedef void (dbfl_freeFunc)(struct db_field_log *pfl); - -/* Types of db_field_log: rec = use record, val = val inside, ref = reference inside */ -typedef enum dbfl_type { - dbfl_type_rec = 0, - dbfl_type_val, - dbfl_type_ref -} dbfl_type; - -/* Context of db_field_log: event = subscription update, read = read reply */ -typedef enum dbfl_context { - dbfl_context_read = 0, - dbfl_context_event -} dbfl_context; - -#define dbflTypeStr(t) (t==dbfl_type_val?"val":t==dbfl_type_rec?"rec":"ref") - -struct dbfl_val { - union native_value field; /* Field value */ -}; - -/* External data reference. - * If dtor is provided then it should be called when the referenced - * data is no longer needed. This is done automatically by - * db_delete_field_log(). Any code which changes a dbfl_type_ref - * field log to another type, or to reference different data, - * must explicitly call the dtor function. - */ -struct dbfl_ref { - dbfl_freeFunc *dtor; /* Callback to free filter-allocated resources */ - void *pvt; /* Private pointer */ - void *field; /* Field value */ -}; - -typedef struct db_field_log { - unsigned int type:2; /* type (union) selector */ - /* ctx is used for all types */ - unsigned int ctx:1; /* context (operation type) */ - /* the following are used for value and reference types */ - epicsTimeStamp time; /* Time stamp */ - unsigned short stat; /* Alarm Status */ - unsigned short sevr; /* Alarm Severity */ - short field_type; /* DBF type of data */ - short field_size; /* Data size */ - long no_elements; /* No of array elements */ - union { - struct dbfl_val v; - struct dbfl_ref r; - } u; -} db_field_log; - -/* - * A db_field_log will in one of three types: - * - * dbfl_type_rec - Reference to record - * The field log stores no data itself. Data must instead be taken - * via the dbChannel* which must always be provided when along - * with the field log. - * For this type only the 'type' and 'ctx' members are used. - * - * dbfl_type_ref - Reference to outside value - * Used for variable size (array) data types. Meta-data - * is stored in the field log, but value data is stored externally - * (see struct dbfl_ref). - * For this type all meta-data members are used. The dbfl_ref side of the - * data union is used. - * - * dbfl_type_val - Internal value - * Used to store small scalar data. Meta-data and value are - * present in this structure and no external references are used. - * For this type all meta-data members are used. The dbfl_val side of the - * data union is used. - */ - -#ifdef __cplusplus -} -#endif - -#endif /*INCLdb_field_logh*/ diff --git a/src/ioc/db/db_test.c b/src/ioc/db/db_test.c deleted file mode 100644 index 8d7ad31b1..000000000 --- a/src/ioc/db/db_test.c +++ /dev/null @@ -1,260 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* database access subroutines */ -/* - * Author: Bob Dalesio - * Andrew Johnson - */ -#include -#include -#include - -#include "cadef.h" -#include "dbDefs.h" -#include "epicsStdio.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "db_access_routines.h" -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbNotify.h" -#include "db_test.h" - -#define MAX_ELEMS 10 - -int gft(const char *pname) -{ - char tgf_buffer[MAX_ELEMS*MAX_STRING_SIZE + sizeof(struct dbr_ctrl_double)]; - struct dbChannel *chan; - struct dbCommon *precord; - long elements; - short type; - int i; - - chan = dbChannel_create(pname); - if (!chan) { - printf("Channel couldn't be created\n"); - return 1; - } - - precord = dbChannelRecord(chan); - elements = dbChannelElements(chan); - type = dbChannelExportCAType(chan); - - printf(" Record Name: %s\n", precord->name); - printf("Record Address: 0x%p\n", precord); - printf(" Export Type: %d\n", type); - printf(" Field Address: 0x%p\n", dbChannelField(chan)); - printf(" Field Size: %d\n", dbChannelFieldSize(chan)); - printf(" No Elements: %ld\n", elements); - - if (elements > MAX_ELEMS) - elements = MAX_ELEMS; - - for (i = 0; i <= LAST_BUFFER_TYPE; i++) { - if (type == 0) { - if ((i != DBR_STRING) && (i != DBR_STS_STRING) && - (i != DBR_TIME_STRING) && (i != DBR_GR_STRING) && - (i != DBR_CTRL_STRING)) - continue; - } - if (dbChannel_get(chan, i, tgf_buffer, elements, NULL) < 0) - printf("\t%s Failed\n", dbr_text[i]); - else - ca_dump_dbr(i, elements, tgf_buffer); - } - - dbChannelDelete(chan); - return 0; -} - -/* - * TPF - * Test put field - */ -int pft(const char *pname, const char *pvalue) -{ - struct dbChannel *chan; - struct dbCommon *precord; - long elements; - short type; - char buffer[500]; - short shortvalue; - long longvalue; - float floatvalue; - unsigned char charvalue; - double doublevalue; - - chan = dbChannel_create(pname); - if (!chan) { - printf("Channel couldn't be created\n"); - return 1; - } - - precord = dbChannelRecord(chan); - elements = dbChannelElements(chan); - type = dbChannelExportCAType(chan); - - printf(" Record Name: %s\n", precord->name); - printf("Record Address: 0x%p\n", precord); - printf(" Export Type: %d\n", type); - printf(" Field Address: 0x%p\n", dbChannelField(chan)); - printf(" Field Size: %d\n", dbChannelFieldSize(chan)); - printf(" No Elements: %ld\n", elements); - - if (dbChannel_put(chan, DBR_STRING,pvalue, 1) < 0) - printf("\n\t failed "); - if (dbChannel_get(chan, DBR_STRING,buffer, 1, NULL) < 0) - printf("\n\tfailed"); - else - ca_dump_dbr(DBR_STRING,1, buffer); - - if (type <= DBF_STRING || type == DBF_ENUM) - return 0; - - if (sscanf(pvalue, "%hd", &shortvalue) == 1) { - if (dbChannel_put(chan, DBR_SHORT,&shortvalue, 1) < 0) - printf("\n\t SHORT failed "); - if (dbChannel_get(chan, DBR_SHORT,buffer, 1, NULL) < 0) - printf("\n\t SHORT GET failed"); - else - ca_dump_dbr(DBR_SHORT,1, buffer); - } - if (sscanf(pvalue, "%ld", &longvalue) == 1) { - if (dbChannel_put(chan, DBR_LONG,&longvalue, 1) < 0) - printf("\n\t LONG failed "); - if (dbChannel_get(chan, DBR_LONG,buffer, 1, NULL) < 0) - printf("\n\t LONG GET failed"); - else - ca_dump_dbr(DBR_LONG,1, buffer); - } - if (epicsScanFloat(pvalue, &floatvalue) == 1) { - if (dbChannel_put(chan, DBR_FLOAT,&floatvalue, 1) < 0) - printf("\n\t FLOAT failed "); - if (dbChannel_get(chan, DBR_FLOAT,buffer, 1, NULL) < 0) - printf("\n\t FLOAT GET failed"); - else - ca_dump_dbr(DBR_FLOAT,1, buffer); - } - if (epicsScanFloat(pvalue, &floatvalue) == 1) { - doublevalue = floatvalue; - if (dbChannel_put(chan, DBR_DOUBLE,&doublevalue, 1) < 0) - printf("\n\t DOUBLE failed "); - if (dbChannel_get(chan, DBR_DOUBLE,buffer, 1, NULL) < 0) - printf("\n\t DOUBLE GET failed"); - else - ca_dump_dbr(DBR_DOUBLE,1, buffer); - } - if (sscanf(pvalue, "%hd", &shortvalue) == 1) { - charvalue = (unsigned char) shortvalue; - if (dbChannel_put(chan, DBR_CHAR,&charvalue, 1) < 0) - printf("\n\t CHAR failed "); - if (dbChannel_get(chan, DBR_CHAR,buffer, 1, NULL) < 0) - printf("\n\t CHAR GET failed"); - else - ca_dump_dbr(DBR_CHAR,1, buffer); - } - if (sscanf(pvalue, "%hd", &shortvalue) == 1) { - if (dbChannel_put(chan, DBR_ENUM,&shortvalue, 1) < 0) - printf("\n\t ENUM failed "); - if (dbChannel_get(chan, DBR_ENUM,buffer, 1, NULL) < 0) - printf("\n\t ENUM GET failed"); - else - ca_dump_dbr(DBR_ENUM,1, buffer); - } - printf("\n"); - dbChannelDelete(chan); - return (0); -} - - -typedef struct tpnInfo { - epicsEventId callbackDone; - processNotify *ppn; - char buffer[80]; -} tpnInfo; - - -static int putCallback(processNotify *ppn,notifyPutType type) { - tpnInfo *ptpnInfo = (tpnInfo *)ppn->usrPvt; - - return db_put_process(ppn, type, DBR_STRING, ptpnInfo->buffer, 1); -} - -static void doneCallback(processNotify *ppn) -{ - tpnInfo *ptpnInfo = (tpnInfo *) ppn->usrPvt; - notifyStatus status = ppn->status; - const char *pname = dbChannelRecord(ppn->chan)->name; - - if (status == 0) - printf("tpnCallback '%s': Success\n", pname); - else - printf("tpnCallback '%s': Notify status %d\n", pname, (int)status); - epicsEventSignal(ptpnInfo->callbackDone); -} - -static void tpnThread(void *pvt) -{ - tpnInfo *ptpnInfo = (tpnInfo *) pvt; - processNotify *ppn = (processNotify *) ptpnInfo->ppn; - - dbProcessNotify(ppn); - epicsEventWait(ptpnInfo->callbackDone); - dbNotifyCancel(ppn); - epicsEventDestroy(ptpnInfo->callbackDone); - dbChannelDelete(ppn->chan); - free(ppn); - free(ptpnInfo); -} - -int tpn(const char *pname, const char *pvalue) -{ - struct dbChannel *chan; - tpnInfo *ptpnInfo; - processNotify *ppn = NULL; - - chan = dbChannel_create(pname); - if (!chan) { - printf("Channel couldn't be created\n"); - return 1; - } - - ppn = calloc(1, sizeof(processNotify)); - if (!ppn) { - printf("calloc failed\n"); - dbChannelDelete(chan); - return -1; - } - ppn->requestType = putProcessRequest; - ppn->chan = chan; - ppn->putCallback = putCallback; - ppn->doneCallback = doneCallback; - - ptpnInfo = calloc(1, sizeof(tpnInfo)); - if (!ptpnInfo) { - printf("calloc failed\n"); - free(ppn); - dbChannelDelete(chan); - return -1; - } - ptpnInfo->ppn = ppn; - ptpnInfo->callbackDone = epicsEventCreate(epicsEventEmpty); - strncpy(ptpnInfo->buffer, pvalue, 80); - ptpnInfo->buffer[79] = 0; - - ppn->usrPvt = ptpnInfo; - epicsThreadCreate("tpn", epicsThreadPriorityHigh, - epicsThreadGetStackSize(epicsThreadStackMedium), tpnThread, ptpnInfo); - return 0; -} - diff --git a/src/ioc/db/db_test.h b/src/ioc/db/db_test.h deleted file mode 100644 index 88eb14c21..000000000 --- a/src/ioc/db/db_test.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INCLdb_testh -#define INCLdb_testh - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int gft(const char *pname); -epicsShareFunc int pft(const char *pname, const char *pvalue); -epicsShareFunc int tpn(const char *pname, const char *pvalue); -#ifdef __cplusplus -} -#endif - -#endif /* INCLdb_testh */ diff --git a/src/ioc/db/initHooks.c b/src/ioc/db/initHooks.c deleted file mode 100644 index 9070c53f5..000000000 --- a/src/ioc/db/initHooks.c +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Authors: Benjamin Franksen (BESY) and Marty Kraimer - * Date: 06-01-91 - * major Revision: 07JuL97 - */ - -#include -#include -#include - -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsMutex.h" -#include "epicsThread.h" - -#define epicsExportSharedSymbols -#include "initHooks.h" - -typedef struct initHookLink { - ELLNODE node; - initHookFunction func; -} initHookLink; - -static ELLLIST functionList = ELLLIST_INIT; -static epicsMutexId listLock; - -/* - * Lazy initialization functions - */ -static void initHookOnce(void *arg) -{ - listLock = epicsMutexMustCreate(); -} - -static void initHookInit(void) -{ - static epicsThreadOnceId onceFlag = EPICS_THREAD_ONCE_INIT; - epicsThreadOnce(&onceFlag, initHookOnce, NULL); -} - -/* - * To be called before iocInit reaches state desired. - */ -int initHookRegister(initHookFunction func) -{ - initHookLink *newHook; - - if (!func) return 0; - - initHookInit(); - - newHook = (initHookLink *)malloc(sizeof(initHookLink)); - if (!newHook) { - printf("Cannot malloc a new initHookLink\n"); - return -1; - } - newHook->func = func; - - epicsMutexMustLock(listLock); - ellAdd(&functionList, &newHook->node); - epicsMutexUnlock(listLock); - return 0; -} - -/* - * Called by iocInit at various points during initialization. - * This function must only be called by iocInit and relatives. - */ -void initHookAnnounce(initHookState state) -{ - initHookLink *hook; - - initHookInit(); - - epicsMutexMustLock(listLock); - hook = (initHookLink *)ellFirst(&functionList); - epicsMutexUnlock(listLock); - - while (hook != NULL) { - hook->func(state); - - epicsMutexMustLock(listLock); - hook = (initHookLink *)ellNext(&hook->node); - epicsMutexUnlock(listLock); - } -} - -void initHookFree(void) -{ - initHookInit(); - epicsMutexMustLock(listLock); - ellFree(&functionList); - epicsMutexUnlock(listLock); -} - -/* - * Call any time you want to print out a state name. - */ -const char *initHookName(int state) -{ - const char *stateName[] = { - "initHookAtIocBuild", - "initHookAtBeginning", - "initHookAfterCallbackInit", - "initHookAfterCaLinkInit", - "initHookAfterInitDrvSup", - "initHookAfterInitRecSup", - "initHookAfterInitDevSup", - "initHookAfterInitDatabase", - "initHookAfterFinishDevSup", - "initHookAfterScanInit", - "initHookAfterInitialProcess", - "initHookAfterCaServerInit", - "initHookAfterIocBuilt", - "initHookAtIocRun", - "initHookAfterDatabaseRunning", - "initHookAfterCaServerRunning", - "initHookAfterIocRunning", - "initHookAtIocPause", - "initHookAfterCaServerPaused", - "initHookAfterDatabasePaused", - "initHookAfterIocPaused", - "initHookAfterInterruptAccept", - "initHookAtEnd" - }; - if (state < 0 || state >= NELEMENTS(stateName)) { - return "Not an initHookState"; - } - return stateName[state]; -} diff --git a/src/ioc/db/initHooks.h b/src/ioc/db/initHooks.h deleted file mode 100644 index 429a768db..000000000 --- a/src/ioc/db/initHooks.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Authors: Benjamin Franksen (BESY) and Marty Kraimer - * Date: 06-01-91 - * major Revision: 07JuL97 - */ - -#ifndef INC_initHooks_H -#define INC_initHooks_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* This enum must agree with the array of names defined in initHookName() */ -typedef enum { - initHookAtIocBuild = 0, /* Start of iocBuild/iocInit commands */ - initHookAtBeginning, - initHookAfterCallbackInit, - initHookAfterCaLinkInit, - initHookAfterInitDrvSup, - initHookAfterInitRecSup, - initHookAfterInitDevSup, - initHookAfterInitDatabase, - initHookAfterFinishDevSup, - initHookAfterScanInit, - initHookAfterInitialProcess, - initHookAfterCaServerInit, - initHookAfterIocBuilt, /* End of iocBuild command */ - - initHookAtIocRun, /* Start of iocRun command */ - initHookAfterDatabaseRunning, - initHookAfterCaServerRunning, - initHookAfterIocRunning, /* End of iocRun/iocInit commands */ - - initHookAtIocPause, /* Start of iocPause command */ - initHookAfterCaServerPaused, - initHookAfterDatabasePaused, - initHookAfterIocPaused, /* End of iocPause command */ - -/* Deprecated states, provided for backwards compatibility. - * These states are announced at the same point they were before, - * but will not be repeated if the IOC gets paused and restarted. - */ - initHookAfterInterruptAccept, /* After initHookAfterDatabaseRunning */ - initHookAtEnd, /* Before initHookAfterIocRunning */ -} initHookState; - -typedef void (*initHookFunction)(initHookState state); -epicsShareFunc int initHookRegister(initHookFunction func); -epicsShareFunc void initHookAnnounce(initHookState state); -epicsShareFunc const char *initHookName(int state); -epicsShareFunc void initHookFree(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_initHooks_H */ diff --git a/src/ioc/db/menuAlarmSevr.dbd.pod b/src/ioc/db/menuAlarmSevr.dbd.pod deleted file mode 100644 index 1d86edba6..000000000 --- a/src/ioc/db/menuAlarmSevr.dbd.pod +++ /dev/null @@ -1,25 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=head1 Menu menuAlarmSevr - -This menu defines the four possible alarm severities that EPICS records can -exhibit. Note that it is not possible to add or remove severities just by -changing the choices defined here. - -=menu menuAlarmSevr - -=cut - -menu(menuAlarmSevr) { - choice(menuAlarmSevrNO_ALARM,"NO_ALARM") - choice(menuAlarmSevrMINOR,"MINOR") - choice(menuAlarmSevrMAJOR,"MAJOR") - choice(menuAlarmSevrINVALID,"INVALID") -} diff --git a/src/ioc/db/menuAlarmStat.dbd b/src/ioc/db/menuAlarmStat.dbd deleted file mode 100644 index e8d7f1ced..000000000 --- a/src/ioc/db/menuAlarmStat.dbd +++ /dev/null @@ -1,33 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(menuAlarmStat) { - choice(menuAlarmStatNO_ALARM,"NO_ALARM") - choice(menuAlarmStatREAD,"READ") - choice(menuAlarmStatWRITE,"WRITE") - choice(menuAlarmStatHIHI,"HIHI") - choice(menuAlarmStatHIGH,"HIGH") - choice(menuAlarmStatLOLO,"LOLO") - choice(menuAlarmStatLOW,"LOW") - choice(menuAlarmStatSTATE,"STATE") - choice(menuAlarmStatCOS,"COS") - choice(menuAlarmStatCOMM,"COMM") - choice(menuAlarmStatTIMEOUT,"TIMEOUT") - choice(menuAlarmStatHWLIMIT,"HWLIMIT") - choice(menuAlarmStatCALC,"CALC") - choice(menuAlarmStatSCAN,"SCAN") - choice(menuAlarmStatLINK,"LINK") - choice(menuAlarmStatSOFT,"SOFT") - choice(menuAlarmStatBAD_SUB,"BAD_SUB") - choice(menuAlarmStatUDF,"UDF") - choice(menuAlarmStatDISABLE,"DISABLE") - choice(menuAlarmStatSIMM,"SIMM") - choice(menuAlarmStatREAD_ACCESS,"READ_ACCESS") - choice(menuAlarmStatWRITE_ACCESS,"WRITE_ACCESS") -} diff --git a/src/ioc/db/menuFtype.dbd b/src/ioc/db/menuFtype.dbd deleted file mode 100644 index af6a8803d..000000000 --- a/src/ioc/db/menuFtype.dbd +++ /dev/null @@ -1,22 +0,0 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(menuFtype) { - choice(menuFtypeSTRING,"STRING") - choice(menuFtypeCHAR,"CHAR") - choice(menuFtypeUCHAR,"UCHAR") - choice(menuFtypeSHORT,"SHORT") - choice(menuFtypeUSHORT,"USHORT") - choice(menuFtypeLONG,"LONG") - choice(menuFtypeULONG,"ULONG") - choice(menuFtypeINT64,"INT64") - choice(menuFtypeUINT64,"UINT64") - choice(menuFtypeFLOAT,"FLOAT") - choice(menuFtypeDOUBLE,"DOUBLE") - choice(menuFtypeENUM,"ENUM") -} diff --git a/src/ioc/db/menuIvoa.dbd b/src/ioc/db/menuIvoa.dbd deleted file mode 100644 index b1b3ce51f..000000000 --- a/src/ioc/db/menuIvoa.dbd +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(menuIvoa) { - choice(menuIvoaContinue_normally,"Continue normally") - choice(menuIvoaDon_t_drive_outputs,"Don't drive outputs") - choice(menuIvoaSet_output_to_IVOV,"Set output to IVOV") -} diff --git a/src/ioc/db/menuOmsl.dbd b/src/ioc/db/menuOmsl.dbd deleted file mode 100644 index 3022437dc..000000000 --- a/src/ioc/db/menuOmsl.dbd +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(menuOmsl) { - choice(menuOmslsupervisory,"supervisory") - choice(menuOmslclosed_loop,"closed_loop") -} diff --git a/src/ioc/db/menuPini.dbd b/src/ioc/db/menuPini.dbd deleted file mode 100644 index 96aca7298..000000000 --- a/src/ioc/db/menuPini.dbd +++ /dev/null @@ -1,16 +0,0 @@ -#************************************************************************* -# Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(menuPini) { - choice(menuPiniNO,"NO") - choice(menuPiniYES,"YES") - choice(menuPiniRUN,"RUN") - choice(menuPiniRUNNING,"RUNNING") - choice(menuPiniPAUSE,"PAUSE") - choice(menuPiniPAUSED,"PAUSED") -} diff --git a/src/ioc/db/menuPost.dbd b/src/ioc/db/menuPost.dbd deleted file mode 100644 index a86b25b5e..000000000 --- a/src/ioc/db/menuPost.dbd +++ /dev/null @@ -1,11 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -menu(menuPost) { - choice(menuPost_OnChange, "On Change") - choice(menuPost_Always, "Always") -} diff --git a/src/ioc/db/menuPriority.dbd b/src/ioc/db/menuPriority.dbd deleted file mode 100644 index 155caa5e7..000000000 --- a/src/ioc/db/menuPriority.dbd +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(menuPriority) { - choice(menuPriorityLOW,"LOW") - choice(menuPriorityMEDIUM,"MEDIUM") - choice(menuPriorityHIGH,"HIGH") -} diff --git a/src/ioc/db/menuScan.dbd b/src/ioc/db/menuScan.dbd deleted file mode 100644 index 17fedd59b..000000000 --- a/src/ioc/db/menuScan.dbd +++ /dev/null @@ -1,21 +0,0 @@ -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(menuScan) { - choice(menuScanPassive,"Passive") - choice(menuScanEvent,"Event") - choice(menuScanI_O_Intr,"I/O Intr") - # Periodic scans follow, ordered from slowest to fastest - choice(menuScan10_second,"10 second") - choice(menuScan5_second,"5 second") - choice(menuScan2_second,"2 second") - choice(menuScan1_second,"1 second") - choice(menuScan_5_second,".5 second") - choice(menuScan_2_second,".2 second") - choice(menuScan_1_second,".1 second") -} diff --git a/src/ioc/db/menuSimm.dbd.pod b/src/ioc/db/menuSimm.dbd.pod deleted file mode 100644 index 5df087ccc..000000000 --- a/src/ioc/db/menuSimm.dbd.pod +++ /dev/null @@ -1,23 +0,0 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=head1 Menu menuSimm - -This menu is used for Simulation Mode (SIMM) fields of input record types that -can fetch either raw or engineering values through their SIOL link. - -=menu menuSimm - -=cut - -menu(menuSimm) { - choice(menuSimmNO,"NO") - choice(menuSimmYES,"YES") - choice(menuSimmRAW,"RAW") -} diff --git a/src/ioc/db/menuYesNo.dbd b/src/ioc/db/menuYesNo.dbd deleted file mode 100644 index 2d09dd65a..000000000 --- a/src/ioc/db/menuYesNo.dbd +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(menuYesNo) { - choice(menuYesNoNO,"NO") - choice(menuYesNoYES,"YES") -} diff --git a/src/ioc/db/recGbl.c b/src/ioc/db/recGbl.c deleted file mode 100644 index a614b5268..000000000 --- a/src/ioc/db/recGbl.c +++ /dev/null @@ -1,371 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* recGbl.c */ -/* - * Author: Marty Kraimer - * Andrew Johnson - */ - -#include -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "epicsMath.h" -#include "epicsPrint.h" -#include "epicsStdlib.h" -#include "epicsTime.h" -#include "errlog.h" - -#include "caeventmask.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbCommon.h" -#include "dbEvent.h" -#include "db_field_log.h" -#include "dbFldTypes.h" -#include "dbLink.h" -#include "dbNotify.h" -#include "dbScan.h" -#include "devSup.h" -#include "link.h" -#include "recGbl.h" - - -/* Hook Routines */ - -epicsShareDef RECGBL_ALARM_HOOK_ROUTINE recGblAlarmHook = NULL; - -/* local routines */ -static void getMaxRangeValues(short field_type, double *pupper_limit, - double *plower_limit); - - - -void recGblDbaddrError(long status, const struct dbAddr *paddr, - const char *pmessage) -{ - dbCommon *precord = 0; - dbFldDes *pdbFldDes = 0; - - if(paddr) { - pdbFldDes = paddr->pfldDes; - precord = paddr->precord; - } - errPrintf(status,0,0, - "PV: %s.%s " - "error detected in routine: %s\n", - (paddr ? precord->name : "Unknown"), - (pdbFldDes ? pdbFldDes->name : ""), - (pmessage ? pmessage : "Unknown")); - return; -} - -void recGblRecordError(long status, void *pdbc, - const char *pmessage) -{ - dbCommon *precord = pdbc; - - errPrintf(status,0,0, - "PV: %s %s\n", - (precord ? precord->name : "Unknown"), - (pmessage ? pmessage : "")); - return; -} - -void recGblRecSupError(long status, const struct dbAddr *paddr, - const char *pmessage, const char *psupport_name) -{ - dbCommon *precord = 0; - dbFldDes *pdbFldDes = 0; - dbRecordType *pdbRecordType = 0; - - if(paddr) { - precord = paddr->precord; - pdbFldDes = paddr->pfldDes; - if(pdbFldDes) pdbRecordType = pdbFldDes->pdbRecordType; - } - errPrintf(status,0,0, - "Record Support Routine (%s) " - "Record Type %s " - "PV %s.%s " - " %s\n", - (psupport_name ? psupport_name : "Unknown"), - (pdbRecordType ? pdbRecordType->name : "Unknown"), - (paddr ? precord->name : "Unknown"), - (pdbFldDes ? pdbFldDes->name : ""), - (pmessage ? pmessage : "")); - return; -} - -void recGblGetPrec(const struct dbAddr *paddr, long *precision) -{ - dbFldDes *pdbFldDes = paddr->pfldDes; - - switch (pdbFldDes->field_type) { - case DBF_CHAR: - case DBF_UCHAR: - case DBF_SHORT: - case DBF_USHORT: - case DBF_LONG: - case DBF_ULONG: - case DBF_INT64: - case DBF_UINT64: - *precision = 0; - break; - - case DBF_FLOAT: - case DBF_DOUBLE: - if (*precision < 0 || *precision > 15) - *precision = 15; - break; - - default: - break; - } -} - -void recGblGetGraphicDouble(const struct dbAddr *paddr, - struct dbr_grDouble *pgd) -{ - dbFldDes *pdbFldDes = paddr->pfldDes; - - getMaxRangeValues(pdbFldDes->field_type, - &pgd->upper_disp_limit, &pgd->lower_disp_limit); -} - -void recGblGetAlarmDouble(const struct dbAddr *paddr, - struct dbr_alDouble *pad) -{ - pad->upper_alarm_limit = epicsNAN; - pad->upper_warning_limit = epicsNAN; - pad->lower_warning_limit = epicsNAN; - pad->lower_alarm_limit = epicsNAN; -} - -void recGblGetControlDouble(const struct dbAddr *paddr, - struct dbr_ctrlDouble *pcd) -{ - dbFldDes *pdbFldDes = paddr->pfldDes; - - getMaxRangeValues(pdbFldDes->field_type, - &pcd->upper_ctrl_limit, &pcd->lower_ctrl_limit); -} - -int recGblInitConstantLink(struct link *plink, short dbftype, void *pdest) -{ - return !dbLoadLink(plink, dbftype, pdest); -} - -unsigned short recGblResetAlarms(void *precord) -{ - dbCommon *pdbc = precord; - epicsEnum16 prev_stat = pdbc->stat; - epicsEnum16 prev_sevr = pdbc->sevr; - epicsEnum16 new_stat = pdbc->nsta; - epicsEnum16 new_sevr = pdbc->nsev; - epicsEnum16 val_mask = 0; - epicsEnum16 stat_mask = 0; - - pdbc->stat = new_stat; - pdbc->sevr = new_sevr; - pdbc->nsta = 0; - pdbc->nsev = 0; - - if (prev_sevr != new_sevr) { - stat_mask = DBE_ALARM; - db_post_events(pdbc, &pdbc->sevr, DBE_VALUE); - } - if (prev_stat != new_stat) { - stat_mask |= DBE_VALUE; - } - if (stat_mask) { - db_post_events(pdbc, &pdbc->stat, stat_mask); - val_mask = DBE_ALARM; - - if (!pdbc->ackt || new_sevr >= pdbc->acks) { - pdbc->acks = new_sevr; - db_post_events(pdbc, &pdbc->acks, DBE_VALUE); - } - - if (recGblAlarmHook) { - (*recGblAlarmHook)(pdbc, prev_sevr, prev_stat); - } - } - return val_mask; -} - -int recGblSetSevr(void *precord, epicsEnum16 new_stat, epicsEnum16 new_sevr) -{ - struct dbCommon *prec = precord; - if (prec->nsev < new_sevr) { - prec->nsta = new_stat; - prec->nsev = new_sevr; - return TRUE; - } - return FALSE; -} - -void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat, - epicsEnum16 sevr) -{ - switch (msMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (sevr < INVALID_ALARM) - break; - /* Fall through */ - case pvlOptMS: - recGblSetSevr(precord, LINK_ALARM, sevr); - break; - case pvlOptMSS: - recGblSetSevr(precord, stat, sevr); - break; - } -} - - -void recGblFwdLink(void *precord) -{ - dbCommon *pdbc = precord; - - dbScanFwdLink(&pdbc->flnk); - /*Handle dbPutFieldNotify record completions*/ - if(pdbc->ppn) dbNotifyCompletion(pdbc); - if(pdbc->rpro) { - /*If anyone requested reprocessing do it*/ - pdbc->rpro = FALSE; - scanOnce(pdbc); - } - /*In case putField caused put we are all done */ - pdbc->putf = FALSE; -} - -void recGblGetTimeStamp(void *pvoid) -{ - dbCommon* prec = (dbCommon*)pvoid; - struct link *plink = &prec->tsel; - - if (!dbLinkIsConstant(plink)) { - struct pv_link *ppv_link = &plink->value.pv_link; - - if (ppv_link->pvlMask & pvlOptTSELisTime) { - if (dbGetTimeStamp(plink, &prec->time)) - errlogPrintf("recGblGetTimeStamp: dbGetTimeStamp failed, %s.TSEL = %s\n", - prec->name, ppv_link->pvname); - return; - } - dbGetLink(&prec->tsel, DBR_SHORT, &prec->tse, 0, 0); - } - if (prec->tse != epicsTimeEventDeviceTime) { - if (epicsTimeGetEvent(&prec->time, prec->tse)) - errlogPrintf("recGblGetTimeStamp: epicsTimeGetEvent failed, %s.TSE = %d\n", - prec->name, prec->tse); - } -} - -void recGblTSELwasModified(struct link *plink) -{ - struct pv_link *ppv_link = &plink->value.pv_link; - char *pfieldname; - - if (plink->type != PV_LINK) { - errlogPrintf("recGblTSELwasModified called for non PV_LINK\n"); - return; - } - /*If pvname ends in .TIME then just ask for VAL*/ - /*Note that the VAL value will not be used*/ - pfieldname = strstr(ppv_link->pvname, ".TIME"); - if (pfieldname) { - *pfieldname = 0; - ppv_link->pvlMask |= pvlOptTSELisTime; - } -} - -void recGblCheckDeadband(epicsFloat64 *poldval, const epicsFloat64 newval, - const epicsFloat64 deadband, unsigned *monitor_mask, const unsigned add_mask) -{ - double delta = 0; - - if (finite(newval) && finite(*poldval)) { - /* both are finite -> compare delta with deadband */ - delta = *poldval - newval; - if (delta < 0.0) delta = -delta; - } - else if (!isnan(newval) != !isnan(*poldval) || - !isinf(newval) != !isinf(*poldval)) { - /* one is NaN or +-inf, the other not -> send update */ - delta = epicsINF; - } - else if (isinf(newval) && newval != *poldval) { - /* one is +inf, the other -inf -> send update */ - delta = epicsINF; - } - if (delta > deadband) { - /* add bits to monitor mask */ - *monitor_mask |= add_mask; - /* update last value monitored */ - *poldval = newval; - } -} - -static void getMaxRangeValues(short field_type, double *pupper_limit, - double *plower_limit) -{ - switch(field_type){ - case DBF_CHAR: - *pupper_limit = (double) CHAR_MAX; - *plower_limit = (double) CHAR_MIN; - break; - case DBF_UCHAR: - *pupper_limit = (double) UCHAR_MAX; - *plower_limit = 0.0; - break; - case DBF_SHORT: - *pupper_limit = (double) SHRT_MAX; - *plower_limit = (double) SHRT_MIN; - break; - case DBF_ENUM: - case DBF_USHORT: - *pupper_limit = (double) USHRT_MAX; - *plower_limit = 0.0; - break; - case DBF_LONG: - *pupper_limit = 2147483647.0; - *plower_limit = -2147483648.0; - break; - case DBF_ULONG: - *pupper_limit = 4294967295.0; - *plower_limit = 0.0; - break; - case DBF_INT64: - *pupper_limit = 9223372036854775808.0; - *plower_limit = -9223372036854775808.0; - break; - case DBF_UINT64: - *pupper_limit = 18446744073709551615.0; - *plower_limit = 0.0; - break; - case DBF_FLOAT: - *pupper_limit = 1e30; - *plower_limit = -1e30; - break; - case DBF_DOUBLE: - *pupper_limit = 1e300; - *plower_limit = -1e300; - break; - } - return; -} diff --git a/src/ioc/db/recGbl.h b/src/ioc/db/recGbl.h deleted file mode 100644 index 8eb589450..000000000 --- a/src/ioc/db/recGbl.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* recGbl.h */ -/* Record Global - * Author: Marty Kraimer - * Date: 13Jun95 - */ -#ifndef INCrecGblh -#define INCrecGblh 1 - -#include "epicsTypes.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*************************************************************************/ - -/* Structures needed for args */ - -struct link; -struct dbAddr; -struct dbr_alDouble; -struct dbr_ctrlDouble; -struct dbr_grDouble; -struct dbCommon; - -/* Hook Routine */ - -typedef void (*RECGBL_ALARM_HOOK_ROUTINE)(struct dbCommon *prec, - epicsEnum16 prev_sevr, epicsEnum16 prev_stat); -epicsShareExtern RECGBL_ALARM_HOOK_ROUTINE recGblAlarmHook; - -/* Global Record Support Routines */ - -epicsShareFunc void recGblDbaddrError(long status, const struct dbAddr *paddr, - const char *pcaller_name); -epicsShareFunc void recGblRecordError(long status, void *precord, - const char *pcaller_name); -epicsShareFunc void recGblRecSupError(long status, const struct dbAddr *paddr, - const char *pcaller_name, const char *psupport_name); -epicsShareFunc void recGblGetGraphicDouble(const struct dbAddr *paddr, - struct dbr_grDouble *pgd); -epicsShareFunc void recGblGetControlDouble( - const struct dbAddr *paddr, struct dbr_ctrlDouble *pcd); -epicsShareFunc void recGblGetAlarmDouble(const struct dbAddr *paddr, - struct dbr_alDouble *pad); -epicsShareFunc void recGblGetPrec(const struct dbAddr *paddr, - long *pprecision); -epicsShareFunc int recGblInitConstantLink(struct link *plink, - short dbftype, void *pdest); -epicsShareFunc unsigned short recGblResetAlarms(void *precord); -epicsShareFunc int recGblSetSevr(void *precord, epicsEnum16 new_stat, - epicsEnum16 new_sevr); -epicsShareFunc void recGblInheritSevr(int msMode, void *precord, epicsEnum16 stat, - epicsEnum16 sevr); -epicsShareFunc void recGblFwdLink(void *precord); -epicsShareFunc void recGblGetTimeStamp(void *precord); -epicsShareFunc void recGblTSELwasModified(struct link *plink); -epicsShareFunc void recGblCheckDeadband(epicsFloat64 *poldval, const epicsFloat64 newval, - const epicsFloat64 deadband, unsigned *monitor_mask, const unsigned add_mask); - -#ifdef __cplusplus -} -#endif - -#endif /*INCrecGblh*/ diff --git a/src/ioc/db/test/Makefile b/src/ioc/db/test/Makefile deleted file mode 100644 index 37ec3da74..000000000 --- a/src/ioc/db/test/Makefile +++ /dev/null @@ -1,195 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -# Allow access to private headers in db/ -USR_CPPFLAGS = -I ../.. - -TESTLIBRARY = dbTestIoc - -dbTestIoc_SRCS += arrRecord.c -dbTestIoc_SRCS += xRecord.c -dbTestIoc_SRCS += dbLinkdset.c -dbTestIoc_SRCS += xLink.c -dbTestIoc_SRCS += devx.c -dbTestIoc_SRCS += jlinkz.c -dbTestIoc_LIBS = dbCore ca Com - -TARGETS += $(COMMON_DIR)/dbTestIoc.dbd -DBDDEPENDS_FILES += dbTestIoc.dbd$(DEP) -dbTestIoc_DBD += menuGlobal.dbd -dbTestIoc_DBD += menuConvert.dbd -dbTestIoc_DBD += menuScan.dbd -dbTestIoc_DBD += xRecord.dbd -dbTestIoc_DBD += arrRecord.dbd -dbTestIoc_DBD += xLink.dbd -dbTestIoc_DBD += devx.dbd -dbTestIoc_DBD += jlinkz.dbd -dbTestIoc_DBD += dbLinkdset.dbd -TESTFILES += $(COMMON_DIR)/dbTestIoc.dbd ../xRecord.db - -testHarness_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp - -PROD_LIBS = dbTestIoc dbCore ca Com - -TESTPROD_HOST += dbScanTest -dbScanTest_SRCS += dbScanTest.c -dbScanTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbScanTest.c -TESTS += dbScanTest - -TESTPROD_HOST += dbShutdownTest -dbShutdownTest_SRCS += dbShutdownTest.c -dbShutdownTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbShutdownTest.c -TESTS += dbShutdownTest - -TESTPROD_HOST += dbPutLinkTest -dbPutLinkTest_SRCS += dbPutLinkTest.c -dbPutLinkTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbPutLinkTest.c -TESTS += dbPutLinkTest -TESTFILES += ../dbPutLinkTest.db ../dbPutLinkTestJ.db ../dbBadLink.db - -TESTPROD_HOST += dbLockTest -dbLockTest_SRCS += dbLockTest.c -dbLockTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbLockTest.c -TESTS += dbLockTest -TESTFILES += ../dbLockTest.db - -TESTPROD_HOST += dbStressTest -dbStressTest_SRCS += dbStressLock.c -dbStressTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -dbStressTest_SYS_LIBS_solaris += rt -dbStressTest_SYS_LIBS_Linux += rt -TESTS += dbStressTest -TESTFILES += ../dbStressLock.db - -TESTPROD_HOST += testdbConvert -testdbConvert_SRCS += testdbConvert.c -testHarness_SRCS += testdbConvert.c -TESTS += testdbConvert - -TESTPROD_HOST += callbackTest -callbackTest_SRCS += callbackTest.c -testHarness_SRCS += callbackTest.c -TESTS += callbackTest - -TESTPROD_HOST += callbackParallelTest -callbackParallelTest_SRCS += callbackParallelTest.c -testHarness_SRCS += callbackParallelTest.c -TESTS += callbackParallelTest - -TESTPROD_HOST += dbStateTest -dbStateTest_SRCS += dbStateTest.c -testHarness_SRCS += dbStateTest.c -TESTS += dbStateTest - -TESTPROD_HOST += dbCaStatsTest -dbCaStatsTest_SRCS += dbCaStatsTest.c -dbCaStatsTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbCaStatsTest.c -TESTS += dbCaStatsTest -TESTFILES += ../dbCaStats.db - -TESTPROD_HOST += dbCaLinkTest -dbCaLinkTest_SRCS += dbCaLinkTest.c -dbCaLinkTest_SRCS += dbCACTest.cpp -dbCaLinkTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbCaLinkTest.c -testHarness_SRCS += dbCACTest.cpp -TESTS += dbCaLinkTest -TESTFILES += ../dbCaLinkTest1.db ../dbCaLinkTest2.db ../dbCaLinkTest3.db - -TESTPROD_HOST += scanIoTest -scanIoTest_SRCS += scanIoTest.c -scanIoTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += scanIoTest.c -TESTFILES += ../scanIoTest.db -TESTS += scanIoTest - -TESTPROD_HOST += dbChannelTest -dbChannelTest_SRCS += dbChannelTest.c -dbChannelTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbChannelTest.c -TESTS += dbChannelTest - -TARGETS += $(COMMON_DIR)/dbChArrTest.dbd -DBDDEPENDS_FILES += dbChArrTest.dbd$(DEP) -dbChArrTest_DBD += arrRecord.dbd -TESTPROD_HOST += dbChArrTest -dbChArrTest_SRCS += dbChArrTest.cpp -dbChArrTest_SRCS += dbChArrTest_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbChArrTest.cpp -testHarness_SRCS += dbChArrTest_registerRecordDeviceDriver.cpp -TESTFILES += $(COMMON_DIR)/dbChArrTest.dbd ../dbChArrTest.db -TESTS += dbChArrTest - -TESTPROD_HOST += chfPluginTest -chfPluginTest_SRCS += chfPluginTest.c -chfPluginTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += chfPluginTest.c -TESTS += chfPluginTest - -TESTPROD_HOST += arrShorthandTest -arrShorthandTest_SRCS += arrShorthandTest.c -arrShorthandTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += arrShorthandTest.c -TESTS += arrShorthandTest - -TESTPROD_HOST += benchdbConvert -benchdbConvert_SRCS += benchdbConvert.c - -TESTPROD_HOST += recGblCheckDeadbandTest -recGblCheckDeadbandTest_SRCS += recGblCheckDeadbandTest.c -recGblCheckDeadbandTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += recGblCheckDeadbandTest.c -TESTS += recGblCheckDeadbandTest - -TESTPROD_HOST += testPutGetTest -testPutGetTest_SRCS += dbPutGetTest.c -testPutGetTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbPutGetTest.c -TESTFILES += ../dbPutGetTest.db -TESTS += testPutGetTest - -TESTPROD_HOST += dbStaticTest -dbStaticTest_SRCS += dbStaticTest.c -dbStaticTest_SRCS += dbTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbStaticTest.c -TESTFILES += ../dbStaticTest.db -TESTS += dbStaticTest - -# This runs all the test programs in a known working order: -testHarness_SRCS += epicsRunDbTests.c - -dbTestHarness_SRCS += $(testHarness_SRCS) -dbTestHarness_SRCS_RTEMS += rtemsTestHarness.c - -PROD_vxWorks = dbTestHarness -PROD_RTEMS = dbTestHarness - -TESTSPEC_vxWorks = dbTestHarness.munch; epicsRunDbTests -TESTSPEC_RTEMS = dbTestHarness.boot; epicsRunDbTests - -TESTSCRIPTS_HOST += $(TESTS:%=%.t) - -include $(TOP)/configure/RULES - -arrRecord$(DEP): $(COMMON_DIR)/arrRecord.h -dbCaLinkTest$(DEP): $(COMMON_DIR)/xRecord.h $(COMMON_DIR)/arrRecord.h -dbPutLinkTest$(DEP): $(COMMON_DIR)/xRecord.h -dbStressLock$(DEP): $(COMMON_DIR)/xRecord.h -devx$(DEP): $(COMMON_DIR)/xRecord.h -scanIoTest$(DEP): $(COMMON_DIR)/xRecord.h -xRecord$(DEP): $(COMMON_DIR)/xRecord.h - diff --git a/src/ioc/db/test/arrRecord.c b/src/ioc/db/test/arrRecord.c deleted file mode 100644 index 16b1b32e2..000000000 --- a/src/ioc/db/test/arrRecord.c +++ /dev/null @@ -1,144 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* arrRecord.c - minimal array record for test purposes: no processing */ - -/* - * Author: Ralph Lange - * - * vaguely implemented like parts of recWaveform.c by Bob Dalesio - * - */ - -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "recSup.h" -#include "recGbl.h" -#include "cantProceed.h" -#define GEN_SIZE_OFFSET -#include "arrRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -static long get_array_info(DBADDR *, long *, long *); -static long put_array_info(DBADDR *, long); -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset arrRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, arrRSET); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct arrRecord *prec = (struct arrRecord *)pcommon; - - if (pass == 0) { - if (prec->nelm <= 0) - prec->nelm = 1; - if (prec->ftvl > DBF_ENUM) - prec->ftvl = DBF_UCHAR; - prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), - "arr calloc failed"); - - if (prec->nelm == 1) { - prec->nord = 1; - } else { - prec->nord = 0; - } - return 0; - } - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct arrRecord *prec = (struct arrRecord *)pcommon; - if(prec->clbk) - (*prec->clbk)(prec); - prec->pact = TRUE; - recGblGetTimeStamp(prec); - recGblFwdLink(prec); - prec->pact = FALSE; - return 0; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - arrRecord *prec = (arrRecord *) paddr->precord; - - paddr->pfield = prec->bptr; - paddr->no_elements = prec->nelm; - paddr->field_type = prec->ftvl; - paddr->field_size = dbValueSize(prec->ftvl); - paddr->dbr_field_type = prec->ftvl; - - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - arrRecord *prec = (arrRecord *) paddr->precord; - - *no_elements = prec->nord; - *offset = prec->off; - - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - arrRecord *prec = (arrRecord *) paddr->precord; - - prec->nord = nNew; - if (prec->nord > prec->nelm) - prec->nord = prec->nelm; - - return 0; -} diff --git a/src/ioc/db/test/arrRecord.dbd b/src/ioc/db/test/arrRecord.dbd deleted file mode 100644 index b504be1cb..000000000 --- a/src/ioc/db/test/arrRecord.dbd +++ /dev/null @@ -1,42 +0,0 @@ -include "menuGlobal.dbd" -include "menuConvert.dbd" -include "menuScan.dbd" -recordtype(arr) { - include "dbCommon.dbd" - field(VAL, DBF_NOACCESS) { - prompt("Value") - special(SPC_DBADDR) - pp(TRUE) - extra("void *val") - } - field(NELM, DBF_ULONG) { - prompt("Number of Elements") - special(SPC_NOMOD) - initial("1") - } - field(FTVL, DBF_MENU) { - prompt("Field Type of Value") - special(SPC_NOMOD) - menu(menuFtype) - } - field(NORD, DBF_ULONG) { - prompt("Number elements read") - special(SPC_NOMOD) - } - field(OFF, DBF_ULONG) { - prompt("Offset into array") - } - field(BPTR, DBF_NOACCESS) { - prompt("Buffer Pointer") - special(SPC_NOMOD) - extra("void *bptr") - } - field(INP, DBF_INLINK) { - prompt("Input Link") - } - field(CLBK, DBF_NOACCESS) { - prompt("Processing callback") - special(SPC_NOMOD) - extra("void (*clbk)(struct arrRecord*)") - } -} diff --git a/src/ioc/db/test/arrShorthandTest.c b/src/ioc/db/test/arrShorthandTest.c deleted file mode 100644 index 8f130ab57..000000000 --- a/src/ioc/db/test/arrShorthandTest.c +++ /dev/null @@ -1,136 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - - /* - * Test the shorthand array notation [ start : incr : end ] - * by registering a thin fake arr plugin - * and checking if values are forwarded correctly - */ - -#include - -#include "chfPlugin.h" -#include "dbStaticLib.h" -#include "dbAccessDefs.h" -#include "registry.h" -#include "errlog.h" -#include "epicsExit.h" -#include "dbUnitTest.h" -#include "testMain.h" -#include "osiFileName.h" - -typedef struct myStruct { - epicsInt32 start; - epicsInt32 incr; - epicsInt32 end; -} myStruct; - -static const -chfPluginArgDef opts[] = { - chfInt32 (myStruct, start, "s", 0, 1), - chfInt32 (myStruct, incr, "i", 0, 1), - chfInt32 (myStruct, end, "e", 0, 1), - chfPluginArgEnd -}; - -static myStruct my; - -static void * allocPvt(void) -{ - my.start = 0; - my.incr = 1; - my.end = -1; - return &my; -} - -static chfPluginIf myPif = { - allocPvt, - NULL, /* freePvt, */ - - NULL, /* parse_error, */ - NULL, /* parse_ok, */ - - NULL, /* channel_open, */ - NULL, /* channelRegisterPre, */ - NULL, /* channelRegisterPost, */ - NULL, /* channel_report, */ - NULL /* channel_close */ -}; - -static int checkValues(epicsUInt32 s, epicsUInt32 i, epicsUInt32 e) { - if (s == my.start && i == my.incr && e == my.end) - return 1; - else - return 0; -} - -static void testHead (char* title) { - testDiag("--------------------------------------------------------"); - testDiag("%s", title); - testDiag("--------------------------------------------------------"); -} - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -MAIN(arrShorthandTest) -{ - dbChannel *pch; - - testPlan(26); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("xRecord.db", NULL, NULL); - - testHead("Register plugin"); - testOk(!chfPluginRegister("arr", &myPif, opts), "register fake arr plugin"); - - eltc(0); - testIocInitOk(); - eltc(1); - -#define TESTBAD(Title, Expr) \ - testDiag(Title); \ - testOk(!(pch = dbChannelCreate("x." Expr)), "dbChannelCreate (" Expr ") fails"); \ - if (pch) dbChannelDelete(pch); - -#define TESTGOOD(Title, Expr, Start, Incr, End) \ - testDiag(Title); \ - testOk(!!(pch = dbChannelCreate("x." Expr)), "dbChannelCreate (" Expr ")"); \ - testOk(checkValues(Start, Incr, End), "parameters set correctly: s=%d i=%d e=%d", Start, Incr, End); \ - if (pch) dbChannelDelete(pch); - - TESTBAD("no parameters []", "[]"); - TESTBAD("invalid char at beginning [x", "[x"); - TESTBAD("invalid char after 1st arg [2x", "[2x"); - TESTBAD("invalid char after 2nd arg [2:3x", "[2:3x"); - TESTBAD("invalid char after 3rd arg [2:3:4x", "[2:3:4x"); - - TESTGOOD("one element [index]", "[2]", 2, 1, 2); - TESTGOOD("to end [s:]", "[2:]", 2, 1, -1); - TESTGOOD("to end [s::]", "[2::]", 2, 1, -1); - TESTGOOD("to end with incr [s:i:]", "[2:3:]", 2, 3, -1); - TESTGOOD("from beginning [:e]", "[:2]", 0, 1, 2); - TESTGOOD("from beginning [::e]", "[::2]", 0, 1, 2); - TESTGOOD("from begin with incr [:i:e]", "[:3:2]", 0, 3, 2); - TESTGOOD("range [s:e]", "[2:4]", 2, 1, 4); - TESTGOOD("range [s::e]", "[2::4]", 2, 1, 4); - TESTGOOD("range with incr [s:i:e]", "[2:3:4]", 2, 3, 4); - - testIocShutdownOk(); - testdbCleanup(); - - return testDone(); -} diff --git a/src/ioc/db/test/benchdbConvert.c b/src/ioc/db/test/benchdbConvert.c deleted file mode 100644 index cbc87ad24..000000000 --- a/src/ioc/db/test/benchdbConvert.c +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 Brookhaven Science Assoc, as Operator of Brookhaven -* National Laboratory. -\*************************************************************************/ -#include "string.h" - -#include "cantProceed.h" -#include "dbAddr.h" -#include "dbConvert.h" -#include "dbDefs.h" -#include "epicsTime.h" -#include "epicsMath.h" -#include "epicsAssert.h" - -#include "epicsUnitTest.h" -#include "testMain.h" - -typedef struct { - size_t nelem, niter; - - short *output; - short *input; - - GETCONVERTFUNC getter; - - DBADDR addr; -} testData; - -static long runRep(testData *D) -{ - size_t i; - - for(i=0; initer; i++) { - D->getter(&D->addr, D->output, D->nelem, D->nelem, 0); - } - return 0; -} - -static void runBench(size_t nelem, size_t niter, size_t nrep) -{ - size_t i; - testData tdat; - double *reptimes; - testDiag("Using %lu element arrays.",(unsigned long)nelem); - testDiag("run %lu reps with %lu iterations each", - (unsigned long)nrep, (unsigned long)niter); - - reptimes = callocMustSucceed(nrep, sizeof(*reptimes), "runBench"); - tdat.output = callocMustSucceed(nelem, sizeof(*tdat.output), "runBench"); - tdat.input = callocMustSucceed(nelem, sizeof(*tdat.input), "runBench"); - - tdat.nelem = nelem; - tdat.niter = niter; - - tdat.getter = dbGetConvertRoutine[DBF_SHORT][DBF_SHORT]; - - memset(&tdat.addr, 0, sizeof(tdat.addr)); - tdat.addr.field_type = DBF_SHORT; - tdat.addr.field_size = nelem*sizeof(*tdat.input); - tdat.addr.no_elements = nelem; - tdat.addr.pfield = (void*)tdat.input; - - for(i=0; i -#include -#include -#include -#include -#include - -#include "callback.h" -#include "cantProceed.h" -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsTime.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -/* - * This test checks both immediate and delayed callbacks in two steps. - * In the first step (pass1) NCALLBACKS immediate callbacks are queued. - * As each is run it starts a second delayed callback (pass2). - * The last delayed callback which runs signals an epicsEvent - * to the main thread. - * - * Two time intervals are measured. The time to queue and run each of - * the immediate callbacks, and the actual delay of the delayed callback. - */ - -#define NCALLBACKS 169 -#define DELAY_QUANTUM 0.25 - -#define TEST_DELAY(i) ((i / NUM_CALLBACK_PRIORITIES) * DELAY_QUANTUM) - -typedef struct myPvt { - CALLBACK cb1; - CALLBACK cb2; - epicsTimeStamp pass1Time; - epicsTimeStamp pass2Time; - double delay; - int pass; - int resultFail; -} myPvt; - -epicsEventId finished; - -static void myCallback(CALLBACK *pCallback) -{ - myPvt *pmyPvt; - - callbackGetUser(pmyPvt, pCallback); - - pmyPvt->pass++; - - if (pmyPvt->pass == 1) { - epicsTimeGetCurrent(&pmyPvt->pass1Time); - callbackRequestDelayed(&pmyPvt->cb2, pmyPvt->delay); - } else if (pmyPvt->pass == 2) { - epicsTimeGetCurrent(&pmyPvt->pass2Time); - } else { - pmyPvt->resultFail = 1; - return; - } -} - -static void finalCallback(CALLBACK *pCallback) -{ - myCallback(pCallback); - epicsEventSignal(finished); -} - -static void updateStats(double *stats, double val) -{ - if (stats[0] > val) stats[0] = val; - if (stats[1] < val) stats[1] = val; - stats[2] += val; - stats[3] += pow(val, 2.0); - stats[4] += 1.; -} - -static void printStats(double *stats, const char* tag) { - testDiag("Priority %4s min/avg/max/sigma = %f / %f / %f / %f", - tag, stats[0], stats[2]/stats[4], stats[1], - sqrt(stats[4]*stats[3]-pow(stats[2], 2.0))/stats[4]); -} - -MAIN(callbackParallelTest) -{ - myPvt *pcbt[NCALLBACKS]; - epicsTimeStamp start; - int noCpus = epicsThreadGetCPUs(); - int i, j, slowups, faults; - /* Statistics: min/max/sum/sum^2/n for each priority */ - double setupError[NUM_CALLBACK_PRIORITIES][5]; - double timeError[NUM_CALLBACK_PRIORITIES][5]; - double defaultError[5] = {1,-1,0,0,0}; - - for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) - for (j = 0; j < 5; j++) - setupError[i][j] = timeError[i][j] = defaultError[j]; - - testPlan(4); - - testDiag("Starting %d parallel callback threads", noCpus); - - callbackParallelThreads(noCpus, ""); - callbackInit(); - epicsThreadSleep(1.0); - - finished = epicsEventMustCreate(epicsEventEmpty); - - for (i = 0; i < NCALLBACKS ; i++) { - pcbt[i] = callocMustSucceed(1, sizeof(myPvt), "pcbt"); - callbackSetCallback(myCallback, &pcbt[i]->cb1); - callbackSetCallback(myCallback, &pcbt[i]->cb2); - callbackSetUser(pcbt[i], &pcbt[i]->cb1); - callbackSetUser(pcbt[i], &pcbt[i]->cb2); - callbackSetPriority(i % NUM_CALLBACK_PRIORITIES, &pcbt[i]->cb1); - callbackSetPriority(i % NUM_CALLBACK_PRIORITIES, &pcbt[i]->cb2); - pcbt[i]->delay = TEST_DELAY(i); - pcbt[i]->pass = 0; - } - - /* Last callback is special */ - callbackSetCallback(finalCallback, &pcbt[NCALLBACKS-1]->cb2); - callbackSetPriority(0, &pcbt[NCALLBACKS-1]->cb1); - callbackSetPriority(0, &pcbt[NCALLBACKS-1]->cb2); - pcbt[NCALLBACKS-1]->delay = TEST_DELAY(NCALLBACKS) + 1.0; - pcbt[NCALLBACKS-1]->pass = 0; - - testOk(epicsTimeGetCurrent(&start)==epicsTimeOK, "Time-of-day clock Ok"); - - for (i = 0; i < NCALLBACKS ; i++) { - callbackRequest(&pcbt[i]->cb1); - } - - testDiag("Waiting %.02f sec", pcbt[NCALLBACKS-1]->delay); - - epicsEventWait(finished); - slowups = 0; - faults = 0; - - for (i = 0; i < NCALLBACKS ; i++) { - if(pcbt[i]->resultFail || pcbt[i]->pass!=2) - testDiag("callback setup fault #%d: pass = %d for delay = %.02f", - ++faults, pcbt[i]->pass, pcbt[i]->delay); - else { - double delta = epicsTimeDiffInSeconds(&pcbt[i]->pass1Time, &start); - - if (fabs(delta) >= 0.05) { - slowups++; - testDiag("callback %.02f setup time |%f| >= 0.05 seconds", - pcbt[i]->delay, delta); - } - updateStats(setupError[i%NUM_CALLBACK_PRIORITIES], delta); - } - } - testOk(faults == 0, "%d faults during callback setup", faults); - testOk(slowups <= 1, "%d slowups during callback setup", slowups); - - slowups = 0; - for (i = 0; i < NCALLBACKS ; i++) { - double delta, error; - - if(pcbt[i]->resultFail || pcbt[i]->pass!=2) - continue; - delta = epicsTimeDiffInSeconds(&pcbt[i]->pass2Time, &pcbt[i]->pass1Time); - error = delta - pcbt[i]->delay; - if (fabs(error) >= 0.05) { - slowups++; - testDiag("delay %.02f seconds, delay error |%.04f| >= 0.05", - pcbt[i]->delay, error); - } - updateStats(timeError[i%NUM_CALLBACK_PRIORITIES], error); - } - testOk(slowups < 5, "%d slowups during callbacks", slowups); - - testDiag("Setup time statistics"); - printStats(setupError[0], "LOW"); - printStats(setupError[1], "MID"); - printStats(setupError[2], "HIGH"); - - testDiag("Delay time statistics"); - printStats(timeError[0], "LOW"); - printStats(timeError[1], "MID"); - printStats(timeError[2], "HIGH"); - - for (i = 0; i < NCALLBACKS ; i++) { - free(pcbt[i]); - } - - callbackStop(); - callbackCleanup(); - - return testDone(); -} diff --git a/src/ioc/db/test/callbackTest.c b/src/ioc/db/test/callbackTest.c deleted file mode 100644 index 7032a7cd1..000000000 --- a/src/ioc/db/test/callbackTest.c +++ /dev/null @@ -1,202 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 26JAN2000 */ - -#include -#include -#include -#include -#include -#include - -#include "callback.h" -#include "cantProceed.h" -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsTime.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -/* - * This test checks both immediate and delayed callbacks in two steps. - * In the first step (pass1) NCALLBACKS immediate callbacks are queued. - * As each is run it starts a second delayed callback (pass2). - * The last delayed callback which runs signals an epicsEvent - * to the main thread. - * - * Two time intervals are measured. The time to queue and run each of - * the immediate callbacks, and the actual delay of the delayed callback. - */ - -#define NCALLBACKS 169 -#define DELAY_QUANTUM 0.25 - -#define TEST_DELAY(i) ((i / NUM_CALLBACK_PRIORITIES) * DELAY_QUANTUM) - -typedef struct myPvt { - CALLBACK cb1; - CALLBACK cb2; - epicsTimeStamp pass1Time; - epicsTimeStamp pass2Time; - double delay; - int pass; - int resultFail; -} myPvt; - -epicsEventId finished; - - -static void myCallback(CALLBACK *pCallback) -{ - myPvt *pmyPvt; - - callbackGetUser(pmyPvt, pCallback); - - pmyPvt->pass++; - - if (pmyPvt->pass == 1) { - epicsTimeGetCurrent(&pmyPvt->pass1Time); - callbackRequestDelayed(&pmyPvt->cb2, pmyPvt->delay); - } else if (pmyPvt->pass == 2) { - epicsTimeGetCurrent(&pmyPvt->pass2Time); - } else { - pmyPvt->resultFail = 1; - return; - } -} - -static void finalCallback(CALLBACK *pCallback) -{ - myCallback(pCallback); - epicsEventSignal(finished); -} - -static void updateStats(double *stats, double val) -{ - if (stats[0] > val) stats[0] = val; - if (stats[1] < val) stats[1] = val; - stats[2] += val; - stats[3] += pow(val, 2.0); - stats[4] += 1.; -} - -static void printStats(double *stats, const char* tag) { - testDiag("Priority %4s min/avg/max/sigma = %f / %f / %f / %f", - tag, stats[0], stats[2]/stats[4], stats[1], - sqrt(stats[4]*stats[3]-pow(stats[2], 2.0))/stats[4]); -} - -MAIN(callbackTest) -{ - myPvt *pcbt[NCALLBACKS]; - epicsTimeStamp start; - int i, j, slowups, faults; - /* Statistics: min/max/sum/sum^2/n for each priority */ - double setupError[NUM_CALLBACK_PRIORITIES][5]; - double timeError[NUM_CALLBACK_PRIORITIES][5]; - double defaultError[5] = {1,-1,0,0,0}; - - for (i = 0; i < NUM_CALLBACK_PRIORITIES; i++) - for (j = 0; j < 5; j++) - setupError[i][j] = timeError[i][j] = defaultError[j]; - - testPlan(4); - - callbackInit(); - epicsThreadSleep(1.0); - - finished = epicsEventMustCreate(epicsEventEmpty); - - for (i = 0; i < NCALLBACKS ; i++) { - pcbt[i] = callocMustSucceed(1, sizeof(myPvt), "pcbt"); - callbackSetCallback(myCallback, &pcbt[i]->cb1); - callbackSetCallback(myCallback, &pcbt[i]->cb2); - callbackSetUser(pcbt[i], &pcbt[i]->cb1); - callbackSetUser(pcbt[i], &pcbt[i]->cb2); - callbackSetPriority(i % NUM_CALLBACK_PRIORITIES, &pcbt[i]->cb1); - callbackSetPriority(i % NUM_CALLBACK_PRIORITIES, &pcbt[i]->cb2); - pcbt[i]->delay = TEST_DELAY(i); - pcbt[i]->pass = 0; - } - - /* Last callback is special */ - callbackSetCallback(finalCallback, &pcbt[NCALLBACKS-1]->cb2); - callbackSetPriority(0, &pcbt[NCALLBACKS-1]->cb1); - callbackSetPriority(0, &pcbt[NCALLBACKS-1]->cb2); - pcbt[NCALLBACKS-1]->delay = TEST_DELAY(NCALLBACKS) + 1.0; - pcbt[NCALLBACKS-1]->pass = 0; - - testOk(epicsTimeGetCurrent(&start)==epicsTimeOK, "Time-of-day clock Ok"); - - for (i = 0; i < NCALLBACKS ; i++) { - callbackRequest(&pcbt[i]->cb1); - } - - testDiag("Waiting %.02f sec", pcbt[NCALLBACKS-1]->delay); - - epicsEventWait(finished); - slowups = 0; - faults = 0; - - for (i = 0; i < NCALLBACKS ; i++) { - if(pcbt[i]->resultFail || pcbt[i]->pass!=2) - testDiag("callback setup fault #%d: pass = %d for delay = %.02f", - ++faults, pcbt[i]->pass, pcbt[i]->delay); - else { - double delta = epicsTimeDiffInSeconds(&pcbt[i]->pass1Time, &start); - - if (fabs(delta) >= 0.05) { - slowups++; - testDiag("callback %.02f setup time |%f| >= 0.05 seconds", - pcbt[i]->delay, delta); - } - updateStats(setupError[i%NUM_CALLBACK_PRIORITIES], delta); - } - } - testOk(faults == 0, "%d faults during callback setup", faults); - testOk(slowups <= 1, "%d slowups during callback setup", slowups); - - slowups = 0; - for (i = 0; i < NCALLBACKS ; i++) { - double delta, error; - - if(pcbt[i]->resultFail || pcbt[i]->pass!=2) - continue; - delta = epicsTimeDiffInSeconds(&pcbt[i]->pass2Time, &pcbt[i]->pass1Time); - error = delta - pcbt[i]->delay; - if (fabs(error) >= 0.05) { - slowups++; - testDiag("delay %.02f seconds, delay error |%.04f| >= 0.05", - pcbt[i]->delay, error); - } - updateStats(timeError[i%NUM_CALLBACK_PRIORITIES], error); - } - testOk(slowups < 5, "%d slowups during callbacks", slowups); - - testDiag("Setup time statistics"); - printStats(setupError[0], "LOW"); - printStats(setupError[1], "MID"); - printStats(setupError[2], "HIGH"); - - testDiag("Delay time statistics"); - printStats(timeError[0], "LOW"); - printStats(timeError[1], "MID"); - printStats(timeError[2], "HIGH"); - - for (i = 0; i < NCALLBACKS ; i++) { - free(pcbt[i]); - } - - callbackStop(); - callbackCleanup(); - - return testDone(); -} diff --git a/src/ioc/db/test/chfPluginTest.c b/src/ioc/db/test/chfPluginTest.c deleted file mode 100644 index becd876e8..000000000 --- a/src/ioc/db/test/chfPluginTest.c +++ /dev/null @@ -1,1058 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* für Materialien und Energie GmbH. -* Copyright (c) 2014 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include -#include - -#include "chfPlugin.h" -#include "dbStaticLib.h" -#include "dbAccessDefs.h" -#include "errlog.h" -#include "registry.h" -#include "epicsUnitTest.h" -#include "testMain.h" -#include "osiFileName.h" - -#define PATTERN 0x55555555 -#define TYPE_START 0xAAA -#define R_LEVEL 42 - -/* Expected / actually run callback bit definitions */ -#define e_alloc 0x00000001 -#define e_free 0x00000002 -#define e_error 0x00000004 -#define e_ok 0x00000008 -#define e_open 0x00000010 -#define e_reg_pre 0x00000020 -#define e_reg_post 0x00000040 -#define e_report 0x00000080 -#define e_close 0x00000100 -#define e_pre 0x00000200 -#define e_post 0x00000400 -#define e_dtor 0x00000800 - -unsigned int e1, e2, c1, c2; -unsigned int offset; -int drop = -1; -db_field_log *dtorpfl; - -#define e_any (e_alloc | e_free | e_error | e_ok | e_open \ -| e_reg_pre | e_reg_post | e_pre | e_post | e_dtor | e_report | e_close) - -typedef struct myStruct { - int sent1; - char flag; - int sent2; - epicsUInt32 ival; - int sent3; - double dval; - int sent4; - int enumval; - int sent5; - char str[20]; - int sent6; - epicsUInt32 tval; - int sent7; - char c; - char c1[2]; - int offpre; - int offpost; -} myStruct; - -static const -chfPluginEnumType colorEnum[] = { {"R", 1}, {"G", 2}, {"B", 4}, {NULL,0} }; - -static const -chfPluginArgDef sloppyTaggedOpts[] = { - chfInt32 (myStruct, tval, "t" , 0, 0), - chfTagInt32 (myStruct, ival, "I" , tval, 1, 0, 0), - chfTagBoolean(myStruct, flag, "F" , tval, 2, 0, 0), - chfTagDouble (myStruct, dval, "D" , tval, 3, 0, 0), - chfTagString (myStruct, str, "S" , tval, 4, 0, 0), - chfTagEnum (myStruct, enumval, "C" , tval, 5, 0, 0, colorEnum), - chfPluginArgEnd -}; - -static const -chfPluginArgDef strictTaggedOpts[] = { - chfInt32 (myStruct, tval, "t" , 1, 0), - chfBoolean (myStruct, flag, "f" , 1, 0), - chfTagInt32 (myStruct, ival, "I" , tval, 1, 0, 0), - chfTagBoolean(myStruct, flag, "F" , tval, 2, 0, 0), - chfTagDouble (myStruct, dval, "D" , tval, 3, 1, 0), - chfTagDouble (myStruct, dval, "D2", tval, 4, 1, 0), - chfTagEnum (myStruct, enumval, "C" , tval, 5, 0, 0, colorEnum), - chfPluginArgEnd -}; - -static const -chfPluginArgDef strictOpts[] = { - chfInt32 (myStruct, ival, "i" , 1, 0), - chfBoolean(myStruct, flag, "f" , 1, 0), - chfDouble (myStruct, dval, "d" , 1, 0), - chfString (myStruct, str, "s" , 1, 0), - chfEnum (myStruct, enumval, "c" , 1, 0, colorEnum), - chfPluginArgEnd -}; - -static const -chfPluginArgDef noconvOpts[] = { - chfInt32 (myStruct, ival, "i" , 0, 0), - chfBoolean(myStruct, flag, "f" , 0, 0), - chfDouble (myStruct, dval, "d" , 0, 0), - chfString (myStruct, str, "s" , 0, 0), - chfEnum (myStruct, enumval, "c" , 0, 0, colorEnum), - chfPluginArgEnd -}; - -static const -chfPluginArgDef sloppyOpts[] = { - chfInt32 (myStruct, ival, "i" , 0, 1), - chfBoolean(myStruct, flag, "f" , 0, 1), - chfDouble (myStruct, dval, "d" , 0, 1), - chfString (myStruct, str, "s" , 0, 1), - chfEnum (myStruct, enumval, "c" , 0, 1, colorEnum), - chfPluginArgEnd -}; - -/* Options defs with not enough room provided */ -static const -chfPluginArgDef brokenOpts1[] = { - chfInt32 (myStruct, c1, "i" , 0, 1), - chfPluginArgEnd -}; - -static const -chfPluginArgDef brokenOpts2[] = { - chfDouble(myStruct, c1, "d" , 0, 1), - chfPluginArgEnd -}; - -static const -chfPluginArgDef brokenOpts3[] = { - chfString(myStruct, c1, "s" , 0, 1), - chfPluginArgEnd -}; - -static const -chfPluginArgDef brokenOpts4[] = { - chfEnum (myStruct, c1, "c" , 0, 1, colorEnum), - chfPluginArgEnd -}; - -int p_ok_return = 0; -int c_open_return = 0; -void *puser1, *puser2; - -static void clearStruct(void *p) { - myStruct *my = (myStruct*) p; - - if (!my) return; - memset(my, 0, sizeof(myStruct)); - my->sent1 = my->sent2 = my->sent3 = my->sent4 = - my->sent5 = my->sent6 = my->sent7 = PATTERN; - my->ival = 12; - my->tval = 99; - my->flag = 1; - my->dval = 1.234e5; - strcpy(my->str, "hello"); - my->enumval = 4; -} - -static char inst(void* user) { - return user == puser1 ? '1' : user == puser2 ? '2' : 'x'; -} - -static void * allocPvt(void) -{ - myStruct *my = (myStruct*) calloc(1, sizeof(myStruct)); - - if (!puser1) { - puser1 = my; - testOk(e1 & e_alloc, "allocPvt (1) called"); - c1 |= e_alloc; - } else if (!puser2) { - puser2 = my; - testOk(e2 & e_alloc, "allocPvt (2) called"); - c2 |= e_alloc; - } - clearStruct (my); - return my; -} - -static void * allocPvtFail(void) -{ - if (!puser1) { - testOk(e1 & e_alloc, "allocPvt (1) called"); - c1 |= e_alloc; - } - return NULL; -} - -static void freePvt(void *user) -{ - if (user == puser1) { - testOk(e1 & e_free, "freePvt (1) called"); - c1 |= e_free; - free(user); - puser1 = NULL; - } else if (user == puser2) { - testOk(e2 & e_free, "freePvt (2) called"); - c2 |= e_free; - free(user); - puser2 = NULL; - } else - testFail("freePvt: user pointer invalid"); -} - -static void parse_error(void *user) -{ - if (user == puser1) { - testOk(e1 & e_error, "parse_error (1) called"); - c1 |= e_error; - } else if (user == puser2) { - testOk(e2 & e_error, "parse_error (2) called"); - c2 |= e_error; - } else - testFail("parse_error: user pointer invalid"); -} - -static int parse_ok(void *user) -{ - if (user == puser1) { - testOk(e1 & e_ok, "parse_ok (1) called"); - c1 |= e_ok; - } else if (user == puser2) { - testOk(e2 & e_ok, "parse_ok (2) called"); - c2 |= e_ok; - } else - testFail("parse_ok: user pointer invalid"); - - return p_ok_return; -} - -static long channel_open(dbChannel *chan, void *user) -{ - if (user == puser1) { - testOk(e1 & e_open, "channel_open (1) called"); - c1 |= e_open; - } else if (user == puser2) { - testOk(e2 & e_open, "channel_open (2) called"); - c2 |= e_open; - } else - testFail("channel_open: user pointer invalid"); - - return c_open_return; -} - -static void dbfl_free1(db_field_log *pfl) { - testOk(e1 & e_dtor, "dbfl_free (1) called"); - testOk(dtorpfl == pfl, "dbfl_free (1): db_field_log pointer correct"); - dtorpfl = NULL; - c1 |= e_dtor; -} - -static void dbfl_free2(db_field_log *pfl) { - testOk(e2 & e_dtor, "dbfl_free (2) called"); - testOk(dtorpfl == pfl, "dbfl_free (2): db_field_log pointer correct"); - dtorpfl = NULL; - c2 |= e_dtor; -} - -static db_field_log * pre(void *user, dbChannel *chan, db_field_log *pLog) { - myStruct *my = (myStruct*)user; - dbfl_freeFunc *dtor = NULL; - - if (my == puser1) { - testOk(e1 & e_pre, "pre (1) called"); - testOk(!(c2 & e_pre), - "pre (2) was not called before pre (1)"); - c1 |= e_pre; - dtor = dbfl_free1; - } else if (my == puser2) { - testOk(e2 & e_pre, "pre (2) called"); - testOk(!(e1 & e_pre) || c1 & e_pre, - "pre (1) was called before pre (2)"); - c2 |= e_pre; - dtor = dbfl_free2; - } else { - testFail("pre: user pointer invalid"); - testSkip(1, "Can't check order of pre(1)/pre(2)"); - } - testOk(!(c1 & e_post), - "post (1) was not called before pre (%c)", inst(user)); - testOk(!(c2 & e_post), - "post (2) was not called before pre (%c)", inst(user)); - - if (!testOk(pLog->field_type == TYPE_START + my->offpre, - "pre (%c) got field log of expected type", inst(user))) - testDiag("expected: %d, got %d", - TYPE_START + my->offpre, pLog->field_type); - pLog->field_type++; - - if (my->offpre == 0) { /* The first one registers a dtor and saves pfl */ - pLog->u.r.dtor = dtor; - dtorpfl = pLog; - } - - if (my->offpre == drop) { - testDiag("pre (%c) is dropping the field log", inst(user)); - return NULL; - } - return pLog; -} - -static db_field_log * post(void *user, dbChannel *chan, db_field_log *pLog) { - myStruct *my = (myStruct*)user; - dbfl_freeFunc *dtor = NULL; - - if (my == puser1) { - testOk(e1 & e_post, "post (1) called"); - testOk(!(c2 & e_post), - "post (2) was not called before post (1)"); - c1 |= e_post; - dtor = dbfl_free1; - } else if (my == puser2) { - testOk(e2 & e_post, "post (2) called"); - testOk(!(e1 & e_post) || c1 & e_post, - "post (1) was called before post (2)"); - c2 |= e_post; - dtor = dbfl_free2; - } else { - testFail("post: user pointer invalid"); - testSkip(1, "Can't check order of post(1)/post(2)"); - } - testOk(!(e1 & e_pre) || c1 & e_pre, - "pre (1) was called before post (%c)", inst(user)); - testOk(!(e2 & e_pre) || c2 & e_pre, - "pre (2) was called before post (%c)", inst(user)); - - if (!testOk(pLog->field_type == TYPE_START + my->offpost, - "post (%c) got field log of expected type", inst(user))) - testDiag("expected: %d, got %d", - TYPE_START + my->offpost, pLog->field_type); - pLog->field_type++; - - if (my->offpost == 0) { /* The first one registers a dtor and saves pfl */ - pLog->u.r.dtor = dtor; - dtorpfl = pLog; - } - - if (my->offpost == drop) { - testDiag("post (%c) is dropping the field log", inst(user)); - return NULL; - } - return pLog; -} - -static void channelRegisterPre(dbChannel *chan, void *user, - chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - myStruct *my = (myStruct*)user; - - if (my == puser1) { - testOk(e1 & e_reg_pre, "register_pre (1) called"); - testOk(!(c2 & e_reg_pre), - "register_pre (2) was not called before register_pre (1)"); - c1 |= e_reg_pre; - } else if (my == puser2) { - testOk(e2 & e_reg_pre, "register_pre (2) called"); - testOk(!(e1 & e_reg_pre) || c1 & e_reg_pre, - "register_pre (1) was called before register_pre (2)"); - c2 |= e_reg_pre; - } else { - testFail("register_pre: user pointer invalid"); - testSkip(1, "Can't check order of register_pre(1)/register_pre(2)"); - } - testOk(!(c1 & e_reg_post), - "register_post (1) was not called before register_pre (%c)", inst(user)); - testOk(!(c2 & e_reg_post), - "register_post (2) was not called before register_pre (%c)", inst(user)); - - my->offpre = offset++; - probe->field_type++; - *cb_out = pre; - *arg_out = user; -} - -static void channelRegisterPost(dbChannel *chan, void *user, - chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - myStruct *my = (myStruct*)user; - - if (my == puser1) { - testOk(e1 & e_reg_post, "register_post (1) called"); - testOk(!(c2 & e_reg_post), - "register_post (2) was not called before register_post (1)"); - c1 |= e_reg_post; - } else if (my == puser2) { - testOk(e2 & e_reg_post, "register_post (2) called"); - testOk(!(e1 & e_reg_post) || c1 & e_reg_post, - "register_post (1) was called before register_post (2)"); - c2 |= e_reg_post; - } else { - testFail("register_post: user pointer invalid"); - testSkip(1, "Can't check order of register_post(1)/register_post(2)"); - } - testOk(!(e1 & e_reg_pre) || c1 & e_reg_pre, - "register_pre (1) was called before register_post (%c)", inst(user)); - testOk(!(e2 & e_reg_pre) || c2 & e_reg_pre, - "register_pre (2) was called before register_post (%c)", inst(user)); - - my->offpost = offset++; - probe->field_type++; - *cb_out = post; - *arg_out = user; -} - -static void channel_report(dbChannel *chan, void *user, int level, - const unsigned short indent) -{ - testOk(level == R_LEVEL - 2, "channel_report: level correct %u == %u", level, R_LEVEL-2); - if (user == puser1) { - testOk(e1 & e_report, "channel_report (1) called"); - c1 |= e_report; - } else if (user == puser2) { - testOk(e2 & e_report, "channel_report (2) called"); - c2 |= e_report; - } else - testFail("channel_report: user pointer invalid"); -} - -static void channel_close(dbChannel *chan, void *user) -{ - if (user == puser1) { - testOk(e1 & e_close, "channel_close (1) called"); - c1 |= e_close; - } else if (user == puser2) { - testOk(e2 & e_close, "channel_close (2) called"); - c2 |= e_close; - } else - testFail("channel_close: user pointer invalid"); -} - -static chfPluginIf myPif = { - allocPvt, - freePvt, - - parse_error, - parse_ok, - - channel_open, - channelRegisterPre, - channelRegisterPost, - channel_report, - channel_close -}; - -static chfPluginIf prePif = { - allocPvt, - freePvt, - - parse_error, - parse_ok, - - channel_open, - channelRegisterPre, - NULL, - channel_report, - channel_close -}; - -static chfPluginIf postPif = { - allocPvt, - freePvt, - - parse_error, - parse_ok, - - channel_open, - NULL, - channelRegisterPost, - channel_report, - channel_close -}; - -static chfPluginIf allocFailPif = { - allocPvtFail, - freePvt, - - parse_error, - parse_ok, - - channel_open, - channelRegisterPre, - channelRegisterPost, - channel_report, - channel_close -}; - -static int checkValues(myStruct *my, - char t, epicsUInt32 i, int f, double d, char *s1, char *s2, int c) { - int ret = 1; - int s1fail, s2fail; - int s2valid = (s2 && s2[0] != '\0'); - - if (!my) return 0; -#define CHK(A,B,FMT) if((A)!=(B)) {testDiag("Fail: " #A " (" FMT ") != " #B " (" FMT")", A, B); ret=0;} - CHK(my->sent1, PATTERN, "%08x") - CHK(my->sent2, PATTERN, "%08x") - CHK(my->sent3, PATTERN, "%08x") - CHK(my->sent4, PATTERN, "%08x") - CHK(my->sent5, PATTERN, "%08x") - CHK(my->sent6, PATTERN, "%08x") - CHK(my->sent7, PATTERN, "%08x") - CHK(my->tval, t, "%08x") - CHK(my->ival, i, "%08x") - CHK(my->flag, f, "%02x") - CHK(my->dval, d, "%f") - CHK(my->enumval, c, "%d") -#undef CHK - s2fail = s1fail = strcmp(s1, my->str); - if (s2valid) s2fail = strcmp(s2, my->str); - if (s1fail && s2fail) { - if (s1fail) testDiag("Fail: my->str (%s) != s (%s)", my->str, s1); - if (s2valid && s2fail) testDiag("Fail: my->str (%s) != s (%s)", my->str, s2); - ret = 0; - } - return ret; -} - -static void testHead (char* title) { - testDiag("--------------------------------------------------------"); - testDiag("%s", title); - testDiag("--------------------------------------------------------"); -} - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -MAIN(chfPluginTest) -{ - dbChannel *pch; - db_field_log *pfl; - -#ifdef _WIN32 -#if (defined(_MSC_VER) && _MSC_VER < 1900) || \ - (defined(_MINGW) && defined(_TWO_DIGIT_EXPONENT)) - _set_output_format(_TWO_DIGIT_EXPONENT); -#endif -#endif - - testPlan(1433); - - dbChannelInit(); - db_init_events(); - - /* Enum to string conversion */ - testHead("Enum to string conversion"); - testOk(strcmp(chfPluginEnumString(colorEnum, 1, "-"), "R") == 0, - "Enum to string: R"); - testOk(strcmp(chfPluginEnumString(colorEnum, 2, "-"), "G") == 0, - "Enum to string: G"); - testOk(strcmp(chfPluginEnumString(colorEnum, 4, "-"), "B") == 0, - "Enum to string: B"); - testOk(strcmp(chfPluginEnumString(colorEnum, 3, "-"), "-") == 0, - "Enum to string: invalid index"); - - if (dbReadDatabase(&pdbbase, "dbTestIoc.dbd", - "." OSI_PATH_LIST_SEPARATOR ".." OSI_PATH_LIST_SEPARATOR - "../O.Common" OSI_PATH_LIST_SEPARATOR "O.Common", NULL)) - testAbort("Database description 'dbTestIoc.dbd' not found"); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - if (dbReadDatabase(&pdbbase, "xRecord.db", - "." OSI_PATH_LIST_SEPARATOR "..", NULL)) - testAbort("Test database 'xRecord.db' not found"); - - testHead("Try to register buggy plugins"); - eltc(0); - testOk(!!chfPluginRegister("buggy", &myPif, brokenOpts1), - "not enough storage for integer"); - testOk(!!chfPluginRegister("buggy", &myPif, brokenOpts2), - "not enough storage for double"); - testOk(!!chfPluginRegister("buggy", &myPif, brokenOpts3), - "not enough storage for string"); - testOk(!!chfPluginRegister("buggy", &myPif, brokenOpts4), - "not enough storage for enum"); - errlogFlush(); - eltc(1); - - testHead("Register plugins"); - testOk(!chfPluginRegister("sloppy-tagged", &myPif, sloppyTaggedOpts), - "register plugin sloppy-tagged"); - testOk(!chfPluginRegister("strict-tagged", &myPif, strictTaggedOpts), - "register plugin strict-tagged"); - testOk(!chfPluginRegister("strict", &myPif, strictOpts), - "register plugin strict"); - testOk(!chfPluginRegister("noconv", &myPif, noconvOpts), - "register plugin noconv"); - testOk(!chfPluginRegister("sloppy", &myPif, sloppyOpts), - "register plugin sloppy"); - testOk(!chfPluginRegister("pre", &prePif, sloppyOpts), - "register plugin pre"); - testOk(!chfPluginRegister("post", &postPif, sloppyOpts), - "register plugin post"); - testOk(!chfPluginRegister("alloc-fail", &allocFailPif, sloppyOpts), - "register plugin alloc-fail"); - - /* Check failing allocation of plugin private structures */ - - testHead("Failing allocation of plugin private structures"); - /* tag i */ - e1 = e_alloc; c1 = 0; - testOk(!(pch = dbChannelCreate( - "x.{\"alloc-fail\":{\"i\":1}}")), - "create channel for alloc-fail: allocPvt returning NULL"); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - - /* TAGGED parsing: shorthand for integer plus other parameter */ - - /* STRICT TAGGED parsing: mandatory, no conversions */ - - /* All perfect */ - testHead("STRICT TAGGED parsing: all ok"); - /* tag D (t and d) and f */ - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate( - "x.{\"strict-tagged\":{\"D\":1.2e15,\"f\":false}}")), - "create channel for strict-tagged parsing: D (t and d) and f"); - testOk(checkValues(puser1, 3, 12, 0, 1.2e15, "hello", 0, 4), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - /* tag D2 (t and d) and f */ - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate( - "x.{\"strict-tagged\":{\"D2\":1.2e15,\"f\":false}}")), - "create channel for strict-tagged parsing: D2 (t and d) and f"); - testOk(checkValues(puser1, 4, 12, 0, 1.2e15, "hello", 0, 4), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - /* tag F: (t and f), d missing) */ - e1 = e_alloc | e_error | e_free; c1 = 0; - testOk(!(pch = dbChannelCreate( - "x.{\"strict-tagged\":{\"F\":false}}")), - "create channel for strict-tagged parsing: F (t and f), d missing"); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - /* tag I: (t and i) and f, d missing) */ - e1 = e_alloc | e_error | e_free; c1 = 0; - testOk(!(pch = dbChannelCreate( - "x.{\"strict-tagged\":{\"I\":1,\"f\":false}}")), - "create channel for strict-tagged parsing: I (t and i) and f, d missing"); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - - /* SLOPPY TAGGED parsing: optional, all others have defaults */ - - testHead("SLOPPY TAGGED parsing: all ok"); - - /* tag i */ - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate( - "x.{\"sloppy-tagged\":{\"I\":1}}")), - "create channel for sloppy-tagged parsing: I"); - testOk(checkValues(puser1, 1, 1, 1, 1.234e5, "hello", 0, 4), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - /* tag f */ - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate( - "x.{\"sloppy-tagged\":{\"F\":false}}")), - "create channel for sloppy-tagged parsing: F"); - testOk(checkValues(puser1, 2, 12, 0, 1.234e5, "hello", 0, 4), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - /* tag d */ - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate( - "x.{\"sloppy-tagged\":{\"D\":1.2e15}}")), - "create channel for sloppy-tagged parsing: D"); - testOk(checkValues(puser1, 3, 12, 1, 1.2e15, "hello", 0, 4), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - /* tag s */ - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate( - "x.{\"sloppy-tagged\":{\"S\":\"bar\"}}")), - "create channel for sloppy-tagged parsing: S"); - testOk(checkValues(puser1, 4, 12, 1, 1.234e5, "bar", 0, 4), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - /* tag c */ - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate( - "x.{\"sloppy-tagged\":{\"C\":\"R\"}}")), - "create channel for sloppy-tagged parsing: C"); - testOk(checkValues(puser1, 5, 12, 1, 1.234e5, "hello", 0, 1), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - - /* STRICT parsing: mandatory, no conversion */ - - /* All perfect */ - testHead("STRICT parsing: all ok"); - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate("x.{\"strict\":{\"i\":1,\"f\":false,\"d\":1.2e15,\"s\":\"bar\",\"c\":\"R\"}}")), - "create channel for strict parsing: JSON correct"); - testOk(checkValues(puser1, 99, 1, 0, 1.2e15, "bar", 0, 1), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - - /* Any one missing must fail */ - testHead("STRICT parsing: any missing parameter must fail"); - e1 = e_alloc | e_error | e_free; c1 = 0; - testOk(!(pch = dbChannelCreate( - "x.{\"strict\":{\"i\":1,\"f\":false,\"d\":1.2e15,\"s\":\"bar\"}}")), - "create channel for strict parsing: c missing"); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_alloc | e_error | e_free; c1 = 0; - testOk(!(pch = dbChannelCreate( - "x.{\"strict\":{\"f\":false,\"i\":1,\"d\":1.2e15,\"c\":\"R\"}}")), - "create channel for strict parsing: s missing"); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_alloc | e_error | e_free; c1 = 0; - testOk(!(pch = dbChannelCreate( - "x.{\"strict\":{\"i\":1,\"c\":\"R\",\"f\":false,\"s\":\"bar\"}}")), - "create channel for strict parsing: d missing"); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_alloc | e_error | e_free; c1 = 0; - testOk(!(pch = dbChannelCreate( - "x.{\"strict\":{\"d\":1.2e15,\"c\":\"R\",\"i\":1,\"s\":\"bar\"}}")), - "create channel for strict parsing: f missing"); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_alloc | e_error | e_free; c1 = 0; - testOk(!(pch = dbChannelCreate( - "x.{\"strict\":{\"c\":\"R\",\"s\":\"bar\",\"f\":false,\"d\":1.2e15}}")), - "create channel for strict parsing: i missing"); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - - /* NOCONV parsing: optional, no conversion */ - - /* Any one missing must leave the default intact */ - testHead("NOCONV parsing: missing parameters get default value"); - e1 = e_alloc | e_ok; c1 = 0; - testOk(!!(pch = dbChannelCreate( - "x.{\"noconv\":{\"i\":1,\"f\":false,\"d\":1.2e15,\"s\":\"bar\"}}")), - "create channel for noconv parsing: c missing"); - testOk(checkValues(puser1, 99, 1, 0, 1.2e15, "bar", 0, 4), - "guards intact, values correct"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - e1 = e_close | e_free; c1 = 0; - if (pch) dbChannelDelete(pch); - testOk(!puser1, "user part cleaned up"); - if (!testOk(c1 == e1, "all expected calls happened")) - testDiag("expected %#x - called %#x", e1, c1); - - e1 = e_any; - testOk(!!(pch = dbChannelCreate( - "x.{\"noconv\":{\"i\":1,\"f\":false,\"d\":1.2e15,\"c\":\"R\"}}")), - "create channel for noconv parsing: s missing"); - testOk(checkValues(puser1, 99, 1, 0, 1.2e15, "hello", 0, 1), - "guards intact, values correct"); - if (pch) dbChannelDelete(pch); - - testOk(!!(pch = dbChannelCreate( - "x.{\"noconv\":{\"i\":1,\"f\":false,\"s\":\"bar\",\"c\":\"R\"}}")), - "create channel for noconv parsing: d missing"); - testOk(checkValues(puser1, 99, 1, 0, 1.234e5, "bar", 0, 1), - "guards intact, values correct"); - if (pch) dbChannelDelete(pch); - - testOk(!!(pch = dbChannelCreate( - "x.{\"noconv\":{\"i\":1,\"d\":1.2e15,\"s\":\"bar\",\"c\":\"R\"}}")), - "create channel for noconv parsing: f missing"); - testOk(checkValues(puser1, 99, 1, 1, 1.2e15, "bar", 0, 1), - "guards intact, values correct"); - if (pch) dbChannelDelete(pch); - - testOk(!!(pch = dbChannelCreate( - "x.{\"noconv\":{\"f\":false,\"d\":1.2e15,\"s\":\"bar\",\"c\":\"R\"}}")), - "create channel for noconv parsing: i missing"); - testOk(checkValues(puser1, 99, 12, 0, 1.2e15, "bar", 0, 1), - "guards intact, values correct"); - if (pch) dbChannelDelete(pch); - - /* Reject wrong types */ -#define WRONGTYPETEST(Var, Val, Typ) \ - e1 = e_alloc | e_error | e_free; c1 = 0; \ - testOk(!(pch = dbChannelCreate("x.{\"noconv\":{\""#Var"\":"#Val"}}")), \ - "create channel for noconv parsing: wrong type "#Typ" for "#Var); \ - testOk(!puser1, "user part cleaned up"); \ - if (!testOk(c1 == e1, "all expected calls happened")) \ - testDiag("expected %#x - called %#x", e1, c1); - - testHead("NOCONV parsing: rejection of wrong parameter types"); - - WRONGTYPETEST(i, 123.0, double); - WRONGTYPETEST(i, true, boolean); - WRONGTYPETEST(i, "1", string); - WRONGTYPETEST(f, "false", string); - WRONGTYPETEST(f, 0.0, double); - WRONGTYPETEST(f, 1, integer); - WRONGTYPETEST(d, "1.2", string); - WRONGTYPETEST(d, true, boolean); - WRONGTYPETEST(d, 123, integer); - WRONGTYPETEST(s, 1.23, double); - WRONGTYPETEST(s, true, boolean); - WRONGTYPETEST(s, 123, integer); - WRONGTYPETEST(c, 1.23, double); - WRONGTYPETEST(c, true, boolean); - WRONGTYPETEST(c, 2, integer); - - /* SLOPPY parsing: optional, with conversion */ - -#define CONVTESTGOOD(Var, Val, Typ, Ival, Fval, Dval, Sval1, Sval2, Cval) \ - e1 = e_alloc | e_ok; c1 = 0; \ - testDiag("Calling dbChannelCreate x.{\"sloppy\":{\""#Var"\":"#Val"}}"); \ - testOk(!!(pch = dbChannelCreate("x.{\"sloppy\":{\""#Var"\":"#Val"}}")), \ - "create channel for sloppy parsing: "#Typ" (good) for "#Var); \ - testOk(checkValues(puser1, 99, Ival, Fval, Dval, Sval1, Sval2, Cval), \ - "guards intact, values correct"); \ - if (!testOk(c1 == e1, "create channel: all expected calls happened")) \ - testDiag("expected %#x - called %#x", e1, c1); \ - e1 = e_close | e_free; c1 = 0; \ - if (pch) dbChannelDelete(pch); \ - testOk(!puser1, "user part cleaned up"); \ - if (!testOk(c1 == e1, "delete channel: all expected calls happened")) \ - testDiag("expected %#x - called %#x", e1, c1); - -#define CONVTESTBAD(Var, Val, Typ) \ - e1 = e_alloc | e_error | e_free; c1 = 0; \ - testDiag("Calling dbChannelCreate x.{\"sloppy\":{\""#Var"\":"#Val"}}"); \ - testOk(!(pch = dbChannelCreate("x.{\"sloppy\":{\""#Var"\":"#Val"}}")), \ - "create channel for sloppy parsing: "#Typ" (bad) for "#Var); \ - testOk(!puser1, "user part cleaned up"); \ - if (!testOk(c1 == e1, "create channel: all expected calls happened")) \ - testDiag("expected %#x - called %#x", e1, c1); - - /* To integer */ - testHead("SLOPPY parsing: conversion to integer"); - CONVTESTGOOD(i, "123e4", positive string, 123, 1, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(i, "-12345", negative string, -12345, 1, 1.234e5, "hello", 0, 4); - CONVTESTBAD(i, "9234567890", out-of-range string); - CONVTESTBAD(i, ".4", invalid string); - CONVTESTGOOD(i, false, valid boolean, 0, 1, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(i, 3456.789, valid double, 3456, 1, 1.234e5, "hello", 0, 4); - CONVTESTBAD(i, 34.7e14, out-of-range double); - - /* To boolean */ - testHead("SLOPPY parsing: conversion to boolean"); - CONVTESTGOOD(f, "false", valid string, 12, 0, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, "False", capital valid string, 12, 0, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, "0", 0 string, 12, 0, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, "15", 15 string, 12, 1, 1.234e5, "hello", 0, 4); - CONVTESTBAD(f, ".4", invalid .4 string); - CONVTESTBAD(f, "Flase", misspelled invalid string); - CONVTESTGOOD(f, 0, zero integer, 12, 0, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, 12, positive integer, 12, 1, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, -1234, negative integer, 12, 1, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, 0.4, positive non-zero double, 12, 1, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, 0.0, zero double, 12, 0, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, -0.0, minus-zero double, 12, 0, 1.234e5, "hello", 0, 4); - CONVTESTGOOD(f, -1.24e14, negative double, 12, 1, 1.234e5, "hello", 0, 4); - - /* To double */ - testHead("SLOPPY parsing: conversion to double"); - CONVTESTGOOD(d, "123e4", positive double string, 12, 1, 1.23e6, "hello", 0, 4); - CONVTESTGOOD(d, "-7.89e-14", negative double string, 12, 1, -7.89e-14, "hello", 0, 4); - CONVTESTGOOD(d, "123", positive integer string, 12, 1, 123.0, "hello", 0, 4); - CONVTESTGOOD(d, "-1234567", negative integer string, 12, 1, -1.234567e6, "hello", 0, 4); - CONVTESTBAD(d, "1.67e407", out-of-range double string); - CONVTESTBAD(d, "blubb", invalid blubb string); - CONVTESTGOOD(d, 123, positive integer, 12, 1, 123.0, "hello", 0, 4); - CONVTESTGOOD(d, -12345, negative integer, 12, 1, -1.2345e4, "hello", 0, 4); - CONVTESTGOOD(d, true, true boolean, 12, 1, 1.0, "hello", 0, 4); - CONVTESTGOOD(d, false, false boolean, 12, 1, 0.0, "hello", 0, 4); - - /* To string */ - testHead("SLOPPY parsing: conversion to string"); - CONVTESTGOOD(s, 12345, positive integer, 12, 1, 1.234e5, "12345", 0, 4); - CONVTESTGOOD(s, -1234567891, negative integer, 12, 1, 1.234e5, "-1234567891", 0, 4); - CONVTESTGOOD(s, true, true boolean, 12, 1, 1.234e5, "true", 0, 4); - CONVTESTGOOD(s, false, false boolean, 12, 1, 1.234e5, "false", 0, 4); - CONVTESTGOOD(s, 123e4, small positive double, 12, 1, 1.234e5, "1230000", 0, 4); - CONVTESTGOOD(s, -123e24, negative double, 12, 1, 1.234e5, "-1.23e+26", "-1.23e+026", 4); - CONVTESTGOOD(s, -1.23456789123e26, large negative double, 12, 1, 1.234e5, "-1.23456789123e+26", "-1.23456789123e+026", 4); - - /* To Enum */ - testHead("SLOPPY parsing: conversion to enum"); - CONVTESTGOOD(c, 2, valid integer choice, 12, 1, 1.234e5, "hello", 0, 2); - CONVTESTBAD(c, 3, invalid integer choice); - CONVTESTBAD(c, 3.2, double); - CONVTESTGOOD(c, "R", valid string choice, 12, 1, 1.234e5, "hello", 0, 1); - CONVTESTBAD(c, "blubb", invalid string choice); - - /* Registering and running filter callbacks */ - -#define CHAINTEST1(Type, Json, ExpReg, ExpRun, DType) \ - testHead("Filter chain test, "Type" filter"); \ - offset = 0; \ - e1 = e_alloc | e_ok; c1 = 0; \ - testOk(!!(pch = dbChannelCreate("x."Json)), "filter chains: create channel with "Type" filter"); \ - if (!testOk(c1 == e1, "create channel: all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - e1 = e_open | ExpReg; c1 = 0; \ - testOk(!dbChannelOpen(pch), "dbChannelOpen returned channel"); \ - if (!testOk(c1 == e1, "open channel: all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - e1 = ExpRun; c1 = 0; \ - testOk(!!(pfl = db_create_read_log(pch)), "create db_field_log"); \ - pfl->type = dbfl_type_ref; \ - pfl->field_type = TYPE_START; \ - testOk(!!(pfl = dbChannelRunPreChain(pch, pfl)), "run pre eventq chain"); \ - testOk(!!(pfl = dbChannelRunPostChain(pch, pfl)), "run post eventq chain"); \ - testOk(pfl->field_type == TYPE_START + DType, "final data type is correct"); \ - db_delete_field_log(pfl); \ - if (!testOk(c1 == e1, "run filter chains: all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - e1 = e_report; c1 = 0; \ - dbChannelShow(pch, R_LEVEL, 0); \ - if (!testOk(c1 == e1, "report: all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - e1 = e_close | e_free; c1 = 0; \ - if (pch) dbChannelDelete(pch); \ - if (!testOk(c1 == e1, "delete channel: all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); - -#define CHAINTEST2(Type, Json, ExpReg1, ExpRun1, ExpReg2, ExpRun2, DType) \ - testHead("Filter chain test, "Type" filters"); \ - offset = 0; \ - e1 = e_alloc | e_ok; c1 = 0; \ - e2 = e_alloc | e_ok; c2 = 0; \ - testOk(!!(pch = dbChannelCreate("x."Json)), "filter chains: create channel with "Type" filters"); \ - if (!testOk(c1 == e1, "create channel (1): all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - if (!testOk(c2 == e2, "create channel (2): all expected calls happened")) testDiag("expected %#x - called %#x", e2, c2); \ - e1 = e_open | ExpReg1; c1 = 0; \ - e2 = e_open | ExpReg2; c2 = 0; \ - if (pch) testOk(!dbChannelOpen(pch), "dbChannelOpen returned channel"); \ - if (!testOk(c1 == e1, "open channel (1): all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - if (!testOk(c2 == e2, "open channel (2): all expected calls happened")) testDiag("expected %#x - called %#x", e2, c2); \ - e1 = ExpRun1; c1 = 0; \ - e2 = ExpRun2; c2 = 0; \ - if (pch) testOk(!!(pfl = db_create_read_log(pch)), "create db_field_log"); \ - pfl->type = dbfl_type_ref; \ - pfl->field_type = TYPE_START; \ - if (pch) testOk(!!(pfl = dbChannelRunPreChain(pch, pfl)) || (drop >=0 && drop <= 1), "run pre eventq chain"); \ - if (pch && (drop < 0 || drop >= 2)) testOk(!!(pfl = dbChannelRunPostChain(pch, pfl)) || drop >=2, "run post eventq chain"); \ - if (pfl) testOk(pfl->field_type == TYPE_START + DType, "final data type is correct"); \ - if (pfl) db_delete_field_log(pfl); \ - if (!testOk(c1 == e1, "run filter chains (1): all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - if (!testOk(c2 == e2, "run filter chains (2): all expected calls happened")) testDiag("expected %#x - called %#x", e2, c2); \ - e1 = e_report; c1 = 0; \ - e2 = e_report; c2 = 0; \ - dbChannelShow(pch, R_LEVEL, 0); \ - if (!testOk(c1 == e1, "report (1): all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - if (!testOk(c2 == e2, "report (2): all expected calls happened")) testDiag("expected %#x - called %#x", e2, c2); \ - e1 = e_close | e_free; c1 = 0; \ - e2 = e_close | e_free; c2 = 0; \ - if (pch) dbChannelDelete(pch); \ - if (!testOk(c1 == e1, "delete channel (1): all expected calls happened")) testDiag("expected %#x - called %#x", e1, c1); \ - if (!testOk(c2 == e2, "delete channel (2): all expected calls happened")) testDiag("expected %#x - called %#x", e2, c2); - - CHAINTEST1("1 pre", "{\"pre\":{}}", e_reg_pre, e_pre | e_dtor, 1); /* One filter, pre chain */ - CHAINTEST1("1 post", "{\"post\":{}}", e_reg_post, e_post | e_dtor, 1); /* One filter, post chain */ - CHAINTEST1("1 both", "{\"sloppy\":{}}", e_reg_pre | e_reg_post, e_pre | e_post | e_dtor, 2); /* One, both chains */ - CHAINTEST2("2 pre", "{\"pre\":{},\"pre\":{}}", e_reg_pre, e_pre | e_dtor, e_reg_pre, e_pre, 2); /* Two filters, pre chain */ - CHAINTEST2("2 post", "{\"post\":{},\"post\":{}}", e_reg_post, e_post | e_dtor, e_reg_post, e_post, 2); /* Two filters, post chain */ - CHAINTEST2("2 both", "{\"sloppy\":{},\"sloppy\":{}}", /* Two, both chains */ - e_reg_pre | e_reg_post, e_pre | e_post | e_dtor, e_reg_pre | e_reg_post, e_pre | e_post, 4); - CHAINTEST2("1 pre, 1 post", "{\"pre\":{},\"post\":{}}", e_reg_pre, e_pre | e_dtor, e_reg_post, e_post, 2); /* Two, pre then post */ - CHAINTEST2("1 post, 1 pre", "{\"post\":{},\"pre\":{}}", e_reg_post, e_post, e_reg_pre, e_pre | e_dtor, 2); /* Two, post then pre */ - CHAINTEST2("1 pre, 1 both", "{\"pre\":{},\"sloppy\":{}}", /* Two, pre then both */ - e_reg_pre, e_pre | e_dtor, e_reg_pre | e_reg_post, e_pre | e_post, 3); - CHAINTEST2("1 both, 1 pre", "{\"sloppy\":{},\"pre\":{}}", /* Two, both then pre */ - e_reg_pre | e_reg_post, e_pre | e_post | e_dtor, e_reg_pre, e_pre, 3); - CHAINTEST2("1 post, 1 both", "{\"post\":{},\"sloppy\":{}}", /* Two, post then both */ - e_reg_post, e_post, e_reg_pre | e_reg_post, e_pre | e_post | e_dtor, 3); - CHAINTEST2("1 both, 1 post", "{\"sloppy\":{},\"post\":{}}", /* Two, both then post */ - e_reg_pre | e_reg_post, e_pre | e_post | e_dtor, e_reg_post, e_post, 3); - - /* Plugins dropping updates */ - drop = 0; - CHAINTEST2("2 both (drop at 0)", "{\"sloppy\":{},\"sloppy\":{}}", /* Two, both chains, drop at filter 0 */ - e_reg_pre | e_reg_post, e_pre, e_reg_pre | e_reg_post, 0, -1); - drop = 1; - CHAINTEST2("2 both (drop at 1)", "{\"sloppy\":{},\"sloppy\":{}}", /* Two, both chains, drop at filter 1 */ - e_reg_pre | e_reg_post, e_pre, e_reg_pre | e_reg_post, e_pre, -1); - drop = 2; - CHAINTEST2("2 both (drop at 2)", "{\"sloppy\":{},\"sloppy\":{}}", /* Two, both chains, drop at filter 2 */ - e_reg_pre | e_reg_post, e_pre | e_post, e_reg_pre | e_reg_post, e_pre, -1); - drop = 3; - CHAINTEST2("2 both (drop at 3)", "{\"sloppy\":{},\"sloppy\":{}}", /* Two, both chains, drop at filter 3 */ - e_reg_pre | e_reg_post, e_pre | e_post, e_reg_pre | e_reg_post, e_pre | e_post, -1); - drop = -1; - - dbFreeBase(pdbbase); - registryFree(); - pdbbase = NULL; - - return testDone(); -} diff --git a/src/ioc/db/test/dbBadLink.db b/src/ioc/db/test/dbBadLink.db deleted file mode 100644 index 6c41e854b..000000000 --- a/src/ioc/db/test/dbBadLink.db +++ /dev/null @@ -1,16 +0,0 @@ -# The records in this file have intentional -# syntax error in their input links - -record(x, "eVME_IO1") { - field(DTYP, "Unit Test VME_IO") - field(INP, "C100 S101 @parm VME_IO") -} -record(x, "eVME_IO2") { - field(DTYP, "Unit Test VME_IO") - field(INP, "#C200 201 @parm VME_IO") -} - -record(x, "eINST_IO") { - field(DTYP, "Unit Test INST_IO") - field(INP, "hello") -} diff --git a/src/ioc/db/test/dbCACTest.cpp b/src/ioc/db/test/dbCACTest.cpp deleted file mode 100644 index 4343ce5c0..000000000 --- a/src/ioc/db/test/dbCACTest.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ -/* - * Part of dbCaLinkTest, compiled seperately to avoid - * dbAccess.h vs. db_access.h conflicts - */ - -#include - -#include -#include - -#include - -#include "epicsUnitTest.h" - -#include "cadef.h" - -#define testECA(OP) if((OP)!=ECA_NORMAL) {testAbort("%s", #OP);} else {testPass("%s", #OP);} - -void putgetarray(chid chanid, double first, size_t count) -{ - testDiag("putgetarray(%f,%u)", first, (unsigned)count); - - std::vector buf(count); - for(size_t i=0; i buf2(count); - - testECA(ca_array_get(DBR_DOUBLE, count, chanid, &buf2[0])); - - testECA(ca_pend_io(1.0)); - - for(size_t i=0; i - */ - -#include -#include -#include - -#define EPICS_DBCA_PRIVATE_API - -#include "epicsString.h" -#include "dbUnitTest.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsEvent.h" -#include "iocInit.h" -#include "dbBase.h" -#include "link.h" -#include "dbAccess.h" -#include "epicsStdio.h" -#include "dbEvent.h" - -/* Declarations from cadef.h and db_access.h which we can't include here */ -typedef void * chid; -epicsShareExtern const unsigned short dbr_value_size[]; -epicsShareExtern short epicsShareAPI ca_field_type (chid chan); -#define MAX_UNITS_SIZE 8 - -#include "dbCaPvt.h" -#include "errlog.h" -#include "testMain.h" - -#include "xRecord.h" -#include "arrRecord.h" - -#define testOp(FMT,A,OP,B) testOk((A)OP(B), #A " ("FMT") " #OP " " #B " ("FMT")", A,B) - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static epicsEventId waitEvent; -static unsigned waitCounter; - -static -void waitForUpdateN(DBLINK *plink, unsigned long n) -{ - while(dbCaGetUpdateCount(plink)val = val; - db_post_events(ptarg, &ptarg->val, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE); - dbScanUnlock((dbCommon*)ptarg); - - epicsThreadSleep(0.1); - } - - if (waitEvent) - epicsEventMustTrigger(waitEvent); -} - -static void testNativeLink(void) -{ - xRecord *psrc, *ptarg; - DBLINK *psrclnk; - epicsInt32 temp; - long nReq; - - testDiag("Link to a scalar numeric field"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbCaLinkTest1.db", NULL, "TARGET=target CA"); - - eltc(0); - testIocInitOk(); - eltc(1); - - psrc = (xRecord*)testdbRecordPtr("source"); - ptarg= (xRecord*)testdbRecordPtr("target"); - psrclnk = &psrc->lnk; - - /* ensure this is really a CA link */ - testOk1(dbLockGetLockId((dbCommon*)psrc)!=dbLockGetLockId((dbCommon*)ptarg)); - - testOk1(psrclnk->type==CA_LINK); - - waitForUpdateN(psrclnk, 1); - - dbScanLock((dbCommon*)ptarg); - ptarg->val = 42; - db_post_events(ptarg, &ptarg->val, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE); - dbScanUnlock((dbCommon*)ptarg); - - waitForUpdateN(psrclnk, 2); - - dbScanLock((dbCommon*)psrc); - /* local CA_LINK connects immediately */ - testOk1(dbCaIsLinkConnected(psrclnk)); - nReq = 422; - testOk1(dbCaGetNelements(psrclnk, &nReq)==0); - testOp("%ld",nReq,==,1l); - - nReq = 1; - temp = 0x0f0f0f0f; - testOk1(dbGetLink(psrclnk, DBR_LONG, (void*)&temp, NULL, &nReq)==0); - testOp("%d",temp,==,42); - dbScanUnlock((dbCommon*)psrc); - - temp = 1010; - nReq = 1; - putLink(psrclnk, DBR_LONG, (void*)&temp, nReq); - - dbScanLock((dbCommon*)ptarg); - testOk1(ptarg->val==1010); - dbScanUnlock((dbCommon*)ptarg); - - assert(!waitEvent); - waitEvent = epicsEventMustCreate(epicsEventEmpty); - - /* Start counter */ - epicsThreadCreate("countUp", epicsThreadPriorityHigh, - epicsThreadGetStackSize(epicsThreadStackSmall), countUp, ptarg); - - dbScanLock((dbCommon*)psrc); - /* Check that unlocked gets change */ - temp = getTwice(psrclnk, NULL); - testOk(temp == -1, "unlocked, getTwice returned %d (-1)", temp); - - /* Check locked gets are atomic */ - temp = dbLinkDoLocked(psrclnk, getTwice, NULL); - testOk(temp == 0, "locked, getTwice returned %d (0)", temp); - dbScanUnlock((dbCommon*)psrc); - - epicsEventMustWait(waitEvent); - epicsEventDestroy(waitEvent); - waitEvent = NULL; - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testStringLink(void) -{ - xRecord *psrc, *ptarg; - DBLINK *psrclnk; - char temp[MAX_STRING_SIZE]; - long nReq; - - testDiag("Link to a string field"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbCaLinkTest1.db", NULL, "TARGET=target.DESC CA"); - - eltc(0); - testIocInitOk(); - eltc(1); - - psrc = (xRecord*)testdbRecordPtr("source"); - ptarg= (xRecord*)testdbRecordPtr("target"); - psrclnk = &psrc->lnk; - - /* ensure this is really a CA link */ - testOk1(dbLockGetLockId((dbCommon*)psrc)!=dbLockGetLockId((dbCommon*)ptarg)); - - testOk1(psrclnk->type==CA_LINK); - - waitForUpdateN(psrclnk, 1); - - dbScanLock((dbCommon*)ptarg); - strcpy(ptarg->desc, "hello"); - db_post_events(ptarg, &ptarg->desc, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE); - dbScanUnlock((dbCommon*)ptarg); - - waitForUpdateN(psrclnk, 2); - - dbScanLock((dbCommon*)psrc); - /* local CA_LINK connects immediately */ - testOk1(dbCaIsLinkConnected(psrclnk)); - - nReq = 1; - memset(temp, '!', sizeof(temp)); - testOk1(dbGetLink(psrclnk, DBR_STRING, (void*)&temp, NULL, &nReq)==0); - testOk(strcmp(temp, "hello")==0, "%s == hello", temp); - dbScanUnlock((dbCommon*)psrc); - - strcpy(temp, "world"); - putLink(psrclnk, DBR_STRING, (void*)&temp, nReq); - - dbScanLock((dbCommon*)ptarg); - testOk(strcmp(ptarg->desc, "world")==0, "%s == world", ptarg->desc); - dbScanUnlock((dbCommon*)ptarg); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void wasproc(xRecord *prec) -{ - waitCounter++; - epicsEventTrigger(waitEvent); -} - -static void testCP(void) -{ - xRecord *psrc, *ptarg; - - testDiag("Link CP modifier"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbCaLinkTest1.db", NULL, "TARGET=target CP"); - - psrc = (xRecord*)testdbRecordPtr("source"); - ptarg= (xRecord*)testdbRecordPtr("target"); - - /* hook in before IOC init */ - waitCounter=0; - psrc->clbk = &wasproc; - - assert(!waitEvent); - waitEvent = epicsEventMustCreate(epicsEventEmpty); - - eltc(0); - testIocInitOk(); - eltc(1); - dbCaSync(); - - epicsEventMustWait(waitEvent); - - dbScanLock((dbCommon*)psrc); - testOp("%u",waitCounter,==,1); /* initial processing */ - dbScanUnlock((dbCommon*)psrc); - - dbScanLock((dbCommon*)ptarg); - ptarg->val = 42; - db_post_events(ptarg, &ptarg->val, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE); - dbScanUnlock((dbCommon*)ptarg); - - epicsEventMustWait(waitEvent); - - dbScanLock((dbCommon*)psrc); - testOp("%u",waitCounter,==,2); /* process due to monitor update */ - dbScanUnlock((dbCommon*)psrc); - - testIocShutdownOk(); - - testdbCleanup(); - - epicsEventDestroy(waitEvent); - waitEvent = NULL; -} - -static void fillArray(epicsInt32 *buf, unsigned count, epicsInt32 first) -{ - for(;count;count--,first++) - *buf++ = first; -} - -static void fillArrayDouble(double *buf, unsigned count, double first) -{ - for(;count;count--,first++) - *buf++ = first; -} - -static void checkArray(const char *msg, - epicsInt32 *buf, epicsInt32 first, - unsigned used) -{ - int match = 1; - unsigned i; - epicsInt32 x, *b; - - for(b=buf,x=first,i=0;ivalue.pv_link.pvt; - - if(lnk->type!=CA_LINK || !pca->pputNative) - return; - epicsMutexMustLock(pca->lock); - memset(pca->pputNative, '!', - pca->nelements*dbr_value_size[ca_field_type(pca->chid)]); - epicsMutexUnlock(pca->lock); -} - -static void testArrayLink(unsigned nsrc, unsigned ntarg) -{ - char buf[100]; - arrRecord *psrc, *ptarg; - DBLINK *psrclnk; - epicsInt32 *bufsrc, *buftarg, *tmpbuf; - long nReq; - unsigned num_min, num_max; - - testDiag("Link to a array numeric field"); - - /* source.INP = "target CA" */ - epicsSnprintf(buf, sizeof(buf), "TARGET=target CA,FTVL=LONG,SNELM=%u,TNELM=%u", - nsrc, ntarg); - testDiag("%s", buf); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbCaLinkTest2.db", NULL, buf); - - psrc = (arrRecord*)testdbRecordPtr("source"); - ptarg= (arrRecord*)testdbRecordPtr("target"); - psrclnk = &psrc->inp; - - eltc(0); - testIocInitOk(); - eltc(1); - - waitForUpdateN(psrclnk, 1); - - bufsrc = psrc->bptr; - buftarg= ptarg->bptr; - - num_max=num_min=psrc->nelm; - if(num_min>ptarg->nelm) - num_min=ptarg->nelm; - if(num_maxnelm) - num_max=ptarg->nelm; - /* always request more than can possibly be filled */ - num_max += 2; - - tmpbuf = callocMustSucceed(num_max, sizeof(*tmpbuf), "tmpbuf"); - - dbScanLock((dbCommon*)ptarg); - fillArray(buftarg, ptarg->nelm, 1); - ptarg->nord = ptarg->nelm; - db_post_events(ptarg, ptarg->bptr, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE); - dbScanUnlock((dbCommon*)ptarg); - - waitForUpdateN(psrclnk, 2); - - dbScanLock((dbCommon*)psrc); - testDiag("fetch source.INP into source.BPTR"); - nReq = psrc->nelm; - if(dbGetLink(psrclnk, DBR_LONG, bufsrc, NULL, &nReq)==0) { - testPass("dbGetLink"); - testOp("%ld",nReq,==,(long)num_min); - checkArray("array update", bufsrc, 1, nReq); - } else { - testFail("dbGetLink"); - testSkip(2, "dbGetLink fails"); - } - testDiag("fetch source.INP into temp buffer w/ larger capacity"); - nReq = num_max; - if(dbGetLink(psrclnk, DBR_LONG, tmpbuf, NULL, &nReq)==0) { - testPass("dbGetLink"); - testOp("%ld",nReq,==,(long)ntarg); - checkArray("array update", tmpbuf, 1, nReq); - } else { - testFail("dbGetLink"); - testSkip(2, "dbGetLink fails"); - } - dbScanUnlock((dbCommon*)psrc); - - fillArray(bufsrc, psrc->nelm, 2); - /* write buffer allocated on first put */ - putLink(psrclnk, DBR_LONG, bufsrc, psrc->nelm); - - dbScanLock((dbCommon*)ptarg); - testOp("%ld",(long)ptarg->nord,==,(long)num_min); - - dbScanUnlock((dbCommon*)ptarg); - - /* write again to ensure that buffer is completely updated */ - spoilputbuf(psrclnk); - fillArray(bufsrc, psrc->nelm, 3); - putLink(psrclnk, DBR_LONG, bufsrc, psrc->nelm); - - dbScanLock((dbCommon*)ptarg); - testOp("%ld",(long)ptarg->nord,==,(long)num_min); - checkArray("array update", buftarg, 3, num_min); - dbScanUnlock((dbCommon*)ptarg); - - testIocShutdownOk(); - - testdbCleanup(); - - free(tmpbuf); - /* records don't cleanup after themselves - * so do here to silence valgrind - */ - free(bufsrc); - free(buftarg); -} - - -static void softarr(arrRecord *prec) -{ - long nReq = prec->nelm; - long status = dbGetLink(&prec->inp, DBR_DOUBLE, prec->bptr, NULL, &nReq); - - if(status) { - testFail("dbGetLink() -> %ld", status); - } else { - testPass("dbGetLink() succeeds"); - prec->nord = nReq; - if(nReq>0) - testDiag("%s.VAL[0] - %f", prec->name, *(double*)prec->bptr); - } - waitCounter++; - epicsEventTrigger(waitEvent); -} - -static void testreTargetTypeChange(void) -{ - arrRecord *psrc, *ptarg1, *ptarg2; - double *bufsrc, *buftarg1; - epicsInt32 *buftarg2; - - testDiag("Retarget an link to a PV with a different type DOUBLE->LONG"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbCaLinkTest3.db", NULL, "NELM=5,TARGET=target1 CP"); - - psrc = (arrRecord*)testdbRecordPtr("source"); - ptarg1= (arrRecord*)testdbRecordPtr("target1"); - ptarg2= (arrRecord*)testdbRecordPtr("target2"); - - /* hook in before IOC init */ - waitCounter=0; - psrc->clbk = &softarr; - - assert(!waitEvent); - waitEvent = epicsEventMustCreate(epicsEventEmpty); - - eltc(0); - testIocInitOk(); - eltc(1); - - epicsEventMustWait(waitEvent); /* wait for initial processing */ - - bufsrc = psrc->bptr; - buftarg1= ptarg1->bptr; - buftarg2= ptarg2->bptr; - - testDiag("Update one with original target"); - - dbScanLock((dbCommon*)ptarg2); - fillArray(buftarg2, ptarg2->nelm, 2); - ptarg2->nord = ptarg2->nelm; - dbScanUnlock((dbCommon*)ptarg2); - - /* initialize buffers */ - dbScanLock((dbCommon*)ptarg1); - fillArrayDouble(buftarg1, ptarg1->nelm, 1); - ptarg1->nord = ptarg1->nelm; - db_post_events(ptarg1, ptarg1->bptr, DBE_VALUE|DBE_ALARM|DBE_ARCHIVE); - dbScanUnlock((dbCommon*)ptarg1); - - epicsEventMustWait(waitEvent); /* wait for update */ - - dbScanLock((dbCommon*)psrc); - testOp("%ld",(long)psrc->nord,==,(long)5); - checkArrayDouble("array update", bufsrc, 1, 5); - dbScanUnlock((dbCommon*)psrc); - - testDiag("Retarget"); - testdbPutFieldOk("source.INP", DBR_STRING, "target2 CP"); - - epicsEventMustWait(waitEvent); /* wait for update */ - - dbScanLock((dbCommon*)psrc); - testOp("%ld",(long)psrc->nord,==,(long)5); - checkArrayDouble("array update", bufsrc, 2, 5); - dbScanUnlock((dbCommon*)psrc); - - testIocShutdownOk(); - - testdbCleanup(); - - /* records don't cleanup after themselves - * so do here to silence valgrind - */ - free(bufsrc); - free(buftarg1); - free(buftarg2); -} - -void dbCaLinkTest_testCAC(void); - -static void testCAC(void) -{ - arrRecord *psrc, *ptarg1, *ptarg2; - double *bufsrc, *buftarg1; - epicsInt32 *buftarg2; - - testDiag("Check local CA through libca"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbCaLinkTest3.db", NULL, "NELM=5,TARGET=target1 CP"); - - psrc = (arrRecord*)testdbRecordPtr("source"); - ptarg1= (arrRecord*)testdbRecordPtr("target1"); - ptarg2= (arrRecord*)testdbRecordPtr("target2"); - - eltc(0); - testIocInitOk(); - eltc(1); - - bufsrc = psrc->bptr; - buftarg1= ptarg1->bptr; - buftarg2= ptarg2->bptr; - - dbCaLinkTest_testCAC(); - - testIocShutdownOk(); - - testdbCleanup(); - - /* records don't cleanup after themselves - * so do here to silence valgrind - */ - free(bufsrc); - free(buftarg1); - free(buftarg2); -} - -MAIN(dbCaLinkTest) -{ - testPlan(101); - testNativeLink(); - testStringLink(); - testCP(); - testArrayLink(1,1); - testArrayLink(10,1); - testArrayLink(1,10); - testArrayLink(10,10); - testreTargetTypeChange(); - testCAC(); - return testDone(); -} diff --git a/src/ioc/db/test/dbCaLinkTest1.db b/src/ioc/db/test/dbCaLinkTest1.db deleted file mode 100644 index aab5ceb86..000000000 --- a/src/ioc/db/test/dbCaLinkTest1.db +++ /dev/null @@ -1,5 +0,0 @@ -record(x, "target") {} - -record(x, "source") { - field(LNK, "$(TARGET)") -} diff --git a/src/ioc/db/test/dbCaLinkTest2.db b/src/ioc/db/test/dbCaLinkTest2.db deleted file mode 100644 index 9cfa4ba00..000000000 --- a/src/ioc/db/test/dbCaLinkTest2.db +++ /dev/null @@ -1,10 +0,0 @@ -record(arr, "target") { - field(FTVL, "$(TFTVL=$(FTVL=))") - field(NELM, "$(TNELM=$(NELM=))") -} - -record(arr, "source") { - field(INP, "$(TARGET)") - field(FTVL, "$(SFTVL=$(FTVL=))") - field(NELM, "$(SNELM=$(NELM=))") -} diff --git a/src/ioc/db/test/dbCaLinkTest3.db b/src/ioc/db/test/dbCaLinkTest3.db deleted file mode 100644 index f820bd554..000000000 --- a/src/ioc/db/test/dbCaLinkTest3.db +++ /dev/null @@ -1,14 +0,0 @@ -record(arr, "target1") { - field(FTVL, "DOUBLE") - field(NELM, "$(TNELM=$(NELM=))") -} -record(arr, "target2") { - field(FTVL, "LONG") - field(NELM, "$(TNELM=$(NELM=))") -} - -record(arr, "source") { - field(INP, "$(TARGET)") - field(FTVL, "DOUBLE") - field(NELM, "$(SNELM=$(NELM=))") -} diff --git a/src/ioc/db/test/dbCaStats.db b/src/ioc/db/test/dbCaStats.db deleted file mode 100644 index bb909968e..000000000 --- a/src/ioc/db/test/dbCaStats.db +++ /dev/null @@ -1,4 +0,0 @@ -record(x, "e1") { -} -record(x, "e2") { -} diff --git a/src/ioc/db/test/dbCaStatsTest.c b/src/ioc/db/test/dbCaStatsTest.c deleted file mode 100644 index 020c65f10..000000000 --- a/src/ioc/db/test/dbCaStatsTest.c +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include "dbCaTest.h" -#include "dbAccess.h" - -#include "dbUnitTest.h" -#include "testMain.h" - -#include "dbAccess.h" -#include "errlog.h" - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static -void testCaStats(void) { - int channels; - int disconnected; - - testDiag("Check dbcaStats"); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbCaStats.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - - testDiag("No CA links"); - - channels = disconnected = -1; - dbcaStats(&channels, &disconnected); - - testOk(channels==0, "channels==0 (got %d)", channels); - testOk(disconnected==0, "disconnected==0 (got %d)", disconnected); - - - testDiag("One CA link, disconnected"); - - testdbPutFieldOk("e2.INP", DBR_STRING, "e12 CA", 1); - - channels = disconnected = -1; - dbcaStats(&channels, &disconnected); - - testOk(channels==1, "channels==1 (got %d)", channels); - testOk(disconnected==1, "disconnected==1 (got %d)", disconnected); - - /* Connected CA links can not be tested without fully starting the IOC - which we will skip for the moment as it is not allowed inside the vxWorks/RTEMS test harness. - The above is good enough to check for bug lp:1394212 */ - - testIocShutdownOk(); - - testdbCleanup(); -} - -MAIN(dbCaStatsTest) -{ - testPlan(5); - testCaStats(); - return testDone(); -} diff --git a/src/ioc/db/test/dbChArrTest.cpp b/src/ioc/db/test/dbChArrTest.cpp deleted file mode 100644 index 8a788bed6..000000000 --- a/src/ioc/db/test/dbChArrTest.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2003 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to the Software License Agreement -* found in the file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Authors: Ralph Lange , - * Andrew Johnson - */ - -#include -#include -#include -#include -#include - -#include "registryFunction.h" -#include "epicsThread.h" -#include "epicsExit.h" -#include "epicsStdio.h" -#include "epicsString.h" -#include "envDefs.h" -#include "dbStaticLib.h" -#include "dbmf.h" -#include "registry.h" -#include "dbAddr.h" -#include "dbAccess.h" -#include "asDbLib.h" -#include "iocInit.h" -#include "iocsh.h" -#include "dbChannel.h" -#include "epicsUnitTest.h" -#include "testMain.h" -#include "osiFileName.h" - -extern "C" { - int dbChArrTest_registerRecordDeviceDriver(struct dbBase *pdbbase); -} - -#define CA_SERVER_PORT "65535" - -const char *server_port = CA_SERVER_PORT; - -static void createAndOpen(const char *name, dbChannel**pch) -{ - testOk(!!(*pch = dbChannelCreate(name)), "dbChannel %s created", name); - testOk(!(dbChannelOpen(*pch)), "dbChannel opened"); - testOk((ellCount(&(*pch)->pre_chain) == 0), "no filters in pre chain"); - testOk((ellCount(&(*pch)->post_chain) == 0), "no filters in post chain"); -} - -extern "C" { -static void freeArray(db_field_log *pfl) { - if (pfl->type == dbfl_type_ref) { - free(pfl->u.r.field); - } -} -} - -static void testHead (const char *title, const char *typ = "") { - const char *line = "------------------------------------------------------------------------------"; - testDiag("%s", line); - testDiag(title, typ); - testDiag("%s", line); -} - -static void check(short dbr_type) { - dbChannel *pch; - db_field_log *pfl; - dbAddr valaddr; - dbAddr offaddr; - const char *offname = NULL, *valname = NULL, *typname = NULL; - epicsInt32 buf[26]; - long off, req; - int i; - - switch (dbr_type) { - case DBR_LONG: - offname = "i32.OFF"; - valname = "i32.VAL"; - typname = "long"; - break; - case DBR_DOUBLE: - offname = "f64.OFF"; - valname = "f64.VAL"; - typname = "double"; - break; - case DBR_STRING: - offname = "c40.OFF"; - valname = "c40.VAL"; - typname = "string"; - break; - default: - testDiag("Invalid data type %d", dbr_type); - } - - (void) dbNameToAddr(offname, &offaddr); - (void) dbNameToAddr(valname, &valaddr); - - testHead("Ten %s elements", typname); - - /* Fill the record's array field with data, 10..19 */ - - epicsInt32 ar[10] = {10,11,12,13,14,15,16,17,18,19}; - (void) dbPutField(&valaddr, DBR_LONG, ar, 10); - - /* Open a channel to it, make sure no filters present */ - - createAndOpen(valname, &pch); - testOk(pch->final_type == valaddr.field_type, - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); - testOk(pch->final_no_elements == valaddr.no_elements, - "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); - - /* TEST1 sets the record's OFF field, then requests 10 elements from the channel, - * passing in a transparent db_field_log and converting the data to LONG on the way in. - * It checks that it got back the expected data and the right number of elements. - */ - -#define TEST1(Size, Offset, Text, Expected) \ - testDiag("Reading from offset = %d (%s)", Offset, Text); \ - off = Offset; req = 10; \ - memset(buf, 0, sizeof(buf)); \ - (void) dbPutField(&offaddr, DBR_LONG, &off, 1); \ - pfl = db_create_read_log(pch); \ - testOk(pfl && pfl->type == dbfl_type_rec, "Valid pfl, type = rec"); \ - testOk(!dbChannelGetField(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \ - testOk(req == Size, "Got %ld elements (expected %d)", req, Size); \ - if (!testOk(!memcmp(buf, Expected, sizeof(Expected)), "Data correct")) \ - for (i=0; ifinal_type == valaddr.field_type, - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); - testOk(pch->final_no_elements == valaddr.no_elements, - "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); - - const epicsInt32 res_5_0[] = {15,16,17,18,19}; - TEST1(5, 0, "no offset", res_5_0); - - const epicsInt32 res_5_3[] = {18,19,15,16,17}; - TEST1(5, 3, "wrapped", res_5_3); - - /* TEST2 sets the record's OFF field, then requests 15 elements from the channel - * but passes in a db_field_log with alternate data, converting that data to LONG. - * It checks that it got back the expected data and the right number of elements. - */ - -#define TEST2(Size, Offset, Text, Expected) \ - testDiag("Reading from offset = %d (%s)", Offset, Text); \ - off = Offset; req = 15; \ - memset(buf, 0, sizeof(buf)); \ - (void) dbPutField(&offaddr, DBR_LONG, &off, 1); \ - pfl = db_create_read_log(pch); \ - pfl->type = dbfl_type_ref; \ - pfl->field_type = DBF_CHAR; \ - pfl->field_size = 1; \ - pfl->no_elements = 26; \ - pfl->u.r.dtor = freeArray; \ - pfl->u.r.field = epicsStrDup("abcdefghijklmnopqrsstuvwxyz"); \ - testOk(!dbChannelGetField(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \ - testOk(req == Size, "Got %ld elements (expected %d)", req, Size); \ - if (!testOk(!memcmp(buf, Expected, sizeof(Expected)), "Data correct")) \ - for (i=0; i - * Ralph Lange - */ - -#include "dbChannel.h" -#include "dbStaticLib.h" -#include "dbAccessDefs.h" -#include "registry.h" -#include "recSup.h" -#include "dbUnitTest.h" -#include "testMain.h" -#include "osiFileName.h" -#include "errlog.h" - -/* Expected call bit definitions */ -#define e_start 0x00000001 -#define e_abort 0x00000002 -#define e_end 0x00000004 -#define e_null 0x00000008 -#define e_boolean 0x00000010 -#define e_integer 0x00000020 -#define e_double 0x00000040 -#define e_string 0x00000080 -#define e_start_map 0x00000100 -#define e_map_key 0x00000200 -#define e_end_map 0x00000400 -#define e_start_array 0x00000800 -#define e_end_array 0x00001000 -#define e_open 0x00002000 -#define e_reg_pre 0x00004000 -#define e_reg_post 0x00008000 -#define e_report 0x00010000 -#define e_close 0x00020000 - -#define r_any (e_start | e_abort | e_end | \ - e_null | e_boolean | e_integer | e_double | e_string | \ - e_start_map | e_map_key | e_end_map | e_start_array | e_end_array) -#define r_scalar (e_start | e_abort | e_end | \ - e_null | e_boolean | e_integer | e_double | e_string) - -unsigned int e, r; -#define p_ret(x) return r & x ? parse_continue : parse_stop - -parse_result p_start(chFilter *filter) -{ - testOk(e & e_start, "parse_start called"); - p_ret(e_start); -} - -void p_abort(chFilter *filter) -{ - testOk(e & e_abort, "parse_abort called"); -} - -parse_result p_end(chFilter *filter) -{ - testOk(e & e_end, "parse_end called"); - p_ret(e_end); -} - -parse_result p_null(chFilter *filter) -{ - testOk(e & e_null, "parse_null called"); - p_ret(e_null); -} -parse_result p_boolean(chFilter *filter, int boolVal) -{ - testOk(e & e_boolean, "parse_boolean called, val = %d", boolVal); - p_ret(e_boolean); -} -parse_result p_integer(chFilter *filter, long integerVal) -{ - testOk(e & e_integer, "parse_integer called, val = %ld", integerVal); - p_ret(e_integer); -} -parse_result p_double(chFilter *filter, double doubleVal) -{ - testOk(e & e_double, "parse_double called, val = %g", doubleVal); - p_ret(e_double); -} -parse_result p_string(chFilter *filter, const char *stringVal, size_t stringLen) -{ - testOk(e & e_string, "parse_string called, val = '%.*s'", (int) stringLen, - stringVal); - p_ret(e_string); -} - -parse_result p_start_map(chFilter *filter) -{ - testOk(e & e_start_map, "parse_start_map called"); - p_ret(e_start_map); -} -parse_result p_map_key(chFilter *filter, const char *key, size_t stringLen) -{ - testOk(e & e_map_key, "parse_map_key called, key = '%.*s'", (int) stringLen, key); - p_ret(e_map_key); -} -parse_result p_end_map(chFilter *filter) -{ - testOk(e & e_end_map, "parse_end_map called"); - p_ret(e_end_map); -} - -parse_result p_start_array(chFilter *filter) -{ - testOk(e & e_start_array, "parse_start_array called"); - p_ret(e_start_array); -} -parse_result p_end_array(chFilter *filter) -{ - testOk(e & e_end_array, "parse_end_array called"); - p_ret(e_end_array); -} - -long c_open(chFilter *filter) -{ - testOk(e & e_open, "channel_open called"); - return 0; -} -void c_reg_pre(chFilter *filter, chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - testOk(e & e_reg_pre, "channel_register_pre called"); -} -void c_reg_post(chFilter *filter, chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - testOk(e & e_reg_post, "channel_register_post called"); -} -void c_report(chFilter *filter, int level, const unsigned short indent) -{ - testOk(e & e_report, "channel_report called, level = %d", level); -} -void c_close(chFilter *filter) -{ - testOk(e & e_close, "channel_close called"); -} - -chFilterIf testIf = - { NULL, p_start, p_abort, p_end, p_null, p_boolean, p_integer, p_double, - p_string, p_start_map, p_map_key, p_end_map, p_start_array, p_end_array, - c_open, c_reg_pre, c_reg_post, c_report, c_close }; - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -MAIN(testDbChannel) /* dbChannelTest is an API routine... */ -{ - dbChannel *pch; - - testPlan(76); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("xRecord.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - r = e = 0; - /* dbChannelTest() checks record and field names */ - testOk1(!dbChannelTest("x.NAME")); - testOk1(!dbChannelTest("x.INP")); - testOk1(!dbChannelTest("x.VAL")); - testOk1(!dbChannelTest("x.")); - testOk1(!dbChannelTest("x")); - testOk(dbChannelTest("y"), "Test, nonexistent record"); - testOk(dbChannelTest("x.NOFIELD"), "Test, nonexistent field"); - - /* dbChannelTest() allows but ignores field modifiers */ - testOk1(!dbChannelTest("x.NAME$")); - testOk1(!dbChannelTest("x.{}")); - testOk1(!dbChannelTest("x.VAL{\"json\":true}")); - - /* dbChannelCreate() accepts field modifiers */ - testOk1(!!(pch = dbChannelCreate("x.{}"))); - if (pch) dbChannelDelete(pch); - testOk1(!!(pch = dbChannelCreate("x.VAL{}"))); - testOk1(pch && dbChannelElements(pch) == 1); - if (pch) dbChannelDelete(pch); - testOk1(!!(pch = dbChannelCreate("x.NAME$"))); - testOk1(pch && dbChannelFieldType(pch) == DBF_CHAR); - testOk1(pch && dbChannelExportType(pch) == DBR_CHAR); - testOk1(pch && dbChannelElements(pch) == PVNAME_STRINGSZ); - if (pch) dbChannelDelete(pch); - testOk1(!!(pch = dbChannelCreate("x.INP$"))); - testOk1(pch && dbChannelFieldType(pch) == DBF_INLINK); - testOk1(pch && dbChannelExportType(pch) == DBR_CHAR); - testOk1(pch && dbChannelElements(pch) > PVNAME_STRINGSZ); - if (pch) dbChannelDelete(pch); - testOk1(!!(pch = dbChannelCreate("x.NAME${}"))); - testOk1(pch && dbChannelFieldType(pch) == DBF_CHAR); - testOk1(pch && dbChannelExportType(pch) == DBR_CHAR); - testOk1(pch && dbChannelElements(pch) == PVNAME_STRINGSZ); - if (pch) dbChannelDelete(pch); - - /* dbChannelCreate() rejects bad PVs */ - testOk(!dbChannelCreate("y"), "Create, bad record"); - testOk(!dbChannelCreate("x.NOFIELD"), "Create, bad field"); - testOk(!dbChannelCreate("x.{not-json}"), "Create, bad JSON"); - eltc(0); - testOk(!dbChannelCreate("x.{\"none\":null}"), "Create, bad filter"); - eltc(1); - - dbRegisterFilter("any", &testIf, NULL); - - /* Parser event rejection by filter */ - e = e_start; - testOk1(!dbChannelCreate("x.{\"any\":null}")); - - r = e_start; - e = e_start | e_null | e_abort; - testOk1(!dbChannelCreate("x.{\"any\":null}")); - - r = e_start | e_null; - e = e_start | e_null | e_end; - testOk1(!dbChannelCreate("x.{\"any\":null}")); - - /* Successful parsing... */ - r = r_any; - e = e_start | e_null | e_end; - testOk1(!!(pch = dbChannelCreate("x.{\"any\":null}"))); - e = e_close; - if (pch) dbChannelDelete(pch); - - dbRegisterFilter("scalar", &testIf, NULL); - - e = e_start | e_null | e_end; - testOk1(!!(pch = dbChannelCreate("x.{\"scalar\":null}"))); - - e = e_report; - dbChannelShow(pch, 2, 2); - - e = e_close; - if (pch) dbChannelDelete(pch); - - e = e_start | e_start_array | e_boolean | e_integer | e_end_array - | e_end; - testOk1(!!(pch = dbChannelCreate("x.{\"any\":[true,1]}"))); - e = e_close; - if (pch) dbChannelDelete(pch); - - e = e_start | e_start_map | e_map_key | e_double | e_string | e_end_map - | e_end; - testOk1(!!(pch = dbChannelCreate("x.{\"any\":{\"a\":2.7183,\"b\":\"c\"}}"))); - e = e_close; - if (pch) dbChannelDelete(pch); - - /* More event rejection */ - r = r_scalar; - e = e_start | e_start_array | e_abort; - testOk1(!dbChannelCreate("x.{\"scalar\":[null]}")); - - e = e_start | e_start_map | e_abort; - testOk1(!dbChannelCreate("x.{\"scalar\":{}}")); - - testIocShutdownOk(); - testdbCleanup(); - - return testDone(); -} diff --git a/src/ioc/db/test/dbLinkdset.c b/src/ioc/db/test/dbLinkdset.c deleted file mode 100644 index d7b8230f0..000000000 --- a/src/ioc/db/test/dbLinkdset.c +++ /dev/null @@ -1,41 +0,0 @@ - -#include - -#include - -#include - -static -long link_test_extend(struct dbCommon *junk) -{ return 0; } - -static dsxt xrecextend = {&link_test_extend, &link_test_extend}; - -static -long link_test_init(int pass) -{ - if (pass == 0) - devExtend(&xrecextend); - return 0; -} - -static -long link_test_noop(void *junk) -{ return 0; } - - - -#define DEFDSET(LTYPE) \ - static dset devxLTest ## LTYPE = {4, NULL, &link_test_init, &link_test_noop, &link_test_noop}; \ - epicsExportAddress(dset, devxLTest ## LTYPE); - -DEFDSET(JSON_LINK) -DEFDSET(VME_IO) -DEFDSET(CAMAC_IO) -DEFDSET(AB_IO) -DEFDSET(GPIB_IO) -DEFDSET(BITBUS_IO) -DEFDSET(INST_IO) -DEFDSET(BBGPIB_IO) -DEFDSET(RF_IO) -DEFDSET(VXI_IO) diff --git a/src/ioc/db/test/dbLinkdset.dbd b/src/ioc/db/test/dbLinkdset.dbd deleted file mode 100644 index da2d4d946..000000000 --- a/src/ioc/db/test/dbLinkdset.dbd +++ /dev/null @@ -1,10 +0,0 @@ -device(x, JSON_LINK, devxLTestJSON_LINK, "Unit Test JSON_LINK") -device(x, VME_IO, devxLTestVME_IO, "Unit Test VME_IO") -device(x, CAMAC_IO, devxLTestCAMAC_IO, "Unit Test CAMAC_IO") -device(x, AB_IO, devxLTestAB_IO, "Unit Test AB_IO") -device(x, GPIB_IO, devxLTestGPIB_IO, "Unit Test GPIB_IO") -device(x, BITBUS_IO, devxLTestBITBUS_IO, "Unit Test BITBUS_IO") -device(x, INST_IO, devxLTestINST_IO, "Unit Test INST_IO") -device(x, BBGPIB_IO, devxLTestBBGPIB_IO, "Unit Test BBGPIB_IO") -device(x, RF_IO, devxLTestRF_IO, "Unit Test RF_IO") -device(x, VXI_IO, devxLTestVXI_IO, "Unit Test VXI_IO") diff --git a/src/ioc/db/test/dbLockTest.c b/src/ioc/db/test/dbLockTest.c deleted file mode 100644 index 39e21a650..000000000 --- a/src/ioc/db/test/dbLockTest.c +++ /dev/null @@ -1,431 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - */ - -#include - -#include "epicsSpin.h" -#include "epicsMutex.h" -#include "dbCommon.h" -#include "epicsThread.h" - -#include "dbLockPvt.h" -#include "dbStaticLib.h" - -#include "dbUnitTest.h" -#include "testMain.h" - -#include "dbAccess.h" -#include "errlog.h" - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static -void compareSets(int match, const char *A, const char *B) -{ - int actual; - dbCommon *rA, *rB; - - rA = testdbRecordPtr(A); - rB = testdbRecordPtr(B); - - actual = rA->lset->plockSet==rB->lset->plockSet; - - testOk(match==actual, "dbLockGetLockId(\"%s\")%c=dbLockGetLockId(\"%s\")", - A, match?'=':'!', B); -} - -#define testIntOk1(A, OP, B) testOk((A) OP (B), "%s (%d) %s %s (%d)", #A, A, #OP, #B, B); -#define testPtrOk1(A, OP, B) testOk((A) OP (B), "%s (%p) %s %s (%p)", #A, A, #OP, #B, B); - -static -void testSets(void) { - DBENTRY entry; - long status; - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbLockTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - testDiag("Check that all records have initialized lockRecord and lockSet"); - - dbInitEntry(pdbbase, &entry); - for(status = dbFirstRecordType(&entry); - !status; - status = dbNextRecordType(&entry)) { - for(status = dbFirstRecord(&entry); - !status; - status = dbNextRecord(&entry)) { - dbCommon *prec = entry.precnode->precord; - testOk(prec->lset!=NULL, "%s.LSET != NULL", prec->name); - if(prec->lset!=NULL) - testOk(prec->lset->plockSet!=NULL, "%s.LSET.plockSet != NULL", prec->name); - else - testSkip(1, "lockRecord missing"); - } - } - dbFinishEntry(&entry); - - testDiag("Check initial creation of DB links"); - - /* reca is by itself */ - compareSets(0, "reca", "recb"); - compareSets(0, "reca", "recc"); - compareSets(0, "reca", "recd"); - compareSets(0, "reca", "rece"); - compareSets(0, "reca", "recf"); - - /* recb and recc should be in a lockset */ - compareSets(1, "recb", "recc"); - compareSets(0, "recb", "recd"); - compareSets(0, "recb", "rece"); - compareSets(0, "recb", "recf"); - - compareSets(0, "recc", "recd"); - compareSets(0, "recc", "rece"); - compareSets(0, "recc", "recf"); - - /* recd, e, and f should be in a lockset */ - compareSets(1, "recd", "rece"); - compareSets(1, "recd", "recf"); - - compareSets(1, "rece", "recf"); - - testOk1(testdbRecordPtr("reca")->lset->plockSet->refcount==1); - testOk1(testdbRecordPtr("recb")->lset->plockSet->refcount==2); - testOk1(testdbRecordPtr("recd")->lset->plockSet->refcount==3); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testSingleLock(void) -{ - dbCommon *prec; - testDiag("testing dbScanLock()/dbScanUnlock()"); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbLockTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - prec = testdbRecordPtr("reca"); - testOk1(prec->lset->plockSet->refcount==1); - dbScanLock(prec); - /* scan lock does not keep a reference to the lockSet */ - testOk1(prec->lset->plockSet->refcount==1); - dbScanUnlock(prec); - - dbScanLock(prec); - dbScanLock(prec); - /* scan lock can be recursive */ - testOk1(prec->lset->plockSet->refcount==1); - dbScanUnlock(prec); - dbScanUnlock(prec); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testMultiLock(void) -{ - dbCommon *prec[8]; - dbLocker *plockA; -#ifdef LOCKSET_DEBUG - epicsThreadId myself = epicsThreadGetIdSelf(); -#endif - - testDiag("Test multi-locker function (lock everything)"); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbLockTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - prec[0] = testdbRecordPtr("reca"); - prec[1] = testdbRecordPtr("recb"); - prec[2] = testdbRecordPtr("recc"); - prec[3] = NULL; - prec[4] = testdbRecordPtr("recd"); - prec[5] = testdbRecordPtr("rece"); - prec[6] = testdbRecordPtr("recf"); - prec[7] = testdbRecordPtr("recg"); - - testDiag("Test init refcounts"); - testIntOk1(testdbRecordPtr("reca")->lset->plockSet->refcount,==,1); - testIntOk1(testdbRecordPtr("recb")->lset->plockSet->refcount,==,2); - testIntOk1(testdbRecordPtr("recd")->lset->plockSet->refcount,==,3); - testIntOk1(testdbRecordPtr("recg")->lset->plockSet->refcount,==,1); - - plockA = dbLockerAlloc(prec, 8, 0); - if(!plockA) - testAbort("dbLockerAlloc() failed"); - - - testDiag("After locker created"); - /* locker takes 7 references, one for each lockRecord. */ - testIntOk1(testdbRecordPtr("reca")->lset->plockSet->refcount,==,2); - testIntOk1(testdbRecordPtr("recb")->lset->plockSet->refcount,==,4); - testIntOk1(testdbRecordPtr("recd")->lset->plockSet->refcount,==,6); - testIntOk1(testdbRecordPtr("recg")->lset->plockSet->refcount,==,2); -#ifdef LOCKSET_DEBUG - testPtrOk1(testdbRecordPtr("reca")->lset->plockSet->owner,==,NULL); - testPtrOk1(testdbRecordPtr("recb")->lset->plockSet->owner,==,NULL); - testPtrOk1(testdbRecordPtr("recd")->lset->plockSet->owner,==,NULL); - testPtrOk1(testdbRecordPtr("recg")->lset->plockSet->owner,==,NULL); -#endif - - dbScanLockMany(plockA); - - testDiag("After locker locked"); - /* locker takes 4 references, one for each lockSet. */ - testIntOk1(ellCount(&plockA->locked),==,4); - testIntOk1(testdbRecordPtr("reca")->lset->plockSet->refcount,==,3); - testIntOk1(testdbRecordPtr("recb")->lset->plockSet->refcount,==,5); - testIntOk1(testdbRecordPtr("recd")->lset->plockSet->refcount,==,7); - testIntOk1(testdbRecordPtr("recg")->lset->plockSet->refcount,==,3); -#ifdef LOCKSET_DEBUG - testPtrOk1(testdbRecordPtr("reca")->lset->plockSet->owner,==,myself); - testPtrOk1(testdbRecordPtr("recb")->lset->plockSet->owner,==,myself); - testPtrOk1(testdbRecordPtr("recd")->lset->plockSet->owner,==,myself); - testPtrOk1(testdbRecordPtr("recg")->lset->plockSet->owner,==,myself); -#endif - - /* recursive locking of individual records is allowed */ - dbScanLock(prec[0]); - testIntOk1(testdbRecordPtr("reca")->lset->plockSet->refcount,==,3); - dbScanUnlock(prec[0]); - - /* recursive locking with dbScanLockMany() isn't - * dbScanLockMany(plockA); <-- would fail - */ - - dbScanUnlockMany(plockA); - - testDiag("After locker unlocked"); - testIntOk1(testdbRecordPtr("reca")->lset->plockSet->refcount,==,2); - testIntOk1(testdbRecordPtr("recb")->lset->plockSet->refcount,==,4); - testIntOk1(testdbRecordPtr("recd")->lset->plockSet->refcount,==,6); - testIntOk1(testdbRecordPtr("recg")->lset->plockSet->refcount,==,2); -#ifdef LOCKSET_DEBUG - testPtrOk1(testdbRecordPtr("reca")->lset->plockSet->owner,==,NULL); - testPtrOk1(testdbRecordPtr("recb")->lset->plockSet->owner,==,NULL); - testPtrOk1(testdbRecordPtr("recd")->lset->plockSet->owner,==,NULL); - testPtrOk1(testdbRecordPtr("recg")->lset->plockSet->owner,==,NULL); -#endif - - dbLockerFree(plockA); - - testDiag("After locker free'd"); - testIntOk1(testdbRecordPtr("reca")->lset->plockSet->refcount,==,1); - testIntOk1(testdbRecordPtr("recb")->lset->plockSet->refcount,==,2); - testIntOk1(testdbRecordPtr("recd")->lset->plockSet->refcount,==,3); - testIntOk1(testdbRecordPtr("recg")->lset->plockSet->refcount,==,1); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testLinkBreak(void) -{ - dbCommon *precB, *precC; - testDiag("Test break link"); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbLockTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - precB = testdbRecordPtr("recb"); - precC = testdbRecordPtr("recc"); - - testOk1(precB->lset->plockSet==precC->lset->plockSet); - testOk1(precB->lset->plockSet->refcount==2); - - /* break the link between B and C */ - testdbPutFieldOk("recb.SDIS", DBR_STRING, ""); - - testOk1(precB->lset->plockSet!=precC->lset->plockSet); - testIntOk1(precB->lset->plockSet->refcount, ==, 1); - testIntOk1(precC->lset->plockSet->refcount, ==, 1); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testLinkMake(void) -{ - dbCommon *precA, *precG; - lockSet *lA, *lG; - testDiag("Test make link"); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbLockTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - precA = testdbRecordPtr("reca"); - lA = dbLockGetRef(precA->lset); - precG = testdbRecordPtr("recg"); - lG = dbLockGetRef(precG->lset); - - testPtrOk1(precA->lset->plockSet, !=, precG->lset->plockSet); - testIntOk1(precA->lset->plockSet->refcount, ==, 2); - testIntOk1(precG->lset->plockSet->refcount, ==, 2); - - /* make a link between A and G */ - testdbPutFieldOk("reca.SDIS", DBR_STRING, "recg"); - - testPtrOk1(precA->lset->plockSet, ==, precG->lset->plockSet); - testIntOk1(precA->lset->plockSet->refcount, ==, 3); - - if(precA->lset->plockSet==lG) { - testIntOk1(lA->refcount, ==, 1); - testIntOk1(lG->refcount, ==, 3); - } else { - testIntOk1(lA->refcount, ==, 3); - testIntOk1(lG->refcount, ==, 1); - } - dbLockDecRef(lG); - dbLockDecRef(lA); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testLinkChange(void) -{ - dbCommon *precB, *precC, *precG; - lockSet *lB, *lG; - testDiag("Test re-target link"); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbLockTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - precB = testdbRecordPtr("recb"); - precC = testdbRecordPtr("recc"); - precG = testdbRecordPtr("recg"); - - lB = dbLockGetRef(precB->lset); - lG = dbLockGetRef(precG->lset); - - testPtrOk1(lB,==,precC->lset->plockSet); - testPtrOk1(lB,!=,lG); - testIntOk1(lB->refcount,==,3); - testIntOk1(lG->refcount,==,2); - - /* break the link between B and C and replace it - * with a link between B and G - */ - testdbPutFieldOk("recb.SDIS", DBR_STRING, "recg"); - - testPtrOk1(precB->lset->plockSet,==,lB); - testPtrOk1(precG->lset->plockSet,==,lB); - testPtrOk1(precC->lset->plockSet,!=,lB); - testPtrOk1(precC->lset->plockSet,!=,lG); - - testIntOk1(lB->refcount,==,3); - testIntOk1(lG->refcount,==,1); - testIntOk1(precC->lset->plockSet->refcount,==,1); - - dbLockDecRef(lB); - dbLockDecRef(lG); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testLinkNOP(void) -{ - dbCommon *precB, *precC; - testDiag("Test re-target link to the same destination"); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbLockTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - precB = testdbRecordPtr("recb"); - precC = testdbRecordPtr("recc"); - - testOk1(precB->lset->plockSet==precC->lset->plockSet); - testOk1(precB->lset->plockSet->refcount==2); - - /* renew link between B and C */ - testdbPutFieldOk("recb.SDIS", DBR_STRING, "recc"); - - testOk1(precB->lset->plockSet==precC->lset->plockSet); - testOk1(precB->lset->plockSet->refcount==2); - - testIocShutdownOk(); - - testdbCleanup(); -} - -MAIN(dbLockTest) -{ -#ifdef LOCKSET_DEBUG - testPlan(100); -#else - testPlan(88); -#endif - testSets(); - testSingleLock(); - testMultiLock(); - testLinkBreak(); - testLinkMake(); - testLinkChange(); - testLinkNOP(); - return testDone(); -} diff --git a/src/ioc/db/test/dbLockTest.db b/src/ioc/db/test/dbLockTest.db deleted file mode 100644 index 37ff6022e..000000000 --- a/src/ioc/db/test/dbLockTest.db +++ /dev/null @@ -1,24 +0,0 @@ -record(x, "reca") { -} - -record(x, "recb") { - field(SDIS, "recc") -} - -record(x, "recc") { - field(SDIS, "recc") -} - -record(x, "recd") { - field(SDIS, "rece") -} - -record(x, "rece") { - field(SDIS, "recf") -} - -record(x, "recf") { -} - -record(x, "recg") { -} diff --git a/src/ioc/db/test/dbPutGetTest.c b/src/ioc/db/test/dbPutGetTest.c deleted file mode 100644 index 61b31a785..000000000 --- a/src/ioc/db/test/dbPutGetTest.c +++ /dev/null @@ -1,150 +0,0 @@ - -#include - -#include -#include -#include -#include -#include -#include - -static -void testdbGetStringEqual(const char *pv, const char *expected) -{ - const char *actual; - int ok; - DBENTRY ent; - - dbInitEntry(pdbbase, &ent); - - if(dbFindRecord(&ent, pv)) { - testFail("Failed to find record '%s'", pv); - return; - } - - actual = dbGetString(&ent); - ok = (!actual && !expected) - || (actual && expected && strcmp(actual, expected)==0); - - testOk(ok, "dbGetString(\"%s\") -> \"%s\" == \"%s\"", pv, actual, expected); - - dbFinishEntry(&ent); -} - -static -void testGetString(void) -{ - testDiag("testGetString()"); - - testdbGetStringEqual("recempty.DTYP", "Soft Channel"); - testdbGetStringEqual("recempty.DESC", ""); - testdbGetStringEqual("recempty.PHAS", "0"); - testdbGetStringEqual("recempty.TSE" , "0"); - testdbGetStringEqual("recempty.DISA", "0"); - testdbGetStringEqual("recempty.DISV", "0"); - - testdbGetStringEqual("recoverwrite.DTYP", "Soft Channel"); - testdbGetStringEqual("recoverwrite.DESC", ""); - testdbGetStringEqual("recoverwrite.PHAS", "0"); - testdbGetStringEqual("recoverwrite.TSE" , "0"); - testdbGetStringEqual("recoverwrite.DISA", "0"); - testdbGetStringEqual("recoverwrite.DISV", "0"); -} - -static -void testStringMax(void) -{ - testDiag("testStringMax()"); - - testdbGetStringEqual("recmax.DISA", "-1"); -} - -static -void testLongLink(void) -{ - testDiag("testLonkLink()"); - - testdbGetFieldEqual("lnktest.INP", DBR_STRING, "lnktarget NPP NMS"); - testdbGetFieldEqual("lnktest.INP$", DBR_STRING, "lnktarget NPP NMS"); - testDiag("dbGet() w/ nRequest==1 gets only trailing nil"); - testdbGetFieldEqual("lnktest.INP$", DBR_CHAR, '\0'); - testdbGetArrFieldEqual("lnktest.INP$", DBR_CHAR, 19, 18, "lnktarget NPP NMS"); - - testDiag("get w/ truncation"); - testdbGetArrFieldEqual("lnktest.INP$", DBR_CHAR, 0, 0, NULL); - testdbGetArrFieldEqual("lnktest.INP$", DBR_CHAR, 1, 1, ""); - testdbGetArrFieldEqual("lnktest.INP$", DBR_CHAR, 2, 2, "l"); - testdbGetArrFieldEqual("lnktest.INP$", DBR_CHAR, 3, 3, "ln"); - testdbGetArrFieldEqual("lnktest.INP$", DBR_CHAR, 17, 17, "lnktarget NPP NM"); - testdbGetArrFieldEqual("lnktest.INP$", DBR_CHAR, 18, 18, "lnktarget NPP NMS"); - - testdbGetArrFieldEqual("lnktest.INP", DBR_STRING, 2, 1, "lnktarget NPP NMS"); -} - -static -void testLongAttr(void) -{ - testDiag("testLongAttr()"); - - testdbGetFieldEqual("lnktest.RTYP", DBR_STRING, "x"); - testdbGetFieldEqual("lnktest.RTYP$", DBR_STRING, "x"); - testDiag("dbGet() w/ nRequest==1 gets only trailing nil"); - testdbGetFieldEqual("lnktest.RTYP$", DBR_CHAR, '\0'); - - testdbGetArrFieldEqual("lnktest.RTYP$", DBR_CHAR, 4, 2, "x"); - - testDiag("get w/ truncation"); - testdbGetArrFieldEqual("lnktest.RTYP$", DBR_CHAR, 0, 0, NULL); - testdbGetArrFieldEqual("lnktest.RTYP$", DBR_CHAR, 1, 1, ""); - testdbGetArrFieldEqual("lnktest.RTYP$", DBR_CHAR, 2, 2, "x"); -} - -static -void testLongField(void) -{ - testDiag("testLongField()"); - - testdbGetFieldEqual("lnktest.NAME", DBR_STRING, "lnktest"); - testdbGetFieldEqual("lnktest.NAME$", DBR_STRING, "108"); - testDiag("dbGet() w/ nRequest==1 gets only trailing nil"); - testdbGetFieldEqual("lnktest.NAME$", DBR_CHAR, '\0'); - testdbGetArrFieldEqual("lnktest.NAME$", DBR_CHAR, 10, 8, "lnktest"); - - testDiag("get w/ truncation"); - testdbGetArrFieldEqual("lnktest.NAME$", DBR_CHAR, 0, 0, NULL); - testdbGetArrFieldEqual("lnktest.NAME$", DBR_CHAR, 1, 1, ""); - testdbGetArrFieldEqual("lnktest.NAME$", DBR_CHAR, 2, 2, "l"); - testdbGetArrFieldEqual("lnktest.NAME$", DBR_CHAR, 3, 3, "ln"); - testdbGetArrFieldEqual("lnktest.NAME$", DBR_CHAR, 7, 7, "lnktes"); - testdbGetArrFieldEqual("lnktest.NAME$", DBR_CHAR, 8, 8, "lnktest"); -} - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -MAIN(dbPutGet) -{ - testPlan(41); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbPutGetTest.db", NULL, NULL); - - testGetString(); - - testStringMax(); - - eltc(0); - testIocInitOk(); - eltc(1); - - testLongLink(); - testLongAttr(); - testLongField(); - - testIocShutdownOk(); - - testdbCleanup(); - - return testDone(); -} diff --git a/src/ioc/db/test/dbPutGetTest.db b/src/ioc/db/test/dbPutGetTest.db deleted file mode 100644 index 793750e6e..000000000 --- a/src/ioc/db/test/dbPutGetTest.db +++ /dev/null @@ -1,41 +0,0 @@ - -record(x, "recempty") { -# empty string is the same "0" for numeric fields - field(DTYP, "") - field(DESC, "") - field(PHAS, "") - field(TSE , "") - field(DISA, "") - field(DISV, "") -} - -record(x, "recoverwrite") { -# first with non-default values - field(DTYP, "Scan I/O") - field(DESC, "hello") - field(PHAS, "2") - field(TSE , "5") - field(DISA, "6") - field(DISV, "7") -} - -record(x, "recoverwrite") { -# now restore default values - field(DTYP, "") - field(DESC, "") - field(PHAS, "") - field(TSE , "") - field(TSEL, "") - field(DISA, "") - field(DISV, "") -} - -record(x, "recmax") { - field(DISA, "0xffffffff") -} - -record(x, "lnktarget") {} - -record(x, "lnktest") { - field(INP, "lnktarget NPP NMS") -} diff --git a/src/ioc/db/test/dbPutLinkTest.c b/src/ioc/db/test/dbPutLinkTest.c deleted file mode 100644 index b39b98db2..000000000 --- a/src/ioc/db/test/dbPutLinkTest.c +++ /dev/null @@ -1,614 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - */ - -#include "string.h" - -#include "epicsString.h" -#include "dbUnitTest.h" -#include "epicsThread.h" -#include "iocInit.h" -#include "dbBase.h" -#include "link.h" -#include "dbAccess.h" -#include "registry.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "osiFileName.h" -#include "dbmf.h" -#include "errlog.h" -#include - -#include "xRecord.h" -#include "jlinkz.h" - -#include "testMain.h" - -static -int testStrcmp(int expect, const char *A, const char *B) { - static const char op[] = "<=>"; - int ret = strcmp(A,B); - testOk(ret==expect, "\"%s\" %c= \"%s\"", - A, op[expect+1], B); - return ret==expect; -} - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -#define TEST_CONSTANT(SET, EXPECT) {SET, {CONSTANT, EXPECT}} -#define TEST_PV_LINK(SET, PV, MOD) {SET, {PV_LINK, PV, MOD}} - -static const struct testParseDataT { - const char * const str; - dbLinkInfo info; -} testParseData[] = { - TEST_CONSTANT("", ""), - TEST_CONSTANT("0.1", "0.1"), - TEST_CONSTANT(" 0.2\t ", "0.2"), - - TEST_PV_LINK("0.1a", "0.1a", 0), - TEST_PV_LINK(" hello ", "hello", 0), - TEST_PV_LINK(" hellox MSI", "hellox", pvlOptMSI), - TEST_PV_LINK(" world MSICP", "world", pvlOptMSI|pvlOptCP), - - {"#C14 S145 @testing", {VME_IO, "testing", 0, "CS", {14, 145}}}, - {"#B11 C12 N13 A14 F15 @cparam", {CAMAC_IO, "cparam", 0, "BCNAF", {11, 12, 13, 14, 15}}}, - {" #B111 C112 N113 @cparam", {CAMAC_IO, "cparam", 0, "BCN", {111, 112, 113}}}, - {" @hello world ", {INST_IO, "hello world", 0, "", /*{}*/}}, - {" {\"x\":true} ", {JSON_LINK, "{\"x\":true}", 0, "", /*{}*/}}, - {NULL} -}; - -static void testLinkParse(void) -{ - const struct testParseDataT *td = testParseData; - dbLinkInfo info; - testDiag("\n# Checking link parsing\n#"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbPutLinkTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - for (;td->str; td++) { - int i, N; - testDiag("Parsing \"%s\"", td->str); - testOk(dbParseLink(td->str, DBF_INLINK, &info, 0) == 0, "Parser returned OK"); - if (!testOk(info.ltype == td->info.ltype, "Link type value")) - testDiag("Expected %d, got %d", td->info.ltype, info.ltype); - if (td->info.target) - testStrcmp(0, info.target, td->info.target); - if (info.ltype == td->info.ltype) { - switch (info.ltype) { - case PV_LINK: - if (!testOk(info.modifiers == td->info.modifiers, - "PV Link modifier flags")) - testDiag("Expected %d, got %d", td->info.modifiers, - info.modifiers); - break; - case VME_IO: - case CAMAC_IO: - testStrcmp(0, info.hwid, td->info.hwid); - N = strlen(td->info.hwid); - for (i=0; iinfo.hwnums[i], "%d == %d", - info.hwnums[i], td->info.hwnums[i]); - } - } - dbFreeLinkInfo(&info); - } - - testIocShutdownOk(); - - testdbCleanup(); -} - -static const char *testParseFailData[] = { - "#", - "#S", - "#ABC", - "#A0 B", - "#A0 B @", - "#A0 B C @", - "#R1 M2 D3 E4 @oops", /* RF_IO has no parm */ - "#C1 S2", /* VME_IO needs parm */ - NULL -}; - -static void testLinkFailParse(void) -{ - const char * const *td = testParseFailData; - dbLinkInfo info; - testDiag("\n# Check parsing of invalid inputs\n#"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbPutLinkTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - for(;*td; td++) { - testOk(dbParseLink(*td, DBF_INLINK, &info, 0) == S_dbLib_badField, - "dbParseLink correctly rejected \"%s\"", *td); - } - - testIocShutdownOk(); - - testdbCleanup(); -} - -static const struct testDataT { - const char * const linkstring; - short linkType; - unsigned int pvlMask; - const char * const linkback; -} testSetData[] = { - {"", CONSTANT, 0}, - {"0", CONSTANT, 0}, - {"42", CONSTANT, 0}, - {"0x1", CONSTANT, 0}, - - {"x1", DB_LINK, 0, "x1 NPP NMS"}, - {"x1.VAL", DB_LINK, 0, "x1.VAL NPP NMS"}, - {"x1.TIME", DB_LINK, 0, "x1.TIME NPP NMS"}, - {"x1 PP", DB_LINK, pvlOptPP, "x1 PP NMS"}, - {"x1 PP MSS", DB_LINK, pvlOptPP|pvlOptMSS, "x1 PP MSS"}, - {"x1 PPMSS", DB_LINK, pvlOptPP|pvlOptMSS, "x1 PP MSS"}, - {"x1 PPMSI", DB_LINK, pvlOptPP|pvlOptMSI, "x1 PP MSI"}, - - {"qq", CA_LINK, pvlOptInpNative, "qq NPP NMS"}, - {"qq MSI", CA_LINK, pvlOptInpNative|pvlOptMSI, "qq NPP MSI"}, - {"qq MSICA", CA_LINK, pvlOptInpNative|pvlOptCA|pvlOptMSI, "qq CA MSI"}, - - {"x1 CA", CA_LINK, pvlOptInpNative|pvlOptCA, "x1 CA NMS"}, - {NULL} -}; - -static void testCADBSet(void) -{ - const struct testDataT *td = testSetData; - xRecord *prec; - DBLINK *plink; - testDiag("\n# Checking DB/CA link retargeting\n#"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbPutLinkTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - prec = (xRecord*)testdbRecordPtr("x1"); - plink = &prec->lnk; - - for (;td->linkstring;td++) { - testDiag("Trying field value \"%s\"", td->linkstring); - - testdbPutFieldOk("x1.LNK", DBF_STRING, td->linkstring); - if (td->linkback) - testdbGetFieldEqual("x1.LNK", DBF_STRING, td->linkback); - else - testdbGetFieldEqual("x1.LNK", DBF_STRING, td->linkstring); - if (!testOk(plink->type == td->linkType, "Link type")) - testDiag("Expected %d, got %d", td->linkType, plink->type); - - if (plink->type == td->linkType) { - switch (td->linkType) { - case CONSTANT: - if (plink->value.constantStr) - testOk1(strcmp(plink->value.constantStr, td->linkstring) == 0); - else if (td->linkstring[0]=='\0') - testPass("Empty String"); - else - testFail("oops"); - break; - - case DB_LINK: - case CA_LINK: - testOk(plink->value.pv_link.pvlMask == td->pvlMask, - "pvlMask %x == %x", plink->value.pv_link.pvlMask, td->pvlMask); - break; - } - } - } - - testIocShutdownOk(); - - testdbCleanup(); -} - -typedef struct { - const char * const recname; - short ltype; - const char * const wval; - short vals[5]; - const char * const parm; -} testHWDataT; - -static const testHWDataT testHWData[] = { - {"rJSON_LINK", JSON_LINK, "{\"x\":true}", {0}, "{\"x\":true}"}, - {"rVME_IO", VME_IO, "#C100 S101 @parm VME_IO", {100, 101}, "parm VME_IO"}, - {"rCAMAC_IO", CAMAC_IO, "#B11 C12 N13 A14 F15 @parm CAMAC_IO", {11, 12, 13, 14, 15}, "parm CAMAC_IO"}, - {"rAB_IO", AB_IO, "#L21 A22 C23 S24 @parm AB_IO", {21, 22, 23, 24}, "parm AB_IO"}, - {"rGPIB_IO", GPIB_IO, "#L31 A32 @parm GPIB_IO", {31, 32}, "parm GPIB_IO"}, - {"rBITBUS_IO", BITBUS_IO, "#L41 N42 P43 S44 @parm BITBUS_IO", {41, 42, 43, 44}, "parm BITBUS_IO"}, - {"rINST_IO", INST_IO, "@parm INST_IO", {0}, "parm INST_IO"}, - {"rBBGPIB_IO", BBGPIB_IO, "#L51 B52 G53 @parm BBGPIB_IO", {51, 52, 53}, "parm BBGPIB_IO"}, - {"rRF_IO", RF_IO, "#R61 M62 D63 E64", {61, 62, 63, 64}, NULL}, - {"rVXI_IO1", VXI_IO, "#V71 C72 S73 @parm1 VXI_IO", {71, 72, 73}, "parm1 VXI_IO"}, - {"rVXI_IO2", VXI_IO, "#V81 S82 @parm2 VXI_IO", {81, 82}, "parm2 VXI_IO"}, - {NULL} -}; - -static void testLink(DBLINK *plink, const testHWDataT *td) -{ - switch(td->ltype) { - case JSON_LINK: - testOk1(strcmp(plink->value.json.string, td->parm) == 0); - break; - case VME_IO: - testOk1(plink->value.vmeio.card == td->vals[0]); - testOk1(plink->value.vmeio.signal == td->vals[1]); - testOk1(strcmp(plink->value.vmeio.parm, td->parm) == 0); - break; - case CAMAC_IO: - testOk1(plink->value.camacio.b == td->vals[0]); - testOk1(plink->value.camacio.c == td->vals[1]); - testOk1(plink->value.camacio.n == td->vals[2]); - testOk1(plink->value.camacio.a == td->vals[3]); - testOk1(plink->value.camacio.f == td->vals[4]); - testOk1(strcmp(plink->value.camacio.parm, td->parm) == 0); - break; - case AB_IO: - testOk1(plink->value.abio.link == td->vals[0]); - testOk1(plink->value.abio.adapter == td->vals[1]); - testOk1(plink->value.abio.card == td->vals[2]); - testOk1(plink->value.abio.signal == td->vals[3]); - testOk1(strcmp(plink->value.abio.parm, td->parm) == 0); - break; - case GPIB_IO: - testOk1(plink->value.gpibio.link == td->vals[0]); - testOk1(plink->value.gpibio.addr == td->vals[1]); - testOk1(strcmp(plink->value.gpibio.parm, td->parm) == 0); - break; - case BITBUS_IO: - testOk1(plink->value.bitbusio.link == td->vals[0]); - testOk1(plink->value.bitbusio.node == td->vals[1]); - testOk1(plink->value.bitbusio.port == td->vals[2]); - testOk1(plink->value.bitbusio.signal == td->vals[3]); - testOk1(strcmp(plink->value.bitbusio.parm, td->parm) == 0); - break; - case INST_IO: - testOk1(strcmp(plink->value.instio.string, td->parm) == 0); - break; - case BBGPIB_IO: - testOk1(plink->value.bbgpibio.link == td->vals[0]); - testOk1(plink->value.bbgpibio.bbaddr == td->vals[1]); - testOk1(plink->value.bbgpibio.gpibaddr == td->vals[2]); - testOk1(strcmp(plink->value.bbgpibio.parm, td->parm) == 0); - break; - case RF_IO: - testOk1(plink->value.rfio.cryo == td->vals[0]); - testOk1(plink->value.rfio.micro == td->vals[1]); - testOk1(plink->value.rfio.dataset == td->vals[2]); - testOk1(plink->value.rfio.element == td->vals[3]); - break; - case VXI_IO: - if(plink->value.vxiio.flag == VXIDYNAMIC) { - testOk1(plink->value.vxiio.frame == td->vals[0]); - testOk1(plink->value.vxiio.slot == td->vals[1]); - testOk1(plink->value.vxiio.signal == td->vals[2]); - } else { - testOk1(plink->value.vxiio.la == td->vals[0]); - testOk1(plink->value.vxiio.signal == td->vals[1]); - } - testOk1(strcmp(plink->value.vxiio.parm, td->parm) == 0); - break; - } -} - -static void testHWInitSet(void) -{ - const testHWDataT *td = testHWData; - testDiag("\n# Checking HW link parsing during initialization\n#"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbPutLinkTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - for (;td->recname; td++) { - char buf[MAX_STRING_SIZE]; - xRecord *prec; - DBLINK *plink; - - testDiag("%s == \"%s\"", td->recname, td->wval); - - prec = (xRecord *) testdbRecordPtr(td->recname); - plink = &prec->inp; - - strcpy(buf, td->recname); - strcat(buf, ".INP"); - - testdbGetFieldEqual(buf, DBR_STRING, td->wval); - - if (!testOk(plink->type == td->ltype, "Link type")) { - testDiag("Expected %d, got %d", - td->ltype, plink->type); - } - else { - testLink(plink, td); - } - - } - - testIocShutdownOk(); - - testdbCleanup(); -} - -static const testHWDataT testHWData2[] = { - {"rJSON_LINK", JSON_LINK, "{\"x\":true}", {0}, "{\"x\":true}"}, - {"rVME_IO", VME_IO, "#C200 S201 @another VME_IO", {200, 201}, "another VME_IO"}, - {"rCAMAC_IO", CAMAC_IO, "#B111 C112 N113 A114 F115 @CAMAC_IO", {111, 112, 113, 114, 115}, "CAMAC_IO"}, - {"rAB_IO", AB_IO, "#L121 A122 C123 S124 @another AB_IO", {121, 122, 123, 124}, "another AB_IO"}, - {"rGPIB_IO", GPIB_IO, "#L131 A132 @another GPIB_IO", {131, 132}, "another GPIB_IO"}, - {"rBITBUS_IO", BITBUS_IO, "#L141 N142 P143 S144 @BITBUS_IO", {141, 142, 143, 144}, "BITBUS_IO"}, - {"rINST_IO", INST_IO, "@another INST_IO", {0}, "another INST_IO"}, - {"rBBGPIB_IO", BBGPIB_IO, "#L151 B152 G153 @another BBGPIB_IO", {151, 152, 153}, "another BBGPIB_IO"}, - {"rRF_IO", RF_IO, "#R161 M162 D163 E164", {161, 162, 163, 164}, NULL}, - {"rVXI_IO1", VXI_IO, "#V171 C172 S173 @another1 VXI_IO", {171, 172, 173}, "another1 VXI_IO"}, - {"rVXI_IO2", VXI_IO, "#V181 S182 @another2 VXI_IO", {181, 182}, "another2 VXI_IO"}, - {NULL} -}; - -static void testHWMod(void) -{ - const testHWDataT *td = testHWData2; - - testDiag("\n# Checking HW link parsing during retarget\n#"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbPutLinkTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - for(;td->recname;td++) { - char buf[MAX_STRING_SIZE]; - xRecord *prec; - DBLINK *plink; - testDiag("%s -> \"%s\"", td->recname, td->wval); - - prec = (xRecord*)testdbRecordPtr(td->recname); - plink = &prec->inp; - - strcpy(buf, td->recname); - strcat(buf, ".INP"); - - testdbPutFieldOk(buf, DBR_STRING, td->wval); - - testdbGetFieldEqual(buf, DBR_STRING, td->wval); - - if (!testOk(plink->type == td->ltype, "Link type")) { - testDiag("Expected %d, got %d", - td->ltype, plink->type); - } - else { - testLink(plink, td); - } - - } - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testLinkInitFail(void) -{ - xRecord *prec; - DBLINK *plink; - testDiag("\n# Checking link parse failures at iocInit\n#"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - /* this load will fail */ - eltc(0); - testOk(dbReadDatabase(&pdbbase, "dbBadLink.db", "." OSI_PATH_LIST_SEPARATOR - ".." OSI_PATH_LIST_SEPARATOR "../O.Common" OSI_PATH_LIST_SEPARATOR - "O.Common", NULL) != 0, "dbReadDatabase returned error (expected)"); - - testIocInitOk(); - eltc(1); - - testdbGetFieldEqual("eVME_IO1.INP", DBR_STRING, "#C0 S0 @"); - - prec = (xRecord *) testdbRecordPtr("eVME_IO1"); - plink = &prec->inp; - testOk1(plink->type == VME_IO); - testOk1(plink->value.vmeio.parm != NULL); - - testdbGetFieldEqual("eVME_IO2.INP", DBR_STRING, "#C0 S0 @"); - - prec = (xRecord *) testdbRecordPtr("eVME_IO2"); - plink = &prec->inp; - testOk1(plink->type == VME_IO); - testOk1(plink->value.vmeio.parm != NULL); - - testdbGetFieldEqual("eINST_IO.INP", DBR_STRING, "@"); - - prec = (xRecord *) testdbRecordPtr("eINST_IO"); - plink = &prec->inp; - testOk1(plink->type == INST_IO); - testOk1(plink->value.instio.string != NULL); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testLinkFail(void) -{ - testDiag("\n# Checking runtime link parse failures\n#"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbPutLinkTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - /* INST_IO doesn't accept empty string */ - testdbPutFieldFail(S_dbLib_badField, "rINST_IO.INP", DBR_STRING, ""); - - /* INST_IO doesn't accept string without @ */ - testdbPutFieldFail(S_dbLib_badField, "rINST_IO.INP", DBR_STRING, "abc"); - - /* JSON_LINK dies when expected */ - testdbPutFieldOk("rJSON_LINK.INP", DBR_STRING, "{\"x\":true}"); - testdbPutFieldFail(S_dbLib_badField, "rJSON_LINK.INP", DBR_STRING, "{\"x\":false}"); - testdbPutFieldFail(S_dbLib_badField, "rJSON_LINK.INP", DBR_STRING, "{\"x\":null}"); - testdbPutFieldFail(S_dbLib_badField, "rJSON_LINK.INP", DBR_STRING, "{\"x\":1}"); - testdbPutFieldFail(S_dbLib_badField, "rJSON_LINK.INP", DBR_STRING, "{\"x\":1.1}"); - testdbPutFieldFail(S_dbLib_badField, "rJSON_LINK.INP", DBR_STRING, "{\"x\":\"x\"}"); - testdbPutFieldFail(S_dbLib_badField, "rJSON_LINK.INP", DBR_STRING, "{\"x\":[]}"); - testdbPutFieldFail(S_dbLib_badField, "rJSON_LINK.INP", DBR_STRING, "{\"x\":{}}"); - - /* JSON_LINK syntax errors */ - testdbPutFieldFail(S_dbLib_badField, "rJSON_LINK.INP", DBR_STRING, "{\"x\":bbbb}"); - - /* syntax errors */ - testdbPutFieldFail(S_dbLib_badField, "rVME_IO.INP", DBR_STRING, "#S201 C200 @another VME_IO"); - testdbPutFieldFail(S_dbLib_badField, "rVME_IO.INP", DBR_STRING, "C200 #S201"); - - /* VME_IO doesn't accept empty string */ - testdbPutFieldFail(S_dbLib_badField, "rVME_IO.INP", DBR_STRING, ""); - - testdbPutFieldOk("rVME_IO.INP", DBR_STRING, "#C1 S2 @hello"); - - /* VME_IO fails invalid input */ - testdbPutFieldFail(S_dbLib_badField, "rVME_IO.INP", DBR_STRING, "abc"); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static -void testNumZ(int expect) -{ - int numz = epicsAtomicGetIntT(&numzalloc); - testOk(numz==expect, "numzalloc==%d (%d)", expect, numz); -} - -static -void testJLink(void) -{ - testDiag("Test json link setup/retarget"); - - testNumZ(0); - - testDiag("Link parsing failures"); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("dbPutLinkTest.db", NULL, NULL); - testdbReadDatabase("dbPutLinkTestJ.db", NULL, NULL); - - testNumZ(0); - - eltc(0); - testIocInitOk(); - eltc(1); - - testNumZ(3); - - testdbPutFieldOk("j1.PROC", DBF_LONG, 1); - testdbPutFieldOk("j2.PROC", DBF_LONG, 1); - testdbPutFieldOk("j3.PROC", DBF_LONG, 1); - - testdbGetFieldEqual("j1.INP", DBF_STRING, "{\"z\":{\"good\":1}}"); - testdbGetFieldEqual("j1.VAL", DBF_LONG, 1); - testdbGetFieldEqual("j2.VAL", DBF_LONG, 2); - testdbGetFieldEqual("j3.VAL", DBF_LONG, 3); - - testNumZ(3); - - testdbPutFieldOk("j1.INP", DBF_STRING, "{\"z\":{\"good\":4}}"); - testdbPutFieldOk("j1.PROC", DBF_LONG, 1); - testdbGetFieldEqual("j1.VAL", DBF_LONG, 4); - - testNumZ(3); - - testdbPutFieldFail(S_dbLib_badField, "j1.INP", DBF_STRING, "{\"z\":{\"fail\":5}}"); - testdbPutFieldOk("j1.PROC", DBF_LONG, 1); - testdbGetFieldEqual("j1.VAL", DBF_LONG, 4); - /* put failure in parsing stage doesn't modify link */ - testdbGetFieldEqual("j1.INP", DBF_STRING, "{\"z\":{\"good\":4}}"); - - testNumZ(3); - - testIocShutdownOk(); - - testNumZ(0); - - testdbCleanup(); -} - -MAIN(dbPutLinkTest) -{ - testPlan(301); - testLinkParse(); - testLinkFailParse(); - testCADBSet(); - testHWInitSet(); - testHWMod(); - testLinkInitFail(); - testLinkFail(); - testJLink(); - return testDone(); -} diff --git a/src/ioc/db/test/dbPutLinkTest.db b/src/ioc/db/test/dbPutLinkTest.db deleted file mode 100644 index 6742fcb39..000000000 --- a/src/ioc/db/test/dbPutLinkTest.db +++ /dev/null @@ -1,49 +0,0 @@ -record(x, "x1") {} -record(x, "x2") {} -record(x, "x3") {} -record(x, "x4") {} - -record(x, "rJSON_LINK") { - field(DTYP, "Unit Test JSON_LINK") - field(INP, {x:true}) -} -record(x, "rVME_IO") { - field(DTYP, "Unit Test VME_IO") - field(INP, "#C100 S101 @parm VME_IO") -} -record(x, "rCAMAC_IO") { - field(DTYP, "Unit Test CAMAC_IO") - field(INP, "#B11 C12 N13 A14 F15 @parm CAMAC_IO") -} -record(x, "rAB_IO") { - field(DTYP, "Unit Test AB_IO") - field(INP, "#L21 A22 C23 S24 @parm AB_IO") -} -record(x, "rGPIB_IO") { - field(DTYP, "Unit Test GPIB_IO") - field(INP, "#L31 A32 @parm GPIB_IO") -} -record(x, "rBITBUS_IO") { - field(DTYP, "Unit Test BITBUS_IO") - field(INP, "#L41 N42 P43 S44 @parm BITBUS_IO") -} -record(x, "rINST_IO") { - field(DTYP, "Unit Test INST_IO") - field(INP, "@parm INST_IO") -} -record(x, "rBBGPIB_IO") { - field(DTYP, "Unit Test BBGPIB_IO") - field(INP, "#L51 B52 G53 @parm BBGPIB_IO") -} -record(x, "rRF_IO") { - field(DTYP, "Unit Test RF_IO") - field(INP, "#R61 M62 D63 E64") -} -record(x, "rVXI_IO1") { - field(DTYP, "Unit Test VXI_IO") - field(INP, "#V71 C72 S73 @parm1 VXI_IO") -} -record(x, "rVXI_IO2") { - field(DTYP, "Unit Test VXI_IO") - field(INP, "#V81 S82 @parm2 VXI_IO") -} diff --git a/src/ioc/db/test/dbPutLinkTestJ.db b/src/ioc/db/test/dbPutLinkTestJ.db deleted file mode 100644 index 25cf4c822..000000000 --- a/src/ioc/db/test/dbPutLinkTestJ.db +++ /dev/null @@ -1,12 +0,0 @@ - -record(x, "j1") { - field(INP, {z:{good:1}}) -} - -record(x, "j2") { - field(INP, {z:{good:2}}) -} - -record(x, "j3") { - field(INP, {z:{good:3}}) -} diff --git a/src/ioc/db/test/dbScanTest.c b/src/ioc/db/test/dbScanTest.c deleted file mode 100644 index 905827e0c..000000000 --- a/src/ioc/db/test/dbScanTest.c +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - */ - -#include - -#include "dbScan.h" -#include "epicsEvent.h" - -#include "dbUnitTest.h" -#include "testMain.h" - -#include "dbAccess.h" -#include "errlog.h" - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static epicsEventId waiter; -static int called; -static dbCommon *prec; - -static void onceComp(void *junk, dbCommon *prec) -{ - testOk1(junk==(void*)&waiter); - testOk1(strcmp(prec->name, "reca")==0); - called = 1; - epicsEventMustTrigger(waiter); -} - -static void testOnce(void) -{ - testDiag("check scanOnceCallback() callback"); - waiter = epicsEventMustCreate(epicsEventEmpty); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbLockTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - prec = testdbRecordPtr("reca"); - - testDiag("scanOnce %s", prec->name); - scanOnceCallback(prec, onceComp, &waiter); - testDiag("Waiting"); - epicsEventMustWait(waiter); - testOk1(called==1); - if(!called) - testSkip(2, "callback failed to run"); - - testIocShutdownOk(); - - testdbCleanup(); - epicsEventDestroy(waiter); -} - -MAIN(dbScanTest) -{ - testPlan(3); - testOnce(); - return testDone(); -} diff --git a/src/ioc/db/test/dbShutdownTest.c b/src/ioc/db/test/dbShutdownTest.c deleted file mode 100644 index 55a8f3e0c..000000000 --- a/src/ioc/db/test/dbShutdownTest.c +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 Brookhaven National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - * Ralph Lange - */ - -#include "epicsString.h" -#include "dbUnitTest.h" -#include "epicsThread.h" -#include "iocInit.h" -#include "dbBase.h" -#include "dbAccess.h" -#include "registry.h" -#include "dbStaticLib.h" -#include "osiFileName.h" -#include "dbmf.h" -#include "errlog.h" - -#include "testMain.h" - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static struct threadItem { - char *name; - char found; -} commonThreads[] = { - { "errlog", 0 }, - { "taskwd", 0 }, - { "timerQueue", 0 }, - { "cbLow", 0 }, - { "scanOnce", 0 }, - { NULL, 0 } -}; - -static -void findCommonThread (epicsThreadId id) { - struct threadItem *thr; - char name[32]; - - epicsThreadGetName(id, name, 32); - - for (thr = commonThreads; thr->name; thr++) { - if (epicsStrCaseCmp(thr->name, name) == 0) { - thr->found = 1; - } - } -} - -static -void checkCommonThreads (void) { - struct threadItem *thr; - - for (thr = commonThreads; thr->name; thr++) { - testOk(thr->found, "Thread %s is running", thr->name); - thr->found = 0; - } -} - -static -void cycle(void) { - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - - dbTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("xRecord.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - epicsThreadMap(findCommonThread); - checkCommonThreads(); - - testIocShutdownOk(); - - testdbCleanup(); -} - -MAIN(dbShutdownTest) -{ - testPlan(10); - - cycle(); - cycle(); - - return testDone(); -} diff --git a/src/ioc/db/test/dbStateTest.c b/src/ioc/db/test/dbStateTest.c deleted file mode 100644 index ae7b6512c..000000000 --- a/src/ioc/db/test/dbStateTest.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include "dbState.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -MAIN(dbStateTest) -{ - dbStateId red, red2, blue, blue2; - int i; - - testPlan(20); - - testOk(!dbStateFind("y"), "Finding nonexisting state fails"); - - testOk(!!(red = dbStateCreate("red")), "Create state 'red'"); - testOk((red2 = dbStateFind("red")) == red, "Find 'red' returns correct id"); - testOk((red2 = dbStateCreate("red")) == red, "Create existing 'red' returns correct id"); - testOk(!dbStateFind("y"), "Finding nonexisting state still fails"); - - testOk(!!(blue = dbStateCreate("blue")), "Create state 'blue'"); - testOk((blue2 = dbStateFind("blue")) == blue, "Find 'blue' returns correct id"); - testOk((blue2 = dbStateCreate("blue")) == blue, "Create existing 'blue' returns correct id"); - testOk(!dbStateFind("y"), "Finding nonexisting state still fails"); - - testOk((i = dbStateGet(red)) == 0, "Default 'red' state is 0"); - testOk((i = dbStateGet(blue)) == 0, "Default 'blue' state is 0"); - dbStateSet(red); - testOk((i = dbStateGet(red)) == 1, "After setting, 'red' state is 1"); - testOk((i = dbStateGet(blue)) == 0, "'blue' state is 0"); - dbStateSet(blue); - testOk((i = dbStateGet(blue)) == 1, "After setting, 'blue' state is 1"); - testOk((i = dbStateGet(red)) == 1, "'red' state is 1"); - dbStateClear(blue); - testOk((i = dbStateGet(blue)) == 0, "After clearing, 'blue' state is 0"); - testOk((i = dbStateGet(red)) == 1, "'red' state is 1"); - dbStateClear(red); - testOk((i = dbStateGet(red)) == 0, "After clearing, 'red' state is 0"); - testOk((i = dbStateGet(blue)) == 0, "'red' state is 0"); - - testOk(!dbStateFind("y"), "Finding nonexisting state still fails"); - - return testDone(); -} diff --git a/src/ioc/db/test/dbStaticTest.c b/src/ioc/db/test/dbStaticTest.c deleted file mode 100644 index 3b8467eec..000000000 --- a/src/ioc/db/test/dbStaticTest.c +++ /dev/null @@ -1,168 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - -static void testEntry(const char *pv) -{ - DBENTRY entry; - - testDiag("testEntry(\"%s\")", pv); - - dbInitEntry(pdbbase, &entry); - - testOk1(dbFindRecord(&entry, pv)==0); - - testDiag("precordType=%p precnode=%p", entry.precordType, entry.precnode); - testOk(entry.precordType && - strcmp(entry.precordType->name, "x")==0, - "Record type is '%s' ('x')", entry.precordType->name); - testOk(entry.precnode && - strcmp(((dbCommon*)entry.precnode->precord)->name, "testrec")==0, - "Record name is '%s' ('testrec')", ((dbCommon*)entry.precnode->precord)->name); - testOk(entry.pflddes && - strcmp(entry.pflddes->name, "VAL")==0, - "Field name is '%s' ('VAL')", entry.pflddes->name); - - /* all tested PVs are either a record with aliases, or an alias */ - testOk(entry.precnode && - (!(entry.precnode->flags & DBRN_FLAGS_ISALIAS) ^ - !(entry.precnode->flags & DBRN_FLAGS_HASALIAS)), - "Recnode flags %d", entry.precnode->flags); - - testOk1(dbFollowAlias(&entry)==0); - - testOk(dbFindInfo(&entry, "A")==0 && - strcmp(dbGetInfoString(&entry), "B")==0, - "Info item is set"); - - dbFinishEntry(&entry); -} - -static void testAddr2Entry(const char *pv) -{ - DBENTRY entry, entry2; - dbAddr addr; - - testDiag("testAddr2Entry(\"%s\")", pv); - - memset(&entry, 0, sizeof(entry)); - memset(&entry2, 0, sizeof(entry2)); - - dbInitEntry(pdbbase, &entry); - - if(dbFindRecord(&entry, pv)!=0) - testAbort("no entry for %s", pv); - - if(dbFollowAlias(&entry)) - testAbort("Can't follow alias"); - - if(dbNameToAddr(pv, &addr)) - testAbort("no addr for %s", pv); - - dbInitEntryFromAddr(&addr, &entry2); - - testOk1(entry.pdbbase==entry2.pdbbase); - testOk1(entry.precordType==entry2.precordType); - testOk1(entry.pflddes==entry2.pflddes); - testOk1(entry.precnode==entry2.precnode); - testOk1(entry.pfield==entry2.pfield); - testOk1(entry.indfield==entry2.indfield); - testOk1(!entry2.pinfonode); - testOk1(!entry2.message); - - testOk(memcmp(&entry, &entry2, sizeof(entry))==0, "dbEntries identical"); - - dbFinishEntry(&entry); - dbFinishEntry(&entry2); -} - -static void testRec2Entry(const char *recname) -{ - DBENTRY entry, entry2; - dbCommon *prec; - - testDiag("testRec2Entry(\"%s\")", recname); - - memset(&entry, 0, sizeof(entry)); - memset(&entry2, 0, sizeof(entry2)); - - prec = testdbRecordPtr(recname); - - dbInitEntry(pdbbase, &entry); - - if(dbFindRecord(&entry, recname)!=0) - testAbort("no entry for %s", recname); - - if(dbFollowAlias(&entry)) - testAbort("Can't follow alias"); - - dbInitEntryFromRecord(prec, &entry2); - - testOk1(entry.pdbbase==entry2.pdbbase); - testOk1(entry.precordType==entry2.precordType); - testOk1(entry.pflddes==entry2.pflddes); - testOk1(entry.precnode==entry2.precnode); - testOk1(entry.pfield==entry2.pfield); - testOk1(entry.indfield==entry2.indfield); - testOk1(!entry2.pinfonode); - testOk1(!entry2.message); - - testOk(memcmp(&entry, &entry2, sizeof(entry))==0, "dbEntries identical"); - - dbFinishEntry(&entry); - dbFinishEntry(&entry2); -} - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -MAIN(dbStaticTest) -{ - testPlan(200); - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbStaticTest.db", NULL, NULL); - - testEntry("testrec.VAL"); - testEntry("testalias.VAL"); - testEntry("testalias2.VAL"); - testEntry("testalias3.VAL"); - testAddr2Entry("testrec.VAL"); - testAddr2Entry("testalias.VAL"); - testAddr2Entry("testalias2.VAL"); - testAddr2Entry("testalias3.VAL"); - testRec2Entry("testrec"); - testRec2Entry("testalias"); - testRec2Entry("testalias2"); - testRec2Entry("testalias3"); - - eltc(0); - testIocInitOk(); - eltc(1); - - testEntry("testrec.VAL"); - testEntry("testalias.VAL"); - testEntry("testalias2.VAL"); - testEntry("testalias3.VAL"); - testAddr2Entry("testrec.VAL"); - testAddr2Entry("testalias.VAL"); - testAddr2Entry("testalias2.VAL"); - testAddr2Entry("testalias3.VAL"); - testRec2Entry("testrec"); - testRec2Entry("testalias"); - testRec2Entry("testalias2"); - testRec2Entry("testalias3"); - - testIocShutdownOk(); - - testdbCleanup(); - - return testDone(); -} - diff --git a/src/ioc/db/test/dbStaticTest.db b/src/ioc/db/test/dbStaticTest.db deleted file mode 100644 index c35ff9a91..000000000 --- a/src/ioc/db/test/dbStaticTest.db +++ /dev/null @@ -1,8 +0,0 @@ - -record(x, "testrec") { - info("A", "B") - alias("testalias") -} - -alias("testrec", "testalias2") -alias("testalias2", "testalias3") diff --git a/src/ioc/db/test/dbStressLock.c b/src/ioc/db/test/dbStressLock.c deleted file mode 100644 index 376587975..000000000 --- a/src/ioc/db/test/dbStressLock.c +++ /dev/null @@ -1,356 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Lockset stress test. - * - * The test stratagy is for N threads to contend for M records. - * Each thread will perform one of three operations: - * 1) Lock a single record. - * 2) Lock several records. - * 3) Retarget the TSEL link of a record - * - * Author: Michael Davidsaver - */ - -#include -#include -#include - -#include "envDefs.h" -#include "epicsEvent.h" -#include "epicsStdlib.h" -#include "epicsSpin.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "dbCommon.h" - -#include "dbLockPvt.h" -#include "dbStaticLib.h" - -#include "dbUnitTest.h" -#include "testMain.h" - -#include "dbAccess.h" -#include "errlog.h" - -#include "xRecord.h" - -#if defined(CLOCK_REALTIME) && defined(CLOCK_MONOTONIC) && !defined(_WIN32) -# define TIME_STATS -#endif - -#define testIntOk1(A, OP, B) testOk((A) OP (B), "%s (%d) %s %s (%d)", #A, A, #OP, #B, B); -#define testPtrOk1(A, OP, B) testOk((A) OP (B), "%s (%p) %s %s (%p)", #A, A, #OP, #B, B); - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -/* number of seconds for the test to run */ -static double runningtime = 18.0; - -/* number of worker threads */ -static unsigned int nworkers = 5; - -static unsigned int nrecords; - -#define MAXLOCK 20 - -static dbCommon **precords; - -typedef struct { - int id; - unsigned long N[3]; -#ifdef TIME_STATS - double X[3]; - double X2[3]; -#endif - - unsigned int done; - epicsEventId donevent; - - dbCommon *prec[MAXLOCK]; -} workerPriv; - -/* hopefully a uniform random number in [0.0, 1.0] */ -static -double getRand(void) -{ - return rand()/(double)RAND_MAX; -} - -static -void doSingle(workerPriv *p) -{ - size_t recn = (size_t)(getRand()*(nrecords-1)); - dbCommon *prec = precords[recn]; - xRecord *px = (xRecord*)prec; - - dbScanLock(prec); - px->val++; - dbScanUnlock(prec); -} - -static -void doMulti(workerPriv *p) -{ - int sum = 0; - size_t i; - size_t nlock = 2 + (size_t)(getRand()*(MAXLOCK-3)); - size_t nrec = (size_t)(getRand()*(nrecords-1)); - dbLocker *locker; - - assert(nlock>=2); - assert(nlockprec[i] = precords[nrec]; - } - - locker = dbLockerAlloc(p->prec, nlock, 0); - if(!locker) - testAbort("locker allocation fails"); - - dbScanLockMany(locker); - for(i=0; iprec[i]; - sum += px->val; - } - dbScanUnlockMany(locker); - - dbLockerFree(locker); -} - -static -void doreTarget(workerPriv *p) -{ - char scratchsrc[60]; - char scratchdst[MAX_STRING_SIZE]; - long ret; - DBADDR dbaddr; - double action = getRand(); - size_t nsrc = (size_t)(getRand()*(nrecords-1)); - size_t ntarg = (size_t)(getRand()*(nrecords-1)); - xRecord *psrc = (xRecord*)precords[nsrc]; - xRecord *ptarg = (xRecord*)precords[ntarg]; - - strcpy(scratchsrc, psrc->name); - strcat(scratchsrc, ".TSEL"); - - ret = dbNameToAddr(scratchsrc, &dbaddr); - if(ret) - testAbort("bad record name? %ld", ret); - - if(action<=0.6) { - scratchdst[0] = '\0'; - } else { - strcpy(scratchdst, ptarg->name); - } - - ret = dbPutField(&dbaddr, DBR_STRING, ptarg->name, 1); - if(ret) - testAbort("put fails with %ld", ret); -} - -static -void worker(void *raw) -{ -#ifdef TIME_STATS - struct timespec before; -#endif - workerPriv *priv = raw; - - testDiag("worker %d is %p", priv->id, epicsThreadGetIdSelf()); - -#ifdef TIME_STATS - clock_gettime(CLOCK_MONOTONIC, &before); -#endif - - while(!priv->done) { - double sel = getRand(); -#ifdef TIME_STATS - struct timespec after; - double duration; -#endif - - int act; - if(sel<0.33) { - doSingle(priv); - act = 0; - } else if(sel<0.66) { - doMulti(priv); - act = 1; - } else { - doreTarget(priv); - act = 2; - } - -#ifdef TIME_STATS - clock_gettime(CLOCK_MONOTONIC, &after); - - duration = (double)((long)after.tv_nsec - (long)before.tv_nsec); - duration *= 1e-9; - duration += (double)(after.tv_sec - before.tv_sec); -#endif - - priv->N[act]++; -#ifdef TIME_STATS - priv->X[act] += duration; - priv->X2[act] += duration*duration; -#endif - } - - epicsEventMustTrigger(priv->donevent); -} - -MAIN(dbStressTest) -{ - DBENTRY ent; - long status; - unsigned int i; - workerPriv *priv; - char *nwork=getenv("NWORK"); - epicsTimeStamp seed; - - epicsTimeGetCurrent(&seed); - - srand(seed.nsec); - - if(nwork) { - long val = 0; - epicsParseLong(nwork, &val, 0, NULL); - if(val>2) - nworkers = val; - } - - testPlan(80+nworkers*3); - - priv = callocMustSucceed(nworkers, sizeof(*priv), "no memory"); - - testDiag("lock set stress test"); - - testdbPrepare(); - - testdbReadDatabase("dbTestIoc.dbd", NULL, NULL); - dbTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase("dbStressLock.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - /* collect an array of all records */ - dbInitEntry(pdbbase, &ent); - for(status = dbFirstRecordType(&ent); - !status; - status = dbNextRecordType(&ent)) - { - for(status = dbFirstRecord(&ent); - !status; - status = dbNextRecord(&ent)) - { - if(ent.precnode->flags&DBRN_FLAGS_ISALIAS) - continue; - nrecords++; - } - - } - if(nrecords<2) - testAbort("where are the records!"); - precords = callocMustSucceed(nrecords, sizeof(*precords), "no mem"); - for(status = dbFirstRecordType(&ent), i = 0; - !status; - status = dbNextRecordType(&ent)) - { - for(status = dbFirstRecord(&ent); - !status; - status = dbNextRecord(&ent)) - { - if(ent.precnode->flags&DBRN_FLAGS_ISALIAS) - continue; - precords[i++] = ent.precnode->precord; - } - - } - dbFinishEntry(&ent); - - testDiag("Running with %u workers and %u records", - nworkers, nrecords); - - for(i=0; iprecord; - lockSet *ls; - if(ent.precnode->flags&DBRN_FLAGS_ISALIAS) - continue; - ls = prec->lset->plockSet; - testOk(ellCount(&ls->lockRecordList)==ls->refcount, "%s only lockRecords hold refs. %d == %d", - prec->name,ellCount(&ls->lockRecordList),ls->refcount); - testOk1(ls->ownerlocker==NULL); - } - - } - dbFinishEntry(&ent); - - testDiag("Statistics"); - for(i=0; i0); - testOk1(priv[i].N[1]>0); - testOk1(priv[i].N[2]>0); - } - - testIocShutdownOk(); - - testdbCleanup(); - - free(priv); - free(precords); - - return testDone(); -} diff --git a/src/ioc/db/test/dbStressLock.db b/src/ioc/db/test/dbStressLock.db deleted file mode 100644 index 5aecf860a..000000000 --- a/src/ioc/db/test/dbStressLock.db +++ /dev/null @@ -1,40 +0,0 @@ -record(x, "rec01") {} -record(x, "rec02") {} -record(x, "rec03") {} -record(x, "rec04") {} -record(x, "rec05") {} -record(x, "rec06") {} -record(x, "rec07") {} -record(x, "rec08") {} -record(x, "rec09") {} -record(x, "rec10") {} -record(x, "rec11") {} -record(x, "rec12") {} -record(x, "rec13") {} -record(x, "rec14") {} -record(x, "rec15") {} -record(x, "rec16") {} -record(x, "rec17") {} -record(x, "rec18") {} -record(x, "rec19") {} -record(x, "rec20") {} -record(x, "rec21") {} -record(x, "rec22") {} -record(x, "rec23") {} -record(x, "rec24") {} -record(x, "rec25") {} -record(x, "rec26") {} -record(x, "rec27") {} -record(x, "rec28") {} -record(x, "rec29") {} -record(x, "rec30") {} -record(x, "rec31") {} -record(x, "rec32") {} -record(x, "rec33") {} -record(x, "rec34") {} -record(x, "rec35") {} -record(x, "rec36") {} -record(x, "rec37") {} -record(x, "rec38") {} -record(x, "rec39") {} -record(x, "rec40") {} diff --git a/src/ioc/db/test/devx.c b/src/ioc/db/test/devx.c deleted file mode 100644 index c5527f14e..000000000 --- a/src/ioc/db/test/devx.c +++ /dev/null @@ -1,159 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc. as Operator of Brookhaven -* National Lab -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "devx.h" - -/* xRecord DTYP="Scan I/O" - * - * dset to test I/O Intr scanning. - * INP="@drvname" names a "driver" which - * provides a IOSCANPVT. - * The driver also defines a callback function which - * is invoked when the record is processed. - */ - -struct ELLLIST xdrivers; - -/* Add a new "driver" with the given group id - * and processing callback - */ -xdrv* xdrv_add(int group, xdrvcb cb, void *arg) -{ - xdrv *drv=callocMustSucceed(1, sizeof(*drv), "xdrv_add"); - drv->cb = cb; - drv->arg = arg; - drv->group = group; - scanIoInit(&drv->scan); - ellAdd(&xdrivers, &drv->drvnode); - return drv; -} - -/* Trigger the named "driver" group to scan */ -xdrv *xdrv_get(int group) -{ - ELLNODE *cur; - for(cur=ellFirst(&xdrivers); cur; cur=ellNext(cur)) { - xdrv *curd = CONTAINER(cur, xdrv, drvnode); - if(curd->group==group) { - return curd; - } - } - cantProceed("xdrv_get() for non-existant group"); - return NULL; -} - -/* Free all "driver" groups and record private structures. - * Call after testdbCleanup() - */ -void xdrv_reset() -{ - ELLNODE *cur; - while((cur=ellGet(&xdrivers))!=NULL) { - ELLNODE *cur2; - xdrv *curd = CONTAINER(cur, xdrv, drvnode); - while((cur2=ellGet(&curd->privlist))!=NULL) { - xpriv *priv = CONTAINER(cur2, xpriv, privnode); - free(priv); - } - free(curd); - } -} - -static long xscanio_init_record(xRecord *prec) -{ - ELLNODE *cur; - xpriv *priv; - xdrv *drv = NULL; - int group, member; - assert(prec->inp.type==INST_IO); - - if(sscanf(prec->inp.value.instio.string, "%d %d", - &group, &member)!=2) - cantProceed("xscanio_init_record invalid INP string"); - - for(cur=ellFirst(&xdrivers); cur; cur=ellNext(cur)) { - xdrv *curd = CONTAINER(cur, xdrv, drvnode); - if(curd->group==group) { - drv = curd; - break; - } - } - - assert(drv!=NULL); - priv = mallocMustSucceed(sizeof(*priv), "xscanio_init_record"); - priv->prec = prec; - priv->drv = drv; - priv->member = member; - ellAdd(&drv->privlist, &priv->privnode); - prec->dpvt = priv; - - return 0; -} - -static long xscanio_get_ioint_info(int cmd, xRecord *prec, IOSCANPVT *ppvt) -{ - xpriv *priv = prec->dpvt; - if(!priv || !priv->drv) - return 0; - *ppvt = priv->drv->scan; - return 0; -} - -static long xscanio_read(xRecord *prec) -{ - xpriv *priv = prec->dpvt; - if(!priv || !priv->drv) - return 0; - if(priv->drv->cb) - (*priv->drv->cb)(priv, priv->drv->arg); - return 0; -} - -static xdset devxScanIO = { - 5, NULL, NULL, - &xscanio_init_record, - &xscanio_get_ioint_info, - &xscanio_read -}; -epicsExportAddress(dset, devxScanIO); - -/* basic DTYP="Soft Channel" */ -static long xsoft_init_record(xRecord *prec) -{ - recGblInitConstantLink(&prec->inp, DBF_LONG, &prec->val); - return 0; -} - -static long xsoft_read(xRecord *prec) -{ - return dbGetLink(&prec->inp, DBR_LONG, &prec->val, NULL, NULL); -} - -static struct xdset devxSoft = { - 5, NULL, NULL, - &xsoft_init_record, - NULL, - &xsoft_read -}; -epicsExportAddress(dset, devxSoft); diff --git a/src/ioc/db/test/devx.dbd b/src/ioc/db/test/devx.dbd deleted file mode 100644 index ee6421bc0..000000000 --- a/src/ioc/db/test/devx.dbd +++ /dev/null @@ -1,2 +0,0 @@ -device(x, CONSTANT, devxSoft, "Soft Channel") -device(x, INST_IO , devxScanIO, "Scan I/O") diff --git a/src/ioc/db/test/devx.h b/src/ioc/db/test/devx.h deleted file mode 100644 index f8f417a14..000000000 --- a/src/ioc/db/test/devx.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc. as Operator of Brookhaven -* National Lab -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef DEVXSCANIO_H -#define DEVXSCANIO_H - -#include -#include - -#include - -struct xRecord; -struct xpriv; - -epicsShareExtern struct ELLLIST xdrivers; - -typedef void (*xdrvcb)(struct xpriv *, void *); - -typedef struct { - ELLNODE drvnode; - IOSCANPVT scan; - xdrvcb cb; - void *arg; - ELLLIST privlist; - int group; -} xdrv; - -typedef struct xpriv { - ELLNODE privnode; - xdrv *drv; - struct xRecord *prec; - int member; -} xpriv; - -epicsShareFunc xdrv *xdrv_add(int group, xdrvcb cb, void *arg); -epicsShareFunc xdrv *xdrv_get(int group); -epicsShareFunc void xdrv_reset(); - -typedef struct xdset { - long number; - long (*report)(int); - long (*init)(int); - long (*init_record)(struct xRecord *); - long (*get_ioint_info)(int, struct xRecord*, IOSCANPVT*); - long (*process)(struct xRecord *); -} xdset; - -#endif /* DEVXSCANIO_H */ diff --git a/src/ioc/db/test/epicsRunDbTests.c b/src/ioc/db/test/epicsRunDbTests.c deleted file mode 100644 index 69f6b082e..000000000 --- a/src/ioc/db/test/epicsRunDbTests.c +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Run Db tests as a batch. - * - * Do not include performance measurements here, they don't prove - * functionality (which is the purpose of this convenience routine). - */ - -#include "epicsUnitTest.h" -#include "epicsExit.h" -#include "dbmf.h" - -int testdbConvert(void); -int callbackTest(void); -int callbackParallelTest(void); -int dbStateTest(void); -int dbCaStatsTest(void); -int dbShutdownTest(void); -int dbScanTest(void); -int scanIoTest(void); -int dbLockTest(void); -int dbPutLinkTest(void); -int dbStaticTest(void); -int dbCaLinkTest(void); -int testDbChannel(void); -int chfPluginTest(void); -int arrShorthandTest(void); -int recGblCheckDeadbandTest(void); - -void epicsRunDbTests(void) -{ - testHarness(); - - runTest(testdbConvert); - runTest(callbackTest); - runTest(callbackParallelTest); - runTest(dbStateTest); - runTest(dbCaStatsTest); - runTest(dbShutdownTest); - runTest(dbScanTest); - runTest(scanIoTest); - runTest(dbLockTest); - runTest(dbPutLinkTest); - runTest(dbStaticTest); - runTest(dbCaLinkTest); - runTest(testDbChannel); - runTest(arrShorthandTest); - runTest(recGblCheckDeadbandTest); - runTest(chfPluginTest); - - dbmfFreeChunks(); - - epicsExit(0); /* Trigger test harness */ -} diff --git a/src/ioc/db/test/jlinkz.c b/src/ioc/db/test/jlinkz.c deleted file mode 100644 index dd6919ffb..000000000 --- a/src/ioc/db/test/jlinkz.c +++ /dev/null @@ -1,252 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols - -#include "jlinkz.h" - -#include - -int numzalloc; - - -static -void z_open(struct link *plink) -{ - zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base); - - if(priv->isopen) - testDiag("lsetZ re-open"); - priv->isopen = 1; - testDiag("Open jlinkz %p", priv); -} - -static -void z_remove(struct dbLocker *locker, struct link *plink) -{ - zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base); - - epicsMutexLock(priv->lock); - - if(!priv->isopen) - testDiag("lsetZ remove without open"); - - epicsMutexUnlock(priv->lock); - - testDiag("Remove/free jlinkz %p", priv); - - epicsAtomicDecrIntT(&numzalloc); - - epicsMutexDestroy(priv->lock); - free(priv); - plink->value.json.jlink = NULL; /* paranoia */ -} - -static -int z_connected(const struct link *plink) -{ - return 1; /* TODO: not provided should be connected */ -} - -static -int z_dbftype(const struct link *plink) -{ - return DBF_LONG; -} - -static -long z_elements(const struct link *plink, long *nelements) -{ - *nelements = 1; - return 0; -} - -static -long z_getval(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest) -{ - long ret; - long (*pconv)(const epicsInt32 *, void *, const dbAddr *) = dbFastGetConvertRoutine[DBF_LONG][dbrType]; - zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base); - - if(pnRequest && *pnRequest==0) return 0; - - epicsMutexLock(priv->lock); - ret = (*pconv)(&priv->value, pbuffer, NULL); - epicsMutexUnlock(priv->lock); - if(ret==0 && pnRequest) *pnRequest = 1; - return ret; -} - -/* TODO: atomicly get value and alarm */ -static -long z_getalarm(const struct link *plink, epicsEnum16 *status, - epicsEnum16 *severity) -{ - zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base); - epicsEnum16 sevr, stat; - - epicsMutexLock(priv->lock); - sevr = priv->isset ? 0 : INVALID_ALARM; - stat = priv->isset ? 0 : LINK_ALARM; - epicsMutexUnlock(priv->lock); - - if(status) *status = stat; - if(severity) *severity = sevr; - return 0; -} - -static -long z_putval(struct link *plink, short dbrType, - const void *pbuffer, long nRequest) -{ - long ret; - long (*pconv)(epicsInt32 *, const void *, const dbAddr *) = dbFastPutConvertRoutine[DBF_LONG][dbrType]; - zpriv *priv = CONTAINER(plink->value.json.jlink, zpriv, base); - - if(nRequest==0) return 0; - - epicsMutexLock(priv->lock); - ret = (*pconv)(&priv->value, pbuffer, NULL); - epicsMutexUnlock(priv->lock); - return ret; -} - -static lset lsetZ = { - 0, 0, /* non-const, non-volatile */ - &z_open, - &z_remove, - NULL, NULL, NULL, /* load */ - &z_connected, - &z_dbftype, - &z_elements, - &z_getval, - NULL, /* control limits */ - NULL, /* display limits */ - NULL, /* alarm limits */ - NULL, /* prec */ - NULL, /* units */ - &z_getalarm, - NULL, /* time */ - &z_putval, - NULL, /* putasync */ - NULL, /* forward */ - NULL, /* doLocked */ -}; - -static -jlink* z_alloc(short dbfType) -{ - zpriv *priv; - priv = calloc(1, sizeof(*priv)); - if(!priv) goto fail; - - priv->lock = epicsMutexCreate(); - if(!priv->lock) goto fail; - - epicsAtomicIncrIntT(&numzalloc); - - testDiag("Alloc jlinkz %p", priv); - - return &priv->base; -fail: - if(priv && priv->lock) epicsMutexDestroy(priv->lock); - free(priv); - return NULL; -} - -static -void z_free(jlink *pj) -{ - zpriv *priv = CONTAINER(pj, zpriv, base); - - if(priv->isopen) - testDiag("lsetZ jlink free after open()"); - - testDiag("Free jlinkz %p", priv); - - epicsAtomicDecrIntT(&numzalloc); - - epicsMutexDestroy(priv->lock); - free(priv); -} - -static -jlif_result z_int(jlink *pj, long long num) -{ - zpriv *priv = CONTAINER(pj, zpriv, base); - - priv->value = num; - priv->isset = 1; - - return jlif_continue; -} - -static -jlif_key_result z_start(jlink *pj) -{ - return jlif_key_continue; -} - -static -jlif_result z_key(jlink *pj, const char *key, size_t len) -{ - zpriv *priv = CONTAINER(pj, zpriv, base); - - if(len==4 && strncmp(key,"fail", len)==0) { - testDiag("Found fail key jlinkz %p", priv); - return jlif_stop; - } else { - return jlif_continue; - } -} - -static -jlif_result z_end(jlink *pj) -{ - return jlif_continue; -} - -static -struct lset* z_lset(const jlink *pj) -{ - return &lsetZ; -} - -static jlif jlifZ = { - "z", - &z_alloc, - &z_free, - NULL, /* null */ - NULL, /* bool */ - &z_int, - NULL, /* double */ - NULL, /* string */ - &z_start, - &z_key, - &z_end, - NULL, /* start array */ - NULL, /* end array */ - NULL, /* end child */ - &z_lset, - NULL, /* report */ - NULL /* map child */ -}; - -epicsExportAddress(jlif, jlifZ); diff --git a/src/ioc/db/test/jlinkz.dbd b/src/ioc/db/test/jlinkz.dbd deleted file mode 100644 index 5408a88b6..000000000 --- a/src/ioc/db/test/jlinkz.dbd +++ /dev/null @@ -1 +0,0 @@ -link("z", "jlifZ") diff --git a/src/ioc/db/test/jlinkz.h b/src/ioc/db/test/jlinkz.h deleted file mode 100644 index 5c34d2eec..000000000 --- a/src/ioc/db/test/jlinkz.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -#ifndef JLINKZ_H -#define JLINKZ_H - -#include -#include -#include - -#include - -epicsShareExtern -int numzalloc; - -typedef struct { - jlink base; - epicsMutexId lock; - unsigned isset:1; - unsigned isopen:1; - epicsInt32 value; -} zpriv; - -#endif /* JLINKZ_H */ diff --git a/src/ioc/db/test/recGblCheckDeadbandTest.c b/src/ioc/db/test/recGblCheckDeadbandTest.c deleted file mode 100644 index d3cac3a45..000000000 --- a/src/ioc/db/test/recGblCheckDeadbandTest.c +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include "recGbl.h" -#include "dbBase.h" -#include "epicsMath.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -/* Test parameters */ - -#define NO_OF_DEADBANDS 3 -#define NO_OF_PATTERNS 19 - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -/* Indices for deadband value, test number, val in sequence */ -static int idbnd, itest; - -/* Different deadbands to test with */ -static double t_Deadband[NO_OF_DEADBANDS] = { -1, 0, 1.5 }; -/* Value sequences for each of the 16 tests */ -static double t_SetValues[NO_OF_PATTERNS][2]; -/* Expected updates (1=yes) for each sequence of each test of each deadband */ -static int t_ExpectedUpdates[NO_OF_DEADBANDS][NO_OF_PATTERNS] = { - { /* deadband = -1 */ - 1, 1, 1, 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - }, - { /* deadband = 0 */ - 1, 1, 0, 0, - 1, 1, 1, - 1, 0, 1, 1, - 1, 1, 0, 1, - 1, 1, 1, 0, - }, - { /* deadband = 1.5 */ - 0, 1, 0, 0, - 1, 1, 1, - 1, 0, 1, 1, - 1, 1, 0, 1, - 1, 1, 1, 0, - }, -}; - -MAIN(recGblCheckDeadbandTest) -{ - unsigned mask; - double oldval, newval; - - /* Test patterns: - * 0: step less than deadband (of 1.5) - * 1: step larger than deadband (of 1.5) - * 2: no change - * 3: -0.0 -> +0.0 - * ... all possible combinations of steps - * between: finite / NaN / -inf / +inf - */ - t_SetValues[ 0][0] = 1.0; t_SetValues[ 0][1] = 2.0; - t_SetValues[ 1][0] = 0.0; t_SetValues[ 1][1] = 2.0; - t_SetValues[ 2][0] = 0.0; t_SetValues[ 2][1] = 0.0; - t_SetValues[ 3][0] = -0.0; t_SetValues[ 3][1] = 0.0; - t_SetValues[ 4][0] = 1.0; t_SetValues[ 4][1] = epicsNAN; - t_SetValues[ 5][0] = 1.0; t_SetValues[ 5][1] = epicsINF; - t_SetValues[ 6][0] = 1.0; t_SetValues[ 6][1] = -epicsINF; - t_SetValues[ 7][0] = epicsNAN; t_SetValues[ 7][1] = 1.0; - t_SetValues[ 8][0] = epicsNAN; t_SetValues[ 8][1] = epicsNAN; - t_SetValues[ 9][0] = epicsNAN; t_SetValues[ 9][1] = epicsINF; - t_SetValues[10][0] = epicsNAN; t_SetValues[10][1] = -epicsINF; - t_SetValues[11][0] = epicsINF; t_SetValues[11][1] = 1.0; - t_SetValues[12][0] = epicsINF; t_SetValues[12][1] = epicsNAN; - t_SetValues[13][0] = epicsINF; t_SetValues[13][1] = epicsINF; - t_SetValues[14][0] = epicsINF; t_SetValues[14][1] = -epicsINF; - t_SetValues[15][0] = -epicsINF; t_SetValues[15][1] = 1.0; - t_SetValues[16][0] = -epicsINF; t_SetValues[16][1] = epicsNAN; - t_SetValues[17][0] = -epicsINF; t_SetValues[17][1] = epicsINF; - t_SetValues[18][0] = -epicsINF; t_SetValues[18][1] = -epicsINF; - - testPlan(114); - - /* Loop over all tested deadband values */ - for (idbnd = 0; idbnd < NO_OF_DEADBANDS; idbnd++) { - - /* Loop over all test patterns */ - for (itest = 0; itest < NO_OF_PATTERNS; itest++) { - oldval = t_SetValues[itest][0]; - newval = t_SetValues[itest][1]; - mask = 0; - - recGblCheckDeadband(&oldval, newval, t_Deadband[idbnd], &mask, 1); - - /* Check expected vs. actual test result */ - testOk(t_ExpectedUpdates[idbnd][itest] == mask, - "deadband=%2.1f: check for oldvalue=%f newvalue=%f (expected %d, got %d)", - t_Deadband[idbnd], t_SetValues[itest][0], t_SetValues[itest][1], - t_ExpectedUpdates[idbnd][itest], mask); - - if (mask) { - testOk((oldval == newval) || (isnan(oldval) && isnan(newval)), "mask set, oldval equals newval"); - } else { - testOk((oldval == t_SetValues[itest][0]) || (isnan(oldval) && isnan(t_SetValues[itest][0])), - "mask not set, oldval unchanged"); - } - } - } - return testDone(); -} diff --git a/src/ioc/db/test/rtemsTestHarness.c b/src/ioc/db/test/rtemsTestHarness.c deleted file mode 100644 index c9ab2a68c..000000000 --- a/src/ioc/db/test/rtemsTestHarness.c +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -extern void epicsRunDbTests(void); - -int main(int argc, char **argv) -{ - epicsRunDbTests(); /* calls epicsExit(0) */ - return 0; -} diff --git a/src/ioc/db/test/scanIoTest.c b/src/ioc/db/test/scanIoTest.c deleted file mode 100644 index ee6d8b462..000000000 --- a/src/ioc/db/test/scanIoTest.c +++ /dev/null @@ -1,308 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2013 Helmholtz-Zentrum Berlin -* für Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include -#include -#include - -#include "epicsEvent.h" -#include "epicsMessageQueue.h" -#include "epicsPrint.h" -#include "epicsMath.h" -#include "alarm.h" -#include "menuPriority.h" -#include "dbChannel.h" -#include "dbStaticLib.h" -#include "dbAccessDefs.h" -#include "dbScan.h" -#include "dbLock.h" -#include "dbUnitTest.h" -#include "dbCommon.h" -#include "recSup.h" -#include "devSup.h" -#include "iocInit.h" -#include "callback.h" -#include "ellLib.h" -#include "epicsUnitTest.h" -#include "testMain.h" -#include "osiFileName.h" - -#include "epicsExport.h" - -#include "devx.h" -#include "xRecord.h" - -STATIC_ASSERT(NUM_CALLBACK_PRIORITIES==3); - -void dbTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static void loadRecord(int group, int member, const char *prio) -{ - char buf[40]; - sprintf(buf, "GROUP=%d,MEMBER=%d,PRIO=%s", - group, member, prio); - testdbReadDatabase("scanIoTest.db", NULL, buf); -} - -typedef struct { - int hasprocd[NUM_CALLBACK_PRIORITIES]; - int getcomplete[NUM_CALLBACK_PRIORITIES]; - epicsEventId wait[NUM_CALLBACK_PRIORITIES]; - epicsEventId wake[NUM_CALLBACK_PRIORITIES]; -} testsingle; - -static void testcb(xpriv *priv, void *raw) -{ - testsingle *td = raw; - int prio = priv->prec->prio; - - testOk1(td->hasprocd[prio]==0); - td->hasprocd[prio] = 1; -} - -static void testcomp(void *raw, IOSCANPVT scan, int prio) -{ - testsingle *td = raw; - - testOk1(td->hasprocd[prio]==1); - testOk1(td->getcomplete[prio]==0); - td->getcomplete[prio] = 1; - epicsEventMustTrigger(td->wait[prio]); - epicsEventMustWait(td->wake[prio]); -} - -static void testSingleThreading(void) -{ - int i; - testsingle data[2]; - xdrv *drvs[2]; - - memset(data, 0, sizeof(data)); - - for(i=0; i<2; i++) { - int p; - for(p=0; pscan, &testcomp, &data[0]); - scanIoSetComplete(drvs[1]->scan, &testcomp, &data[1]); - - eltc(0); - testIocInitOk(); - eltc(1); - - testDiag("Scan first list"); - scanIoRequest(drvs[0]->scan); - testDiag("Scan second list"); - scanIoRequest(drvs[1]->scan); - - testDiag("Wait for first list to complete"); - for(i=0; imember; - - testOk1(td->hasprocd==0); - td->hasprocd = 1; - epicsEventMustTrigger(td->wait); - epicsEventMustWait(td->wake); - td->getcomplete = 1; -} - -static void testcompmulti(void *raw, IOSCANPVT scan, int prio) -{ - int *mask = raw; - testOk(((*mask)&(1<scan, &testcompmulti, &masks[0]); - scanIoSetComplete(drvs[1]->scan, &testcompmulti, &masks[1]); - - /* just enough workers to process all records concurrently */ - callbackParallelThreads(2, "LOW"); - callbackParallelThreads(2, "MEDIUM"); - callbackParallelThreads(2, "HIGH"); - - eltc(0); - testIocInitOk(); - eltc(1); - - testDiag("Scan first list"); - testOk1(scanIoRequest(drvs[0]->scan)==0x7); - testDiag("Scan second list"); - testOk1(scanIoRequest(drvs[1]->scan)==0x7); - - testDiag("Wait for everything to start"); - for(i=0; ijlink; -} - -static void xlink_free(jlink *pjlink) -{ - xlink *xlink = CONTAINER(pjlink, struct xlink, jlink); - - free(xlink); -} - -static jlif_result xlink_boolean(jlink *pjlink, int val) -{ - return val; /* False triggers a parse failure */ -} - -static struct lset* xlink_get_lset(const jlink *pjlink) -{ - return &xlink_lset; -} - - -static void xlink_remove(struct dbLocker *locker, struct link *plink) -{ - xlink_free(plink->value.json.jlink); -} - -static long xlink_getNelements(const struct link *plink, long *nelements) -{ - *nelements = 0; - return 0; -} - -static long xlink_getValue(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest) -{ - if (pnRequest) - *pnRequest = 0; - return 0; -} - - -static lset xlink_lset = { - 1, 0, /* Constant, not Volatile */ - NULL, xlink_remove, - NULL, NULL, NULL, NULL, - NULL, xlink_getNelements, xlink_getValue, - NULL, NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL -}; - -static jlif xlinkIf = { - "x", xlink_alloc, xlink_free, - NULL, xlink_boolean, NULL, NULL, NULL, - NULL, NULL, NULL, - NULL, NULL, - NULL, xlink_get_lset, - NULL, NULL -}; -epicsExportAddress(jlif, xlinkIf); - diff --git a/src/ioc/db/test/xLink.dbd b/src/ioc/db/test/xLink.dbd deleted file mode 100644 index 290b0ba02..000000000 --- a/src/ioc/db/test/xLink.dbd +++ /dev/null @@ -1 +0,0 @@ -link(x, xlinkIf) diff --git a/src/ioc/db/test/xRecord.c b/src/ioc/db/test/xRecord.c deleted file mode 100644 index 5188bf187..000000000 --- a/src/ioc/db/test/xRecord.c +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Andrew Johnson - * Ralph Lange - */ - -#include "dbAccessDefs.h" -#include "recSup.h" -#include "recGbl.h" -#include "devSup.h" -#include "dbScan.h" - -#define GEN_SIZE_OFFSET -#include "xRecord.h" - -#include - -#include "devx.h" - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct xRecord *prec = (struct xRecord *)pcommon; - long ret = 0; - xdset *xset = (xdset*)prec->dset; - if(!pass) return 0; - - if(!xset) { - recGblRecordError(S_dev_noDSET, prec, "x: init_record"); - return S_dev_noDSET; - } - if(xset->init_record) - ret = (*xset->init_record)(prec); - return ret; -} - -static long process(struct dbCommon *pcommon) -{ - struct xRecord *prec = (struct xRecord *)pcommon; - long ret = 0; - xdset *xset = (xdset*)prec->dset; - - if(prec->clbk) - (*prec->clbk)(prec); - prec->pact = TRUE; - if(xset && xset->process) - ret = (*xset->process)(prec); - recGblGetTimeStamp(prec); - recGblFwdLink(prec); - prec->pact = FALSE; - return ret; -} - -static rset xRSET = { - RSETNUMBER, NULL, NULL, init_record, process -}; -epicsExportAddress(rset,xRSET); diff --git a/src/ioc/db/test/xRecord.db b/src/ioc/db/test/xRecord.db deleted file mode 100644 index a6fa08e40..000000000 --- a/src/ioc/db/test/xRecord.db +++ /dev/null @@ -1,2 +0,0 @@ -record(x, x) {} - diff --git a/src/ioc/db/test/xRecord.dbd b/src/ioc/db/test/xRecord.dbd deleted file mode 100644 index 915746a25..000000000 --- a/src/ioc/db/test/xRecord.dbd +++ /dev/null @@ -1,19 +0,0 @@ -# This is a minimal record definition - -recordtype(x) { - include "dbCommon.dbd" - field(VAL, DBF_LONG) { - prompt("Value") - } - field(LNK, DBF_INLINK) { - prompt("Link") - } - field(INP, DBF_INLINK) { - prompt("Input Link") - } - field(CLBK, DBF_NOACCESS) { - prompt("Processing callback") - special(SPC_NOMOD) - extra("void (*clbk)(struct xRecord*)") - } -} diff --git a/src/ioc/dbCore.rc b/src/ioc/dbCore.rc deleted file mode 100644 index 3267f3ca7..000000000 --- a/src/ioc/dbCore.rc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "epicsVersion.h" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - PRODUCTVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_UNKNOWN - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments","Database Core Library for EPICS\0" - VALUE "CompanyName", "The EPICS collaboration\0" - VALUE "FileDescription", "Database Core Library\0" - VALUE "FileVersion", EPICS_VERSION_STRING "\0" - VALUE "InternalName", "dbCore\0" - VALUE "LegalCopyright", "Copyright (C) Univ. of California, UChicago Argonne LLC\0" - VALUE "OriginalFilename", "dbCore.dll\0" - VALUE "ProductName", "Experimental Physics and Industrial Control System (EPICS)\0" - VALUE "ProductVersion", EPICS_VERSION_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/ioc/dbStatic/Makefile b/src/ioc/dbStatic/Makefile deleted file mode 100644 index c962501d9..000000000 --- a/src/ioc/dbStatic/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(IOCDIR)/dbStatic - -INC += dbBase.h -INC += dbFldTypes.h -INC += dbStaticLib.h -INC += dbStaticPvt.h -INC += link.h -INC += special.h -INC += guigroup.h -INC += devSup.h -INC += drvSup.h -INC += recSup.h -INC += dbStaticIocRegister.h - -dbCore_SRCS += dbStaticLib.c -dbCore_SRCS += dbYacc.c -dbCore_SRCS += dbPvdLib.c -dbCore_SRCS += dbStaticRun.c -dbCore_SRCS += dbStaticIocRegister.c - -CLEANS += dbLex.c dbYacc.c diff --git a/src/ioc/dbStatic/RULES b/src/ioc/dbStatic/RULES deleted file mode 100644 index 70e2cdaee..000000000 --- a/src/ioc/dbStatic/RULES +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -# dbLexRoutines.c is included in dbYacc.c -dbYacc.c: dbLex.c $(IOCDIR)/dbStatic/dbLexRoutines.c diff --git a/src/ioc/dbStatic/dbBase.h b/src/ioc/dbStatic/dbBase.h deleted file mode 100644 index df3be4352..000000000 --- a/src/ioc/dbStatic/dbBase.h +++ /dev/null @@ -1,186 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Current Author: Marty Kraimer - * Date: 03-19-92 - */ - -#ifndef INCdbBaseh -#define INCdbBaseh 1 - -#include "epicsTypes.h" -#include "dbFldTypes.h" -#include "ellLib.h" -#include "dbDefs.h" -#include "recSup.h" - -typedef struct dbMenu { - ELLNODE node; - char *name; - int nChoice; - char **papChoiceName; - char **papChoiceValue; -}dbMenu; - -typedef struct drvSup { - ELLNODE node; - char *name; - struct drvet *pdrvet; -}drvSup; - -typedef struct devSup { - ELLNODE node; - char *name; - char *choice; - int link_type; - /*Following only available on run time system*/ - struct dset *pdset; - struct dsxt *pdsxt; /* Extended device support */ -}devSup; - -typedef struct linkSup { - ELLNODE node; - char *name; - char *jlif_name; - struct jlif *pjlif; -} linkSup; - -typedef struct dbDeviceMenu { - int nChoice; - char **papChoice; -}dbDeviceMenu; - -/* conversion types*/ -typedef enum {CT_DECIMAL,CT_HEX} ctType; -/* access level types */ -typedef enum {ASL0,ASL1} asLevel; - -/*Breakpoint Tables */ -typedef struct brkInt{ /* breakpoint interval */ - double raw; /*raw value for beginning of interval */ - double slope; /*slope for interval */ - double eng; /*converted value for beginning of interval*/ -}brkInt; - -typedef struct brkTable { /* breakpoint table */ - ELLNODE node; - char *name; /*breakpoint table name */ - long number; /*number of brkInt in this table*/ - struct brkInt *paBrkInt; /* ptr to array of brkInts */ -}brkTable; - -typedef struct dbFldDes{ /* field description */ - char *prompt; /*Prompt string for DCT*/ - char *name; /*Field name*/ - char *extra; /*C def for DBF_NOACCESS*/ - struct dbRecordType *pdbRecordType; - short indRecordType; /*within dbRecordType.papFldDes */ - short special; /*Special processing requirements */ - dbfType field_type; /*Field type as defined in dbFldTypes.h */ - unsigned int process_passive:1;/*should dbPutField process passive */ - unsigned int prop:1;/*field is a metadata, post DBE_PROPERTY on change*/ - unsigned int isDevLink:1; /* true for INP/OUT fields */ - ctType base; /*base for integer to string conversions*/ - short promptgroup; /*prompt, i.e. gui group */ - short interest; /*interest level */ - asLevel as_level; /*access security level */ - char *initial; /*initial value */ - /*If (DBF_MENU,DBF_DEVICE) ftPvt is (pdbMenu,pdbDeviceMenu) */ - void *ftPvt; - /*On no runtime following only set for STRING */ - short size; /*length in bytes of a field element */ - /*The following are only available on run time system*/ - unsigned short offset; /*Offset in bytes from beginning of record*/ -}dbFldDes; - -typedef struct dbInfoNode { /*non-field per-record information*/ - ELLNODE node; - char *name; - char *string; - void *pointer; -}dbInfoNode; - -#define DBRN_FLAGS_VISIBLE 1 -#define DBRN_FLAGS_ISALIAS 2 -#define DBRN_FLAGS_HASALIAS 4 - -typedef struct dbRecordNode { - ELLNODE node; - void *precord; - char *recordname; - ELLLIST infoList; /*LIST head of info nodes*/ - int flags; - struct dbRecordNode *aliasedRecnode; /* NULL unless flags|DBRN_FLAGS_ISALIAS */ -}dbRecordNode; - -/*dbRecordAttribute is for "psuedo" fields */ -/*pdbFldDes is so that other access routines work correctly*/ -/*Until base supports char * value MUST be fixed length string*/ -typedef struct dbRecordAttribute { - ELLNODE node; - char *name; - dbFldDes *pdbFldDes; - char value[MAX_STRING_SIZE]; -}dbRecordAttribute; - -typedef struct dbText { - ELLNODE node; - char *text; -}dbText; - -typedef struct dbVariableDef { - ELLNODE node; - char *name; - char *type; - -}dbVariableDef; - -typedef struct dbRecordType { - ELLNODE node; - ELLLIST attributeList; /*LIST head of attributes*/ - ELLLIST recList; /*LIST head of sorted dbRecordNodes*/ - ELLLIST devList; /*List of associated device support*/ - ELLLIST cdefList; /*LIST of Cdef text items*/ - char *name; - short no_fields; /* number of fields defined */ - short no_prompt; /* number of fields to configure*/ - short no_links; /* number of links */ - short no_aliases; /* number of aliases in recList */ - short *link_ind; /* addr of array of ind in papFldDes*/ - char **papsortFldName;/* ptr to array of ptr to fld names*/ - short *sortFldInd; /* addr of array of ind in papFldDes*/ - dbFldDes *pvalFldDes; /*pointer dbFldDes for VAL field*/ - short indvalFlddes; /*ind in papFldDes*/ - dbFldDes **papFldDes; /* ptr to array of ptr to fldDes*/ - /*The following are only available on run time system*/ - rset *prset; - int rec_size; /*record size in bytes */ -}dbRecordType; - -struct dbPvd; /* Contents private to dbPvdLib code */ -struct gphPvt; /* Contents private to gpHashLib code */ - -typedef struct dbBase { - ELLLIST menuList; - ELLLIST recordTypeList; - ELLLIST drvList; - ELLLIST linkList; - ELLLIST registrarList; - ELLLIST functionList; - ELLLIST variableList; - ELLLIST bptList; - ELLLIST filterList; - ELLLIST guiGroupList; - void *pathPvt; - struct dbPvd *ppvd; - struct gphPvt *pgpHash; - short ignoreMissingMenus; - short loadCdefs; -}dbBase; -#endif diff --git a/src/ioc/dbStatic/dbFldTypes.h b/src/ioc/dbStatic/dbFldTypes.h deleted file mode 100644 index ba1a69573..000000000 --- a/src/ioc/dbStatic/dbFldTypes.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ -#ifndef INCdbFldTypesh -#define INCdbFldTypesh 1 - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* field types */ -typedef enum { - DBF_STRING, - DBF_CHAR, - DBF_UCHAR, - DBF_SHORT, - DBF_USHORT, - DBF_LONG, - DBF_ULONG, - DBF_INT64, - DBF_UINT64, - DBF_FLOAT, - DBF_DOUBLE, - DBF_ENUM, - DBF_MENU, - DBF_DEVICE, - DBF_INLINK, - DBF_OUTLINK, - DBF_FWDLINK, - DBF_NOACCESS -}dbfType; -#define DBF_NTYPES DBF_NOACCESS+1 - -typedef struct mapdbfType{ - char *strvalue; - dbfType value; -}mapdbfType; - -epicsShareExtern mapdbfType pamapdbfType[]; -#ifdef DBFLDTYPES_GBLSOURCE -epicsShareDef mapdbfType pamapdbfType[DBF_NTYPES] = { - {"DBF_STRING",DBF_STRING}, - {"DBF_CHAR",DBF_CHAR}, - {"DBF_UCHAR",DBF_UCHAR}, - {"DBF_SHORT",DBF_SHORT}, - {"DBF_USHORT",DBF_USHORT}, - {"DBF_LONG",DBF_LONG}, - {"DBF_ULONG",DBF_ULONG}, - {"DBF_INT64",DBF_INT64}, - {"DBF_UINT64",DBF_UINT64}, - {"DBF_FLOAT",DBF_FLOAT}, - {"DBF_DOUBLE",DBF_DOUBLE}, - {"DBF_ENUM",DBF_ENUM}, - {"DBF_MENU",DBF_MENU}, - {"DBF_DEVICE",DBF_DEVICE}, - {"DBF_INLINK",DBF_INLINK}, - {"DBF_OUTLINK",DBF_OUTLINK}, - {"DBF_FWDLINK",DBF_FWDLINK}, - {"DBF_NOACCESS",DBF_NOACCESS} -}; -#endif /*DBFLDTYPES_GBLSOURCE*/ - -/* data request buffer types */ -#define DBR_STRING DBF_STRING -#define DBR_CHAR DBF_CHAR -#define DBR_UCHAR DBF_UCHAR -#define DBR_SHORT DBF_SHORT -#define DBR_USHORT DBF_USHORT -#define DBR_LONG DBF_LONG -#define DBR_ULONG DBF_ULONG -#define DBR_INT64 DBF_INT64 -#define DBR_UINT64 DBF_UINT64 -#define DBR_FLOAT DBF_FLOAT -#define DBR_DOUBLE DBF_DOUBLE -#define DBR_ENUM DBF_ENUM -#define DBR_PUT_ACKT DBR_ENUM+1 -#define DBR_PUT_ACKS DBR_PUT_ACKT+1 -#define DBR_NOACCESS DBF_NOACCESS -#define VALID_DB_REQ(x) ((x >= 0) && (x <= DBR_ENUM)) -#define INVALID_DB_REQ(x) ((x < 0) || (x > DBR_ENUM)) - -#ifdef __cplusplus -} -#endif - -#endif /*INCdbFldTypesh*/ diff --git a/src/ioc/dbStatic/dbLex.l b/src/ioc/dbStatic/dbLex.l deleted file mode 100644 index cfbb5bda4..000000000 --- a/src/ioc/dbStatic/dbLex.l +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -newline "\n" -backslash "\\" -doublequote "\"" -comment "#" -whitespace [ \t\r\n] -escape {backslash}. -stringchar [^"\n\\] -bareword [a-zA-Z0-9_\-+:.\[\]<>;] - -punctuation [:,\[\]{}] -normalchar [^"\\\0-\x1f] -barechar [a-zA-Z0-9_\-+.] -escapedchar ({backslash}["\\/bfnrt]) -hexdigit [0-9a-fA-F] -unicodechar ({backslash}"u"{hexdigit}{4}) -jsonchar ({normalchar}|{escapedchar}|{unicodechar}) -jsondqstr ({doublequote}{jsonchar}*{doublequote}) -int ("-"?([0-9]|[1-9][0-9]+)) -frac ("."[0-9]+) -exp ([eE][+-]?[0-9]+) -number ({int}{frac}?{exp}?) - -%{ -#undef YY_INPUT -#define YY_INPUT(b,r,ms) (r=(*db_yyinput)((char *)b,ms)) - -static int yyreset(void) -{ - BEGIN INITIAL; - return(0); -} - -%} - -%x JSON - -%% - -"include" return(tokenINCLUDE); -"path" return(tokenPATH); -"addpath" return(tokenADDPATH); -"menu" return(tokenMENU); -"choice" return(tokenCHOICE); -"recordtype" return(tokenRECORDTYPE); -"field" return(tokenFIELD); -"device" return(tokenDEVICE); -"driver" return(tokenDRIVER); -"link" return(tokenLINK); -"breaktable" return(tokenBREAKTABLE); -"record" return(tokenRECORD); -"grecord" return(tokenGRECORD); -"alias" return(tokenALIAS); -"info" return(tokenINFO); -"registrar" return(tokenREGISTRAR); -"function" return(tokenFUNCTION); -"variable" return(tokenVARIABLE); - -{bareword}+ { /* unquoted string or number */ - yylval.Str = dbmfStrdup((char *) yytext); - return(tokenSTRING); -} - -{doublequote}({stringchar}|{escape})*{doublequote} { /* quoted string */ - yylval.Str = dbmfStrdup((char *) yytext+1); - yylval.Str[strlen(yylval.Str)-1] = '\0'; - return(tokenSTRING); -} - -%.* { /*C definition in recordtype*/ - yylval.Str = dbmfStrdup((char *) yytext+1); - return(tokenCDEFS); -} - -"{" return(yytext[0]); -"}" return(yytext[0]); -"(" return(yytext[0]); -")" return(yytext[0]); -"," return(yytext[0]); - -{doublequote}({stringchar}|{escape})*{newline} { /* bad string */ - yyerrorAbort("Newline in string, closing quote missing"); -} - -"null" return jsonNULL; -"true" return jsonTRUE; -"false" return jsonFALSE; - -{punctuation} return yytext[0]; - -{jsondqstr} { - yylval.Str = dbmfStrdup((char *) yytext); - return jsonSTRING; -} - -{number} { - yylval.Str = dbmfStrdup((char *) yytext); - return jsonNUMBER; -} - -{barechar}+ { - yylval.Str = dbmfStrdup((char *) yytext); - return jsonBARE; -} - -{comment}.* ; - -{whitespace} ; - -. { - char message[40]; - YY_BUFFER_STATE *dummy=0; - - if (isprint((int) yytext[0])) { - sprintf(message, "Invalid character '%c'", yytext[0]); - } - else { - sprintf(message, "Invalid character 0x%2.2x", yytext[0]); - } - yyerrorAbort(message); - /*The following suppresses compiler warning messages*/ - if(FALSE) yyunput('c',(unsigned char *) message); - if(FALSE) yy_switch_to_buffer(*dummy); -} - -%% diff --git a/src/ioc/dbStatic/dbLexRoutines.c b/src/ioc/dbStatic/dbLexRoutines.c deleted file mode 100644 index 19bea450d..000000000 --- a/src/ioc/dbStatic/dbLexRoutines.c +++ /dev/null @@ -1,1170 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 13JUL95*/ - -/*The routines in this module are serially reusable NOT reentrant*/ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "dbmf.h" -#include "ellLib.h" -#include "epicsPrint.h" -#include "epicsString.h" -#include "errMdef.h" -#include "freeList.h" -#include "gpHash.h" -#include "macLib.h" - -#define epicsExportSharedSymbols -#include "dbBase.h" -#include "dbFldTypes.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "epicsExport.h" -#include "link.h" -#include "special.h" - - - -/*global declarations*/ -epicsShareDef char *makeDbdDepends=0; - -epicsShareDef int dbRecordsOnceOnly=0; -epicsExportAddress(int,dbRecordsOnceOnly); - -epicsShareDef int dbBptNotMonotonic=0; -epicsExportAddress(int,dbBptNotMonotonic); - -epicsShareDef int dbQuietMacroWarnings=0; -epicsExportAddress(int,dbQuietMacroWarnings); - -epicsShareDef int dbRecordsAbcSorted=0; -epicsExportAddress(int,dbRecordsAbcSorted); - -/*private routines */ -static void yyerrorAbort(char *str); -static void allocTemp(void *pvoid); -static void *popFirstTemp(void); -static void *getLastTemp(void); -static int db_yyinput(char *buf,int max_size); -static void dbIncludePrint(void); -static void dbPathCmd(char *path); -static void dbAddPathCmd(char *path); -static void dbIncludeNew(char *include_file); -static void dbMenuHead(char *name); -static void dbMenuChoice(char *name,char *value); -static void dbMenuBody(void); - -static void dbRecordtypeHead(char *name); -static void dbRecordtypeEmpty(void); -static void dbRecordtypeBody(void); -static void dbRecordtypeFieldHead(char *name,char *type); -static void dbRecordtypeFieldItem(char *name,char *value); -static short findOrAddGuiGroup(const char *name); - -static void dbDevice(char *recordtype,char *linktype, - char *dsetname,char *choicestring); -static void dbDriver(char *name); -static void dbLinkType(char *name, char *jlif_name); -static void dbRegistrar(char *name); -static void dbFunction(char *name); -static void dbVariable(char *name, char *type); - -static void dbBreakHead(char *name); -static void dbBreakItem(char *value); -static void dbBreakBody(void); - -static void dbRecordHead(char *recordType,char*name,int visible); -static void dbRecordField(char *name,char *value); -static void dbRecordBody(void); - -/*private declarations*/ -#define MY_BUFFER_SIZE 1024 -static char *my_buffer=NULL; -static char *mac_input_buffer=NULL; -static char *my_buffer_ptr=NULL; -static MAC_HANDLE *macHandle = NULL; -typedef struct inputFile{ - ELLNODE node; - char *path; - char *filename; - FILE *fp; - int line_num; -}inputFile; -static ELLLIST inputFileList = ELLLIST_INIT; - -static inputFile *pinputFileNow = NULL; -static DBBASE *pdbbase = NULL; - -typedef struct tempListNode { - ELLNODE node; - void *item; -}tempListNode; - -static ELLLIST tempList = ELLLIST_INIT; -static void *freeListPvt = NULL; -static int duplicate = FALSE; - -static void yyerrorAbort(char *str) -{ - yyerror(str); - yyAbort = TRUE; -} - -static void allocTemp(void *pvoid) -{ - tempListNode *ptempListNode; - - ptempListNode = freeListCalloc(freeListPvt); - ptempListNode->item = pvoid; - ellAdd(&tempList,&ptempListNode->node); -} - -static void *popFirstTemp(void) -{ - tempListNode *ptempListNode; - void *ptemp; - - ptempListNode = (tempListNode *)ellFirst(&tempList); - ptemp = ptempListNode->item; - ellDelete(&tempList,(ELLNODE *)ptempListNode); - freeListFree(freeListPvt,ptempListNode); - return(ptemp); -} - -static void *getLastTemp(void) -{ - tempListNode *ptempListNode; - - ptempListNode = (tempListNode *)ellLast(&tempList); - return(ptempListNode->item); -} - -static char *dbOpenFile(DBBASE *pdbbase,const char *filename,FILE **fp) -{ - ELLLIST *ppathList = (ELLLIST *)pdbbase->pathPvt; - dbPathNode *pdbPathNode; - char *fullfilename; - - *fp = 0; - if (!filename) return 0; - if (!ppathList || ellCount(ppathList) == 0 || - strchr(filename, '/') || strchr(filename, '\\')) { - *fp = fopen(filename, "r"); - if (*fp && makeDbdDepends) - fprintf(stdout, "%s:%s \n", makeDbdDepends, filename); - return 0; - } - pdbPathNode = (dbPathNode *)ellFirst(ppathList); - while (pdbPathNode) { - fullfilename = dbMalloc(strlen(pdbPathNode->directory) + - strlen(filename) + 2); - strcpy(fullfilename, pdbPathNode->directory); - strcat(fullfilename, "/"); - strcat(fullfilename, filename); - *fp = fopen(fullfilename, "r"); - if (*fp && makeDbdDepends) - fprintf(stdout, "%s:%s \n", makeDbdDepends, fullfilename); - free((void *)fullfilename); - if (*fp) return pdbPathNode->directory; - pdbPathNode = (dbPathNode *)ellNext(&pdbPathNode->node); - } - return 0; -} - - -static void freeInputFileList(void) -{ - inputFile *pinputFileNow; - - while((pinputFileNow=(inputFile *)ellFirst(&inputFileList))) { - if(fclose(pinputFileNow->fp)) - errPrintf(0,__FILE__, __LINE__, - "Closing file %s",pinputFileNow->filename); - free((void *)pinputFileNow->filename); - ellDelete(&inputFileList,(ELLNODE *)pinputFileNow); - free((void *)pinputFileNow); - } -} - -static -int cmp_dbRecordNode(const ELLNODE *lhs, const ELLNODE *rhs) -{ - dbRecordNode *LHS = (dbRecordNode*)lhs, - *RHS = (dbRecordNode*)rhs; - - return strcmp(LHS->recordname, RHS->recordname); -} - -static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp, - const char *path,const char *substitutions) -{ - long status; - inputFile *pinputFile = NULL; - char *penv; - char **macPairs; - - if(ellCount(&tempList)) { - epicsPrintf("dbReadCOM: Parser stack dirty %d\n", ellCount(&tempList)); - } - - if(*ppdbbase == 0) *ppdbbase = dbAllocBase(); - pdbbase = *ppdbbase; - if(path && strlen(path)>0) { - dbPath(pdbbase,path); - } else { - penv = getenv("EPICS_DB_INCLUDE_PATH"); - if(penv) { - dbPath(pdbbase,penv); - } else { - dbPath(pdbbase,"."); - } - } - my_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char)); - freeListInitPvt(&freeListPvt,sizeof(tempListNode),100); - if(substitutions) { - if(macCreateHandle(&macHandle,NULL)) { - epicsPrintf("macCreateHandle error\n"); - status = -1; - goto cleanup; - } - macParseDefns(macHandle,(char *)substitutions,&macPairs); - if(macPairs ==NULL) { - macDeleteHandle(macHandle); - macHandle = NULL; - } else { - macInstallMacros(macHandle,macPairs); - free((void *)macPairs); - mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char)); - } - macSuppressWarning(macHandle,dbQuietMacroWarnings); - } - pinputFile = dbCalloc(1,sizeof(inputFile)); - if (filename) { - pinputFile->filename = macEnvExpand(filename); - } - if (!fp) { - FILE *fp1 = 0; - - if (pinputFile->filename) - pinputFile->path = dbOpenFile(pdbbase, pinputFile->filename, &fp1); - if (!pinputFile->filename || !fp1) { - errPrintf(0, __FILE__, __LINE__, - "dbRead opening file %s",pinputFile->filename); - free(pinputFile->filename); - free(pinputFile); - status = -1; - goto cleanup; - } - pinputFile->fp = fp1; - } else { - pinputFile->fp = fp; - } - pinputFile->line_num = 0; - pinputFileNow = pinputFile; - my_buffer[0] = '\0'; - my_buffer_ptr = my_buffer; - ellAdd(&inputFileList,&pinputFile->node); - status = pvt_yy_parse(); - - if (ellCount(&tempList) && !yyAbort) - epicsPrintf("dbReadCOM: Parser stack dirty w/o error. %d\n", ellCount(&tempList)); - while (ellCount(&tempList)) - popFirstTemp(); /* Memory leak on parser failure */ - - dbFreePath(pdbbase); - if(!status) { /*add RTYP and VERS as an attribute */ - DBENTRY dbEntry; - DBENTRY *pdbEntry = &dbEntry; - long localStatus; - - dbInitEntry(pdbbase,pdbEntry); - localStatus = dbFirstRecordType(pdbEntry); - while(!localStatus) { - localStatus = dbPutRecordAttribute(pdbEntry,"RTYP", - dbGetRecordTypeName(pdbEntry)); - if(!localStatus) { - localStatus = dbPutRecordAttribute(pdbEntry,"VERS", - "none specified"); - } - if(localStatus) { - fprintf(stderr,"dbPutRecordAttribute status %ld\n",status); - } else { - localStatus = dbNextRecordType(pdbEntry); - } - } - dbFinishEntry(pdbEntry); - } -cleanup: - if(dbRecordsAbcSorted) { - ELLNODE *cur; - for(cur = ellFirst(&pdbbase->recordTypeList); cur; cur=ellNext(cur)) - { - dbRecordType *rtype = CONTAINER(cur, dbRecordType, node); - - ellSortStable(&rtype->recList, &cmp_dbRecordNode); - } - } - if(macHandle) macDeleteHandle(macHandle); - macHandle = NULL; - if(mac_input_buffer) free((void *)mac_input_buffer); - mac_input_buffer = NULL; - if(freeListPvt) freeListCleanup(freeListPvt); - freeListPvt = NULL; - if(my_buffer) free((void *)my_buffer); - my_buffer = NULL; - freeInputFileList(); - return(status); -} - -long dbReadDatabase(DBBASE **ppdbbase,const char *filename, - const char *path,const char *substitutions) -{return (dbReadCOM(ppdbbase,filename,0,path,substitutions));} - -long dbReadDatabaseFP(DBBASE **ppdbbase,FILE *fp, - const char *path,const char *substitutions) -{return (dbReadCOM(ppdbbase,0,fp,path,substitutions));} - -static int db_yyinput(char *buf, int max_size) -{ - size_t l,n; - char *fgetsRtn; - - if(yyAbort) return(0); - if(*my_buffer_ptr==0) { - while(TRUE) { /*until we get some input*/ - if(macHandle) { - fgetsRtn = fgets(mac_input_buffer,MY_BUFFER_SIZE, - pinputFileNow->fp); - if(fgetsRtn) { - int exp = macExpandString(macHandle,mac_input_buffer, - my_buffer,MY_BUFFER_SIZE); - if (exp < 0) { - fprintf(stderr, "Warning: '%s' line %d has undefined macros\n", - pinputFileNow->filename, pinputFileNow->line_num+1); - } - } - } else { - fgetsRtn = fgets(my_buffer,MY_BUFFER_SIZE,pinputFileNow->fp); - } - if(fgetsRtn) break; - if(fclose(pinputFileNow->fp)) - errPrintf(0,__FILE__, __LINE__, - "Closing file %s",pinputFileNow->filename); - free((void *)pinputFileNow->filename); - ellDelete(&inputFileList,(ELLNODE *)pinputFileNow); - free((void *)pinputFileNow); - pinputFileNow = (inputFile *)ellLast(&inputFileList); - if(!pinputFileNow) return(0); - } - if(dbStaticDebug) fprintf(stderr,"%s",my_buffer); - pinputFileNow->line_num++; - my_buffer_ptr = &my_buffer[0]; - } - l = strlen(my_buffer_ptr); - n = (l<=max_size ? l : max_size); - memcpy(buf,my_buffer_ptr,n); - my_buffer_ptr += n; - return (int)n; -} - -static void dbIncludePrint(void) -{ - inputFile *pinputFile = pinputFileNow; - - while (pinputFile) { - epicsPrintf(" in"); - if (pinputFile->path) - epicsPrintf(" path \"%s\" ",pinputFile->path); - if (pinputFile->filename) { - epicsPrintf(" file \"%s\"",pinputFile->filename); - } else { - epicsPrintf(" standard input"); - } - epicsPrintf(" line %d\n",pinputFile->line_num); - pinputFile = (inputFile *)ellPrevious(&pinputFile->node); - } - return; -} - -static void dbPathCmd(char *path) -{ - dbPath(pdbbase,path); -} - -static void dbAddPathCmd(char *path) -{ - dbAddPath(pdbbase,path); -} - -static void dbIncludeNew(char *filename) -{ - inputFile *pinputFile; - FILE *fp; - - pinputFile = dbCalloc(1,sizeof(inputFile)); - pinputFile->filename = macEnvExpand(filename); - pinputFile->path = dbOpenFile(pdbbase, pinputFile->filename, &fp); - if (!fp) { - epicsPrintf("Can't open include file \"%s\"\n", filename); - yyerror(NULL); - free((void *)pinputFile->filename); - free((void *)pinputFile); - return; - } - pinputFile->fp = fp; - ellAdd(&inputFileList,&pinputFile->node); - pinputFileNow = pinputFile; -} - -static void dbMenuHead(char *name) -{ - dbMenu *pdbMenu; - GPHENTRY *pgphentry; - - pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->menuList); - if(pgphentry) { - duplicate = TRUE; - return; - } - if(ellCount(&tempList)) yyerrorAbort("dbMenuHead: tempList not empty"); - pdbMenu = dbCalloc(1,sizeof(dbMenu)); - pdbMenu->name = epicsStrDup(name); - allocTemp(pdbMenu); -} - -static void dbMenuChoice(char *name,char *value) -{ - if(duplicate) return; - allocTemp(epicsStrDup(name)); - allocTemp(epicsStrDup(value)); -} - -static void dbMenuBody(void) -{ - dbMenu *pnewMenu; - dbMenu *pMenu; - int nChoice; - int i; - GPHENTRY *pgphentry; - - if(duplicate) { - duplicate = FALSE; - return; - } - pnewMenu = (dbMenu *)popFirstTemp(); - pnewMenu->nChoice = nChoice = ellCount(&tempList)/2; - pnewMenu->papChoiceName = dbCalloc(pnewMenu->nChoice,sizeof(char *)); - pnewMenu->papChoiceValue = dbCalloc(pnewMenu->nChoice,sizeof(char *)); - for(i=0; ipapChoiceName[i] = (char *)popFirstTemp(); - pnewMenu->papChoiceValue[i] = (char *)popFirstTemp(); - } - if(ellCount(&tempList)) yyerrorAbort("dbMenuBody: tempList not empty"); - /* Add menu in sorted order */ - pMenu = (dbMenu *)ellFirst(&pdbbase->menuList); - while(pMenu && strcmp(pMenu->name,pnewMenu->name) >0 ) - pMenu = (dbMenu *)ellNext(&pMenu->node); - if(pMenu) - ellInsert(&pdbbase->menuList,ellPrevious(&pMenu->node),&pnewMenu->node); - else - ellAdd(&pdbbase->menuList,&pnewMenu->node); - pgphentry = gphAdd(pdbbase->pgpHash,pnewMenu->name,&pdbbase->menuList); - if(!pgphentry) { - yyerrorAbort("gphAdd failed"); - } else { - pgphentry->userPvt = pnewMenu; - } -} - -static void dbRecordtypeHead(char *name) -{ - dbRecordType *pdbRecordType; - GPHENTRY *pgphentry; - - pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->recordTypeList); - if(pgphentry) { - duplicate = TRUE; - return; - } - pdbRecordType = dbCalloc(1,sizeof(dbRecordType)); - pdbRecordType->name = epicsStrDup(name); - if (pdbbase->loadCdefs) ellInit(&pdbRecordType->cdefList); - if(ellCount(&tempList)) - yyerrorAbort("dbRecordtypeHead tempList not empty"); - allocTemp(pdbRecordType); -} - -static void dbRecordtypeFieldHead(char *name,char *type) -{ - dbFldDes *pdbFldDes; - int i; - - if(duplicate) return; - pdbFldDes = dbCalloc(1,sizeof(dbFldDes)); - allocTemp(pdbFldDes); - pdbFldDes->name = epicsStrDup(name); - pdbFldDes->as_level = ASL1; - pdbFldDes->isDevLink = strcmp(pdbFldDes->name, "INP")==0 || - strcmp(pdbFldDes->name, "OUT")==0; - i = dbFindFieldType(type); - if (i < 0) - yyerrorAbort("Illegal Field Type"); - pdbFldDes->field_type = i; -} - -static short findOrAddGuiGroup(const char *name) -{ - dbGuiGroup *pdbGuiGroup; - GPHENTRY *pgphentry; - pgphentry = gphFind(pdbbase->pgpHash, name, &pdbbase->guiGroupList); - if (!pgphentry) { - pdbGuiGroup = dbCalloc(1,sizeof(dbGuiGroup)); - pdbGuiGroup->name = epicsStrDup(name); - ellAdd(&pdbbase->guiGroupList, &pdbGuiGroup->node); - pdbGuiGroup->key = ellCount(&pdbbase->guiGroupList); - pgphentry = gphAdd(pdbbase->pgpHash, pdbGuiGroup->name, &pdbbase->guiGroupList); - pgphentry->userPvt = pdbGuiGroup; - } - return ((dbGuiGroup *)pgphentry->userPvt)->key; -} - -static void dbRecordtypeFieldItem(char *name,char *value) -{ - dbFldDes *pdbFldDes; - - if(duplicate) return; - pdbFldDes = (dbFldDes *)getLastTemp(); - if(strcmp(name,"asl")==0) { - if(strcmp(value,"ASL0")==0) { - pdbFldDes->as_level = ASL0; - } else if(strcmp(value,"ASL1")==0) { - pdbFldDes->as_level = ASL1; - } else { - yyerror("Illegal Access Security value: Must be ASL0 or ASL1"); - } - return; - } - if(strcmp(name,"initial")==0) { - pdbFldDes->initial = epicsStrDup(value); - return; - } - if(strcmp(name,"promptgroup")==0) { - pdbFldDes->promptgroup = findOrAddGuiGroup(value); - return; - } - if(strcmp(name,"prompt")==0) { - pdbFldDes->prompt = epicsStrDup(value); - return; - } - if(strcmp(name,"special")==0) { - int i; - for(i=0; ispecial = pamapspcType[i].value; - return; - } - } - if(sscanf(value,"%hd",&pdbFldDes->special)==1) { - return; - } - yyerror("Illegal special value."); - return; - } - if(strcmp(name,"pp")==0) { - if((strcmp(value,"YES")==0) || (strcmp(value,"TRUE")==0)) { - pdbFldDes->process_passive = TRUE; - } else if((strcmp(value,"NO")==0) || (strcmp(value,"FALSE")==0)) { - pdbFldDes->process_passive = FALSE; - } else { - yyerror("Illegal value. Must be NO or YES"); - } - return; - } - if(strcmp(name,"interest")==0) { - if(sscanf(value,"%hd",&pdbFldDes->interest)!=1) - yyerror("Illegal value. Must be integer"); - return; - } - if(strcmp(name,"base")==0) { - if(strcmp(value,"DECIMAL")==0) { - pdbFldDes->base = CT_DECIMAL; - } else if(strcmp(value,"HEX")==0) { - pdbFldDes->base = CT_HEX; - } else { - yyerror("Illegal value. Must be CT_DECIMAL or CT_HEX"); - } - return; - } - if(strcmp(name,"size")==0) { - if(sscanf(value,"%hd",&pdbFldDes->size)!=1) - yyerror("Illegal value. Must be integer"); - return; - } - if(strcmp(name,"extra")==0) { - pdbFldDes->extra = epicsStrDup(value); - return; - } - if(strcmp(name,"menu")==0) { - pdbFldDes->ftPvt = (dbMenu *)dbFindMenu(pdbbase,value); - if(!pdbbase->ignoreMissingMenus && !pdbFldDes->ftPvt) - yyerrorAbort("menu not found"); - return; - } - if(strcmp(name,"prop")==0) { - if(strcmp(value, "YES")==0) - pdbFldDes->prop = 1; - else - pdbFldDes->prop = 0; - return; - } -} - -static void dbRecordtypeCdef(char *text) { - dbText *pdbCdef; - tempListNode *ptempListNode; - dbRecordType *pdbRecordType; - - if (!pdbbase->loadCdefs || duplicate) return; - ptempListNode = (tempListNode *)ellFirst(&tempList); - pdbRecordType = ptempListNode->item; - - pdbCdef = dbCalloc(1,sizeof(dbText)); - if (text[0] == ' ') text++; /* strip leading space if present */ - pdbCdef->text = epicsStrDup(text); - ellAdd(&pdbRecordType->cdefList, &pdbCdef->node); - return; -} - -static void dbRecordtypeEmpty(void) -{ - tempListNode *ptempListNode; - dbRecordType *pdbRecordType; - - if (duplicate) { - duplicate = FALSE; - return; - } - - ptempListNode = (tempListNode *)ellFirst(&tempList); - pdbRecordType = ptempListNode->item; - epicsPrintf("Declaration of recordtype(%s) preceeded full definition.\n", - pdbRecordType->name); - yyerrorAbort(NULL); -} - -static void dbRecordtypeBody(void) -{ - dbRecordType *pdbRecordType; - dbFldDes *pdbFldDes; - int i,j,ilink; - GPHENTRY *pgphentry; - int no_fields,no_prompt,no_links; - dbfType field_type; - char *psortFldNameTemp; - short psortFldIndTemp; - char **papsortFldName; - short *sortFldInd; - - if(duplicate) { - duplicate = FALSE; - return; - } - pdbRecordType= (dbRecordType *)popFirstTemp(); - pdbRecordType->no_fields = no_fields = ellCount(&tempList); - pdbRecordType->papFldDes = dbCalloc(no_fields,sizeof(dbFldDes *)); - pdbRecordType->papsortFldName = dbCalloc(no_fields,sizeof(char *)); - pdbRecordType->sortFldInd = dbCalloc(no_fields,sizeof(short)); - no_prompt = no_links = 0; - for(i=0; ipdbRecordType = pdbRecordType; - pdbFldDes->indRecordType = i; - pdbRecordType->papFldDes[i] = pdbFldDes; - if(pdbFldDes->promptgroup) no_prompt++; - field_type = pdbFldDes->field_type; - if((field_type>=DBF_INLINK) && (field_type<=DBF_FWDLINK))no_links++; - if((field_type==DBF_STRING) && (pdbFldDes->size==0)) - fprintf(stderr,"recordtype(%s).%s size not specified\n", - pdbRecordType->name,pdbFldDes->name); - if((field_type==DBF_NOACCESS) && (pdbFldDes->extra==0)) - fprintf(stderr,"recordtype(%s).%s extra not specified\n", - pdbRecordType->name,pdbFldDes->name); - } - if (ellCount(&tempList)) - yyerrorAbort("dbRecordtypeBody: tempList not empty"); - pdbRecordType->no_prompt = no_prompt; - pdbRecordType->no_links = no_links; - pdbRecordType->link_ind = dbCalloc(no_links,sizeof(short)); - ilink = 0; - for(i=0; ipapFldDes[i]; - /* if prompt is null make it a null string */ - if(!pdbFldDes->prompt) pdbFldDes->prompt = dbCalloc(1,sizeof(char)); - field_type = pdbFldDes->field_type; - if((field_type>=DBF_INLINK) && (field_type<=DBF_FWDLINK)) - pdbRecordType->link_ind[ilink++] = i; - if(strcmp(pdbFldDes->name,"VAL")==0) { - pdbRecordType->pvalFldDes = pdbRecordType->papFldDes[i]; - pdbRecordType->indvalFlddes = i; - } - pdbRecordType->papsortFldName[i] = pdbFldDes->name; - pdbRecordType->sortFldInd[i] = i; - } - /*Now sort fields. Sorry dumb sort algorithm */ - papsortFldName = pdbRecordType->papsortFldName; - sortFldInd = pdbRecordType->sortFldInd; - for(i=0; iattributeList); - ellInit(&pdbRecordType->recList); - ellInit(&pdbRecordType->devList); - pgphentry = gphAdd(pdbbase->pgpHash,pdbRecordType->name, - &pdbbase->recordTypeList); - if(!pgphentry) { - yyerrorAbort("gphAdd failed"); - } else { - pgphentry->userPvt = pdbRecordType; - } - ellAdd(&pdbbase->recordTypeList,&pdbRecordType->node); -} - -static void dbDevice(char *recordtype,char *linktype, - char *dsetname,char *choicestring) -{ - devSup *pdevSup; - dbRecordType *pdbRecordType; - GPHENTRY *pgphentry; - int i,link_type; - pgphentry = gphFind(pdbbase->pgpHash,recordtype,&pdbbase->recordTypeList); - if(!pgphentry) { - epicsPrintf("Record type \"%s\" not found for device \"%s\"\n", - recordtype, choicestring); - yyerror(NULL); - return; - } - link_type=-1; - for(i=0; iuserPvt; - pgphentry = gphFind(pdbbase->pgpHash,choicestring,&pdbRecordType->devList); - if(pgphentry) { - return; - } - pdevSup = dbCalloc(1,sizeof(devSup)); - pdevSup->name = epicsStrDup(dsetname); - pdevSup->choice = epicsStrDup(choicestring); - pdevSup->link_type = link_type; - pgphentry = gphAdd(pdbbase->pgpHash,pdevSup->choice,&pdbRecordType->devList); - if(!pgphentry) { - yyerrorAbort("gphAdd failed"); - } else { - pgphentry->userPvt = pdevSup; - } - ellAdd(&pdbRecordType->devList,&pdevSup->node); -} - -static void dbDriver(char *name) -{ - drvSup *pdrvSup; - GPHENTRY *pgphentry; - - pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->drvList); - if(pgphentry) { - return; - } - pdrvSup = dbCalloc(1,sizeof(drvSup)); - pdrvSup->name = epicsStrDup(name); - pgphentry = gphAdd(pdbbase->pgpHash,pdrvSup->name,&pdbbase->drvList); - if(!pgphentry) { - yyerrorAbort("gphAdd failed"); - } - pgphentry->userPvt = pdrvSup; - ellAdd(&pdbbase->drvList,&pdrvSup->node); -} - -static void dbLinkType(char *name, char *jlif_name) -{ - linkSup *pLinkSup; - GPHENTRY *pgphentry; - - pgphentry = gphFind(pdbbase->pgpHash, name, &pdbbase->linkList); - if (pgphentry) { - return; - } - pLinkSup = dbCalloc(1,sizeof(linkSup)); - pLinkSup->name = epicsStrDup(name); - pLinkSup->jlif_name = epicsStrDup(jlif_name); - pgphentry = gphAdd(pdbbase->pgpHash, pLinkSup->name, &pdbbase->linkList); - if (!pgphentry) { - yyerrorAbort("gphAdd failed"); - } - pgphentry->userPvt = pLinkSup; - ellAdd(&pdbbase->linkList, &pLinkSup->node); -} - -static void dbRegistrar(char *name) -{ - dbText *ptext; - GPHENTRY *pgphentry; - - pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->registrarList); - if(pgphentry) { - return; - } - ptext = dbCalloc(1,sizeof(dbText)); - ptext->text = epicsStrDup(name); - pgphentry = gphAdd(pdbbase->pgpHash,ptext->text,&pdbbase->registrarList); - if(!pgphentry) { - yyerrorAbort("gphAdd failed"); - } - pgphentry->userPvt = ptext; - ellAdd(&pdbbase->registrarList,&ptext->node); -} - -static void dbFunction(char *name) -{ - dbText *ptext; - GPHENTRY *pgphentry; - - pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->functionList); - if(pgphentry) { - return; - } - ptext = dbCalloc(1,sizeof(dbText)); - ptext->text = epicsStrDup(name); - pgphentry = gphAdd(pdbbase->pgpHash,ptext->text,&pdbbase->functionList); - if(!pgphentry) { - yyerrorAbort("gphAdd failed"); - } - pgphentry->userPvt = ptext; - ellAdd(&pdbbase->functionList,&ptext->node); -} - -static void dbVariable(char *name, char *type) -{ - dbVariableDef *pvar; - GPHENTRY *pgphentry; - - pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->variableList); - if(pgphentry) { - return; - } - pvar = dbCalloc(1,sizeof(dbVariableDef)); - pvar->name = epicsStrDup(name); - pvar->type = epicsStrDup(type); - pgphentry = gphAdd(pdbbase->pgpHash,pvar->name,&pdbbase->variableList); - if(!pgphentry) { - yyerrorAbort("gphAdd failed"); - } - pgphentry->userPvt = pvar; - ellAdd(&pdbbase->variableList,&pvar->node); -} - -static void dbBreakHead(char *name) -{ - brkTable *pbrkTable; - GPHENTRY *pgphentry; - - pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->bptList); - if(pgphentry) { - duplicate = TRUE; - return; - } - pbrkTable = dbCalloc(1,sizeof(brkTable)); - pbrkTable->name = epicsStrDup(name); - if(ellCount(&tempList)) yyerrorAbort("dbBreakHead:tempList not empty"); - allocTemp(pbrkTable); -} - -static void dbBreakItem(char *value) -{ - double dummy; - if (duplicate) return; - if (epicsScanDouble(value, &dummy) != 1) { - yyerrorAbort("Non-numeric value in breaktable"); - } - allocTemp(epicsStrDup(value)); -} - -static void dbBreakBody(void) -{ - brkTable *pnewbrkTable; - brkInt *paBrkInt; - brkTable *pbrkTable; - int number, down=0; - int i; - GPHENTRY *pgphentry; - - if (duplicate) { - duplicate = FALSE; - return; - } - pnewbrkTable = (brkTable *)popFirstTemp(); - number = ellCount(&tempList); - if (number % 2) { - yyerrorAbort("breaktable: Raw value missing"); - return; - } - number /= 2; - if (number < 2) { - yyerrorAbort("breaktable: Must have at least two points!"); - return; - } - pnewbrkTable->number = number; - pnewbrkTable->paBrkInt = paBrkInt = dbCalloc(number, sizeof(brkInt)); - for (i=0; ibptList); - while (pbrkTable) { - if (strcmp(pbrkTable->name, pnewbrkTable->name) > 0) { - ellInsert(&pdbbase->bptList, ellPrevious((ELLNODE *)pbrkTable), - (ELLNODE *)pnewbrkTable); - break; - } - pbrkTable = (brkTable *)ellNext(&pbrkTable->node); - } - if (!pbrkTable) ellAdd(&pdbbase->bptList, &pnewbrkTable->node); - pgphentry = gphAdd(pdbbase->pgpHash,pnewbrkTable->name,&pdbbase->bptList); - if (!pgphentry) { - yyerrorAbort("dbBreakBody: gphAdd failed"); - return; - } - pgphentry->userPvt = pnewbrkTable; -} - -static void dbRecordHead(char *recordType, char *name, int visible) -{ - char *badch; - DBENTRY *pdbentry; - long status; - - badch = strpbrk(name, " \"'.$"); - if (badch) { - epicsPrintf("Bad character '%c' in record name \"%s\"\n", - *badch, name); - } - - pdbentry = dbAllocEntry(pdbbase); - if (ellCount(&tempList)) - yyerrorAbort("dbRecordHead: tempList not empty"); - allocTemp(pdbentry); - - if (recordType[0] == '*' && recordType[1] == 0) { - if (dbRecordsOnceOnly) - epicsPrintf("Record-type \"*\" not valid with dbRecordsOnceOnly\n"); - else { - status = dbFindRecord(pdbentry, name); - if (status == 0) - return; /* done */ - epicsPrintf("Record \"%s\" not found\n", name); - } - yyerror(NULL); - duplicate = TRUE; - return; - } - - status = dbFindRecordType(pdbentry, recordType); - if (status) { - epicsPrintf("Record \"%s\" is of unknown type \"%s\"\n", - name, recordType); - yyerrorAbort(NULL); - return; - } - - /*Duplicate records are ok if the same type */ - - status = dbCreateRecord(pdbentry,name); - if (status == S_dbLib_recExists) { - if (strcmp(recordType, dbGetRecordTypeName(pdbentry)) != 0) { - epicsPrintf("Record \"%s\" of type \"%s\" redefined with new type " - "\"%s\"\n", name, dbGetRecordTypeName(pdbentry), recordType); - yyerror(NULL); - duplicate = TRUE; - return; - } - else if (dbRecordsOnceOnly) { - epicsPrintf("Record \"%s\" already defined (dbRecordsOnceOnly is " - "set)\n", name); - yyerror(NULL); - duplicate = TRUE; - } - } - else if (status) { - epicsPrintf("Can't create record \"%s\" of type \"%s\"\n", - name, recordType); - yyerrorAbort(NULL); - } - - if (visible) - dbVisibleRecord(pdbentry); -} - -static void dbRecordField(char *name,char *value) -{ - DBENTRY *pdbentry; - tempListNode *ptempListNode; - long status; - - if(duplicate) return; - ptempListNode = (tempListNode *)ellFirst(&tempList); - pdbentry = ptempListNode->item; - status = dbFindField(pdbentry,name); - if(status) { - epicsPrintf("Record \"%s\" does not have a field \"%s\"\n", - dbGetRecordName(pdbentry), name); - yyerror(NULL); - return; - } - if (*value == '"') { - /* jsonSTRING values still have their quotes */ - value++; - value[strlen(value) - 1] = 0; - } - dbTranslateEscape(value, value); /* in-place; safe & legal */ - status = dbPutString(pdbentry,value); - if(status) { - char msg[128]; - errSymLookup(status, msg, sizeof(msg)); - epicsPrintf("Can't set \"%s.%s\" to \"%s\" %s\n", - dbGetRecordName(pdbentry), name, value, msg); - yyerror(NULL); - return; - } -} - -static void dbRecordInfo(char *name, char *value) -{ - DBENTRY *pdbentry; - tempListNode *ptempListNode; - long status; - - if(duplicate) return; - ptempListNode = (tempListNode *)ellFirst(&tempList); - pdbentry = ptempListNode->item; - if (*value == '"') { - /* jsonSTRING values still have their quotes */ - value++; - value[strlen(value) - 1] = 0; - } - dbTranslateEscape(value, value); /* yuck: in-place, but safe */ - status = dbPutInfo(pdbentry,name,value); - if(status) { - epicsPrintf("Can't set \"%s\" info \"%s\" to \"%s\"\n", - dbGetRecordName(pdbentry), name, value); - yyerror(NULL); - return; - } -} - -static void dbRecordAlias(char *name) -{ - DBENTRY *pdbentry; - tempListNode *ptempListNode; - long status; - - if(duplicate) return; - ptempListNode = (tempListNode *)ellFirst(&tempList); - pdbentry = ptempListNode->item; - status = dbCreateAlias(pdbentry, name); - if(status) { - epicsPrintf("Can't create alias \"%s\" for \"%s\"\n", - name, dbGetRecordName(pdbentry)); - yyerror(NULL); - return; - } -} - -static void dbAlias(char *name, char *alias) -{ - DBENTRY dbEntry; - DBENTRY *pdbEntry = &dbEntry; - - dbInitEntry(pdbbase, pdbEntry); - if (dbFindRecord(pdbEntry, name)) { - epicsPrintf("Alias \"%s\" refers to unknown record \"%s\"\n", - alias, name); - yyerror(NULL); - } else if (dbCreateAlias(pdbEntry, alias)) { - epicsPrintf("Can't create alias \"%s\" referring to \"%s\"\n", - alias, name); - yyerror(NULL); - } - dbFinishEntry(pdbEntry); -} - -static void dbRecordBody(void) -{ - DBENTRY *pdbentry; - - if(duplicate) { - duplicate = FALSE; - return; - } - pdbentry = (DBENTRY *)popFirstTemp(); - if(ellCount(&tempList)) - yyerrorAbort("dbRecordBody: tempList not empty"); - dbFreeEntry(pdbentry); -} diff --git a/src/ioc/dbStatic/dbPvdLib.c b/src/ioc/dbStatic/dbPvdLib.c deleted file mode 100644 index 15fc5f401..000000000 --- a/src/ioc/dbStatic/dbPvdLib.c +++ /dev/null @@ -1,229 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* dbPvdLib.c */ - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsMutex.h" -#include "epicsStdio.h" -#include "epicsString.h" - -#define epicsExportSharedSymbols -#include "dbBase.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" - -typedef struct { - ELLLIST list; - epicsMutexId lock; -} dbPvdBucket; - -typedef struct dbPvd { - unsigned int size; - unsigned int mask; - dbPvdBucket **buckets; -} dbPvd; - -unsigned int dbPvdHashTableSize = 0; - -#define MIN_SIZE 256 -#define DEFAULT_SIZE 512 -#define MAX_SIZE 65536 - - -int dbPvdTableSize(int size) -{ - if (size & (size - 1)) { - printf("dbPvdTableSize: %d is not a power of 2\n", size); - return -1; - } - - if (size < MIN_SIZE) - size = MIN_SIZE; - - if (size > MAX_SIZE) - size = MAX_SIZE; - - dbPvdHashTableSize = size; - return 0; -} - -void dbPvdInitPvt(dbBase *pdbbase) -{ - dbPvd *ppvd; - - if (pdbbase->ppvd) return; - - if (dbPvdHashTableSize == 0) { - dbPvdHashTableSize = DEFAULT_SIZE; - } - - ppvd = (dbPvd *)dbMalloc(sizeof(dbPvd)); - ppvd->size = dbPvdHashTableSize; - ppvd->mask = dbPvdHashTableSize - 1; - ppvd->buckets = dbCalloc(ppvd->size, sizeof(dbPvdBucket *)); - - pdbbase->ppvd = ppvd; - return; -} - -PVDENTRY *dbPvdFind(dbBase *pdbbase, const char *name, size_t lenName) -{ - dbPvd *ppvd = pdbbase->ppvd; - dbPvdBucket *pbucket; - PVDENTRY *ppvdNode; - - pbucket = ppvd->buckets[epicsMemHash(name, lenName, 0) & ppvd->mask]; - if (pbucket == NULL) return NULL; - - epicsMutexMustLock(pbucket->lock); - ppvdNode = (PVDENTRY *) ellFirst(&pbucket->list); - while (ppvdNode) { - const char *recordname = ppvdNode->precnode->recordname; - - if (strncmp(name, recordname, lenName) == 0 && - strlen(recordname) == lenName) - break; - ppvdNode = (PVDENTRY *) ellNext((ELLNODE *)ppvdNode); - } - epicsMutexUnlock(pbucket->lock); - return ppvdNode; -} - -PVDENTRY *dbPvdAdd(dbBase *pdbbase, dbRecordType *precordType, - dbRecordNode *precnode) -{ - dbPvd *ppvd = pdbbase->ppvd; - dbPvdBucket *pbucket; - PVDENTRY *ppvdNode; - char *name = precnode->recordname; - unsigned int h; - - h = epicsStrHash(name, 0) & ppvd->mask; - pbucket = ppvd->buckets[h]; - if (pbucket == NULL) { - pbucket = dbCalloc(1, sizeof(dbPvdBucket)); - ellInit(&pbucket->list); - pbucket->lock = epicsMutexCreate(); - ppvd->buckets[h] = pbucket; - } - - epicsMutexMustLock(pbucket->lock); - ppvdNode = (PVDENTRY *) ellFirst(&pbucket->list); - while (ppvdNode) { - if (strcmp(name, ppvdNode->precnode->recordname) == 0) { - epicsMutexUnlock(pbucket->lock); - return NULL; - } - ppvdNode = (PVDENTRY *) ellNext((ELLNODE *)ppvdNode); - } - ppvdNode = dbCalloc(1, sizeof(PVDENTRY)); - ppvdNode->precordType = precordType; - ppvdNode->precnode = precnode; - ellAdd(&pbucket->list, (ELLNODE *)ppvdNode); - epicsMutexUnlock(pbucket->lock); - return ppvdNode; -} - -void dbPvdDelete(dbBase *pdbbase, dbRecordNode *precnode) -{ - dbPvd *ppvd = pdbbase->ppvd; - dbPvdBucket *pbucket; - PVDENTRY *ppvdNode; - char *name = precnode->recordname; - - pbucket = ppvd->buckets[epicsStrHash(name, 0) & ppvd->mask]; - if (pbucket == NULL) return; - - epicsMutexMustLock(pbucket->lock); - ppvdNode = (PVDENTRY *) ellFirst(&pbucket->list); - while (ppvdNode) { - if (ppvdNode->precnode && - ppvdNode->precnode->recordname && - strcmp(name, ppvdNode->precnode->recordname) == 0) { - ellDelete(&pbucket->list, (ELLNODE *)ppvdNode); - free(ppvdNode); - break; - } - ppvdNode = (PVDENTRY *) ellNext((ELLNODE *)ppvdNode); - } - epicsMutexUnlock(pbucket->lock); - return; -} - -void dbPvdFreeMem(dbBase *pdbbase) -{ - dbPvd *ppvd = pdbbase->ppvd; - unsigned int h; - - if (ppvd == NULL) return; - pdbbase->ppvd = NULL; - - for (h = 0; h < ppvd->size; h++) { - dbPvdBucket *pbucket = ppvd->buckets[h]; - PVDENTRY *ppvdNode; - - if (pbucket == NULL) continue; - epicsMutexMustLock(pbucket->lock); - ppvd->buckets[h] = NULL; - while ((ppvdNode = (PVDENTRY *) ellFirst(&pbucket->list))) { - ellDelete(&pbucket->list, (ELLNODE *)ppvdNode); - free(ppvdNode); - } - epicsMutexUnlock(pbucket->lock); - epicsMutexDestroy(pbucket->lock); - free(pbucket); - } - free(ppvd->buckets); - free(ppvd); -} - -void dbPvdDump(dbBase *pdbbase, int verbose) -{ - unsigned int empty = 0; - dbPvd *ppvd; - unsigned int h; - - if (!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - ppvd = pdbbase->ppvd; - if (ppvd == NULL) return; - - printf("Process Variable Directory has %u buckets", ppvd->size); - - for (h = 0; h < ppvd->size; h++) { - dbPvdBucket *pbucket = ppvd->buckets[h]; - PVDENTRY *ppvdNode; - int i = 1; - - if (pbucket == NULL) { - empty++; - continue; - } - epicsMutexMustLock(pbucket->lock); - ppvdNode = (PVDENTRY *) ellFirst(&pbucket->list); - printf("\n [%4u] %4d ", h, ellCount(&pbucket->list)); - while (ppvdNode && verbose) { - if (!(++i % 4)) - printf("\n "); - printf(" %s", ppvdNode->precnode->recordname); - ppvdNode = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode); - } - epicsMutexUnlock(pbucket->lock); - } - printf("\n%u buckets empty.\n", empty); -} diff --git a/src/ioc/dbStatic/dbStaticIocRegister.c b/src/ioc/dbStatic/dbStaticIocRegister.c deleted file mode 100644 index 65acc198d..000000000 --- a/src/ioc/dbStatic/dbStaticIocRegister.c +++ /dev/null @@ -1,179 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "iocsh.h" - -#define epicsExportSharedSymbols -#include "dbStaticIocRegister.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" - -/* common arguments */ - -static const iocshArg argPdbbase = { "pdbbase", iocshArgPdbbase}; -static const iocshArg argRecType = { "recordTypeName", iocshArgString}; - - -/* dbDumpPath */ -static const iocshArg * const dbDumpPathArgs[] = {&argPdbbase}; -static const iocshFuncDef dbDumpPathFuncDef = {"dbDumpPath",1,dbDumpPathArgs}; -static void dbDumpPathCallFunc(const iocshArgBuf *args) -{ - dbDumpPath(*iocshPpdbbase); -} - -/* dbDumpRecord */ -static const iocshArg dbDumpRecordArg2 = { "interest level",iocshArgInt}; -static const iocshArg * const dbDumpRecordArgs[] = - {&argPdbbase, &argRecType, &dbDumpRecordArg2}; -static const iocshFuncDef dbDumpRecordFuncDef = - {"dbDumpRecord",3,dbDumpRecordArgs}; -static void dbDumpRecordCallFunc(const iocshArgBuf *args) -{ - dbDumpRecord(*iocshPpdbbase,args[1].sval,args[2].ival); -} - -/* dbDumpMenu */ -static const iocshArg dbDumpMenuArg1 = { "menuName",iocshArgString}; -static const iocshArg * const dbDumpMenuArgs[] = { - &argPdbbase, &dbDumpMenuArg1}; -static const iocshFuncDef dbDumpMenuFuncDef = {"dbDumpMenu",2,dbDumpMenuArgs}; -static void dbDumpMenuCallFunc(const iocshArgBuf *args) -{ - dbDumpMenu(*iocshPpdbbase,args[1].sval); -} - -/* dbDumpRecordType */ -static const iocshArg * const dbDumpRecordTypeArgs[] = - {&argPdbbase, &argRecType}; -static const iocshFuncDef dbDumpRecordTypeFuncDef = - {"dbDumpRecordType",2,dbDumpRecordTypeArgs}; -static void dbDumpRecordTypeCallFunc(const iocshArgBuf *args) -{ - dbDumpRecordType(*iocshPpdbbase,args[1].sval); -} - -/* dbDumpField */ -static const iocshArg dbDumpFieldArg2 = { "fieldName",iocshArgString}; -static const iocshArg * const dbDumpFieldArgs[] = - {&argPdbbase, &argRecType,&dbDumpFieldArg2}; -static const iocshFuncDef dbDumpFieldFuncDef = {"dbDumpField",3,dbDumpFieldArgs}; -static void dbDumpFieldCallFunc(const iocshArgBuf *args) -{ - dbDumpField(*iocshPpdbbase,args[1].sval,args[2].sval); -} - -/* dbDumpDevice */ -static const iocshArg * const dbDumpDeviceArgs[] = { - &argPdbbase, &argRecType}; -static const iocshFuncDef dbDumpDeviceFuncDef = {"dbDumpDevice",2,dbDumpDeviceArgs}; -static void dbDumpDeviceCallFunc(const iocshArgBuf *args) -{ - dbDumpDevice(*iocshPpdbbase,args[1].sval); -} - -/* dbDumpDriver */ -static const iocshArg * const dbDumpDriverArgs[] = { &argPdbbase}; -static const iocshFuncDef dbDumpDriverFuncDef = {"dbDumpDriver",1,dbDumpDriverArgs}; -static void dbDumpDriverCallFunc(const iocshArgBuf *args) -{ - dbDumpDriver(*iocshPpdbbase); -} - -/* dbDumpLink */ -static const iocshArg * const dbDumpLinkArgs[] = { &argPdbbase}; -static const iocshFuncDef dbDumpLinkFuncDef = {"dbDumpLink",1,dbDumpLinkArgs}; -static void dbDumpLinkCallFunc(const iocshArgBuf *args) -{ - dbDumpLink(*iocshPpdbbase); -} - -/* dbDumpRegistrar */ -static const iocshArg * const dbDumpRegistrarArgs[] = { &argPdbbase}; -static const iocshFuncDef dbDumpRegistrarFuncDef = {"dbDumpRegistrar",1,dbDumpRegistrarArgs}; -static void dbDumpRegistrarCallFunc(const iocshArgBuf *args) -{ - dbDumpRegistrar(*iocshPpdbbase); -} - -/* dbDumpFunction */ -static const iocshArg * const dbDumpFunctionArgs[] = { &argPdbbase}; -static const iocshFuncDef dbDumpFunctionFuncDef = {"dbDumpFunction",1,dbDumpFunctionArgs}; -static void dbDumpFunctionCallFunc(const iocshArgBuf *args) -{ - dbDumpFunction(*iocshPpdbbase); -} - -/* dbDumpVariable */ -static const iocshArg * const dbDumpVariableArgs[] = { &argPdbbase}; -static const iocshFuncDef dbDumpVariableFuncDef = {"dbDumpVariable",1,dbDumpVariableArgs}; -static void dbDumpVariableCallFunc(const iocshArgBuf *args) -{ - dbDumpVariable(*iocshPpdbbase); -} - -/* dbDumpBreaktable */ -static const iocshArg dbDumpBreaktableArg1 = { "tableName",iocshArgString}; -static const iocshArg * const dbDumpBreaktableArgs[] = - {&argPdbbase,&dbDumpBreaktableArg1}; -static const iocshFuncDef dbDumpBreaktableFuncDef = - {"dbDumpBreaktable",2,dbDumpBreaktableArgs}; -static void dbDumpBreaktableCallFunc(const iocshArgBuf *args) -{ - dbDumpBreaktable(*iocshPpdbbase,args[1].sval); -} - -/* dbPvdDump */ -static const iocshArg dbPvdDumpArg1 = { "verbose",iocshArgInt}; -static const iocshArg * const dbPvdDumpArgs[] = { - &argPdbbase,&dbPvdDumpArg1}; -static const iocshFuncDef dbPvdDumpFuncDef = {"dbPvdDump",2,dbPvdDumpArgs}; -static void dbPvdDumpCallFunc(const iocshArgBuf *args) -{ - dbPvdDump(*iocshPpdbbase,args[1].ival); -} - -/* dbPvdTableSize */ -static const iocshArg dbPvdTableSizeArg0 = { "size",iocshArgInt}; -static const iocshArg * const dbPvdTableSizeArgs[1] = - {&dbPvdTableSizeArg0}; -static const iocshFuncDef dbPvdTableSizeFuncDef = - {"dbPvdTableSize",1,dbPvdTableSizeArgs}; -static void dbPvdTableSizeCallFunc(const iocshArgBuf *args) -{ - dbPvdTableSize(args[0].ival); -} - -/* dbReportDeviceConfig */ -static const iocshArg * const dbReportDeviceConfigArgs[] = {&argPdbbase}; -static const iocshFuncDef dbReportDeviceConfigFuncDef = { - "dbReportDeviceConfig",1,dbReportDeviceConfigArgs}; -static void dbReportDeviceConfigCallFunc(const iocshArgBuf *args) -{ - dbReportDeviceConfig(*iocshPpdbbase,stdout); -} - -void dbStaticIocRegister(void) -{ - iocshRegister(&dbDumpPathFuncDef, dbDumpPathCallFunc); - iocshRegister(&dbDumpRecordFuncDef, dbDumpRecordCallFunc); - iocshRegister(&dbDumpMenuFuncDef, dbDumpMenuCallFunc); - iocshRegister(&dbDumpRecordTypeFuncDef, dbDumpRecordTypeCallFunc); - iocshRegister(&dbDumpFieldFuncDef, dbDumpFieldCallFunc); - iocshRegister(&dbDumpDeviceFuncDef, dbDumpDeviceCallFunc); - iocshRegister(&dbDumpDriverFuncDef, dbDumpDriverCallFunc); - iocshRegister(&dbDumpLinkFuncDef, dbDumpLinkCallFunc); - iocshRegister(&dbDumpRegistrarFuncDef,dbDumpRegistrarCallFunc); - iocshRegister(&dbDumpFunctionFuncDef, dbDumpFunctionCallFunc); - iocshRegister(&dbDumpVariableFuncDef, dbDumpVariableCallFunc); - iocshRegister(&dbDumpBreaktableFuncDef, dbDumpBreaktableCallFunc); - iocshRegister(&dbPvdDumpFuncDef, dbPvdDumpCallFunc); - iocshRegister(&dbPvdTableSizeFuncDef,dbPvdTableSizeCallFunc); - iocshRegister(&dbReportDeviceConfigFuncDef, dbReportDeviceConfigCallFunc); -} diff --git a/src/ioc/dbStatic/dbStaticIocRegister.h b/src/ioc/dbStatic/dbStaticIocRegister.h deleted file mode 100644 index 0b7ff743b..000000000 --- a/src/ioc/dbStatic/dbStaticIocRegister.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_dbStaticIocRegister_H -#define INC_dbStaticIocRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void dbStaticIocRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbStaticIocRegister_H */ diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c deleted file mode 100644 index d647f787d..000000000 --- a/src/ioc/dbStatic/dbStaticLib.c +++ /dev/null @@ -1,3390 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#include "cantProceed.h" -#include "cvtFast.h" -#include "epicsAssert.h" -#include "dbDefs.h" -#include "dbmf.h" -#include "ellLib.h" -#include "epicsPrint.h" -#include "epicsStdio.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "errlog.h" -#include "gpHash.h" -#include "osiFileName.h" -#include "postfix.h" - -#define DBFLDTYPES_GBLSOURCE -#define SPECIAL_GBLSOURCE - -#define epicsExportSharedSymbols -#include "dbChannel.h" -#include "dbFldTypes.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "devSup.h" -#include "drvSup.h" -#include "link.h" -#include "special.h" - -#include "dbCommon.h" -#include "dbJLink.h" - -int dbStaticDebug = 0; -static char *pNullString = ""; -#define messagesize 276 -#define RPCL_LEN INFIX_TO_POSTFIX_SIZE(80) - -/* must be long enough to hold 32-bit signed integer in base 10 */ -STATIC_ASSERT(messagesize>=11); - -static char *ppstring[5]={" NPP"," PP"," CA"," CP"," CPP"}; -static char *msstring[4]={" NMS"," MS"," MSI"," MSS"}; - -epicsShareDef maplinkType pamaplinkType[LINK_NTYPES] = { - {"CONSTANT",CONSTANT}, - {"PV_LINK",PV_LINK}, - {"VME_IO",VME_IO}, - {"CAMAC_IO",CAMAC_IO}, - {"AB_IO",AB_IO}, - {"GPIB_IO",GPIB_IO}, - {"BITBUS_IO",BITBUS_IO}, - {"MACRO_LINK",MACRO_LINK}, - {"JSON_LINK",JSON_LINK}, - {"PN_LINK",PN_LINK}, - {"DB_LINK",DB_LINK}, - {"CA_LINK",CA_LINK}, - {"INST_IO",INST_IO}, - {"BBGPIB_IO",BBGPIB_IO}, - {"RF_IO",RF_IO}, - {"VXI_IO",VXI_IO} -}; - -static int mapDBFtoDCT[DBF_NOACCESS+1] = { - DCT_STRING, - DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER, - DCT_REAL,DCT_REAL, - DCT_INTEGER, - DCT_MENU, - DCT_MENUFORM, - DCT_INLINK,DCT_OUTLINK,DCT_FWDLINK, - DCT_NOACCESS}; - -/*forward references for private routines*/ -static void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...) - EPICS_PRINTF_STYLE(2,3); -static long dbAddOnePath (DBBASE *pdbbase, const char *path, unsigned length); - -/* internal routines*/ -static FILE *openOutstream(const char *filename) -{ - FILE *stream; - errno = 0; - stream = fopen(filename,"w"); - if(!stream) { - fprintf(stderr,"error opening %s %s\n",filename,strerror(errno)); - return 0; - } - return stream; -} - -static void finishOutstream(FILE *stream) -{ - if(stream==stdout) { - fflush(stdout); - } else { - if(fclose(stream)) fprintf(stderr,"fclose error %s\n",strerror(errno)); - } -} - -void dbFreeLinkContents(struct link *plink) -{ - char *parm = NULL; - - switch(plink->type) { - case CONSTANT: free((void *)plink->value.constantStr); break; - case MACRO_LINK: free((void *)plink->value.macro_link.macroStr); break; - case PV_LINK: free((void *)plink->value.pv_link.pvname); break; - case JSON_LINK: - dbJLinkFree(plink->value.json.jlink); - parm = plink->value.json.string; - break; - case VME_IO: parm = plink->value.vmeio.parm; break; - case CAMAC_IO: parm = plink->value.camacio.parm; break; - case AB_IO: parm = plink->value.abio.parm; break; - case GPIB_IO: parm = plink->value.gpibio.parm; break; - case BITBUS_IO: parm = plink->value.bitbusio.parm;break; - case INST_IO: parm = plink->value.instio.string; break; - case BBGPIB_IO: parm = plink->value.bbgpibio.parm;break; - case RF_IO: break; - case VXI_IO: parm = plink->value.vxiio.parm; break; - default: - epicsPrintf("dbFreeLink called but link type %d unknown\n", plink->type); - } - if(parm && (parm != pNullString)) free((void *)parm); - if(plink->text) free(plink->text); - plink->lset = NULL; - plink->text = NULL; - memset(&plink->value, 0, sizeof(union value)); -} - -void dbFreePath(DBBASE *pdbbase) -{ - ELLLIST *ppathList; - dbPathNode *pdbPathNode; - - if(!pdbbase) return; - ppathList = (ELLLIST *)pdbbase->pathPvt; - if(!ppathList) return; - while((pdbPathNode = (dbPathNode *)ellFirst(ppathList))) { - ellDelete(ppathList,&pdbPathNode->node); - free((void *)pdbPathNode->directory); - free((void *)pdbPathNode); - } - free((void *)ppathList); - pdbbase->pathPvt = 0; - return; -} - - -static void entryErrMessage(DBENTRY *pdbentry,long status,char *mess) -{ - char message[200]; - char *pmessage=&message[0]; - dbRecordNode *precnode = pdbentry->precnode; - dbFldDes *pflddes = pdbentry->pflddes; - char *pname = NULL; - - *pmessage=0; - if(pdbentry->precordType) pname = pdbentry->precordType->name; - if(pname) { - strcat(pmessage,"RecordType:"); - strcat(pmessage,pname); - } - if(precnode){ - if (dbIsAlias(pdbentry)) - strcat(pmessage," Record Alias:"); - else - strcat(pmessage," Record:"); - strcat(pmessage,(char *)precnode->precord); - } - if(pflddes) { - char *pstr=pflddes->name; - - strcat(pmessage," Field:"); - strcat(pmessage,pstr); - } - strcat(pmessage,"\n"); - strcat(pmessage,mess); - errMessage(status,pmessage); -} - -static void zeroDbentry(DBENTRY *pdbentry) -{ - /*NOTE that pdbbase and message MUST NOT be set to NULL*/ - pdbentry->precordType=NULL; - pdbentry->pflddes=NULL; - pdbentry->precnode=NULL; - pdbentry->pfield=NULL; - pdbentry->indfield=0; -} - -static char *getpMessage(DBENTRY *pdbentry) -{ - char *msg = pdbentry->message; - if (!msg) { - msg = dbCalloc(1, messagesize); - pdbentry->message = msg; - } - *msg = '\0'; - return msg; -} - -static -void dbMsgCpy(DBENTRY *pdbentry, const char *msg) -{ - getpMessage(pdbentry); - strncpy(pdbentry->message, msg, messagesize-1); - pdbentry->message[messagesize-1] = '\0'; -} - -static -void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...) -{ - va_list args; - getpMessage(pdbentry); - va_start(args, fmt); - epicsVsnprintf(pdbentry->message, messagesize, fmt, args); - va_end(args); -} - -static void ulongToHexString(epicsUInt32 source, char *pdest) -{ - static const char hex_digit_to_ascii[16] = "0123456789abcdef"; - epicsUInt32 val,temp; - char digit[10]; - int i,j; - - if (source==0) { - strcpy(pdest,"0x0"); - return; - } - *pdest++ = '0'; *pdest++ = 'x'; - val = source; - for (i=0; val!=0; i++) { - temp = val/16; - digit[i] = hex_digit_to_ascii[val - temp*16]; - val = temp; - } - for (j=i-1; j>=0; j--) { - *pdest++ = digit[j]; - } - *pdest = 0; - return; -} - -static void realToString(double value, char *preturn, int isdouble) -{ - static const double delta[2] = {1e-6, 1e-15}; - static const int precision[2] = {6, 14}; - double absvalue; - int logval,prec; - size_t end; - char tstr[30]; - char *ptstr = &tstr[0]; - int round; - int ise = FALSE; - char *loce = NULL; - - if (value == 0) { - strcpy(preturn, "0"); - return; - } - - absvalue = value < 0 ? -value : value; - if (absvalue < (double)INT_MAX) { - epicsInt32 intval = (epicsInt32) value; - double diff = value - intval; - - if (diff < 0) diff = -diff; - if (diff < absvalue * delta[isdouble]) { - cvtLongToString(intval, preturn); - return; - } - } - - /*Now starts the hard cases*/ - if (value < 0) { - *preturn++ = '-'; - value = -value; - } - - logval = (int)log10(value); - if (logval > 6 || logval < -2) { - int nout; - - ise = TRUE; - prec = precision[isdouble]; - nout = sprintf(ptstr, "%.*e", prec, value); - loce = strchr(ptstr, 'e'); - - if (!loce) { - ptstr[nout] = 0; - strcpy(preturn, ptstr); - return; - } - - *loce++ = 0; - } else { - prec = precision[isdouble] - logval; - if ( prec < 0) prec = 0; - sprintf(ptstr, "%.*f", prec, value); - } - - if (prec > 0) { - end = strlen(ptstr) - 1; - round = FALSE; - while (end > 0) { - if (tstr[end] == '.') {end--; break;} - if (tstr[end] == '0') {end--; continue;} - if (!round && end < precision[isdouble]) break; - if (!round && tstr[end] < '8') break; - if (tstr[end-1] == '.') { - if (round) end = end-2; - break; - } - if (tstr[end-1] != '9') break; - round = TRUE; - end--; - } - tstr[end+1] = 0; - while (round) { - if (tstr[end] < '9') {tstr[end]++; break;} - if (end == 0) { *preturn++ = '1'; tstr[end] = '0'; break;} - tstr[end--] = '0'; - } - } - strcpy(preturn, &tstr[0]); - if (ise) { - if (!(strchr(preturn, '.'))) strcat(preturn, ".0"); - strcat(preturn, "e"); - strcat(preturn, loce); - } -} - -static void floatToString(float value, char *preturn) -{ - realToString((double)value, preturn, 0); -} - -static void doubleToString(double value, char *preturn) -{ - realToString(value, preturn, 1); -} - -/*Public only for dbStaticNoRun*/ -dbDeviceMenu *dbGetDeviceMenu(DBENTRY *pdbentry) -{ - dbRecordType *precordType = pdbentry->precordType; - dbFldDes *pflddes = pdbentry->pflddes; - dbDeviceMenu *pdbDeviceMenu; - devSup *pdevSup; - int ind; - int nChoice; - - if(!precordType) return(NULL); - if(!pflddes) return(NULL); - if(pflddes->field_type!=DBF_DEVICE) return(NULL); - if(pflddes->ftPvt){ - pdbDeviceMenu = (dbDeviceMenu *)pflddes->ftPvt; - if(pdbDeviceMenu->nChoice == ellCount(&precordType->devList)) - return(pdbDeviceMenu); - free((void *)pdbDeviceMenu->papChoice); - free((void *)pdbDeviceMenu); - pflddes->ftPvt = NULL; - } - nChoice = ellCount(&precordType->devList); - if(nChoice <= 0) return(NULL); - pdbDeviceMenu = dbCalloc(1,sizeof(dbDeviceMenu)); - pdbDeviceMenu->nChoice = nChoice; - pdbDeviceMenu->papChoice = dbCalloc(pdbDeviceMenu->nChoice,sizeof(char *)); - pdevSup = (devSup *)ellFirst(&precordType->devList); - ind = 0; - while(pdevSup) { - pdbDeviceMenu->papChoice[ind] = pdevSup->choice; - ind++; - pdevSup = (devSup *)ellNext(&pdevSup->node); - } - pflddes->ftPvt = pdbDeviceMenu; - return(pdbDeviceMenu); -} - -/* Beginning of Public Routines */ - -#define INC_SIZE 256 -void dbCatString(char **string,int *stringLength,char *src,char *separator) -{ - if((*string==NULL) - || ((strlen(*string)+strlen(src)+2) > (size_t)*stringLength)) { - char *newString; - size_t size; - - size = strlen(src); - if(*string) size += strlen(*string); - /*Make size multiple of INC_SIZE*/ - size = ((size + 2 + INC_SIZE)/INC_SIZE) * INC_SIZE; - newString = dbCalloc(size,sizeof(char)); - if(*string) { - strcpy(newString,*string); - free((void *)(*string)); - } - *string = newString; - } - if(*stringLength>0) { - strcat(*string,separator); - *stringLength += (int) strlen(separator); - } - strcat(*string,src); - *stringLength += (int) strlen(src); -} - -dbBase * dbAllocBase(void) -{ - dbBase *pdbbase; - - pdbbase = dbCalloc(1,sizeof(dbBase)); - ellInit(&pdbbase->menuList); - ellInit(&pdbbase->recordTypeList); - ellInit(&pdbbase->drvList); - ellInit(&pdbbase->registrarList); - ellInit(&pdbbase->functionList); - ellInit(&pdbbase->variableList); - ellInit(&pdbbase->bptList); - ellInit(&pdbbase->filterList); - ellInit(&pdbbase->guiGroupList); - gphInitPvt(&pdbbase->pgpHash,256); - dbPvdInitPvt(pdbbase); - return (pdbbase); -} -void dbFreeBase(dbBase *pdbbase) -{ - dbMenu *pdbMenu; - dbMenu *pdbMenuNext; - dbRecordType *pdbRecordType; - dbRecordType *pdbRecordTypeNext; - dbFldDes * pdbFldDes; - dbRecordAttribute *pAttribute; - dbRecordAttribute *pAttributeNext; - devSup *pdevSup; - devSup *pdevSupNext; - dbText *ptext; - dbText *ptextNext; - dbVariableDef *pvar; - dbVariableDef *pvarNext; - drvSup *pdrvSup; - drvSup *pdrvSupNext; - linkSup *plinkSup; - brkTable *pbrkTable; - brkTable *pbrkTableNext; - chFilterPlugin *pfilt; - chFilterPlugin *pfiltNext; - dbGuiGroup *pguiGroup; - dbGuiGroup *pguiGroupNext; - int i; - DBENTRY dbentry; - long status; - - dbInitEntry(pdbbase,&dbentry); - status = dbFirstRecordType(&dbentry); - while(!status) { - /* dbDeleteRecord() will remove alias or real record node. - * For real record nodes, also removes the nodes of all aliases. - * This complicates safe traversal, so we re-start iteration - * from the first record after each call. - */ - while((status = dbFirstRecord(&dbentry))==0) { - dbDeleteRecord(&dbentry); - } - assert(status==S_dbLib_recNotFound); - status = dbNextRecordType(&dbentry); - } - dbFinishEntry(&dbentry); - pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - while(pdbRecordType) { - for(i=0; ino_fields; i++) { - pdbFldDes = pdbRecordType->papFldDes[i]; - free((void *)pdbFldDes->prompt); - free((void *)pdbFldDes->name); - free((void *)pdbFldDes->extra); - free((void *)pdbFldDes->initial); - if(pdbFldDes->field_type==DBF_DEVICE && pdbFldDes->ftPvt) { - dbDeviceMenu *pdbDeviceMenu; - - pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt; - free((void *)pdbDeviceMenu->papChoice); - free((void *)pdbDeviceMenu); - pdbFldDes->ftPvt=0; - } - free((void *)pdbFldDes); - } - pdevSup = (devSup *)ellFirst(&pdbRecordType->devList); - while(pdevSup) { - pdevSupNext = (devSup *)ellNext(&pdevSup->node); - ellDelete(&pdbRecordType->devList,&pdevSup->node); - free((void *)pdevSup->name); - free((void *)pdevSup->choice); - free((void *)pdevSup); - pdevSup = pdevSupNext; - } - ptext = (dbText *)ellFirst(&pdbRecordType->cdefList); - while(ptext) { - ptextNext = (dbText *)ellNext(&ptext->node); - ellDelete(&pdbRecordType->cdefList,&ptext->node); - free((void *)ptext->text); - free((void *)ptext); - ptext = ptextNext; - } - pAttribute = - (dbRecordAttribute *)ellFirst(&pdbRecordType->attributeList); - while(pAttribute) { - pAttributeNext = (dbRecordAttribute *)ellNext(&pAttribute->node); - ellDelete(&pdbRecordType->attributeList,&pAttribute->node); - free((void *)pAttribute->name); - free((void *)pAttribute->pdbFldDes); - free(pAttribute); - pAttribute = pAttributeNext; - } - pdbRecordTypeNext = (dbRecordType *)ellNext(&pdbRecordType->node); - gphDelete(pdbbase->pgpHash,pdbRecordType->name,&pdbbase->recordTypeList); - ellDelete(&pdbbase->recordTypeList,&pdbRecordType->node); - free((void *)pdbRecordType->name); - free((void *)pdbRecordType->link_ind); - free((void *)pdbRecordType->papsortFldName); - free((void *)pdbRecordType->sortFldInd); - free((void *)pdbRecordType->papFldDes); - free((void *)pdbRecordType); - pdbRecordType = pdbRecordTypeNext; - } - pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); - while(pdbMenu) { - pdbMenuNext = (dbMenu *)ellNext(&pdbMenu->node); - gphDelete(pdbbase->pgpHash,pdbMenu->name,&pdbbase->menuList); - ellDelete(&pdbbase->menuList,&pdbMenu->node); - for(i=0; i< pdbMenu->nChoice; i++) { - free((void *)pdbMenu->papChoiceName[i]); - free((void *)pdbMenu->papChoiceValue[i]); - } - free((void *)pdbMenu->papChoiceName); - free((void *)pdbMenu->papChoiceValue); - free((void *)pdbMenu ->name); - free((void *)pdbMenu); - pdbMenu = pdbMenuNext; - } - pdrvSup = (drvSup *)ellFirst(&pdbbase->drvList); - while(pdrvSup) { - pdrvSupNext = (drvSup *)ellNext(&pdrvSup->node); - ellDelete(&pdbbase->drvList,&pdrvSup->node); - free((void *)pdrvSup->name); - free((void *)pdrvSup); - pdrvSup = pdrvSupNext; - } - while ((plinkSup = (linkSup *) ellGet(&pdbbase->linkList))) { - free(plinkSup->jlif_name); - free(plinkSup->name); - free(plinkSup); - } - ptext = (dbText *)ellFirst(&pdbbase->registrarList); - while(ptext) { - ptextNext = (dbText *)ellNext(&ptext->node); - ellDelete(&pdbbase->registrarList,&ptext->node); - free((void *)ptext->text); - free((void *)ptext); - ptext = ptextNext; - } - ptext = (dbText *)ellFirst(&pdbbase->functionList); - while(ptext) { - ptextNext = (dbText *)ellNext(&ptext->node); - ellDelete(&pdbbase->functionList,&ptext->node); - free((void *)ptext->text); - free((void *)ptext); - ptext = ptextNext; - } - pvar = (dbVariableDef *)ellFirst(&pdbbase->variableList); - while(pvar) { - pvarNext = (dbVariableDef *)ellNext(&pvar->node); - ellDelete(&pdbbase->variableList,&pvar->node); - free((void *)pvar->name); - free((void *)pvar->type); - free((void *)pvar); - pvar = pvarNext; - } - pbrkTable = (brkTable *)ellFirst(&pdbbase->bptList); - while(pbrkTable) { - pbrkTableNext = (brkTable *)ellNext(&pbrkTable->node); - gphDelete(pdbbase->pgpHash,pbrkTable->name,&pdbbase->bptList); - ellDelete(&pdbbase->bptList,&pbrkTable->node); - free(pbrkTable->name); - free((void *)pbrkTable->paBrkInt); - free((void *)pbrkTable); - pbrkTable = pbrkTableNext; - } - pfilt = (chFilterPlugin *)ellFirst(&pdbbase->filterList); - while(pfilt) { - pfiltNext = (chFilterPlugin *)ellNext(&pfilt->node); - free((char*)pfilt->name); - if(pfilt->fif->priv_free) - (*pfilt->fif->priv_free)(pfilt->puser); - free(pfilt); - pfilt = pfiltNext; - } - pguiGroup = (dbGuiGroup *)ellFirst(&pdbbase->guiGroupList); - while (pguiGroup) { - pguiGroupNext = (dbGuiGroup *)ellNext(&pguiGroup->node); - gphDelete(pdbbase->pgpHash, pguiGroup->name, &pdbbase->guiGroupList); - ellDelete(&pdbbase->guiGroupList, &pguiGroup->node); - free(pguiGroup->name); - free((void *)pguiGroup); - pguiGroup = pguiGroupNext; - } - gphFreeMem(pdbbase->pgpHash); - dbPvdFreeMem(pdbbase); - dbFreePath(pdbbase); - free((void *)pdbbase); - pdbbase = NULL; - return; -} - -DBENTRY * dbAllocEntry(dbBase *pdbbase) -{ - DBENTRY *pdbentry; - - pdbentry = dbmfMalloc(sizeof(DBENTRY)); - memset(pdbentry,'\0',sizeof(DBENTRY)); - pdbentry->pdbbase = pdbbase; - return(pdbentry); -} - -void dbFreeEntry(DBENTRY *pdbentry) -{ - if (!pdbentry) - return; - if (pdbentry->message) - free((void *)pdbentry->message); - dbmfFree(pdbentry); -} - -void dbInitEntry(dbBase *pdbbase,DBENTRY *pdbentry) -{ - memset((char *)pdbentry,'\0',sizeof(DBENTRY)); - pdbentry->pdbbase = pdbbase; -} - -void dbFinishEntry(DBENTRY *pdbentry) -{ - if(pdbentry->message) { - free((void *)pdbentry->message); - pdbentry->message = NULL; - } -} - -DBENTRY * dbCopyEntry(DBENTRY *pdbentry) -{ - DBENTRY *pnew; - - pnew = dbAllocEntry(pdbentry->pdbbase); - *pnew = *pdbentry; - pnew->message = NULL; - return(pnew); -} - -void dbCopyEntryContents(DBENTRY *pfrom,DBENTRY *pto) -{ - *pto = *pfrom; - pto->message = NULL; -} - - -long dbPath(DBBASE *pdbbase,const char *path) -{ - if(!pdbbase) return(-1); - dbFreePath(pdbbase); - if(!path || strlen(path)==0) return(dbAddPath(pdbbase,".")); - return(dbAddPath(pdbbase,path)); -} - -long dbAddPath(DBBASE *pdbbase,const char *path) -{ - ELLLIST *ppathList; - const char *pcolon; - const char *plast; - unsigned expectingPath; - unsigned sawMissingPath; - - if(!pdbbase) return(-1); - ppathList = (ELLLIST *)pdbbase->pathPvt; - if(!ppathList) { - ppathList = dbCalloc(1,sizeof(ELLLIST)); - ellInit(ppathList); - pdbbase->pathPvt = (void *)ppathList; - } - if (!path) return(0); /* Empty path strings are ignored */ - /* care is taken to properly deal with white space - * 1) preceding and trailing white space is removed from paths - * 2) white space inbetween path separator counts as an empty name - * (see below) - */ - expectingPath = FALSE; - sawMissingPath = FALSE; - while (*path) { - size_t len; - - /* preceding white space is removed */ - if (isspace((int)*path)) { - path++; - continue; - } - pcolon = strstr (path, OSI_PATH_LIST_SEPARATOR); - if (pcolon==path) { - sawMissingPath = TRUE; - path += strlen (OSI_PATH_LIST_SEPARATOR); - continue; - } - if (pcolon) { - plast = pcolon - 1; - expectingPath = TRUE; - } else { - plast = strlen (path) + path - 1; - expectingPath = FALSE; - } - /* trailing white space is removed */ - while (isspace((int)*plast)) { - plast--; - } - - /* - * len is always nonzero because we found something that - * 1) isnt white space - * 2) isnt a path separator - */ - len = (plast - path) + 1; - if (dbAddOnePath (pdbbase, path, (unsigned) len)) return (-1); - path += len; - if (pcolon) { - path += strlen(OSI_PATH_LIST_SEPARATOR); - } - } - - /* - * an empty name at beginning, middle, or end of a path string that isnt - * empty means current directory - */ - if (expectingPath||sawMissingPath) { - return dbAddOnePath (pdbbase, ".", 1); - } - return(0); -} - -static long dbAddOnePath (DBBASE *pdbbase, const char *path, unsigned length) -{ - ELLLIST *ppathList; - dbPathNode *pdbPathNode; - - if(!pdbbase) return(-1); - ppathList = (ELLLIST *)pdbbase->pathPvt; - - pdbPathNode = (dbPathNode *)dbCalloc(1, sizeof(dbPathNode)); - pdbPathNode->directory = (char *)dbCalloc(length+1, sizeof(char)); - strncpy(pdbPathNode->directory, path, length); - pdbPathNode->directory[length] = '\0'; - ellAdd(ppathList, &pdbPathNode->node); - return 0; -} - -char *dbGetPromptGroupNameFromKey(DBBASE *pdbbase, const short key) -{ - dbGuiGroup *pdbGuiGroup; - - if (!pdbbase) return NULL; - for (pdbGuiGroup = (dbGuiGroup *)ellFirst(&pdbbase->guiGroupList); - pdbGuiGroup; pdbGuiGroup = (dbGuiGroup *)ellNext(&pdbGuiGroup->node)) { - if (pdbGuiGroup->key == key) return pdbGuiGroup->name; - } - return NULL; -} - -short dbGetPromptGroupKeyFromName(DBBASE *pdbbase, const char *name) -{ - GPHENTRY *pgphentry; - - if (!pdbbase) return 0; - pgphentry = gphFind(pdbbase->pgpHash, name, &pdbbase->guiGroupList); - if (!pgphentry) { - return 0; - } else { - return ((dbGuiGroup*)pgphentry->userPvt)->key; - } -} - - -long dbWriteRecord(DBBASE *ppdbbase,const char *filename, - const char *precordTypename,int level) -{ - FILE *stream; - long status; - - stream = openOutstream(filename); - if(!stream) return -1; - status = dbWriteRecordFP(ppdbbase,stream,precordTypename,level); - finishOutstream(stream); - return status; -} - -long dbWriteRecordFP( - DBBASE *pdbbase,FILE *fp,const char *precordTypename,int level) -{ - DBENTRY dbentry; - DBENTRY *pdbentry=&dbentry; - long status; - int dctonly; - - dctonly = ((level>1) ? FALSE : TRUE); - dbInitEntry(pdbbase,pdbentry); - if (precordTypename) { - if (*precordTypename == 0 || *precordTypename == '*') - precordTypename = 0; - } - - if(!precordTypename) { - status = dbFirstRecordType(pdbentry); - if(status) { - /* No record descriptions, so no record instances */ - dbFinishEntry(pdbentry); - return(0); - } - } else { - status = dbFindRecordType(pdbentry,precordTypename); - if(status) { - fprintf(stderr,"dbWriteRecordFP: No record description for %s\n", - precordTypename); - dbFinishEntry(pdbentry); - return(status); - } - } - while(!status) { - status = dbFirstRecord(pdbentry); - while(!status) { - if (dbIsAlias(pdbentry)) { - status = dbNextRecord(pdbentry); - continue; - } - if(dbIsVisibleRecord(pdbentry)) - fprintf(fp,"grecord(%s,\"%s\") {\n", - dbGetRecordTypeName(pdbentry),dbGetRecordName(pdbentry)); - else - fprintf(fp,"record(%s,\"%s\") {\n", - dbGetRecordTypeName(pdbentry),dbGetRecordName(pdbentry)); - status = dbFirstField(pdbentry,dctonly); - while(!status) { - if (!dbIsDefaultValue(pdbentry) || level>0) { - char *pvalstring = dbGetString(pdbentry); - - if (!pvalstring) { - fprintf(fp,"\tfield(%s,\"\")\n", - dbGetFieldName(pdbentry)); - } else { - fprintf(fp,"\tfield(%s,\"", - dbGetFieldName(pdbentry)); - epicsStrPrintEscaped(fp,pvalstring,strlen(pvalstring)); - fprintf(fp,"\")\n"); - } - } else if(level>0) { /*generate 0 length string*/ - fprintf(fp,"\tfield(%s,\"\")\n",dbGetFieldName(pdbentry)); - } - status=dbNextField(pdbentry,dctonly); - } - status = dbFirstInfo(pdbentry); - while(!status) { - fprintf(fp,"\tinfo(\"%s\",\"%s\")\n", - dbGetInfoName(pdbentry), dbGetInfoString(pdbentry)); - status=dbNextInfo(pdbentry); - } - fprintf(fp,"}\n"); - status = dbNextRecord(pdbentry); - } - status = dbFirstRecord(pdbentry); - while (!status) { - if (!dbIsAlias(pdbentry)) { - status = dbNextRecord(pdbentry); - continue; - } - fprintf(fp, "alias(\"%s\",\"%s\")\n", - dbRecordName(pdbentry), dbGetRecordName(pdbentry)); - status = dbNextRecord(pdbentry); - } - if(precordTypename) break; - status = dbNextRecordType(pdbentry); - } - dbFinishEntry(pdbentry); - return(0); -} - -long dbWriteMenu( - DBBASE *ppdbbase,const char *filename,const char *menuName) -{ - FILE *stream; - long status; - - stream = openOutstream(filename); - status = dbWriteMenuFP(ppdbbase,stream,menuName); - finishOutstream(stream); - return status; -} - -long dbWriteMenuFP(DBBASE *pdbbase,FILE *fp,const char *menuName) -{ - dbMenu *pdbMenu; - int gotMatch; - int i; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return(-1); - } - if (menuName) { - if (*menuName == 0 || *menuName == '*') - menuName = 0; - } - pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); - while(pdbMenu) { - if(menuName) { - gotMatch = (strcmp(menuName,pdbMenu->name)==0) ? TRUE : FALSE; - }else { - gotMatch=TRUE; - } - if(gotMatch) { - fprintf(fp,"menu(%s) {\n",pdbMenu->name); - for(i=0; inChoice; i++) { - fprintf(fp,"\tchoice(%s,\"%s\")\n",pdbMenu->papChoiceName[i], - pdbMenu->papChoiceValue[i]); - } - fprintf(fp,"}\n"); - if(menuName) break; - } - pdbMenu = (dbMenu *)ellNext(&pdbMenu->node); - } - return(0); -} - -long dbWriteRecordType( - DBBASE *pdbbase,const char *filename,const char *recordTypeName) -{ - FILE *stream; - long status; - - stream = openOutstream(filename); - status = dbWriteRecordTypeFP(pdbbase,stream,recordTypeName); - finishOutstream(stream); - return status; -} - -long dbWriteRecordTypeFP( - DBBASE *pdbbase,FILE *fp,const char *recordTypeName) -{ - dbRecordType *pdbRecordType; - dbFldDes *pdbFldDes; - int gotMatch; - int i; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return(-1); - } - if (recordTypeName) { - if (*recordTypeName == 0 || *recordTypeName == '*') - recordTypeName = 0; - } - - for(pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - if(recordTypeName) { - gotMatch = (strcmp(recordTypeName,pdbRecordType->name)==0) - ? TRUE : FALSE; - }else { - gotMatch=TRUE; - } - if(!gotMatch) continue; - fprintf(fp,"recordtype(%s) {\n",pdbRecordType->name); - for(i=0; ino_fields; i++) { - int j; - - pdbFldDes = pdbRecordType->papFldDes[i]; - fprintf(fp,"\tfield(%s,%s) {\n",pdbFldDes->name, - dbGetFieldTypeString(pdbFldDes->field_type)); - if(pdbFldDes->prompt) - fprintf(fp,"\t\tprompt(\"%s\")\n",pdbFldDes->prompt); - if(pdbFldDes->initial) - fprintf(fp,"\t\tinitial(\"%s\")\n",pdbFldDes->initial); - if (pdbFldDes->promptgroup) { - fprintf(fp,"\t\tpromptgroup(\"%s\")\n", - dbGetPromptGroupNameFromKey(pdbbase, pdbFldDes->promptgroup)); - } - if(pdbFldDes->special) { - if(pdbFldDes->special >= SPC_NTYPES) { - fprintf(fp,"\t\tspecial(%d)\n",pdbFldDes->special); - } else for(j=0; jspecial) { - fprintf(fp,"\t\tspecial(%s)\n", - pamapspcType[j].strvalue); - break; - } - } - } - if(pdbFldDes->extra) - fprintf(fp,"\t\textra(\"%s\")\n",pdbFldDes->extra); - if(pdbFldDes->field_type==DBF_MENU) { - if(pdbFldDes->ftPvt) - fprintf(fp,"\t\tmenu(%s)\n", - ((dbMenu *)pdbFldDes->ftPvt)->name); - else - fprintf(stderr,"\t\t menu: NOT FOUND\n"); - } - if(pdbFldDes->field_type==DBF_STRING) { - fprintf(fp,"\t\tsize(%d)\n", - pdbFldDes->size); - } - if(pdbFldDes->process_passive) fprintf(fp,"\t\tpp(TRUE)\n"); - if(pdbFldDes->prop) fprintf(fp,"\t\tprop(YES)\n"); - if(pdbFldDes->base) fprintf(fp,"\t\tbase(HEX)\n"); - if(pdbFldDes->interest) - fprintf(fp,"\t\tinterest(%d)\n",pdbFldDes->interest); - if(!pdbFldDes->as_level) fprintf(fp,"\t\tasl(ASL0)\n"); - fprintf(fp,"\t}\n"); - } - fprintf(fp,"}\n"); - if(recordTypeName) break; - } - return(0); -} - -long dbWriteDevice(DBBASE *pdbbase,const char *filename) -{ - FILE *stream; - long status; - - stream = openOutstream(filename); - status = dbWriteDeviceFP(pdbbase,stream); - finishOutstream(stream); - return status; -} - -long dbWriteDeviceFP(DBBASE *pdbbase,FILE *fp) -{ - dbRecordType *pdbRecordType; - devSup *pdevSup; - - if(!pdbbase) { - fprintf(stderr,"dbWriteDeviceFP: pdbbase not specified\n"); - return(-1); - } - for(pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - for(pdevSup = (devSup *)ellFirst(&pdbRecordType->devList); - pdevSup; pdevSup = (devSup *)ellNext(&pdevSup->node)) { - int j; - - for(j=0; j< LINK_NTYPES; j++) { - if(pamaplinkType[j].value==pdevSup->link_type) break; - } - if(j>=LINK_NTYPES) { - fprintf(fp,"link_type not valid\n"); - continue; - } - fprintf(fp,"device(%s,%s,%s,\"%s\")\n", - pdbRecordType->name, - pamaplinkType[j].strvalue, - pdevSup->name,pdevSup->choice); - } - } - return(0); -} - -long dbWriteDriver(DBBASE *pdbbase,const char *filename) -{ - FILE *stream; - long status; - - stream = openOutstream(filename); - status = dbWriteDriverFP(pdbbase,stream); - finishOutstream(stream); - return status; -} - -long dbWriteDriverFP(DBBASE *pdbbase,FILE *fp) -{ - drvSup *pdrvSup; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return(-1); - } - for(pdrvSup = (drvSup *)ellFirst(&pdbbase->drvList); - pdrvSup; pdrvSup = (drvSup *)ellNext(&pdrvSup->node)) { - fprintf(fp,"driver(%s)\n",pdrvSup->name); - } - return(0); -} - -long dbWriteLinkFP(DBBASE *pdbbase, FILE *fp) -{ - linkSup *plinkSup; - - if (!pdbbase) { - fprintf(stderr, "pdbbase not specified\n"); - return -1; - } - for (plinkSup = (linkSup *) ellFirst(&pdbbase->linkList); - plinkSup; plinkSup = (linkSup *) ellNext(&plinkSup->node)) { - fprintf(fp, "link(%s,%s)\n", plinkSup->name, plinkSup->jlif_name); - } - return 0; -} - -long dbWriteRegistrarFP(DBBASE *pdbbase,FILE *fp) -{ - dbText *ptext; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return(-1); - } - for(ptext = (dbText *)ellFirst(&pdbbase->registrarList); - ptext; ptext = (dbText *)ellNext(&ptext->node)) { - fprintf(fp,"registrar(%s)\n",ptext->text); - } - return(0); -} - -long dbWriteFunctionFP(DBBASE *pdbbase,FILE *fp) -{ - dbText *ptext; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return(-1); - } - for(ptext = (dbText *)ellFirst(&pdbbase->functionList); - ptext; ptext = (dbText *)ellNext(&ptext->node)) { - fprintf(fp,"function(%s)\n",ptext->text); - } - return(0); -} - -long dbWriteVariableFP(DBBASE *pdbbase,FILE *fp) -{ - dbVariableDef *pvar; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return(-1); - } - for(pvar = (dbVariableDef *)ellFirst(&pdbbase->variableList); - pvar; pvar = (dbVariableDef *)ellNext(&pvar->node)) { - fprintf(fp,"variable(%s,%s)\n",pvar->name,pvar->type); - } - return(0); -} - -long dbWriteBreaktable(DBBASE *pdbbase,const char *filename) -{ - FILE *stream; - long status; - - stream = openOutstream(filename); - status = dbWriteBreaktableFP(pdbbase,stream); - finishOutstream(stream); - return status; -} - -long dbWriteBreaktableFP(DBBASE *pdbbase,FILE *fp) -{ - brkTable *pbrkTable; - brkInt *pbrkInt; - int i; - - if (!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return(-1); - } - for (pbrkTable = (brkTable *)ellFirst(&pdbbase->bptList); - pbrkTable; - pbrkTable = (brkTable *)ellNext(&pbrkTable->node)) { - fprintf(fp,"breaktable(%s) {\n",pbrkTable->name); - pbrkInt = pbrkTable->paBrkInt; - for(i=0; i < pbrkTable->number; i++) { - fprintf(fp,"\t%e, %e\n",pbrkInt->raw,pbrkInt->eng); - pbrkInt++; - } - fprintf(fp,"}\n"); - } - return(0); -} - -long dbFindRecordType(DBENTRY *pdbentry,const char *recordType) -{ - dbBase *pdbbase = pdbentry->pdbbase; - GPHENTRY *phash; - - zeroDbentry(pdbentry); - phash = gphFind(pdbbase->pgpHash,recordType,&pdbbase->recordTypeList); - if(!phash) return(S_dbLib_recordTypeNotFound); - pdbentry->precordType = phash->userPvt; - return(0); -} - -long dbFirstRecordType(DBENTRY *pdbentry) -{ - dbRecordType *precordType; - - zeroDbentry(pdbentry); - precordType = (dbRecordType *)ellFirst(&pdbentry->pdbbase->recordTypeList); - if(!precordType) return(S_dbLib_recordTypeNotFound); - pdbentry->precordType = precordType; - return(0); -} - -long dbNextRecordType(DBENTRY *pdbentry) -{ - dbRecordType *precordType = pdbentry->precordType; - - zeroDbentry(pdbentry); - precordType = (dbRecordType *)ellNext(&precordType->node); - if(!precordType) return(S_dbLib_recordTypeNotFound); - pdbentry->precordType = precordType; - return(0); -} - -char * dbGetRecordTypeName(DBENTRY *pdbentry) -{ - return(pdbentry->precordType->name); -} - -int dbGetNRecordTypes(DBENTRY *pdbentry) -{ - return(ellCount(&pdbentry->pdbbase->recordTypeList)); -} - -long dbPutRecordAttribute( - DBENTRY *pdbentry, const char *name, const char*value) -{ - dbRecordType *precordType = pdbentry->precordType; - int createNew = TRUE; - int compare; - dbRecordAttribute *pattribute; - - if(!precordType) return(S_dbLib_recordTypeNotFound); - pattribute = (dbRecordAttribute *)ellFirst(&precordType->attributeList); - /*put new attribute name in sort order*/ - while(pattribute) { - compare = strcmp(pattribute->name,name); - if(compare==0) { - createNew = FALSE; - } - if(compare>=0) break; - pattribute = (dbRecordAttribute *)ellNext(&pattribute->node); - } - if(createNew) { - dbRecordAttribute *pnew; - dbFldDes *pdbFldDes; - - pnew = dbCalloc(1,sizeof(dbRecordAttribute)); - if(pattribute) { - ellInsert(&precordType->attributeList,pattribute->node.previous, - &pnew->node); - } else { - ellAdd(&precordType->attributeList,&pnew->node); - } - pattribute = pnew; - pattribute->name = dbCalloc(strlen(name)+1,sizeof(char)); - strcpy(pattribute->name,name); - pdbFldDes = dbCalloc(1,sizeof(dbFldDes)); - pdbFldDes->name = pattribute->name; - pdbFldDes->pdbRecordType = precordType; - pdbFldDes->special = SPC_ATTRIBUTE; - pdbFldDes->field_type = DBF_STRING; - pdbFldDes->as_level = ASL1; - pdbFldDes->size = MAX_STRING_SIZE; - pattribute->pdbFldDes = pdbFldDes; - } - strncpy(pattribute->value,value,MAX_STRING_SIZE); - pattribute->value[MAX_STRING_SIZE-1] = 0; - return(0); -} - -long dbGetAttributePart(DBENTRY *pdbentry, const char **ppname) -{ - dbRecordType *precordType = pdbentry->precordType; - const char *pname = *ppname; - dbRecordAttribute *pattribute; - - if (!precordType) - return S_dbLib_recordTypeNotFound; - - pattribute = (dbRecordAttribute *)ellFirst(&precordType->attributeList); - while (pattribute) { - size_t nameLen = strlen(pattribute->name); - int compare = strncmp(pattribute->name, pname, nameLen); - - if (compare == 0) { - int ch = pname[nameLen]; - - if (ch != '_' && !isalnum(ch)) { - /* Any other character can't be in the attribute name */ - pdbentry->pflddes = pattribute->pdbFldDes; - pdbentry->pfield = pattribute->value; - *ppname = &pname[nameLen]; - return 0; - } - if (strlen(pname) > nameLen) { - compare = -1; - } - } - if (compare >= 0) break; - pattribute = (dbRecordAttribute *)ellNext(&pattribute->node); - } - return S_dbLib_fieldNotFound; -} - -long dbGetRecordAttribute(DBENTRY *pdbentry, const char *pname) -{ - return dbGetAttributePart(pdbentry, &pname); -} - -long dbFirstField(DBENTRY *pdbentry,int dctonly) -{ - - pdbentry->indfield = -1; - return(dbNextField(pdbentry,dctonly)); -} - -long dbNextField(DBENTRY *pdbentry,int dctonly) -{ - dbRecordType *precordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - dbFldDes *pflddes; - short indfield = pdbentry->indfield; - - if(!precordType) return(S_dbLib_recordTypeNotFound); - indfield++; - while(TRUE) { - if(indfield>=precordType->no_fields) { - pdbentry->indfield = 0; - pdbentry->pflddes = NULL; - pdbentry->pfield = NULL; - return(S_dbLib_fieldNotFound); - } - pflddes = precordType->papFldDes[indfield]; - if(!dctonly || pflddes->promptgroup) { - /*Skip field if dctonly and no device support*/ - if(!dctonly || (pflddes->field_type!=DBF_DEVICE) - || (ellCount(&precordType->devList)>0)) { - pdbentry->indfield = indfield; - pdbentry->pflddes = pflddes; - pdbentry->indfield = indfield; - if(precnode) { - dbGetFieldAddress(pdbentry); - }else { - pdbentry->pfield = NULL; - } - return(0); - } - } - indfield++; - } -} - -int dbGetFieldType(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - long status; - - if(!pflddes){ - status = S_dbLib_flddesNotFound; - entryErrMessage(pdbentry,status,"dbGetFieldType"); - return(status); - } - return(mapDBFtoDCT[pflddes->field_type]); -} - -int dbGetNFields(DBENTRY *pdbentry,int dctonly) -{ - dbRecordType *precordType = pdbentry->precordType; - dbFldDes *pflddes; - int indfield,n; - - if(!precordType) return(S_dbLib_recordTypeNotFound); - n = 0; - for(indfield=0; indfieldno_fields; indfield++) { - pflddes = precordType->papFldDes[indfield]; - if(dctonly && (pflddes->field_type==DBF_DEVICE) - && (ellCount(&precordType->devList)==0) ) continue; - if(!dctonly || pflddes->promptgroup) n++; - } - return(n); -} - -char * dbGetFieldName(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - - if(!pflddes) return(NULL); - return(pflddes->name); -} - -char * dbGetDefault(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - - if(!pflddes) return(NULL); - return(pflddes->initial); -} - -char * dbGetPrompt(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - - if(!pflddes) return(NULL); - return(&pflddes->prompt[0]); -} - -int dbGetPromptGroup(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - - if(!pflddes) return(0); - return(pflddes->promptgroup); -} - -long dbCreateRecord(DBENTRY *pdbentry,const char *precordName) -{ - dbRecordType *precordType = pdbentry->precordType; - dbFldDes *pdbFldDes; - PVDENTRY *ppvd; - ELLLIST *preclist = NULL; - dbRecordNode *pNewRecNode = NULL; - long status = 0; - - if(!precordType) return(S_dbLib_recordTypeNotFound); - /*Get size of NAME field*/ - pdbFldDes = precordType->papFldDes[0]; - if(!pdbFldDes || (strcmp(pdbFldDes->name,"NAME")!=0)) - return(S_dbLib_nameLength); - if((int)strlen(precordName)>=pdbFldDes->size) return(S_dbLib_nameLength); - /* clear callers entry */ - zeroDbentry(pdbentry); - if(!dbFindRecord(pdbentry,precordName)) return (S_dbLib_recExists); - zeroDbentry(pdbentry); - pdbentry->precordType = precordType; - preclist = &precordType->recList; - /* create a recNode */ - pNewRecNode = dbCalloc(1,sizeof(dbRecordNode)); - /* create a new record of this record type */ - pdbentry->precnode = pNewRecNode; - if((status = dbAllocRecord(pdbentry,precordName))) return(status); - pNewRecNode->recordname = dbRecordName(pdbentry); - ellInit(&pNewRecNode->infoList); - ellAdd(preclist, &pNewRecNode->node); - pdbentry->precnode = pNewRecNode; - ppvd = dbPvdAdd(pdbentry->pdbbase,precordType,pNewRecNode); - if(!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);} - return(0); -} - -long dbDeleteAliases(DBENTRY *pdbentry) -{ - dbBase *pdbbase = pdbentry->pdbbase; - dbRecordType *precordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - ELLLIST *preclist = &precordType->recList; - dbRecordNode *pAliasNode, *pAliasNodeNext; - DBENTRY dbentry; - void *precord; - - if (!precnode) return S_dbLib_recNotFound; - if (precnode->flags & DBRN_FLAGS_ISALIAS) return S_dbLib_recExists; - precord = precnode->precord; - - dbInitEntry(pdbbase, &dbentry); - pAliasNode = (dbRecordNode *)ellFirst(preclist); - while (pAliasNode) { - pAliasNodeNext = (dbRecordNode *)ellNext(&pAliasNode->node); - if (pAliasNode->flags & DBRN_FLAGS_ISALIAS && - pAliasNode->precord == precord && - !dbFindRecord(&dbentry, pAliasNode->recordname)) { - dbDeleteRecord(&dbentry); - } - pAliasNode = pAliasNodeNext; - } - precnode->flags &= ~DBRN_FLAGS_HASALIAS; - return 0; -} - -long dbDeleteRecord(DBENTRY *pdbentry) -{ - dbBase *pdbbase = pdbentry->pdbbase; - dbRecordType *precordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - ELLLIST *preclist; - long status; - - if (!precnode) return S_dbLib_recNotFound; - if (precnode->flags & DBRN_FLAGS_HASALIAS) - dbDeleteAliases(pdbentry); - - preclist = &precordType->recList; - ellDelete(preclist, &precnode->node); - dbPvdDelete(pdbbase, precnode); - while (!dbFirstInfo(pdbentry)) { - dbDeleteInfo(pdbentry); - } - if (precnode->flags & DBRN_FLAGS_ISALIAS) { - free(precnode->recordname); - precordType->no_aliases--; - } else { - status = dbFreeRecord(pdbentry); - if (status) return status; - } - free(precnode); - pdbentry->precnode = NULL; - return 0; -} - -long dbFreeRecords(DBBASE *pdbbase) -{ - DBENTRY dbentry; - dbRecordType *pdbRecordType; - dbRecordNode *pdbRecordNode; - dbRecordNode *pdbRecordNodeNext; - - dbInitEntry(pdbbase,&dbentry); - pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - while(pdbRecordType) { - pdbRecordNode = (dbRecordNode *)ellFirst(&pdbRecordType->recList); - while(pdbRecordNode) { - pdbRecordNodeNext = (dbRecordNode *)ellNext(&pdbRecordNode->node); - if(!dbFindRecord(&dbentry,pdbRecordNode->recordname)) - dbDeleteRecord(&dbentry); - pdbRecordNode = pdbRecordNodeNext; - } - pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node); - } - dbFinishEntry(&dbentry); - return(0); -} - -long dbFindRecordPart(DBENTRY *pdbentry, const char **ppname) -{ - dbBase *pdbbase = pdbentry->pdbbase; - const char *pname = *ppname; - const char *pfn; - size_t lenName; - PVDENTRY *ppvdNode; - - zeroDbentry(pdbentry); - pfn = strchr(pname, '.'); - if (pfn) { - lenName = (size_t) (pfn - pname); - } else { - lenName = strlen(pname); - } - - ppvdNode = dbPvdFind(pdbbase, pname, lenName); - if (!ppvdNode) - return S_dbLib_recNotFound; - - pdbentry->precnode = ppvdNode->precnode; - pdbentry->precordType = ppvdNode->precordType; - *ppname = pname + lenName; - return 0; -} - -long dbFindRecord(DBENTRY *pdbentry, const char *pname) -{ - long status = dbFindRecordPart(pdbentry, &pname); - - if (status) return status; - if (*pname == '.') - return dbFindField(pdbentry, ++pname); - return 0; -} - -long dbFirstRecord(DBENTRY *pdbentry) -{ - dbRecordType *precordType = pdbentry->precordType; - dbRecordNode *precnode; - - zeroDbentry(pdbentry); - if(!precordType) return(S_dbLib_recordTypeNotFound); - pdbentry->precordType = precordType; - precnode = (dbRecordNode *)ellFirst(&precordType->recList); - if(!precnode) return(S_dbLib_recNotFound); - pdbentry->precnode = precnode; - return(0); -} - -long dbNextRecord(DBENTRY *pdbentry) -{ - dbRecordNode *precnode=pdbentry->precnode; - long status=0; - - if(!precnode) return(S_dbLib_recNotFound); - precnode = (dbRecordNode *)ellNext(&precnode->node); - if(!precnode) status = S_dbLib_recNotFound; - pdbentry->precnode = precnode; - pdbentry->pfield = NULL; - return(status); -} - -int dbGetNRecords(DBENTRY *pdbentry) -{ - dbRecordType *precordType = pdbentry->precordType; - - if(!precordType) return(0); - return(ellCount(&precordType->recList)); -} - -int dbGetNAliases(DBENTRY *pdbentry) -{ - dbRecordType *precordType = pdbentry->precordType; - - if(!precordType) return(0); - return(precordType->no_aliases); -} - -char * dbGetRecordName(DBENTRY *pdbentry) -{ - dbRecordType *pdbRecordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - - if(!pdbRecordType) return NULL; - if(!precnode) return NULL; - return precnode->recordname; -} - -long dbVisibleRecord(DBENTRY *pdbentry) -{ - dbRecordNode *precnode = pdbentry->precnode; - - if(!precnode) return(S_dbLib_recNotFound); - precnode->flags |= DBRN_FLAGS_VISIBLE; - return 0; -} - -long dbInvisibleRecord(DBENTRY *pdbentry) -{ - dbRecordNode *precnode = pdbentry->precnode; - - if(!precnode) return(S_dbLib_recNotFound); - precnode->flags &= ~DBRN_FLAGS_VISIBLE; - return 0; -} - -int dbIsVisibleRecord(DBENTRY *pdbentry) -{ - dbRecordNode *precnode = pdbentry->precnode; - - if(!precnode) return 0; - return precnode->flags & DBRN_FLAGS_VISIBLE ? 1 : 0; -} - -long dbCreateAlias(DBENTRY *pdbentry, const char *alias) -{ - dbRecordType *precordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - dbRecordNode *pnewnode; - PVDENTRY *ppvd; - ELLLIST *preclist = NULL; - if (!precordType) return S_dbLib_recordTypeNotFound; - /* alias of alias still references actual record */ - while(precnode && (precnode->flags&DBRN_FLAGS_ISALIAS)) - precnode = precnode->aliasedRecnode; - if (!precnode) return S_dbLib_recNotFound; - zeroDbentry(pdbentry); - if (!dbFindRecord(pdbentry, alias)) return S_dbLib_recExists; - zeroDbentry(pdbentry); - pdbentry->precordType = precordType; - preclist = &precordType->recList; - pnewnode = dbCalloc(1, sizeof(dbRecordNode)); - pnewnode->recordname = epicsStrDup(alias); - pnewnode->precord = precnode->precord; - pnewnode->aliasedRecnode = precnode; - pnewnode->flags = DBRN_FLAGS_ISALIAS; - precnode->flags |= DBRN_FLAGS_HASALIAS; - ellInit(&pnewnode->infoList); - ellAdd(preclist, &pnewnode->node); - precordType->no_aliases++; - pdbentry->precnode = pnewnode; - ppvd = dbPvdAdd(pdbentry->pdbbase, precordType, pnewnode); - if (!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);} - return 0; -} - -int dbFollowAlias(DBENTRY *pdbentry) -{ - if(!pdbentry->precnode) - return S_dbLib_recNotFound; - if(pdbentry->precnode->aliasedRecnode) - pdbentry->precnode = pdbentry->precnode->aliasedRecnode; - return 0; -} - -int dbIsAlias(DBENTRY *pdbentry) -{ - dbRecordNode *precnode = pdbentry->precnode; - - if(!precnode) return 0; - return precnode->flags & DBRN_FLAGS_ISALIAS ? 1 : 0; -} - -long dbCopyRecord(DBENTRY *pdbentry,const char *newRecordName,int overWriteOK) -{ - dbRecordType *precordType = pdbentry->precordType; - dbFldDes *pdbFldDes; - dbRecordNode *precnode = pdbentry->precnode; - long status; - DBENTRY dbentry; - char *pvalue; - - if(!precordType) return(S_dbLib_recordTypeNotFound); - /*Get size of NAME field*/ - pdbFldDes = precordType->papFldDes[0]; - if(!pdbFldDes || (strcmp(pdbFldDes->name,"NAME")!=0)) - return(S_dbLib_nameLength); - if((int)strlen(newRecordName)>=pdbFldDes->size) return(S_dbLib_nameLength); - if (!precnode || dbIsAlias(pdbentry)) return S_dbLib_recNotFound; - dbInitEntry(pdbentry->pdbbase,&dbentry); - status = dbFindRecord(&dbentry,newRecordName); - if(!status) { - if(!overWriteOK) { - dbFinishEntry(&dbentry); - return(S_dbLib_recExists); - } - status = dbDeleteRecord(&dbentry); - if(status) return(status); - } - dbFinishEntry(&dbentry); - if((status = dbFindRecordType(&dbentry,precordType->name))) return(status); - if((status = dbCreateRecord(&dbentry,newRecordName))) return(status); - if((status = dbFirstField(pdbentry,TRUE))) return(status); - if((status = dbFirstField(&dbentry,TRUE))) return(status); - while(!status) { - if(!dbIsDefaultValue(pdbentry)) { - pvalue = dbGetString(pdbentry); - if((status = dbPutString(&dbentry,pvalue))) return(status); - } - status = dbNextField(pdbentry,TRUE); - if(!status) status = dbNextField(&dbentry,TRUE); - if(!status && (pdbentry->pflddes!=dbentry.pflddes)) { - epicsPrintf("dbCopyRecord: Logic Error\n"); - return(-1); - } - } - /*Copy the info strings too*/ - status = dbFirstInfo(pdbentry); - while (!status) { - status = dbPutInfo(&dbentry, dbGetInfoName(pdbentry), dbGetInfoString(pdbentry)); - if (status) return (status); - status = dbNextInfo(pdbentry); - } - /*Leave pdbentry pointing to newRecordName*/ - return(dbFindRecord(pdbentry,newRecordName)); -} - -long dbFindFieldPart(DBENTRY *pdbentry,const char **ppname) -{ - dbRecordType *precordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - const char *pname = *ppname; - short top, bottom, test; - char **papsortFldName; - short *sortFldInd; - int ch; - size_t nameLen; - - if (!precordType) return S_dbLib_recordTypeNotFound; - if (!precnode) return S_dbLib_recNotFound; - papsortFldName = precordType->papsortFldName; - sortFldInd = precordType->sortFldInd; - - /* Measure field name length; name is a valid C identifier */ - nameLen = 0; - if ((ch = *pname) && - (ch == '_' || isalpha(ch))) { - while ((ch = pname[++nameLen])) - if (!(ch == '_' || isalnum(ch))) break; - } - - /* Handle absent field name */ - if (nameLen == 0) { - dbFldDes *pflddes = precordType->pvalFldDes; - - if (!pflddes) - return S_dbLib_recordTypeNotFound; - pdbentry->pflddes = pflddes; - pdbentry->indfield = precordType->indvalFlddes; - *ppname = &pname[nameLen]; - return dbGetFieldAddress(pdbentry); - } - - /* binary search through ordered field names */ - top = precordType->no_fields - 1; - bottom = 0; - test = (top + bottom) / 2; - while (1) { - int compare = strncmp(papsortFldName[test], pname, nameLen); - if (compare == 0) - compare = (int) (strlen(papsortFldName[test]) - nameLen); - if (compare == 0) { - dbFldDes *pflddes = precordType->papFldDes[sortFldInd[test]]; - - if (!pflddes) - return S_dbLib_recordTypeNotFound; - pdbentry->pflddes = pflddes; - pdbentry->indfield = sortFldInd[test]; - *ppname = &pname[nameLen]; - return dbGetFieldAddress(pdbentry); - } else if (compare > 0) { - top = test - 1; - if (top < bottom) break; - test = (top + bottom) / 2; - } else { - bottom = test + 1; - if (top < bottom) break; - test = (top + bottom) / 2; - } - } - return S_dbLib_fieldNotFound; -} - -long dbFindField(DBENTRY *pdbentry,const char *pname) -{ - long status = dbFindFieldPart(pdbentry, &pname); - int ch; - - if (status == S_dbLib_fieldNotFound) - return dbGetRecordAttribute(pdbentry, pname); - if (status) return status; - - ch = *pname; - if (ch == 0 || isspace(ch)) return 0; - return S_dbLib_recNotFound; -} - -int dbFoundField(DBENTRY *pdbentry) -{ return((pdbentry->pfield) ? TRUE : FALSE); } - -char * dbGetString(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - void *pfield = pdbentry->pfield; - DBLINK *plink; - - if (!pflddes) { - dbMsgCpy(pdbentry, "fldDes not found"); - return pdbentry->message; - } - switch (pflddes->field_type) { - case DBF_STRING: - case DBF_INLINK: - case DBF_OUTLINK: - case DBF_FWDLINK: - if (!pfield) { - dbMsgCpy(pdbentry, "Field not allocated (NULL)"); - return pdbentry->message; - } - break; - default: - break; - } - - switch (pflddes->field_type) { - case DBF_STRING: - dbMsgCpy(pdbentry, (char *)pfield); - break; - case DBF_CHAR: - case DBF_UCHAR: - case DBF_SHORT: - case DBF_USHORT: - case DBF_ENUM: - case DBF_LONG: - case DBF_ULONG: - case DBF_INT64: - case DBF_UINT64: - case DBF_FLOAT: - case DBF_DOUBLE: - case DBF_MENU: - case DBF_DEVICE: - return(dbGetStringNum(pdbentry)); - case DBF_INLINK: - case DBF_OUTLINK: - plink = (DBLINK *)pfield; - switch(plink->type) { - case CONSTANT: - if (plink->value.constantStr) { - dbMsgCpy(pdbentry, plink->value.constantStr); - } else { - dbMsgCpy(pdbentry, ""); - } - break; - case MACRO_LINK: - if (plink->value.macro_link.macroStr) { - dbMsgCpy(pdbentry, plink->value.macro_link.macroStr); - } else { - dbMsgCpy(pdbentry, ""); - } - break; - case JSON_LINK: - dbMsgCpy(pdbentry, plink->value.json.string); - break; - case PN_LINK: - dbMsgPrint(pdbentry, "%s%s", - plink->value.pv_link.pvname ? plink->value.pv_link.pvname : "", - msstring[plink->value.pv_link.pvlMask&pvlOptMsMode]); - break; - case PV_LINK: - case CA_LINK: - case DB_LINK: { - int ppind; - short pvlMask; - - pvlMask = plink->value.pv_link.pvlMask; - if (pvlMask&pvlOptPP) ppind=1; - else if(pvlMask&pvlOptCA) ppind=2; - else if(pvlMask&pvlOptCP) ppind=3; - else if(pvlMask&pvlOptCPP) ppind=4; - else ppind=0; - dbMsgPrint(pdbentry, "%s%s%s%s", - plink->value.pv_link.pvname ? plink->value.pv_link.pvname : "", - (pvlMask & pvlOptTSELisTime) ? ".TIME" : "", - ppstring[ppind], - msstring[plink->value.pv_link.pvlMask&pvlOptMsMode]); - break; - } - case VME_IO: - dbMsgPrint(pdbentry, "#C%d S%d @%s", - plink->value.vmeio.card,plink->value.vmeio.signal, - plink->value.vmeio.parm); - break; - case CAMAC_IO: - dbMsgPrint(pdbentry, "#B%d C%d N%d A%d F%d @%s", - plink->value.camacio.b,plink->value.camacio.c, - plink->value.camacio.n,plink->value.camacio.a, - plink->value.camacio.f,plink->value.camacio.parm); - break; - case RF_IO: - dbMsgPrint(pdbentry, "#R%d M%d D%d E%d", - plink->value.rfio.cryo, - plink->value.rfio.micro, - plink->value.rfio.dataset, - plink->value.rfio.element); - break; - case AB_IO: - dbMsgPrint(pdbentry, "#L%d A%d C%d S%d @%s", - plink->value.abio.link,plink->value.abio.adapter, - plink->value.abio.card,plink->value.abio.signal, - plink->value.abio.parm); - break; - case GPIB_IO: - dbMsgPrint(pdbentry, "#L%d A%d @%s", - plink->value.gpibio.link,plink->value.gpibio.addr, - plink->value.gpibio.parm); - break; - case BITBUS_IO: - dbMsgPrint(pdbentry, "#L%u N%u P%u S%u @%s", - plink->value.bitbusio.link,plink->value.bitbusio.node, - plink->value.bitbusio.port,plink->value.bitbusio.signal, - plink->value.bitbusio.parm); - break; - case BBGPIB_IO: - dbMsgPrint(pdbentry, "#L%u B%u G%u @%s", - plink->value.bbgpibio.link,plink->value.bbgpibio.bbaddr, - plink->value.bbgpibio.gpibaddr,plink->value.bbgpibio.parm); - break; - case INST_IO: - dbMsgPrint(pdbentry, "@%s", plink->value.instio.string); - break; - case VXI_IO : - if (plink->value.vxiio.flag == VXIDYNAMIC) - dbMsgPrint(pdbentry, "#V%d C%d S%d @%s", - plink->value.vxiio.frame,plink->value.vxiio.slot, - plink->value.vxiio.signal,plink->value.vxiio.parm); - else - dbMsgPrint(pdbentry, "#V%d S%d @%s", - plink->value.vxiio.la,plink->value.vxiio.signal, - plink->value.vxiio.parm); - break; - default : - return(NULL); - } - break; - case DBF_FWDLINK: { - DBLINK *plink=(DBLINK *)pfield; - - switch(plink->type) { - case CONSTANT: - dbMsgCpy(pdbentry, "0"); - break; - case MACRO_LINK: - if (plink->value.macro_link.macroStr) { - dbMsgCpy(pdbentry, plink->value.macro_link.macroStr); - } else { - dbMsgCpy(pdbentry, ""); - } - break; - case JSON_LINK: - dbMsgCpy(pdbentry, plink->value.json.string); - break; - case PV_LINK: - case CA_LINK: - case DB_LINK: { - int ppind; - short pvlMask; - - pvlMask = plink->value.pv_link.pvlMask; - if (pvlMask&pvlOptCA) ppind=2; - else ppind=0; - dbMsgPrint(pdbentry, "%s%s", - plink->value.pv_link.pvname ? plink->value.pv_link.pvname : "", - ppind ? ppstring[ppind] : ""); - break; - } - default : - return(NULL); - } - } - break; - default: - return(NULL); - } - return pdbentry->message; -} - -char *dbGetStringNum(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - void *pfield = pdbentry->pfield; - char *message; - unsigned char cvttype; - - /* the following assumes that messagesize is large enough - * to hold the base 10 encoded value of a 32-bit integer. - */ - message = getpMessage(pdbentry); - cvttype = pflddes->base; - switch (pflddes->field_type) { - case DBF_CHAR: - if (cvttype == CT_DECIMAL) - cvtCharToString(*(char *) pfield, message); - else - ulongToHexString(*(char *) pfield, message); - break; - case DBF_UCHAR: - if (cvttype==CT_DECIMAL) - cvtUcharToString(*(epicsUInt8 *) pfield, message); - else - ulongToHexString(*(epicsUInt8 *) pfield, message); - break; - case DBF_SHORT: - if (cvttype==CT_DECIMAL) - cvtShortToString(*(epicsInt16 *) pfield, message); - else - ulongToHexString(*(epicsInt16 *) pfield, message); - break; - case DBF_USHORT: - case DBF_ENUM: - if (cvttype==CT_DECIMAL) - cvtUshortToString(*(epicsUInt16 *) pfield, message); - else - ulongToHexString(*(epicsUInt16 *) pfield, message); - break; - case DBF_LONG: - if (cvttype==CT_DECIMAL) - cvtLongToString(*(epicsInt32 *) pfield, message); - else - ulongToHexString(*(epicsInt32 *) pfield, message); - break; - case DBF_ULONG: - if (cvttype==CT_DECIMAL) - cvtUlongToString(*(epicsUInt32 *) pfield, message); - else - ulongToHexString(*(epicsUInt32 *) pfield, message); - break; - case DBF_INT64: - if (cvttype==CT_DECIMAL) - cvtInt64ToString(*(epicsInt64 *) pfield, message); - else - cvtInt64ToHexString(*(epicsInt64 *) pfield, message); - break; - case DBF_UINT64: - if (cvttype==CT_DECIMAL) - cvtUInt64ToString(*(epicsUInt32 *) pfield, message); - else - cvtUInt64ToHexString(*(epicsUInt32 *) pfield, message); - break; - case DBF_FLOAT: - floatToString(*(epicsFloat32 *) pfield, message); - break; - case DBF_DOUBLE: - doubleToString(*(epicsFloat64 *) pfield, message); - break; - case DBF_MENU: - { - dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; - epicsEnum16 choice_ind; - char *pchoice; - - if (!pfield) { - dbMsgCpy(pdbentry, "Field not found"); - return message; - } - choice_ind = *((epicsEnum16 *) pdbentry->pfield); - if (!pdbMenu || choice_ind < 0 || choice_ind >= pdbMenu->nChoice) - return NULL; - pchoice = pdbMenu->papChoiceValue[choice_ind]; - dbMsgCpy(pdbentry, pchoice); - } - break; - case DBF_DEVICE: - { - dbDeviceMenu *pdbDeviceMenu; - epicsEnum16 choice_ind; - char *pchoice; - - if (!pfield) { - dbMsgCpy(pdbentry, "Field not found"); - return message; - } - pdbDeviceMenu = dbGetDeviceMenu(pdbentry); - if (!pdbDeviceMenu) - return NULL; - choice_ind = *((epicsEnum16 *) pdbentry->pfield); - if (choice_ind<0 || choice_ind>=pdbDeviceMenu->nChoice) - return NULL; - pchoice = pdbDeviceMenu->papChoice[choice_ind]; - dbMsgCpy(pdbentry, pchoice); - } - break; - default: - return NULL; - } - return message; -} - -long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec) -{ - short i; - - for (i=0; ino_links; i++) { - dbLinkInfo link_info; - dbFldDes *pflddes = rtyp->papFldDes[rtyp->link_ind[i]]; - DBLINK *plink = (DBLINK *)(((char *)prec) + pflddes->offset); - devSup *devsup = NULL; - - plink->precord = prec; - - /* link fields are zero'd on allocation. - * so are effectively CONSTANT, but with constantStr==NULL. - * Here we initialize them to have the correct link type, - * with zero values and empty (but non-NULL) strings. - */ - - if(pflddes->isDevLink) { - devsup = (devSup *)ellNth(&rtyp->devList, prec->dtyp+1); - } - if(devsup) - plink->type = devsup->link_type; - else - plink->type = CONSTANT; - - switch (plink->type) { - /* constantStr is allowed to remain NULL if plink->text==NULL - * constantStr==NULL has special meaning in recGblInitConstantLink() - */ - case CONSTANT: plink->value.constantStr = NULL; break; - case PV_LINK: plink->value.pv_link.pvname = callocMustSucceed(1, 1, "init PV_LINK"); break; - case JSON_LINK: plink->value.json.string = pNullString; break; - case VME_IO: plink->value.vmeio.parm = pNullString; break; - case CAMAC_IO: plink->value.camacio.parm = pNullString; break; - case AB_IO: plink->value.abio.parm = pNullString; break; - case GPIB_IO: plink->value.gpibio.parm = pNullString; break; - case BITBUS_IO: plink->value.bitbusio.parm = pNullString; break; - case INST_IO: plink->value.instio.string = pNullString; break; - case BBGPIB_IO: plink->value.bbgpibio.parm = pNullString; break; - case VXI_IO: plink->value.vxiio.parm = pNullString; break; - } - - if(!plink->text) - continue; - - if(dbParseLink(plink->text, pflddes->field_type, &link_info, 0)!=0) { - /* This was already parsed once when ->text was set. - * Any syntax error messages were printed at that time. - */ - - } else if(dbCanSetLink(plink, &link_info, devsup)!=0) { - errlogPrintf("Error: %s.%s: can't initialize link type %d with \"%s\" (type %d)\n", - prec->name, pflddes->name, plink->type, plink->text, link_info.ltype); - - } else if(dbSetLink(plink, &link_info, devsup)) { - errlogPrintf("Error: %s.%s: failed to initialize link type %d with \"%s\" (type %d)\n", - prec->name, pflddes->name, plink->type, plink->text, link_info.ltype); - } - free(plink->text); - plink->text = NULL; - } - return 0; -} - -void dbFreeLinkInfo(dbLinkInfo *pinfo) -{ - if (pinfo->ltype == JSON_LINK) { - dbJLinkFree(pinfo->jlink); - pinfo->jlink = NULL; - } - free(pinfo->target); - pinfo->target = NULL; -} - -long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, unsigned opts) -{ - char *pstr; - size_t len; - double value; - - memset(pinfo, 0, sizeof(*pinfo)); - - /* Strip leading white space */ - while (*str && isspace((int)*str)) str++; - - len = strlen(str); - /* Strip trailing white space */ - while (len > 0 && isspace((int)str[len-1])) len--; - - pstr = malloc(len + 1); - if (!pstr) - return S_dbLib_outMem; - pinfo->target = pstr; - - /* Check for Instrument I/O links */ - if (*str == '@') { - pinfo->ltype = INST_IO; - - /* Store everything after the '@' */ - memcpy(pstr, str+1, --len); - pstr[len] = '\0'; - return 0; - } - - /* Store the stripped string */ - memcpy(pstr, str, len); - pstr[len] = '\0'; - - /* Check for braces => JSON */ - if (*str == '{' && str[len-1] == '}') { - if (dbJLinkParse(str, len, ftype, &pinfo->jlink, opts)) - goto fail; - - pinfo->ltype = JSON_LINK; - return 0; - } - - /* Check for other HW link types */ - if (*pstr == '#') { - int ret; - char junk = 0; - char *parm = strchr(pstr, '@'); /* find start of parm string */ - - if (parm) { - *parm++ = '\0'; /* isolate the parm string for later */ - len -= (parm - pstr); - } - - /* generalized extraction of ID charactor and integer pairs (eg. "#C15 S14") */ - ret = sscanf(pinfo->target, "# %c%d %c%d %c%d %c%d %c%d %c", - &pinfo->hwid[0], &pinfo->hwnums[0], - &pinfo->hwid[1], &pinfo->hwnums[1], - &pinfo->hwid[2], &pinfo->hwnums[2], - &pinfo->hwid[3], &pinfo->hwnums[3], - &pinfo->hwid[4], &pinfo->hwnums[4], - &junk); - - /* ret<0 when pattern not matched - * ret==11 when extra non-space before '@'. - * ret is odd when a number is missing - */ - if (ret<0 || ret>10 || ret%2==1) goto fail; - - if (strcmp(pinfo->hwid, "CS")==0) pinfo->ltype = VME_IO; - else if (strcmp(pinfo->hwid, "BCN")==0) pinfo->ltype = CAMAC_IO; - else if (strcmp(pinfo->hwid, "BCNA")==0) pinfo->ltype = CAMAC_IO; - else if (strcmp(pinfo->hwid, "BCNF")==0) pinfo->ltype = CAMAC_IO; - else if (strcmp(pinfo->hwid, "BCNAF")==0) pinfo->ltype = CAMAC_IO; - else if (strcmp(pinfo->hwid, "RMDE")==0) pinfo->ltype = RF_IO; - else if (strcmp(pinfo->hwid, "LACS")==0) pinfo->ltype = AB_IO; - else if (strcmp(pinfo->hwid, "LA")==0) pinfo->ltype = GPIB_IO; - else if (strcmp(pinfo->hwid, "LNPS")==0) pinfo->ltype = BITBUS_IO; - else if (strcmp(pinfo->hwid, "LBG")==0) pinfo->ltype = BBGPIB_IO; - else if (strcmp(pinfo->hwid, "VCS")==0) pinfo->ltype = VXI_IO; - else if (strcmp(pinfo->hwid, "VS")==0) pinfo->ltype = VXI_IO; - else goto fail; - - if (parm && pinfo->ltype != RF_IO) { - /* move parm string to beginning of buffer */ - memmove(pinfo->target, parm, len + 1); - } else if (!parm && pinfo->ltype == RF_IO) { - /* RF_IO, the string isn't needed at all */ - free(pinfo->target); - pinfo->target = NULL; - } - else goto fail; - - return 0; - } - - /* Link is a constant if empty or it holds just a number */ - if (len == 0 || epicsParseDouble(pstr, &value, NULL) == 0) { - pinfo->ltype = CONSTANT; - return 0; - } - - /* Link may be an array constant */ - if (pstr[0] == '[' && pstr[len-1] == ']' && - (strchr(pstr, ',') || strchr(pstr, '"'))) { - pinfo->ltype = CONSTANT; - return 0; - } - - pinfo->ltype = PV_LINK; - pstr = strchr(pstr, ' '); /* find start of link modifiers (can't be seperated by tabs) */ - if (pstr) { - *pstr++ = '\0'; /* isolate modifiers. pinfo->target is PV name only for re-use in struct pv_link */ - - /* Space seperation of modifiers isn't required, and other chars are ignored. - * Order of comparisons resolves ambiguity by checking for - * longer matches first. - * eg. "QQCPPXMSITT" is pvlOptCPP|pvlOptMSI - */ - - if (strstr(pstr, "NPP")) pinfo->modifiers = 0; - else if (strstr(pstr, "CPP")) pinfo->modifiers = pvlOptCPP; - else if (strstr(pstr, "PP")) pinfo->modifiers = pvlOptPP; - else if (strstr(pstr, "CA")) pinfo->modifiers = pvlOptCA; - else if (strstr(pstr, "CP")) pinfo->modifiers = pvlOptCP; - - if (strstr(pstr, "NMS")) pinfo->modifiers |= pvlOptNMS; - else if (strstr(pstr, "MSI")) pinfo->modifiers |= pvlOptMSI; - else if (strstr(pstr, "MSS")) pinfo->modifiers |= pvlOptMSS; - else if (strstr(pstr, "MS")) pinfo->modifiers |= pvlOptMS; - - /* filter modifiers based on link type */ - switch(ftype) { - case DBF_INLINK: /* accept all */ break; - case DBF_OUTLINK: pinfo->modifiers &= ~pvlOptCPP; break; - case DBF_FWDLINK: pinfo->modifiers &= pvlOptCA; break; - } - } - - return 0; -fail: - dbFreeLinkInfo(pinfo); - return S_dbLib_badField; -} - -long dbCanSetLink(DBLINK *plink, dbLinkInfo *pinfo, devSup *devsup) -{ - /* Release pinfo resources on failure */ - int expected_type = devsup ? devsup->link_type : CONSTANT; - - if (pinfo->ltype == expected_type) - return 0; - - switch (pinfo->ltype) { - case CONSTANT: - case JSON_LINK: - case PV_LINK: - if (expected_type == CONSTANT || - expected_type == JSON_LINK || - expected_type == PV_LINK) - return 0; - default: - dbFreeLinkInfo(pinfo); - return 1; - } -} - -static -void dbSetLinkConst(DBLINK *plink, dbLinkInfo *pinfo) -{ - plink->type = CONSTANT; - plink->value.constantStr = pinfo->target; - - pinfo->target = NULL; -} - -static -void dbSetLinkPV(DBLINK *plink, dbLinkInfo *pinfo) -{ - plink->type = PV_LINK; - plink->value.pv_link.pvname = pinfo->target; - plink->value.pv_link.pvlMask = pinfo->modifiers; - - pinfo->target = NULL; -} - -static -void dbSetLinkJSON(DBLINK *plink, dbLinkInfo *pinfo) -{ - plink->type = JSON_LINK; - plink->value.json.string = pinfo->target; - plink->value.json.jlink = pinfo->jlink; - - pinfo->target = NULL; - pinfo->jlink = NULL; -} - -static -void dbSetLinkHW(DBLINK *plink, dbLinkInfo *pinfo) -{ - switch(pinfo->ltype) { - case JSON_LINK: - plink->value.json.string = pinfo->target; - break; - case INST_IO: - plink->value.instio.string = pinfo->target; - break; - case VME_IO: - plink->value.vmeio.card = pinfo->hwnums[0]; - plink->value.vmeio.signal = pinfo->hwnums[1]; - plink->value.vmeio.parm = pinfo->target; - break; - case CAMAC_IO: - plink->value.camacio.b = pinfo->hwnums[0]; - plink->value.camacio.c = pinfo->hwnums[1]; - plink->value.camacio.n = pinfo->hwnums[2]; - plink->value.camacio.a = pinfo->hwnums[3]; - plink->value.camacio.f = pinfo->hwnums[4]; - plink->value.camacio.parm = pinfo->target; - break; - case RF_IO: - plink->value.rfio.cryo = pinfo->hwnums[0]; - plink->value.rfio.micro = pinfo->hwnums[1]; - plink->value.rfio.dataset = pinfo->hwnums[2]; - plink->value.rfio.element = pinfo->hwnums[3]; - break; - case AB_IO: - plink->value.abio.link = pinfo->hwnums[0]; - plink->value.abio.adapter = pinfo->hwnums[1]; - plink->value.abio.card = pinfo->hwnums[2]; - plink->value.abio.signal = pinfo->hwnums[3]; - plink->value.abio.parm = pinfo->target; - break; - case GPIB_IO: - plink->value.gpibio.link = pinfo->hwnums[0]; - plink->value.gpibio.addr = pinfo->hwnums[1]; - plink->value.gpibio.parm = pinfo->target; - break; - case BITBUS_IO: - plink->value.bitbusio.link = pinfo->hwnums[0]; - plink->value.bitbusio.node = pinfo->hwnums[1]; - plink->value.bitbusio.port = pinfo->hwnums[2]; - plink->value.bitbusio.signal = pinfo->hwnums[3]; - plink->value.bitbusio.parm = pinfo->target; - break; - case BBGPIB_IO: - plink->value.bbgpibio.link = pinfo->hwnums[0]; - plink->value.bbgpibio.bbaddr = pinfo->hwnums[1]; - plink->value.bbgpibio.gpibaddr = pinfo->hwnums[2]; - plink->value.bbgpibio.parm = pinfo->target; - break; - case VXI_IO: - if(strcmp(pinfo->hwid, "VCS")==0) { - plink->value.vxiio.flag=VXIDYNAMIC; - plink->value.vxiio.frame = pinfo->hwnums[0]; - plink->value.vxiio.slot = pinfo->hwnums[1]; - plink->value.vxiio.signal = pinfo->hwnums[2]; - } else if(strcmp(pinfo->hwid, "VS")==0) { - plink->value.vxiio.flag=VXISTATIC; - plink->value.vxiio.la = pinfo->hwnums[0]; - plink->value.vxiio.signal = pinfo->hwnums[1]; - } else { - cantProceed("dbSetLinkHW: logic error, unknown VXI_IO variant"); - } - plink->value.vxiio.parm = pinfo->target; - break; - - default: - cantProceed("dbSetLinkHW: logic error, unhandled link type"); - return; - } - - plink->type = pinfo->ltype; - - pinfo->target = NULL; /* now owned by link field */ -} - -long dbSetLink(DBLINK *plink, dbLinkInfo *pinfo, devSup *devsup) -{ - int expected_type = devsup ? devsup->link_type : CONSTANT; - - if (expected_type == CONSTANT || - expected_type == JSON_LINK || - expected_type == PV_LINK) { - switch (pinfo->ltype) { - case CONSTANT: - dbFreeLinkContents(plink); - dbSetLinkConst(plink, pinfo); - break; - case PV_LINK: - dbFreeLinkContents(plink); - dbSetLinkPV(plink, pinfo); - break; - case JSON_LINK: - dbFreeLinkContents(plink); - dbSetLinkJSON(plink, pinfo); - break; - default: - errlogMessage("Warning: dbSetLink: forgot to test with dbCanSetLink() or logic error"); - goto fail; /* can't assign HW link */ - } - } - else if (expected_type == pinfo->ltype) { - dbFreeLinkContents(plink); - dbSetLinkHW(plink, pinfo); - } - else - goto fail; - - return 0; -fail: - dbFreeLinkInfo(pinfo); - return S_dbLib_badField; -} - -long dbPutString(DBENTRY *pdbentry,const char *pstring) -{ - dbFldDes *pflddes = pdbentry->pflddes; - void *pfield = pdbentry->pfield; - long status=0; - int macroIsOk; - int stringHasMacro=FALSE; - - if(!pflddes) return(S_dbLib_flddesNotFound); - macroIsOk = dbIsMacroOk(pdbentry); - stringHasMacro = strstr(pstring,"$(") || strstr(pstring,"${"); - if(!macroIsOk && stringHasMacro) { - epicsPrintf("%s.%s Has unexpanded macro\n", - dbGetRecordName(pdbentry),dbGetFieldName(pdbentry)); - return(S_dbLib_badField); - } - switch (pflddes->field_type) { - case DBF_STRING: - if(!pfield) return(S_dbLib_fieldNotFound); - if(strlen(pstring) >= (size_t)pflddes->size) return S_dbLib_strLen; - strncpy((char *)pfield, pstring, pflddes->size-1); - ((char *)pfield)[pflddes->size-1] = 0; - - if((pflddes->special == SPC_CALC) && !stringHasMacro) { - char rpcl[RPCL_LEN]; - short err; - - if (postfix(pstring,rpcl,&err)) { - status = S_dbLib_badField; - errlogPrintf("%s in CALC expression '%s'\n", - calcErrorStr(err), pstring); - } - } - break; - - case DBF_CHAR: - case DBF_SHORT: - case DBF_LONG: - case DBF_INT64: - case DBF_UCHAR: - case DBF_USHORT: - case DBF_ULONG: - case DBF_UINT64: - case DBF_ENUM: - case DBF_FLOAT: - case DBF_DOUBLE: - case DBF_MENU: - case DBF_DEVICE: - status = dbPutStringNum(pdbentry,pstring); - break; - - case DBF_INLINK: - case DBF_OUTLINK: - case DBF_FWDLINK: { - dbLinkInfo link_info; - DBLINK *plink = (DBLINK *)pfield; - DBENTRY infoentry; - unsigned opts = 0; - - if(pdbentry->precnode && ellCount(&pdbentry->precnode->infoList)) { - dbCopyEntryContents(pdbentry, &infoentry); - - if(dbFindInfo(&infoentry, "base:lsetDebug")==0 && epicsStrCaseCmp(dbGetInfoString(&infoentry), "YES")==0) - opts |= LINK_DEBUG_LSET; - if(dbFindInfo(&infoentry, "base:jlinkDebug")==0 && epicsStrCaseCmp(dbGetInfoString(&infoentry), "YES")==0) - opts |= LINK_DEBUG_JPARSE; - - dbFinishEntry(&infoentry); - } - - status = dbParseLink(pstring, pflddes->field_type, &link_info, opts); - if (status) break; - - if (plink->type==CONSTANT && plink->value.constantStr==NULL) { - /* links not yet initialized by dbInitRecordLinks() */ - free(plink->text); - plink->text = epicsStrDup(pstring); - dbFreeLinkInfo(&link_info); - } else { - /* assignment after init (eg. autosave restore) */ - struct dbCommon *prec = pdbentry->precnode->precord; - devSup *devsup = (devSup *)ellNth(&pdbentry->precordType->devList, prec->dtyp+1); - - status = dbCanSetLink(plink, &link_info, devsup); - if (status == 0) - status = dbSetLink(plink, &link_info, devsup); - } - } - break; - - default: - return S_dbLib_badField; - } - - if (!status && strcmp(pflddes->name, "VAL") == 0) { - DBENTRY dbentry; - - dbCopyEntryContents(pdbentry, &dbentry); - if (!dbFindField(&dbentry, "UDF")) { - dbPutString(&dbentry, "0"); - } - dbFinishEntry(&dbentry); - } - return(status); -} - -long dbFirstInfo(DBENTRY *pdbentry) -{ - dbRecordNode *precnode = pdbentry->precnode; - - pdbentry->pinfonode = NULL; - if (!precnode) return (S_dbLib_recNotFound); - - pdbentry->pinfonode = (dbInfoNode *)ellFirst(&precnode->infoList); - return (pdbentry->pinfonode ? 0 : S_dbLib_infoNotFound); -} - -long dbNextInfo(DBENTRY *pdbentry) -{ - dbRecordNode *precnode = pdbentry->precnode; - dbInfoNode *pinfo; - - if (!precnode) return (S_dbLib_recNotFound); - pinfo = pdbentry->pinfonode; - if (!pinfo) return (S_dbLib_infoNotFound); - - pinfo = (dbInfoNode *)ellNext(&pinfo->node); - pdbentry->pinfonode = pinfo; - return (pinfo ? 0 : S_dbLib_infoNotFound); -} - -long dbFindInfo(DBENTRY *pdbentry,const char *name) -{ - dbRecordNode *precnode = pdbentry->precnode; - dbInfoNode *pinfo; - - pdbentry->pinfonode = NULL; - if (!precnode) return(S_dbLib_recNotFound); - - pinfo = (dbInfoNode *)ellFirst(&precnode->infoList); - while (pinfo) { - if (!strcmp(pinfo->name, name)) { - pdbentry->pinfonode = pinfo; - return (0); - } - pinfo = (dbInfoNode *)ellNext(&pinfo->node); - } - return (S_dbLib_infoNotFound); -} - -long dbDeleteInfo(DBENTRY *pdbentry) -{ - dbRecordNode *precnode = pdbentry->precnode; - dbInfoNode *pinfo = pdbentry->pinfonode; - - if (!precnode) return (S_dbLib_recNotFound); - if (!pinfo) return (S_dbLib_infoNotFound); - ellDelete(&precnode->infoList,&pinfo->node); - free(pinfo->name); - free(pinfo->string); - free(pinfo); - pdbentry->pinfonode = NULL; - return (0); -} - -const char * dbGetInfoName(DBENTRY *pdbentry) -{ - dbInfoNode *pinfo = pdbentry->pinfonode; - if (!pinfo) return (NULL); - return (pinfo->name); -} - -const char * dbGetInfoString(DBENTRY *pdbentry) -{ - dbInfoNode *pinfo = pdbentry->pinfonode; - if (!pinfo) return (NULL); - return (pinfo->string); -} - -long dbPutInfoString(DBENTRY *pdbentry,const char *string) -{ - dbInfoNode *pinfo = pdbentry->pinfonode; - char *newstring; - if (!pinfo) return (S_dbLib_infoNotFound); - newstring = realloc(pinfo->string,1+strlen(string)); - if (!newstring) return (S_dbLib_outMem); - strcpy(newstring, string); - pinfo->string = newstring; - return (0); -} - -long dbPutInfoPointer(DBENTRY *pdbentry, void *pointer) -{ - dbInfoNode *pinfo = pdbentry->pinfonode; - if (!pinfo) return (S_dbLib_infoNotFound); - pinfo->pointer = pointer; - return (0); -} - -void * dbGetInfoPointer(DBENTRY *pdbentry) -{ - dbInfoNode *pinfo = pdbentry->pinfonode; - if (!pinfo) return (NULL); - return (pinfo->pointer); -} - -const char * dbGetInfo(DBENTRY *pdbentry,const char *name) -{ - if (dbFindInfo(pdbentry, name)) return NULL; - return dbGetInfoString(pdbentry); -} - -long dbPutInfo(DBENTRY *pdbentry,const char *name,const char *string) -{ - dbInfoNode *pinfo; - dbRecordNode *precnode = pdbentry->precnode; - if (!precnode) return (S_dbLib_recNotFound); - - dbFindInfo(pdbentry, name); - pinfo = pdbentry->pinfonode; - if (pinfo) return (dbPutInfoString(pdbentry, string)); - - /*Create new info node*/ - pinfo = calloc(1,sizeof(dbInfoNode)); - if (!pinfo) return (S_dbLib_outMem); - pinfo->name = calloc(1,1+strlen(name)); - if (!pinfo->name) { - free(pinfo); - return (S_dbLib_outMem); - } - strcpy(pinfo->name, name); - pinfo->string = calloc(1,1+strlen(string)); - if (!pinfo->string) { - free(pinfo->name); - free(pinfo); - return (S_dbLib_outMem); - } - strcpy(pinfo->string, string); - ellAdd(&precnode->infoList,&pinfo->node); - pdbentry->pinfonode = pinfo; - return (0); -} - -brkTable * dbFindBrkTable(dbBase *pdbbase,const char *name) -{ - GPHENTRY *pgph; - - pgph = gphFind(pdbbase->pgpHash,name,(void *)&pdbbase->bptList); - if(!pgph) return(NULL); - return((brkTable *)pgph->userPvt); -} - -const char * dbGetFieldTypeString(int dbfType) -{ - int i; - - for (i=0; i < DBF_NTYPES; i++) { - if (pamapdbfType[i].value == dbfType) { - return pamapdbfType[i].strvalue; - } - } - return "BAD_DBF_TYPE"; -} - -int dbFindFieldType(const char *type) -{ - int i; - - for (i = 0; i < DBF_NTYPES; i++) { - if (strcmp(type, pamapdbfType[i].strvalue) == 0) { - return pamapdbfType[i].value; - } - } - return -1; -} - -dbMenu * dbFindMenu(dbBase *pdbbase,const char *name) -{ - GPHENTRY *pgph; - - pgph = gphFind(pdbbase->pgpHash,name,(void *)&pdbbase->menuList); - if(!pgph) return(NULL); - return((dbMenu *)pgph->userPvt); -} - -char ** dbGetMenuChoices(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - - if(!pflddes) return(NULL); - switch (pflddes->field_type) { - case DBF_MENU: { - dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; - - if(!pdbMenu) return(NULL); - return(pdbMenu->papChoiceValue); - } - case DBF_DEVICE: { - dbDeviceMenu *pdbDeviceMenu; - - pdbDeviceMenu = dbGetDeviceMenu(pdbentry); - if(!pdbDeviceMenu) return(NULL); - return(pdbDeviceMenu->papChoice); - } - default: - return(NULL); - } -} - -int dbGetNMenuChoices(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - - if(!pflddes) return(-1); - switch (pflddes->field_type) { - case DBF_MENU: { - dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; - - if(!pdbMenu) return(0); - return(pdbMenu->nChoice); - } - case DBF_DEVICE: { - dbDeviceMenu *pdbDeviceMenu; - - pdbDeviceMenu = dbGetDeviceMenu(pdbentry); - if(!pdbDeviceMenu) return(0); - return(pdbDeviceMenu->nChoice); - } - default: - break; - } - return (-1); -} - -char * dbGetMenuStringFromIndex(DBENTRY *pdbentry, int index) -{ - dbFldDes *pflddes = pdbentry->pflddes; - - if(!pflddes) return(NULL); - switch (pflddes->field_type) { - case DBF_MENU: { - dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; - - if(!pdbMenu) return(NULL); - if(index<0 || index>=pdbMenu->nChoice) return(NULL); - return(pdbMenu->papChoiceValue[index]); - } - case DBF_DEVICE: { - dbDeviceMenu *pdbDeviceMenu; - - pdbDeviceMenu = dbGetDeviceMenu(pdbentry); - if(!pdbDeviceMenu) return(NULL); - if(index<0 || index>=pdbDeviceMenu->nChoice) return(NULL); - return(pdbDeviceMenu->papChoice[index]); - } - default: - break; - } - return (NULL); -} - -int dbGetMenuIndexFromString(DBENTRY *pdbentry, const char *choice) -{ - dbFldDes *pflddes = pdbentry->pflddes; - int ind; - int nChoice = 0; - char **papChoice = NULL; - - if(!pflddes) return(-1); - switch (pflddes->field_type) { - case DBF_MENU: { - dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; - - if(!pdbMenu) return(-1); - papChoice = pdbMenu->papChoiceValue; - nChoice = pdbMenu->nChoice; - break; - } - case DBF_DEVICE: { - dbDeviceMenu *pdbDeviceMenu; - - pdbDeviceMenu = dbGetDeviceMenu(pdbentry); - if(!pdbDeviceMenu) return(-1); - papChoice = pdbDeviceMenu->papChoice; - nChoice = pdbDeviceMenu->nChoice; - break; - } - default: - return(-1); - } - if(nChoice<=0 || !papChoice) return(-1); - for(ind=0; indpgpHash,name,&pdbbase->drvList); - if (!pgph) return NULL; - return (drvSup *) pgph->userPvt; -} - -char * dbGetRelatedField(DBENTRY *psave) -{ - DBENTRY dbEntry; - DBENTRY *pdbentry= &dbEntry; - dbFldDes *pflddes; - char *rtnval = NULL; - long status; - - pflddes = psave->pflddes; - if(pflddes->field_type !=DBF_DEVICE) return(NULL); - dbCopyEntryContents(psave,pdbentry); - pflddes = pdbentry->pflddes; - status = dbFindField(pdbentry,"INP"); - if(status) status = dbFindField(pdbentry,"OUT"); - if(!status) rtnval = pdbentry->pflddes->name; - dbFinishEntry(pdbentry); - return(rtnval); -} - -linkSup* dbFindLinkSup(dbBase *pdbbase, const char *name) { - GPHENTRY *pgph = gphFind(pdbbase->pgpHash,name,&pdbbase->linkList); - if (!pgph) return NULL; - return (linkSup *) pgph->userPvt; -} - -int dbGetNLinks(DBENTRY *pdbentry) -{ - dbRecordType *precordType = pdbentry->precordType; - - if(!precordType) return(S_dbLib_recordTypeNotFound); - return((int)precordType->no_links); -} - -long dbGetLinkField(DBENTRY *pdbentry,int index) -{ - dbRecordType *precordType = pdbentry->precordType; - dbFldDes *pflddes; - - if(!precordType) return(S_dbLib_recordTypeNotFound); - if(index<0 || index>=precordType->no_links) return(S_dbLib_badLink); - pdbentry->indfield = precordType->link_ind[index]; - pdbentry->pflddes = pflddes = precordType->papFldDes[pdbentry->indfield]; - dbGetFieldAddress(pdbentry); - return(0); -} - -int dbGetLinkType(DBENTRY *pdbentry) -{ - dbFldDes *pflddes; - DBLINK *plink; - int field_type; - - dbGetFieldAddress(pdbentry); - pflddes = pdbentry->pflddes; - if(!pflddes) return(-1); - plink = (DBLINK *)pdbentry->pfield; - if(!plink) return(-1); - field_type = pflddes->field_type; - switch (field_type) { - case DBF_INLINK: - case DBF_OUTLINK: - case DBF_FWDLINK: - switch(plink->type) { - case CONSTANT: - return(DCT_LINK_CONSTANT); - case PV_LINK: - case PN_LINK: - case DB_LINK: - case CA_LINK: - return(DCT_LINK_PV); - default: - return(DCT_LINK_FORM); - } - } - return(-1); -} - -void dbDumpPath(DBBASE *pdbbase) -{ - ELLLIST *ppathList; - dbPathNode *pdbPathNode; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - ppathList = (ELLLIST *)pdbbase->pathPvt; - if(!ppathList || !(pdbPathNode = (dbPathNode *)ellFirst(ppathList))) { - printf("no path defined\n"); - return; - } - while(pdbPathNode) { - printf("%s",pdbPathNode->directory); - pdbPathNode = (dbPathNode *)ellNext(&pdbPathNode->node); - if(pdbPathNode) printf("%s", OSI_PATH_LIST_SEPARATOR); - } - printf("\n"); - return; -} - -void dbDumpRecord( - dbBase *pdbbase,const char *precordTypename,int level) -{ - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - dbWriteRecordFP(pdbbase,stdout,precordTypename,level); -} - -void dbDumpMenu(dbBase *pdbbase,const char *menuName) -{ - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - dbWriteMenuFP(pdbbase,stdout,menuName); -} - -void dbDumpRecordType(DBBASE *pdbbase,const char *recordTypeName) -{ - dbRecordType *pdbRecordType; - dbFldDes *pdbFldDes; - int gotMatch; - int i; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - for(pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - if(recordTypeName) { - gotMatch = (strcmp(recordTypeName,pdbRecordType->name)==0) - ? TRUE : FALSE; - }else { - gotMatch=TRUE; - } - if(!gotMatch) continue; - printf("name(%s) no_fields(%hd) no_prompt(%hd) no_links(%hd)\n", - pdbRecordType->name,pdbRecordType->no_fields, - pdbRecordType->no_prompt,pdbRecordType->no_links); - printf("index name\tsortind sortname\n"); - for(i=0; ino_fields; i++) { - pdbFldDes = pdbRecordType->papFldDes[i]; - printf("%5d %s\t%7d %s\n", - i,pdbFldDes->name, - pdbRecordType->sortFldInd[i],pdbRecordType->papsortFldName[i]); - } - printf("link_ind "); - for(i=0; ino_links; i++) - printf(" %hd",pdbRecordType->link_ind[i]); - printf("\n"); - printf("indvalFlddes %d name %s\n",pdbRecordType->indvalFlddes, - pdbRecordType->pvalFldDes->name); - printf("rset * %p rec_size %d\n", - (void *)pdbRecordType->prset,pdbRecordType->rec_size); - if(recordTypeName) break; - } -} - -void dbDumpField( - DBBASE *pdbbase,const char *recordTypeName,const char *fname) -{ - dbRecordType *pdbRecordType; - dbFldDes *pdbFldDes; - int gotMatch; - int i; - dbRecordAttribute *pAttribute; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - for(pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - if(recordTypeName) { - gotMatch = (strcmp(recordTypeName,pdbRecordType->name)==0) - ? TRUE : FALSE; - }else { - gotMatch=TRUE; - } - if(!gotMatch) continue; - printf("recordtype(%s) \n",pdbRecordType->name); - for(i=0; ino_fields; i++) { - int j; - - pdbFldDes = pdbRecordType->papFldDes[i]; - if(fname && strcmp(fname,pdbFldDes->name)!=0) continue; - printf(" %s\n", pdbFldDes->name); - printf("\t prompt: %s\n", - (pdbFldDes->prompt ? pdbFldDes->prompt : "")); - printf("\t extra: %s\n", - (pdbFldDes->extra ? pdbFldDes->extra: "")); - printf("\t indRecordType: %hd\n",pdbFldDes->indRecordType); - printf("\t special: %hd ",pdbFldDes->special); - if(pdbFldDes->special) { - for(j=0; jspecial) { - printf("%s",pamapspcType[j].strvalue); - break; - } - } - } - printf("\n"); - printf("\t field_type: %s\n", - dbGetFieldTypeString(pdbFldDes->field_type)); - printf("\tprocess_passive: %u\n",pdbFldDes->process_passive); - printf("\t property: %u\n",pdbFldDes->prop); - printf("\t base: %d\n",pdbFldDes->base); - if(!pdbFldDes->promptgroup) { - printf("\t promptgroup: %d\n",pdbFldDes->promptgroup); - } else { - printf("\t promptgroup: %s\n", - dbGetPromptGroupNameFromKey(pdbbase, pdbFldDes->promptgroup)); - } - printf("\t interest: %hd\n", pdbFldDes->interest); - printf("\t as_level: %d\n",pdbFldDes->as_level); - printf("\t initial: %s\n", - (pdbFldDes->initial ? pdbFldDes->initial : "")); - if(pdbFldDes->field_type==DBF_MENU) { - if(pdbFldDes->ftPvt) - printf("\t\t menu: %s\n", - ((dbMenu *)pdbFldDes->ftPvt)->name); - else - printf("\t\t menu: NOT FOUND\n"); - } - if(pdbFldDes->field_type==DBF_DEVICE) { - printf("\t ftPvt: %p\n",pdbFldDes->ftPvt); - } - printf("\t size: %hd\n",pdbFldDes->size); - printf("\t offset: %hd\n",pdbFldDes->offset); - } - pAttribute = - (dbRecordAttribute *)ellFirst(&pdbRecordType->attributeList); - while(pAttribute) { - printf("Attribute: name %s value %s\n", - pAttribute->name,pAttribute->value); - pAttribute = (dbRecordAttribute *)ellNext(&pAttribute->node); - } - if(recordTypeName) break; - } -} - -void dbDumpDevice(DBBASE *pdbbase,const char *recordTypeName) -{ - dbRecordType *pdbRecordType; - devSup *pdevSup; - int gotMatch; - - if (recordTypeName) { - if (*recordTypeName == 0 || *recordTypeName == '*') - recordTypeName = 0; - } - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - for(pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - if(recordTypeName) { - gotMatch = (strcmp(recordTypeName,pdbRecordType->name)==0) - ? TRUE : FALSE; - }else { - gotMatch=TRUE; - } - if(!gotMatch) continue; - printf("recordtype(%s)\n",pdbRecordType->name); - for(pdevSup = (devSup *)ellFirst(&pdbRecordType->devList); - pdevSup; pdevSup = (devSup *)ellNext(&pdevSup->node)) { - printf(" device name: %s\n",pdevSup->name); - printf("\tchoice: %s\n",pdevSup->choice); - printf("\tlink_type: %d\n",pdevSup->link_type); - printf("\tpdset: %p\n",(void *)pdevSup->pdset); - if (pdevSup->pdset) { - static const char *names[] = { - " - report()", - " - init()", - " - init_record()", - " - get_ioint_info()" - }; - int i, n = pdevSup->pdset->number; - DEVSUPFUN *pfunc = &pdevSup->pdset->report; - - printf("\t number: %d\n", n); - for (i = 0; i < n; ++i, ++pfunc) { - const char *name = (i < NELEMENTS(names)) ? names[i] : ""; - - printf("\t func %d: %p%s\n", i, (void *)*pfunc, name); - } - } - printf("\tpdsxt: %p\n",(void *)pdevSup->pdsxt); - if (pdevSup->pdsxt) { - printf("\t add_record: %p\n", - (void *)pdevSup->pdsxt->add_record); - printf("\t del_record: %p\n", - (void *)pdevSup->pdsxt->del_record); - } - } - if(recordTypeName) break; - } -} - -void dbDumpDriver(DBBASE *pdbbase) -{ - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - dbWriteDriverFP(pdbbase,stdout); -} - -void dbDumpLink(DBBASE *pdbbase) -{ - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - dbWriteLinkFP(pdbbase,stdout); -} - -void dbDumpRegistrar(DBBASE *pdbbase) -{ - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - dbWriteRegistrarFP(pdbbase,stdout); -} - -void dbDumpFunction(DBBASE *pdbbase) -{ - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - dbWriteFunctionFP(pdbbase,stdout); -} - -void dbDumpVariable(DBBASE *pdbbase) -{ - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - dbWriteVariableFP(pdbbase,stdout); -} - -void dbDumpBreaktable(DBBASE *pdbbase,const char *name) -{ - brkTable *pbrkTable; - brkInt *pbrkInt; - int ind; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - for(pbrkTable = (brkTable *)ellFirst(&pdbbase->bptList); - pbrkTable; pbrkTable = (brkTable *)ellNext(&pbrkTable->node)) { - if (name && strcmp(name,pbrkTable->name)!=0) continue; - printf("breaktable(%s) {\n",pbrkTable->name); - pbrkInt = pbrkTable->paBrkInt; - for(ind=0; ind < pbrkTable->number; ind++) { - printf("\traw=%f slope=%e eng=%f\n", - pbrkInt->raw, pbrkInt->slope, pbrkInt->eng); - pbrkInt++; - } - printf("}\n"); - } - return; -} - -static char *bus[VXI_IO+1] = {"","","VME","CAMAC","AB", - "GPIB","BITBUS","","","","","","INST","BBGPIB","VXI"}; -void dbReportDeviceConfig(dbBase *pdbbase,FILE *report) -{ - DBENTRY dbentry; - DBENTRY *pdbentry=&dbentry; - long status; - char linkValue[messagesize]; - char dtypValue[50]; - char cvtValue[40]; - int ilink,nlinks; - struct link *plink; - int linkType; - FILE *stream = (report==0) ? stdout : report; - - if(!pdbbase) { - fprintf(stderr,"pdbbase not specified\n"); - return; - } - dbInitEntry(pdbbase,pdbentry); - status = dbFirstRecordType(pdbentry); - while(!status) { - status = dbFirstRecord(pdbentry); - while(!status) { - nlinks = dbGetNLinks(pdbentry); - for(ilink=0; ilinkpfield; - linkType = plink->type; - if(bus[linkType][0]==0) continue; - strncpy(linkValue, dbGetString(pdbentry), NELEMENTS(linkValue)-1); - linkValue[NELEMENTS(linkValue)-1] = '\0'; - status = dbFindField(pdbentry,"DTYP"); - if(status) break; - strcpy(dtypValue,dbGetString(pdbentry)); - status = dbFindField(pdbentry,"LINR"); - if(status) { - cvtValue[0] = 0; - } else { - if(strcmp(dbGetString(pdbentry),"LINEAR")!=0) { - cvtValue[0] = 0; - } else { - strcpy(cvtValue,"cvt("); - status = dbFindField(pdbentry,"EGUL"); - if(!status) strcat(cvtValue,dbGetString(pdbentry)); - status = dbFindField(pdbentry,"EGUF"); - if(!status) { - strcat(cvtValue,","); - strcat(cvtValue,dbGetString(pdbentry)); - } - strcat(cvtValue,")"); - } - } - fprintf(stream,"%-8s %-20s %-20s %-20s %-s\n", - bus[linkType],linkValue,dtypValue, - dbGetRecordName(pdbentry),cvtValue); - break; - } - status = dbNextRecord(pdbentry); - } - status = dbNextRecordType(pdbentry); - } - dbFinishEntry(pdbentry); - finishOutstream(stream); - return; -} diff --git a/src/ioc/dbStatic/dbStaticLib.h b/src/ioc/dbStatic/dbStaticLib.h deleted file mode 100644 index b2f4a02ae..000000000 --- a/src/ioc/dbStatic/dbStaticLib.h +++ /dev/null @@ -1,283 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Marty Kraimer - * Date: 06-08-93 - */ - -#ifndef INCdbStaticLibh -#define INCdbStaticLibh 1 - -#include -#include - -#include "shareLib.h" -#include "dbFldTypes.h" -#include "dbBase.h" -#include "link.h" -#include "errMdef.h" -#include "cantProceed.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*Field types as seen by static database access clients*/ -#define DCT_STRING 0 -#define DCT_INTEGER 1 -#define DCT_REAL 2 -#define DCT_MENU 3 -#define DCT_MENUFORM 4 -#define DCT_INLINK 5 -#define DCT_OUTLINK 6 -#define DCT_FWDLINK 7 -#define DCT_NOACCESS 8 - -/*Link types as seen by static database access clients*/ -#define DCT_LINK_CONSTANT 0 -#define DCT_LINK_FORM 1 -#define DCT_LINK_PV 2 - -typedef dbBase DBBASE; - -typedef struct{ - DBBASE *pdbbase; - dbRecordType *precordType; - dbFldDes *pflddes; - dbRecordNode *precnode; - dbInfoNode *pinfonode; - void *pfield; - char *message; - short indfield; -} DBENTRY; - -struct dbAddr; -struct dbCommon; - -/* Static database access routines*/ -epicsShareFunc DBBASE * dbAllocBase(void); -epicsShareFunc void dbFreeBase(DBBASE *pdbbase); -epicsShareFunc DBENTRY * dbAllocEntry(DBBASE *pdbbase); -epicsShareFunc void dbFreeEntry(DBENTRY *pdbentry); -epicsShareFunc void dbInitEntry(DBBASE *pdbbase, - DBENTRY *pdbentry); - -/** Initialize DBENTRY from a valid dbAddr*. - * Constant time equivalent of dbInitEntry() then dbFindRecord(), - * and finally dbFollowAlias() - */ -epicsShareFunc void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry); - -/** Initialize DBENTRY from a valid record (dbCommon*). - * Constant time equivalent of dbInitEntry() then dbFindRecord(), - * and finally dbFollowAlias() when no field is specified. - */ -epicsShareFunc void dbInitEntryFromRecord(struct dbCommon *prec, DBENTRY *pdbentry); - -epicsShareFunc void dbFinishEntry(DBENTRY *pdbentry); -epicsShareFunc DBENTRY * dbCopyEntry(DBENTRY *pdbentry); -epicsShareFunc void dbCopyEntryContents(DBENTRY *pfrom, - DBENTRY *pto); - -epicsShareExtern int dbBptNotMonotonic; - -epicsShareFunc long dbReadDatabase(DBBASE **ppdbbase, - const char *filename, const char *path, const char *substitutions); -epicsShareFunc long dbReadDatabaseFP(DBBASE **ppdbbase, - FILE *fp, const char *path, const char *substitutions); -epicsShareFunc long dbPath(DBBASE *pdbbase, const char *path); -epicsShareFunc long dbAddPath(DBBASE *pdbbase, const char *path); -epicsShareFunc char * dbGetPromptGroupNameFromKey(DBBASE *pdbbase, - const short key); -epicsShareFunc short dbGetPromptGroupKeyFromName(DBBASE *pdbbase, - const char *name); -epicsShareFunc long dbWriteRecord(DBBASE *ppdbbase, - const char *filename, const char *precordTypename, int level); -epicsShareFunc long dbWriteRecordFP(DBBASE *ppdbbase, - FILE *fp, const char *precordTypename, int level); -epicsShareFunc long dbWriteMenu(DBBASE *pdbbase, - const char *filename, const char *menuName); -epicsShareFunc long dbWriteMenuFP(DBBASE *pdbbase, - FILE *fp, const char *menuName); -epicsShareFunc long dbWriteRecordType(DBBASE *pdbbase, - const char *filename, const char *recordTypeName); -epicsShareFunc long dbWriteRecordTypeFP(DBBASE *pdbbase, - FILE *fp, const char *recordTypeName); -epicsShareFunc long dbWriteDevice(DBBASE *pdbbase, - const char *filename); -epicsShareFunc long dbWriteDeviceFP(DBBASE *pdbbase, FILE *fp); -epicsShareFunc long dbWriteDriver(DBBASE *pdbbase, - const char *filename); -epicsShareFunc long dbWriteDriverFP(DBBASE *pdbbase, FILE *fp); -epicsShareFunc long dbWriteLinkFP(DBBASE *pdbbase, FILE *fp); -epicsShareFunc long dbWriteRegistrarFP(DBBASE *pdbbase, FILE *fp); -epicsShareFunc long dbWriteFunctionFP(DBBASE *pdbbase, FILE *fp); -epicsShareFunc long dbWriteVariableFP(DBBASE *pdbbase, FILE *fp); -epicsShareFunc long dbWriteBreaktable(DBBASE *pdbbase, - const char *filename); -epicsShareFunc long dbWriteBreaktableFP(DBBASE *pdbbase, - FILE *fp); - -epicsShareFunc long dbFindRecordType(DBENTRY *pdbentry, - const char *recordTypename); -epicsShareFunc long dbFirstRecordType(DBENTRY *pdbentry); -epicsShareFunc long dbNextRecordType(DBENTRY *pdbentry); -epicsShareFunc char * dbGetRecordTypeName(DBENTRY *pdbentry); -epicsShareFunc int dbGetNRecordTypes(DBENTRY *pdbentry); -epicsShareFunc long dbPutRecordAttribute(DBENTRY *pdbentry, - const char *name, const char*value); -epicsShareFunc long dbGetRecordAttribute(DBENTRY *pdbentry, - const char *name); -epicsShareFunc long dbGetAttributePart(DBENTRY *pdbentry, - const char **ppname); - -epicsShareFunc long dbFirstField(DBENTRY *pdbentry, int dctonly); -epicsShareFunc long dbNextField(DBENTRY *pdbentry, int dctonly); -epicsShareFunc int dbGetFieldType(DBENTRY *pdbentry); -epicsShareFunc int dbGetNFields(DBENTRY *pdbentry, int dctonly); -epicsShareFunc char * dbGetFieldName(DBENTRY *pdbentry); -epicsShareFunc char * dbGetDefault(DBENTRY *pdbentry); -epicsShareFunc char * dbGetPrompt(DBENTRY *pdbentry); -epicsShareFunc int dbGetPromptGroup(DBENTRY *pdbentry); - -epicsShareFunc long dbCreateRecord(DBENTRY *pdbentry, - const char *pname); -epicsShareFunc long dbDeleteRecord(DBENTRY *pdbentry); -epicsShareFunc long dbFreeRecords(DBBASE *pdbbase); -epicsShareFunc long dbFindRecordPart(DBENTRY *pdbentry, - const char **ppname); -epicsShareFunc long dbFindRecord(DBENTRY *pdbentry, - const char *pname); - -epicsShareFunc long dbFirstRecord(DBENTRY *pdbentry); -epicsShareFunc long dbNextRecord(DBENTRY *pdbentry); -epicsShareFunc int dbGetNRecords(DBENTRY *pdbentry); -epicsShareFunc int dbGetNAliases(DBENTRY *pdbentry); -epicsShareFunc char * dbGetRecordName(DBENTRY *pdbentry); -epicsShareFunc long dbCopyRecord(DBENTRY *pdbentry, - const char *newRecordName, int overWriteOK); - -epicsShareFunc long dbVisibleRecord(DBENTRY *pdbentry); -epicsShareFunc long dbInvisibleRecord(DBENTRY *pdbentry); -epicsShareFunc int dbIsVisibleRecord(DBENTRY *pdbentry); - -epicsShareFunc long dbCreateAlias(DBENTRY *pdbentry, - const char *paliasName); -epicsShareFunc int dbIsAlias(DBENTRY *pdbentry); -/* Follow alias to actual record */ -epicsShareFunc int dbFollowAlias(DBENTRY *pdbentry); -epicsShareFunc long dbDeleteAliases(DBENTRY *pdbentry); - -epicsShareFunc long dbFindFieldPart(DBENTRY *pdbentry, - const char **ppname); -epicsShareFunc long dbFindField(DBENTRY *pdbentry, - const char *pfieldName); -epicsShareFunc int dbFoundField(DBENTRY *pdbentry); -epicsShareFunc char * dbGetString(DBENTRY *pdbentry); -epicsShareFunc long dbPutString(DBENTRY *pdbentry, - const char *pstring); -epicsShareFunc int dbIsDefaultValue(DBENTRY *pdbentry); - -epicsShareFunc long dbFirstInfo(DBENTRY *pdbentry); -epicsShareFunc long dbNextInfo(DBENTRY *pdbentry); -epicsShareFunc long dbFindInfo(DBENTRY *pdbentry, - const char *name); -epicsShareFunc long dbDeleteInfo(DBENTRY *pdbentry); -epicsShareFunc const char * dbGetInfoName(DBENTRY *pdbentry); -epicsShareFunc const char * dbGetInfoString(DBENTRY *pdbentry); -epicsShareFunc long dbPutInfoString(DBENTRY *pdbentry, - const char *string); -epicsShareFunc long dbPutInfoPointer(DBENTRY *pdbentry, - void *pointer); -epicsShareFunc void * dbGetInfoPointer(DBENTRY *pdbentry); -epicsShareFunc const char * dbGetInfo(DBENTRY *pdbentry, - const char *name); -epicsShareFunc long dbPutInfo(DBENTRY *pdbentry, - const char *name, const char *string); - -epicsShareFunc brkTable * dbFindBrkTable(DBBASE *pdbbase, - const char *name); - -epicsShareFunc const char * dbGetFieldTypeString(int dbfType); -epicsShareFunc int dbFindFieldType(const char *type); - -epicsShareFunc dbMenu * dbFindMenu(DBBASE *pdbbase, - const char *name); -epicsShareFunc char ** dbGetMenuChoices(DBENTRY *pdbentry); -epicsShareFunc int dbGetMenuIndex(DBENTRY *pdbentry); -epicsShareFunc long dbPutMenuIndex(DBENTRY *pdbentry, int index); -epicsShareFunc int dbGetNMenuChoices(DBENTRY *pdbentry); -epicsShareFunc char * dbGetMenuStringFromIndex(DBENTRY *pdbentry, - int index); -epicsShareFunc int dbGetMenuIndexFromString(DBENTRY *pdbentry, - const char *choice); - -epicsShareFunc drvSup * dbFindDriver(dbBase *pdbbase, - const char *name); -epicsShareFunc char * dbGetRelatedField(DBENTRY *pdbentry); - -epicsShareFunc linkSup * dbFindLinkSup(dbBase *pdbbase, - const char *name); - -epicsShareFunc int dbGetNLinks(DBENTRY *pdbentry); -epicsShareFunc long dbGetLinkField(DBENTRY *pdbentry, int index); -epicsShareFunc int dbGetLinkType(DBENTRY *pdbentry); - -/* Dump routines */ -epicsShareFunc void dbDumpPath(DBBASE *pdbbase); -epicsShareFunc void dbDumpRecord(DBBASE *pdbbase, - const char *precordTypename, int level); -epicsShareFunc void dbDumpMenu(DBBASE *pdbbase, - const char *menuName); -epicsShareFunc void dbDumpRecordType(DBBASE *pdbbase, - const char *recordTypeName); -epicsShareFunc void dbDumpField(DBBASE *pdbbase, - const char *recordTypeName, const char *fname); -epicsShareFunc void dbDumpDevice(DBBASE *pdbbase, - const char *recordTypeName); -epicsShareFunc void dbDumpDriver(DBBASE *pdbbase); -epicsShareFunc void dbDumpLink(DBBASE *pdbbase); -epicsShareFunc void dbDumpRegistrar(DBBASE *pdbbase); -epicsShareFunc void dbDumpFunction(DBBASE *pdbbase); -epicsShareFunc void dbDumpVariable(DBBASE *pdbbase); -epicsShareFunc void dbDumpBreaktable(DBBASE *pdbbase, - const char *name); -epicsShareFunc void dbPvdDump(DBBASE *pdbbase, int verbose); -epicsShareFunc void dbReportDeviceConfig(DBBASE *pdbbase, - FILE *report); - -/* Misc useful routines*/ -#define dbCalloc(nobj,size) callocMustSucceed(nobj,size,"dbCalloc") -#define dbMalloc(size) mallocMustSucceed(size,"dbMalloc") -epicsShareFunc void dbCatString(char **string, int *stringLength, - char *pnew, char *separator); - -extern int dbStaticDebug; -extern int dbConvertStrict; - -#define S_dbLib_recordTypeNotFound (M_dbLib|1) /* Record Type does not exist */ -#define S_dbLib_recExists (M_dbLib|3) /* Record Already exists */ -#define S_dbLib_recNotFound (M_dbLib|5) /* Record Not Found */ -#define S_dbLib_flddesNotFound (M_dbLib|7) /* Field Description Not Found */ -#define S_dbLib_fieldNotFound (M_dbLib|9) /* Field Not Found */ -#define S_dbLib_badField (M_dbLib|11) /* Bad Field value */ -#define S_dbLib_menuNotFound (M_dbLib|13) /* Menu not found */ -#define S_dbLib_badLink (M_dbLib|15) /* Bad Link Field */ -#define S_dbLib_nameLength (M_dbLib|17) /* Record Name is too long */ -#define S_dbLib_noRecSup (M_dbLib|19) /* Record support not found */ -#define S_dbLib_strLen (M_dbLib|21) /* String is too long */ -#define S_dbLib_noSizeOffset (M_dbLib|23) /* Missing SizeOffset Routine - No record support? */ -#define S_dbLib_outMem (M_dbLib|27) /* Out of memory */ -#define S_dbLib_infoNotFound (M_dbLib|29) /* Info item Not Found */ - -#ifdef __cplusplus -} -#endif - -#endif /*INCdbStaticLibh*/ diff --git a/src/ioc/dbStatic/dbStaticPvt.h b/src/ioc/dbStatic/dbStaticPvt.h deleted file mode 100644 index 58d32c28c..000000000 --- a/src/ioc/dbStatic/dbStaticPvt.h +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbStaticPvt.h */ -/* - * Author: Marty Kraimer - * Date: 06Jun95 - */ - -#ifndef INCdbStaticPvth -#define INCdbStaticPvth 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/*Following are not intended for client code */ -dbDeviceMenu *dbGetDeviceMenu(DBENTRY *pdbentry); -void dbFreeLinkContents(struct link *plink); -void dbFreePath(DBBASE *pdbbase); -int dbIsMacroOk(DBENTRY *pdbentry); - -/*The following routines have different versions for run-time no-run-time*/ -long dbAllocRecord(DBENTRY *pdbentry,const char *precordName); -long dbFreeRecord(DBENTRY *pdbentry); - -long dbGetFieldAddress(DBENTRY *pdbentry); -char *dbRecordName(DBENTRY *pdbentry); - -char *dbGetStringNum(DBENTRY *pdbentry); -long dbPutStringNum(DBENTRY *pdbentry,const char *pstring); - -struct jlink; - -typedef struct dbLinkInfo { - short ltype; - - /* full link string for CONSTANT and PV_LINK, - * parm string for HW links, JSON for JSON_LINK - */ - char *target; - - /* for PV_LINK */ - short modifiers; - - /* for HW links */ - char hwid[6]; /* one extra element for a nil */ - int hwnums[5]; - - /* for JSON_LINK */ - struct jlink *jlink; -} dbLinkInfo; - -long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec); - -#define LINK_DEBUG_LSET 1 -#define LINK_DEBUG_JPARSE 2 - -/* Parse link string. no record locks needed. - * on success caller must free pinfo->target - */ -epicsShareFunc long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, unsigned opts); -/* Check if link type allow the parsed link value pinfo - * to be assigned to the given link. - * Record containing plink must be locked. - * Frees pinfo->target on failure. - */ -long dbCanSetLink(DBLINK *plink, dbLinkInfo *pinfo, devSup *devsup); -/* Set link field. source record must be locked (target record too - * when a DB_LINK is created) - * Unconditionally takes ownership of pinfo->target - */ -long dbSetLink(DBLINK *plink, dbLinkInfo *pinfo, devSup *dset); -/* Free dbLinkInfo storage */ -epicsShareFunc void dbFreeLinkInfo(dbLinkInfo *pinfo); - -/* The following is for path */ -typedef struct dbPathNode { - ELLNODE node; - char *directory; -} dbPathNode; - -/* Element of the global gui group list */ -typedef struct dbGuiGroup { - ELLNODE node; - short key; - char *name; -} dbGuiGroup; - -/*The following are in dbPvdLib.c*/ -/*directory*/ -typedef struct{ - ELLNODE node; - dbRecordType *precordType; - dbRecordNode *precnode; -}PVDENTRY; -epicsShareFunc int dbPvdTableSize(int size); -extern int dbStaticDebug; -void dbPvdInitPvt(DBBASE *pdbbase); -PVDENTRY *dbPvdFind(DBBASE *pdbbase,const char *name,size_t lenname); -PVDENTRY *dbPvdAdd(DBBASE *pdbbase,dbRecordType *precordType,dbRecordNode *precnode); -void dbPvdDelete(DBBASE *pdbbase,dbRecordNode *precnode); -void dbPvdFreeMem(DBBASE *pdbbase); - -#ifdef __cplusplus -} -#endif -#endif /*INCdbStaticPvth*/ diff --git a/src/ioc/dbStatic/dbStaticRun.c b/src/ioc/dbStatic/dbStaticRun.c deleted file mode 100644 index efc672270..000000000 --- a/src/ioc/dbStatic/dbStaticRun.c +++ /dev/null @@ -1,558 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*dbStaticLibRun.c*/ - -#include -#include -#include -#include -#include - -#include "cvtFast.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsPrint.h" -#include "epicsStdlib.h" -#include "epicsTypes.h" -#include "errMdef.h" - -#include "epicsExport.h" /* #define epicsExportSharedSymbols */ -#include "dbBase.h" -#include "dbCommonPvt.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "devSup.h" -#include "special.h" - -epicsShareDef int dbConvertStrict = 0; -epicsExportAddress(int, dbConvertStrict); - -static long do_nothing(struct dbCommon *precord) { return 0; } - -/* Dummy DSXT used for soft device supports */ -struct dsxt devSoft_DSXT = { - do_nothing, - do_nothing -}; - -static devSup *pthisDevSup = NULL; - -void dbInitDevSup(devSup *pdevSup, dset *pdset) -{ - pdevSup->pdset = pdset; - if (pdevSup->link_type == CONSTANT) - pdevSup->pdsxt = &devSoft_DSXT; - - if (pdset->init) { - pthisDevSup = pdevSup; - pdset->init(0); - pthisDevSup = NULL; - } -} - -void devExtend(dsxt *pdsxt) -{ - if (!pthisDevSup) - errlogPrintf("devExtend() called outside of dbInitDevSup()\n"); - else { - pthisDevSup->pdsxt = pdsxt; - } -} - -long dbAllocRecord(DBENTRY *pdbentry,const char *precordName) -{ - dbRecordType *pdbRecordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - dbFldDes *pflddes; - int i; - dbCommonPvt *ppvt; - dbCommon *precord; - char *pfield; - - if(!pdbRecordType) return(S_dbLib_recordTypeNotFound); - if(!precnode) return(S_dbLib_recNotFound); - if(pdbRecordType->rec_size == 0) { - printf("\t*** Did you run x_RegisterRecordDeviceDriver(pdbbase) yet? ***\n"); - epicsPrintf("dbAllocRecord(%s) with %s rec_size = 0\n", - precordName, pdbRecordType->name); - return(S_dbLib_noRecSup); - } else if(pdbRecordType->rec_sizename); - epicsPrintf("dbAllocRecord(%s) with %s rec_size = %d\n", - precordName, pdbRecordType->name, pdbRecordType->rec_size); - return(S_dbLib_noRecSup); - } - ppvt = dbCalloc(1, offsetof(dbCommonPvt, common) + pdbRecordType->rec_size); - precord = &ppvt->common; - ppvt->recnode = precnode; - precord->rdes = pdbRecordType; - precnode->precord = precord; - pflddes = pdbRecordType->papFldDes[0]; - if(!pflddes) { - epicsPrintf("dbAllocRecord pflddes for NAME not found\n"); - return(S_dbLib_flddesNotFound); - } - assert(pflddes->offset == 0); - assert(pflddes->size == sizeof(precord->name)); - if(strlen(precordName) >= sizeof(precord->name)) { - epicsPrintf("dbAllocRecord: NAME(%s) too long\n",precordName); - return(S_dbLib_nameLength); - } - strcpy(precord->name, precordName); - for(i=1; ino_fields; i++) { - - pflddes = pdbRecordType->papFldDes[i]; - if(!pflddes) continue; - pfield = (char*)precord + pflddes->offset; - pdbentry->pfield = (void *)pfield; - pdbentry->pflddes = pflddes; - pdbentry->indfield = i; - switch(pflddes->field_type) { - case DBF_STRING: - if(pflddes->initial) { - if(strlen(pflddes->initial) >= pflddes->size) { - epicsPrintf("initial size > size for %s.%s\n", - pdbRecordType->name,pflddes->name); - } else { - strcpy(pfield,pflddes->initial); - } - } - break; - case DBF_CHAR: - case DBF_UCHAR: - case DBF_SHORT: - case DBF_USHORT: - case DBF_LONG: - case DBF_ULONG: - case DBF_INT64: - case DBF_UINT64: - case DBF_FLOAT: - case DBF_DOUBLE: - case DBF_ENUM: - case DBF_MENU: - if(pflddes->initial) { - long status; - - status = dbPutStringNum(pdbentry,pflddes->initial); - if(status) - epicsPrintf("Error initializing %s.%s initial %s\n", - pdbRecordType->name,pflddes->name,pflddes->initial); - } - break; - case DBF_DEVICE: - if(!pflddes->ftPvt) dbGetDeviceMenu(pdbentry); - break; - case DBF_INLINK: - case DBF_OUTLINK: - case DBF_FWDLINK: { - DBLINK *plink = (DBLINK *)pfield; - - plink->type = CONSTANT; - if(pflddes->initial) { - plink->text = - dbCalloc(strlen(pflddes->initial)+1,sizeof(char)); - strcpy(plink->text,pflddes->initial); - } - } - break; - case DBF_NOACCESS: - break; - default: - epicsPrintf("dbAllocRecord: Illegal field type\n"); - } - } - return(0); -} - -long dbFreeRecord(DBENTRY *pdbentry) -{ - dbRecordType *pdbRecordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - - if(!pdbRecordType) return(S_dbLib_recordTypeNotFound); - if(!precnode) return(S_dbLib_recNotFound); - if(!precnode->precord) return(S_dbLib_recNotFound); - free(CONTAINER(precnode->precord, dbCommonPvt, common)); - precnode->precord = NULL; - return(0); -} - -long dbGetFieldAddress(DBENTRY *pdbentry) -{ - dbRecordType *pdbRecordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - dbFldDes *pflddes = pdbentry->pflddes; - - if(!pdbRecordType) return(S_dbLib_recordTypeNotFound); - if(!precnode) return(S_dbLib_recNotFound); - if(!pflddes) return(S_dbLib_flddesNotFound); - if(!precnode->precord) return(0); - pdbentry->pfield = ((char *)precnode->precord) + pflddes->offset; - return(0); -} - -char *dbRecordName(DBENTRY *pdbentry) -{ - dbRecordType *pdbRecordType = pdbentry->precordType; - dbRecordNode *precnode = pdbentry->precnode; - dbFldDes *pflddes; - char *precord; - - if(!pdbRecordType) return(0); - if(!precnode) return(0); - if(!precnode->precord) return(0); - precord = (char *)precnode->precord; - pflddes = pdbRecordType->papFldDes[0]; - if(!pflddes) return(NULL); - return(precord + pflddes->offset); -} - -int dbIsMacroOk(DBENTRY *pdbentry) { return(FALSE); } - -epicsShareFunc int dbIsDefaultValue(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - void *pfield = pdbentry->pfield; - - if (!pflddes || !pfield) - return FALSE; - - switch (pflddes->field_type) { - case DBF_STRING: { - char *p = (char *)pfield; - - return pflddes->initial ? ! strcmp(pflddes->initial, p) - : ! strlen(p); - } - case DBF_CHAR: { - epicsInt8 field = *(epicsInt8 *)pfield; - epicsInt8 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseInt8(pflddes->initial, &def, 0, NULL) - && field == def; - } - case DBF_UCHAR: { - epicsUInt8 field = *(epicsUInt8 *)pfield; - epicsUInt8 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseUInt8(pflddes->initial, &def, 0, NULL) - && field == def; - } - case DBF_SHORT: { - epicsInt16 field = *(epicsInt16 *)pfield; - epicsInt16 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseInt16(pflddes->initial, &def, 0, NULL) - && field == def; - } - case DBF_ENUM: - case DBF_USHORT: { - epicsUInt16 field = *(epicsUInt16 *)pfield; - epicsUInt16 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseUInt16(pflddes->initial, &def, 0, NULL) - && field == def; - } - case DBF_LONG: { - epicsInt32 field = *(epicsInt32 *)pfield; - epicsInt32 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseInt32(pflddes->initial, &def, 0, NULL) - && field == def; - } - case DBF_ULONG: { - epicsUInt32 field = *(epicsUInt32 *)pfield; - epicsUInt32 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseUInt32(pflddes->initial, &def, 0, NULL) - && field == def; - } - case DBF_INT64: { - epicsInt64 field = *(epicsInt64 *)pfield; - epicsInt64 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseInt64(pflddes->initial, &def, 0, NULL) - && field == def; - } - case DBF_UINT64: { - epicsUInt64 field = *(epicsUInt64 *)pfield; - epicsUInt64 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseUInt64(pflddes->initial, &def, 0, NULL) - && field == def; - } - case DBF_FLOAT: { - epicsFloat32 field = *(epicsFloat32 *)pfield; - epicsFloat32 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseFloat32(pflddes->initial, &def, NULL) - && field == def; - } - case DBF_DOUBLE: { - epicsFloat64 field = *(epicsFloat64 *)pfield; - epicsFloat64 def; - - if (!pflddes->initial) - return field == 0; - - return ! epicsParseFloat64(pflddes->initial, &def, NULL) - && field == def; - } - case DBF_MENU: { - epicsEnum16 field = *(epicsEnum16 *)pfield; - epicsEnum16 def; - int index; - - if (!pflddes->initial) - return field == 0; - - index = dbGetMenuIndexFromString(pdbentry, pflddes->initial); - if (index < 0) { - if (epicsParseUInt16(pflddes->initial, &def, 0, NULL)) - return FALSE; - } - else - def = index; - return field == def; - } - case DBF_DEVICE: { - dbRecordType *precordType = pdbentry->precordType; - - if (!precordType) { - epicsPrintf("dbIsDefaultValue: pdbRecordType is NULL??\n"); - return FALSE; - } - return ellCount(&precordType->devList) == 0; - } - case DBF_INLINK: - case DBF_OUTLINK: - case DBF_FWDLINK: { - struct link *plink = (struct link *)pfield; - - if (!plink || plink->type != CONSTANT) - return FALSE; - - /* These conditions don't make a lot of sense... */ - if (!plink->value.constantStr) - return TRUE; - - if (!pflddes->initial) /* Default value for a link field? */ - return FALSE; - - return !strcmp(plink->value.constantStr, pflddes->initial); - } - default: - return TRUE; - } -} - -long dbPutStringNum(DBENTRY *pdbentry, const char *pstring) -{ - dbFldDes *pflddes = pdbentry->pflddes; - void *pfield = pdbentry->pfield; - long status; - epicsUInt64 u64; - epicsInt64 i64; - - if (!pfield) - return S_dbLib_fieldNotFound; - - /* empty string is the same as writing numeric zero */ - if (pstring[0] == '\0') - pstring = "0"; - - switch (pflddes->field_type) { - case DBF_CHAR: - if (dbConvertStrict) - return epicsParseInt8(pstring, pfield, 0, NULL); - goto lax_signed; - - case DBF_SHORT: - if (dbConvertStrict) - return epicsParseInt16(pstring, pfield, 0, NULL); - goto lax_signed; - - case DBF_LONG: - if (dbConvertStrict) - return epicsParseInt32(pstring, pfield, 0, NULL); - goto lax_signed; - - case DBF_INT64: - if (dbConvertStrict) - return epicsParseInt64(pstring, pfield, 0, NULL); - - lax_signed: - status = epicsParseInt64(pstring, &i64, 0, NULL); - if (status) - return status; - - switch (pflddes->field_type) { - case DBF_CHAR: *(epicsInt8 *)pfield = (epicsInt8) i64; break; - case DBF_SHORT: *(epicsInt16*)pfield = (epicsInt16)i64; break; - case DBF_LONG: *(epicsInt32*)pfield = (epicsInt32)i64; break; - case DBF_INT64: *(epicsInt64*)pfield = (epicsInt64)i64; break; - default: break; - } - return status; - - case DBF_UCHAR: - if (dbConvertStrict) - return epicsParseUInt8(pstring, pfield, 0, NULL); - goto lax_unsigned; - - case DBF_ENUM: - case DBF_USHORT: - if (dbConvertStrict) - return epicsParseUInt16(pstring, pfield, 0, NULL); - goto lax_unsigned; - - case DBF_ULONG: - if (dbConvertStrict) - return epicsParseUInt32(pstring, pfield, 0, NULL); - goto lax_unsigned; - - case DBF_UINT64: - if (dbConvertStrict) - return epicsParseUInt64(pstring, pfield, 0, NULL); - - lax_unsigned: - status = epicsParseUInt64(pstring, &u64, 0, NULL); - if (status) - return status; - - switch (pflddes->field_type) { - case DBF_UCHAR: *(epicsUInt8 *)pfield = (epicsInt8) u64; break; - case DBF_ENUM: - case DBF_USHORT: *(epicsUInt16*)pfield = (epicsInt16)u64; break; - case DBF_ULONG: *(epicsUInt32*)pfield = (epicsInt32)u64; break; - case DBF_UINT64: *(epicsUInt64*)pfield = (epicsInt64)u64; break; - default: break; - } - return status; - - case DBF_FLOAT: - return epicsParseFloat32(pstring, pfield, NULL); - - case DBF_DOUBLE: - return epicsParseFloat64(pstring, pfield, NULL); - - case DBF_MENU: - case DBF_DEVICE: { - epicsEnum16 *field = (epicsEnum16 *) pfield; - int index = dbGetMenuIndexFromString(pdbentry, pstring); - - if (index < 0) { - epicsEnum16 value; - long status = epicsParseUInt16(pstring, &value, 0, NULL); - - if (status) - return status; - - index = dbGetNMenuChoices(pdbentry); - if (value > index && index > 0) - return S_dbLib_badField; - - *field = value; - } - else - *field = index; - return 0; - } - - default: - return S_dbLib_badField; - } -} - -epicsShareFunc int dbGetMenuIndex(DBENTRY *pdbentry) -{ - dbFldDes *pflddes = pdbentry->pflddes; - void *pfield = pdbentry->pfield; - - if (!pflddes || !pfield) - return -1; - - switch (pflddes->field_type) { - case DBF_MENU: - case DBF_DEVICE: - return * (epicsEnum16 *) pfield; - default: - epicsPrintf("dbGetMenuIndex: Called for field type %d\n", - pflddes->field_type); - } - return -1; -} - -epicsShareFunc long dbPutMenuIndex(DBENTRY *pdbentry, int index) -{ - dbFldDes *pflddes = pdbentry->pflddes; - epicsEnum16 *pfield = pdbentry->pfield; - - if (!pflddes) - return S_dbLib_flddesNotFound; - if (!pfield) - return S_dbLib_fieldNotFound; - - switch (pflddes->field_type) { - case DBF_MENU: { - dbMenu *pdbMenu = (dbMenu *) pflddes->ftPvt; - - if (!pdbMenu) - return S_dbLib_menuNotFound; - if (index < 0 || index >= pdbMenu->nChoice) - return S_dbLib_badField; - - *pfield = index; - return 0; - } - - case DBF_DEVICE: { - dbDeviceMenu *pdbDeviceMenu = dbGetDeviceMenu(pdbentry); - - if (!pdbDeviceMenu) - return S_dbLib_menuNotFound; - if (index < 0 || index >= pdbDeviceMenu->nChoice) - return S_dbLib_badField; - - return dbPutString(pdbentry, pdbDeviceMenu->papChoice[index]); - } - - default: - break; - } - return S_dbLib_badField; -} diff --git a/src/ioc/dbStatic/dbYacc.y b/src/ioc/dbStatic/dbYacc.y deleted file mode 100644 index e61ce58b0..000000000 --- a/src/ioc/dbStatic/dbYacc.y +++ /dev/null @@ -1,376 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -%{ -static int yyerror(); -static int yy_start; -static long pvt_yy_parse(void); -static int yyFailed = 0; -static int yyAbort = 0; -#include "dbLexRoutines.c" -%} - -%start database - -%union -{ - char *Str; -} - -%token tokenINCLUDE tokenPATH tokenADDPATH -%token tokenALIAS tokenMENU tokenCHOICE tokenRECORDTYPE -%token tokenFIELD tokenINFO tokenREGISTRAR -%token tokenDEVICE tokenDRIVER tokenLINK tokenBREAKTABLE -%token tokenRECORD tokenGRECORD tokenVARIABLE tokenFUNCTION -%token tokenSTRING tokenCDEFS - -%token jsonNULL jsonTRUE jsonFALSE -%token jsonNUMBER jsonSTRING jsonBARE -%type json_value json_object json_array -%type json_members json_pair json_elements json_string - -%% - -database: /* empty */ - | database_item_list - ; - -database_item_list: database_item_list database_item - | database_item - ; - -database_item: include - | path - | addpath - | tokenMENU menu_head menu_body - | tokenRECORDTYPE recordtype_head recordtype_body - | device - | driver - | link - | registrar - | function - | variable - | tokenBREAKTABLE break_head break_body - | tokenRECORD record_head record_body - | tokenGRECORD grecord_head record_body - | alias - ; - -include: tokenINCLUDE tokenSTRING -{ - if(dbStaticDebug>2) printf("include : %s\n",$2); - dbIncludeNew($2); dbmfFree($2); -}; - -path: tokenPATH tokenSTRING -{ - if(dbStaticDebug>2) printf("path : %s\n",$2); - dbPathCmd($2); dbmfFree($2); -}; - -addpath: tokenADDPATH tokenSTRING -{ - if(dbStaticDebug>2) printf("addpath : %s\n",$2); - dbAddPathCmd($2); dbmfFree($2); -}; - -menu_head: '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("menu_head %s\n",$2); - dbMenuHead($2); dbmfFree($2); -}; - -menu_body: '{' choice_list '}' -{ - if(dbStaticDebug>2) printf("menu_body\n"); - dbMenuBody(); -}; - -choice_list: choice_list choice | choice; - -choice: tokenCHOICE '(' tokenSTRING ',' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("choice %s %s\n",$3,$5); - dbMenuChoice($3,$5); dbmfFree($3); dbmfFree($5); -} - | include; - -recordtype_head: '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("recordtype_head %s\n",$2); - dbRecordtypeHead($2); dbmfFree($2); -}; - -recordtype_body: '{' '}' -{ - if(dbStaticDebug>2) printf("empty recordtype_body\n"); - dbRecordtypeEmpty(); -} - | '{' recordtype_field_list '}' -{ - if(dbStaticDebug>2) printf("recordtype_body\n"); - dbRecordtypeBody(); -}; - -recordtype_field_list: recordtype_field_list recordtype_field - | recordtype_field; - -recordtype_field: tokenFIELD recordtype_field_head recordtype_field_body - | tokenCDEFS -{ - if(dbStaticDebug>2) printf("recordtype_cdef %s", $1); - dbRecordtypeCdef($1); dbmfFree($1); -} - | include ; - -recordtype_field_head: '(' tokenSTRING ',' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("recordtype_field_head %s %s\n",$2,$4); - dbRecordtypeFieldHead($2,$4); dbmfFree($2); dbmfFree($4); -}; - -recordtype_field_body: '{' recordtype_field_item_list '}' ; - -recordtype_field_item_list: recordtype_field_item_list recordtype_field_item - | recordtype_field_item; - -recordtype_field_item: tokenSTRING '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("recordtype_field_item %s %s\n",$1,$3); - dbRecordtypeFieldItem($1,$3); dbmfFree($1); dbmfFree($3); -} - | tokenMENU '(' tokenSTRING ')' -{ - - if(dbStaticDebug>2) printf("recordtype_field_item %s (%s)\n","menu",$3); - dbRecordtypeFieldItem("menu",$3); dbmfFree($3); -}; - - -device: tokenDEVICE '(' - tokenSTRING ',' tokenSTRING ',' tokenSTRING ',' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("device %s %s %s %s\n",$3,$5,$7,$9); - dbDevice($3,$5,$7,$9); - dbmfFree($3); dbmfFree($5); - dbmfFree($7); dbmfFree($9); -}; - - -driver: tokenDRIVER '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("driver %s\n",$3); - dbDriver($3); dbmfFree($3); -}; - -link: tokenLINK '(' tokenSTRING ',' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("link %s %s\n",$3,$5); - dbLinkType($3,$5); - dbmfFree($3); dbmfFree($5); -}; - -registrar: tokenREGISTRAR '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("registrar %s\n",$3); - dbRegistrar($3); dbmfFree($3); -}; - -function: tokenFUNCTION '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("function %s\n",$3); - dbFunction($3); dbmfFree($3); -}; - -variable: tokenVARIABLE '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("variable %s\n",$3); - dbVariable($3,"int"); dbmfFree($3); -} - | tokenVARIABLE '(' tokenSTRING ',' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("variable %s, %s\n",$3,$5); - dbVariable($3,$5); dbmfFree($3); dbmfFree($5); -}; - -break_head: '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("break_head %s\n",$2); - dbBreakHead($2); dbmfFree($2); -}; - -break_body : '{' break_list '}' -{ - if(dbStaticDebug>2) printf("break_body\n"); - dbBreakBody(); -}; - -break_list: break_list ',' break_item - | break_list break_item - | break_item; - -break_item: tokenSTRING -{ - if(dbStaticDebug>2) printf("break_item tokenSTRING %s\n",$1); - dbBreakItem($1); dbmfFree($1); -}; - - -grecord_head: '(' tokenSTRING ',' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("grecord_head %s %s\n",$2,$4); - dbRecordHead($2,$4,1); dbmfFree($2); dbmfFree($4); -}; - -record_head: '(' tokenSTRING ',' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("record_head %s %s\n",$2,$4); - dbRecordHead($2,$4,0); dbmfFree($2); dbmfFree($4); -}; - -record_body: /* empty */ -{ - if(dbStaticDebug>2) printf("null record_body\n"); - dbRecordBody(); -} - | '{' '}' -{ - if(dbStaticDebug>2) printf("empty record_body\n"); - dbRecordBody(); -} - | '{' record_field_list '}' -{ - if(dbStaticDebug>2) printf("record_body\n"); - dbRecordBody(); -}; - -record_field_list: record_field_list record_field - | record_field; - -record_field: tokenFIELD '(' tokenSTRING ',' - { BEGIN JSON; } json_value { BEGIN INITIAL; } ')' -{ - if(dbStaticDebug>2) printf("record_field %s %s\n",$3,$6); - dbRecordField($3,$6); dbmfFree($3); dbmfFree($6); -} - | tokenINFO '(' tokenSTRING ',' - { BEGIN JSON; } json_value { BEGIN INITIAL; } ')' -{ - if(dbStaticDebug>2) printf("record_info %s %s\n",$3,$6); - dbRecordInfo($3,$6); dbmfFree($3); dbmfFree($6); -} - | tokenALIAS '(' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("record_alias %s\n",$3); - dbRecordAlias($3); dbmfFree($3); -} - | include ; - -alias: tokenALIAS '(' tokenSTRING ',' tokenSTRING ')' -{ - if(dbStaticDebug>2) printf("alias %s %s\n",$3,$5); - dbAlias($3,$5); dbmfFree($3); dbmfFree($5); -}; - -json_object: '{' '}' -{ - $$ = dbmfStrdup("{}"); - if (dbStaticDebug>2) printf("json %s\n", $$); -} - | '{' json_members '}' -{ - $$ = dbmfStrcat3("{", $2, "}"); - dbmfFree($2); - if (dbStaticDebug>2) printf("json %s\n", $$); -}; - -json_members: json_pair - | json_pair ',' json_members -{ - $$ = dbmfStrcat3($1, ",", $3); - dbmfFree($1); dbmfFree($3); - if (dbStaticDebug>2) printf("json %s\n", $$); -}; - -json_pair: json_string ':' json_value -{ - $$ = dbmfStrcat3($1, ":", $3); - dbmfFree($1); dbmfFree($3); - if (dbStaticDebug>2) printf("json %s\n", $$); -}; - -json_string: jsonSTRING - | jsonBARE -{ - $$ = dbmfStrcat3("\"", $1, "\""); - dbmfFree($1); - if (dbStaticDebug>2) printf("json %s\n", $$); -}; - -json_array: '[' ']' -{ - $$ = dbmfStrdup("[]"); - if (dbStaticDebug>2) printf("json %s\n", $$); -} - | '[' json_elements ']' -{ - $$ = dbmfStrcat3("[", $2, "]"); - dbmfFree($2); - if (dbStaticDebug>2) printf("json %s\n", $$); -}; - -json_elements: json_value - | json_value ',' json_elements -{ - $$ = dbmfStrcat3($1, ",", $3); - dbmfFree($1); dbmfFree($3); - if (dbStaticDebug>2) printf("json %s\n", $$); -}; - -json_value: jsonNULL { $$ = dbmfStrdup("null"); } - | jsonTRUE { $$ = dbmfStrdup("true"); } - | jsonFALSE { $$ = dbmfStrdup("false"); } - | jsonNUMBER - | json_string - | json_array - | json_object ; - - -%% - -#include "dbLex.c" - - -static int yyerror(char *str) -{ - if (str) - epicsPrintf("Error: %s\n", str); - else - epicsPrintf("Error"); - if (!yyFailed) { /* Only print this stuff once */ - epicsPrintf(" at or before \"%s\"", yytext); - dbIncludePrint(); - yyFailed = TRUE; - } - return(0); -} -static long pvt_yy_parse(void) -{ - static int FirstFlag = 1; - long rtnval; - - if (!FirstFlag) { - yyAbort = FALSE; - yyFailed = FALSE; - yyreset(); - yyrestart(NULL); - } - FirstFlag = 0; - rtnval = yyparse(); - if(rtnval!=0 || yyFailed) return(-1); else return(0); -} diff --git a/src/ioc/dbStatic/devSup.h b/src/ioc/dbStatic/devSup.h deleted file mode 100644 index bd900cae4..000000000 --- a/src/ioc/dbStatic/devSup.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devSup.h Device Support */ -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - -#ifndef INCdevSuph -#define INCdevSuph 1 - -#include "errMdef.h" -#include "shareLib.h" - -/* structures defined elsewhere */ -struct dbCommon; -struct devSup; - -#ifdef __cplusplus -extern "C" { - typedef long (*DEVSUPFUN)(void *); /* ptr to device support function*/ -#else - typedef long (*DEVSUPFUN)(); /* ptr to device support function*/ -#endif - -typedef struct dset { /* device support entry table */ - long number; /*number of support routines*/ - DEVSUPFUN report; /*print report*/ - DEVSUPFUN init; /*init support layer*/ - DEVSUPFUN init_record; /*init device for particular record*/ - DEVSUPFUN get_ioint_info; /* get io interrupt information*/ - /*other functions are record dependent*/ -} dset; - -typedef struct dsxt { /* device support extension table */ - long (*add_record)(struct dbCommon *precord); - long (*del_record)(struct dbCommon *precord); - /* Recordtypes are *not* allowed to extend this table */ -} dsxt; - -epicsShareExtern dsxt devSoft_DSXT; /* Allow anything table */ - -epicsShareFunc void devExtend(dsxt *pdsxt); -epicsShareFunc void dbInitDevSup(struct devSup *pdevSup, dset *pdset); - - -#define S_dev_noDevSup (M_devSup| 1) /*SDR_DEVSUP: Device support missing*/ -#define S_dev_noDSET (M_devSup| 3) /*Missing device support entry table*/ -#define S_dev_missingSup (M_devSup| 5) /*Missing device support routine*/ -#define S_dev_badInpType (M_devSup| 7) /*Bad INP link type*/ -#define S_dev_badOutType (M_devSup| 9) /*Bad OUT link type*/ -#define S_dev_badInitRet (M_devSup|11) /*Bad init_rec return value */ -#define S_dev_badBus (M_devSup|13) /*Illegal bus type*/ -#define S_dev_badCard (M_devSup|15) /*Illegal or nonexistant module*/ -#define S_dev_badSignal (M_devSup|17) /*Illegal signal*/ -#define S_dev_NoInit (M_devSup|19) /*No init*/ -#define S_dev_Conflict (M_devSup|21) /*Multiple records accessing same signal*/ -#define S_dev_noDeviceFound (M_devSup|23) /*No device found at specified address*/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/src/ioc/dbStatic/drvSup.h b/src/ioc/dbStatic/drvSup.h deleted file mode 100644 index 5778038e7..000000000 --- a/src/ioc/dbStatic/drvSup.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* drvSup.h Driver Support */ - -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - -#ifndef INCdrvSuph -#define INCdrvSuph 1 - -#include "errMdef.h" - -typedef long (*DRVSUPFUN) (); /* ptr to driver support function*/ - -typedef struct drvet { /* driver entry table */ - long number; /*number of support routines*/ - DRVSUPFUN report; /*print report*/ - DRVSUPFUN init; /*init support*/ - /*other functions are device dependent*/ -}drvet; -#define DRVETNUMBER ( (sizeof(struct drvet) -sizeof(long))/sizeof(DRVSUPFUN) ) - -#define S_drv_noDrvSup (M_drvSup| 1) /*SDR_DRVSUP: Driver support missing*/ -#define S_drv_noDrvet (M_drvSup| 3) /*Missing driver support entry table*/ - -#endif diff --git a/src/ioc/dbStatic/guigroup.h b/src/ioc/dbStatic/guigroup.h deleted file mode 100644 index 4e2f2e1dd..000000000 --- a/src/ioc/dbStatic/guigroup.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - these are used in the pmt (prompt) field of the record support - ascii files. They represent field groupings for dct tools -*/ - -#ifndef __gui_group_h__ -#define __gui_group_h__ - -#error As of Base 3.15.4, the promptgroup implementation has changed. \ - This header file (guigroup.h) is invalid and will be removed shortly. \ - Instead, you should include dbStaticLib.h, parse the DBD, \ - and use dbGetPromptGroupNameFromKey() and dbGetPromptGroupKeyFromName() \ - that have been added to dbStaticLib. \ - More details in the 3.15.4 release notes and the AppDev Guide. - -#endif /*__gui_group_h__*/ diff --git a/src/ioc/dbStatic/link.h b/src/ioc/dbStatic/link.h deleted file mode 100644 index f2b426308..000000000 --- a/src/ioc/dbStatic/link.h +++ /dev/null @@ -1,206 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* link.h */ - -/* - * Original Authors: Bob Dalesio, Marty Kraimer - */ - -#ifndef INC_link_H -#define INC_link_H - -#include "dbDefs.h" -#include "ellLib.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* link types */ -#define CONSTANT 0 -#define PV_LINK 1 -#define VME_IO 2 -#define CAMAC_IO 3 -#define AB_IO 4 -#define GPIB_IO 5 -#define BITBUS_IO 6 -#define MACRO_LINK 7 -#define JSON_LINK 8 -#define PN_LINK 9 -#define DB_LINK 10 -#define CA_LINK 11 -#define INST_IO 12 /* instrument */ -#define BBGPIB_IO 13 /* bitbus -> gpib */ -#define RF_IO 14 -#define VXI_IO 15 -#define LINK_NTYPES 16 -typedef struct maplinkType { - char *strvalue; - int value; -} maplinkType; - -epicsShareExtern maplinkType pamaplinkType[]; - -#define VXIDYNAMIC 0 -#define VXISTATIC 1 - -/* structure of a PV_LINK DB_LINK and a CA_LINK */ -/*Options defined by pvlMask */ -#define pvlOptMsMode 0x3 /*Maximize Severity mode selection*/ -#define pvlOptNMS 0 /*Don't Maximize Severity*/ -#define pvlOptMS 1 /*Maximize Severity always*/ -#define pvlOptMSI 2 /*Maximize Severity if INVALID*/ -#define pvlOptMSS 3 /*Maximize Severity and copy Status*/ -#define pvlOptPP 0x4 /*Process Passive*/ -#define pvlOptCA 0x8 /*Always make it a CA link*/ -#define pvlOptCP 0x10 /*CA + process on monitor*/ -#define pvlOptCPP 0x20 /*CA + process passive record on monitor*/ -#define pvlOptFWD 0x40 /*Generate ca_put for forward link*/ -#define pvlOptInpNative 0x80 /*Input native*/ -#define pvlOptInpString 0x100 /*Input as string*/ -#define pvlOptOutNative 0x200 /*Output native*/ -#define pvlOptOutString 0x400 /*Output as string*/ -#define pvlOptTSELisTime 0x800 /*Field TSEL is getting timeStamp*/ - -/* DBLINK Flag bits */ -#define DBLINK_FLAG_INITIALIZED 1 /* dbInitLink() called */ - -struct macro_link { - char *macroStr; -}; - -struct dbCommon; -typedef long (*LINKCVT)(); - -struct pv_link { - ELLNODE backlinknode; - char *pvname; /* pvname link points to */ - void *pvt; /* CA or DB private */ - LINKCVT getCvt; /* input conversion function */ - short pvlMask; /* Options mask */ - short lastGetdbrType; /* last dbrType for DB or CA get */ -}; - -struct jlink; -struct json_link { - char *string; - struct jlink *jlink; -}; - -/* structure of a VME io channel */ -struct vmeio { - short card; - short signal; - char *parm; -}; - -/* structure of a CAMAC io channel */ -struct camacio { - short b; - short c; - short n; - short a; - short f; - char *parm; -}; - -/* structure of a RF io channel */ -struct rfio { - short branch; - short cryo; - short micro; - short dataset; - short element; - long ext; -}; - -/* structure of a Allen-Bradley io channel */ -struct abio { - short link; - short adapter; - short card; - short signal; - char *parm; -}; - -/* structure of a gpib io channel */ -struct gpibio { - short link; - short addr; /* device address */ - char *parm; -}; - -/* structure of a bitbus io channel */ -struct bitbusio { - unsigned char link; - unsigned char node; - unsigned char port; - unsigned char signal; - char *parm; -}; - -/* structure of a bitbus to gpib io channel */ -struct bbgpibio { - unsigned char link; - unsigned char bbaddr; - unsigned char gpibaddr; - unsigned char pad; - char *parm; -}; - -/* structure of an instrument io link */ -struct instio { - char *string; -}; - -/* structure of a vxi link */ -struct vxiio { - short flag; /* 0 = frame/slot, 1 = SA */ - short frame; - short slot; - short la; /* logical address if flag =1 */ - short signal; - char *parm; -}; - -/* union of possible address structures */ -union value { - char *constantStr; /*constant string*/ - struct macro_link macro_link; /* link containing macro substitution*/ - struct json_link json; /* JSON-encoded link */ - struct pv_link pv_link; /* link to process variable*/ - struct vmeio vmeio; /* vme io point */ - struct camacio camacio; /* camac io point */ - struct rfio rfio; /* CEBAF RF buffer interface */ - struct abio abio; /* allen-bradley io point */ - struct gpibio gpibio; - struct bitbusio bitbusio; - struct instio instio; /* instrument io link */ - struct bbgpibio bbgpibio; /* bitbus to gpib io link */ - struct vxiio vxiio; /* vxi io */ -}; - -struct lset; - -struct link { - struct dbCommon *precord; /* Pointer to record owning link */ - short type; - short flags; - struct lset *lset; - char *text; /* Raw link text */ - union value value; -}; - -typedef struct link DBLINK; - -#ifdef __cplusplus -} -#endif -#endif /* INC_link_H */ diff --git a/src/ioc/dbStatic/recSup.h b/src/ioc/dbStatic/recSup.h deleted file mode 100644 index 2850e6292..000000000 --- a/src/ioc/dbStatic/recSup.h +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* recSup.h - * Record Support - * Author: Marty Kraimer - * Date: 6-1-90 - */ - -#ifndef INCrecSuph -#define INCrecSuph 1 - -#include "errMdef.h" -#include "compilerDependencies.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* RSET definition */ - -/* defined elsewhere */ -struct dbAddr; -struct dbCommon; -struct dbr_enumStrs; -struct dbr_grDouble; -struct dbr_ctrlDouble; -struct dbr_alDouble; - -/* record support entry table */ -struct typed_rset { - long number; /* number of support routines */ - long (*report)(void *precord); - long (*init)(); - long (*init_record)(struct dbCommon *precord, int pass); - long (*process)(struct dbCommon *precord); - long (*special)(struct dbAddr *paddr, int after); - long (*get_value)(void); /* DEPRECATED set to NULL */ - long (*cvt_dbaddr)(struct dbAddr *paddr); - long (*get_array_info)(struct dbAddr *paddr, long *no_elements, long *offset); - long (*put_array_info)(struct dbAddr *paddr, long nNew); - long (*get_units)(struct dbAddr *paddr, char *units); - long (*get_precision)(const struct dbAddr *paddr, long *precision); - long (*get_enum_str)(const struct dbAddr *paddr, char *pbuffer); - long (*get_enum_strs)(const struct dbAddr *paddr, struct dbr_enumStrs *p); - long (*put_enum_str)(const struct dbAddr *paddr, const char *pbuffer); - long (*get_graphic_double)(struct dbAddr *paddr, struct dbr_grDouble *p); - long (*get_control_double)(struct dbAddr *paddr, struct dbr_ctrlDouble *p); - long (*get_alarm_double)(struct dbAddr *paddr, struct dbr_alDouble *p); -}; - -#ifdef USE_TYPED_RSET - -typedef struct typed_rset rset; - -#else - -/* pre-3.16 old untyped RSET definition - DEPRECATED */ - -typedef long (*RECSUPFUN) () EPICS_DEPRECATED; /* ptr to record support function*/ - -struct rset { /* record support entry table */ - long number; /*number of support routines */ - long (*report)(); /*print report */ - long (*init)(); /*init support */ - long (*init_record)(); /*init record */ - long (*process)(); /*process record */ - long (*special)(); /*special processing */ - long (*get_value)(); /*no longer used */ - long (*cvt_dbaddr)(); /*cvt dbAddr */ - long (*get_array_info)(); - long (*put_array_info)(); - long (*get_units)(); - long (*get_precision)(); - long (*get_enum_str)(); /*get string from enum item*/ - long (*get_enum_strs)();/*get all enum strings */ - long (*put_enum_str)(); /*put string from enum item*/ - long (*get_graphic_double)(); - long (*get_control_double)(); - long (*get_alarm_double)(); -} EPICS_DEPRECATED; - -typedef struct rset rset EPICS_DEPRECATED; - -#endif - -#define RSETNUMBER 17 - -#define S_rec_noRSET (M_recSup| 1) /*Missing record support entry table*/ -#define S_rec_noSizeOffset (M_recSup| 2) /*Missing SizeOffset Routine*/ -#define S_rec_outMem (M_recSup| 3) /*Out of Memory*/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /*INCrecSuph*/ diff --git a/src/ioc/dbStatic/special.h b/src/ioc/dbStatic/special.h deleted file mode 100644 index 055287a64..000000000 --- a/src/ioc/dbStatic/special.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* special.h */ - -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - -#ifndef INCspecialh -#define INCspecialh 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/*NOTE Do NOT add aditional definitions with out modifying dbLexRoutines.c */ -/* types 1-99 are global. Record specific must start with 100 */ -#define SPC_NOMOD 1 /*Field must not be modified */ -#define SPC_DBADDR 2 /*db_name_to_addr must call cvt_dbaddr */ -#define SPC_SCAN 3 /*A scan related field is being changed */ -#define SPC_ALARMACK 5 /*Special Alarm Acknowledgement*/ -#define SPC_AS 6 /* Access Security*/ -#define SPC_ATTRIBUTE 7 /* psuedo field, i.e. attribute field*/ -/* useful when record support must be notified of a field changing value*/ -#define SPC_MOD 100 -/* used by all records that support a reset field */ -#define SPC_RESET 101 /*The res field is being modified*/ -/* Specific to conversion (Currently only ai */ -#define SPC_LINCONV 102 /*A linear conversion field is being changed*/ -/* Specific to calculation records */ -#define SPC_CALC 103 /*The CALC field is being changed*/ - - -#define SPC_NTYPES 9 -typedef struct mapspcType{ - char *strvalue; - int value; -}mapspcType; - -#ifndef SPECIAL_GBLSOURCE -extern mapspcType pamapspcType[]; -#else -mapspcType pamapspcType[SPC_NTYPES] = { - {"SPC_NOMOD",SPC_NOMOD}, - {"SPC_DBADDR",SPC_DBADDR}, - {"SPC_SCAN",SPC_SCAN}, - {"SPC_ALARMACK",SPC_ALARMACK}, - {"SPC_AS",SPC_AS}, - {"SPC_MOD",SPC_MOD}, - {"SPC_RESET",SPC_RESET}, - {"SPC_LINCONV",SPC_LINCONV}, - {"SPC_CALC",SPC_CALC} -}; -#endif /*SPECIAL_GBLSOURCE*/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCspecialh*/ diff --git a/src/ioc/dbtemplate/Makefile b/src/ioc/dbtemplate/Makefile deleted file mode 100644 index 2aa5a0c78..000000000 --- a/src/ioc/dbtemplate/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(IOCDIR)/dbtemplate - -PROD_HOST += msi - -msi_SRCS = msi.c -msi_LIBS += Com -HTMLS += msi.html - -INC += dbLoadTemplate.h -INC += dbtoolsIocRegister.h - -dbCore_SRCS += dbLoadTemplate.c -dbCore_SRCS += dbtoolsIocRegister.c - -CLEANS += dbLoadTemplate_lex.c dbLoadTemplate.c - diff --git a/src/ioc/dbtemplate/RULES b/src/ioc/dbtemplate/RULES deleted file mode 100644 index d528be9ec..000000000 --- a/src/ioc/dbtemplate/RULES +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -# dbLoadTemplate_lex.c is included by dbLoadTemplate.c -dbLoadTemplate.c: dbLoadTemplate_lex.c $(IOCDIR)/dbtemplate/dbLoadTemplate.h - diff --git a/src/ioc/dbtemplate/dbLoadTemplate.h b/src/ioc/dbtemplate/dbLoadTemplate.h deleted file mode 100644 index a6ca60617..000000000 --- a/src/ioc/dbtemplate/dbLoadTemplate.h +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dbLoadTemplate.h */ - -#ifndef INCdbLoadTemplateh -#define INCdbLoadTemplateh - -#include "shareLib.h" -epicsShareFunc int dbLoadTemplate( - const char *sub_file, const char *cmd_collect); - -#endif /*INCdbLoadTemplateh*/ diff --git a/src/ioc/dbtemplate/dbLoadTemplate.y b/src/ioc/dbtemplate/dbLoadTemplate.y deleted file mode 100644 index 1a4a47caf..000000000 --- a/src/ioc/dbtemplate/dbLoadTemplate.y +++ /dev/null @@ -1,392 +0,0 @@ -%{ - -/*************************************************************************\ -* Copyright (c) 2006 UChicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include - -#include "osiUnistd.h" -#include "macLib.h" -#include "dbmf.h" - -#include "epicsExport.h" -#include "dbAccess.h" -#include "dbLoadTemplate.h" - -static int line_num; -static int yyerror(char* str); - -static char *sub_collect = NULL; -static char *sub_locals; -static char **vars = NULL; -static char *db_file_name = NULL; -static int var_count, sub_count; - -/* We allocate MAX_VAR_FACTOR chars in the sub_collect string for each - * "variable=value," segment, and will accept at most dbTemplateMaxVars - * template variables. The user can adjust that variable to increase - * the number of variables or the length allocated for the buffer. - */ -#define MAX_VAR_FACTOR 50 - -int dbTemplateMaxVars = 100; -epicsExportAddress(int, dbTemplateMaxVars); - -%} - -%start substitution_file - -%token WORD QUOTE -%token DBFILE -%token PATTERN -%token GLOBAL -%token EQUALS COMMA -%left O_PAREN C_PAREN -%left O_BRACE C_BRACE - -%union -{ - int Int; - char Char; - char *Str; - double Real; -} - -%% - -substitution_file: global_or_template - | substitution_file global_or_template - ; - -global_or_template: global_definitions - | template_substitutions - ; - -global_definitions: GLOBAL O_BRACE C_BRACE - | GLOBAL O_BRACE variable_definitions C_BRACE - { - #ifdef ERROR_STUFF - fprintf(stderr, "global_definitions: %s\n", sub_collect+1); - #endif - sub_locals += strlen(sub_locals); - } - ; - -template_substitutions: template_filename O_BRACE C_BRACE - { - #ifdef ERROR_STUFF - fprintf(stderr, "template_substitutions: %s unused\n", db_file_name); - #endif - dbmfFree(db_file_name); - db_file_name = NULL; - } - | template_filename O_BRACE substitutions C_BRACE - { - #ifdef ERROR_STUFF - fprintf(stderr, "template_substitutions: %s finished\n", db_file_name); - #endif - dbmfFree(db_file_name); - db_file_name = NULL; - } - ; - -template_filename: DBFILE WORD - { - #ifdef ERROR_STUFF - fprintf(stderr, "template_filename: %s\n", $2); - #endif - var_count = 0; - db_file_name = dbmfMalloc(strlen($2)+1); - strcpy(db_file_name, $2); - dbmfFree($2); - } - | DBFILE QUOTE - { - #ifdef ERROR_STUFF - fprintf(stderr, "template_filename: \"%s\"\n", $2); - #endif - var_count = 0; - db_file_name = dbmfMalloc(strlen($2)+1); - strcpy(db_file_name, $2); - dbmfFree($2); - } - ; - -substitutions: pattern_substitutions - | variable_substitutions - ; - -pattern_substitutions: PATTERN O_BRACE C_BRACE - | PATTERN O_BRACE C_BRACE pattern_definitions - | PATTERN O_BRACE pattern_names C_BRACE - | PATTERN O_BRACE pattern_names C_BRACE pattern_definitions - ; - -pattern_names: pattern_name - | pattern_names COMMA - | pattern_names pattern_name - ; - -pattern_name: WORD - { - #ifdef ERROR_STUFF - fprintf(stderr, "pattern_name: [%d] = %s\n", var_count, $1); - #endif - if (var_count >= dbTemplateMaxVars) { - fprintf(stderr, - "More than dbTemplateMaxVars = %d macro variables used\n", - dbTemplateMaxVars); - yyerror(NULL); - } - else { - vars[var_count] = dbmfMalloc(strlen($1)+1); - strcpy(vars[var_count], $1); - var_count++; - dbmfFree($1); - } - } - ; - -pattern_definitions: pattern_definition - | pattern_definitions pattern_definition - ; - -pattern_definition: global_definitions - | O_BRACE C_BRACE - { - #ifdef ERROR_STUFF - fprintf(stderr, "pattern_definition: pattern_values empty\n"); - fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1); - #endif - dbLoadRecords(db_file_name, sub_collect+1); - } - | O_BRACE pattern_values C_BRACE - { - #ifdef ERROR_STUFF - fprintf(stderr, "pattern_definition:\n"); - fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1); - #endif - dbLoadRecords(db_file_name, sub_collect+1); - *sub_locals = '\0'; - sub_count = 0; - } - | WORD O_BRACE pattern_values C_BRACE - { /* DEPRECATED SYNTAX */ - fprintf(stderr, - "dbLoadTemplate: Substitution file uses deprecated syntax.\n" - " the string '%s' on line %d that comes just before the\n" - " '{' character is extraneous and should be removed.\n", - $1, line_num); - #ifdef ERROR_STUFF - fprintf(stderr, "pattern_definition:\n"); - fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1); - #endif - dbLoadRecords(db_file_name, sub_collect+1); - dbmfFree($1); - *sub_locals = '\0'; - sub_count = 0; - } - ; - -pattern_values: pattern_value - | pattern_values COMMA - | pattern_values pattern_value - ; - -pattern_value: QUOTE - { - #ifdef ERROR_STUFF - fprintf(stderr, "pattern_value: [%d] = \"%s\"\n", sub_count, $1); - #endif - if (sub_count < var_count) { - strcat(sub_locals, ","); - strcat(sub_locals, vars[sub_count]); - strcat(sub_locals, "=\""); - strcat(sub_locals, $1); - strcat(sub_locals, "\""); - sub_count++; - } else { - fprintf(stderr, "dbLoadTemplate: Too many values given, line %d.\n", - line_num); - } - dbmfFree($1); - } - | WORD - { - #ifdef ERROR_STUFF - fprintf(stderr, "pattern_value: [%d] = %s\n", sub_count, $1); - #endif - if (sub_count < var_count) { - strcat(sub_locals, ","); - strcat(sub_locals, vars[sub_count]); - strcat(sub_locals, "="); - strcat(sub_locals, $1); - sub_count++; - } else { - fprintf(stderr, "dbLoadTemplate: Too many values given, line %d.\n", - line_num); - } - dbmfFree($1); - } - ; - -variable_substitutions: variable_substitution - | variable_substitutions variable_substitution - ; - -variable_substitution: global_definitions - | O_BRACE C_BRACE - { - #ifdef ERROR_STUFF - fprintf(stderr, "variable_substitution: variable_definitions empty\n"); - fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1); - #endif - dbLoadRecords(db_file_name, sub_collect+1); - } - | O_BRACE variable_definitions C_BRACE - { - #ifdef ERROR_STUFF - fprintf(stderr, "variable_substitution:\n"); - fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1); - #endif - dbLoadRecords(db_file_name, sub_collect+1); - *sub_locals = '\0'; - } - | WORD O_BRACE variable_definitions C_BRACE - { /* DEPRECATED SYNTAX */ - fprintf(stderr, - "dbLoadTemplate: Substitution file uses deprecated syntax.\n" - " the string '%s' on line %d that comes just before the\n" - " '{' character is extraneous and should be removed.\n", - $1, line_num); - #ifdef ERROR_STUFF - fprintf(stderr, "variable_substitution:\n"); - fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1); - #endif - dbLoadRecords(db_file_name, sub_collect+1); - dbmfFree($1); - *sub_locals = '\0'; - } - ; - -variable_definitions: variable_definition - | variable_definitions COMMA - | variable_definitions variable_definition - ; - -variable_definition: WORD EQUALS WORD - { - #ifdef ERROR_STUFF - fprintf(stderr, "variable_definition: %s = %s\n", $1, $3); - #endif - strcat(sub_locals, ","); - strcat(sub_locals, $1); - strcat(sub_locals, "="); - strcat(sub_locals, $3); - dbmfFree($1); dbmfFree($3); - } - | WORD EQUALS QUOTE - { - #ifdef ERROR_STUFF - fprintf(stderr, "variable_definition: %s = \"%s\"\n", $1, $3); - #endif - strcat(sub_locals, ","); - strcat(sub_locals, $1); - strcat(sub_locals, "=\""); - strcat(sub_locals, $3); - strcat(sub_locals, "\""); - dbmfFree($1); dbmfFree($3); - } - ; - -%% - -#include "dbLoadTemplate_lex.c" - -static int yyerror(char* str) -{ - if (str) - fprintf(stderr, "Substitution file error: %s\n", str); - else - fprintf(stderr, "Substitution file error.\n"); - fprintf(stderr, "line %d: '%s'\n", line_num, yytext); - return 0; -} - -static int is_not_inited = 1; - -int dbLoadTemplate(const char *sub_file, const char *cmd_collect) -{ - FILE *fp; - int i; - - line_num = 1; - - if (!sub_file || !*sub_file) { - fprintf(stderr, "must specify variable substitution file\n"); - return -1; - } - - if (dbTemplateMaxVars < 1) - { - fprintf(stderr,"Error: dbTemplateMaxVars = %d, must be +ve\n", - dbTemplateMaxVars); - return -1; - } - - fp = fopen(sub_file, "r"); - if (!fp) { - fprintf(stderr, "dbLoadTemplate: error opening sub file %s\n", sub_file); - return -1; - } - - vars = malloc(dbTemplateMaxVars * sizeof(char*)); - sub_collect = malloc(dbTemplateMaxVars * MAX_VAR_FACTOR); - if (!vars || !sub_collect) { - free(vars); - free(sub_collect); - fclose(fp); - fprintf(stderr, "dbLoadTemplate: Out of memory!\n"); - return -1; - } - strcpy(sub_collect, ","); - - if (cmd_collect && *cmd_collect) { - strcat(sub_collect, cmd_collect); - sub_locals = sub_collect + strlen(sub_collect); - } else { - sub_locals = sub_collect; - *sub_locals = '\0'; - } - var_count = 0; - sub_count = 0; - - if (is_not_inited) { - yyin = fp; - is_not_inited = 0; - } else { - yyrestart(fp); - } - - yyparse(); - - for (i = 0; i < var_count; i++) { - dbmfFree(vars[i]); - } - free(vars); - free(sub_collect); - vars = NULL; - fclose(fp); - if (db_file_name) { - dbmfFree(db_file_name); - db_file_name = NULL; - } - return 0; -} diff --git a/src/ioc/dbtemplate/dbLoadTemplate_lex.l b/src/ioc/dbtemplate/dbLoadTemplate_lex.l deleted file mode 100644 index c6a99a8a1..000000000 --- a/src/ioc/dbtemplate/dbLoadTemplate_lex.l +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -newline "\n" -backslash "\\" -doublequote "\"" -singlequote "'" -comment "#" -whitespace [ \t\r] -escape {backslash}. -dstringchar [^"\n\\] -sstringchar [^'\n\\] -bareword [a-zA-Z0-9_\-+:./\\\[\]<>;] - -%% - -"pattern" { return(PATTERN); } -"file" { return(DBFILE); } -"global" { return(GLOBAL); } - -{doublequote}({dstringchar}|{escape})*{doublequote} | -{singlequote}({sstringchar}|{escape})*{singlequote} { - yylval.Str = dbmfStrdup((char *) yytext+1); - yylval.Str[strlen(yylval.Str)-1] = '\0'; - return(QUOTE); -} - -{bareword}+ { - yylval.Str = dbmfStrdup((char *) yytext); - return(WORD); -} - -"=" { return(EQUALS); } -"," { return(COMMA); } -"{" { return(O_BRACE); } -"}" { return(C_BRACE); } - -{comment}.* ; -{whitespace} ; -{newline} { line_num++; } - -. { - char message[40]; - - sprintf(message, "invalid character '%c'", yytext[0]); - yyerror(message); - - /* Suppress compiler warning messages */ - if (0) yyunput('c',NULL); - if (0) yy_switch_to_buffer(NULL); -} - -%% diff --git a/src/ioc/dbtemplate/dbtoolsIocRegister.c b/src/ioc/dbtemplate/dbtoolsIocRegister.c deleted file mode 100644 index 201a32398..000000000 --- a/src/ioc/dbtemplate/dbtoolsIocRegister.c +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "iocsh.h" - -#define epicsExportSharedSymbols -#include "dbtoolsIocRegister.h" -#include "dbLoadTemplate.h" - - -/* dbLoadTemplate */ -static const iocshArg dbLoadTemplateArg0 = {"filename", iocshArgString}; -static const iocshArg dbLoadTemplateArg1 = {"var=value", iocshArgString}; -static const iocshArg * const dbLoadTemplateArgs[2] = { - &dbLoadTemplateArg0, &dbLoadTemplateArg1 -}; -static const iocshFuncDef dbLoadTemplateFuncDef = - {"dbLoadTemplate", 2, dbLoadTemplateArgs}; -static void dbLoadTemplateCallFunc(const iocshArgBuf *args) -{ - dbLoadTemplate(args[0].sval, args[1].sval); -} - - -void dbtoolsIocRegister(void) -{ - iocshRegister(&dbLoadTemplateFuncDef, dbLoadTemplateCallFunc); -} diff --git a/src/ioc/dbtemplate/dbtoolsIocRegister.h b/src/ioc/dbtemplate/dbtoolsIocRegister.h deleted file mode 100644 index ef35b2dfa..000000000 --- a/src/ioc/dbtemplate/dbtoolsIocRegister.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_dbtoolsIocRegister_H -#define INC_dbtoolsIocRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void dbtoolsIocRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_dbtoolsIocRegister_H */ diff --git a/src/ioc/dbtemplate/msi.c b/src/ioc/dbtemplate/msi.c deleted file mode 100644 index 5a5023163..000000000 --- a/src/ioc/dbtemplate/msi.c +++ /dev/null @@ -1,895 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS Base is distributed subject to a Software License Agreement found -* in the file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* msi - macro substitutions and include */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define MAX_BUFFER_SIZE 4096 -#define MAX_DEPS 1024 - -/* Module to read the template files */ -typedef struct inputData inputData; - -static void inputConstruct(inputData **ppvt); -static void inputDestruct(inputData *pvt); -static void inputAddPath(inputData *pvt, char *pval); -static void inputBegin(inputData *pvt, char *fileName); -static char *inputNextLine(inputData *pvt); -static void inputNewIncludeFile(inputData *pvt, char *name); -static void inputErrPrint(inputData *pvt); - -/* Module to read the substitution file */ -typedef struct subInfo subInfo; - -static void substituteOpen(subInfo **ppvt, char *substitutionName); -static void substituteDestruct(subInfo *pvt); -static int substituteGetNextSet(subInfo *pvt, char **filename); -static int substituteGetGlobalSet(subInfo *pvt); -static char *substituteGetReplacements(subInfo *pvt); -static char *substituteGetGlobalReplacements(subInfo *pvt); - -/* Forward references to local routines */ -static void usageExit(int status); -static void addMacroReplacements(MAC_HANDLE *macPvt, char *pval); -static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *templateName); - -/*Global variables */ -static int opt_V = 0; -static int opt_D = 0; - -static char *outFile = 0; -static int numDeps = 0, depHashes[MAX_DEPS]; - - -int main(int argc,char **argv) -{ - inputData *inputPvt; - MAC_HANDLE *macPvt; - char *pval; - int narg; - char *substitutionName=0; - char *templateName=0; - int i; - int localScope = 1; - - inputConstruct(&inputPvt); - macCreateHandle(&macPvt,0); - while((argc>1) && (argv[1][0] == '-')) { - narg = (strlen(argv[1])==2) ? 2 : 1; - pval = (narg==1) ? (argv[1]+2) : argv[2]; - if(strncmp(argv[1],"-I",2)==0) { - inputAddPath(inputPvt,pval); - } else if (strcmp(argv[1], "-D") == 0) { - opt_D = 1; - narg = 1; /* no argument for this option */ - } else if(strncmp(argv[1],"-o",2)==0) { - outFile = epicsStrDup(pval); - } else if(strncmp(argv[1],"-M",2)==0) { - addMacroReplacements(macPvt,pval); - } else if(strncmp(argv[1],"-S",2)==0) { - substitutionName = epicsStrDup(pval); - } else if (strcmp(argv[1], "-V") == 0) { - opt_V = 1; - narg = 1; /* no argument for this option */ - } else if (strcmp(argv[1], "-g") == 0) { - localScope = 0; - narg = 1; /* no argument for this option */ - } else if (strcmp(argv[1], "-h") == 0) { - usageExit(0); - } else { - fprintf(stderr, "msi: Bad argument \"%s\"\n", argv[1]); - usageExit(1); - } - argc -= narg; - for(i=1; i2) { - fprintf(stderr,"msi: Too many arguments\n"); - usageExit(1); - } - if (opt_D) { - if (!outFile) { - fprintf(stderr, "msi: Option -D requires -o for Makefile target\n"); - exit(1); - } - printf("%s:", outFile); - } - else if (outFile && freopen(outFile, "w", stdout) == NULL) { - fprintf(stderr, "msi: Can't open %s for writing: %s\n", - outFile, strerror(errno)); - exit(1); - } - if(argc==2) { - templateName = epicsStrDup(argv[1]); - } - if(!substitutionName) { - makeSubstitutions(inputPvt,macPvt,templateName); - } else { - subInfo *substitutePvt; - char *filename = 0; - int isGlobal, isFile; - - substituteOpen(&substitutePvt,substitutionName); - do { - if ((isGlobal = substituteGetGlobalSet(substitutePvt))) { - pval = substituteGetGlobalReplacements(substitutePvt); - if(pval) { - addMacroReplacements(macPvt,pval); - } - } else if ((isFile = substituteGetNextSet(substitutePvt,&filename))) { - if(templateName) filename = templateName; - if(!filename) { - fprintf(stderr,"msi: No template file\n"); - usageExit(1); - } - while((pval = substituteGetReplacements(substitutePvt))){ - if (localScope) macPushScope(macPvt); - addMacroReplacements(macPvt,pval); - makeSubstitutions(inputPvt,macPvt,filename); - if (localScope) macPopScope(macPvt); - } - } - } while (isGlobal || isFile); - substituteDestruct(substitutePvt); - } - errlogFlush(); - macDeleteHandle(macPvt); - inputDestruct(inputPvt); - if (opt_D) { - printf("\n"); - } - free(templateName); - free(substitutionName); - return opt_V & 2; -} - -void usageExit(int status) -{ - fprintf(stderr, - "Usage: msi [options] [template]\n" - " stdin is used if neither template nor substitution file is given\n" - " options:\n" - " -h Print this help message\n" - " -D Output file dependencies, not substitutions\n" - " -V Undefined macros generate an error\n" - " -g All macros have global scope\n" - " -o Send output to \n" - " -I

Add to include file search path\n" - " -M Add to (global) macro definitions\n" - " ( takes the form VAR=VALUE,...)\n" - " -S Expand the substitutions in FILE\n"); - exit(status); -} - -static void addMacroReplacements(MAC_HANDLE *macPvt,char *pval) -{ - char **pairs; - long status; - - status = macParseDefns(macPvt,pval,&pairs); - if(status==-1) { - fprintf(stderr,"msi: Error from macParseDefns\n"); - usageExit(1); - } - if(status) { - status = macInstallMacros(macPvt,pairs); - if(!status) { - fprintf(stderr,"Error from macInstallMacros\n"); - usageExit(1); - } - free(pairs); - } -} - -typedef enum {cmdInclude,cmdSubstitute} cmdType; -static const char *cmdNames[] = {"include","substitute"}; - -static void makeSubstitutions(inputData *inputPvt, MAC_HANDLE *macPvt, char *templateName) -{ - char *input; - static char buffer[MAX_BUFFER_SIZE]; - int n; - - inputBegin(inputPvt,templateName); - while((input = inputNextLine(inputPvt))) { - int expand=1; - char *p; - char *command = 0; - - p = input; - /*skip whitespace at beginning of line*/ - while(*p && (isspace((int) *p))) ++p; - /*Look for i or s */ - if(*p && (*p=='i' || *p=='s')) command = p; - if(command) { - char *pstart; - char *pend; - char *copy; - int cmdind=-1; - int i; - - for(i=0; i< NELEMENTS(cmdNames); i++) { - if(strstr(command,cmdNames[i])) { - cmdind = i; - } - } - if(cmdind<0) goto endif; - p = command + strlen(cmdNames[cmdind]); - /*skip whitespace after command*/ - while(*p && (isspace((int) *p))) ++p; - /*Next character must be quote*/ - if((*p==0) || (*p!='"')) goto endif; - pstart = ++p; - /*Look for end quote*/ - while(*p && (*p!='"')) { - /*allow escape for imbeded quote*/ - if((*p=='\\') && *(p+1)=='"') { - p += 2; continue; - } else { - if(*p=='"') break; - } - ++p; - } - pend = p; - if(*p==0) goto endif; - /*skip quote and any trailing blanks*/ - while(*++p==' ') ; - if(*p != '\n' && *p !=0) goto endif; - copy = calloc(pend-pstart+1,sizeof(char)); - strncpy(copy,pstart,pend-pstart); - switch(cmdind) { - case cmdInclude: - inputNewIncludeFile(inputPvt,copy); - break; - case cmdSubstitute: - addMacroReplacements(macPvt,copy); - break; - default: - fprintf(stderr,"msi: Logic error in makeSubstitutions\n"); - inputErrPrint(inputPvt); - exit(1); - } - free(copy); - expand = 0; - } -endif: - if (expand && !opt_D) { - n = macExpandString(macPvt,input,buffer,MAX_BUFFER_SIZE-1); - fputs(buffer,stdout); - if (opt_V == 1 && n < 0) { - fprintf(stderr,"msi: Error - undefined macros present\n"); - opt_V++; - } - } - } -} - -typedef struct inputFile{ - ELLNODE node; - char *filename; - FILE *fp; - int lineNum; -}inputFile; - -typedef struct pathNode { - ELLNODE node; - char *directory; -} pathNode; - -struct inputData { - ELLLIST inputFileList; - ELLLIST pathList; - char inputBuffer[MAX_BUFFER_SIZE]; -}; - -static void inputOpenFile(inputData *pinputData,char *filename); -static void inputCloseFile(inputData *pinputData); -static void inputCloseAllFiles(inputData *pinputData); - -static void inputConstruct(inputData **ppvt) -{ - inputData *pinputData; - - pinputData = calloc(1,sizeof(inputData)); - ellInit(&pinputData->inputFileList); - ellInit(&pinputData->pathList); - *ppvt = pinputData; -} - -static void inputDestruct(inputData *pinputData) -{ - pathNode *ppathNode; - - inputCloseAllFiles(pinputData); - while((ppathNode = (pathNode *)ellFirst(&pinputData->pathList))) { - ellDelete(&pinputData->pathList,&ppathNode->node); - free(ppathNode->directory); - free(ppathNode); - } - free(pinputData); -} - -static void inputAddPath(inputData *pinputData, char *path) -{ - ELLLIST *ppathList = &pinputData->pathList; - pathNode *ppathNode; - const char *pcolon; - const char *pdir; - size_t len; - int emptyName; - const char sep = *OSI_PATH_LIST_SEPARATOR; - - pdir = path; - /*an empty name at beginning, middle, or end means current directory*/ - while(pdir && *pdir) { - emptyName = ((*pdir == sep) ? 1 : 0); - if(emptyName) ++pdir; - ppathNode = (pathNode *)calloc(1,sizeof(pathNode)); - ellAdd(ppathList,&ppathNode->node); - if(!emptyName) { - pcolon = strchr(pdir,sep); - len = (pcolon ? (pcolon - pdir) : strlen(pdir)); - if(len>0) { - ppathNode->directory = (char *)calloc(len+1,sizeof(char)); - strncpy(ppathNode->directory,pdir,len); - pdir = pcolon; - /*unless at end skip past first colon*/ - if(pdir && *(pdir+1)!=0) ++pdir; - } else { /*must have been trailing : */ - emptyName=1; - } - } - if(emptyName) { - ppathNode->directory = (char *)calloc(2,sizeof(char)); - strcpy(ppathNode->directory,"."); - } - } - return; -} - -static void inputBegin(inputData *pinputData, char *fileName) -{ - inputCloseAllFiles(pinputData); - inputOpenFile(pinputData,fileName); -} - -static char *inputNextLine(inputData *pinputData) -{ - inputFile *pinputFile; - char *pline; - - while((pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList))) { - pline = fgets(pinputData->inputBuffer,MAX_BUFFER_SIZE,pinputFile->fp); - if(pline) { - ++pinputFile->lineNum; - return(pline); - } - inputCloseFile(pinputData); - } - return(0); -} - -static void inputNewIncludeFile(inputData *pinputData, char *name) -{ - inputOpenFile(pinputData,name); -} - -static void inputErrPrint(inputData *pinputData) -{ - inputFile *pinputFile; - - fprintf(stderr,"input: '%s' at ",pinputData->inputBuffer); - pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList); - while(pinputFile) { - fprintf(stderr,"line %d of ",pinputFile->lineNum); - if(pinputFile->filename) { - fprintf(stderr," file %s\n",pinputFile->filename); - } else { - fprintf(stderr,"stdin:\n"); - } - pinputFile = (inputFile *)ellNext(&pinputFile->node); - if(pinputFile) { - fprintf(stderr," included from "); - } else { - fprintf(stderr,"\n"); - } - } - fprintf(stderr,"\n"); -} - -static void inputOpenFile(inputData *pinputData,char *filename) -{ - ELLLIST *ppathList = &pinputData->pathList; - pathNode *ppathNode = 0; - inputFile *pinputFile; - char *fullname = 0; - FILE *fp = 0; - - if(!filename) { - fp = stdin; - } else if((ellCount(ppathList)==0) || strchr(filename,'/')){ - fp = fopen(filename,"r"); - } else { - ppathNode = (pathNode *)ellFirst(ppathList); - while(ppathNode) { - fullname = calloc(strlen(filename)+strlen(ppathNode->directory) +2, - sizeof(char)); - strcpy(fullname,ppathNode->directory); - strcat(fullname,"/"); - strcat(fullname,filename); - fp = fopen(fullname,"r"); - if(fp) break; - free(fullname); - ppathNode = (pathNode *)ellNext(&ppathNode->node); - } - } - if(!fp) { - fprintf(stderr,"msi: Can't open file '%s'\n",filename); - inputErrPrint(pinputData); - exit(1); - } - pinputFile = calloc(1,sizeof(inputFile)); - if(ppathNode) { - pinputFile->filename = fullname; - } else if(filename) { - pinputFile->filename = epicsStrDup(filename); - } else { - pinputFile->filename = epicsStrDup("stdin"); - } - - if (opt_D) { - int hash = epicsStrHash(pinputFile->filename, 12345); - int i = 0; - int match = 0; - - while (i < numDeps) { - if (hash == depHashes[i++]) { - match = 1; - break; - } - } - if (!match) { - const char *wrap = numDeps ? " \\\n" : ""; - - printf("%s %s", wrap, pinputFile->filename); - if (numDeps < MAX_DEPS) { - depHashes[numDeps++] = hash; - } - else { - fprintf(stderr, "msi: More than %d dependencies!\n", MAX_DEPS); - depHashes[0] = hash; - } - } - } - - pinputFile->fp = fp; - ellInsert(&pinputData->inputFileList,0,&pinputFile->node); -} - -static void inputCloseFile(inputData *pinputData) -{ - inputFile *pinputFile; - - pinputFile = (inputFile *)ellFirst(&pinputData->inputFileList); - if(!pinputFile) return; - ellDelete(&pinputData->inputFileList,&pinputFile->node); - if(fclose(pinputFile->fp)) - fprintf(stderr,"msi: Can't close input file '%s'\n",pinputFile->filename); - free(pinputFile->filename); - free(pinputFile); -} - -static void inputCloseAllFiles(inputData *pinputData) -{ - inputFile *pinputFile; - - while((pinputFile=(inputFile *)ellFirst(&pinputData->inputFileList))){ - inputCloseFile(pinputData); - } -} - -/*start of code that handles substitution file*/ -typedef enum { - tokenLBrace,tokenRBrace,tokenSeparater,tokenString,tokenEOF -}tokenType; - -typedef struct subFile { - char *substitutionName; - FILE *fp; - int lineNum; - char inputBuffer[MAX_BUFFER_SIZE]; - char *pnextChar; - tokenType token; - char string[MAX_BUFFER_SIZE]; -} subFile; - -typedef struct patternNode { - ELLNODE node; - char *var; -} patternNode; - -struct subInfo { - subFile *psubFile; - int isFile; - char *filename; - int isPattern; - ELLLIST patternList; - size_t size; - size_t curLength; - char *macroReplacements; -}; - -static char *subGetNextLine(subFile *psubFile); -static tokenType subGetNextToken(subFile *psubFile); -static void subFileErrPrint(subFile *psubFile,char * message); -static void freeSubFile(subInfo *psubInfo); -static void freePattern(subInfo *psubInfo); -static void catMacroReplacements(subInfo *psubInfo,const char *value); - -void freeSubFile(subInfo *psubInfo) -{ - subFile *psubFile = psubInfo->psubFile; - if(psubFile->fp) { - if(fclose(psubFile->fp)) - fprintf(stderr,"msi: Can't close substitution file\n"); - } - free(psubFile); - free(psubInfo->filename); - psubInfo->psubFile = 0; -} - -void freePattern(subInfo *psubInfo) -{ - patternNode *ppatternNode; - while((ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList))) { - ellDelete(&psubInfo->patternList,&ppatternNode->node); - free(ppatternNode->var); - free(ppatternNode); - } - psubInfo->isPattern = 0; -} - -static void substituteDestruct(subInfo *psubInfo) -{ - freeSubFile(psubInfo); - freePattern(psubInfo); - free(psubInfo); - return; -} - -static void substituteOpen(subInfo **ppvt,char *substitutionName) -{ - subInfo *psubInfo; - subFile *psubFile; - FILE *fp; - - psubInfo = calloc(1,sizeof(subInfo)); - *ppvt = psubInfo; - psubFile = calloc(1,sizeof(subFile)); - psubInfo->psubFile = psubFile; - ellInit(&psubInfo->patternList); - fp = fopen(substitutionName,"r"); - if(!fp) { - fprintf(stderr,"msi: Can't open file '%s'\n",substitutionName); - exit(1); - } - psubFile->substitutionName = substitutionName; - psubFile->fp = fp; - psubFile->lineNum = 1; - psubFile->inputBuffer[0] = 0; - psubFile->pnextChar = &psubFile->inputBuffer[0]; - subGetNextToken(psubFile); - return; -} - -static int substituteGetGlobalSet(subInfo *psubInfo) -{ - subFile *psubFile = psubInfo->psubFile; - - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenString && strcmp(psubFile->string,"global")==0) { - subGetNextToken(psubFile); - return(1); - } - return(0); -} - -static int substituteGetNextSet(subInfo *psubInfo,char **filename) -{ - subFile *psubFile = psubInfo->psubFile; - patternNode *ppatternNode; - - *filename = 0; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenEOF) return(0); - if(psubFile->token==tokenString && strcmp(psubFile->string,"file")==0) { - psubInfo->isFile = 1; - if(subGetNextToken(psubFile)!=tokenString) { - subFileErrPrint(psubFile,"Parse error, expecting filename"); - exit(1); - } - freePattern(psubInfo); - free(psubInfo->filename); - if(psubFile->string[0]=='"'&&psubFile->string[strlen(psubFile->string)-1]=='"') { - psubFile->string[strlen(psubFile->string)-1]='\0'; - psubInfo->filename = macEnvExpand(psubFile->string+1); - } - else { - psubInfo->filename = macEnvExpand(psubFile->string); - } - while(subGetNextToken(psubFile)==tokenSeparater); - if(psubFile->token!=tokenLBrace) { - subFileErrPrint(psubFile,"Parse error, expecting {"); - exit(1); - } - subGetNextToken(psubFile); - } - *filename = psubInfo->filename; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenLBrace) return(1); - if(psubFile->token==tokenRBrace) return(1); - if(psubFile->token!=tokenString - || strcmp(psubFile->string,"pattern")!=0) { - subFileErrPrint(psubFile,"Parse error, expecting pattern"); - exit(1); - } - freePattern(psubInfo); - psubInfo->isPattern = 1; - while(subGetNextToken(psubFile)==tokenSeparater); - if(psubFile->token!=tokenLBrace) { - subFileErrPrint(psubFile,"Parse error, expecting {"); - exit(1); - } - while(1) { - while(subGetNextToken(psubFile)==tokenSeparater); - if(psubFile->token!=tokenString) break; - ppatternNode = calloc(1,sizeof(patternNode)); - ellAdd(&psubInfo->patternList,&ppatternNode->node); - ppatternNode->var = epicsStrDup(psubFile->string); - } - if(psubFile->token!=tokenRBrace) { - subFileErrPrint(psubFile,"Parse error, expecting }"); - exit(1); - } - subGetNextToken(psubFile); - return(1); -} - -static char *substituteGetGlobalReplacements(subInfo *psubInfo) -{ - subFile *psubFile = psubInfo->psubFile; - - if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0; - psubInfo->curLength = 0; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenRBrace && psubInfo->isFile) { - psubInfo->isFile = 0; - free(psubInfo->filename); - psubInfo->filename = 0; - freePattern(psubInfo); - subGetNextToken(psubFile); - return(0); - } - if(psubFile->token==tokenEOF) return(0); - if(psubFile->token!=tokenLBrace) return(0); - while(1) { - switch(subGetNextToken(psubFile)) { - case tokenRBrace: - subGetNextToken(psubFile); - if (!psubInfo->macroReplacements) { - catMacroReplacements(psubInfo,""); - } - return(psubInfo->macroReplacements); - case tokenSeparater: - catMacroReplacements(psubInfo,","); - break; - case tokenString: - catMacroReplacements(psubInfo,psubFile->string); - break; - default: - subFileErrPrint(psubFile,"Parse error, illegal token"); - exit(1); - } - } -} - -static char *substituteGetReplacements(subInfo *psubInfo) -{ - subFile *psubFile = psubInfo->psubFile; - patternNode *ppatternNode; - - if(psubInfo->macroReplacements) psubInfo->macroReplacements[0] = 0; - psubInfo->curLength = 0; - while(psubFile->token==tokenSeparater) subGetNextToken(psubFile); - if(psubFile->token==tokenRBrace && psubInfo->isFile) { - psubInfo->isFile = 0; - free(psubInfo->filename); - psubInfo->filename = 0; - freePattern(psubInfo); - subGetNextToken(psubFile); - return(0); - } - if(psubFile->token==tokenEOF) return(0); - if(psubFile->token!=tokenLBrace) return(0); - if(psubInfo->isPattern) { - int gotFirstPattern = 0; - - while(subGetNextToken(psubFile)==tokenSeparater); - ppatternNode = (patternNode *)ellFirst(&psubInfo->patternList); - while(1) { - if(psubFile->token==tokenRBrace) { - subGetNextToken(psubFile); - return(psubInfo->macroReplacements); - } - if(psubFile->token!=tokenString) { - subFileErrPrint(psubFile,"Parse error, illegal token"); - exit(-1); - } - if(gotFirstPattern) catMacroReplacements(psubInfo,","); - gotFirstPattern = 1; - if(ppatternNode) { - catMacroReplacements(psubInfo,ppatternNode->var); - catMacroReplacements(psubInfo,"="); - catMacroReplacements(psubInfo,psubFile->string); - ppatternNode = (patternNode *)ellNext(&ppatternNode->node); - } else { - subFileErrPrint(psubFile,"Warning, too many values given"); - } - while(subGetNextToken(psubFile)==tokenSeparater); - } - } else while(1) { - switch(subGetNextToken(psubFile)) { - case tokenRBrace: - subGetNextToken(psubFile); - if (!psubInfo->macroReplacements) { - catMacroReplacements(psubInfo,""); - } - return(psubInfo->macroReplacements); - case tokenSeparater: - catMacroReplacements(psubInfo,","); - break; - case tokenString: - catMacroReplacements(psubInfo,psubFile->string); - break; - default: - subFileErrPrint(psubFile,"Parse error, illegal token"); - exit(1); - } - } -} - -static char *subGetNextLine(subFile *psubFile) -{ - char *pline; - - do { - pline = fgets(psubFile->inputBuffer,MAX_BUFFER_SIZE,psubFile->fp); - ++psubFile->lineNum; - } while(pline && psubFile->inputBuffer[0]=='#'); - if(!pline) { - psubFile->token = tokenEOF; - psubFile->inputBuffer[0] = 0; - psubFile->pnextChar = 0; - return(0); - } - psubFile->pnextChar = &psubFile->inputBuffer[0]; - return(&psubFile->inputBuffer[0]); -} - -static void subFileErrPrint(subFile *psubFile,char * message) -{ - fprintf(stderr,"msi: %s\n",message); - fprintf(stderr," in substitution file '%s' at line %d:\n %s", - psubFile->substitutionName, - psubFile->lineNum,psubFile->inputBuffer); -} - - -static tokenType subGetNextToken(subFile *psubFile) -{ - char *p; - char *pto; - - p = psubFile->pnextChar; - if(!p) { psubFile->token = tokenEOF; return(tokenEOF);} - if(*p==0 || *p=='\n' || *p=='#') { - p = subGetNextLine(psubFile); - if(!p) { psubFile->token = tokenEOF; return(tokenEOF);} - else { psubFile->token = tokenSeparater; return(tokenSeparater);} - } - while(isspace((int) *p)) p++; - if(*p=='{') { - psubFile->token = tokenLBrace; - psubFile->pnextChar = ++p; - return(tokenLBrace); - } - if(*p=='}') { - psubFile->token = tokenRBrace; - psubFile->pnextChar = ++p; - return(tokenRBrace); - } - if(*p==0 || isspace((int) *p) || *p==',') { - while (isspace((int) *p) || *p==',') p++; - psubFile->token = tokenSeparater; - psubFile->pnextChar = p; - return(tokenSeparater); - } - /*now handle quoted strings*/ - if(*p=='"') { - pto = &psubFile->string[0]; - *pto++ = *p++; - while(*p!='"') { - if(*p==0 || *p=='\n') { - subFileErrPrint(psubFile,"Strings must be on single line\n"); - exit(1); - } - /*allow escape for imbeded quote*/ - if((*p=='\\') && *(p+1)=='"') { - *pto++ = *p++; - *pto++ = *p++; - continue; - } - *pto++ = *p++; - } - *pto++ = *p++; - psubFile->pnextChar = p; - *pto = 0; - psubFile->token = tokenString; - return(tokenString); - } - /*Now take anything up to next non String token and not space*/ - pto = &psubFile->string[0]; - while(!isspace((int) *p) && (strspn(p,"\",{}")==0)) *pto++ = *p++; - *pto = 0; - psubFile->pnextChar = p; - psubFile->token = tokenString; - return(tokenString); -} - -static void catMacroReplacements(subInfo *psubInfo,const char *value) -{ - size_t len = strlen(value); - - if(psubInfo->size <= (psubInfo->curLength + len)) { - size_t newsize = psubInfo->size + MAX_BUFFER_SIZE; - char *newbuf; - - if(newsize <= psubInfo->curLength + len) - newsize = psubInfo->curLength + len + 1; - newbuf = calloc(1,newsize); - if(!newbuf) { - fprintf(stderr,"calloc failed for size %lu\n", - (unsigned long) newsize); - exit(1); - } - if(psubInfo->macroReplacements) { - memcpy(newbuf,psubInfo->macroReplacements,psubInfo->curLength); - free(psubInfo->macroReplacements); - } - psubInfo->size = newsize; - psubInfo->macroReplacements = newbuf; - } - strcat(psubInfo->macroReplacements,value); - psubInfo->curLength += len; -} diff --git a/src/ioc/dbtemplate/msi.html b/src/ioc/dbtemplate/msi.html deleted file mode 100644 index ff4341ead..000000000 --- a/src/ioc/dbtemplate/msi.html +++ /dev/null @@ -1,445 +0,0 @@ - - - - - - - - - -

msi: Macro Substitution and Include Tool

- -

Introduction

- -

msi is a general purpose macro substitution/include tool. It accepts as input -an ascii template file. It looks for lines containing two reserved command -names: include and substitute. It also looks for and performs -substitutions on macros of the form $(var) and ${var}. It uses the macLib -routines from EPICS Base to perform the substitutions, so it also accepts the -default value and value definition syntax that macLib implements.

- -

msi also allows substitutions to be specified via a separate substitution -file. This substitution file allows the same format as the substitution files -accepted by the EPICS IOC's dbLoadTemplate command.

- -

Command Syntax:

- -
msi -V -g -D -ooutfile -Idir -Msubs -Ssubfile template
- -

All parameters are optional. The -o, -I, -M, and -S switches may be -separated from their associated value string by spaces if desired. Output will -be written to stdout unless the -o option is given.

- -

Switches have the following meanings:

- -
-
-V
-
Verbose warnings; if this parameter is specified then any undefined - macro discovered in the template file which does not have an associated - default value is considered an error. An error message is generated, and - when msi terminates it will do so with an exit status of 2.
- -
-g
-
When this flag is given all macros defined in a substitution file will - have global scope and thus their values will persist until a new value is - given for this macro. This flag is provided for backwards compatibility as - this was the behavior of previous versions of msi, but it does not follow - common scoping rules and is discouraged.
- -
-D
-
Output dependency information suitable for including by a Makefile to - stdout instead of performing the macro substitutions. The -o option - must be given to specify the target name for the dependency rules. Other - options should be given exactly as will be used in the macro substitution - process.
- -
-o file
-
Output will be written to the specifed file rather than to the standard - output.
- -
-I dir
-
This parameter, which may be repeated or contain a colon-separated (or - semi-colon separated on Windows) list of directory paths, specifies a search - path for include commands. For example: - -
-
msi -I /home/mrk/examples:. -I.. template
-
- - specifies that all named files should be searched for in the following - locations in the order given: - -
    -
  1. /home/mrk/examples
  2. -
  3. . (the current directory)
  4. -
  5. .. (the parent of the current directory)
  6. -
-
- -
-M substitutions
-
This parameter specifies macro values for the template instance. - Multiple macro values can be specified in one substitution parameter, or in - multiple -M parameters. For example: - -
-
msi -M "a=aval,b=bval" -Mc=cval template
-
- - specifies that in the template file each occurrence of: - -
-
$(a) or ${a} is replaced by aval
-
$(b) or ${b} is replaced by bval
-
$(c) or ${c} is replaced by cval
-
-
- -
-S subfile
-
The substitution file. See below for format.
- -
template
-
The input file. If no file is specified then input is taken from - stdin, i.e. msi can be used as a filter. See below for a description of - commands that can be embedded in the template file.
-
- -

It is not possible to display usage by just typing msi since -executing the command with no arguments is a valid command. To show usage -specify an illegal switch, e.g.

- -
-
msi -help
-
- -

Exit Status

- -
-
0
Success. -
1
Can't open/create file, or other I/O error. -
2
Undefined macros encountered with the -V option specified. -
- -

Template File Format

- -

This file contains the text to be read and written to the output after macro -substitution is performed. If no file is given then input is read from stdin. -Variable instances to be substituted by macro values are expressed in the -template using the syntax $(name) or -${name}. The template can also provide default values -to be used when a macro has not been given a value, using the syntax -$(name=default) or -${name=default}.

- -

For example, using the command

- -
-
msi -M name=Marty template
-
- -

where the file template contains

- -
-
My name is $(name)
-My age is $(age=none of your business)
-
- -

results in this output:

- -
-
My name is Marty
-My age is none of your business
-
- -

Macro variables and their default values can be expressed in terms of other -macros if necessary, to almost any level of complexity. Recursive definitions -will generate warning messages on stderr and result in undefined output.

- -

The template file is read and processed one line at a time, where the -maximum length of a line before and/or after macro expansion is 1023 characters -— longer input or output lines will cause msi to fail. Within the context -of a single line, macro expansion does not occur when the variable instance -appears inside a single-quoted string, or where the dollar sign $ is -preceded by a back-slash character \, but as with the standard Unix -shells, variables inside double quoted strings are expanded properly.

- -

However neither back-slash characters nor quotes of either variety are -removed when generating the output file, so depending on what is being output -the single quote behaviour may not be useful and may even be a hinderance. It -cannot be disabled in the current version of msi.

- -

Template file commands

- -

In addition to the regular text and variable instances described above, the -template file may also contain commands which allow the insertion of other -template files and the ability to set macro values inside the template file -itself. These commands are:

- -
-
include "file"
-substitute "var=value,var=value,..."
-
- -

Lines containing commands must be in one of these forms:

- -
    -
  • include "filename"
  • -
  • substitute "name1=value1, name2=value2, ..."
  • -
- -

White space is allowed before and after the command verb, and after the -quoted string. If embedded quotes are needed, the backslash character -\ can be used as an escape character. For example

- -
-
substitute "a=\"val\""
-
- -

specifies that (unless a is subsequently redefined) wherever a -$(a) macro appears in the template below this point, the text -"val" (including the double quote characters) will appear in the -output instead.

- -

If a line does match either syntax above it is just passed to macLib for -processing without any notification. Thus the input line:

- -
-
include "myfile" #include file
-
- -

would just be passed to macLib, i.e. it would not be considered an -include command.

- -

As an example of these commands, let the Unix command be:

- -
-
msi template
-
- -

and file includeFile contain:

- -
-
first name is ${first}
-family name is ${family}
-
- -

and template is

- -
-
substitute "first=Marty,family=Kraimer"
-include "includeFile"
-substitute "first=Irma,family=Kraimer"
-include "includeFile"
-
- -

then the following is written to the output.

- -
-
first name is Marty
-family name is Kraimer
-first name is Irma
-family name is Kraimer
-
- -

Note that the IOC's dbLoadTemplate command does not support the -substitute syntax in template files, although the include -syntax is supported.

- -

Substitution File Format

- -

The optional substitution file has three formats: regular, pattern, and -dbTemplate format. We will discuss each separately.

- -

Regular format

- -
-
global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
-{var1=set1_val1, var2=set1_val2, ...}
-{var2=set2_val2, var1=set2_val1, ...}
-global {gbl_var1=gbl_val3, gbl_var2=gbl_val4, ...}
-{var1=set3_val1, var2=set3_val2, ...}
-{var2=set4_val2, var1=set4_val1, ...}
-
- -

The template file is output with macro substitutions performed once for each -set of braces containing macro replacement values.

- -

Pattern format

- -
-
global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
-pattern {var1, var2, ...}
-{set1_val1, set1_val2, ...}
-{set2_val1, set2_val2, ...}
-pattern {var2, var1, ...}
-global {gbl_var1=gbl_val3, gbl_var2=gbl_val4, ...}
-{set3_val2, set3_val1, ...}
-{set4_val2, set4_val2, ...}
-
- -

This produces the same result as the regular format example above.

- -

dbLoadTemplate Format

- -

This format is an extension of the format accepted by the EPICS IOC command -dbLoadTemplate, and allows templates to be expanded on the host rather -by using dbLoadTemplate at IOC boot time.

- -
-
global {gbl_var1=gbl_val1, gbl_var2=gbl_val2, ...}
-file templatefile {
-    pattern format or regular format
-}
-file "${WHERE}/template2" {
-    pattern format or regular format
-}
-
- -

For the dbTemplate format, the template filename does not have to be given -on the command line, and is usually specified in the substitutions file -instead. If a template filename is given on the command line it will override -the filenames listed in the substitutions files.

- -

Syntax for all formats

- -

A comment line may appear anywhere in a substitution file, and will be -ignored. A comment line is any line beginning with the character #, -which must be the very first character on the line.

- -

Global definitions may supplement or override the macro values supplied on -the command-line using the -M switch, and set default values that will -survive for the remainder of the file unless another global definition of the -same macro changes it.

- -

For definitions within braces given in any of the file formats, a separator -must be given between items. A separator is either a comma, or one or more of -the standard white space characters (space, formfeed, newline, carriage return, -tab or vertical tab).

- -

Each item within braces can be an alphanumeric token, or a double-quoted -string. A back-slash character \ can be used to escape a quote -character needed inside a quoted string. These three sets of substitutions are -all equivalent:

- -
-
{a=aa b=bb c="\"cc\""}
-{b="bb",a=aa,c="\"cc\""}
-{
-    c="\"cc\""
-    b=bb
-    a="aa"
-}
-
- -

Within a substitutions file, the file name may appear inside double quotation -marks; these are required if the name contains certain characters or environment -variable macros of the form ${ENV_VAR} or $(ENV_VAR), which will be expanded -before the file is opened.

- -

Regular substitution example

- -

Let the command be:

- -
-
msi -S substitute template
-
- -

The file template contains

- -
-
first name is ${first}
-family name is ${family}
-
- -

and the file substitute is

- -
-
global {family=Kraimer}
-{first=Marty}
-{first=Irma}
-
- -

The following is the output produced:

- -
-
first name is Marty
-family name is Kraimer
-first name is Irma
-family name is Kraimer
-
- -

Pattern substitution example

- -

Let the command be:

- -
-
msi -S pattern template
-
- -

The file pattern contains

- -
-
pattern {first,last}
-{Marty,Kraimer}
-{Irma,Kraimer}
-
- -

and template is the same as the previous example:

- -
-
first name is ${first}
-family name is ${family}
-
- -

This is the output:

- -
-
first name is Marty
-family name is Kraimer
-first name is Irma
-family name is Kraimer
-
- -

dbTemplate example

-Let the command be - -
-
msi -S xxx.substitutions
-
- -xxx.substitutions is - -
-
file template {
-pattern {first,last}
-{Marty,Kraimer}
-{Irma,Kraimer}
-pattern {last,first}
-{Smith,Bill}
-{Smith,Mary}
-}
-file template {
-{first=Marty,last=Kraimer}
-{first=Irma,last=Kraimer}
-}
-
-template is the same as in the previous example.. - -

The following is written to the output

- -
-
first name is Marty
-family name is Kraimer
-first name is Irma
-family name is Kraimer
-first name is Bill
-last name is Smith
-first name is Mary
-last name is Smith
-first name is Marty
-family name is Kraimer
-first name is Irma
-family name is Kraimer
-
- - - diff --git a/src/ioc/dbtemplate/test/Makefile b/src/ioc/dbtemplate/test/Makefile deleted file mode 100644 index 30e748983..000000000 --- a/src/ioc/dbtemplate/test/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -TESTPROD_HOST_DEFAULT = dbltExpand -TESTPROD_HOST_WIN32 = -nil- -dbltExpand_SRCS += dbltExpand.c -dbltExpand_LIBS += dbCore Com - -TESTS += msi - -TESTSCRIPTS_HOST += $(TESTS:%=%.t) - -TARGETS_HOST += msi-copy$(EXE) -TARGETS += $(TARGETS_$(BUILD_CLASS)) - -include $(TOP)/configure/RULES - -msi-copy$(EXE): $(INSTALL_BIN)/msi$(EXE) - @$(RM) $@ - $(CP) $< $@ diff --git a/src/ioc/dbtemplate/test/dbltExpand.c b/src/ioc/dbtemplate/test/dbltExpand.c deleted file mode 100644 index 4fda7e30e..000000000 --- a/src/ioc/dbtemplate/test/dbltExpand.c +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS Base is distributed subject to a Software License Agreement found -* in the file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* This is a simple version of msi for testing the dbLoadTemplate() code. - * - * It calls dbLoadTemplate() to parse the substitution file, but replaces - * dbLoadRecords() with its own version that reads the template file, - * expands any macros in the text and prints the result to stdout. - * - * This technique won't work on Windows, dbLoadRecords() has to be - * epicsShare... decorated and loaded from a shared library. - */ - -#include -#include -#include -#include - -#include "macLib.h" -#include "dbLoadTemplate.h" - - -#define BUFFER_SIZE 0x10000 - -static char *input_buffer, *output_buffer; - -int dbLoadRecords(const char *file, const char *macros) -{ - MAC_HANDLE *macHandle = NULL; - char **macPairs; - FILE *fp; - size_t input_len; - - if (macCreateHandle(&macHandle, NULL)) { - fprintf(stderr, "macCreateHandle failed\n"); - exit(1); - } - - macSuppressWarning(macHandle, 1); - macParseDefns(macHandle, macros, &macPairs); - if (!macPairs) { - macDeleteHandle(macHandle); - macHandle = NULL; - } else { - macInstallMacros(macHandle, macPairs); - free(macPairs); - } - - fp = fopen(file, "r"); - if (!fp) { - fprintf(stderr, "fopen('%s') failed: %s\n", file, strerror(errno)); - exit(1); - } - - input_len = fread(input_buffer, 1, BUFFER_SIZE, fp); - if (!feof(fp)) { - fprintf(stderr, "input file > 64K!\n"); - fclose(fp); - exit(1); - } - input_buffer[input_len] = 0; - - if (fclose(fp)) { - fprintf(stderr, "fclose('%s') failed: %s\n", file, strerror(errno)); - exit(1); - } - - macExpandString(macHandle, input_buffer, output_buffer, BUFFER_SIZE-1); - printf("%s", output_buffer); - - if (macHandle) macDeleteHandle(macHandle); - - return 0; -} - -int main(int argc, char **argv) -{ - input_buffer = malloc(BUFFER_SIZE); - output_buffer = malloc(BUFFER_SIZE); - - if (!input_buffer || !output_buffer) { - fprintf(stderr, "malloc(%d) failed\n", BUFFER_SIZE); - exit(1); - } - - if (argc != 2) { - fprintf(stderr, "Usage: %s file.sub\n", argv[0]); - exit(1); - } - - dbLoadTemplate(argv[1], NULL); - - free(output_buffer); - free(input_buffer); - return 0; -} diff --git a/src/ioc/dbtemplate/test/msi.plt b/src/ioc/dbtemplate/test/msi.plt deleted file mode 100644 index 230a2c18b..000000000 --- a/src/ioc/dbtemplate/test/msi.plt +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/perl -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# Script to run tests on the msi program - -use strict; -use Test; - -BEGIN {plan tests => 9} - -# Check include/substitute command model -ok(msi('-I .. ../t1-template.txt'), slurp('../t1-result.txt')); - -# Substitution file, dbLoadTemplate format -ok(msi('-I.. -S ../t2-substitution.txt'), slurp('../t2-result.txt')); - -# Macro scoping -ok(msi('-I. -I.. -S ../t3-substitution.txt'), slurp('../t3-result.txt')); - -# Global scope (backwards compatibility check) -ok(msi('-g -I.. -S ../t4-substitution.txt'), slurp('../t4-result.txt')); - -# Substitution file, regular format -ok(msi('-S ../t5-substitute.txt ../t5-template.txt'), slurp('../t5-result.txt')); - -# Substitution file, pattern format -ok(msi('-S../t6-substitute.txt ../t6-template.txt'), slurp('../t6-result.txt')); - -# Output option -o -my $out = 't7-output.txt'; -unlink $out; -msi("-I.. -o $out ../t1-template.txt"); -ok(slurp($out), slurp('../t1-result.txt')); - -# Dependency generation, include/substitute model -ok(msi('-I.. -D -o t8.txt ../t1-template.txt'), slurp('../t8-result.txt')); - -# Dependency generation, dbLoadTemplate format -ok(msi('-I.. -D -ot9.txt -S ../t2-substitution.txt'), slurp('../t9-result.txt')); - - -# Test support routines - -sub slurp { - my ($file) = @_; - open my $in, '<', $file - or die "Can't open file $file: $!\n"; - my $contents = do { local $/; <$in> }; - return $contents; -} - -sub msi { - my ($args) = @_; - my $exe = ($^O eq 'MSWin32') || ($^O eq 'cygwin') ? '.exe' : ''; - my $msi = "./msi-copy$exe"; - my $result; - if ($args =~ m/-o / && $args !~ m/-D/) { - # An empty result is expected - $result = `$msi $args`; - } - else { - # Try up to 5 times, sometimes msi fails on Windows - my $count = 5; - do { - $result = `$msi $args`; - print "# result of '$msi $args' empty, retrying\n" - if $result eq ''; - } while ($result eq '') && (--$count > 0); - } - return $result; -} diff --git a/src/ioc/dbtemplate/test/t1-include.txt b/src/ioc/dbtemplate/test/t1-include.txt deleted file mode 100644 index 9793c73bd..000000000 --- a/src/ioc/dbtemplate/test/t1-include.txt +++ /dev/null @@ -1,5 +0,0 @@ -This is t1-include.txt $(include-file-again=) - a = $(a=default value used when a is undefined) - b = $(b=default value used when b is undefined) -substitute "include-file-again=again" -End of t1-include.txt diff --git a/src/ioc/dbtemplate/test/t1-result.txt b/src/ioc/dbtemplate/test/t1-result.txt deleted file mode 100644 index fcd065585..000000000 --- a/src/ioc/dbtemplate/test/t1-result.txt +++ /dev/null @@ -1,21 +0,0 @@ -This is t1-template.txt - -With $(a,undefined) & $(b,undefined): -This is t1-include.txt - a = default value used when a is undefined - b = default value used when b is undefined -End of t1-include.txt - -On defining a=aaa & b=bbb: -This is t1-include.txt again - a = aaa - b = bbb -End of t1-include.txt - -On setting a="aa": -This is t1-include.txt again - a = "aa" - b = bbb -End of t1-include.txt - -End of t1-template.txt diff --git a/src/ioc/dbtemplate/test/t1-template.txt b/src/ioc/dbtemplate/test/t1-template.txt deleted file mode 100644 index 9ef49e8fe..000000000 --- a/src/ioc/dbtemplate/test/t1-template.txt +++ /dev/null @@ -1,14 +0,0 @@ -This is t1-template.txt - -With $(a) & ${b}: -include "t1-include.txt" - -substitute "a=aaa,b=bbb" -On defining a=$(a) & b=${b}: -include "t1-include.txt" - -substitute "a=\"aa\"" -On setting a=$(a): -include "t1-include.txt" - -End of t1-template.txt diff --git a/src/ioc/dbtemplate/test/t2-result.txt b/src/ioc/dbtemplate/test/t2-result.txt deleted file mode 100644 index 5239e6a05..000000000 --- a/src/ioc/dbtemplate/test/t2-result.txt +++ /dev/null @@ -1,6 +0,0 @@ -a = va1-a b = def-b c = def-c d = $(d,undefined) -a = va2-a b = va2-b c = def-c d = $(d,undefined) -a = va3-a b = va3-b c = va3-c d = $(d,undefined) -a = va4-a b = va4-b c = def-c d = $(d,undefined) -a = va5-a b = def-b c = def-c d = $(d,undefined) -a = pt3-a b = pt3-b c = pt3-c d = $(d,undefined) diff --git a/src/ioc/dbtemplate/test/t2-substitution.txt b/src/ioc/dbtemplate/test/t2-substitution.txt deleted file mode 100644 index a3f3d6874..000000000 --- a/src/ioc/dbtemplate/test/t2-substitution.txt +++ /dev/null @@ -1,11 +0,0 @@ -file t2-template.txt { - {a=va1-a} - {a=va2-a, b=va2-b} - {a=va3-a, b=va3-b, c=va3-c} - {a=va4-a, b=va4-b} - {a=va5-a} -} -file t2-template.txt { - pattern {a, b, c} - {pt3-a, pt3-b, pt3-c} -} diff --git a/src/ioc/dbtemplate/test/t2-template.txt b/src/ioc/dbtemplate/test/t2-template.txt deleted file mode 100644 index c4ac7b427..000000000 --- a/src/ioc/dbtemplate/test/t2-template.txt +++ /dev/null @@ -1 +0,0 @@ -a = $(a=def-a) b = $(b=def-b) c = $(c=def-c) d = $(d,undef) diff --git a/src/ioc/dbtemplate/test/t3-result.txt b/src/ioc/dbtemplate/test/t3-result.txt deleted file mode 100644 index c6961507f..000000000 --- a/src/ioc/dbtemplate/test/t3-result.txt +++ /dev/null @@ -1,28 +0,0 @@ -a = gb1-a b = gb1-b c = def-c d = $(d,undefined) -a = va1-a b = gb1-b c = def-c d = $(d,undefined) -a = va2-a b = va2-b c = def-c d = $(d,undefined) -a = va3-a b = va3-b c = va3-c d = $(d,undefined) -a = va4-a b = va4-b c = def-c d = $(d,undefined) -a = va5-a b = gb1-b c = def-c d = $(d,undefined) -a = gb1-a b = gb1-b c = def-c d = $(d,undefined) -a = gb2-a b = gb2-b c = def-c d = $(d,undefined) -a = va1-a b = gb2-b c = def-c d = $(d,undefined) -a = va2-a b = va2-b c = def-c d = $(d,undefined) -a = va3-a b = va3-b c = va3-c d = $(d,undefined) -a = va4-a b = va4-b c = def-c d = $(d,undefined) -a = va5-a b = gb2-b c = def-c d = $(d,undefined) -a = gb2-a b = gb2-b c = def-c d = $(d,undefined) -a = gb3-a b = gb3-b c = def-c d = $(d,undefined) -a = pt1-a b = gb3-b c = def-c d = $(d,undefined) -a = pt2-a b = pt2-b c = def-c d = $(d,undefined) -a = pt3-a b = pt3-b c = pt3-c d = $(d,undefined) -a = pt4-a b = pt4-b c = def-c d = $(d,undefined) -a = pt5-a b = gb3-b c = def-c d = $(d,undefined) -a = gb3-a b = gb3-b c = def-c d = $(d,undefined) -a = gb4-a b = gb4-b c = def-c d = $(d,undefined) -a = pt1-a b = gb4-b c = def-c d = $(d,undefined) -a = pt2-a b = pt2-b c = def-c d = $(d,undefined) -a = pt3-a b = pt3-b c = pt3-c d = $(d,undefined) -a = pt4-a b = pt4-b c = def-c d = $(d,undefined) -a = pt5-a b = gb4-b c = def-c d = $(d,undefined) -a = gb4-a b = gb4-b c = def-c d = $(d,undefined) diff --git a/src/ioc/dbtemplate/test/t3-substitution.txt b/src/ioc/dbtemplate/test/t3-substitution.txt deleted file mode 100644 index 30b0741d3..000000000 --- a/src/ioc/dbtemplate/test/t3-substitution.txt +++ /dev/null @@ -1,37 +0,0 @@ -global {a=gb1-a, b=gb1-b} -file t3-template.txt { - {} - {a=va1-a} - {a=va2-a, b=va2-b} - {a=va3-a, b=va3-b, c=va3-c} - {a=va4-a, b=va4-b} - {a=va5-a} - {} - global {a=gb2-a, b=gb2-b} - {} - {a=va1-a} - {a=va2-a, b=va2-b} - {a=va3-a, b=va3-b, c=va3-c} - {a=va4-a, b=va4-b} - {a=va5-a} - {} -} -global {b=gb3-b, a=gb3-a} -file t3-template.txt { - pattern {a, b, c} - {} - {pt1-a} - {pt2-a, pt2-b} - {pt3-a, pt3-b, pt3-c} - {pt4-a, pt4-b} - {pt5-a} - {} - global {b=gb4-b, a=gb4-a} - {} - {pt1-a} - {pt2-a, pt2-b} - {pt3-a, pt3-b, pt3-c} - {pt4-a, pt4-b} - {pt5-a} - {} -} diff --git a/src/ioc/dbtemplate/test/t3-template.txt b/src/ioc/dbtemplate/test/t3-template.txt deleted file mode 100644 index c4ac7b427..000000000 --- a/src/ioc/dbtemplate/test/t3-template.txt +++ /dev/null @@ -1 +0,0 @@ -a = $(a=def-a) b = $(b=def-b) c = $(c=def-c) d = $(d,undef) diff --git a/src/ioc/dbtemplate/test/t4-result.txt b/src/ioc/dbtemplate/test/t4-result.txt deleted file mode 100644 index 664872013..000000000 --- a/src/ioc/dbtemplate/test/t4-result.txt +++ /dev/null @@ -1,6 +0,0 @@ -a = va1-a b = def-b c = def-c d = $(d,undefined) -a = va2-a b = va2-b c = def-c d = $(d,undefined) -a = va3-a b = va3-b c = va3-c d = $(d,undefined) -a = va4-a b = va4-b c = va3-c d = $(d,undefined) -a = va5-a b = va4-b c = va3-c d = $(d,undefined) -a = pt3-a b = pt3-b c = pt3-c d = $(d,undefined) diff --git a/src/ioc/dbtemplate/test/t4-substitution.txt b/src/ioc/dbtemplate/test/t4-substitution.txt deleted file mode 100644 index a3f3d6874..000000000 --- a/src/ioc/dbtemplate/test/t4-substitution.txt +++ /dev/null @@ -1,11 +0,0 @@ -file t2-template.txt { - {a=va1-a} - {a=va2-a, b=va2-b} - {a=va3-a, b=va3-b, c=va3-c} - {a=va4-a, b=va4-b} - {a=va5-a} -} -file t2-template.txt { - pattern {a, b, c} - {pt3-a, pt3-b, pt3-c} -} diff --git a/src/ioc/dbtemplate/test/t5-result.txt b/src/ioc/dbtemplate/test/t5-result.txt deleted file mode 100644 index 19a57c87c..000000000 --- a/src/ioc/dbtemplate/test/t5-result.txt +++ /dev/null @@ -1,20 +0,0 @@ -# comment line -a = 111 -b = 222 -c = xx -d = $(d,undefined) -# comment line -a = aaa -b = bbb -c = ccc -d = $(d,undefined) -# comment line -a = AA -b = BB -c = xx -d = $(d,undefined) -# comment line -a = aaa -b = bbb -c = yy -d = $(d,undefined) diff --git a/src/ioc/dbtemplate/test/t5-substitute.txt b/src/ioc/dbtemplate/test/t5-substitute.txt deleted file mode 100644 index 6b6ca985d..000000000 --- a/src/ioc/dbtemplate/test/t5-substitute.txt +++ /dev/null @@ -1,9 +0,0 @@ -global {c=xx} -{a=111,b="222"} -{ a = aaa , b=bbb , c = ccc} -{a=AA,b='BB'} -global { c = yy } -{ - a= aaa - b= bbb -} diff --git a/src/ioc/dbtemplate/test/t5-template.txt b/src/ioc/dbtemplate/test/t5-template.txt deleted file mode 100644 index 561b52a0a..000000000 --- a/src/ioc/dbtemplate/test/t5-template.txt +++ /dev/null @@ -1,5 +0,0 @@ -# comment line -a = $(a) -b = $(b) -c = $(c) -d = $(d) diff --git a/src/ioc/dbtemplate/test/t6-result.txt b/src/ioc/dbtemplate/test/t6-result.txt deleted file mode 100644 index 19a57c87c..000000000 --- a/src/ioc/dbtemplate/test/t6-result.txt +++ /dev/null @@ -1,20 +0,0 @@ -# comment line -a = 111 -b = 222 -c = xx -d = $(d,undefined) -# comment line -a = aaa -b = bbb -c = ccc -d = $(d,undefined) -# comment line -a = AA -b = BB -c = xx -d = $(d,undefined) -# comment line -a = aaa -b = bbb -c = yy -d = $(d,undefined) diff --git a/src/ioc/dbtemplate/test/t6-substitute.txt b/src/ioc/dbtemplate/test/t6-substitute.txt deleted file mode 100644 index 7d80824fd..000000000 --- a/src/ioc/dbtemplate/test/t6-substitute.txt +++ /dev/null @@ -1,13 +0,0 @@ -global {c=xx} -pattern {b,a} -{"222",111} -pattern {a b c} -{ aaa , bbb , ccc} -pattern { a , b } -{AA,'BB'} -global { c = yy } -pattern { a , b } -{ - aaa - bbb -} diff --git a/src/ioc/dbtemplate/test/t6-template.txt b/src/ioc/dbtemplate/test/t6-template.txt deleted file mode 100644 index 561b52a0a..000000000 --- a/src/ioc/dbtemplate/test/t6-template.txt +++ /dev/null @@ -1,5 +0,0 @@ -# comment line -a = $(a) -b = $(b) -c = $(c) -d = $(d) diff --git a/src/ioc/dbtemplate/test/t8-result.txt b/src/ioc/dbtemplate/test/t8-result.txt deleted file mode 100644 index 478c00614..000000000 --- a/src/ioc/dbtemplate/test/t8-result.txt +++ /dev/null @@ -1,2 +0,0 @@ -t8.txt: ../t1-template.txt \ - ../t1-include.txt diff --git a/src/ioc/dbtemplate/test/t9-result.txt b/src/ioc/dbtemplate/test/t9-result.txt deleted file mode 100644 index 9f122bbcf..000000000 --- a/src/ioc/dbtemplate/test/t9-result.txt +++ /dev/null @@ -1 +0,0 @@ -t9.txt: ../t2-template.txt diff --git a/src/ioc/misc/Makefile b/src/ioc/misc/Makefile deleted file mode 100644 index e97efe15a..000000000 --- a/src/ioc/misc/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(IOCDIR)/misc - -DBD += system.dbd -DBD += dlload.dbd -DBD += dbCore.dbd - -INC += epicsRelease.h -INC += iocInit.h -INC += miscIocRegister.h -INC += iocshRegisterCommon.h - -dbCore_SRCS += epicsRelease.c -dbCore_SRCS += iocInit.c -dbCore_SRCS += miscIocRegister.c -dbCore_SRCS += dlload.c -dbCore_SRCS += iocshRegisterCommon.c - diff --git a/src/ioc/misc/dbCore.dbd b/src/ioc/misc/dbCore.dbd deleted file mode 100644 index 7349994f7..000000000 --- a/src/ioc/misc/dbCore.dbd +++ /dev/null @@ -1,25 +0,0 @@ -# dbCore.dbd -# -# This file provides iocsh access to variables that control some lesser-used -# and debugging features of the IOC database code. - -# show epicsAtExit callbacks as they are run -variable(atExitDebug,int) - -# Access security subroutines -variable(asCaDebug,int) - -# Static database access variables -variable(dbRecordsOnceOnly,int) -variable(dbRecordsAbcSorted,int) -variable(dbBptNotMonotonic,int) -variable(dbQuietMacroWarnings,int) -variable(dbConvertStrict,int) - -# dbLoadTemplate settings -variable(dbTemplateMaxVars,int) -# Default number of parallel callback threads -variable(callbackParallelThreadsDefault,int) - -# Real-time operation -variable(dbThreadRealtimeLock,int) diff --git a/src/ioc/misc/dlload.c b/src/ioc/misc/dlload.c deleted file mode 100644 index 5b0591d5f..000000000 --- a/src/ioc/misc/dlload.c +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "epicsFindSymbol.h" -#include "iocsh.h" -#include "epicsExport.h" - -static const iocshArg dlloadArg0 = { "path/library.so", iocshArgString}; -static const iocshArg * const dlloadArgs[] = {&dlloadArg0}; -static const iocshFuncDef dlloadFuncDef = {"dlload", 1, dlloadArgs}; -static void dlloadCallFunc(const iocshArgBuf *args) -{ - if (!epicsLoadLibrary(args[0].sval)) { - printf("epicsLoadLibrary failed: %s\n", epicsLoadError()); - } -} - -static void dlloadRegistar(void) { - iocshRegister(&dlloadFuncDef, dlloadCallFunc); -} -epicsExportRegistrar(dlloadRegistar); diff --git a/src/ioc/misc/dlload.dbd b/src/ioc/misc/dlload.dbd deleted file mode 100644 index 740ebbbba..000000000 --- a/src/ioc/misc/dlload.dbd +++ /dev/null @@ -1,3 +0,0 @@ -# Including this DBD file adds the 'dlload' command to the IOC shell. - -registrar(dlloadRegistar) diff --git a/src/ioc/misc/epicsRelease.c b/src/ioc/misc/epicsRelease.c deleted file mode 100644 index 7ee89fcda..000000000 --- a/src/ioc/misc/epicsRelease.c +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "compilerDependencies.h" -#include "epicsStdio.h" -#include "epicsVersion.h" - -#define epicsExportSharedSymbols -#include "epicsRelease.h" - -static const char id[] EPICS_UNUSED = - "@(#) " EPICS_VERSION_STRING ", Misc. Utilities Library" __DATE__; - -epicsShareFunc int coreRelease(void) -{ - printf ( "############################################################################\n" ); - printf ( "## %s\n", epicsReleaseVersion ); - printf ( "## %s\n", "EPICS Base built " __DATE__ ); - printf ( "############################################################################\n" ); - return 0; -} diff --git a/src/ioc/misc/epicsRelease.h b/src/ioc/misc/epicsRelease.h deleted file mode 100644 index 298a1403b..000000000 --- a/src/ioc/misc/epicsRelease.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsRelease.h */ - -#ifndef INCepicsReleaseh -#define INCepicsReleaseh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" -epicsShareFunc int coreRelease(void); - -#ifdef __cplusplus -} -#endif - -#endif /*INCepicsReleaseh*/ - diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c deleted file mode 100644 index 98f7dae11..000000000 --- a/src/ioc/misc/iocInit.c +++ /dev/null @@ -1,732 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 Helmholtz-Zentrum Berlin -* für Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Original Author: Marty Kraimer - * Date: 06-01-91 - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include "dbBase.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "envDefs.h" -#include "epicsExit.h" -#include "epicsGeneralTime.h" -#include "epicsPrint.h" -#include "epicsSignal.h" -#include "epicsThread.h" -#include "errMdef.h" -#include "iocsh.h" -#include "taskwd.h" - -#include "caeventmask.h" - -#include "epicsExport.h" /* defines epicsExportSharedSymbols */ -#include "alarm.h" -#include "asDbLib.h" -#include "callback.h" -#include "dbAccess.h" -#include "db_access_routines.h" -#include "dbAddr.h" -#include "dbBase.h" -#include "dbBkpt.h" -#include "dbCa.h" -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbFldTypes.h" -#include "dbLock.h" -#include "dbNotify.h" -#include "dbScan.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "devSup.h" -#include "drvSup.h" -#include "epicsRelease.h" -#include "initHooks.h" -#include "iocInit.h" -#include "link.h" -#include "menuConvert.h" -#include "menuPini.h" -#include "recGbl.h" -#include "recSup.h" -#include "registryDeviceSupport.h" -#include "registryDriverSupport.h" -#include "registryJLinks.h" -#include "registryRecordType.h" -#include "rsrv.h" - -static enum { - iocVirgin, iocBuilding, iocBuilt, iocRunning, iocPaused, iocStopped -} iocState = iocVirgin; -static enum { - buildRSRV, buildIsolated -} iocBuildMode; - -/* define forward references*/ -static int checkDatabase(dbBase *pdbbase); -static void checkGeneralTime(void); -static void initDrvSup(void); -static void initRecSup(void); -static void initDevSup(void); -static void finishDevSup(void); -static void initDatabase(void); -static void initialProcess(void); -static void exitDatabase(void *dummy); - -/* - * Iterate through all record instances (but not aliases), - * calling a function for each one. - */ -typedef void (*recIterFunc)(dbRecordType *rtyp, dbCommon *prec, void *user); - -static void iterateRecords(recIterFunc func, void *user); - -int dbThreadRealtimeLock = 1; -epicsExportAddress(int, dbThreadRealtimeLock); - -/* - * Initialize EPICS on the IOC. - */ -int iocInit(void) -{ - return iocBuild() || iocRun(); -} - -static int iocBuild_1(void) -{ - if (iocState != iocVirgin && iocState != iocStopped) { - errlogPrintf("iocBuild: IOC can only be initialized from uninitialized or stopped state\n"); - return -1; - } - errlogInit(0); - initHookAnnounce(initHookAtIocBuild); - - if (!epicsThreadIsOkToBlock()) { - epicsThreadSetOkToBlock(1); - } - - errlogPrintf("Starting iocInit\n"); - if (checkDatabase(pdbbase)) { - errlogPrintf("iocBuild: Aborting, bad database definition (DBD)!\n"); - return -1; - } - epicsSignalInstallSigHupIgnore(); - initHookAnnounce(initHookAtBeginning); - - coreRelease(); - iocState = iocBuilding; - - checkGeneralTime(); - taskwdInit(); - callbackInit(); - initHookAnnounce(initHookAfterCallbackInit); - - return 0; -} - -static void prepareLinks(dbRecordType *rtyp, dbCommon *prec, void *junk) -{ - dbInitRecordLinks(rtyp, prec); -} - -static int iocBuild_2(void) -{ - initHookAnnounce(initHookAfterCaLinkInit); - - initDrvSup(); - initHookAnnounce(initHookAfterInitDrvSup); - - initRecSup(); - initHookAnnounce(initHookAfterInitRecSup); - - initDevSup(); - initHookAnnounce(initHookAfterInitDevSup); /* used by autosave pass 0 */ - - iterateRecords(prepareLinks, NULL); - - dbLockInitRecords(pdbbase); - initDatabase(); - dbBkptInit(); - initHookAnnounce(initHookAfterInitDatabase); /* used by autosave pass 1 */ - - finishDevSup(); - initHookAnnounce(initHookAfterFinishDevSup); - - scanInit(); - if (asInit()) { - errlogPrintf("iocBuild: asInit Failed.\n"); - return -1; - } - dbProcessNotifyInit(); - epicsThreadSleep(.5); - initHookAnnounce(initHookAfterScanInit); - - initialProcess(); - initHookAnnounce(initHookAfterInitialProcess); - return 0; -} - -static int iocBuild_3(void) -{ - initHookAnnounce(initHookAfterCaServerInit); - - iocState = iocBuilt; - initHookAnnounce(initHookAfterIocBuilt); - return 0; -} - -int iocBuild(void) -{ - int status; - - status = iocBuild_1(); - if (status) return status; - - dbCaLinkInit(); - - status = iocBuild_2(); - if (status) return status; - - /* Start CA server threads */ - rsrv_init(); - - status = iocBuild_3(); - - if (dbThreadRealtimeLock) - epicsThreadRealtimeLock(); - - if (!status) iocBuildMode = buildRSRV; - return status; -} - -int iocBuildIsolated(void) -{ - int status; - - status = iocBuild_1(); - if (status) return status; - - dbCaLinkInitIsolated(); - - status = iocBuild_2(); - if (status) return status; - - status = iocBuild_3(); - if (!status) iocBuildMode = buildIsolated; - return status; -} - -int iocRun(void) -{ - if (iocState != iocPaused && iocState != iocBuilt) { - errlogPrintf("iocRun: IOC not paused\n"); - return -1; - } - initHookAnnounce(initHookAtIocRun); - - /* Enable scan tasks and some driver support functions. */ - scanRun(); - dbCaRun(); - initHookAnnounce(initHookAfterDatabaseRunning); - if (iocState == iocBuilt) - initHookAnnounce(initHookAfterInterruptAccept); - - rsrv_run(); - initHookAnnounce(initHookAfterCaServerRunning); - if (iocState == iocBuilt) - initHookAnnounce(initHookAtEnd); - - errlogPrintf("iocRun: %s\n", iocState == iocBuilt ? - "All initialization complete" : - "IOC restarted"); - iocState = iocRunning; - initHookAnnounce(initHookAfterIocRunning); - return 0; -} - -int iocPause(void) -{ - if (iocState != iocRunning) { - errlogPrintf("iocPause: IOC not running\n"); - return -1; - } - initHookAnnounce(initHookAtIocPause); - - rsrv_pause(); - initHookAnnounce(initHookAfterCaServerPaused); - - dbCaPause(); - scanPause(); - initHookAnnounce(initHookAfterDatabasePaused); - - iocState = iocPaused; - errlogPrintf("iocPause: IOC suspended\n"); - initHookAnnounce(initHookAfterIocPaused); - return 0; -} - -/* - * Database sanity checks - * - * This is not an attempt to sanity-check the whole .dbd file, only - * two menus normally get modified by users: menuConvert and menuScan. - * - * The menuConvert checks were added to flag problems with IOCs - * converted from 3.13.x, where the SLOPE choice didn't exist. - * - * The menuScan checks make sure the user didn't fiddle too much - * when creating new periodic scan choices. - */ - -static int checkDatabase(dbBase *pdbbase) -{ - const dbMenu *pMenu; - - if (!pdbbase) { - errlogPrintf("checkDatabase: No database definitions loaded.\n"); - return -1; - } - - pMenu = dbFindMenu(pdbbase, "menuConvert"); - if (!pMenu) { - errlogPrintf("checkDatabase: menuConvert not defined.\n"); - return -1; - } - if (pMenu->nChoice <= menuConvertLINEAR) { - errlogPrintf("checkDatabase: menuConvert has too few choices.\n"); - return -1; - } - if (strcmp(pMenu->papChoiceName[menuConvertNO_CONVERSION], - "menuConvertNO_CONVERSION")) { - errlogPrintf("checkDatabase: menuConvertNO_CONVERSION doesn't match.\n"); - return -1; - } - if (strcmp(pMenu->papChoiceName[menuConvertSLOPE], "menuConvertSLOPE")) { - errlogPrintf("checkDatabase: menuConvertSLOPE doesn't match.\n"); - return -1; - } - if (strcmp(pMenu->papChoiceName[menuConvertLINEAR], "menuConvertLINEAR")) { - errlogPrintf("checkDatabase: menuConvertLINEAR doesn't match.\n"); - return -1; - } - - pMenu = dbFindMenu(pdbbase, "menuScan"); - if (!pMenu) { - errlogPrintf("checkDatabase: menuScan not defined.\n"); - return -1; - } - if (pMenu->nChoice <= menuScanI_O_Intr) { - errlogPrintf("checkDatabase: menuScan has too few choices.\n"); - return -1; - } - if (strcmp(pMenu->papChoiceName[menuScanPassive], - "menuScanPassive")) { - errlogPrintf("checkDatabase: menuScanPassive doesn't match.\n"); - return -1; - } - if (strcmp(pMenu->papChoiceName[menuScanEvent], - "menuScanEvent")) { - errlogPrintf("checkDatabase: menuScanEvent doesn't match.\n"); - return -1; - } - if (strcmp(pMenu->papChoiceName[menuScanI_O_Intr], - "menuScanI_O_Intr")) { - errlogPrintf("checkDatabase: menuScanI_O_Intr doesn't match.\n"); - return -1; - } - if (pMenu->nChoice <= SCAN_1ST_PERIODIC) { - errlogPrintf("checkDatabase: menuScan has no periodic choices.\n"); - return -1; - } - - return 0; -} - -static void checkGeneralTime(void) -{ - epicsTimeStamp ts; - - epicsTimeGetCurrent(&ts); - if (ts.secPastEpoch < 2*24*60*60) { - static const char * const tsfmt = "%Y-%m-%d %H:%M:%S.%09f"; - char buff[40]; - - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - errlogPrintf("iocInit: Time provider has not yet synchronized.\n"); - } - - epicsTimeGetEvent(&ts, 1); /* Prime gtPvt.lastEventProvider for ISRs */ -} - - -static void initDrvSup(void) /* Locate all driver support entry tables */ -{ - drvSup *pdrvSup; - - for (pdrvSup = (drvSup *)ellFirst(&pdbbase->drvList); pdrvSup; - pdrvSup = (drvSup *)ellNext(&pdrvSup->node)) { - struct drvet *pdrvet = registryDriverSupportFind(pdrvSup->name); - - if (!pdrvet) { - errlogPrintf("iocInit: driver %s not found\n", pdrvSup->name); - continue; - } - pdrvSup->pdrvet = pdrvet; - - if (pdrvet->init) - pdrvet->init(); - } -} - -static void initRecSup(void) -{ - dbRecordType *pdbRecordType; - - for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; - pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - recordTypeLocation *precordTypeLocation = - registryRecordTypeFind(pdbRecordType->name); - rset *prset; - - if (!precordTypeLocation) { - errlogPrintf("iocInit record support for %s not found\n", - pdbRecordType->name); - continue; - } - prset = precordTypeLocation->prset; - pdbRecordType->prset = prset; - if (prset->init) { - prset->init(); - } - } -} - -static void initDevSup(void) -{ - dbRecordType *pdbRecordType; - - for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; - pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - devSup *pdevSup; - - for (pdevSup = (devSup *)ellFirst(&pdbRecordType->devList); - pdevSup; - pdevSup = (devSup *)ellNext(&pdevSup->node)) { - struct dset *pdset = registryDeviceSupportFind(pdevSup->name); - - if (!pdset) { - errlogPrintf("device support %s not found\n",pdevSup->name); - continue; - } - dbInitDevSup(pdevSup, pdset); /* Calls pdset->init(0) */ - } - } -} - -static void finishDevSup(void) -{ - dbRecordType *pdbRecordType; - - for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; - pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - devSup *pdevSup; - - for (pdevSup = (devSup *)ellFirst(&pdbRecordType->devList); - pdevSup; - pdevSup = (devSup *)ellNext(&pdevSup->node)) { - struct dset *pdset = pdevSup->pdset; - - if (pdset && pdset->init) - pdset->init(1); - } - } -} - -static void iterateRecords(recIterFunc func, void *user) -{ - dbRecordType *pdbRecordType; - - for (pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList); - pdbRecordType; - pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node)) { - dbRecordNode *pdbRecordNode; - - for (pdbRecordNode = (dbRecordNode *)ellFirst(&pdbRecordType->recList); - pdbRecordNode; - pdbRecordNode = (dbRecordNode *)ellNext(&pdbRecordNode->node)) { - dbCommon *precord = pdbRecordNode->precord; - - if (!precord->name[0] || - pdbRecordNode->flags & DBRN_FLAGS_ISALIAS) - continue; - - func(pdbRecordType, precord, user); - } - } - return; -} - -static void doInitRecord0(dbRecordType *pdbRecordType, dbCommon *precord, - void *user) -{ - rset *prset = pdbRecordType->prset; - devSup *pdevSup; - - if (!prset) return; /* unlikely */ - - precord->rset = prset; - precord->mlok = epicsMutexMustCreate(); - ellInit(&precord->mlis); - - /* Reset the process active field */ - precord->pact = FALSE; - - /* Initial UDF severity */ - if (precord->udf && precord->stat == UDF_ALARM) - precord->sevr = precord->udfs; - - /* Init DSET NOTE that result may be NULL */ - pdevSup = dbDTYPtoDevSup(pdbRecordType, precord->dtyp); - precord->dset = pdevSup ? pdevSup->pdset : NULL; - - if (prset->init_record) - prset->init_record(precord, 0); -} - -static void doResolveLinks(dbRecordType *pdbRecordType, dbCommon *precord, - void *user) -{ - dbFldDes **papFldDes = pdbRecordType->papFldDes; - short *link_ind = pdbRecordType->link_ind; - int j; - - /* For all the links in the record type... */ - for (j = 0; j < pdbRecordType->no_links; j++) { - dbFldDes *pdbFldDes = papFldDes[link_ind[j]]; - DBLINK *plink = (DBLINK*)((char*)precord + pdbFldDes->offset); - - if (ellCount(&precord->rdes->devList) > 0 && pdbFldDes->isDevLink) { - devSup *pdevSup = dbDTYPtoDevSup(pdbRecordType, precord->dtyp); - - if (pdevSup) { - struct dsxt *pdsxt = pdevSup->pdsxt; - if (pdsxt && pdsxt->add_record) { - pdsxt->add_record(precord); - } - } - } - - dbInitLink(plink, pdbFldDes->field_type); - } -} - -static void doInitRecord1(dbRecordType *pdbRecordType, dbCommon *precord, - void *user) -{ - rset *prset = pdbRecordType->prset; - - if (!prset) return; /* unlikely */ - - if (prset->init_record) - prset->init_record(precord, 1); -} - -static void initDatabase(void) -{ - dbChannelInit(); - iterateRecords(doInitRecord0, NULL); - iterateRecords(doResolveLinks, NULL); - iterateRecords(doInitRecord1, NULL); - - epicsAtExit(exitDatabase, NULL); - return; -} - -/* - * Process database records at initialization ordered by phase - * if their pini (process at init) field is set. - */ -typedef struct { - int this; - int next; - epicsEnum16 pini; -} phaseData_t; - -static void doRecordPini(dbRecordType *rtype, dbCommon *precord, void *user) -{ - phaseData_t *pphase = (phaseData_t *)user; - int phas; - - if (precord->pini != pphase->pini) return; - - phas = precord->phas; - if (phas == pphase->this) { - dbScanLock(precord); - dbProcess(precord); - dbScanUnlock(precord); - } else if (phas > pphase->this && phas < pphase->next) - pphase->next = phas; -} - -static void piniProcess(int pini) -{ - phaseData_t phase; - phase.next = MIN_PHASE; - phase.pini = pini; - - /* This scans through the whole database as many times as needed. - * During the first pass it is unlikely to find any records with - * PHAS = MIN_PHASE, but during each iteration it looks for the - * phase value of the next pass to run. Note that PHAS fields can - * be changed at runtime, so we have to look for the lowest value - * of PHAS each time. - */ - do { - phase.this = phase.next; - phase.next = MAX_PHASE + 1; - iterateRecords(doRecordPini, &phase); - } while (phase.next != MAX_PHASE + 1); -} - -static void piniProcessHook(initHookState state) -{ - switch (state) { - case initHookAtIocRun: - piniProcess(menuPiniRUN); - break; - - case initHookAfterIocRunning: - piniProcess(menuPiniRUNNING); - break; - - case initHookAtIocPause: - piniProcess(menuPiniPAUSE); - break; - - case initHookAfterIocPaused: - piniProcess(menuPiniPAUSED); - break; - - default: - break; - } -} - -static void initialProcess(void) -{ - initHookRegister(piniProcessHook); - piniProcess(menuPiniYES); -} - - -/* - * set DB_LINK and CA_LINK to PV_LINK - * Delete record scans - */ -static void doCloseLinks(dbRecordType *pdbRecordType, dbCommon *precord, - void *user) -{ - devSup *pdevSup; - struct dsxt *pdsxt; - int j; - int locked = 0; - - for (j = 0; j < pdbRecordType->no_links; j++) { - dbFldDes *pdbFldDes = - pdbRecordType->papFldDes[pdbRecordType->link_ind[j]]; - DBLINK *plink = (DBLINK *)((char *)precord + pdbFldDes->offset); - - if (plink->type == CA_LINK || - plink->type == JSON_LINK || - (plink->type == DB_LINK && iocBuildMode == buildIsolated)) { - if (!locked) { - dbScanLock(precord); - locked = 1; - } - dbRemoveLink(NULL, plink); - } - } - - if (precord->dset && - (pdevSup = dbDSETtoDevSup(pdbRecordType, precord->dset)) && - (pdsxt = pdevSup->pdsxt) && - pdsxt->del_record) { - if (!locked) { - dbScanLock(precord); - locked = 1; - } - scanDelete(precord); /* Being consistent... */ - pdsxt->del_record(precord); - } - if (locked) { - precord->pact = TRUE; - dbScanUnlock(precord); - } -} - -static void doFreeRecord(dbRecordType *pdbRecordType, dbCommon *precord, - void *user) -{ - int j; - - for (j = 0; j < pdbRecordType->no_links; j++) { - dbFldDes *pdbFldDes = - pdbRecordType->papFldDes[pdbRecordType->link_ind[j]]; - DBLINK *plink = (DBLINK *)((char *)precord + pdbFldDes->offset); - - dbFreeLinkContents(plink); - } - - epicsMutexDestroy(precord->mlok); - free(precord->ppnr); /* may be allocated in dbNotify.c */ -} - -int iocShutdown(void) -{ - if (iocState == iocVirgin || iocState == iocStopped) return 0; - iterateRecords(doCloseLinks, NULL); - if (iocBuildMode==buildIsolated) { - /* stop and "join" threads */ - scanStop(); - callbackStop(); - } - dbCaShutdown(); /* must be before dbFreeRecord and dbChannelExit */ - if (iocBuildMode==buildIsolated) { - /* free resources */ - scanCleanup(); - callbackCleanup(); - iterateRecords(doFreeRecord, NULL); - dbLockCleanupRecords(pdbbase); - asShutdown(); - dbChannelExit(); - dbProcessNotifyExit(); - iocshFree(); - } - iocState = iocStopped; - iocBuildMode = buildRSRV; - return 0; -} - -static void exitDatabase(void *dummy) -{ - iocShutdown(); -} diff --git a/src/ioc/misc/iocInit.h b/src/ioc/misc/iocInit.h deleted file mode 100644 index 24ae45e06..000000000 --- a/src/ioc/misc/iocInit.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* iocInit.h ioc initialization */ - -#ifndef INCiocInith -#define INCiocInith - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int iocInit(void); -epicsShareFunc int iocBuild(void); -epicsShareFunc int iocBuildIsolated(void); -epicsShareFunc int iocRun(void); -epicsShareFunc int iocPause(void); -epicsShareFunc int iocShutdown(void); - -#ifdef __cplusplus -} -#endif - - -#endif /*INCiocInith*/ diff --git a/src/ioc/misc/iocshRegisterCommon.c b/src/ioc/misc/iocshRegisterCommon.c deleted file mode 100644 index fefa716b9..000000000 --- a/src/ioc/misc/iocshRegisterCommon.c +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "envDefs.h" -#include "epicsVersion.h" -#include "iocsh.h" -#include "libComRegister.h" - -#define epicsExportSharedSymbols -#include "asIocRegister.h" -#include "dbAccess.h" -#include "dbIocRegister.h" -#include "dbStaticIocRegister.h" -#include "dbtoolsIocRegister.h" -#include "iocshRegisterCommon.h" -#include "miscIocRegister.h" -#include "registryIocRegister.h" -#include "rsrvIocRegister.h" - -#define quote(v) #v -#define str(v) quote(v) - -void iocshRegisterCommon(void) -{ - const char *targetArch = envGetConfigParamPtr(&EPICS_BUILD_TARGET_ARCH); - iocshPpdbbase = &pdbbase; - - /* This uses a config param so the user can override it */ - if (targetArch) { - epicsEnvSet("ARCH", targetArch); - } - - /* Base build version variables */ - epicsEnvSet("EPICS_VERSION_MAJOR", str(EPICS_VERSION)); - epicsEnvSet("EPICS_VERSION_MIDDLE", str(EPICS_REVISION)); - epicsEnvSet("EPICS_VERSION_MINOR", str(EPICS_MODIFICATION)); - epicsEnvSet("EPICS_VERSION_PATCH", str(EPICS_PATCH_LEVEL)); - epicsEnvSet("EPICS_VERSION_SNAPSHOT", EPICS_DEV_SNAPSHOT); - epicsEnvSet("EPICS_VERSION_SITE", EPICS_SITE_VERSION); - epicsEnvSet("EPICS_VERSION_SHORT", EPICS_VERSION_SHORT); - epicsEnvSet("EPICS_VERSION_FULL", EPICS_VERSION_FULL); - - dbStaticIocRegister(); - registryIocRegister(); - dbIocRegister(); - dbtoolsIocRegister(); - asIocRegister(); - rsrvIocRegister(); - miscIocRegister(); - libComRegister(); -} diff --git a/src/ioc/misc/iocshRegisterCommon.h b/src/ioc/misc/iocshRegisterCommon.h deleted file mode 100644 index 62a5d7c1b..000000000 --- a/src/ioc/misc/iocshRegisterCommon.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* iocshRegisterCommon.h */ -/* Author: Marty Kraimer Date: 27APR2000 */ - -#ifndef INCiocshRegisterCommonH -#define INCiocshRegisterCommonH - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* register many useful commands */ -epicsShareFunc void iocshRegisterCommon(void); - -#ifdef __cplusplus -} -#endif - -#endif /*INCiocshRegisterCommonH*/ diff --git a/src/ioc/misc/miscIocRegister.c b/src/ioc/misc/miscIocRegister.c deleted file mode 100644 index 233852ed2..000000000 --- a/src/ioc/misc/miscIocRegister.c +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "iocsh.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "iocInit.h" -#include "epicsExport.h" -#include "epicsRelease.h" -#include "miscIocRegister.h" - -/* iocInit */ -static const iocshFuncDef iocInitFuncDef = {"iocInit",0,NULL}; -static void iocInitCallFunc(const iocshArgBuf *args) -{ - iocInit(); -} - -/* iocBuild */ -static const iocshFuncDef iocBuildFuncDef = {"iocBuild",0,NULL}; -static void iocBuildCallFunc(const iocshArgBuf *args) -{ - iocBuild(); -} - -/* iocRun */ -static const iocshFuncDef iocRunFuncDef = {"iocRun",0,NULL}; -static void iocRunCallFunc(const iocshArgBuf *args) -{ - iocRun(); -} - -/* iocPause */ -static const iocshFuncDef iocPauseFuncDef = {"iocPause",0,NULL}; -static void iocPauseCallFunc(const iocshArgBuf *args) -{ - iocPause(); -} - -/* coreRelease */ -static const iocshFuncDef coreReleaseFuncDef = {"coreRelease",0,NULL}; -static void coreReleaseCallFunc(const iocshArgBuf *args) -{ - coreRelease (); -} - - -void miscIocRegister(void) -{ - iocshRegister(&iocInitFuncDef,iocInitCallFunc); - iocshRegister(&iocBuildFuncDef,iocBuildCallFunc); - iocshRegister(&iocRunFuncDef,iocRunCallFunc); - iocshRegister(&iocPauseFuncDef,iocPauseCallFunc); - iocshRegister(&coreReleaseFuncDef, coreReleaseCallFunc); -} - - -/* system -- escape to system command interpreter. - * - * Disabled by default, for security reasons. To enable this command, add - * registrar(iocshSystemCommand) - * to an application dbd file. - */ -static const iocshArg systemArg0 = { "command string",iocshArgString}; -static const iocshArg * const systemArgs[] = {&systemArg0}; -static const iocshFuncDef systemFuncDef = {"system",1,systemArgs}; -static void systemCallFunc(const iocshArgBuf *args) -{ - system(args[0].sval); -} - -static void iocshSystemCommand(void) -{ - if (system(NULL)) - iocshRegister(&systemFuncDef, systemCallFunc); - else - errlogPrintf ("Can't register 'system' command -- no command interpreter available.\n"); -} -epicsExportRegistrar(iocshSystemCommand); diff --git a/src/ioc/misc/miscIocRegister.h b/src/ioc/misc/miscIocRegister.h deleted file mode 100644 index 78a54d620..000000000 --- a/src/ioc/misc/miscIocRegister.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_miscIocRegister_H -#define INC_miscIocRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void miscIocRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_miscIocRegister_H */ diff --git a/src/ioc/misc/system.dbd b/src/ioc/misc/system.dbd deleted file mode 100644 index e50c19820..000000000 --- a/src/ioc/misc/system.dbd +++ /dev/null @@ -1,3 +0,0 @@ -# Including this DBD file adds a 'system' command to the IOC shell. - -registrar(iocshSystemCommand) diff --git a/src/ioc/registry/Makefile b/src/ioc/registry/Makefile deleted file mode 100644 index a85320a9d..000000000 --- a/src/ioc/registry/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(IOCDIR)/registry - -INC += registryRecordType.h -INC += registryDeviceSupport.h -INC += registryDriverSupport.h -INC += registryJLinks.h -INC += registryFunction.h -INC += registryCommon.h -INC += registryIocRegister.h - -dbCore_SRCS += registryRecordType.c -dbCore_SRCS += registryDeviceSupport.c -dbCore_SRCS += registryDriverSupport.c -dbCore_SRCS += registryJLinks.c -dbCore_SRCS += registryFunction.c -dbCore_SRCS += registryCommon.c -dbCore_SRCS += registryIocRegister.c - diff --git a/src/ioc/registry/registryCommon.c b/src/ioc/registry/registryCommon.c deleted file mode 100644 index 56664c5bb..000000000 --- a/src/ioc/registry/registryCommon.c +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* registryCommon.c */ - -/* Author: Andrew Johnson - * Date: 2004-03-19 - */ - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "registryCommon.h" -#include "registryDeviceSupport.h" -#include "registryDriverSupport.h" -#include "registryJLinks.h" - - -void registerRecordTypes(DBBASE *pbase, int nRecordTypes, - const char * const *recordTypeNames, const recordTypeLocation *rtl) -{ - int i; - for (i = 0; i < nRecordTypes; i++) { - recordTypeLocation *precordTypeLocation; - computeSizeOffset sizeOffset; - DBENTRY dbEntry; - - if (registryRecordTypeFind(recordTypeNames[i])) continue; - if (!registryRecordTypeAdd(recordTypeNames[i], &rtl[i])) { - errlogPrintf("registryRecordTypeAdd failed %s\n", - recordTypeNames[i]); - continue; - } - dbInitEntry(pbase,&dbEntry); - precordTypeLocation = registryRecordTypeFind(recordTypeNames[i]); - sizeOffset = precordTypeLocation->sizeOffset; - if (dbFindRecordType(&dbEntry, recordTypeNames[i])) { - errlogPrintf("registerRecordDeviceDriver failed %s\n", - recordTypeNames[i]); - } else { - sizeOffset(dbEntry.precordType); - } - } -} - -void registerDevices(DBBASE *pbase, int nDevices, - const char * const *deviceSupportNames, const dset * const *devsl) -{ - int i; - for (i = 0; i < nDevices; i++) { - if (registryDeviceSupportFind(deviceSupportNames[i])) continue; - if (!registryDeviceSupportAdd(deviceSupportNames[i], devsl[i])) { - errlogPrintf("registryDeviceSupportAdd failed %s\n", - deviceSupportNames[i]); - continue; - } - } -} - -void registerDrivers(DBBASE *pbase, int nDrivers, - const char * const * driverSupportNames, struct drvet * const *drvsl) -{ - int i; - for (i = 0; i < nDrivers; i++) { - if (registryDriverSupportFind(driverSupportNames[i])) continue; - if (!registryDriverSupportAdd(driverSupportNames[i], drvsl[i])) { - errlogPrintf("registryDriverSupportAdd failed %s\n", - driverSupportNames[i]); - continue; - } - } -} - -void registerJLinks(DBBASE *pbase, int nLinks, jlif * const *jlifsl) -{ - int i; - for (i = 0; i < nLinks; i++) { - if (!registryJLinkAdd(pbase, jlifsl[i])) { - errlogPrintf("registryJLinkAdd failed %s\n", - jlifsl[i]->name); - continue; - } - } -} - diff --git a/src/ioc/registry/registryCommon.h b/src/ioc/registry/registryCommon.h deleted file mode 100644 index 51b32dee3..000000000 --- a/src/ioc/registry/registryCommon.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_registryCommon_H -#define INC_registryCommon_H - -#include "dbStaticLib.h" -#include "devSup.h" -#include "dbJLink.h" -#include "registryRecordType.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void registerRecordTypes( - DBBASE *pbase, int nRecordTypes, - const char * const *recordTypeNames, const recordTypeLocation *rtl); -epicsShareFunc void registerDevices( - DBBASE *pbase, int nDevices, - const char * const *deviceSupportNames, const dset * const *devsl); -epicsShareFunc void registerDrivers( - DBBASE *pbase, int nDrivers, - const char * const *driverSupportNames, struct drvet * const *drvsl); -epicsShareFunc void registerJLinks( - DBBASE *pbase, int nDrivers, jlif * const *jlifsl); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_registryCommon_H */ diff --git a/src/ioc/registry/registryDeviceSupport.c b/src/ioc/registry/registryDeviceSupport.c deleted file mode 100644 index 4310c923d..000000000 --- a/src/ioc/registry/registryDeviceSupport.c +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* registryDeviceSupport.c */ - -/* Author: Marty Kraimer Date: 08JUN99 */ - -#define epicsExportSharedSymbols -#include "registry.h" -#include "registryDeviceSupport.h" - -static void *registryID = "device support"; - - -epicsShareFunc int registryDeviceSupportAdd( - const char *name, const struct dset *pdset) -{ - return registryAdd(registryID, name, (void *)pdset); -} - -epicsShareFunc struct dset * registryDeviceSupportFind( - const char *name) -{ - return registryFind(registryID, name); -} diff --git a/src/ioc/registry/registryDeviceSupport.h b/src/ioc/registry/registryDeviceSupport.h deleted file mode 100644 index 52a269863..000000000 --- a/src/ioc/registry/registryDeviceSupport.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_registryDeviceSupport_H -#define INC_registryDeviceSupport_H - -#include "devSup.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int registryDeviceSupportAdd( - const char *name, const struct dset *pdset); -epicsShareFunc struct dset * registryDeviceSupportFind( - const char *name); - -#ifdef __cplusplus -} -#endif - - -#endif /* INC_registryDeviceSupport_H */ diff --git a/src/ioc/registry/registryDriverSupport.c b/src/ioc/registry/registryDriverSupport.c deleted file mode 100644 index 8393bc414..000000000 --- a/src/ioc/registry/registryDriverSupport.c +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* registryDriverSupport.c */ - -/* Author: Marty Kraimer Date: 08JUN99 */ - -#define epicsExportSharedSymbols -#include "registry.h" -#include "registryDriverSupport.h" - -static void *registryID = "driver support"; - - -epicsShareFunc int registryDriverSupportAdd( - const char *name, struct drvet *pdrvet) -{ - return registryAdd(registryID, name, pdrvet); -} - -epicsShareFunc struct drvet * registryDriverSupportFind( - const char *name) -{ - return registryFind(registryID, name); -} diff --git a/src/ioc/registry/registryDriverSupport.h b/src/ioc/registry/registryDriverSupport.h deleted file mode 100644 index 79be29295..000000000 --- a/src/ioc/registry/registryDriverSupport.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_registryDriverSupport_H -#define INC_registryDriverSupport_H - -#include "drvSup.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int registryDriverSupportAdd( - const char *name, struct drvet *pdrvet); -epicsShareFunc struct drvet * registryDriverSupportFind( - const char *name); - -#ifdef __cplusplus -} -#endif - - -#endif /* INC_registryDriverSupport_H */ diff --git a/src/ioc/registry/registryFunction.c b/src/ioc/registry/registryFunction.c deleted file mode 100644 index 194f078c1..000000000 --- a/src/ioc/registry/registryFunction.c +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* registryFunction.c */ - -/* Author: Marty Kraimer Date: 01MAY2000 */ - -#include - -#define epicsExportSharedSymbols -#include "registry.h" -#include "registryFunction.h" - -static void * const registryID = "function"; - - -epicsShareFunc int registryFunctionAdd( - const char *name, REGISTRYFUNCTION func) -{ - return registryAdd(registryID, name, func); -} - -epicsShareFunc REGISTRYFUNCTION registryFunctionFind( - const char *name) -{ - REGISTRYFUNCTION func = registryFind(registryID, name); - - if (!func) { - func = registryFind(0, name); - if (func) registryFunctionAdd(name, func); - } - return func; -} - -epicsShareFunc int registryFunctionRefAdd( - registryFunctionRef ref[], int nfunctions) -{ - int i; - - for (i = 0; i < nfunctions; i++) { - if (!registryFunctionAdd(ref[i].name, ref[i].addr)) { - printf("registryFunctionRefAdd: could not register %s\n", - ref[i].name); - return 0; - } - } - return 1; -} diff --git a/src/ioc/registry/registryFunction.h b/src/ioc/registry/registryFunction.h deleted file mode 100644 index e20513771..000000000 --- a/src/ioc/registry/registryFunction.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_registryFunction_H -#define INC_registryFunction_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*REGISTRYFUNCTION)(void); - -typedef struct registryFunctionRef { - const char * name; - REGISTRYFUNCTION addr; -} registryFunctionRef; - - -epicsShareFunc int registryFunctionAdd( - const char *name, REGISTRYFUNCTION func); -epicsShareFunc REGISTRYFUNCTION registryFunctionFind( - const char *name); -epicsShareFunc int registryFunctionRefAdd( - registryFunctionRef ref[], int nfunctions); - -#ifdef __cplusplus -} -#endif - - -#endif /* INC_registryFunction_H */ diff --git a/src/ioc/registry/registryIocRegister.c b/src/ioc/registry/registryIocRegister.c deleted file mode 100644 index e36a809df..000000000 --- a/src/ioc/registry/registryIocRegister.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "iocsh.h" - -#define epicsExportSharedSymbols -#include "registryDeviceSupport.h" -#include "registryDriverSupport.h" -#include "registryFunction.h" -#include "registryIocRegister.h" -#include "registryRecordType.h" - -static const iocshArg registryXxxFindArg0 = { "name",iocshArgString}; -static const iocshArg * const registryXxxFindArgs[1] = {®istryXxxFindArg0}; - -/* registryRecordTypeFind */ -static const iocshFuncDef registryRecordTypeFindFuncDef = { - "registryRecordTypeFind",1,registryXxxFindArgs}; -static void registryRecordTypeFindCallFunc(const iocshArgBuf *args) { - printf("%p\n", (void*) registryRecordTypeFind(args[0].sval)); -} - -/* registryDeviceSupportFind */ -static const iocshFuncDef registryDeviceSupportFindFuncDef = { - "registryDeviceSupportFind",1,registryXxxFindArgs}; -static void registryDeviceSupportFindCallFunc(const iocshArgBuf *args) { - printf("%p\n", (void*) registryDeviceSupportFind(args[0].sval)); -} - -/* registryDriverSupportFind */ -static const iocshFuncDef registryDriverSupportFindFuncDef = { - "registryDriverSupportFind",1,registryXxxFindArgs}; -static void registryDriverSupportFindCallFunc(const iocshArgBuf *args) { - printf("%p\n", (void*) registryDriverSupportFind(args[0].sval)); -} - -/* registryFunctionFind */ -static const iocshFuncDef registryFunctionFindFuncDef = { - "registryFunctionFind",1,registryXxxFindArgs}; -static void registryFunctionFindCallFunc(const iocshArgBuf *args) { - printf("%p\n", (void*) registryFunctionFind(args[0].sval)); -} - -void registryIocRegister(void) -{ - iocshRegister(®istryRecordTypeFindFuncDef,registryRecordTypeFindCallFunc); - iocshRegister(®istryDeviceSupportFindFuncDef,registryDeviceSupportFindCallFunc); - iocshRegister(®istryDriverSupportFindFuncDef,registryDriverSupportFindCallFunc); - iocshRegister(®istryFunctionFindFuncDef,registryFunctionFindCallFunc); -} diff --git a/src/ioc/registry/registryIocRegister.h b/src/ioc/registry/registryIocRegister.h deleted file mode 100644 index ca02ce0e3..000000000 --- a/src/ioc/registry/registryIocRegister.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_registryIocRegister_H -#define INC_registryIocRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void registryIocRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_registryIocRegister_H */ diff --git a/src/ioc/registry/registryJLinks.c b/src/ioc/registry/registryJLinks.c deleted file mode 100644 index 921a2cbcc..000000000 --- a/src/ioc/registry/registryJLinks.c +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* registryJLinks.c */ - -#include "registry.h" -#define epicsExportSharedSymbols -#include "dbBase.h" -#include "dbStaticLib.h" -#include "registryJLinks.h" -#include "dbJLink.h" - -epicsShareFunc int registryJLinkAdd(DBBASE *pbase, struct jlif *pjlif) -{ - linkSup *plinkSup = dbFindLinkSup(pbase, pjlif->name); - - if (plinkSup) - plinkSup->pjlif = pjlif; - return !!plinkSup; -} diff --git a/src/ioc/registry/registryJLinks.h b/src/ioc/registry/registryJLinks.h deleted file mode 100644 index 7e6a8933e..000000000 --- a/src/ioc/registry/registryJLinks.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_registryJLinks_H -#define INC_registryJLinks_H - -#include "dbBase.h" -#include "dbJLink.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int registryJLinkAdd(DBBASE *pbase, jlif *pjlif); - -#ifdef __cplusplus -} -#endif - - -#endif /* INC_registryDriverSupport_H */ diff --git a/src/ioc/registry/registryRecordType.c b/src/ioc/registry/registryRecordType.c deleted file mode 100644 index eced6f0f6..000000000 --- a/src/ioc/registry/registryRecordType.c +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* registryRecordType.c */ - -/* Author: Marty Kraimer Date: 08JUN99 */ - -#define epicsExportSharedSymbols -#include "registry.h" -#include "registryRecordType.h" - -static void * const registryID = "record type"; - - -epicsShareFunc int registryRecordTypeAdd( - const char *name, const recordTypeLocation *prtl) -{ - return registryAdd(registryID, name, (void *)prtl); -} - -epicsShareFunc recordTypeLocation * registryRecordTypeFind( - const char *name) -{ - return registryFind(registryID, name); -} diff --git a/src/ioc/registry/registryRecordType.h b/src/ioc/registry/registryRecordType.h deleted file mode 100644 index 29ba714e8..000000000 --- a/src/ioc/registry/registryRecordType.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_registryRecordType_H -#define INC_registryRecordType_H - -#include "recSup.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct dbRecordType; -struct dbBase; - -typedef int (*computeSizeOffset)(struct dbRecordType *pdbRecordType); - -typedef struct recordTypeLocation { - struct typed_rset *prset; - computeSizeOffset sizeOffset; -}recordTypeLocation; - -epicsShareFunc int registryRecordTypeAdd( - const char *name, const recordTypeLocation *prtl); -epicsShareFunc recordTypeLocation * registryRecordTypeFind( - const char *name); - -int registerRecordDeviceDriver(struct dbBase *pdbbase); - -#ifdef __cplusplus -} -#endif - - -#endif /* INC_registryRecordType_H */ diff --git a/src/ioc/rsrv/Makefile b/src/ioc/rsrv/Makefile deleted file mode 100644 index ba6ed6bd6..000000000 --- a/src/ioc/rsrv/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(IOCDIR)/rsrv - -# These need access to net_convert.h from the CA client -caserverio_INCLUDES = -I$(SRC)/ca/client -camessage_INCLUDES = -I$(SRC)/ca/client - -INC += rsrv.h -INC += rsrvIocRegister.h - -dbCore_SRCS += caserverio.c -dbCore_SRCS += caservertask.c -dbCore_SRCS += camsgtask.c -dbCore_SRCS += camessage.c -dbCore_SRCS += cast_server.c -dbCore_SRCS += online_notify.c -dbCore_SRCS += rsrvIocRegister.c - diff --git a/src/ioc/rsrv/camessage.c b/src/ioc/rsrv/camessage.c deleted file mode 100644 index 942e01e32..000000000 --- a/src/ioc/rsrv/camessage.c +++ /dev/null @@ -1,2563 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * - * Ralph Lange - */ - -#include -#include -#include -#include -#include -#include - -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsStdio.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "freeList.h" -#include "osiPoolStatus.h" -#include "osiSock.h" - -#include "caerr.h" -#include "net_convert.h" - -#define epicsExportSharedSymbols -#include "asDbLib.h" -#include "callback.h" -#include "db_access.h" -#include "db_access_routines.h" -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbEvent.h" -#include "db_field_log.h" -#include "dbNotify.h" -#include "rsrv.h" -#include "server.h" -#include "special.h" - -#define RECORD_NAME(CHAN) (dbChannelRecord(CHAN)->name) - -static EVENTFUNC read_reply; - -#define logBadId(CLIENT, MP, PPL)\ -logBadIdWithFileAndLineno(CLIENT, MP, PPL, __FILE__, __LINE__) - -/* - * for tracking db put notifies - */ -typedef struct rsrv_put_notify { - ELLNODE node; - processNotify dbPutNotify; - caHdrLargeArray msg; - /* - * Include a union of all scalar types - * including fixed length strings so - * that in many cases we can avoid - * allocating another buffer and only - * use an rsrv_put_notify from its - * free list. - */ - union { - dbr_string_t strval; - dbr_short_t shrtval; - dbr_short_t intval; - dbr_float_t fltval; - dbr_enum_t enmval; - dbr_char_t charval; - dbr_long_t longval; - dbr_double_t doubleval; - } dbrScalarValue; - /* arguments for db_put_field */ - void *pbuffer; - long nRequest; - short dbrType; - /* end arguments for db_put_field */ - void * asWritePvt; - unsigned valueSize; /* size of block pointed to by pbuffer */ - char busy; /* put notify in progress */ - char onExtraLaborQueue; -} RSRVPUTNOTIFY; - -/* - * casCalloc() - * - * (dont drop below some max block threshold) - */ -static void *casCalloc(size_t count, size_t size) -{ - if ( UINT_MAX / size >= count ) { - if (!osiSufficentSpaceInPool(size*count)) { - return NULL; - } - return calloc(count, size); - } - else { - return NULL; - } -} - -/* - * MPTOPCIU() - * - * used to be a macro - */ -static struct channel_in_use *MPTOPCIU (const caHdrLargeArray *mp) -{ - struct channel_in_use *pciu; - const unsigned id = mp->m_cid; - - LOCK_CLIENTQ; - pciu = bucketLookupItemUnsignedId (pCaBucket, &id); - UNLOCK_CLIENTQ; - - return pciu; -} - -/* vsend_err() - * - * reflect error msg back to the client - * - * send buffer lock must be on while in this routine - * - */ -static void vsend_err( -const caHdrLargeArray *curp, -int status, -struct client *client, -const char *pformat, -va_list args -) -{ - static const ca_uint32_t maxDiagLen = 512; - struct channel_in_use *pciu; - caHdr *pReqOut; - char *pMsgString; - ca_uint32_t size; - ca_uint32_t cid; - int localStatus; - - switch ( curp->m_cmmd ) { - case CA_PROTO_EVENT_ADD: - case CA_PROTO_EVENT_CANCEL: - case CA_PROTO_READ: - case CA_PROTO_READ_NOTIFY: - case CA_PROTO_WRITE: - case CA_PROTO_WRITE_NOTIFY: - pciu = MPTOPCIU(curp); - if(pciu){ - cid = pciu->cid; - } - else{ - cid = 0xffffffff; - } - break; - - case CA_PROTO_SEARCH: - cid = curp->m_cid; - break; - - case CA_PROTO_EVENTS_ON: - case CA_PROTO_EVENTS_OFF: - case CA_PROTO_READ_SYNC: - case CA_PROTO_SNAPSHOT: - default: - cid = 0xffffffff; - break; - } - - /* - * allocate plenty of space for a sprintf() buffer - */ - localStatus = cas_copy_in_header ( client, - CA_PROTO_ERROR, maxDiagLen, 0, 0, cid, status, - ( void * ) &pReqOut ); - if ( localStatus != ECA_NORMAL ) { - errlogPrintf ( "caserver: Unable to deliver err msg \"%s\" to client because \"%s\"\n", - ca_message (status), ca_message (localStatus) ); - errlogVprintf ( pformat, args ); - return; - } - - /* - * copy back the request protocol - * (in network byte order) - */ - if ( ( curp->m_postsize >= 0xffff || curp->m_count >= 0xffff ) && - CA_V49( client->minor_version_number ) ) { - ca_uint32_t *pLW = ( ca_uint32_t * ) ( pReqOut + 1 ); - pReqOut->m_cmmd = htons ( curp->m_cmmd ); - pReqOut->m_postsize = htons ( 0xffff ); - pReqOut->m_dataType = htons ( curp->m_dataType ); - pReqOut->m_count = htons ( 0u ); - pReqOut->m_cid = htonl ( curp->m_cid ); - pReqOut->m_available = htonl ( curp->m_available ); - pLW[0] = htonl ( curp->m_postsize ); - pLW[1] = htonl ( curp->m_count ); - pMsgString = ( char * ) ( pLW + 2 ); - size = sizeof ( caHdr ) + 2 * sizeof ( *pLW ); - } - else { - pReqOut->m_cmmd = htons (curp->m_cmmd); - pReqOut->m_postsize = htons ( ( (ca_uint16_t) curp->m_postsize ) ); - pReqOut->m_dataType = htons (curp->m_dataType); - pReqOut->m_count = htons ( ( (ca_uint16_t) curp->m_count ) ); - pReqOut->m_cid = htonl (curp->m_cid); - pReqOut->m_available = htonl (curp->m_available); - pMsgString = ( char * ) ( pReqOut + 1 ); - size = sizeof ( caHdr ); - } - - /* - * add their context string into the protocol - */ - localStatus = epicsVsnprintf ( pMsgString, maxDiagLen, pformat, args ); - if ( localStatus >= 1 ) { - unsigned diagLen = ( unsigned ) localStatus; - if ( diagLen < maxDiagLen ) { - size += (ca_uint32_t) (diagLen + 1u); - } - else { - errlogPrintf ( - "caserver: vsend_err: epicsVsnprintf detected " - "error message truncation, pFormat = \"%s\"\n", - pformat ); - size += maxDiagLen; - pMsgString [ maxDiagLen - 1 ] = '\0'; - } - } - cas_commit_msg ( client, size ); -} - -/* send_err() - * - * reflect error msg back to the client - * - * send buffer lock must be on while in this routine - * - */ -static void send_err ( -const caHdrLargeArray *curp, -int status, -struct client *client, -const char *pformat, - ... ) -{ - va_list args; - va_start ( args, pformat ); - vsend_err ( curp, status, client, pformat, args ); - va_end ( args ); -} - -/* log_header() - * - * Debug aid - print the header part of a message. - * - */ -static void log_header ( - const char *pContext, - struct client *client, - const caHdrLargeArray *mp, - const void *pPayLoad, - unsigned mnum -) -{ - struct channel_in_use *pciu; - char hostName[256]; - - ipAddrToDottedIP (&client->addr, hostName, sizeof(hostName)); - - pciu = MPTOPCIU(mp); - - if (pContext) { - epicsPrintf ("CAS: request from %s => %s\n", - hostName, pContext); - } - - epicsPrintf ( "CAS: Request from %s => cmmd=%d cid=0x%x type=%d count=%d postsize=%u\n", - hostName, mp->m_cmmd, mp->m_cid, mp->m_dataType, mp->m_count, mp->m_postsize); - - epicsPrintf ( "CAS: Request from %s => available=0x%x \tN=%u paddr=%p\n", - hostName, mp->m_available, mnum, (pciu ? (void *)&pciu->dbch : NULL)); - - if (mp->m_cmmd==CA_PROTO_WRITE && mp->m_dataType==DBF_STRING && pPayLoad ) { - epicsPrintf ( "CAS: Request from %s => Wrote string \"%s\"\n", - hostName, (char *)pPayLoad ); - } -} - -/* - * logBadIdWithFileAndLineno() - */ -static void logBadIdWithFileAndLineno( -struct client *client, -caHdrLargeArray *mp, -const void *pPayload, -char *pFileName, -unsigned lineno -) -{ - log_header ( "bad resource ID", client, mp, pPayload, 0 ); - SEND_LOCK ( client ); - send_err ( mp, ECA_INTERNAL, client, "Bad Resource ID at %s.%d", - pFileName, lineno ); - SEND_UNLOCK ( client ); -} - -/* - * bad_udp_cmd_action() - */ -static int bad_udp_cmd_action ( caHdrLargeArray *mp, - void *pPayload, struct client *pClient ) -{ - if (CASDEBUG > 0) - log_header ("invalid (damaged?) request code from UDP", - pClient, mp, pPayload, 0); - return RSRV_ERROR; -} - -/* - * bad_tcp_cmd_action() - */ -static int bad_tcp_cmd_action ( caHdrLargeArray *mp, void *pPayload, - struct client *client ) -{ - const char *pCtx = "invalid (damaged?) request code from TCP"; - log_header ( pCtx, client, mp, pPayload, 0 ); - - /* - * by default, clients dont recover - * from this - */ - SEND_LOCK (client); - send_err (mp, ECA_INTERNAL, client, pCtx); - SEND_UNLOCK (client); - - return RSRV_ERROR; -} - -/* - * tcp_version_action() - */ -static int tcp_version_action ( caHdrLargeArray *mp, void *pPayload, - struct client *client ) -{ - double tmp; - unsigned epicsPriorityNew; - unsigned epicsPrioritySelf; - - client->minor_version_number = mp->m_count; - - if (!CA_VSUPPORTED(mp->m_count)) { - DLOG ( 2, ( "CAS: Ignore version from unsupported client %u\n", mp->m_count ) ); - return RSRV_ERROR; - } - - if ( mp->m_dataType > CA_PROTO_PRIORITY_MAX ) { - return RSRV_ERROR; - } - - tmp = mp->m_dataType - CA_PROTO_PRIORITY_MIN; - tmp *= epicsThreadPriorityCAServerHigh - epicsThreadPriorityCAServerLow; - tmp /= CA_PROTO_PRIORITY_MAX - CA_PROTO_PRIORITY_MIN; - tmp += epicsThreadPriorityCAServerLow; - epicsPriorityNew = (unsigned) tmp; - epicsPrioritySelf = epicsThreadGetPrioritySelf(); - if ( epicsPriorityNew != epicsPrioritySelf ) { - epicsThreadBooleanStatus tbs; - unsigned priorityOfEvents; - tbs = epicsThreadHighestPriorityLevelBelow ( epicsPriorityNew, &priorityOfEvents ); - if ( tbs != epicsThreadBooleanStatusSuccess ) { - priorityOfEvents = epicsPriorityNew; - } - - if ( epicsPriorityNew > epicsPrioritySelf ) { - epicsThreadSetPriority ( epicsThreadGetIdSelf(), epicsPriorityNew ); - db_event_change_priority ( client->evuser, priorityOfEvents ); - } - else { - db_event_change_priority ( client->evuser, priorityOfEvents ); - epicsThreadSetPriority ( epicsThreadGetIdSelf(), epicsPriorityNew ); - } - client->priority = mp->m_dataType; - } - return RSRV_OK; -} - -/* - * tcp_echo_action() - */ -static int tcp_echo_action ( caHdrLargeArray *mp, - void *pPayload, struct client *pClient ) -{ - char *pPayloadOut; - int status; - SEND_LOCK ( pClient ); - status = cas_copy_in_header ( pClient, mp->m_cmmd, mp->m_postsize, - mp->m_dataType, mp->m_count, mp->m_cid, mp->m_available, - ( void * ) &pPayloadOut ); - if ( status == ECA_NORMAL ) { - memcpy ( pPayloadOut, pPayload, mp->m_postsize ); - cas_commit_msg ( pClient, mp->m_postsize ); - } - SEND_UNLOCK ( pClient ); - return RSRV_OK; -} - -/* - * events_on_action () - */ -static int events_on_action ( caHdrLargeArray *mp, - void *pPayload, struct client *pClient ) -{ - db_event_flow_ctrl_mode_off ( pClient->evuser ); - return RSRV_OK; -} - -/* - * events_off_action () - */ -static int events_off_action ( caHdrLargeArray *mp, - void *pPayload, struct client *pClient ) -{ - db_event_flow_ctrl_mode_on ( pClient->evuser ); - return RSRV_OK; -} - -/* - * no_read_access_event() - * - * !! LOCK needs to applied by caller !! - * - * substantial complication introduced here by the need for backwards - * compatibility - */ -static void no_read_access_event ( struct client *pClient, - struct event_ext *pevext ) -{ - char *pPayloadOut; - int status; - - /* - * New clients recv the status of the - * operation directly to the - * event/put/get callback. - * - * Fetched value is zerod in case they - * use it even when the status indicates - * failure. - * - * The m_cid field in the protocol - * header is abused to carry the status - */ - status = cas_copy_in_header ( pClient, pevext->msg.m_cmmd, pevext->size, - pevext->msg.m_dataType, pevext->msg.m_count, ECA_NORDACCESS, - pevext->msg.m_available, ( void * ) &pPayloadOut ); - if ( status == ECA_NORMAL ) { - memset ( pPayloadOut, 0, pevext->size ); - cas_commit_msg ( pClient, pevext->size ); - } - else { - send_err ( &pevext->msg, status, pClient, - "server unable to load read access denied response into protocol buffer PV=\"%s max bytes=%u\"", - RECORD_NAME ( pevext->pciu->dbch ), rsrvSizeofLargeBufTCP ); - } -} - -/* - * read_reply() - */ -static void read_reply ( void *pArg, struct dbChannel *dbch, - int eventsRemaining, db_field_log *pfl ) -{ - ca_uint32_t cid; - void *pPayload; - struct event_ext *pevext = pArg; - struct client *pClient = pevext->pciu->client; - struct channel_in_use *pciu = pevext->pciu; - const int readAccess = asCheckGet ( pciu->asClientPVT ); - int status; - int autosize; - int local_fl = 0; - long item_count; - ca_uint32_t payload_size; - dbAddr *paddr=&dbch->addr; - - SEND_LOCK ( pClient ); - - cid = ECA_NORMAL; - - /* If the client has requested a zero element count we interpret this as a - * request for all avaiable elements. In this case we initialise the - * header with the maximum element size specified by the database. */ - autosize = pevext->msg.m_count == 0; - item_count = - autosize ? paddr->no_elements : pevext->msg.m_count; - payload_size = dbr_size_n(pevext->msg.m_dataType, item_count); - status = cas_copy_in_header( - pClient, pevext->msg.m_cmmd, payload_size, - pevext->msg.m_dataType, item_count, cid, pevext->msg.m_available, - &pPayload ); - if ( status != ECA_NORMAL ) { - send_err ( &pevext->msg, status, pClient, - "server unable to load read (or subscription update) response " - "into protocol buffer PV=\"%s\" max bytes=%u", - RECORD_NAME ( dbch ), rsrvSizeofLargeBufTCP ); - if ( ! eventsRemaining ) - cas_send_bs_msg ( pClient, FALSE ); - SEND_UNLOCK ( pClient ); - return; - } - - /* - * verify read access - */ - if ( ! readAccess ) { - no_read_access_event ( pClient, pevext ); - if ( ! eventsRemaining ) - cas_send_bs_msg ( pClient, FALSE ); - SEND_UNLOCK ( pClient ); - return; - } - - /* If filters are involved in a read, create field log and run filters */ - if (!pfl && (ellCount(&dbch->pre_chain) || ellCount(&dbch->post_chain))) { - pfl = db_create_read_log(dbch); - if (pfl) { - local_fl = 1; - pfl = dbChannelRunPreChain(dbch, pfl); - pfl = dbChannelRunPostChain(dbch, pfl); - } - } - - status = dbChannel_get_count ( dbch, pevext->msg.m_dataType, - pPayload, &item_count, pfl); - - if (local_fl) db_delete_field_log(pfl); - - if ( status < 0 ) { - /* Clients recv the status of the operation directly to the - * event/put/get callback. (from CA_V41()) - * - * Fetched value is set to zero in case they use it even when the - * status indicates failure -- unless the client selected autosizing - * data, in which case they'd better know what they're doing! - * - * The m_cid field in the protocol header is abused to carry the - * status */ - if (autosize) { - payload_size = dbr_size_n(pevext->msg.m_dataType, 0); - cas_set_header_count(pClient, 0); - } - memset ( pPayload, 0, payload_size ); - cas_set_header_cid ( pClient, ECA_GETFAIL ); - cas_commit_msg ( pClient, payload_size ); - } - else { - int cacStatus = caNetConvert ( - pevext->msg.m_dataType, pPayload, pPayload, - TRUE /* host -> net format */, item_count ); - if ( cacStatus == ECA_NORMAL ) { - ca_uint32_t data_size = - dbr_size_n(pevext->msg.m_dataType, item_count); - if (autosize) { - payload_size = data_size; - cas_set_header_count(pClient, item_count); - } - else if (payload_size > data_size) - memset( - (char *) pPayload + data_size, 0, payload_size - data_size); - } - else { - if (autosize) { - payload_size = dbr_size_n(pevext->msg.m_dataType, 0); - cas_set_header_count(pClient, 0); - } - memset ( pPayload, 0, payload_size ); - cas_set_header_cid ( pClient, cacStatus ); - } - cas_commit_msg ( pClient, payload_size ); - } - - /* - * Ensures timely response for events, but does queue - * them up like db requests when the OPI does not keep up. - */ - if ( ! eventsRemaining ) - cas_send_bs_msg ( pClient, FALSE ); - - SEND_UNLOCK ( pClient ); - - return; -} - -/* - * read_action () - */ -static int read_action ( caHdrLargeArray *mp, void *pPayloadIn, struct client *pClient ) -{ - struct channel_in_use *pciu = MPTOPCIU ( mp ); - int readAccess; - ca_uint32_t payloadSize; - void *pPayload; - int status; - int local_fl = 0; - db_field_log *pfl = NULL; - - if ( ! pciu ) { - logBadId ( pClient, mp, 0 ); - return RSRV_ERROR; - } - readAccess = asCheckGet ( pciu->asClientPVT ); - - SEND_LOCK ( pClient ); - - if ( INVALID_DB_REQ ( mp->m_dataType ) ) { - send_err ( mp, ECA_BADTYPE, pClient, RECORD_NAME ( pciu->dbch ) ); - SEND_UNLOCK ( pClient ); - return RSRV_ERROR; - } - - payloadSize = dbr_size_n ( mp->m_dataType, mp->m_count ); - status = cas_copy_in_header ( pClient, mp->m_cmmd, payloadSize, - mp->m_dataType, mp->m_count, pciu->cid, mp->m_available, &pPayload ); - if ( status != ECA_NORMAL ) { - send_err ( mp, status, pClient, - "server unable to load read response into protocol buffer PV=\"%s\" max bytes=%u", - RECORD_NAME ( pciu->dbch ), rsrvSizeofLargeBufTCP ); - SEND_UNLOCK ( pClient ); - return RSRV_OK; - } - - /* - * verify read access - */ - if ( ! readAccess ) { - status = ECA_NORDACCESS; - send_err ( mp, status, - pClient, RECORD_NAME ( pciu->dbch ) ); - SEND_UNLOCK ( pClient ); - return RSRV_OK; - } - - /* If filters are involved in a read, create field log and run filters */ - if (ellCount(&pciu->dbch->pre_chain) || ellCount(&pciu->dbch->post_chain)) { - pfl = db_create_read_log(pciu->dbch); - if (pfl) { - local_fl = 1; - pfl = dbChannelRunPreChain(pciu->dbch, pfl); - pfl = dbChannelRunPostChain(pciu->dbch, pfl); - } - } - - status = dbChannel_get ( pciu->dbch, mp->m_dataType, - pPayload, mp->m_count, pfl ); - - if (local_fl) db_delete_field_log(pfl); - - if ( status < 0 ) { - send_err ( mp, ECA_GETFAIL, pClient, RECORD_NAME ( pciu->dbch ) ); - SEND_UNLOCK ( pClient ); - return RSRV_OK; - } - - status = caNetConvert ( - mp->m_dataType, pPayload, pPayload, - TRUE /* host -> net format */, mp->m_count ); - if ( status != ECA_NORMAL ) { - send_err ( mp, status, pClient, RECORD_NAME ( pciu->dbch ) ); - SEND_UNLOCK ( pClient ); - return RSRV_OK; - } - - /* - * force string message size to be the true size rounded to even - * boundary - */ - if ( mp->m_dataType == DBR_STRING && mp->m_count == 1 ) { - char * pStr = (char *) pPayload; - size_t strcnt = epicsStrnLen( pStr, payloadSize ); - if ( strcnt < payloadSize ) { - payloadSize = ( ca_uint32_t ) ( strcnt + 1u ); - } - else { - pStr[payloadSize-1] = '\0'; - errlogPrintf ( - "caserver: read_action: detected DBR_STRING w/o nill termination " - "in response from db_get_field, pPayload = \"%s\"\n", - pStr ); - } - } - cas_commit_msg ( pClient, payloadSize ); - - SEND_UNLOCK ( pClient ); - - return RSRV_OK; -} - -/* - * read_notify_action() - */ -static int read_notify_action ( caHdrLargeArray *mp, void *pPayload, struct client *client ) -{ - struct channel_in_use *pciu; - struct event_ext evext; - - if ( INVALID_DB_REQ(mp->m_dataType) ) { - return RSRV_ERROR; - } - - pciu = MPTOPCIU ( mp ); - if ( !pciu ) { - logBadId ( client, mp, pPayload ); - return RSRV_ERROR; - } - - evext.msg = *mp; - evext.pciu = pciu; - evext.pdbev = NULL; - evext.size = dbr_size_n ( mp->m_dataType, mp->m_count ); - - /* - * Arguments to this routine organized in - * favor of the standard db event calling - * mechanism- routine(userarg, paddr). See - * events added above. - * - * Hold argument set true so the send message - * buffer is not flushed once each call. - */ - read_reply ( &evext, pciu->dbch, TRUE, NULL ); - - return RSRV_OK; -} - -/* - * write_action() - */ -static int write_action ( caHdrLargeArray *mp, - void *pPayload, struct client *client ) -{ - struct channel_in_use *pciu; - int status; - long dbStatus; - void *asWritePvt; - - pciu = MPTOPCIU(mp); - if(!pciu){ - logBadId(client, mp, pPayload); - return RSRV_ERROR; - } - - if(!rsrvCheckPut(pciu)){ - status = ECA_NOWTACCESS; - SEND_LOCK(client); - send_err( - mp, - status, - client, - RECORD_NAME ( pciu->dbch )); - SEND_UNLOCK(client); - return RSRV_OK; - } - - status = caNetConvert ( - mp->m_dataType, pPayload, pPayload, - FALSE /* net -> host format */, mp->m_count ); - if ( status != ECA_NORMAL ) { - log_header ("invalid data type", client, mp, pPayload, 0); - SEND_LOCK(client); - send_err( - mp, - status, - client, - RECORD_NAME ( pciu->dbch )); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - - asWritePvt = asTrapWriteWithData ( pciu->asClientPVT, - pciu->client->pUserName ? pciu->client->pUserName : "", - pciu->client->pHostName ? pciu->client->pHostName : "", - pciu->dbch, mp->m_dataType, mp->m_count, pPayload ); - - dbStatus = dbChannel_put( - pciu->dbch, - mp->m_dataType, - pPayload, - mp->m_count); - - asTrapWriteAfter(asWritePvt); - - if (dbStatus < 0) { - SEND_LOCK(client); - send_err( - mp, - ECA_PUTFAIL, - client, - RECORD_NAME ( pciu->dbch )); - SEND_UNLOCK(client); - } - - return RSRV_OK; -} - -/* - * host_name_action() - */ -static int host_name_action ( caHdrLargeArray *mp, void *pPayload, - struct client *client ) -{ - ca_uint32_t size; - char *pName; - char *pMalloc; - int chanCount; - - epicsMutexMustLock ( client->chanListLock ); - chanCount = - ellCount ( &client->chanList ) + - ellCount ( &client->chanPendingUpdateARList ); - epicsMutexUnlock( client->chanListLock ); - - if ( chanCount != 0 ) { - SEND_LOCK ( client ); - send_err( - mp, - ECA_INTERNAL, - client, - "attempts to use protocol to set host name " - "after creating first channel ignored by server" ); - SEND_UNLOCK ( client ); - return RSRV_OK; - } - - pName = (char *) pPayload; - size = epicsStrnLen(pName, mp->m_postsize)+1; - if (size > 512 || size > mp->m_postsize) { - log_header ( "bad (very long) host name", - client, mp, pPayload, 0 ); - SEND_LOCK(client); - send_err( - mp, - ECA_INTERNAL, - client, - "bad (very long) host name"); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - - /* - * user name will not change if there isnt enough memory - */ - pMalloc = malloc(size); - if(!pMalloc){ - log_header ( "no space in pool for new host name", - client, mp, pPayload, 0 ); - SEND_LOCK(client); - send_err( - mp, - ECA_ALLOCMEM, - client, - "no space in pool for new host name"); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - strncpy( - pMalloc, - pName, - size-1); - pMalloc[size-1]='\0'; - - pName = client->pHostName; - client->pHostName = pMalloc; - if ( pName ) { - free ( pName ); - } - - DLOG (2, ( "CAS: host_name_action for \"%s\"\n", - client->pHostName ? client->pHostName : "" ) ); - - return RSRV_OK; -} - - -/* - * client_name_action() - */ -static int client_name_action ( caHdrLargeArray *mp, void *pPayload, - struct client *client ) -{ - ca_uint32_t size; - char *pName; - char *pMalloc; - int chanCount; - - epicsMutexMustLock ( client->chanListLock ); - chanCount = - ellCount ( &client->chanList ) + - ellCount ( &client->chanPendingUpdateARList ); - epicsMutexUnlock( client->chanListLock ); - - if ( chanCount != 0 ) { - SEND_LOCK ( client ); - send_err( - mp, - ECA_INTERNAL, - client, - "attempts to use protocol to set user name " - "after creating first channel ignored by server" ); - SEND_UNLOCK ( client ); - return RSRV_OK; - } - - pName = (char *) pPayload; - size = epicsStrnLen(pName, mp->m_postsize)+1; - if (size > 512 || size > mp->m_postsize) { - log_header ("a very long user name was specified", - client, mp, pPayload, 0); - SEND_LOCK(client); - send_err( - mp, - ECA_INTERNAL, - client, - "a very long user name was specified"); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - - /* - * user name will not change if there isnt enough memory - */ - pMalloc = malloc(size); - if(!pMalloc){ - log_header ("no memory for new user name", - client, mp, pPayload, 0); - SEND_LOCK(client); - send_err( - mp, - ECA_ALLOCMEM, - client, - "no memory for new user name"); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - strncpy( - pMalloc, - pName, - size-1); - pMalloc[size-1]='\0'; - - pName = client->pUserName; - client->pUserName = pMalloc; - if ( pName ) { - free ( pName ); - } - - return RSRV_OK; -} - -/* - * casCreateChannel () - */ -static struct channel_in_use *casCreateChannel ( -struct client *client, -struct dbChannel *dbch, -unsigned cid -) -{ - static unsigned bucketID; - unsigned *pCID; - struct channel_in_use *pchannel; - int status; - - /* get block off free list if possible */ - pchannel = (struct channel_in_use *) - freeListCalloc(rsrvChanFreeList); - if (!pchannel) { - return NULL; - } - ellInit(&pchannel->eventq); - epicsTimeGetCurrent(&pchannel->time_at_creation); - pchannel->dbch = dbch; - pchannel->client = client; - /* - * bypass read only warning - */ - pCID = (unsigned *) &pchannel->cid; - *pCID = cid; - - /* - * allocate a server id and enter the channel pointer - * in the table - * - * NOTE: This detects the case where the PV id wraps - * around and we attempt to have two resources on the same id. - * The lock is applied here because on some architectures the - * ++ operator isnt atomic. - */ - LOCK_CLIENTQ; - - do { - /* - * bypass read only warning - */ - pCID = (unsigned *) &pchannel->sid; - *pCID = bucketID++; - - /* - * Verify that this id is not in use - */ - status = bucketAddItemUnsignedId ( - pCaBucket, - &pchannel->sid, - pchannel); - } while (status == S_bucket_idInUse); - - if ( status == S_bucket_success ) { - rsrvChannelCount++; - } - - UNLOCK_CLIENTQ; - - if(status!=S_bucket_success){ - freeListFree(rsrvChanFreeList, pchannel); - errMessage (status, "Unable to allocate server id"); - return NULL; - } - - epicsMutexMustLock( client->chanListLock ); - pchannel->state = rsrvCS_pendConnectResp; - ellAdd ( &client->chanList, &pchannel->node ); - epicsMutexUnlock ( client->chanListLock ); - - return pchannel; -} - -/* - * casAccessRightsCB() - * - * If access right state changes then inform the client. - * asLock is held - */ -static void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type) -{ - struct client * pclient; - struct channel_in_use * pciu; - struct event_ext * pevext; - - pciu = asGetClientPvt(ascpvt); - assert(pciu); - - pclient = pciu->client; - assert(pclient); - - if(pclient->proto==IPPROTO_UDP){ - return; - } - - switch(type) - { - case asClientCOAR: - { - const int readAccess = asCheckGet ( pciu->asClientPVT ); - unsigned sigReq = 0; - - epicsMutexMustLock ( pclient->chanListLock ); - if ( pciu->state == rsrvCS_pendConnectResp ) { - ellDelete ( &pclient->chanList, &pciu->node ); - pciu->state = rsrvCS_pendConnectRespUpdatePendAR; - ellAdd ( &pclient->chanPendingUpdateARList, &pciu->node ); - sigReq = 1; - } - else if ( pciu->state == rsrvCS_inService ) { - ellDelete ( &pclient->chanList, &pciu->node ); - pciu->state = rsrvCS_inServiceUpdatePendAR; - ellAdd ( &pclient->chanPendingUpdateARList, &pciu->node ); - sigReq = 1; - } - epicsMutexUnlock ( pclient->chanListLock ); - - /* - * Update all event call backs - */ - epicsMutexMustLock(pclient->eventqLock); - for (pevext = (struct event_ext *) ellFirst(&pciu->eventq); - pevext; - pevext = (struct event_ext *) ellNext(&pevext->node)){ - - if ( pevext->pdbev ) { - if ( readAccess ){ - db_event_enable ( pevext->pdbev ); - db_post_single_event ( pevext->pdbev ); - } - else { - db_post_single_event ( pevext->pdbev ); - db_event_disable ( pevext->pdbev ); - } - } - } - epicsMutexUnlock(pclient->eventqLock); - - if ( sigReq ) { - db_post_extra_labor( pclient->evuser ); - } - - break; - } - default: - break; - } -} - -/* - * access_rights_reply() - */ -static void access_rights_reply ( struct channel_in_use * pciu ) -{ - unsigned ar; - int status; - - assert ( pciu->client->proto!=IPPROTO_UDP ); - - ar = 0; /* none */ - if ( asCheckGet ( pciu->asClientPVT ) ) { - ar |= CA_PROTO_ACCESS_RIGHT_READ; - } - if ( rsrvCheckPut ( pciu ) ) { - ar |= CA_PROTO_ACCESS_RIGHT_WRITE; - } - - SEND_LOCK ( pciu->client ); - status = cas_copy_in_header ( - pciu->client, CA_PROTO_ACCESS_RIGHTS, 0, - 0, 0, pciu->cid, ar, 0 ); - /* - * OK to just ignore the request if the connection drops - */ - if ( status == ECA_NORMAL ) { - cas_commit_msg ( pciu->client, 0u ); - } - SEND_UNLOCK ( pciu->client ); -} - -/* - * claim_ciu_reply() - */ -static void claim_ciu_reply ( struct channel_in_use * pciu ) -{ - int status; - ca_uint32_t nElem; - long dbElem; - - access_rights_reply ( pciu ); - - SEND_LOCK ( pciu->client ); - dbElem = dbChannelFinalElements(pciu->dbch); - if ( dbElem < 0 ) { - nElem = 0; - } - else { - if ( ! CA_V49 ( pciu->client->minor_version_number ) ) { - if ( dbElem >= 0xffff ) { - nElem = 0xfffe; - } - else { - nElem = (ca_uint32_t) dbElem; - } - } - else { - nElem = (ca_uint32_t) dbElem; - } - } - status = cas_copy_in_header ( - pciu->client, CA_PROTO_CREATE_CHAN, 0u, - dbChannelFinalCAType(pciu->dbch), nElem, pciu->cid, - pciu->sid, NULL ); - if ( status == ECA_NORMAL ) { - cas_commit_msg ( pciu->client, 0u ); - } - SEND_UNLOCK(pciu->client); -} - -/* - * claim_ciu_action() - */ -static int claim_ciu_action ( caHdrLargeArray *mp, - void *pPayload, client *client ) -{ - int status; - struct channel_in_use *pciu; - struct dbChannel *dbch; - char *pName = (char *) pPayload; - - /* - * The available field is used (abused) - * here to communicate the miner version number - * starting with CA 4.1. The field was set to zero - * prior to 4.1 - */ - client->minor_version_number = mp->m_available; - - if (!CA_V44(client->minor_version_number)) - return RSRV_ERROR; /* shouldn't actually get here due to VSUPPORTED test in camessage() */ - - /* - * check the sanity of the message - */ - if (mp->m_postsize<=1) { - log_header ( "empty PV name in UDP search request?", - client, mp, pPayload, 0 ); - return RSRV_OK; - } - pName[mp->m_postsize-1] = '\0'; - - dbch = dbChannel_create (pName); - if (!dbch) { - SEND_LOCK(client); - status = cas_copy_in_header ( client, - CA_PROTO_CREATE_CH_FAIL, 0, 0, 0, mp->m_cid, 0, NULL ); - if (status == ECA_NORMAL) - cas_commit_msg ( client, 0u ); - SEND_UNLOCK(client); - return RSRV_OK; - } - - DLOG ( 2, ("CAS: claim_ciu_action found '%s', type %d, count %d\n", - pName, dbChannelCAType(dbch), dbChannelElements(dbch)) ); - - pciu = casCreateChannel ( - client, - dbch, - mp->m_cid); - if (!pciu) { - log_header ("no memory to create new channel", - client, mp, pPayload, 0); - SEND_LOCK(client); - send_err(mp, - ECA_ALLOCMEM, - client, - RECORD_NAME(dbch)); - SEND_UNLOCK(client); - dbChannelDelete(dbch); - return RSRV_ERROR; - } - - /* - * set up access security for this channel - */ - status = asAddClient( - &pciu->asClientPVT, - asDbGetMemberPvt(pciu->dbch), - asDbGetAsl(pciu->dbch), - client->pUserName ? client->pUserName : "", - client->pHostName ? client->pHostName : ""); - if(status != 0 && status != S_asLib_asNotActive){ - log_header ("No room for security table", - client, mp, pPayload, 0); - SEND_LOCK(client); - send_err(mp, ECA_ALLOCMEM, client, "No room for security table"); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - - /* - * store ptr to channel in use block - * in access security private - */ - asPutClientPvt(pciu->asClientPVT, pciu); - - /* - * register for asynch updates of access rights changes - */ - status = asRegisterClientCallback( - pciu->asClientPVT, - casAccessRightsCB); - if ( status == S_asLib_asNotActive ) { - epicsMutexMustLock ( client->chanListLock ); - pciu->state = rsrvCS_inService; - epicsMutexUnlock ( client->chanListLock ); - /* - * force the initial AR update followed by claim response - */ - claim_ciu_reply ( pciu ); - } - else if (status!=0) { - log_header ("No room for access security state change subscription", - client, mp, pPayload, 0); - SEND_LOCK(client); - send_err(mp, ECA_ALLOCMEM, client, - "No room for access security state change subscription"); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - return RSRV_OK; -} - -/* - * write_notify_put_callback() - * - * (called by the db call back thread) - */ - LOCAL int write_notify_put_callback(processNotify *ppn,notifyPutType type) - { - struct channel_in_use * pciu = (struct channel_in_use *) ppn->usrPvt; - struct rsrv_put_notify *pNotify; - - if(ppn->status==notifyCanceled) return 0; - /* - * No locking in this method because only a dbNotifyCancel could interrupt - * and it does not return until cancel is done. - */ - assert(pciu); - assert(pciu->pPutNotify); - pNotify = pciu->pPutNotify; - return db_put_process(ppn,type, - pNotify->dbrType,pNotify->pbuffer,pNotify->nRequest); - } - - /* - * write_notify_done_callback() - * - * (called by the db call back thread) - */ - LOCAL void write_notify_done_callback(processNotify *ppn) -{ - struct channel_in_use * pciu = (struct channel_in_use *) ppn->usrPvt; - struct client * pClient; - - /* - * independent lock used here in order to - * avoid any possibility of blocking - * the database (or indirectly blocking - * one client on another client). - */ - assert(pciu); - assert(pciu->pPutNotify); - pClient = pciu->client; - epicsMutexMustLock(pClient->putNotifyLock); - - if ( ! pciu->pPutNotify->busy || pciu->pPutNotify->onExtraLaborQueue ) { - epicsMutexUnlock(pClient->putNotifyLock); - errlogPrintf("Double DB put notify call back!!\n"); - return; - } - - ellAdd(&pClient->putNotifyQue, &pciu->pPutNotify->node); - pciu->pPutNotify->onExtraLaborQueue = TRUE; - - epicsMutexUnlock(pClient->putNotifyLock); - - /* - * offload the labor for this to the - * event task so that we never block - * the db or another client. - */ - db_post_extra_labor(pClient->evuser); -} - -/* - * write_notify_reply() - * (called by the CA server event task via the extra labor interface) - */ -static void write_notify_reply ( struct client * pClient ) -{ - while(TRUE){ - caHdrLargeArray msgtmp; - void * asWritePvtTmp; - ca_uint32_t status; - int localStatus; - - /* - * independent lock used here in order to - * avoid any possibility of blocking - * the database (or indirectly blocking - * one client on another client). - */ - epicsMutexMustLock(pClient->putNotifyLock); - { - RSRVPUTNOTIFY * ppnb = (RSRVPUTNOTIFY *) - ellGet ( &pClient->putNotifyQue ); - if ( ! ppnb ) { - epicsMutexUnlock(pClient->putNotifyLock); - break; - } - /* - * - * Map from DB status to CA status - * - */ - if ( ppnb->dbPutNotify.status != notifyOK ) { - status = ECA_PUTFAIL; - } - else{ - status = ECA_NORMAL; - } - msgtmp = ppnb->msg; - asWritePvtTmp = ppnb->asWritePvt; - ppnb->asWritePvt = 0; - ppnb->onExtraLaborQueue = FALSE; - ppnb->busy = FALSE; - } - epicsMutexUnlock(pClient->putNotifyLock); - - asTrapWriteAfter ( asWritePvtTmp ); - - /* - * the channel id field is being abused to carry - * status here - */ - SEND_LOCK(pClient); - localStatus = cas_copy_in_header ( - pClient, CA_PROTO_WRITE_NOTIFY, - 0u, msgtmp.m_dataType, msgtmp.m_count, status, - msgtmp.m_available, 0 ); - if ( localStatus != ECA_NORMAL ) { - /* - * inability to aquire buffer space - * Indicates corruption - */ - errlogPrintf("CA server corrupted - put call back(s) discarded\n"); - SEND_UNLOCK ( pClient ); - break; - } - - /* commit the message */ - cas_commit_msg ( pClient, 0u ); - SEND_UNLOCK ( pClient ); - } - - /* - * wakeup the TCP thread if it is waiting for a cb to complete - */ - epicsEventSignal ( pClient->blockSem ); -} - -/* - * sendAllUpdateAS() - */ -static void sendAllUpdateAS ( struct client *client ) -{ - struct channel_in_use *pciu; - - epicsMutexMustLock ( client->chanListLock ); - - pciu = ( struct channel_in_use * ) - ellGet ( & client->chanPendingUpdateARList ); - while ( pciu ) { - if ( pciu->state == rsrvCS_pendConnectRespUpdatePendAR ) { - claim_ciu_reply ( pciu ); - } - else if ( pciu->state == rsrvCS_inServiceUpdatePendAR ) { - access_rights_reply ( pciu ); - } - else if ( pciu->state == rsrvCS_shutdown ) { - /* no-op */ - } - else { - errlogPrintf ( - "%s at %d: corrupt channel state detected durring AR update\n", - __FILE__, __LINE__); - } - pciu->state = rsrvCS_inService; - ellAdd ( & client->chanList, & pciu->node ); - pciu = ( struct channel_in_use * ) - ellGet ( & client->chanPendingUpdateARList ); - } - - epicsMutexUnlock( client->chanListLock ); -} - -/* - * rsrv_extra_labor() - * (called by the CA server event task via the extra labor interface) - */ -void rsrv_extra_labor ( void * pArg ) -{ - struct client * pClient = pArg; - write_notify_reply ( pClient ); - sendAllUpdateAS ( pClient ); - cas_send_bs_msg ( pClient, TRUE ); -} - -/* - * putNotifyErrorReply - */ -static void putNotifyErrorReply ( struct client *client, caHdrLargeArray *mp, int statusCA ) -{ - int status; - - SEND_LOCK ( client ); - /* - * the cid field abused to contain status - * during put cb replies - */ - status = cas_copy_in_header ( client, CA_PROTO_WRITE_NOTIFY, - 0u, mp->m_dataType, mp->m_count, statusCA, - mp->m_available, 0 ); - if ( status != ECA_NORMAL ) { - SEND_UNLOCK ( client ); - errlogPrintf ("%s at %d: should always get sufficent space for put notify error reply\n", - __FILE__, __LINE__); - return; - } - cas_commit_msg ( client, 0u ); - SEND_UNLOCK ( client ); -} - -void initializePutNotifyFreeList (void) -{ - if ( ! rsrvPutNotifyFreeList ) { - freeListInitPvt ( &rsrvPutNotifyFreeList, - sizeof(struct rsrv_put_notify), 512 ); - assert ( rsrvPutNotifyFreeList ); - } -} - -static struct rsrv_put_notify * - rsrvAllocPutNotify ( struct channel_in_use * pciu ) -{ - struct rsrv_put_notify *pNotify; - - if ( rsrvPutNotifyFreeList ) { - pNotify = (RSRVPUTNOTIFY *) - freeListCalloc ( rsrvPutNotifyFreeList ); - if ( pNotify ) { - pNotify->pbuffer = &pNotify->dbrScalarValue; - pNotify->valueSize = - sizeof (pNotify->dbrScalarValue); - pNotify->dbPutNotify.usrPvt = pciu; - pNotify->dbPutNotify.chan = pciu->dbch; - pNotify->dbPutNotify.putCallback = - write_notify_put_callback; - pNotify->dbPutNotify.doneCallback = - write_notify_done_callback; - pNotify->dbPutNotify.requestType = putProcessRequest; - } - } - else { - pNotify = NULL; - } - return pNotify; -} - -static int rsrvExpandPutNotify ( - struct rsrv_put_notify * pNotify, unsigned sizeNeeded ) -{ - int booleanStatus; - - if ( sizeNeeded > pNotify->valueSize ) { - /* - * try to use the union embeded in the free list - * item, but allocate a random sized block if they - * writing a vector. - */ - if ( pNotify->valueSize > - sizeof (pNotify->dbrScalarValue) ) { - free ( pNotify->pbuffer ); - } - pNotify->pbuffer = casCalloc(1,sizeNeeded); - if ( pNotify->pbuffer ) { - pNotify->valueSize = sizeNeeded; - booleanStatus = TRUE; - } - else { - /* - * revert back to the embedded union - */ - pNotify->pbuffer = - &pNotify->dbrScalarValue; - pNotify->valueSize = - sizeof (pNotify->dbrScalarValue); - booleanStatus = FALSE; - } - } - else { - booleanStatus = TRUE; - } - - return booleanStatus; -} - -unsigned rsrvSizeOfPutNotify ( struct rsrv_put_notify *pNotify ) -{ - unsigned size = sizeof ( *pNotify ); - if ( pNotify ) { - if ( pNotify->valueSize > - sizeof ( pNotify->dbrScalarValue ) ) { - size += pNotify->valueSize; - } - } - return size; -} - -void rsrvFreePutNotify ( client *pClient, - struct rsrv_put_notify *pNotify ) -{ - if ( pNotify ) { - char busyTmp; - void * asWritePvtTmp = 0; - - epicsMutexMustLock ( pClient->putNotifyLock ); - busyTmp = pNotify->busy; - epicsMutexUnlock ( pClient->putNotifyLock ); - - /* - * if any possiblity that the put notify is - * outstanding then cancel it - */ - if ( busyTmp ) { - dbNotifyCancel ( &pNotify->dbPutNotify ); - } - - epicsMutexMustLock ( pClient->putNotifyLock ); - if ( pNotify->onExtraLaborQueue ) { - ellDelete ( &pClient->putNotifyQue, - &pNotify->node ); - } - busyTmp = pNotify->busy; - asWritePvtTmp = pNotify->asWritePvt; - pNotify->asWritePvt = 0; - epicsMutexUnlock ( pClient->putNotifyLock ); - - if ( busyTmp ) { - asTrapWriteAfter ( asWritePvtTmp ); - } - - if ( pNotify->valueSize > - sizeof(pNotify->dbrScalarValue) ) { - free ( pNotify->pbuffer ); - } - freeListFree ( rsrvPutNotifyFreeList, pNotify ); - } -} - -/* - * write_notify_action() - */ -static int write_notify_action ( caHdrLargeArray *mp, void *pPayload, - struct client *client ) -{ - unsigned size; - int status; - struct channel_in_use *pciu; - - pciu = MPTOPCIU(mp); - if(!pciu){ - logBadId ( client, mp, pPayload ); - return RSRV_ERROR; - } - - if (mp->m_dataType > LAST_BUFFER_TYPE) { - log_header ("bad put notify data type", client, mp, pPayload, 0); - putNotifyErrorReply (client, mp, ECA_BADTYPE); - return RSRV_ERROR; - } - - if(!rsrvCheckPut(pciu)){ - putNotifyErrorReply (client, mp, ECA_NOWTACCESS); - return RSRV_OK; - } - - size = dbr_size_n (mp->m_dataType, mp->m_count); - - if ( pciu->pPutNotify ) { - - /* - * serialize concurrent put notifies - */ - epicsMutexMustLock(client->putNotifyLock); - while(pciu->pPutNotify->busy){ - epicsMutexUnlock(client->putNotifyLock); - status = epicsEventWaitWithTimeout(client->blockSem,60.0); - if ( status != epicsEventWaitOK ) { - char busyTmp; - void * asWritePvtTmp = 0; - - epicsMutexMustLock(client->putNotifyLock); - busyTmp = pciu->pPutNotify->busy; - epicsMutexUnlock(client->putNotifyLock); - - /* - * if any possibility of put notify still running - * then cancel it - */ - if ( busyTmp ) { - dbNotifyCancel(&pciu->pPutNotify->dbPutNotify); - } - epicsMutexMustLock(client->putNotifyLock); - busyTmp = pciu->pPutNotify->busy; - if ( busyTmp ) { - if ( pciu->pPutNotify->onExtraLaborQueue ) { - ellDelete ( &client->putNotifyQue, - &pciu->pPutNotify->node ); - } - pciu->pPutNotify->busy = FALSE; - asWritePvtTmp = pciu->pPutNotify->asWritePvt; - pciu->pPutNotify->asWritePvt = 0; - } - epicsMutexUnlock(client->putNotifyLock); - - if ( busyTmp ) { - log_header("put call back time out", client, - &pciu->pPutNotify->msg, pciu->pPutNotify->pbuffer, 0); - asTrapWriteAfter ( asWritePvtTmp ); - putNotifyErrorReply (client, &pciu->pPutNotify->msg, ECA_PUTCBINPROG); - } - } - epicsMutexMustLock(client->putNotifyLock); - } - epicsMutexUnlock(client->putNotifyLock); - } - else { - pciu->pPutNotify = rsrvAllocPutNotify ( pciu ); - if ( ! pciu->pPutNotify ) { - /* - * send error and go to next request - * if there isnt enough memory left - */ - log_header ( "no memory to initiate put notify", - client, mp, pPayload, 0 ); - putNotifyErrorReply (client, mp, ECA_ALLOCMEM); - return RSRV_ERROR; - } - } - - if ( ! rsrvExpandPutNotify ( pciu->pPutNotify, size ) ) { - log_header ( "no memory to initiate vector put notify", - client, mp, pPayload, 0 ); - putNotifyErrorReply ( client, mp, ECA_ALLOCMEM ); - return RSRV_ERROR; - } - - pciu->pPutNotify->busy = TRUE; - pciu->pPutNotify->onExtraLaborQueue = FALSE; - pciu->pPutNotify->msg = *mp; - pciu->pPutNotify->nRequest = mp->m_count; - - status = caNetConvert ( - mp->m_dataType, pPayload, pciu->pPutNotify->pbuffer, - FALSE /* net -> host format */, mp->m_count ); - if ( status != ECA_NORMAL ) { - log_header ("invalid data type", client, mp, pPayload, 0); - putNotifyErrorReply ( client, mp, status ); - return RSRV_ERROR; - } - - pciu->pPutNotify->dbrType = mp->m_dataType; - - pciu->pPutNotify->asWritePvt = asTrapWriteWithData ( - pciu->asClientPVT, - pciu->client->pUserName ? pciu->client->pUserName : "", - pciu->client->pHostName ? pciu->client->pHostName : "", - pciu->dbch, mp->m_dataType, mp->m_count, - pciu->pPutNotify->pbuffer ); - - dbProcessNotify(&pciu->pPutNotify->dbPutNotify); - - return RSRV_OK; -} - -/* - * - * event_add_action() - * - */ -static int event_add_action (caHdrLargeArray *mp, void *pPayload, struct client *client) -{ - struct mon_info *pmi = (struct mon_info *) pPayload; - int spaceAvailOnFreeList; - struct channel_in_use *pciu; - struct event_ext *pevext; - - if ( INVALID_DB_REQ(mp->m_dataType) ) { - return RSRV_ERROR; - } - - pciu = MPTOPCIU ( mp ); - if ( ! pciu ) { - logBadId ( client, mp, pPayload ); - return RSRV_ERROR; - } - - /* - * stop further use of server if memory becomes scarce - */ - spaceAvailOnFreeList = freeListItemsAvail ( rsrvEventFreeList ) > 0; - if ( osiSufficentSpaceInPool(sizeof(*pevext)) || spaceAvailOnFreeList ) { - pevext = (struct event_ext *) freeListCalloc (rsrvEventFreeList); - } - else { - pevext = 0; - } - - if (!pevext) { - log_header ("no memory to add subscription", - client, mp, pPayload, 0); - SEND_LOCK(client); - send_err( - mp, - ECA_ALLOCMEM, - client, - RECORD_NAME(pciu->dbch)); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - - pevext->msg = *mp; - pevext->pciu = pciu; - pevext->size = dbr_size_n(mp->m_dataType, mp->m_count); - pevext->mask = ntohs ( pmi->m_mask ); - - epicsMutexMustLock(client->eventqLock); - ellAdd( &pciu->eventq, &pevext->node); - epicsMutexUnlock(client->eventqLock); - - pevext->pdbev = db_add_event (client->evuser, pciu->dbch, - read_reply, pevext, pevext->mask); - if (pevext->pdbev == NULL) { - log_header ("no memory to add subscription to db", - client, mp, pPayload, 0); - SEND_LOCK(client); - send_err (mp, ECA_ALLOCMEM, client, - "subscription install into record %s failed", - RECORD_NAME(pciu->dbch)); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - - /* - * always send it once at event add - */ - /* - * if the client program issues many monitors - * in a row then I recv when the send side - * of the socket would block. This prevents - * a application program initiated deadlock. - * - * However when I am reconnecting I reissue - * the monitors and I could get deadlocked. - * The client is blocked sending and the server - * task for the client is blocked sending in - * this case. I cant check the recv part of the - * socket in the client since I am still handling an - * outstanding recv ( they must be processed in order). - * I handle this problem in the server by using - * post_single_event() below instead of calling - * read_reply() in this module. This is a complete - * fix since a monitor setup is the only request - * soliciting a reply in the client which is - * issued from inside of service.c (from inside - * of the part of the ca client which services - * messages sent by the server). - */ - - DLOG ( 3, ("event_add_action: db_post_single_event (0x%X)\n", - pevext->pdbev) ); - db_post_single_event(pevext->pdbev); - - /* - * enable future labor if we have read access - */ - if(asCheckGet(pciu->asClientPVT)){ - db_event_enable(pevext->pdbev); - } - else { - DLOG ( 3, ( "Disable event because cannot read\n" ) ); - } - - return RSRV_OK; -} - -/* - * clear_channel_reply() - */ -static int clear_channel_reply ( caHdrLargeArray *mp, - void *pPayload, struct client *client ) -{ - struct event_ext *pevext; - struct channel_in_use *pciu; - int status; - - /* - * - * Verify the channel - * - */ - pciu = MPTOPCIU(mp); - if(pciu?pciu->client!=client:TRUE){ - logBadId ( client, mp, pPayload ); - return RSRV_ERROR; - } - - rsrvFreePutNotify ( client, pciu->pPutNotify ); - - while (TRUE){ - epicsMutexMustLock(client->eventqLock); - pevext = (struct event_ext *) ellGet(&pciu->eventq); - epicsMutexUnlock(client->eventqLock); - - if(!pevext){ - break; - } - - if (pevext->pdbev) { - db_cancel_event (pevext->pdbev); - } - freeListFree(rsrvEventFreeList, pevext); - } - - db_flush_extra_labor_event ( client->evuser ); - - /* - * send delete confirmed message - */ - SEND_LOCK(client); - status = cas_copy_in_header ( client, CA_PROTO_CLEAR_CHANNEL, - 0u, mp->m_dataType, mp->m_count, mp->m_cid, - mp->m_available, NULL ); - if ( status != ECA_NORMAL ) { - SEND_UNLOCK(client); - return RSRV_ERROR; - } - - cas_commit_msg ( client, 0u ); - SEND_UNLOCK(client); - - /* - * remove from access control list - */ - status = asRemoveClient(&pciu->asClientPVT); - if(status != 0 && status != S_asLib_asNotActive){ - errMessage(status, RECORD_NAME(pciu->dbch)); - return RSRV_ERROR; - } - - epicsMutexMustLock ( client->chanListLock ); - if ( pciu->state == rsrvCS_inService || - pciu->state == rsrvCS_pendConnectResp ) { - ellDelete ( &client->chanList, &pciu->node ); - pciu->state = rsrvCS_shutdown; - } - else if ( pciu->state == rsrvCS_inServiceUpdatePendAR || - pciu->state == rsrvCS_pendConnectRespUpdatePendAR ) { - ellDelete ( &client->chanPendingUpdateARList, &pciu->node ); - pciu->state = rsrvCS_shutdown; - } - else if ( pciu->state == rsrvCS_shutdown ) { - /* no-op */ - } - else { - epicsMutexUnlock( client->chanListLock ); - SEND_LOCK(client); - send_err(mp, ECA_INTERNAL, client, - "channel was in strange state or corrupted during cleanup"); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - epicsMutexUnlock( client->chanListLock ); - - LOCK_CLIENTQ; - status = bucketRemoveItemUnsignedId (pCaBucket, &pciu->sid); - if(status != S_bucket_success){ - UNLOCK_CLIENTQ; - errMessage (status, "Bad resource id during channel clear"); - logBadId ( client, mp, pPayload ); - return RSRV_ERROR; - } - rsrvChannelCount--; - UNLOCK_CLIENTQ; - - dbChannelDelete(pciu->dbch); - freeListFree(rsrvChanFreeList, pciu); - - return RSRV_OK; -} - -/* - * - * event_cancel_reply() - * - * - * Much more efficient now since the event blocks hang off the channel in use - * blocks not all together off the client block. - */ -static int event_cancel_reply ( caHdrLargeArray *mp, void *pPayload, struct client *client ) -{ - struct channel_in_use *pciu; - struct event_ext *pevext; - int status; - - /* - * - * Verify the channel - * - */ - pciu = MPTOPCIU(mp); - if (pciu?pciu->client!=client:TRUE) { - logBadId ( client, mp, pPayload ); - return RSRV_ERROR; - } - - /* - * search events on this channel for a match - * (there are usually very few monitors per channel) - */ - epicsMutexMustLock(client->eventqLock); - for (pevext = (struct event_ext *) ellFirst(&pciu->eventq); - pevext; pevext = (struct event_ext *) ellNext(&pevext->node)){ - - if (pevext->msg.m_available == mp->m_available) { - ellDelete(&pciu->eventq, &pevext->node); - break; - } - } - epicsMutexUnlock(client->eventqLock); - - /* - * Not Found- return an exception event - */ - if(!pevext){ - SEND_LOCK(client); - send_err(mp, ECA_BADMONID, client, RECORD_NAME(pciu->dbch)); - SEND_UNLOCK(client); - return RSRV_ERROR; - } - - /* - * cancel monitor activity in progress - */ - if (pevext->pdbev) { - db_cancel_event (pevext->pdbev); - } - - /* - * send delete confirmed message - */ - SEND_LOCK(client); - - status = cas_copy_in_header ( client, pevext->msg.m_cmmd, - 0u, pevext->msg.m_dataType, pevext->msg.m_count, pevext->msg.m_cid, - pevext->msg.m_available, NULL ); - if ( status != ECA_NORMAL ) { - SEND_UNLOCK(client); - return RSRV_ERROR; - } - cas_commit_msg ( client, 0 ); - SEND_UNLOCK(client); - - freeListFree (rsrvEventFreeList, pevext); - - return RSRV_OK; -} - -/* - * read_sync_reply() - */ -static int read_sync_reply ( caHdrLargeArray *mp, void *pPayload, struct client *client ) -{ - int status; - SEND_LOCK(client); - status = cas_copy_in_header ( client, mp->m_cmmd, - 0u, mp->m_dataType, mp->m_count, mp->m_cid, - mp->m_available, NULL ); - if ( status != ECA_NORMAL ) { - SEND_UNLOCK(client); - return RSRV_ERROR; - } - cas_commit_msg ( client, 0 ); - SEND_UNLOCK(client); - return RSRV_OK; -} - -/* - * search_fail_reply() - * - * Only when requested by the client - * send search failed reply - */ -static void search_fail_reply ( caHdrLargeArray *mp, void *pPayload, struct client *client) -{ - int status; - SEND_LOCK ( client ); - status = cas_copy_in_header ( client, CA_PROTO_NOT_FOUND, - 0u, mp->m_dataType, mp->m_count, mp->m_cid, mp->m_available, NULL ); - if ( status != ECA_NORMAL ) { - SEND_UNLOCK ( client ); - errlogPrintf ( "%s at %d: should always get sufficent space for search fail reply?\n", - __FILE__, __LINE__ ); - return; - } - cas_commit_msg ( client, 0 ); - SEND_UNLOCK ( client ); -} - -/* - * udp_version_action() - */ -static int udp_version_action ( caHdrLargeArray *mp, void *pPayload, struct client *client ) -{ - client->minor_version_number = mp->m_count; - - if (!CA_VSUPPORTED(mp->m_count)) { - DLOG ( 2, ( "CAS: Ignore version from unsupported client %u\n", mp->m_count ) ); - return RSRV_ERROR; - } - - if ( CA_V411 ( mp->m_count ) ) { - client->seqNoOfReq = mp->m_cid; - } - else { - client->seqNoOfReq = 0; - } - return RSRV_OK; -} - -/* - * rsrv_version_reply() - */ -int rsrv_version_reply ( struct client *client ) -{ - int status; - SEND_LOCK ( client ); - /* - * sequence number is specified zero when we copy in the - * header because we dont know it until we receive a datagram - * from the client - */ - status = cas_copy_in_header ( client, CA_PROTO_VERSION, - 0, 0, CA_MINOR_PROTOCOL_REVISION, - 0, 0, 0 ); - if ( status != ECA_NORMAL ) { - SEND_UNLOCK ( client ); - return RSRV_ERROR; - } - cas_commit_msg ( client, 0 ); - SEND_UNLOCK ( client ); - return RSRV_OK; -} - -/* - * search_reply_udp () - */ -static int search_reply_udp ( caHdrLargeArray *mp, void *pPayload, struct client *client ) -{ - ca_uint16_t *pMinorVersion; - char *pName = (char *) pPayload; - int status; - unsigned sid; - ca_uint16_t count; - ca_uint16_t type; - int spaceAvailOnFreeList; - size_t spaceNeeded; - size_t reasonableMonitorSpace = 10; - - if (!CA_VSUPPORTED(mp->m_count)) { - DLOG ( 2, ( "CAS: Ignore search from unsupported client %u\n", mp->m_count ) ); - return RSRV_ERROR; - } - - /* - * check the sanity of the message - */ - if (mp->m_postsize<=1) { - log_header ("empty PV name in UDP search request?", - client, mp, pPayload, 0); - return RSRV_OK; - } - pName[mp->m_postsize-1] = '\0'; - - /* Exit quickly if channel not on this node */ - if (dbChannelTest(pName)) { - DLOG ( 2, ( "CAS: Lookup for channel \"%s\" failed\n", pPayLoad ) ); - return RSRV_OK; - } - - /* - * stop further use of server if memory becomes scarce - */ - spaceAvailOnFreeList = freeListItemsAvail ( rsrvChanFreeList ) > 0 - && freeListItemsAvail ( rsrvEventFreeList ) > reasonableMonitorSpace; - spaceNeeded = sizeof (struct channel_in_use) + - reasonableMonitorSpace * sizeof (struct event_ext); - if ( ! ( osiSufficentSpaceInPool(spaceNeeded) || spaceAvailOnFreeList ) ) { - return RSRV_ERROR; - } - - /* - * starting with V4.4 the count field is used (abused) - * to store the minor version number of the client. - * - * New versions dont alloc the channel in response - * to a search request. - * For these, allocation has been moved to claim_ciu_action(). - * - * m_count, m_cid are already in host format... - */ - if (CA_V44(mp->m_count)) { - sid = ~0U; - count = 0; - type = ca_server_port; - } - else { - /* shouldn't actually get here due to VSUPPORTED test */ - return RSRV_ERROR; - } - - SEND_LOCK ( client ); - status = cas_copy_in_header ( client, CA_PROTO_SEARCH, - sizeof(*pMinorVersion), type, count, - sid, mp->m_available, - ( void * ) &pMinorVersion ); - if ( status != ECA_NORMAL ) { - SEND_UNLOCK ( client ); - return RSRV_ERROR; - } - - /* - * Starting with CA V4.1 the minor version number - * is appended to the end of each search reply. - * This value is ignored by earlier clients. - */ - *pMinorVersion = htons ( CA_MINOR_PROTOCOL_REVISION ); - - cas_commit_msg ( client, sizeof ( *pMinorVersion ) ); - SEND_UNLOCK ( client ); - - return RSRV_OK; -} - -/* - * search_reply_tcp () - */ -static int search_reply_tcp ( - caHdrLargeArray *mp, void *pPayload, struct client *client ) -{ - char *pName = (char *) pPayload; - int status; - int spaceAvailOnFreeList; - size_t spaceNeeded; - size_t reasonableMonitorSpace = 10; - - if (!CA_VSUPPORTED(mp->m_count)) { - DLOG ( 2, ( "CAS: Ignore search from unsupported client %u\n", mp->m_count ) ); - return RSRV_ERROR; - } - - /* - * check the sanity of the message - */ - if (mp->m_postsize<=1) { - log_header ("empty PV name in UDP search request?", - client, mp, pPayload, 0); - return RSRV_OK; - } - pName[mp->m_postsize-1] = '\0'; - - /* Exit quickly if channel not on this node */ - if (dbChannelTest(pName)) { - DLOG ( 2, ( "CAS: Lookup for channel \"%s\" failed\n", pPayLoad ) ); - if (mp->m_dataType == DOREPLY) - search_fail_reply ( mp, pPayload, client ); - return RSRV_OK; - } - - /* - * stop further use of server if memory becomes scarse - */ - spaceAvailOnFreeList = freeListItemsAvail ( rsrvChanFreeList ) > 0 - && freeListItemsAvail ( rsrvEventFreeList ) > reasonableMonitorSpace; - spaceNeeded = sizeof (struct channel_in_use) + - reasonableMonitorSpace * sizeof (struct event_ext); - if ( ! ( osiSufficentSpaceInPool(spaceNeeded) || spaceAvailOnFreeList ) ) { - SEND_LOCK(client); - send_err ( mp, ECA_ALLOCMEM, client, "Server memory exhausted" ); - SEND_UNLOCK(client); - return RSRV_OK; - } - - SEND_LOCK ( client ); - status = cas_copy_in_header ( client, CA_PROTO_SEARCH, - 0, ca_server_port, 0, ~0U, mp->m_available, 0 ); - if ( status != ECA_NORMAL ) { - SEND_UNLOCK ( client ); - return RSRV_ERROR; - } - - cas_commit_msg ( client, 0 ); - SEND_UNLOCK ( client ); - - return RSRV_OK; -} - -typedef int (*pProtoStubTCP) (caHdrLargeArray *mp, void *pPayload, struct client *client); - -/* - * TCP protocol jump table - */ -static const pProtoStubTCP tcpJumpTable[] = -{ - tcp_version_action, - event_add_action, - event_cancel_reply, - read_action, - write_action, - bad_tcp_cmd_action, - search_reply_tcp, - bad_tcp_cmd_action, - events_off_action, - events_on_action, - read_sync_reply, - bad_tcp_cmd_action, - clear_channel_reply, - bad_tcp_cmd_action, - bad_tcp_cmd_action, - read_notify_action, - bad_tcp_cmd_action, - bad_tcp_cmd_action, - claim_ciu_action, - write_notify_action, - client_name_action, - host_name_action, - bad_tcp_cmd_action, - tcp_echo_action, - bad_tcp_cmd_action, - bad_tcp_cmd_action, - bad_tcp_cmd_action, - bad_tcp_cmd_action -}; - -/* - * UDP protocol jump table - */ -typedef int (*pProtoStubUDP) (caHdrLargeArray *mp, void *pPayload, struct client *client); -static const pProtoStubUDP udpJumpTable[] = -{ - udp_version_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - search_reply_udp, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action, - bad_udp_cmd_action -}; - -/* - * CAMESSAGE() - */ -int camessage ( struct client *client ) -{ - unsigned nmsg = 0; - unsigned msgsize; - unsigned bytes_left; - int status = RSRV_ERROR; - - assert(pCaBucket); - - /* drain remnents of large messages that will not fit */ - if ( client->recvBytesToDrain ) { - if ( client->recvBytesToDrain >= client->recv.cnt ) { - client->recvBytesToDrain -= client->recv.cnt; - client->recv.stk = client->recv.cnt; - return RSRV_OK; - } - else { - client->recv.stk += client->recvBytesToDrain; - client->recvBytesToDrain = 0u; - } - } - - DLOG ( 2, ( "CAS: Parsing %d(decimal) bytes\n", recv->cnt ) ); - - while ( 1 ) - { - caHdrLargeArray msg; - caHdr *mp; - void *pBody; - - /* wait for at least a complete caHdr */ - bytes_left = client->recv.cnt - client->recv.stk; - if ( bytes_left < sizeof(*mp) ) { - status = RSRV_OK; - break; - } - - mp = (caHdr *) &client->recv.buf[client->recv.stk]; - msg.m_cmmd = ntohs ( mp->m_cmmd ); - msg.m_postsize = ntohs ( mp->m_postsize ); - msg.m_dataType = ntohs ( mp->m_dataType ); - msg.m_count = ntohs ( mp->m_count ); - msg.m_cid = ntohl ( mp->m_cid ); - msg.m_available = ntohl ( mp->m_available ); - - if ( CA_V49(client->minor_version_number) && msg.m_postsize == 0xffff ) { - ca_uint32_t *pLW = ( ca_uint32_t * ) ( mp + 1 ); - if ( bytes_left < sizeof(*mp) + 2 * sizeof(*pLW) ) { - status = RSRV_OK; - break; - } - msg.m_postsize = ntohl ( pLW[0] ); - msg.m_count = ntohl ( pLW[1] ); - msgsize = msg.m_postsize + sizeof(*mp) + 2 * sizeof ( *pLW ); - pBody = ( void * ) ( pLW + 2 ); - } - else { - msgsize = msg.m_postsize + sizeof(*mp); - pBody = ( void * ) ( mp + 1 ); - } - - /* ignore deprecated clients, but let newer clients identify themselves. */ - if (msg.m_cmmd!=CA_PROTO_VERSION && !CA_VSUPPORTED(client->minor_version_number)) { - if (client->proto==IPPROTO_TCP) { - /* log and error for too old clients, but keep the connection open to avoid a - * re-connect loop. - */ - send_err ( &msg, ECA_DEFUNCT, client, - "CAS: Client version %u too old", client->minor_version_number ); - log_header ( "CAS: Client version too old", - client, &msg, 0, nmsg ); - client->recvBytesToDrain = msgsize - bytes_left; - client->recv.stk = client->recv.cnt; - status = RSRV_OK; - } else { - /* silently ignore UDP from old clients */ - status = RSRV_ERROR; - } - break; - } - - /* - * disconnect clients that dont send 8 byte - * aligned payloads - */ - if ( msgsize & 0x7 ) { - if (client->proto==IPPROTO_TCP) { - send_err ( &msg, ECA_INTERNAL, client, - "CAS: Missaligned protocol rejected" ); - log_header ( "CAS: Missaligned protocol rejected", - client, &msg, 0, nmsg ); - } - status = RSRV_ERROR; - break; - } - - /* problem: we have a complete header, - * but before we check msgsize we don't know - * if we have a complete message body - * -> we may be called again with the same header - * after receiving the full message - */ - if ( msgsize > client->recv.maxstk ) { - casExpandRecvBuffer ( client, msgsize ); - if ( msgsize > client->recv.maxstk ) { - if (client->proto==IPPROTO_TCP) { - send_err ( &msg, ECA_TOLARGE, client, - "CAS: Server unable to load large request message. Max bytes=%lu", - rsrvSizeofLargeBufTCP ); - log_header ( "CAS: server unable to load large request message", - client, &msg, 0, nmsg ); - } - assert ( client->recv.cnt <= client->recv.maxstk ); - assert ( msgsize >= bytes_left ); - client->recvBytesToDrain = msgsize - bytes_left; - client->recv.stk = client->recv.cnt; - status = RSRV_OK; - break; - } - } - - /* - * wait for complete message body - */ - if ( msgsize > bytes_left ) { - status = RSRV_OK; - break; - } - - nmsg++; - - if ( CASDEBUG > 2 ) - log_header (NULL, client, &msg, pBody, nmsg); - - if ( client->proto==IPPROTO_UDP ) { - if ( msg.m_cmmd < NELEMENTS ( udpJumpTable ) ) { - status = ( *udpJumpTable[msg.m_cmmd] )( &msg, pBody, client ); - if (status!=RSRV_OK) { - status = RSRV_ERROR; - break; - } - } - else { - status = bad_udp_cmd_action ( &msg, pBody, client ); - break; - } - } - else { - if ( msg.m_cmmd < NELEMENTS(tcpJumpTable) ) { - status = ( *tcpJumpTable[msg.m_cmmd] ) ( &msg, pBody, client ); - if ( status != RSRV_OK ) { - status = RSRV_ERROR; - break; - } - } - else { - return bad_tcp_cmd_action ( &msg, pBody, client ); - } - } - - client->recv.stk += msgsize; - } - - return status; -} - -/* - * rsrvCheckPut () - */ -int rsrvCheckPut (const struct channel_in_use *pciu) -{ - /* - * SPC_NOMOD fields are always unwritable - */ - if (dbChannelSpecial(pciu->dbch) == SPC_NOMOD) { - return 0; - } - else { - return asCheckPut (pciu->asClientPVT); - } -} diff --git a/src/ioc/rsrv/camsgtask.c b/src/ioc/rsrv/camsgtask.c deleted file mode 100644 index 65d37c9a9..000000000 --- a/src/ioc/rsrv/camsgtask.c +++ /dev/null @@ -1,188 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - * Date: 6-88 - */ - - -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsStdio.h" -#include "epicsTime.h" -#include "errlog.h" -#include "osiSock.h" -#include "taskwd.h" - -#include "caerr.h" - -#define epicsExportSharedSymbols -#include "db_access.h" -#include "rsrv.h" -#include "server.h" - -/* - * camsgtask() - * - * CA server TCP client task (one spawned for each client) - */ -void camsgtask ( void *pParm ) -{ - struct client *client = (struct client *) pParm; - osiSockIoctl_t nchars; - int status; - - casAttachThreadToClient ( client ); - - /* - * send the server's minor version number to the client - */ - status = cas_copy_in_header ( client, CA_PROTO_VERSION, 0, - 0, CA_MINOR_PROTOCOL_REVISION, 0, 0, 0 ); - if ( status != ECA_NORMAL ) { - LOCK_CLIENTQ; - ellDelete ( &clientQ, &client->node ); - UNLOCK_CLIENTQ; - destroy_tcp_client ( client ); - return; - } - - while (castcp_ctl == ctlRun && !client->disconnect) { - - /* - * allow message to batch up if more are comming - */ - status = socket_ioctl (client->sock, FIONREAD, &nchars); - if (status < 0) { - char sockErrBuf[64]; - - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf("CAS: ioctl error - %s\n", - sockErrBuf); - cas_send_bs_msg(client, TRUE); - } - else if (nchars == 0){ - cas_send_bs_msg(client, TRUE); - } - - client->recv.stk = 0; - assert ( client->recv.maxstk >= client->recv.cnt ); - nchars = recv ( client->sock, &client->recv.buf[client->recv.cnt], - (int) ( client->recv.maxstk - client->recv.cnt ), 0 ); - if ( nchars == 0 ){ - if ( CASDEBUG > 0 ) { - /* convert to u long so that %lu works on both 32 and 64 bit archs */ - unsigned long cnt = sizeof ( client->recv.buf ) - client->recv.cnt; - errlogPrintf ( "CAS: nill message disconnect ( %lu bytes request )\n", - cnt ); - } - break; - } - else if ( nchars < 0 ) { - int anerrno = SOCKERRNO; - - if ( anerrno == SOCK_EINTR ) { - continue; - } - - if ( anerrno == SOCK_ENOBUFS ) { - errlogPrintf ( - "CAS: Out of network buffers, retring receive in 15 seconds\n" ); - epicsThreadSleep ( 15.0 ); - continue; - } - - /* - * normal conn lost conditions - */ - if ( ( anerrno != SOCK_ECONNABORTED && - anerrno != SOCK_ECONNRESET && - anerrno != SOCK_ETIMEDOUT ) || - CASDEBUG > 2 ) { - char sockErrBuf[64]; - - epicsSocketConvertErrorToString( - sockErrBuf, sizeof ( sockErrBuf ), anerrno); - errlogPrintf ( "CAS: Client disconnected - %s\n", - sockErrBuf ); - } - break; - } - - epicsTimeGetCurrent ( &client->time_at_last_recv ); - client->recv.cnt += ( unsigned ) nchars; - - status = camessage ( client ); - if (status == 0) { - /* - * if there is a partial message - * align it with the start of the buffer - */ - if (client->recv.cnt > client->recv.stk) { - unsigned bytes_left; - - bytes_left = client->recv.cnt - client->recv.stk; - - /* - * overlapping regions handled - * properly by memmove - */ - memmove (client->recv.buf, - &client->recv.buf[client->recv.stk], bytes_left); - client->recv.cnt = bytes_left; - } - else { - client->recv.cnt = 0ul; - } - } - else { - char buf[64]; - - client->recv.cnt = 0ul; - - /* - * disconnect when there are severe message errors - */ - ipAddrToDottedIP (&client->addr, buf, sizeof(buf)); - epicsPrintf ("CAS: forcing disconnect from %s\n", buf); - break; - } - } - - LOCK_CLIENTQ; - ellDelete ( &clientQ, &client->node ); - UNLOCK_CLIENTQ; - - destroy_tcp_client ( client ); -} - - -int casClientInitiatingCurrentThread ( char * pBuf, size_t bufSize ) -{ - struct client * pClient = ( struct client * ) - epicsThreadPrivateGet ( rsrvCurrentClient ); - - if ( ! pClient ) - return RSRV_ERROR; - - if ( pBuf && bufSize ) { - epicsSnprintf(pBuf, bufSize, "ca:%s@%s", - pClient->pUserName, pClient->pHostName); - } - return RSRV_OK; -} - diff --git a/src/ioc/rsrv/caserverio.c b/src/ioc/rsrv/caserverio.c deleted file mode 100644 index 15a26375a..000000000 --- a/src/ioc/rsrv/caserverio.c +++ /dev/null @@ -1,400 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - * Date: 060791 - */ - -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsSignal.h" -#include "epicsTime.h" -#include "errlog.h" -#include "osiSock.h" - -#include "caerr.h" -#include "net_convert.h" - -#define epicsExportSharedSymbols -#include "server.h" - -/* - * cas_send_bs_msg() - * - * (channel access server send message) - */ -void cas_send_bs_msg ( struct client *pclient, int lock_needed ) -{ - int status; - - if ( CASDEBUG > 2 && pclient->send.stk ) { - errlogPrintf ( "CAS: Sending a message of %d bytes\n", pclient->send.stk ); - } - - if ( pclient->disconnect ) { - if ( CASDEBUG > 2 ) { - errlogPrintf ( "CAS: msg Discard for sock %d addr %x\n", - pclient->sock, (unsigned) pclient->addr.sin_addr.s_addr ); - } - pclient->send.stk = 0u; - return; - } - - if ( lock_needed ) { - SEND_LOCK ( pclient ); - } - - while ( pclient->send.stk && ! pclient->disconnect ) { - status = send ( pclient->sock, pclient->send.buf, pclient->send.stk, 0 ); - if ( status >= 0 ) { - unsigned transferSize = (unsigned) status; - if ( transferSize >= pclient->send.stk ) { - pclient->send.stk = 0; - epicsTimeGetCurrent ( &pclient->time_at_last_send ); - break; - } - else { - unsigned bytesLeft = pclient->send.stk - transferSize; - memmove ( pclient->send.buf, &pclient->send.buf[transferSize], - bytesLeft ); - pclient->send.stk = bytesLeft; - } - } - else { - int causeWasSocketHangup = 0; - int anerrno = SOCKERRNO; - char buf[64]; - - if ( pclient->disconnect ) { - pclient->send.stk = 0u; - break; - } - - if ( anerrno == SOCK_EINTR ) { - continue; - } - - if ( anerrno == SOCK_ENOBUFS ) { - errlogPrintf ( - "CAS: Out of network buffers, retrying send in 15 seconds\n" ); - epicsThreadSleep ( 15.0 ); - continue; - } - - ipAddrToDottedIP ( &pclient->addr, buf, sizeof(buf) ); - - if ( - anerrno == SOCK_ECONNABORTED || - anerrno == SOCK_ECONNRESET || - anerrno == SOCK_EPIPE || - anerrno == SOCK_ETIMEDOUT ) { - causeWasSocketHangup = 1; - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: TCP send to %s failed - %s\n", - buf, sockErrBuf); - } - pclient->disconnect = TRUE; - pclient->send.stk = 0u; - - /* - * wakeup the receive thread - */ - if ( ! causeWasSocketHangup ) { - enum epicsSocketSystemCallInterruptMechanismQueryInfo info = - epicsSocketSystemCallInterruptMechanismQuery (); - switch ( info ) { - case esscimqi_socketCloseRequired: - if ( pclient->sock != INVALID_SOCKET ) { - epicsSocketDestroy ( pclient->sock ); - pclient->sock = INVALID_SOCKET; - } - break; - case esscimqi_socketBothShutdownRequired: - { - int status = shutdown ( pclient->sock, SHUT_RDWR ); - if ( status ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAS: Socket shutdown error - %s\n", - sockErrBuf ); - } - } - break; - case esscimqi_socketSigAlarmRequired: - epicsSignalRaiseSigAlarm ( pclient->tid ); - break; - default: - break; - }; - break; - } - } - } - - if ( lock_needed ) { - SEND_UNLOCK(pclient); - } - - DLOG ( 3, ( "------------------------------\n\n" ) ); - - return; -} - -/* - * cas_send_dg_msg() - * - * (channel access server send udp message) - */ -void cas_send_dg_msg ( struct client * pclient ) -{ - int status; - int sizeDG; - char * pDG; - caHdr * pMsg; - - if ( CASDEBUG > 2 && pclient->send.stk ) { - errlogPrintf ( "CAS: Sending a udp message of %d bytes\n", pclient->send.stk ); - } - - SEND_LOCK ( pclient ); - - if ( pclient->send.stk <= sizeof (caHdr) ) { - SEND_UNLOCK(pclient); - return; - } - - pDG = pclient->send.buf; - pMsg = ( caHdr * ) pDG; - sizeDG = pclient->send.stk; - assert ( ntohs ( pMsg->m_cmmd ) == CA_PROTO_VERSION ); - if ( CA_V411 ( pclient->minor_version_number ) ) { - pMsg->m_cid = htonl ( pclient->seqNoOfReq ); - pMsg->m_dataType = htons ( sequenceNoIsValid ); - } - else { - pDG += sizeof (caHdr); - sizeDG -= sizeof (caHdr); - } - - status = sendto ( pclient->sock, pDG, sizeDG, 0, - (struct sockaddr *)&pclient->addr, sizeof(pclient->addr) ); - if ( status >= 0 ) { - if ( status >= sizeDG ) { - epicsTimeGetCurrent ( &pclient->time_at_last_send ); - } - else { - errlogPrintf ( - "CAS: System failed to send entire udp frame?\n" ); - } - } - else { - char sockErrBuf[64]; - char buf[128]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - ipAddrToDottedIP ( &pclient->addr, buf, sizeof(buf) ); - errlogPrintf( "CAS: UDP send to %s failed - %s\n", - buf, sockErrBuf); - } - - pclient->send.stk = 0u; - - /* - * add placeholder for the first version message should it be needed - */ - rsrv_version_reply ( pclient ); - - SEND_UNLOCK(pclient); - - DLOG ( 3, ( "------------------------------\n\n" ) ); - - return; -} - -/* - * - * cas_copy_in_header() - * - * Allocate space in the outgoing message buffer and - * copy in message header. Return pointer to message body. - * - * send lock must be on while in this routine - * - * Returns a valid ptr to message body or NULL if the msg - * will not fit. - */ -int cas_copy_in_header ( - struct client *pclient, ca_uint16_t response, ca_uint32_t payloadSize, - ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid, - ca_uint32_t responseSpecific, void **ppPayload ) -{ - unsigned msgSize; - ca_uint32_t alignedPayloadSize; - caHdr *pMsg; - - if ( payloadSize > UINT_MAX - sizeof ( caHdr ) - 8u ) { - return ECA_TOLARGE; - } - - alignedPayloadSize = CA_MESSAGE_ALIGN ( payloadSize ); - - msgSize = alignedPayloadSize + sizeof ( caHdr ); - if ( alignedPayloadSize >= 0xffff || nElem >= 0xffff ) { - if ( ! CA_V49 ( pclient->minor_version_number ) ) { - return ECA_16KARRAYCLIENT; - } - msgSize += 2 * sizeof ( ca_uint32_t ); - } - - if ( msgSize > pclient->send.maxstk ) { - casExpandSendBuffer ( pclient, msgSize ); - if ( msgSize > pclient->send.maxstk ) { - return ECA_TOLARGE; - } - } - - if ( pclient->send.stk > pclient->send.maxstk - msgSize ) { - if ( pclient->disconnect ) { - pclient->send.stk = 0; - } - else{ - if ( pclient->proto == IPPROTO_TCP) { - cas_send_bs_msg ( pclient, FALSE ); - } - else if ( pclient->proto == IPPROTO_UDP ) { - cas_send_dg_msg ( pclient ); - } - else { - return ECA_INTERNAL; - } - } - } - - pMsg = (caHdr *) &pclient->send.buf[pclient->send.stk]; - pMsg->m_cmmd = htons(response); - pMsg->m_dataType = htons(dataType); - pMsg->m_cid = htonl(cid); - pMsg->m_available = htonl(responseSpecific); - if (alignedPayloadSize < 0xffff && nElem < 0xffff) { - pMsg->m_postsize = htons(((ca_uint16_t) alignedPayloadSize)); - pMsg->m_count = htons(((ca_uint16_t) nElem)); - if (ppPayload) - *ppPayload = (void *) (pMsg + 1); - } - else { - ca_uint32_t *pW32 = (ca_uint32_t *) (pMsg + 1); - pMsg->m_postsize = htons(0xffff); - pMsg->m_count = htons(0u); - pW32[0] = htonl(alignedPayloadSize); - pW32[1] = htonl(nElem); - if (ppPayload) - *ppPayload = (void *) (pW32 + 2); - } - - /* zero out pad bytes */ - if ( alignedPayloadSize > payloadSize ) { - char *p = ( char * ) *ppPayload; - memset ( p + payloadSize, '\0', - alignedPayloadSize - payloadSize ); - } - - return ECA_NORMAL; -} - -void cas_set_header_cid ( struct client *pClient, ca_uint32_t cid ) -{ - caHdr *pMsg = ( caHdr * ) &pClient->send.buf[pClient->send.stk]; - pMsg->m_cid = htonl ( cid ); -} - -void cas_set_header_count (struct client *pClient, ca_uint32_t count) -{ - caHdr *pMsg = (caHdr *) &pClient->send.buf[pClient->send.stk]; - if (pMsg->m_postsize == htons(0xffff)) { - ca_uint32_t *pLW; - - assert(pMsg->m_count == 0); - pLW = (ca_uint32_t *) (pMsg + 1); - pLW[1] = htonl(count); - } - else { - assert(count < 65536); - pMsg->m_count = htons((ca_uint16_t) count); - } -} - -void cas_commit_msg ( struct client *pClient, ca_uint32_t size ) -{ - caHdr * pMsg = ( caHdr * ) &pClient->send.buf[pClient->send.stk]; - size = CA_MESSAGE_ALIGN ( size ); - if ( pMsg->m_postsize == htons ( 0xffff ) ) { - ca_uint32_t * pLW = ( ca_uint32_t * ) ( pMsg + 1 ); - assert ( size <= ntohl ( *pLW ) ); - pLW[0] = htonl ( size ); - size += sizeof ( caHdr ) + 2 * sizeof ( *pLW ); - } - else { - assert ( size <= ntohs ( pMsg->m_postsize ) ); - pMsg->m_postsize = htons ( (ca_uint16_t) size ); - size += sizeof ( caHdr ); - } - pClient->send.stk += size; -} - -/* - * this assumes that we have already checked to see - * if sufficent bytes are available - */ -ca_uint16_t rsrvGetUInt16 ( struct message_buffer *recv ) -{ - ca_uint8_t *pBuf = ( ca_uint8_t * ) recv->buf; - ca_uint16_t result; - /* - * this assumes that we have already checked to see - * if sufficent bytes are available - */ - assert ( recv->cnt - recv->stk >= 2u ); - result = pBuf[recv->stk++] << 8u; - result |= pBuf[recv->stk++] << 0u; - return result; -} - -/* - * this assumes that we have already checked to see - * if sufficent bytes are available - */ -ca_uint32_t rsrvGetUInt32 ( struct message_buffer *recv ) -{ - ca_uint8_t *pBuf = ( ca_uint8_t * ) recv->buf; - ca_uint32_t result; - /* - * this assumes that we have already checked to see - * if sufficent bytes are available - */ - assert ( recv->cnt - recv->stk >= 4u ); - result = pBuf[recv->stk++] << 24u; - result |= pBuf[recv->stk++] << 16u; - result |= pBuf[recv->stk++] << 8u; - result |= pBuf[recv->stk++] << 0u; - return result; -} diff --git a/src/ioc/rsrv/caservertask.c b/src/ioc/rsrv/caservertask.c deleted file mode 100644 index 37c721f8a..000000000 --- a/src/ioc/rsrv/caservertask.c +++ /dev/null @@ -1,1553 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 Michael Davidsaver -* Copyright (c) 2015 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - */ - -#include -#include -#include -#include -#include -#include - -#include "addrList.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsSignal.h" -#include "epicsStdio.h" -#include "epicsTime.h" -#include "errlog.h" -#include "freeList.h" -#include "osiPoolStatus.h" -#include "osiSock.h" -#include "taskwd.h" -#include "cantProceed.h" - -#include "epicsExport.h" - -#define epicsExportSharedSymbols -#include "dbChannel.h" -#include "dbCommon.h" -#include "dbEvent.h" -#include "db_field_log.h" -#include "dbServer.h" -#include "rsrv.h" - -#define GLBLSOURCE -#include "server.h" - -epicsThreadPrivateId rsrvCurrentClient; - -/* - * - * req_server() - * - * CA server task - * - * Waits for connections at the CA port and spawns a task to - * handle each of them - * - */ -static void req_server (void *pParm) -{ - rsrv_iface_config *conf = pParm; - SOCKET IOC_sock; - - taskwdInsert ( epicsThreadGetIdSelf (), NULL, NULL ); - - IOC_sock = conf->tcp; - - /* listen and accept new connections */ - if ( listen ( IOC_sock, 20 ) < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: Listen error %s\n", - sockErrBuf ); - epicsSocketDestroy (IOC_sock); - epicsThreadSuspendSelf (); - } - - epicsEventSignal(castcp_startStopEvent); - - while (TRUE) { - SOCKET clientSock; - struct sockaddr sockAddr; - osiSocklen_t addLen = sizeof(sockAddr); - - while (castcp_ctl == ctlPause) { - epicsThreadSleep(0.1); - } - - clientSock = epicsSocketAccept ( IOC_sock, &sockAddr, &addLen ); - if ( clientSock == INVALID_SOCKET ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf("CAS: Client accept error was \"%s\"\n", - sockErrBuf ); - epicsThreadSleep(15.0); - continue; - } - else { - epicsThreadId id; - struct client *pClient; - - /* socket passed in is closed if unsuccessful here */ - pClient = create_tcp_client ( clientSock ); - if ( ! pClient ) { - epicsThreadSleep ( 15.0 ); - continue; - } - - LOCK_CLIENTQ; - ellAdd ( &clientQ, &pClient->node ); - UNLOCK_CLIENTQ; - - id = epicsThreadCreate ( "CAS-client", epicsThreadPriorityCAServerLow, - epicsThreadGetStackSize ( epicsThreadStackBig ), - camsgtask, pClient ); - if ( id == 0 ) { - LOCK_CLIENTQ; - ellDelete ( &clientQ, &pClient->node ); - UNLOCK_CLIENTQ; - destroy_tcp_client ( pClient ); - errlogPrintf ( "CAS: task creation for new client failed\n" ); - epicsThreadSleep ( 15.0 ); - continue; - } - } - } -} - -static -int tryBind(SOCKET sock, const osiSockAddr* addr, const char *name) -{ - if(bind(sock, (struct sockaddr *) &addr->sa, sizeof(*addr))<0) { - char sockErrBuf[64]; - if(SOCKERRNO!=SOCK_EADDRINUSE) - { - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: %s bind error: \"%s\"\n", - name, sockErrBuf ); - epicsThreadSuspendSelf (); - } - return -1; - } else - return 0; -} - -/* need to collect a set of TCP sockets, one for each interface, - * which are bound to the same TCP port number. - * Needed to avoid the complications and confusion of different TCP - * ports for each interface (name server and beacon sender would need - * to know this). - */ -static -SOCKET* rsrv_grab_tcp(unsigned short *port) -{ - SOCKET *socks; - osiSockAddr scratch; - unsigned i; - - socks = mallocMustSucceed(ellCount(&casIntfAddrList)*sizeof(*socks), "rsrv_grab_tcp"); - for(i=0; i0) { - ELLNODE *cur, *next; - unsigned ok = 1; - - for(i=0; iaddr; - - scratch.ia.sin_addr = ifaceAddr.ia.sin_addr; - - tcpsock = socks[i] = epicsSocketCreate (AF_INET, SOCK_STREAM, 0); - if(tcpsock==INVALID_SOCKET) - cantProceed("rsrv ran out of sockets during initialization"); - - epicsSocketEnableAddressReuseDuringTimeWaitState ( tcpsock ); - - if(bind(tcpsock, &scratch.sa, sizeof(scratch))==0) { - if(scratch.ia.sin_port==0) { - /* use first socket to pick a random port */ - osiSocklen_t alen = sizeof(ifaceAddr); - assert(i==0); - if(getsockname(tcpsock, &ifaceAddr.sa, &alen)) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: getsockname error was \"%s\"\n", - sockErrBuf ); - epicsThreadSuspendSelf (); - ok = 0; - break; - } - scratch.ia.sin_port = ifaceAddr.ia.sin_port; - assert(scratch.ia.sin_port!=0); - } - } else { - int errcode = SOCKERRNO; - /* bind fails. React harshly to unexpected errors to avoid an infinite loop */ - if(errcode==SOCK_EADDRNOTAVAIL) { - /* this is not a bind()able address. */ - int j; - char name[40]; - ipAddrToDottedIP(&scratch.ia, name, sizeof(name)); - printf("Skipping %s which is not an interface address\n", name); - - for(j=0; j<=i; j++) { - epicsSocketDestroy(socks[j]); - socks[j] = INVALID_SOCKET; - } - - ellDelete(&casIntfAddrList, cur); - free(cur); - ok = 0; - break; - } - /* if SOCK_EADDRINUSE or SOCK_EACCES try again with a different - * port number, otherwise fail hard. - */ - if (errcode != SOCK_EADDRINUSE && - errcode != SOCK_EACCES) { - char name[40]; - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - ipAddrToDottedIP(&scratch.ia, name, sizeof(name)); - cantProceed( "CAS: Socket bind %s error was %s\n", - name, sockErrBuf ); - } - ok = 0; - break; - } - } - - if (ok) { - assert(scratch.ia.sin_port!=0); - *port = ntohs(scratch.ia.sin_port); - - break; - } else { - - for(i=0; inode) : NULL; - pNode; - pNode = pNext, - pNext = pNext ? (osiSockAddrNode*)ellNext(&pNext->node) : NULL) - { - osiSockAddr match; - epicsUInt32 top = ntohl(pNode->addr.ia.sin_addr.s_addr)>>24; - - if(pNode->addr.ia.sin_family==AF_INET && pNode->addr.ia.sin_addr.s_addr==htonl(INADDR_ANY)) - { - foundWildcard = 1; - - } else if(pNode->addr.ia.sin_family==AF_INET && top>=224 && top<=239) { - /* This is a multi-cast address */ - ellDelete(&casIntfAddrList, &pNode->node); - ellAdd(&casMCastAddrList, &pNode->node); - continue; - } - - if(!doautobeacon) - continue; - /* when given a specific interface address, auto populate with the - * corresponding broadcast address. - */ - - autobeaconlist = 0; /* prevent later population from wildcard */ - - memset(&match, 0, sizeof(match)); - match.ia.sin_family = AF_INET; - match.ia.sin_addr.s_addr = pNode->addr.ia.sin_addr.s_addr; - match.ia.sin_port = htons(ca_beacon_port); - - osiSockDiscoverBroadcastAddresses(&beaconAddrList, beaconSocket, &match); - } - - if (foundWildcard && ellCount(&casIntfAddrList) != 1) { - cantProceed("CAS interface address list can not contain 0.0.0.0 and other interface addresses.\n"); - } - } - - if (ellCount(&casIntfAddrList) == 0) { - /* default to wildcard 0.0.0.0 when interface address list is empty */ - osiSockAddrNode *pNode = (osiSockAddrNode *) callocMustSucceed( 1, sizeof(*pNode), "rsrv_init" ); - pNode->addr.ia.sin_family = AF_INET; - pNode->addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY ); - pNode->addr.ia.sin_port = 0; - ellAdd ( &casIntfAddrList, &pNode->node ); - } - - { - ELLLIST temp = ELLLIST_INIT; - osiSockAddrNode *pNode; - - ellConcat(&temp, &beaconAddrList); - - /* collect user specified beacon address list - * prefer EPICS_CAS_BEACON_ADDR_LIST, fallback to EPICS_CA_ADDR_LIST - */ - addAddrToChannelAccessAddressList ( &temp, &EPICS_CAS_BEACON_ADDR_LIST, ca_beacon_port, 0 ); - - if (autobeaconlist) { - /* auto populate with all broadcast addresses. - * Note that autobeaconlist is zeroed above if an interface - * address list is provided. - */ - osiSockAddr match; - memset(&match, 0, sizeof(match)); - match.ia.sin_family = AF_INET; - match.ia.sin_addr.s_addr = htonl(INADDR_ANY); - match.ia.sin_port = htons(ca_beacon_port); - - osiSockDiscoverBroadcastAddresses(&temp, beaconSocket, &match); - } - - /* set the port for any automatically discovered destinations. */ - for(pNode = (osiSockAddrNode*)ellFirst(&temp); - pNode; - pNode = (osiSockAddrNode*)ellNext(&pNode->node)) - { - if(pNode->addr.ia.sin_port==0) - pNode->addr.ia.sin_port = htons(ca_beacon_port); - } - - removeDuplicateAddresses(&beaconAddrList, &temp, 0); - } - - if (ellCount(&beaconAddrList)==0) - fprintf(stderr, "Warning: RSRV has empty beacon address list\n"); - - { - osiSockAddrNode *node; - ELLLIST temp = ELLLIST_INIT, - temp2= ELLLIST_INIT; - size_t idx = 0; - - addAddrToChannelAccessAddressList ( &temp, &EPICS_CAS_IGNORE_ADDR_LIST, 0, 0 ); - removeDuplicateAddresses(&temp2, &temp, 0); - - /* Keep the list of addresses to ignore in an array on the assumption that - * it is short enough that using a hash table would be slower. - * 0.0.0.0 indicates end of list - */ - casIgnoreAddrs = callocMustSucceed(1+ellCount(&temp2), sizeof(casIgnoreAddrs[0]), "casIgnoreAddrs"); - - while((node=(osiSockAddrNode*)ellGet(&temp2))!=NULL) - { - casIgnoreAddrs[idx++] = node->addr.ia.sin_addr.s_addr; - free(node); - } - casIgnoreAddrs[idx] = 0; - } -} - -static dbServer rsrv_server = { - ELLNODE_INIT, - "rsrv", - casr, - casStatsFetch, - casClientInitiatingCurrentThread -}; - -/* - * rsrv_init () - */ -int rsrv_init (void) -{ - long maxBytesAsALong; - long status; - SOCKET *socks; - int autoMaxBytes; - - clientQlock = epicsMutexMustCreate(); - - freeListInitPvt ( &rsrvClientFreeList, sizeof(struct client), 8 ); - freeListInitPvt ( &rsrvChanFreeList, sizeof(struct channel_in_use), 512 ); - freeListInitPvt ( &rsrvEventFreeList, sizeof(struct event_ext), 512 ); - freeListInitPvt ( &rsrvSmallBufFreeListTCP, MAX_TCP, 16 ); - initializePutNotifyFreeList (); - - epicsSignalInstallSigPipeIgnore (); - - rsrvCurrentClient = epicsThreadPrivateCreate (); - - dbRegisterServer(&rsrv_server); - - if ( envGetConfigParamPtr ( &EPICS_CAS_SERVER_PORT ) ) { - ca_server_port = envGetInetPortConfigParam ( &EPICS_CAS_SERVER_PORT, - (unsigned short) CA_SERVER_PORT ); - } - else { - ca_server_port = envGetInetPortConfigParam ( &EPICS_CA_SERVER_PORT, - (unsigned short) CA_SERVER_PORT ); - } - ca_udp_port = ca_server_port; - - if (envGetConfigParamPtr(&EPICS_CAS_BEACON_PORT)) { - ca_beacon_port = envGetInetPortConfigParam (&EPICS_CAS_BEACON_PORT, - (unsigned short) CA_REPEATER_PORT ); - } - else { - ca_beacon_port = envGetInetPortConfigParam (&EPICS_CA_REPEATER_PORT, - (unsigned short) CA_REPEATER_PORT ); - } - - status = envGetLongConfigParam ( &EPICS_CA_MAX_ARRAY_BYTES, &maxBytesAsALong ); - if ( status || maxBytesAsALong < 0 ) { - errlogPrintf ( "CAS: EPICS_CA_MAX_ARRAY_BYTES was not a positive integer\n" ); - rsrvSizeofLargeBufTCP = MAX_TCP; - } - else { - /* allow room for the protocol header so that they get the array size they requested */ - static const unsigned headerSize = sizeof ( caHdr ) + 2 * sizeof ( ca_uint32_t ); - ca_uint32_t maxBytes = ( unsigned ) maxBytesAsALong; - if ( maxBytes < 0xffffffff - headerSize ) { - maxBytes += headerSize; - } - else { - maxBytes = 0xffffffff; - } - if ( maxBytes < MAX_TCP ) { - errlogPrintf ( "CAS: EPICS_CA_MAX_ARRAY_BYTES was rounded up to %u\n", MAX_TCP ); - rsrvSizeofLargeBufTCP = MAX_TCP; - } - else { - rsrvSizeofLargeBufTCP = maxBytes; - } - } - - if(envGetBoolConfigParam(&EPICS_CA_AUTO_ARRAY_BYTES, &autoMaxBytes)) - autoMaxBytes = 1; - - if (!autoMaxBytes) - freeListInitPvt ( &rsrvLargeBufFreeListTCP, rsrvSizeofLargeBufTCP, 1 ); - else - rsrvLargeBufFreeListTCP = NULL; - pCaBucket = bucketCreate(CAS_HASH_TABLE_SIZE); - if (!pCaBucket) - cantProceed("RSRV failed to allocate ID lookup table\n"); - - rsrv_build_addr_lists(); - - castcp_startStopEvent = epicsEventMustCreate(epicsEventEmpty); - casudp_startStopEvent = epicsEventMustCreate(epicsEventEmpty); - beacon_startStopEvent = epicsEventMustCreate(epicsEventEmpty); - castcp_ctl = ctlPause; - - /* Thread priorites - * Now starting per interface - * TCP Listener: epicsThreadPriorityCAServerLow-2 - * Name receiver: epicsThreadPriorityCAServerLow-4 - * Now starting global - * Beacon sender: epicsThreadPriorityCAServerLow-3 - * Started later per TCP client - * TCP receiver: epicsThreadPriorityCAServerLow - * TCP sender : epicsThreadPriorityCAServerLow-1 - */ - { - unsigned i; - threadPrios[0] = epicsThreadPriorityCAServerLow; - - for(i=1; itcpAddr = ((osiSockAddrNode *)cur)->addr; - conf->tcpAddr.ia.sin_port = htons(ca_server_port); - conf->tcp = socks[i]; - socks[i] = INVALID_SOCKET; - - ipAddrToDottedIP (&conf->tcpAddr.ia, ifaceName, sizeof(ifaceName)); - - conf->udp = conf->udpbcast = INVALID_SOCKET; - - /* create and bind UDP name receiver socket(s) */ - - conf->udp = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); - if(conf->udp==INVALID_SOCKET) - cantProceed("rsrv_init ran out of udp sockets"); - - conf->udpAddr = conf->tcpAddr; - conf->udpAddr.ia.sin_port = htons(ca_udp_port); - - epicsSocketEnableAddressUseForDatagramFanout ( conf->udp ); - - if(tryBind(conf->udp, &conf->udpAddr, "UDP unicast socket")) - goto cleanup; - -#ifdef IP_ADD_MEMBERSHIP - /* join UDP socket to any multicast groups */ - { - osiSockAddrNode *pNode; - - for(pNode = (osiSockAddrNode*)ellFirst(&casMCastAddrList); - pNode; - pNode = (osiSockAddrNode*)ellNext(&pNode->node)) - { - struct ip_mreq mreq; - - memset(&mreq, 0, sizeof(mreq)); - mreq.imr_multiaddr = pNode->addr.ia.sin_addr; - mreq.imr_interface.s_addr = conf->udpAddr.ia.sin_addr.s_addr; - - if (setsockopt(conf->udp, IPPROTO_IP, IP_ADD_MEMBERSHIP, - (char *) &mreq, sizeof(mreq))!=0) { - struct sockaddr_in temp; - char name[40]; - char sockErrBuf[64]; - temp.sin_family = AF_INET; - temp.sin_addr = mreq.imr_multiaddr; - temp.sin_port = conf->udpAddr.ia.sin_port; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - ipAddrToDottedIP (&temp, name, sizeof(name)); - fprintf(stderr, "CAS: Socket mcast join %s to %s failed with \"%s\"\n", - ifaceName, name, sockErrBuf ); - } - } - } -#else - if(ellCount(&casMCastAddrList)){ - fprintf(stderr, "IPv4 Multicast name lookup not supported by this target\n"); - } -#endif - -#if !(defined(_WIN32) || defined(__CYGWIN__)) - /* An oddness of BSD sockets (not winsock) is that binding to - * INADDR_ANY will receive unicast and broadcast, but binding to - * a specific interface address receives only unicast. The trick - * is to bind a second socket to the interface broadcast address, - * which will then receive only broadcasts. - */ - if(conf->udpAddr.ia.sin_addr.s_addr!=htonl(INADDR_ANY)) { - /* find interface broadcast address */ - ELLLIST bcastList = ELLLIST_INIT; - osiSockAddrNode *pNode; - - osiSockDiscoverBroadcastAddresses (&bcastList, - conf->udp, &conf->udpAddr); // match addr - - if(ellCount(&bcastList)==0) { - fprintf(stderr, "Warning: Can't find broadcast address of interface %s\n" - " Name lookup may not work on this interface\n", ifaceName); - } else { - if(ellCount(&bcastList)>1 && conf->udpAddr.ia.sin_addr.s_addr!=htonl(INADDR_ANY)) - printf("Interface %s has more than one broadcast address?\n", ifaceName); - - pNode = (osiSockAddrNode*)ellFirst(&bcastList); - - conf->udpbcast = epicsSocketCreate(AF_INET, SOCK_DGRAM, 0); - if(conf->udpbcast==INVALID_SOCKET) - cantProceed("rsrv_init ran out of udp sockets for bcast"); - - epicsSocketEnableAddressUseForDatagramFanout ( conf->udpbcast ); - - conf->udpbcastAddr = conf->udpAddr; - conf->udpbcastAddr.ia.sin_addr.s_addr = pNode->addr.ia.sin_addr.s_addr; - - if(tryBind(conf->udpbcast, &conf->udpbcastAddr, "UDP Socket bcast")) - goto cleanup; - } - - ellFree(&bcastList); - } - -#endif /* !(defined(_WIN32) || defined(__CYGWIN__)) */ - - ellAdd(&servers, &conf->node); - - /* have all sockets, time to start some threads */ - - epicsThreadMustCreate("CAS-TCP", threadPrios[2], - epicsThreadGetStackSize(epicsThreadStackMedium), - &req_server, conf); - - epicsEventMustWait(castcp_startStopEvent); - - epicsThreadMustCreate("CAS-UDP", threadPrios[4], - epicsThreadGetStackSize(epicsThreadStackMedium), - &cast_server, conf); - - epicsEventMustWait(casudp_startStopEvent); - -#if !(defined(_WIN32) || defined(__CYGWIN__)) - if(conf->udpbcast != INVALID_SOCKET) { - conf->startbcast = 1; - - epicsThreadMustCreate("CAS-UDP2", threadPrios[4], - epicsThreadGetStackSize(epicsThreadStackMedium), - &cast_server, conf); - - epicsEventMustWait(casudp_startStopEvent); - - conf->startbcast = 0; - } -#endif /* !(defined(_WIN32) || defined(__CYGWIN__)) */ - - havesometcp = 1; - continue; - cleanup: - epicsSocketDestroy(conf->tcp); - if(conf->udp!=INVALID_SOCKET) epicsSocketDestroy(conf->udp); - if(conf->udpbcast!=INVALID_SOCKET) epicsSocketDestroy(conf->udpbcast); - free(conf); - } - - if(!havesometcp) - cantProceed("CAS: No TCP server started\n"); - } - - /* servers list is considered read-only from this point */ - - epicsThreadMustCreate("CAS-beacon", threadPrios[3], - epicsThreadGetStackSize(epicsThreadStackSmall), - &rsrv_online_notify_task, NULL); - - epicsEventMustWait(beacon_startStopEvent); - - return RSRV_OK; -} - -int rsrv_run (void) -{ - castcp_ctl = ctlRun; - casudp_ctl = ctlRun; - beacon_ctl = ctlRun; - - return RSRV_OK; -} - -int rsrv_pause (void) -{ - beacon_ctl = ctlPause; - casudp_ctl = ctlPause; - castcp_ctl = ctlPause; - - return RSRV_OK; -} - -static unsigned countChanListBytes ( - struct client *client, ELLLIST * pList ) -{ - struct channel_in_use * pciu; - unsigned bytes_reserved = 0; - - epicsMutexMustLock ( client->chanListLock ); - pciu = ( struct channel_in_use * ) pList->node.next; - while ( pciu ) { - bytes_reserved += sizeof(struct channel_in_use); - bytes_reserved += sizeof(struct event_ext)*ellCount( &pciu->eventq ); - bytes_reserved += rsrvSizeOfPutNotify ( pciu->pPutNotify ); - pciu = ( struct channel_in_use * ) ellNext( &pciu->node ); - } - epicsMutexUnlock ( client->chanListLock ); - - return bytes_reserved; -} - -static void showChanList ( - struct client * client, unsigned level, ELLLIST * pList ) -{ - struct channel_in_use * pciu; - epicsMutexMustLock ( client->chanListLock ); - pciu = (struct channel_in_use *) pList->node.next; - while ( pciu ){ - dbChannelShow ( pciu->dbch, level, 8 ); - if ( level >= 1u ) - printf( "%12s# on eventq=%d, access=%c%c\n", "", - ellCount ( &pciu->eventq ), - asCheckGet ( pciu->asClientPVT ) ? 'r': '-', - rsrvCheckPut ( pciu ) ? 'w': '-' ); - pciu = ( struct channel_in_use * ) ellNext ( &pciu->node ); - } - epicsMutexUnlock ( client->chanListLock ); -} - -/* - * log_one_client () - */ -static void log_one_client (struct client *client, unsigned level) -{ - char clientIP[40]; - int n; - - ipAddrToDottedIP (&client->addr, clientIP, sizeof(clientIP)); - - if ( client->proto == IPPROTO_UDP ) { - printf ( "\tLast name requested by %s:\n", - clientIP ); - } - else if ( client->proto == IPPROTO_TCP ) { - printf ( " TCP client at %s '%s':\n", - clientIP, - client->pHostName ? client->pHostName : "" ); - } - else { - printf ( " Unknown client at %s '%s':\n", - clientIP, - client->pHostName ? client->pHostName : "" ); - } - - n = ellCount(&client->chanList) + ellCount(&client->chanPendingUpdateARList); - printf ( "\tUser '%s', V%u.%u, Priority = %u, %d Channel%s\n", - client->pUserName ? client->pUserName : "", - CA_MAJOR_PROTOCOL_REVISION, - client->minor_version_number, - client->priority, - n, n == 1 ? "" : "s" ); - - if ( level >= 3u ) { - double send_delay; - double recv_delay; - char *state[] = {"up", "down"}; - epicsTimeStamp current; - - epicsTimeGetCurrent(¤t); - send_delay = epicsTimeDiffInSeconds(¤t,&client->time_at_last_send); - recv_delay = epicsTimeDiffInSeconds(¤t,&client->time_at_last_recv); - - printf ("\tTask Id = %p, Socket FD = %d\n", - (void *) client->tid, client->sock); - printf( - "\t%.2f secs since last send, %.2f secs since last receive\n", - send_delay, recv_delay); - printf( - "\tUnprocessed request bytes = %u, Undelivered response bytes = %u\n", - client->recv.cnt - client->recv.stk, - client->send.stk ); - printf( - "\tState = %s%s%s\n", - state[client->disconnect?1:0], - client->send.type == mbtLargeTCP ? " jumbo-send-buf" : "", - client->recv.type == mbtLargeTCP ? " jumbo-recv-buf" : ""); - } - - if ( level >= 1u ) { - showChanList ( client, level - 1u, & client->chanList ); - showChanList ( client, level - 1u, & client->chanPendingUpdateARList ); - } - - if ( level >= 4u ) { - unsigned bytes_reserved = sizeof(struct client); - - bytes_reserved += countChanListBytes ( - client, & client->chanList ); - bytes_reserved += countChanListBytes ( - client, & client->chanPendingUpdateARList ); - printf( "\t%d bytes allocated\n", bytes_reserved); - printf( "\tSend Lock:\n\t "); - epicsMutexShow(client->lock,1); - printf( "\tPut Notify Lock:\n\t "); - epicsMutexShow (client->putNotifyLock,1); - printf( "\tAddress Queue Lock:\n\t "); - epicsMutexShow (client->chanListLock,1); - printf( "\tEvent Queue Lock:\n\t "); - epicsMutexShow (client->eventqLock,1); - printf( "\tBlock Semaphore:\n\t "); - epicsEventShow (client->blockSem,1); - } -} - -/* - * casr() - */ -void casr (unsigned level) -{ - size_t bytes_reserved; - int n; - - if ( ! clientQlock ) { - return; - } - - printf ("Channel Access Server V%s\n", - CA_VERSION_STRING ( CA_MINOR_PROTOCOL_REVISION ) ); - - LOCK_CLIENTQ - n = ellCount ( &clientQ ); - if (n == 0) { - printf("No clients connected.\n"); - } - else if (level == 0) { - printf("%d client%s connected.\n", - n, n == 1 ? "" : "s" ); - } - else { - struct client *client = (struct client *) ellFirst ( &clientQ ); - - printf("%d client%s connected:\n", - n, n == 1 ? "" : "s" ); - while (client) { - log_one_client(client, level - 1); - client = (struct client *) ellNext(&client->node); - } - } - UNLOCK_CLIENTQ - - if (level>=1) { - rsrv_iface_config *iface = (rsrv_iface_config *) ellFirst ( &servers ); - while (iface) { - char buf[40]; - - ipAddrToDottedIP (&iface->tcpAddr.ia, buf, sizeof(buf)); - printf("CAS-TCP server on %s with\n", buf); - - ipAddrToDottedIP (&iface->udpAddr.ia, buf, sizeof(buf)); -#if defined(_WIN32) - printf(" CAS-UDP name server on %s\n", buf); - if (level >= 2) - log_one_client(iface->client, level - 2); -#else - if (iface->udpbcast==INVALID_SOCKET) { - printf(" CAS-UDP name server on %s\n", buf); - if (level >= 2) - log_one_client(iface->client, level - 2); - } - else { - printf(" CAS-UDP unicast name server on %s\n", buf); - if (level >= 2) - log_one_client(iface->client, level - 2); - ipAddrToDottedIP (&iface->udpbcastAddr.ia, buf, sizeof(buf)); - printf(" CAS-UDP broadcast name server on %s\n", buf); - if (level >= 2) - log_one_client(iface->bclient, level - 2); - } -#endif - - iface = (rsrv_iface_config *) ellNext(&iface->node); - } - } - - if (level>=1) { - osiSockAddrNode * pAddr; - char buf[40]; - int n = ellCount(&casMCastAddrList); - - if (n) { - printf("Monitoring %d multicast address%s:\n", - n, n == 1 ? "" : "es"); - for(pAddr = (osiSockAddrNode*)ellFirst(&casMCastAddrList); - pAddr; - pAddr = (osiSockAddrNode*)ellNext(&pAddr->node)) - { - ipAddrToDottedIP (&pAddr->addr.ia, buf, sizeof(buf)); - printf(" %s\n", buf); - } - } - - n = ellCount(&beaconAddrList); - printf("Sending CAS-beacons to %d address%s:\n", - n, n == 1 ? "" : "es"); - for(pAddr = (osiSockAddrNode*)ellFirst(&beaconAddrList); - pAddr; - pAddr = (osiSockAddrNode*)ellNext(&pAddr->node)) - { - ipAddrToDottedIP (&pAddr->addr.ia, buf, sizeof(buf)); - printf(" %s\n", buf); - } - - if (casIgnoreAddrs[0]) { /* 0 indicates end of array */ - size_t i; - printf("Ignoring UDP messages from address%s\n", - n == 1 ? "" : "es"); - for(i=0; casIgnoreAddrs[i]; i++) - { - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = casIgnoreAddrs[i]; - addr.sin_port = 0; - ipAddrToDottedIP(&addr, buf, sizeof(buf)); - printf(" %s\n", buf); - } - } - } - - if (level>=4u) { - bytes_reserved = 0u; - bytes_reserved += sizeof (struct client) * - freeListItemsAvail (rsrvClientFreeList); - bytes_reserved += sizeof (struct channel_in_use) * - freeListItemsAvail (rsrvChanFreeList); - bytes_reserved += sizeof(struct event_ext) * - freeListItemsAvail (rsrvEventFreeList); - bytes_reserved += MAX_TCP * - freeListItemsAvail ( rsrvSmallBufFreeListTCP ); - if(rsrvLargeBufFreeListTCP) { - bytes_reserved += rsrvSizeofLargeBufTCP * - freeListItemsAvail ( rsrvLargeBufFreeListTCP ); - } - bytes_reserved += rsrvSizeOfPutNotify ( 0 ) * - freeListItemsAvail ( rsrvPutNotifyFreeList ); - printf( "Free-lists total %u bytes, comprising\n", - (unsigned int) bytes_reserved); - printf( " %u client(s), %u channel(s), %u monitor event(s), %u putNotify(s)\n", - (unsigned int) freeListItemsAvail ( rsrvClientFreeList ), - (unsigned int) freeListItemsAvail ( rsrvChanFreeList ), - (unsigned int) freeListItemsAvail ( rsrvEventFreeList ), - (unsigned int) freeListItemsAvail ( rsrvPutNotifyFreeList )); - printf( " %u small (%u byte) buffers, %u jumbo (%u byte) buffers\n", - (unsigned int) freeListItemsAvail ( rsrvSmallBufFreeListTCP ), - MAX_TCP, - (unsigned int)(rsrvLargeBufFreeListTCP ? freeListItemsAvail ( rsrvLargeBufFreeListTCP ) : -1), - rsrvSizeofLargeBufTCP ); - printf( "Server resource id table:\n"); - LOCK_CLIENTQ; - bucketShow (pCaBucket); - UNLOCK_CLIENTQ; - } -} - -/* - * destroy_client () - */ -void destroy_client ( struct client *client ) -{ - if ( ! client ) { - return; - } - - if ( client->tid != 0 ) { - taskwdRemove ( client->tid ); - } - - if ( client->sock != INVALID_SOCKET ) { - epicsSocketDestroy ( client->sock ); - } - - if ( client->proto == IPPROTO_TCP ) { - if ( client->send.buf ) { - if ( client->send.type == mbtSmallTCP ) { - freeListFree ( rsrvSmallBufFreeListTCP, client->send.buf ); - } - else if ( client->send.type == mbtLargeTCP ) { - if(rsrvLargeBufFreeListTCP) - freeListFree ( rsrvLargeBufFreeListTCP, client->send.buf ); - else - free(client->send.buf); - } - else { - errlogPrintf ( "CAS: Corrupt send buffer free list type code=%u during client cleanup?\n", - client->send.type ); - } - } - if ( client->recv.buf ) { - if ( client->recv.type == mbtSmallTCP ) { - freeListFree ( rsrvSmallBufFreeListTCP, client->recv.buf ); - } - else if ( client->recv.type == mbtLargeTCP ) { - if(rsrvLargeBufFreeListTCP) - freeListFree ( rsrvLargeBufFreeListTCP, client->recv.buf ); - else - free(client->recv.buf); - } - else { - errlogPrintf ( "CAS: Corrupt recv buffer free list type code=%u during client cleanup?\n", - client->send.type ); - } - } - } - else if ( client->proto == IPPROTO_UDP ) { - if ( client->send.buf ) { - free ( client->send.buf ); - } - if ( client->recv.buf ) { - free ( client->recv.buf ); - } - } - - if ( client->eventqLock ) { - epicsMutexDestroy ( client->eventqLock ); - } - - if ( client->chanListLock ) { - epicsMutexDestroy ( client->chanListLock ); - } - - if ( client->putNotifyLock ) { - epicsMutexDestroy ( client->putNotifyLock ); - } - - if ( client->lock ) { - epicsMutexDestroy ( client->lock ); - } - - if ( client->blockSem ) { - epicsEventDestroy ( client->blockSem ); - } - - if ( client->pUserName ) { - free ( client->pUserName ); - } - - if ( client->pHostName ) { - free ( client->pHostName ); - } - - freeListFree ( rsrvClientFreeList, client ); -} - -static void destroyAllChannels ( - struct client * client, ELLLIST * pList ) -{ - if ( !client->chanListLock || !client->eventqLock ) { - return; - } - - while ( TRUE ) { - struct event_ext *pevext; - int status; - struct channel_in_use *pciu; - - epicsMutexMustLock ( client->chanListLock ); - pciu = (struct channel_in_use *) ellGet ( pList ); - if(pciu) pciu->state = rsrvCS_shutdown; - epicsMutexUnlock ( client->chanListLock ); - - if ( ! pciu ) { - break; - } - - while ( TRUE ) { - /* - * AS state change could be using this list - */ - epicsMutexMustLock ( client->eventqLock ); - pevext = (struct event_ext *) ellGet ( &pciu->eventq ); - epicsMutexUnlock ( client->eventqLock ); - - if ( ! pevext ) { - break; - } - - if ( pevext->pdbev ) { - db_cancel_event (pevext->pdbev); - } - freeListFree (rsrvEventFreeList, pevext); - } - rsrvFreePutNotify ( client, pciu->pPutNotify ); - LOCK_CLIENTQ; - status = bucketRemoveItemUnsignedId ( pCaBucket, &pciu->sid); - rsrvChannelCount--; - UNLOCK_CLIENTQ; - if ( status != S_bucket_success ) { - errPrintf ( status, __FILE__, __LINE__, - "Bad id=%d at close", pciu->sid); - } - status = asRemoveClient(&pciu->asClientPVT); - if ( status && status != S_asLib_asNotActive ) { - printf ( "bad asRemoveClient() status was %x \n", status ); - errPrintf ( status, __FILE__, __LINE__, "asRemoveClient" ); - } - - dbChannelDelete(pciu->dbch); - freeListFree ( rsrvChanFreeList, pciu ); - } -} - -void destroy_tcp_client ( struct client *client ) -{ - int status; - - if ( CASDEBUG > 0 ) { - errlogPrintf ( "CAS: Connection %d Terminated\n", client->sock ); - } - - if ( client->evuser ) { - /* - * turn off extra labor callbacks from the event thread - */ - status = db_add_extra_labor_event ( client->evuser, NULL, NULL ); - assert ( ! status ); - - /* - * wait for extra labor in progress to comple - */ - db_flush_extra_labor_event ( client->evuser ); - } - - destroyAllChannels ( client, & client->chanList ); - destroyAllChannels ( client, & client->chanPendingUpdateARList ); - - if ( client->evuser ) { - db_close_events (client->evuser); - } - - destroy_client ( client ); -} - -/* - * create_client () - */ -struct client * create_client ( SOCKET sock, int proto ) -{ - struct client *client; - int spaceAvailOnFreeList; - size_t spaceNeeded; - - /* - * stop further use of server if memory becomes scarse - */ - spaceAvailOnFreeList = freeListItemsAvail ( rsrvClientFreeList ) > 0 - && freeListItemsAvail ( rsrvSmallBufFreeListTCP ) > 0; - spaceNeeded = sizeof (struct client) + MAX_TCP; - if ( ! ( osiSufficentSpaceInPool(spaceNeeded) || spaceAvailOnFreeList ) ) { - epicsSocketDestroy ( sock ); - epicsPrintf ("CAS: no space in pool for a new client (below max block thresh)\n"); - return NULL; - } - - client = freeListCalloc ( rsrvClientFreeList ); - if ( ! client ) { - epicsSocketDestroy ( sock ); - epicsPrintf ("CAS: no space in pool for a new client (alloc failed)\n"); - return NULL; - } - - client->sock = sock; - client->proto = proto; - - client->blockSem = epicsEventCreate ( epicsEventEmpty ); - client->lock = epicsMutexCreate(); - client->putNotifyLock = epicsMutexCreate(); - client->chanListLock = epicsMutexCreate(); - client->eventqLock = epicsMutexCreate(); - if ( ! client->blockSem || ! client->lock || ! client->putNotifyLock || - ! client->chanListLock || ! client->eventqLock ) { - destroy_client ( client ); - return NULL; - } - - client->pUserName = NULL; - client->pHostName = NULL; - ellInit ( & client->chanList ); - ellInit ( & client->chanPendingUpdateARList ); - ellInit ( & client->putNotifyQue ); - memset ( (char *)&client->addr, 0, sizeof (client->addr) ); - client->tid = 0; - - if ( proto == IPPROTO_TCP ) { - client->send.buf = (char *) freeListCalloc ( rsrvSmallBufFreeListTCP ); - client->send.maxstk = MAX_TCP; - client->send.type = mbtSmallTCP; - client->recv.buf = (char *) freeListCalloc ( rsrvSmallBufFreeListTCP ); - client->recv.maxstk = MAX_TCP; - client->recv.type = mbtSmallTCP; - } - else if ( proto == IPPROTO_UDP ) { - client->send.buf = malloc ( MAX_UDP_SEND ); - client->send.maxstk = MAX_UDP_SEND; - client->send.type = mbtUDP; - client->recv.buf = malloc ( MAX_UDP_RECV ); - client->recv.maxstk = MAX_UDP_RECV; - client->recv.type = mbtUDP; - } - if ( ! client->send.buf || ! client->recv.buf ) { - destroy_client ( client ); - return NULL; - } - client->send.stk = 0u; - client->send.cnt = 0u; - client->recv.stk = 0u; - client->recv.cnt = 0u; - client->evuser = NULL; - client->priority = CA_PROTO_PRIORITY_MIN; - client->disconnect = FALSE; - epicsTimeGetCurrent ( &client->time_at_last_send ); - epicsTimeGetCurrent ( &client->time_at_last_recv ); - client->minor_version_number = CA_UKN_MINOR_VERSION; - client->recvBytesToDrain = 0u; - - return client; -} - -void casAttachThreadToClient ( struct client *pClient ) -{ - epicsSignalInstallSigAlarmIgnore (); - epicsSignalInstallSigPipeIgnore (); - pClient->tid = epicsThreadGetIdSelf (); - epicsThreadPrivateSet ( rsrvCurrentClient, pClient ); - taskwdInsert ( pClient->tid, NULL, NULL ); -} - -static -void casExpandBuffer ( struct message_buffer *buf, ca_uint32_t size, int sendbuf ) -{ - char *newbuf = NULL; - unsigned newsize; - enum messageBufferType newtype; - - assert (size > MAX_TCP); - - if ( size <= buf->maxstk || buf->type == mbtUDP ) return; - - /* try to alloc new buffer */ - if (size <= MAX_TCP) { - return; /* shouldn't happen */ - - } else if(!rsrvLargeBufFreeListTCP) { - // round up to multiple of 4K - size = ((size-1)|0xfff)+1; - - if (buf->type==mbtLargeTCP) - newbuf = realloc (buf->buf, size); - else - newbuf = malloc (size); - newtype = mbtLargeTCP; - newsize = size; - - } else if (size <= rsrvSizeofLargeBufTCP) { - newbuf = freeListCalloc ( rsrvLargeBufFreeListTCP ); - newsize = rsrvSizeofLargeBufTCP; - newtype = mbtLargeTCP; - } - - if (newbuf) { - /* copy existing buffer */ - if (sendbuf) { - /* send buffer uses [0, stk) */ - if (!rsrvLargeBufFreeListTCP && buf->type==mbtLargeTCP) { - /* realloc already copied */ - } else { - memcpy ( newbuf, buf->buf, buf->stk ); - } - } else { - /* recv buffer uses [stk, cnt) */ - unsigned used; - assert ( buf->cnt >= buf->stk ); - used = buf->cnt - buf->stk; - - /* buf->buf may be the same as newbuf if realloc() used */ - memmove ( newbuf, &buf->buf[buf->stk], used ); - - buf->cnt = used; - buf->stk = 0; - - } - - /* free existing buffer */ - if(buf->type==mbtSmallTCP) { - freeListFree ( rsrvSmallBufFreeListTCP, buf->buf ); - } else if(buf->type==mbtLargeTCP) { - freeListFree ( rsrvLargeBufFreeListTCP, buf->buf ); - } else { - /* realloc() already free()'d if necessary */ - } - - buf->buf = newbuf; - buf->type = newtype; - buf->maxstk = newsize; - } -} - -void casExpandSendBuffer ( struct client *pClient, ca_uint32_t size ) -{ - casExpandBuffer (&pClient->send, size, 1); -} - -void casExpandRecvBuffer ( struct client *pClient, ca_uint32_t size ) -{ - casExpandBuffer (&pClient->recv, size, 0); -} - -/* - * create_tcp_client () - */ -struct client *create_tcp_client ( SOCKET sock ) -{ - int status; - struct client *client; - int intTrue = TRUE; - osiSocklen_t addrSize; - unsigned priorityOfEvents; - - /* socket passed in is destroyed here if unsuccessful */ - client = create_client ( sock, IPPROTO_TCP ); - if ( ! client ) { - return NULL; - } - - /* - * see TCP(4P) this seems to make unsolicited single events much - * faster. I take care of queue up as load increases. - */ - status = setsockopt ( sock, IPPROTO_TCP, TCP_NODELAY, - (char *) &intTrue, sizeof (intTrue) ); - if (status < 0) { - errlogPrintf ( "CAS: TCP_NODELAY option set failed\n" ); - destroy_client ( client ); - return NULL; - } - - /* - * turn on KEEPALIVE so if the client crashes - * this task will find out and exit - */ - status = setsockopt ( sock, SOL_SOCKET, SO_KEEPALIVE, - (char *) &intTrue, sizeof (intTrue) ); - if ( status < 0 ) { - errlogPrintf ( "CAS: SO_KEEPALIVE option set failed\n" ); - destroy_client ( client ); - return NULL; - } - - /* - * some concern that vxWorks will run out of mBuf's - * if this change is made - * - * joh 11-10-98 - */ -#if 0 - /* - * set TCP buffer sizes to be synergistic - * with CA internal buffering - */ - i = MAX_MSG_SIZE; - status = setsockopt ( sock, SOL_SOCKET, SO_SNDBUF, (char *) &i, sizeof (i) ); - if (status < 0) { - errlogPrintf ( "CAS: SO_SNDBUF set failed\n" ); - destroy_client ( client ); - return NULL; - } - i = MAX_MSG_SIZE; - status = setsockopt ( sock, SOL_SOCKET, SO_RCVBUF, (char *) &i, sizeof (i) ); - if (status < 0) { - errlogPrintf ( "CAS: SO_RCVBUF set failed\n" ); - destroy_client ( client ); - return NULL; - } -#endif - - addrSize = sizeof ( client->addr ); - status = getpeername ( sock, (struct sockaddr *)&client->addr, - &addrSize ); - if ( status < 0 ) { - epicsPrintf ("CAS: peer address fetch failed\n"); - destroy_tcp_client (client); - return NULL; - } - - client->evuser = (struct event_user *) db_init_events (); - if ( ! client->evuser ) { - errlogPrintf ("CAS: unable to init the event facility\n"); - destroy_tcp_client (client); - return NULL; - } - - status = db_add_extra_labor_event ( client->evuser, rsrv_extra_labor, client ); - if (status != DB_EVENT_OK) { - errlogPrintf("CAS: unable to setup the event facility\n"); - destroy_tcp_client (client); - return NULL; - } - - { - epicsThreadBooleanStatus tbs; - - tbs = epicsThreadHighestPriorityLevelBelow ( epicsThreadPriorityCAServerLow, &priorityOfEvents ); - if ( tbs != epicsThreadBooleanStatusSuccess ) { - priorityOfEvents = epicsThreadPriorityCAServerLow; - } - } - - status = db_start_events ( client->evuser, "CAS-event", - NULL, NULL, priorityOfEvents ); - if ( status != DB_EVENT_OK ) { - errlogPrintf ( "CAS: unable to start the event facility\n" ); - destroy_tcp_client ( client ); - return NULL; - } - - /* - * add first version message should it be needed - */ - rsrv_version_reply ( client ); - - if ( CASDEBUG > 0 ) { - char buf[64]; - ipAddrToDottedIP ( &client->addr, buf, sizeof(buf) ); - errlogPrintf ( "CAS: conn req from %s\n", buf ); - } - - return client; -} - -void casStatsFetch ( unsigned *pChanCount, unsigned *pCircuitCount ) -{ - LOCK_CLIENTQ; - { - int circuitCount = ellCount ( &clientQ ); - if ( circuitCount < 0 ) { - *pCircuitCount = 0; - } - else { - *pCircuitCount = (unsigned) circuitCount; - } - *pChanCount = rsrvChannelCount; - } - UNLOCK_CLIENTQ; -} diff --git a/src/ioc/rsrv/cast_server.c b/src/ioc/rsrv/cast_server.c deleted file mode 100644 index be5ec15c6..000000000 --- a/src/ioc/rsrv/cast_server.c +++ /dev/null @@ -1,293 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - * Date: 5-88 - * - * Improvements - * ------------ - * .01 - * Dont send channel found message unless there is memory, a task slot, - * and a TCP socket available. Send a diagnostic instead. - * Or ... make the timeout shorter? This is only a problem if - * they persist in trying to make a connection after getting no - * response. - * - * Notes: - * ------ - * .01 - * Replies to broadcasts are not returned over - * an existing TCP connection to avoid a TCP - * pend which could lock up the cast server. - */ - - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "envDefs.h" -#include "epicsMutex.h" -#include "epicsTime.h" -#include "errlog.h" -#include "freeList.h" -#include "osiSock.h" -#include "taskwd.h" - -#define epicsExportSharedSymbols -#include "rsrv.h" -#include "server.h" - -#define TIMEOUT 60.0 /* sec */ - -/* - * clean_addrq - */ -static void clean_addrq(struct client *client) -{ - struct channel_in_use * pciu; - struct channel_in_use * pnextciu; - epicsTimeStamp current; - double delay; - double maxdelay = 0; - unsigned ndelete=0; - double timeout = TIMEOUT; - int s; - - epicsTimeGetCurrent ( ¤t ); - - epicsMutexMustLock ( client->chanListLock ); - pnextciu = (struct channel_in_use *) - client->chanList.node.next; - - while( (pciu = pnextciu) ) { - pnextciu = (struct channel_in_use *)pciu->node.next; - - delay = epicsTimeDiffInSeconds(¤t,&pciu->time_at_creation); - if (delay > timeout) { - - ellDelete(&client->chanList, &pciu->node); - LOCK_CLIENTQ; - s = bucketRemoveItemUnsignedId ( - pCaBucket, - &pciu->sid); - if(s){ - errMessage (s, "Bad id at close"); - } - else { - rsrvChannelCount--; - } - UNLOCK_CLIENTQ; - if ( ! s ) { - freeListFree(rsrvChanFreeList, pciu); - ndelete++; - } - if(delay>maxdelay) maxdelay = delay; - } - } - epicsMutexUnlock ( client->chanListLock ); - -# ifdef DEBUG - if(ndelete){ - epicsPrintf ("CAS: %d CA channels have expired after %f sec\n", - ndelete, maxdelay); - } -# endif - -} - -/* - * CAST_SERVER - * - * service UDP messages - * - */ -void cast_server(void *pParm) -{ - rsrv_iface_config *conf = pParm; - int status; - int count=0; - int mysocket=0; - struct sockaddr_in new_recv_addr; - osiSocklen_t recv_addr_size; - osiSockIoctl_t nchars; - SOCKET recv_sock, reply_sock; - struct client *client; - - recv_addr_size = sizeof(new_recv_addr); - - reply_sock = conf->udp; - - /* - * setup new client structure but reuse old structure if - * possible - * - */ - while ( TRUE ) { - client = create_client ( reply_sock, IPPROTO_UDP ); - if ( client ) { - break; - } - epicsThreadSleep(300.0); - } - if (conf->startbcast) { - recv_sock = conf->udpbcast; - conf->bclient = client; - } - else { - recv_sock = conf->udp; - conf->client = client; - } - client->udpRecv = recv_sock; - - casAttachThreadToClient ( client ); - - /* - * add placeholder for the first version message should it be needed - */ - rsrv_version_reply ( client ); - - /* these pointers become invalid after signaling casudp_startStopEvent */ - conf = NULL; - - epicsEventSignal(casudp_startStopEvent); - - while (TRUE) { - status = recvfrom ( - recv_sock, - client->recv.buf, - client->recv.maxstk, - 0, - (struct sockaddr *)&new_recv_addr, - &recv_addr_size); - if (status < 0) { - if (SOCKERRNO != SOCK_EINTR) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - epicsPrintf ("CAS: UDP recv error (errno=%s)\n", - sockErrBuf); - epicsThreadSleep(1.0); - } - - } else { - size_t idx; - for(idx=0; casIgnoreAddrs[idx]; idx++) - { - if(new_recv_addr.sin_addr.s_addr==casIgnoreAddrs[idx]) { - status = -1; /* ignore */ - break; - } - } - } - - if (status >= 0 && casudp_ctl == ctlRun) { - client->recv.cnt = (unsigned) status; - client->recv.stk = 0ul; - epicsTimeGetCurrent(&client->time_at_last_recv); - - client->minor_version_number = CA_UKN_MINOR_VERSION; - client->seqNoOfReq = 0; - - /* - * If we are talking to a new client flush to the old one - * in case we are holding UDP messages waiting to - * see if the next message is for this same client. - */ - if (client->send.stk>sizeof(caHdr)) { - status = memcmp(&client->addr, - &new_recv_addr, recv_addr_size); - if(status){ - /* - * if the address is different - */ - cas_send_dg_msg(client); - client->addr = new_recv_addr; - } - } - else { - client->addr = new_recv_addr; - } - - if (CASDEBUG>1) { - char buf[40]; - - ipAddrToDottedIP (&client->addr, buf, sizeof(buf)); - errlogPrintf ("CAS: cast server msg of %d bytes from addr %s\n", - client->recv.cnt, buf); - } - - if (CASDEBUG>2) - count = ellCount (&client->chanList); - - status = camessage ( client ); - if(status == RSRV_OK){ - if(client->recv.cnt != - client->recv.stk){ - char buf[40]; - - ipAddrToDottedIP (&client->addr, buf, sizeof(buf)); - - epicsPrintf ("CAS: partial (damaged?) UDP msg of %d bytes from %s ?\n", - client->recv.cnt - client->recv.stk, buf); - - epicsTimeToStrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", - &client->time_at_last_recv); - epicsPrintf ("CAS: message received at %s\n", buf); - } - } - else if (CASDEBUG>0){ - char buf[40]; - - ipAddrToDottedIP (&client->addr, buf, sizeof(buf)); - - epicsPrintf ("CAS: invalid (damaged?) UDP request from %s ?\n", buf); - - epicsTimeToStrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", - &client->time_at_last_recv); - epicsPrintf ("CAS: message received at %s\n", buf); - } - - if (CASDEBUG>2) { - if ( ellCount (&client->chanList) ) { - errlogPrintf ("CAS: Fnd %d name matches (%d tot)\n", - ellCount(&client->chanList)-count, - ellCount(&client->chanList)); - } - } - } - - /* - * allow messages to batch up if more are comming - */ - nchars = 0; /* supress purify warning */ - status = socket_ioctl(recv_sock, FIONREAD, &nchars); - if (status<0) { - errlogPrintf ("CA cast server: Unable to fetch N characters pending\n"); - cas_send_dg_msg (client); - clean_addrq (client); - } - else if (nchars == 0) { - cas_send_dg_msg (client); - clean_addrq (client); - } - } - - /* ATM never reached, just a placeholder */ - - if(!mysocket) - client->sock = INVALID_SOCKET; /* only one cast_server should destroy the reply socket */ - destroy_client(client); - epicsSocketDestroy(recv_sock); -} diff --git a/src/ioc/rsrv/online_notify.c b/src/ioc/rsrv/online_notify.c deleted file mode 100644 index d1d557943..000000000 --- a/src/ioc/rsrv/online_notify.c +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * tell CA clients this a server has joined the network - * - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - * Date: 103090 - * - */ - -#include -#include -#include -#include -#include - -#include "addrList.h" -#include "dbDefs.h" -#include "envDefs.h" -#include "errlog.h" -#include "osiSock.h" -#include "taskwd.h" - -#define epicsExportSharedSymbols -#include "server.h" - -/* - * RSRV_ONLINE_NOTIFY_TASK - */ -void rsrv_online_notify_task(void *pParm) -{ - double delay; - double maxdelay; - long longStatus; - double maxPeriod; - caHdr msg; - int status; - ca_uint32_t beaconCounter = 0; - char buf[16]; - - taskwdInsert (epicsThreadGetIdSelf(),NULL,NULL); - - if ( envGetConfigParamPtr ( & EPICS_CAS_BEACON_PERIOD ) ) { - longStatus = envGetDoubleConfigParam ( & EPICS_CAS_BEACON_PERIOD, & maxPeriod ); - } - else { - longStatus = envGetDoubleConfigParam ( & EPICS_CA_BEACON_PERIOD, & maxPeriod ); - } - if (longStatus || maxPeriod<=0.0) { - maxPeriod = 15.0; - epicsPrintf ("EPICS \"%s\" float fetch failed\n", - EPICS_CAS_BEACON_PERIOD.name); - epicsPrintf ("Setting \"%s\" = %f\n", - EPICS_CAS_BEACON_PERIOD.name, maxPeriod); - } - - delay = 0.02; /* initial beacon period in sec */ - maxdelay = maxPeriod; - - memset((char *)&msg, 0, sizeof msg); - msg.m_cmmd = htons (CA_PROTO_RSRV_IS_UP); - msg.m_count = htons (ca_server_port); - msg.m_dataType = htons (CA_MINOR_PROTOCOL_REVISION); - - - epicsEventSignal(beacon_startStopEvent); - - while (TRUE) { - ELLNODE *cur; - - /* send beacon to each interface */ - for(cur=ellFirst(&beaconAddrList); cur; cur=ellNext(cur)) - { - osiSockAddrNode *pAddr = CONTAINER(cur, osiSockAddrNode, node); - status = sendto (beaconSocket, (char *)&msg, sizeof(msg), 0, - &pAddr->addr.sa, sizeof(pAddr->addr)); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - ipAddrToDottedIP (&pAddr->addr.ia, buf, sizeof(buf)); - errlogPrintf ( "%s: CA beacon (send to \"%s\") error was \"%s\"\n", - __FILE__, buf, sockErrBuf); - } - else { - assert (status == sizeof(msg)); - } - } - - epicsThreadSleep(delay); - if (delaymaxdelay) { - delay = maxdelay; - } - } - - msg.m_cid = htonl ( beaconCounter++ ); /* expected to overflow */ - - while (beacon_ctl == ctlPause) { - epicsThreadSleep(0.1); - delay = 0.02; /* Restart beacon timing if paused */ - } - } -} - - diff --git a/src/ioc/rsrv/rsrv.h b/src/ioc/rsrv/rsrv.h deleted file mode 100644 index 10947cdf0..000000000 --- a/src/ioc/rsrv/rsrv.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - * Date: 5-88 - */ - -#ifndef rsrvh -#define rsrvh - -#include -#include "shareLib.h" - -#define RSRV_OK 0 -#define RSRV_ERROR (-1) - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int rsrv_init(void); -epicsShareFunc int rsrv_run(void); -epicsShareFunc int rsrv_pause(void); - -epicsShareFunc void casr (unsigned level); -epicsShareFunc int casClientInitiatingCurrentThread ( - char * pBuf, size_t bufSize ); -epicsShareFunc void casStatsFetch ( - unsigned *pChanCount, unsigned *pConnCount ); - -#ifdef __cplusplus -} -#endif - -#endif /*rsrvh */ diff --git a/src/ioc/rsrv/rsrvIocRegister.c b/src/ioc/rsrv/rsrvIocRegister.c deleted file mode 100644 index 7a01fc9f6..000000000 --- a/src/ioc/rsrv/rsrvIocRegister.c +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "iocsh.h" - -#define epicsExportSharedSymbols -#include "rsrv.h" -#include "rsrvIocRegister.h" - -/* casr */ -static const iocshArg casrArg0 = { "level",iocshArgInt}; -static const iocshArg * const casrArgs[1] = {&casrArg0}; -static const iocshFuncDef casrFuncDef = {"casr",1,casrArgs}; -static void casrCallFunc(const iocshArgBuf *args) -{ - casr(args[0].ival); -} - - -void rsrvIocRegister(void) -{ - iocshRegister(&casrFuncDef,casrCallFunc); -} diff --git a/src/ioc/rsrv/rsrvIocRegister.h b/src/ioc/rsrv/rsrvIocRegister.h deleted file mode 100644 index f4c7e31f1..000000000 --- a/src/ioc/rsrv/rsrvIocRegister.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_rsrvIocRegister_H -#define INC_rsrvIocRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void rsrvIocRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_rsrvIocRegister_H */ diff --git a/src/ioc/rsrv/server.h b/src/ioc/rsrv/server.h deleted file mode 100644 index 7ace5ad7c..000000000 --- a/src/ioc/rsrv/server.h +++ /dev/null @@ -1,258 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * - */ - -#ifndef INCLserverh -#define INCLserverh - -#ifdef epicsExportSharedSymbols -# define rsrvRestore_epicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif /* ifdef epicsExportSharedSymbols */ - -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "bucketLib.h" -#include "asLib.h" -#include "dbChannel.h" -#include "dbNotify.h" -#define CA_MINOR_PROTOCOL_REVISION 13 -#include "caProto.h" -#include "ellLib.h" -#include "epicsTime.h" -#include "epicsAssert.h" -#include "osiSock.h" - -#ifdef rsrvRestore_epicsExportSharedSymbols -#define epicsExportSharedSymbols -#endif - -/* a modified ca header with capacity for large arrays */ -typedef struct caHdrLargeArray { - ca_uint32_t m_postsize; /* size of message extension */ - ca_uint32_t m_count; /* operation data count */ - ca_uint32_t m_cid; /* channel identifier */ - ca_uint32_t m_available; /* protocol stub dependent */ - ca_uint16_t m_dataType; /* operation data type */ - ca_uint16_t m_cmmd; /* operation to be performed */ -} caHdrLargeArray; - -/* - * !! buf must be the first item in this structure !! - * This guarantees that buf will have 8 byte natural - * alignment - * - * The terminating unsigned pad0 field is there to force the - * length of the message_buffer to be a multiple of 8 bytes. - * This is due to the sequential placing of two message_buffer - * structures (trans, rec) within the client structure. - * Eight-byte alignment is required by the Sparc 5 and other RISC - * processors. - */ -enum messageBufferType { mbtUDP, mbtSmallTCP, mbtLargeTCP }; -struct message_buffer { - char *buf; - unsigned stk; - unsigned maxstk; - unsigned cnt; - enum messageBufferType type; -}; - -extern epicsThreadPrivateId rsrvCurrentClient; - -typedef struct client { - ELLNODE node; - struct message_buffer send; - struct message_buffer recv; - epicsMutexId lock; - epicsMutexId putNotifyLock; - epicsMutexId chanListLock; - epicsMutexId eventqLock; - ELLLIST chanList; - ELLLIST chanPendingUpdateARList; - ELLLIST putNotifyQue; - struct sockaddr_in addr; - epicsTimeStamp time_at_last_send; - epicsTimeStamp time_at_last_recv; - void *evuser; - char *pUserName; - char *pHostName; - epicsEventId blockSem; /* used whenever the client blocks */ - SOCKET sock, udpRecv; - int proto; - epicsThreadId tid; - unsigned minor_version_number; - ca_uint32_t seqNoOfReq; /* for udp */ - unsigned recvBytesToDrain; - unsigned priority; - char disconnect; /* disconnect detected */ -} client; - -/* Channel state shows which struct client list a - * channel_in_us::node is in. - * - * client::chanList - * rsrvCS_pendConnectResp, rsrvCS_inService - * client::chanPendingUpdateARList - * rsrvCS_pendConnectRespUpdatePendAR, rsrvCS_inServiceUpdatePendAR - * Not in any list - * rsrvCS_shutdown - * - * rsrvCS_invalid is not used - */ -enum rsrvChanState { - rsrvCS_invalid, - rsrvCS_pendConnectResp, - rsrvCS_inService, - rsrvCS_pendConnectRespUpdatePendAR, - rsrvCS_inServiceUpdatePendAR, - rsrvCS_shutdown -}; - -/* - * per channel structure - * (stored in chanList or chanPendingUpdateARList off of a client block) - */ -struct channel_in_use { - ELLNODE node; - ELLLIST eventq; - struct client *client; - struct rsrv_put_notify *pPutNotify; /* potential active put notify */ - const unsigned cid; /* client id */ - const unsigned sid; /* server id */ - epicsTimeStamp time_at_creation; /* for UDP timeout */ - struct dbChannel *dbch; - ASCLIENTPVT asClientPVT; - enum rsrvChanState state; -}; - -/* - * Event block extension for channel access - * some things duplicated for speed - */ -struct event_ext { - ELLNODE node; - caHdrLargeArray msg; - struct channel_in_use *pciu; - struct event_block *pdbev; /* ptr to db event block */ - unsigned size; /* for speed */ - unsigned mask; - char modified; /* mod & ev flw ctrl enbl */ -}; - -typedef struct { - ELLNODE node; - osiSockAddr tcpAddr, /* TCP listener endpoint */ - udpAddr, /* UDP name unicast receiver endpoint */ - udpbcastAddr; /* UDP name broadcast receiver endpoint */ - SOCKET tcp, udp, udpbcast; - struct client *client, *bclient; - - unsigned int startbcast:1; -} rsrv_iface_config; - -enum ctl {ctlInit, ctlRun, ctlPause, ctlExit}; - -/* NOTE: external used so they remember the state across loads */ -#ifdef GLBLSOURCE -# define GLBLTYPE -# define GLBLTYPE_INIT(A) = A -#else -# define GLBLTYPE extern -# define GLBLTYPE_INIT(A) -#endif - -/* - * for debug-level dependent messages: - */ -#ifdef DEBUG -# define DLOG(LEVEL,ARGSINPAREN) \ - if (CASDEBUG > LEVEL) errlogPrintf ARGSINPAREN -#else -# define DLOG(LEVEL,ARGSINPAREN) -#endif - -GLBLTYPE int CASDEBUG; -GLBLTYPE unsigned short ca_server_port, ca_udp_port, ca_beacon_port; -GLBLTYPE ELLLIST clientQ GLBLTYPE_INIT(ELLLIST_INIT); -GLBLTYPE ELLLIST servers; /* rsrv_iface_config::node, read-only after rsrv_init() */ -GLBLTYPE ELLLIST beaconAddrList; -GLBLTYPE SOCKET beaconSocket; -GLBLTYPE ELLLIST casIntfAddrList, casMCastAddrList; -GLBLTYPE epicsUInt32 *casIgnoreAddrs; -GLBLTYPE epicsMutexId clientQlock; -GLBLTYPE BUCKET *pCaBucket; /* locked by clientQlock */ -GLBLTYPE void *rsrvClientFreeList; -GLBLTYPE void *rsrvChanFreeList; -GLBLTYPE void *rsrvEventFreeList; -GLBLTYPE void *rsrvSmallBufFreeListTCP; -GLBLTYPE void *rsrvLargeBufFreeListTCP; -GLBLTYPE unsigned rsrvSizeofLargeBufTCP; -GLBLTYPE void *rsrvPutNotifyFreeList; -GLBLTYPE unsigned rsrvChannelCount; /* locked by clientQlock */ - -GLBLTYPE epicsEventId casudp_startStopEvent; -GLBLTYPE epicsEventId beacon_startStopEvent; -GLBLTYPE epicsEventId castcp_startStopEvent; -GLBLTYPE volatile enum ctl casudp_ctl; -GLBLTYPE volatile enum ctl beacon_ctl; -GLBLTYPE volatile enum ctl castcp_ctl; - -GLBLTYPE unsigned int threadPrios[5]; - -#define CAS_HASH_TABLE_SIZE 4096 - -#define SEND_LOCK(CLIENT) epicsMutexMustLock((CLIENT)->lock) -#define SEND_UNLOCK(CLIENT) epicsMutexUnlock((CLIENT)->lock) - -#define LOCK_CLIENTQ epicsMutexMustLock (clientQlock); -#define UNLOCK_CLIENTQ epicsMutexUnlock (clientQlock); - -void camsgtask (void *client); -void cas_send_bs_msg ( struct client *pclient, int lock_needed ); -void cas_send_dg_msg ( struct client *pclient ); -void rsrv_online_notify_task (void *); -void cast_server (void *); -struct client *create_client ( SOCKET sock, int proto ); -void destroy_client ( struct client * ); -struct client *create_tcp_client ( SOCKET sock ); -void destroy_tcp_client ( struct client * ); -void casAttachThreadToClient ( struct client * ); -int camessage ( struct client *client ); -void rsrv_extra_labor ( void * pArg ); -int rsrvCheckPut ( const struct channel_in_use *pciu ); -int rsrv_version_reply ( struct client *client ); -void rsrvFreePutNotify ( struct client *pClient, - struct rsrv_put_notify *pNotify ); -void initializePutNotifyFreeList (void); -unsigned rsrvSizeOfPutNotify ( struct rsrv_put_notify *pNotify ); - -/* - * inclming protocol maintetnance - */ -void casExpandRecvBuffer ( struct client *pClient, ca_uint32_t size ); - -/* - * outgoing protocol maintenance - */ -void casExpandSendBuffer ( struct client *pClient, ca_uint32_t size ); -int cas_copy_in_header ( - struct client *pClient, ca_uint16_t response, ca_uint32_t payloadSize, - ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid, - ca_uint32_t responseSpecific, void **pPayload ); -void cas_set_header_cid ( struct client *pClient, ca_uint32_t ); -void cas_set_header_count (struct client *pClient, ca_uint32_t count); -void cas_commit_msg ( struct client *pClient, ca_uint32_t size ); - -#endif /*INCLserverh*/ diff --git a/src/libCom/Com.rc b/src/libCom/Com.rc deleted file mode 100644 index d5a5562b7..000000000 --- a/src/libCom/Com.rc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "epicsVersion.h" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - PRODUCTVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_UNKNOWN - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments","Common Library for EPICS\0" - VALUE "CompanyName", "The EPICS collaboration\0" - VALUE "FileDescription", "Common Library\0" - VALUE "FileVersion", EPICS_VERSION_STRING "\0" - VALUE "InternalName", "Com\0" - VALUE "LegalCopyright", "Copyright (C) Univ. of California, Univ. of Chicago\0" - VALUE "OriginalFilename", "Com.dll\0" - VALUE "ProductName", "Experimental Physics and Industrial Control System (EPICS)\0" - VALUE "ProductVersion", EPICS_VERSION_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/libCom/Makefile b/src/libCom/Makefile deleted file mode 100644 index ee93ada0a..000000000 --- a/src/libCom/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP = ../.. -include $(TOP)/configure/CONFIG - -# Uncomment this to remove the (benign) valgrind helper stubs -#USR_CFLAGS += -DNVALGRIND - -SRC = $(TOP)/src -LIBCOM = $(SRC)/libCom - -INC += valgrind/valgrind.h - -include $(LIBCOM)/as/Makefile -include $(LIBCOM)/bucketLib/Makefile -include $(LIBCOM)/calc/Makefile -include $(LIBCOM)/cvtFast/Makefile -include $(LIBCOM)/cppStd/Makefile -include $(LIBCOM)/cxxTemplates/Makefile -include $(LIBCOM)/dbmf/Makefile -include $(LIBCOM)/ellLib/Makefile -include $(LIBCOM)/env/Makefile -include $(LIBCOM)/error/Makefile -include $(LIBCOM)/fdmgr/Makefile -include $(LIBCOM)/flex/Makefile -include $(LIBCOM)/freeList/Makefile -include $(LIBCOM)/gpHash/Makefile -include $(LIBCOM)/iocsh/Makefile -include $(LIBCOM)/log/Makefile -include $(LIBCOM)/macLib/Makefile -include $(LIBCOM)/misc/Makefile -include $(LIBCOM)/osi/Makefile -include $(LIBCOM)/pool/Makefile -include $(LIBCOM)/ring/Makefile -include $(LIBCOM)/taskwd/Makefile -include $(LIBCOM)/timer/Makefile -include $(LIBCOM)/yacc/Makefile -include $(LIBCOM)/yajl/Makefile - -# Library to build: -LIBRARY=Com - -Com_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 - -Com_RCS = Com.rc - -ifeq ($(T_A),$(EPICS_HOST_ARCH)) - # Antelope & flex are needed to finish libCom - DELAY_INSTALL_LIBS = YES -endif - -include $(TOP)/configure/RULES - -include $(LIBCOM)/as/RULES -include $(LIBCOM)/env/RULES -include $(LIBCOM)/error/RULES -include $(LIBCOM)/flex/RULES -include $(LIBCOM)/misc/RULES -include $(LIBCOM)/osi/RULES - diff --git a/src/libCom/RTEMS/Makefile b/src/libCom/RTEMS/Makefile deleted file mode 100644 index 4c0b64c04..000000000 --- a/src/libCom/RTEMS/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../.. -include $(TOP)/configure/CONFIG - -INC += epicsRtemsInitHooks.h - -rtemsCom_SRCS += rtems_init.c -rtemsCom_SRCS += rtems_config.c -rtemsCom_SRCS += rtems_netconfig.c -rtemsCom_SRCS += rtems_util.c -rtemsCom_SRCS += setBootConfigFromNVRAM.c -rtemsCom_SRCS += epicsRtemsInitHookPre.c -rtemsCom_SRCS += epicsRtemsInitHookPost.c - -LIBRARY_RTEMS = rtemsCom - -include $(TOP)/configure/RULES diff --git a/src/libCom/RTEMS/epicsRtemsInitHookPost.c b/src/libCom/RTEMS/epicsRtemsInitHookPost.c deleted file mode 100644 index f589eb9cf..000000000 --- a/src/libCom/RTEMS/epicsRtemsInitHookPost.c +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Dummy version -- use if application does not provide its own version - */ -#include "epicsRtemsInitHooks.h" - -int -epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config) -{ - return 0; -} diff --git a/src/libCom/RTEMS/epicsRtemsInitHookPre.c b/src/libCom/RTEMS/epicsRtemsInitHookPre.c deleted file mode 100644 index 08efe1fe2..000000000 --- a/src/libCom/RTEMS/epicsRtemsInitHookPre.c +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Dummy version -- use if application does not provide its own version - */ -#include "epicsRtemsInitHooks.h" - -int -epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config) -{ - return 0; -} diff --git a/src/libCom/RTEMS/epicsRtemsInitHooks.h b/src/libCom/RTEMS/epicsRtemsInitHooks.h deleted file mode 100644 index b7f09c100..000000000 --- a/src/libCom/RTEMS/epicsRtemsInitHooks.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Hooks into RTEMS startup code - */ -#include -#include - -extern char *env_nfsServer; -extern char *env_nfsPath; -extern char *env_nfsMountPoint; - -/* - * Return 0 for success, non-zero for failure (will cause panic) - */ -int epicsRtemsInitPreSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config); -int epicsRtemsInitPostSetBootConfigFromNVRAM(struct rtems_bsdnet_config *config); diff --git a/src/libCom/RTEMS/rtems_config.c b/src/libCom/RTEMS/rtems_config.c deleted file mode 100644 index 147c08b10..000000000 --- a/src/libCom/RTEMS/rtems_config.c +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS configuration for EPICS - * Author: W. Eric Norum - * norume@aps.anl.gov - * (630) 252-4793 - */ - -#include - -/* - *********************************************************************** - * RTEMS CONFIGURATION * - *********************************************************************** - */ -#define CONFIGURE_RTEMS_INIT_TASKS_TABLE - -#if __RTEMS_MAJOR__>4 || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) -# define CONFIGURE_UNIFIED_WORK_AREAS -#else -# define CONFIGURE_EXECUTIVE_RAM_SIZE (2000*1024) -#endif - -#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(30) -#define CONFIGURE_MAXIMUM_SEMAPHORES rtems_resource_unlimited(500) -#define CONFIGURE_MAXIMUM_TIMERS rtems_resource_unlimited(20) -#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES rtems_resource_unlimited(5) -#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1 - -#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 150 -#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM -#define CONFIGURE_MAXIMUM_DRIVERS 8 - -#define CONFIGURE_MICROSECONDS_PER_TICK 20000 - -#define CONFIGURE_INIT_TASK_PRIORITY 80 - -#define CONFIGURE_MALLOC_STATISTICS 1 - -#define CONFIGURE_INIT -#define CONFIGURE_INIT_TASK_INITIAL_MODES (RTEMS_PREEMPT | \ - RTEMS_NO_TIMESLICE | \ - RTEMS_NO_ASR | \ - RTEMS_INTERRUPT_LEVEL(0)) -#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_FLOATING_POINT | RTEMS_LOCAL) -#define CONFIGURE_INIT_TASK_STACK_SIZE (16*1024) -rtems_task Init (rtems_task_argument argument); - -#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER -#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER - -#define CONFIGURE_FILESYSTEM_NFS -#define CONFIGURE_FILESYSTEM_IMFS - -/* - * This should be made BSP dependent, not CPU dependent but I know of no - * appropriate conditionals to use. - * The new general time support makes including the RTC driverr less important. - */ -#if !defined(mpc604) && !defined(__mc68040__) && !defined(__mcf5200__) && !defined(mpc7455) && !defined(__arm__) && !defined(__nios2__)/* don't have RTC code */ -#define CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER -#endif - - -#include -#include diff --git a/src/libCom/RTEMS/rtems_init.c b/src/libCom/RTEMS/rtems_init.c deleted file mode 100644 index 82871da0d..000000000 --- a/src/libCom/RTEMS/rtems_init.c +++ /dev/null @@ -1,668 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS startup task for EPICS - * Author: W. Eric Norum - * eric.norum@usask.ca - * (306) 966-5394 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsTime.h" -#include "epicsExit.h" -#include "envDefs.h" -#include "errlog.h" -#include "logClient.h" -#include "osiUnistd.h" -#include "iocsh.h" -#include "osdTime.h" - -#include "epicsRtemsInitHooks.h" - -/* - * Prototypes for some functions not in header files - */ -void tzset(void); -int fileno(FILE *); -int main(int argc, char **argv); - -static void -logReset (void) -{ - void rtems_bsp_reset_cause(char *buf, size_t capacity) __attribute__((weak)); - void (*fp)(char *buf, size_t capacity) = rtems_bsp_reset_cause; - - if (fp) { - char buf[80]; - fp(buf, sizeof buf); - errlogPrintf ("Startup after %s.\n", buf); - } - else { - errlogPrintf ("Startup.\n"); - } -} - -/* - *********************************************************************** - * FATAL ERROR REPORTING * - *********************************************************************** - */ -/* - * Delay for a while, then terminate - */ -static void -delayedPanic (const char *msg) -{ - extern rtems_interval rtemsTicksPerSecond; - - rtems_task_wake_after (rtemsTicksPerSecond); - rtems_panic (msg); -} - -/* - * Log error and terminate - */ -void -LogFatal (const char *msg, ...) -{ - va_list ap; - - va_start (ap, msg); - errlogVprintf (msg, ap); - va_end (ap); - delayedPanic (msg); -} - -/* - * Log RTEMS error and terminate - */ -void -LogRtemsFatal (const char *msg, rtems_status_code sc) -{ - errlogPrintf ("%s: %s\n", msg, rtems_status_text (sc)); - delayedPanic (msg); -} - -/* - * Log network error and terminate - */ -void -LogNetFatal (const char *msg, int err) -{ - errlogPrintf ("%s: %d\n", msg, err); - delayedPanic (msg); -} - -void * -mustMalloc(int size, const char *msg) -{ - void *p; - - if ((p = malloc (size)) == NULL) - LogFatal ("Can't allocate space for %s.\n", msg); - return p; -} - -/* - *********************************************************************** - * REMOTE FILE ACCESS * - *********************************************************************** - */ -#ifdef OMIT_NFS_SUPPORT -# include -#endif - -static int -initialize_local_filesystem(char **argv) -{ - extern char _DownloadLocation[] __attribute__((weak)); - extern char _FlashBase[] __attribute__((weak)); - extern char _FlashSize[] __attribute__((weak)); - - argv[0] = rtems_bsdnet_bootp_boot_file_name; - if (_FlashSize && (_DownloadLocation || _FlashBase)) { - extern char _edata[]; - size_t flashIndex = _edata - _DownloadLocation; - char *header = _FlashBase + flashIndex; - - if (memcmp(header + 257, "ustar ", 8) == 0) { - int fd; - printf ("***** Unpack in-memory file system (IMFS) *****\n"); - if (rtems_tarfs_load("/", (unsigned char *)header, (size_t)_FlashSize - flashIndex) != 0) { - printf("Can't unpack tar filesystem\n"); - return 0; - } - if ((fd = open(rtems_bsdnet_bootp_cmdline, 0)) >= 0) { - close(fd); - printf ("***** Found startup script (%s) in IMFS *****\n", rtems_bsdnet_bootp_cmdline); - argv[1] = rtems_bsdnet_bootp_cmdline; - return 1; - } - printf ("***** Startup script (%s) not in IMFS *****\n", rtems_bsdnet_bootp_cmdline); - } - } - return 0; -} - -#ifndef OMIT_NFS_SUPPORT -#if __RTEMS_MAJOR__>4 || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) -int -nfsMount(char *uidhost, char *path, char *mntpoint) -{ - int devl = strlen(uidhost) + strlen(path) + 2; - char *dev; - int rval = -1; - - if ((dev = malloc(devl)) == NULL) { - fprintf(stderr,"nfsMount: out of memory\n"); - return -1; - } - sprintf(dev, "%s:%s", uidhost, path); - printf("Mount %s on %s\n", dev, mntpoint); - if (rtems_mkdir(mntpoint, S_IRWXU | S_IRWXG | S_IRWXO)) - printf("Warning -- unable to make directory \"%s\"\n", mntpoint); - if (mount(dev, mntpoint, RTEMS_FILESYSTEM_TYPE_NFS, - RTEMS_FILESYSTEM_READ_WRITE, NULL)) { - perror("mount failed"); - } - else { - rval = 0; - } - free(dev); - return rval; -} -#define NFS_INIT -#else -#define NFS_INIT rpcUdpInit(); nfsInit(0,0); -#endif -#endif - -static void -initialize_remote_filesystem(char **argv, int hasLocalFilesystem) -{ -#ifdef OMIT_NFS_SUPPORT - printf ("***** Initializing TFTP *****\n"); -#if __RTEMS_MAJOR__>4 || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>9) || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==9 && __RTEMS_REVISION__==99) - mount_and_make_target_path(NULL, - "/TFTP", - RTEMS_FILESYSTEM_TYPE_TFTPFS, - RTEMS_FILESYSTEM_READ_WRITE, - NULL); -#else - rtems_bsdnet_initialize_tftp_filesystem (); -#endif - if (!hasLocalFilesystem) { - char *path; - int pathsize = 200; - int l; - - path = mustMalloc(pathsize, "Command path name "); - strcpy (path, "/TFTP/BOOTP_HOST/epics/"); - l = strlen (path); - if (gethostname (&path[l], pathsize - l - 10) || (path[l] == '\0')) - { - LogFatal ("Can't get host name"); - } - strcat (path, "/st.cmd"); - argv[1] = path; - } -#else - char *server_name; - char *server_path; - char *mount_point; - char *cp; - int l = 0; - - printf ("***** Initializing NFS *****\n"); - NFS_INIT - if (env_nfsServer && env_nfsPath && env_nfsMountPoint) { - server_name = env_nfsServer; - server_path = env_nfsPath; - mount_point = env_nfsMountPoint; - cp = mount_point; - while ((cp = strchr(cp+1, '/')) != NULL) { - *cp = '\0'; - if ((mkdir (mount_point, 0755) != 0) - && (errno != EEXIST)) - LogFatal("Can't create directory \"%s\": %s.\n", - mount_point, strerror(errno)); - *cp = '/'; - } - argv[1] = rtems_bsdnet_bootp_cmdline; - } - else if (hasLocalFilesystem) { - return; - } - else { - /* - * Use first component of nvram/bootp command line pathname - * to set up initial NFS mount. A "/tftpboot/" is prepended - * if the pathname does not begin with a '/'. This allows - * NFS and TFTP to have a similar view of the remote system. - */ - if (rtems_bsdnet_bootp_cmdline[0] == '/') - cp = rtems_bsdnet_bootp_cmdline + 1; - else - cp = rtems_bsdnet_bootp_cmdline; - cp = strchr(cp, '/'); - if ((cp == NULL) - || ((l = cp - rtems_bsdnet_bootp_cmdline) == 0)) - LogFatal("\"%s\" is not a valid command pathname.\n", rtems_bsdnet_bootp_cmdline); - cp = mustMalloc(l + 20, "NFS mount paths"); - server_path = cp; - server_name = rtems_bsdnet_bootp_server_name; - if (rtems_bsdnet_bootp_cmdline[0] == '/') { - mount_point = server_path; - strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l); - mount_point[l] = '\0'; - argv[1] = rtems_bsdnet_bootp_cmdline; - /* - * Its probably common to embed the mount point in the server - * name so, when this is occurring, dont clobber the mount point - * by appending the first node from the command path. This allows - * the mount point to be a different path then the server's mount - * path. - * - * This allows for example a line similar to as follows the DHCP - * configuration file. - * - * server-name "159.233@192.168.0.123:/vol/vol0/bootRTEMS"; - */ - if ( server_name ) { - const size_t allocSize = strlen ( server_name ) + 2; - char * const pServerName = mustMalloc( allocSize, - "NFS mount paths"); - char * const pServerPath = mustMalloc ( allocSize, - "NFS mount paths"); - const int scanfStatus = sscanf ( - server_name, - "%[^:] : / %s", - pServerName, - pServerPath + 1u ); - if ( scanfStatus == 2 ) { - pServerPath[0u]= '/'; - server_name = pServerName; - server_path = pServerPath; - } - else { - free ( pServerName ); - free ( pServerPath ); - } - } - } - else { - char *abspath = mustMalloc(strlen(rtems_bsdnet_bootp_cmdline)+2,"Absolute command path"); - strcpy(server_path, "/tftpboot/"); - mount_point = server_path + strlen(server_path); - strncpy(mount_point, rtems_bsdnet_bootp_cmdline, l); - mount_point[l] = '\0'; - mount_point--; - strcpy(abspath, "/"); - strcat(abspath, rtems_bsdnet_bootp_cmdline); - argv[1] = abspath; - } - } - errlogPrintf("nfsMount(\"%s\", \"%s\", \"%s\")\n", - server_name, server_path, mount_point); - nfsMount(server_name, server_path, mount_point); -#endif -} - -static -char rtems_etc_hosts[] = "127.0.0.1 localhost\n"; - -/* If it doesn't already exist, create /etc/hosts with an entry for 'localhost' */ -static -void fixup_hosts(void) -{ - FILE *fp; - int ret; - struct stat STAT; - - ret=stat("/etc/hosts", &STAT); - if(ret==0) - { - return; /* already exists, assume file */ - } else if(errno!=ENOENT) { - perror("error: fixup_hosts stat /etc/hosts"); - return; - } - - ret = mkdir("/etc", 0775); - if(ret!=0 && errno!=EEXIST) - { - perror("error: fixup_hosts create /etc"); - return; - } - - if((fp=fopen("/etc/hosts", "w"))==NULL) - { - perror("error: fixup_hosts create /etc/hosts"); - } - - if(fwrite(rtems_etc_hosts, 1, sizeof(rtems_etc_hosts)-1, fp)!=sizeof(rtems_etc_hosts)-1) - { - perror("error: failed to write /etc/hosts"); - } - - fclose(fp); -} - -/* - * Get to the startup script directory - * The TFTP filesystem requires a trailing '/' on chdir arguments. - */ -static void -set_directory (const char *commandline) -{ - const char *cp; - char *directoryPath; - int l; - - cp = strrchr(commandline, '/'); - if (cp == NULL) { - l = 0; - cp = "/"; - } - else { - l = cp - commandline; - cp = commandline; - } - directoryPath = mustMalloc(l + 2, "Command path directory "); - strncpy(directoryPath, cp, l); - directoryPath[l] = '/'; - directoryPath[l+1] = '\0'; - if (chdir (directoryPath) < 0) - LogFatal ("Can't set initial directory(%s): %s\n", directoryPath, strerror(errno)); - else - errlogPrintf("chdir(\"%s\")\n", directoryPath); - free(directoryPath); -} - -/* - *********************************************************************** - * RTEMS/EPICS COMMANDS * - *********************************************************************** - */ -/* - * RTEMS status - */ -static void -rtems_netstat (unsigned int level) -{ - rtems_bsdnet_show_if_stats (); - rtems_bsdnet_show_mbuf_stats (); - if (level >= 1) { - rtems_bsdnet_show_inet_routes (); - } - if (level >= 2) { - rtems_bsdnet_show_ip_stats (); - rtems_bsdnet_show_icmp_stats (); - rtems_bsdnet_show_udp_stats (); - rtems_bsdnet_show_tcp_stats (); - } -} - -static const iocshArg netStatArg0 = { "level",iocshArgInt}; -static const iocshArg * const netStatArgs[1] = {&netStatArg0}; -static const iocshFuncDef netStatFuncDef = {"netstat",1,netStatArgs}; -static void netStatCallFunc(const iocshArgBuf *args) -{ - rtems_netstat(args[0].ival); -} - -static const iocshFuncDef heapSpaceFuncDef = {"heapSpace",0,NULL}; -static void heapSpaceCallFunc(const iocshArgBuf *args) -{ - rtems_malloc_statistics_t s; - double x; - - malloc_get_statistics(&s); - x = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed); - if (x >= 1024*1024) - printf("Heap space: %.1f MB\n", x / (1024 * 1024)); - else - printf("Heap space: %.1f kB\n", x / 1024); -} - -#ifndef OMIT_NFS_SUPPORT -static const iocshArg nfsMountArg0 = { "[uid.gid@]host",iocshArgString}; -static const iocshArg nfsMountArg1 = { "server path",iocshArgString}; -static const iocshArg nfsMountArg2 = { "mount point",iocshArgString}; -static const iocshArg * const nfsMountArgs[3] = {&nfsMountArg0,&nfsMountArg1, - &nfsMountArg2}; -static const iocshFuncDef nfsMountFuncDef = {"nfsMount",3,nfsMountArgs}; -static void nfsMountCallFunc(const iocshArgBuf *args) -{ - char *cp = args[2].sval; - while ((cp = strchr(cp+1, '/')) != NULL) { - *cp = '\0'; - if ((mkdir (args[2].sval, 0755) != 0) && (errno != EEXIST)) { - printf("Can't create directory \"%s\": %s.\n", - args[2].sval, strerror(errno)); - return; - } - *cp = '/'; - } - nfsMount(args[0].sval, args[1].sval, args[2].sval); -} -#endif - -/* - * Register RTEMS-specific commands - */ -static void iocshRegisterRTEMS (void) -{ - iocshRegister(&netStatFuncDef, netStatCallFunc); - iocshRegister(&heapSpaceFuncDef, heapSpaceCallFunc); -#ifndef OMIT_NFS_SUPPORT - iocshRegister(&nfsMountFuncDef, nfsMountCallFunc); -#endif -} - -/* - * Set up the console serial line (no handshaking) - */ -static void -initConsole (void) -{ - struct termios t; - - if (tcgetattr (fileno (stdin), &t) < 0) { - printf ("tcgetattr failed: %s\n", strerror (errno)); - return; - } - t.c_iflag &= ~(IXOFF | IXON | IXANY); - if (tcsetattr (fileno (stdin), TCSANOW, &t) < 0) { - printf ("tcsetattr failed: %s\n", strerror (errno)); - return; - } -} - -/* - * Ensure that the configuration object files - * get pulled in from the library - */ -extern rtems_configuration_table Configuration; -extern struct rtems_bsdnet_config rtems_bsdnet_config; -const void *rtemsConfigArray[] = { - &Configuration, - &rtems_bsdnet_config -}; - -/* - * Hook to ensure that BSP cleanup code gets run on exit - */ -static void -exitHandler(void) -{ - rtems_shutdown_executive(0); -} - -/* - * RTEMS Startup task - */ -rtems_task -Init (rtems_task_argument ignored) -{ - int result; - char *argv[3] = { NULL, NULL, NULL }; - char *cp; - rtems_task_priority newpri; - rtems_status_code sc; - rtems_time_of_day now; - - /* - * Explain why we're here - */ - logReset(); - - /* - * Architecture-specific hooks - */ - if (epicsRtemsInitPreSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0) - delayedPanic("epicsRtemsInitPreSetBootConfigFromNVRAM"); - if (rtems_bsdnet_config.bootp == NULL) { - extern void setBootConfigFromNVRAM(void); - setBootConfigFromNVRAM(); - } - if (epicsRtemsInitPostSetBootConfigFromNVRAM(&rtems_bsdnet_config) != 0) - delayedPanic("epicsRtemsInitPostSetBootConfigFromNVRAM"); - - /* - * Override RTEMS configuration - */ - rtems_task_set_priority ( - RTEMS_SELF, - epicsThreadGetOssPriorityValue(epicsThreadPriorityIocsh), - &newpri); - - /* - * Create a reasonable environment - */ - initConsole (); - putenv ("TERM=xterm"); - putenv ("IOCSH_HISTSIZE=20"); - - /* - * Display some OS information - */ - printf("\n***** RTEMS Version: %s *****\n", - rtems_get_version_string()); - - /* - * Start network - */ - if ((cp = getenv("EPICS_TS_NTP_INET")) != NULL) - rtems_bsdnet_config.ntp_server[0] = cp; - if (rtems_bsdnet_config.network_task_priority == 0) - { - unsigned int p; - if (epicsThreadHighestPriorityLevelBelow(epicsThreadPriorityScanLow, &p) - == epicsThreadBooleanStatusSuccess) - { - rtems_bsdnet_config.network_task_priority = epicsThreadGetOssPriorityValue(p); - } - } - printf("\n***** Initializing network *****\n"); - rtems_bsdnet_initialize_network(); - initialize_remote_filesystem(argv, initialize_local_filesystem(argv)); - fixup_hosts(); - - /* - * More environment: iocsh prompt and hostname - */ - { - char hostname[1024]; - gethostname(hostname, 1023); - char *cp = mustMalloc(strlen(hostname)+3, "iocsh prompt"); - sprintf(cp, "%s> ", hostname); - epicsEnvSet ("IOCSH_PS1", cp); - epicsEnvSet("IOC_NAME", hostname); - } - - /* - * Use BSP-supplied time of day if available otherwise supply default time. - * It is very likely that other time synchronization facilities in EPICS - * will soon override this value. - */ - if (rtems_clock_get(RTEMS_CLOCK_GET_TOD,&now) != RTEMS_SUCCESSFUL) { - now.year = 2001; - now.month = 1; - now.day = 1; - now.hour = 0; - now.minute = 0; - now.second = 0; - now.ticks = 0; - if ((sc = rtems_clock_set (&now)) != RTEMS_SUCCESSFUL) - printf ("***** Can't set time: %s\n", rtems_status_text (sc)); - } - if (getenv("TZ") == NULL) { - const char *tzp = envGetConfigParamPtr(&EPICS_TIMEZONE); - if (tzp == NULL) { - printf("Warning -- no timezone information available -- times will be displayed as GMT.\n"); - } - else { - char tz[10]; - int minWest, toDst = 0, fromDst = 0; - if(sscanf(tzp, "%9[^:]::%d:%d:%d", tz, &minWest, &toDst, &fromDst) < 2) { - printf("Warning: EPICS_TIMEZONE (%s) unrecognizable -- times will be displayed as GMT.\n", tzp); - } - else { - char posixTzBuf[40]; - char *p = posixTzBuf; - p += sprintf(p, "%cST%d:%.2d", tz[0], minWest/60, minWest%60); - if (toDst != fromDst) - p += sprintf(p, "%cDT", tz[0]); - epicsEnvSet("TZ", posixTzBuf); - } - } - } - tzset(); - osdTimeRegister(); - - /* - * Run the EPICS startup script - */ - printf ("***** Preparing EPICS application *****\n"); - iocshRegisterRTEMS (); - set_directory (argv[1]); - epicsEnvSet ("IOC_STARTUP_SCRIPT", argv[1]); - atexit(exitHandler); - errlogFlush(); - printf ("***** Starting EPICS application *****\n"); - result = main ((sizeof argv / sizeof argv[0]) - 1, argv); - printf ("***** IOC application terminating *****\n"); - epicsThreadSleep(1.0); - epicsExit(result); -} diff --git a/src/libCom/RTEMS/rtems_netconfig.c b/src/libCom/RTEMS/rtems_netconfig.c deleted file mode 100644 index 832a6646b..000000000 --- a/src/libCom/RTEMS/rtems_netconfig.c +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS network configuration for EPICS - * Author: W. Eric Norum - * eric.norum@usask.ca - * (306) 966-5394 - * - * This file can be copied to an application source dirctory - * and modified to override the values shown below. - */ -#include -#include -#include - -extern void rtems_bsdnet_loopattach(); -static struct rtems_bsdnet_ifconfig loopback_config = { - "lo0", /* name */ - (int (*)(struct rtems_bsdnet_ifconfig *, int))rtems_bsdnet_loopattach, /* attach function */ - NULL, /* link to next interface */ - "127.0.0.1", /* IP address */ - "255.0.0.0", /* IP net mask */ -}; - -/* - * The following conditionals select the network interface card. - * - * On RTEMS-pc386 targets all network drivers which support run-time - * probing are linked. - * On other targets the network interface specified by the board-support - * package is used. - * To use a different NIC for a particular application, copy this file to the - * application directory and make the appropriate changes. - */ -#if defined(__i386__) -extern int rtems_fxp_attach (struct rtems_bsdnet_ifconfig *, int); -static struct rtems_bsdnet_ifconfig fxp_driver_config = { - "fxp1", /* name */ - rtems_fxp_attach, /* attach function */ - &loopback_config, /* link to next interface */ -}; -extern int rtems_3c509_driver_attach (struct rtems_bsdnet_ifconfig *, int); -static struct rtems_bsdnet_ifconfig e3c509_driver_config = { - "ep0", /* name */ - rtems_3c509_driver_attach, /* attach function */ - &fxp_driver_config, /* link to next interface */ -}; -#define FIRST_DRIVER_CONFIG &e3c509_driver_config -#else - -# if defined(__PPC) - /* - * FIXME: This really belongs in the BSP - */ -# ifndef RTEMS_BSP_NETWORK_DRIVER_NAME -# define RTEMS_BSP_NETWORK_DRIVER_NAME "dc1" -# endif -# ifndef RTEMS_BSP_NETWORK_DRIVER_ATTACH -# define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_dec21140_driver_attach - extern int rtems_dec21140_driver_attach(); -# endif -# endif - -static struct rtems_bsdnet_ifconfig bsp_driver_config = { - RTEMS_BSP_NETWORK_DRIVER_NAME, /* name */ - RTEMS_BSP_NETWORK_DRIVER_ATTACH, /* attach function */ - &loopback_config, /* link to next interface */ -}; -#define FIRST_DRIVER_CONFIG &bsp_driver_config - -#endif - -/* - * Allow configure/os/CONFIG_SITE.Common.RTEMS to provide domain name - */ -#ifdef RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME -# define XSTR(x) STR(x) -# define STR(x) #x -# define MY_DOMAINNAME XSTR(RTEMS_NETWORK_CONFIG_DNS_DOMAINNAME) -#else -# define MY_DOMAINNAME NULL -#endif - -/* - * Allow non-BOOTP network configuration - */ -#ifndef MY_DO_BOOTP -# define MY_DO_BOOTP rtems_bsdnet_do_bootp -#endif - -/* - * Allow site- and BSP-specific network buffer space configuration. - * The macro values are specified in KBytes. - */ -#ifndef RTEMS_NETWORK_CONFIG_MBUF_SPACE -# define RTEMS_NETWORK_CONFIG_MBUF_SPACE 180 -#endif -#ifndef RTEMS_NETWORK_CONFIG_CLUSTER_SPACE -# define RTEMS_NETWORK_CONFIG_CLUSTER_SPACE 350 -#endif - -/* - * Network configuration - */ -struct rtems_bsdnet_config rtems_bsdnet_config = { - FIRST_DRIVER_CONFIG, /* Link to next interface */ - MY_DO_BOOTP, /* How to find network config */ - 10, /* If 0 then the network daemons will run at a */ - /* priority just less than the lowest-priority */ - /* EPICS scan thread. */ - /* If non-zero then the network daemons will run */ - /* at this *RTEMS* priority */ - RTEMS_NETWORK_CONFIG_MBUF_SPACE*1024, - RTEMS_NETWORK_CONFIG_CLUSTER_SPACE*1024, - NULL, /* Host name */ - MY_DOMAINNAME, /* Domain name */ -}; diff --git a/src/libCom/RTEMS/rtems_util.c b/src/libCom/RTEMS/rtems_util.c deleted file mode 100644 index ca64f9650..000000000 --- a/src/libCom/RTEMS/rtems_util.c +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS utilitiy routines for EPICS - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - * - * Supplies routines that are present in vxWorks but missing in RTEMS. - */ - -#include -#include -#include -#include -#include -#include - -/* - * Like connect(), but with an explicit timeout - */ -int connectWithTimeout (int sfd, - struct sockaddr *addr, - int addrlen, - struct timeval *timeout) -{ - struct timeval sv; - socklen_t svlen = sizeof sv; - int ret; - - if (!timeout) - return connect (sfd, addr, addrlen); - if (getsockopt (sfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&sv, &svlen) < 0) - return -1; - if (setsockopt (sfd, SOL_SOCKET, SO_RCVTIMEO, (char *)timeout, sizeof *timeout) < 0) - return -1; - ret = connect (sfd, addr, addrlen); - setsockopt (sfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&sv, sizeof sv); - return ret; -} diff --git a/src/libCom/RTEMS/setBootConfigFromNVRAM.c b/src/libCom/RTEMS/setBootConfigFromNVRAM.c deleted file mode 100644 index 6a162c602..000000000 --- a/src/libCom/RTEMS/setBootConfigFromNVRAM.c +++ /dev/null @@ -1,370 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char *env_nfsServer; -char *env_nfsPath; -char *env_nfsMountPoint; - -/* - * Split argument string of form nfs_server:nfs_export: - * The nfs_export component will be used as: - * - the path to the directory exported from the NFS server - * - the local mount point - * - a prefix of - * For example, the argument string: - * romeo:/export/users:smith/ioc/iocexample/st.cmd - * would: - * - mount /export/users from NFS server romeo on /export/users - * - chdir to /export/users/smith/ioc/iocexample - * - read commands from st.cmd - */ -static void -splitRtemsBsdnetBootpCmdline(void) -{ - char *cp1, *cp2, *cp3; - - if ((cp1 = rtems_bsdnet_bootp_cmdline) == NULL) - return; - if (((cp2 = strchr(cp1, ':')) != NULL) - && (((cp3 = strchr(cp2+1, ' ')) != NULL) - || ((cp3 = strchr(cp2+1, ':')) != NULL))) { - int l1 = cp2 - cp1; - int l2 = cp3 - cp2 - 1; - int l3 = strlen(cp3) - 1; - if (l1 && l2 && l3) { - *cp2++ = '\0'; - *cp3 = '\0'; - env_nfsServer = cp1; - env_nfsMountPoint = env_nfsPath = epicsStrDup(cp2); - *cp3 = '/'; - rtems_bsdnet_bootp_cmdline = cp2; - } - } -} - -/* - * Split NFS mount information of the form nfs_server:host_path:local_path - */ -static void -splitNfsMountPath(char *nfsString) -{ - char *cp2, *cp3; - - if (nfsString == NULL) - return; - if (((cp2 = strchr(nfsString, ':')) != NULL) - && (((cp3 = strchr(cp2+1, ' ')) != NULL) - || ((cp3 = strchr(cp2+1, ':')) != NULL))) { - int l1 = cp2 - nfsString; - int l2 = cp3 - cp2 - 1; - int l3 = strlen(cp3) - 1; - if (l1 && l2 && l3) { - *cp2++ = '\0'; - *cp3++ = '\0'; - env_nfsServer = nfsString; - env_nfsPath = cp2; - env_nfsMountPoint = cp3; - } - } -} - -#if defined(HAVE_MOTLOAD) - -/* - * Motorola MOTLOAD NVRAM Access - */ -static char * -gev(const char *parm, volatile char *nvp) -{ - const char *val; - const char *name; - char *ret; - char c; - - for (;;) { - if (*nvp == '\0') - return NULL; - name = parm; - while ((c = *nvp++) != '\0') { - if ((c == '=') && (*name == '\0')) { - val = (char *)nvp; - while (*nvp++ != '\0') - continue; - ret = malloc(nvp - val); - if (ret == NULL) - return NULL; - strcpy(ret, val); - return ret; - } - if (c != *name++) { - while (*nvp++ != '\0') - continue; - break; - } - } - } -} - -static char * -motScriptParm(const char *mot_script_boot, char parm) -{ - const char *cp; - char *ret; - int l; - - while (*mot_script_boot != '\0') { - if (isspace(*(unsigned char *)mot_script_boot) - && (*(mot_script_boot+1) == '-') - && (*(mot_script_boot+2) == parm)) { - mot_script_boot += 3; - cp = mot_script_boot; - while ((*mot_script_boot != '\0') && - !isspace(*(unsigned char *)mot_script_boot)) - mot_script_boot++; - l = mot_script_boot - cp; - ret = malloc(l+1); - if (ret == NULL) - return NULL; - strncpy(ret, cp, l); - *(ret+l) = '\0'; - return ret; - } - mot_script_boot++; - } - return NULL; -} - -void -setBootConfigFromNVRAM(void) -{ - char *cp; - const char *mot_script_boot; - char *nvp; - -# if defined(BSP_NVRAM_BASE_ADDR) - nvp = (volatile unsigned char *)(BSP_NVRAM_BASE_ADDR+0x70f8); -# elif defined(BSP_I2C_VPD_EEPROM_DEV_NAME) - char gev_buf[3592]; - int fd; - if ((fd = open(BSP_I2C_VPD_EEPROM_DEV_NAME, 0)) < 0) { - printf("Can't open %s: %s\n", BSP_I2C_VPD_EEPROM_DEV_NAME, strerror(errno)); - return; - } - lseek(fd, 0x10f8, SEEK_SET); - if (read(fd, gev_buf, sizeof gev_buf) != sizeof gev_buf) { - printf("Can't read %s: %s\n", BSP_I2C_VPD_EEPROM_DEV_NAME, strerror(errno)); - return; - } - close(fd); - nvp = gev_buf; -# else -# error "No way to read GEV!" -# endif - - if (rtems_bsdnet_config.bootp != NULL) - return; - mot_script_boot = gev("mot-script-boot", nvp); - if ((rtems_bsdnet_bootp_server_name = gev("mot-/dev/enet0-sipa", nvp)) == NULL) - rtems_bsdnet_bootp_server_name = motScriptParm(mot_script_boot, 's'); - if ((rtems_bsdnet_config.gateway = gev("mot-/dev/enet0-gipa", nvp)) == NULL) - rtems_bsdnet_config.gateway = motScriptParm(mot_script_boot, 'g'); - if ((rtems_bsdnet_config.ifconfig->ip_netmask = gev("mot-/dev/enet0-snma", nvp)) == NULL) - rtems_bsdnet_config.ifconfig->ip_netmask = motScriptParm(mot_script_boot, 'm'); - - rtems_bsdnet_config.name_server[0] = gev("rtems-dns-server", nvp); - if (rtems_bsdnet_config.name_server[0] == NULL) - rtems_bsdnet_config.name_server[0] = rtems_bsdnet_bootp_server_name; - cp = gev("rtems-dns-domainname", nvp); - if (cp) - rtems_bsdnet_config.domainname = cp; - - if ((rtems_bsdnet_config.ifconfig->ip_address = gev("mot-/dev/enet0-cipa", nvp)) == NULL) - rtems_bsdnet_config.ifconfig->ip_address = motScriptParm(mot_script_boot, 'c'); - rtems_bsdnet_config.hostname = gev("rtems-client-name", nvp); - if (rtems_bsdnet_config.hostname == NULL) - rtems_bsdnet_config.hostname = rtems_bsdnet_config.ifconfig->ip_address; - - if ((rtems_bsdnet_bootp_boot_file_name = gev("mot-/dev/enet0-file", nvp)) == NULL) - rtems_bsdnet_bootp_boot_file_name = motScriptParm(mot_script_boot, 'f'); - rtems_bsdnet_bootp_cmdline = gev("epics-script", nvp); - splitRtemsBsdnetBootpCmdline(); - splitNfsMountPath(gev("epics-nfsmount", nvp)); - rtems_bsdnet_config.ntp_server[0] = gev("epics-ntpserver", nvp); - if (rtems_bsdnet_config.ntp_server[0] == NULL) - rtems_bsdnet_config.ntp_server[0] = rtems_bsdnet_bootp_server_name; - if ((cp = gev("epics-tz", nvp)) != NULL) - epicsEnvSet("TZ", cp); -} - -#elif defined(HAVE_PPCBUG) -/* - * Motorola PPCBUG NVRAM Access - */ -struct ppcbug_nvram { - uint32_t PacketVersionIdentifier; - uint32_t NodeControlMemoryAddress; - uint32_t BootFileLoadAddress; - uint32_t BootFileExecutionAddress; - uint32_t BootFileExecutionDelay; - uint32_t BootFileLength; - uint32_t BootFileByteOffset; - uint32_t TraceBufferAddress; - uint32_t ClientIPAddress; - uint32_t ServerIPAddress; - uint32_t SubnetIPAddressMask; - uint32_t BroadcastIPAddressMask; - uint32_t GatewayIPAddress; - uint8_t BootpRarpRetry; - uint8_t TftpRarpRetry; - uint8_t BootpRarpControl; - uint8_t UpdateControl; - char BootFilenameString[64]; - char ArgumentFilenameString[64]; -}; - -static char *addr(char *cbuf, uint32_t addr) -{ - struct in_addr a; - if ((a.s_addr = addr) == 0) - return NULL; - return (char *)inet_ntop(AF_INET, &a, cbuf, INET_ADDRSTRLEN); -} - -void -setBootConfigFromNVRAM(void) -{ - static struct ppcbug_nvram nvram; - static char ip_address[INET_ADDRSTRLEN]; - static char ip_netmask[INET_ADDRSTRLEN]; - static char server[INET_ADDRSTRLEN]; - static char gateway[INET_ADDRSTRLEN]; - - if (rtems_bsdnet_config.bootp != NULL) - return; - - /* - * Get network configuation from PPCBUG. - * The 'correct' way to do this would be to issue a .NETCFIG PPCBUG - * system call. Unfortunately it is very difficult to issue such a - * call once RTEMS is up and running so we just copy from the 'known' - * location of the network configuration parameters. - * Care must be taken to access the NVRAM a byte at a time. - */ - -#if defined(NVRAM_INDIRECT) - { - volatile char *addrLo = (volatile char *)0x80000074; - volatile char *addrHi = (volatile char *)0x80000075; - volatile char *data = (volatile char *)0x80000077; - int addr = 0x1000; - char *d = (char *)&nvram; - - while (d < ((char *)&nvram + sizeof nvram)) { - *addrLo = addr & 0xFF; - *addrHi = (addr >> 8) & 0xFF; - *d++ = *data; - addr++; - } - } -#else - { - volatile char *s = (volatile char *)0xFFE81000; - char *d = (char *)&nvram; - - while (d < ((char *)&nvram + sizeof nvram)) - *d++ = *s++; - } -#endif - /* - * Assume that the boot server is also the name, log and ntp server! - */ - rtems_bsdnet_config.name_server[0] = - rtems_bsdnet_config.ntp_server[0] = - rtems_bsdnet_bootp_server_name = addr(server, nvram.ServerIPAddress); - rtems_bsdnet_bootp_server_address.s_addr = nvram.ServerIPAddress; - /* - * Nothing better to use as host name! - */ - rtems_bsdnet_config.ifconfig->ip_address = - rtems_bsdnet_config.hostname = addr(ip_address, nvram.ClientIPAddress); - - rtems_bsdnet_config.gateway = addr(gateway, nvram.GatewayIPAddress); - rtems_bsdnet_config.ifconfig->ip_netmask = addr(ip_netmask, nvram.SubnetIPAddressMask); - - rtems_bsdnet_bootp_boot_file_name = nvram.BootFilenameString; - rtems_bsdnet_bootp_cmdline = nvram.ArgumentFilenameString; - splitRtemsBsdnetBootpCmdline(); -} - -#elif defined(__mcf528x__) - -static char * -env(const char *parm, const char *defaultValue) -{ - const char *cp = bsp_getbenv(parm); - - if (!cp) { - if (!defaultValue) - return NULL; - cp = defaultValue; - printf ("%s environment variable missing -- using %s.\n", parm, cp); - } - return epicsStrDup(cp); -} - -void -setBootConfigFromNVRAM(void) -{ - const char *cp1; - - if (rtems_bsdnet_config.bootp != NULL) - return; - rtems_bsdnet_config.gateway = env("GATEWAY", NULL); - rtems_bsdnet_config.ifconfig->ip_netmask = env("NETMASK", "255.255.252.0"); - - rtems_bsdnet_bootp_server_name = env("SERVER", "192.168.0.1"); - rtems_bsdnet_config.name_server[0] = env("NAMESERVER", rtems_bsdnet_bootp_server_name); - rtems_bsdnet_config.ntp_server[0] = env("NTPSERVER", rtems_bsdnet_bootp_server_name); - cp1 = env("DOMAIN", NULL); - if (cp1 != NULL) - rtems_bsdnet_config.domainname = cp1; - rtems_bsdnet_config.hostname = env("HOSTNAME", "iocNobody"); - rtems_bsdnet_config.ifconfig->ip_address = env("IPADDR0", "192.168.0.2"); - rtems_bsdnet_bootp_boot_file_name = env("BOOTFILE", "uC5282App.boot"); - rtems_bsdnet_bootp_cmdline = env("CMDLINE", "epics/iocBoot/iocNobody/st.cmd"); - splitNfsMountPath(env("NFSMOUNT", NULL)); - if ((cp1 = env("TZ", NULL)) != NULL) - epicsEnvSet("TZ", cp1); -} - -#else -/* - * Placeholder for systems without NVRAM - */ -void -setBootConfigFromNVRAM(void) -{ - printf("SYSTEM HAS NO NON-VOLATILE RAM!\n"); - printf("YOU MUST USE SOME OTHER METHOD TO OBTAIN NETWORK CONFIGURATION\n"); -} -#endif diff --git a/src/libCom/as/Makefile b/src/libCom/as/Makefile deleted file mode 100644 index 65f752018..000000000 --- a/src/libCom/as/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 Brookhaven Science Associates, as Operator of -# Brookhaven National Lab. -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************ - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/as - -INC += asLib.h -INC += asTrapWrite.h - -Com_SRCS += asLib.c -Com_SRCS += asTrapWrite.c - -CLEANS += asLib.c asLib_lex.c diff --git a/src/libCom/as/RULES b/src/libCom/as/RULES deleted file mode 100644 index a2a416f6e..000000000 --- a/src/libCom/as/RULES +++ /dev/null @@ -1,21 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 Brookhaven Science Associates, as Operator of -# Brookhaven National Lab. -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************ - -# This is a Makefile fragment, see src/libCom/Makefile. - -# Extra rule since asLib_lex.c is included by asLib.c -asLib$(DEP): asLib_lex.c -asLib.c: asLib_lex.c - -# Ensure that lexer and parser are built before they are needed -asLib.c: $(EPICS_BASE_HOST_BIN)/antelope$(HOSTEXE) -asLib_lex.c: $(EPICS_BASE_HOST_BIN)/e_flex$(HOSTEXE) -asLib_lex.c: $(INSTALL_INCLUDE)/flex.skel.static diff --git a/src/libCom/as/asLib.h b/src/libCom/as/asLib.h deleted file mode 100644 index 95fed7a9a..000000000 --- a/src/libCom/as/asLib.h +++ /dev/null @@ -1,244 +0,0 @@ -/* asLib.h */ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 09-27-93*/ - -#ifndef INCasLibh -#define INCasLibh - -#include "shareLib.h" -#include "ellLib.h" -#include "errMdef.h" -#include "errlog.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct asgMember *ASMEMBERPVT; -typedef struct asgClient *ASCLIENTPVT; -typedef int (*ASINPUTFUNCPTR)(char *buf,int max_size); -typedef enum{ - asClientCOAR /*Change of access rights*/ - /*For now this is all*/ -} asClientStatus; - -typedef void (*ASCLIENTCALLBACK) (ASCLIENTPVT,asClientStatus); - -/* The following routines are macros with the following syntax -long asCheckGet(ASCLIENTPVT asClientPvt); -long asCheckPut(ASCLIENTPVT asClientPvt); -*/ -#define asCheckGet(asClientPvt) \ - (!asActive || ((asClientPvt)->access >= asREAD)) -#define asCheckPut(asClientPvt) \ - (!asActive || ((asClientPvt)->access >= asWRITE)) - -/* More convenience macros -void *asTrapWriteWithData(ASCLIENTPVT asClientPvt, - const char *userid, const char *hostid, void *addr, - int dbrType, int no_elements, void *data); -void asTrapWriteAfter(ASCLIENTPVT asClientPvt); -*/ -#define asTrapWriteWithData(asClientPvt, user, host, addr, type, count, data) \ - ((asActive && (asClientPvt)->trapMask) \ - ? asTrapWriteBeforeWithData((user), (host), (addr), (type), (count), (data)) \ - : 0) -#define asTrapWriteAfter(pvt) \ - if (pvt) asTrapWriteAfterWrite(pvt) - -/* This macro is for backwards compatibility, upgrade any code - calling it to use asTrapWriteWithData() instead ASAP: -void *asTrapWriteBefore(ASCLIENTPVT asClientPvt, - const char *userid, const char *hostid, void *addr); -*/ -#define asTrapWriteBefore(asClientPvt, user, host, addr) \ - asTrapWriteWithData(asClientPvt, user, host, addr, 0, 0, NULL) - - -epicsShareFunc long epicsShareAPI asInitialize(ASINPUTFUNCPTR inputfunction); -epicsShareFunc long epicsShareAPI asInitFile( - const char *filename,const char *substitutions); -epicsShareFunc long epicsShareAPI asInitFP(FILE *fp,const char *substitutions); -/*caller must provide permanent storage for asgName*/ -epicsShareFunc long epicsShareAPI asAddMember( - ASMEMBERPVT *asMemberPvt,const char *asgName); -epicsShareFunc long epicsShareAPI asRemoveMember(ASMEMBERPVT *asMemberPvt); -/*caller must provide permanent storage for newAsgName*/ -epicsShareFunc long epicsShareAPI asChangeGroup( - ASMEMBERPVT *asMemberPvt,const char *newAsgName); -epicsShareFunc void * epicsShareAPI asGetMemberPvt(ASMEMBERPVT asMemberPvt); -epicsShareFunc void epicsShareAPI asPutMemberPvt( - ASMEMBERPVT asMemberPvt,void *userPvt); -/*client must provide permanent storage for user and host*/ -epicsShareFunc long epicsShareAPI asAddClient( - ASCLIENTPVT *asClientPvt,ASMEMBERPVT asMemberPvt, - int asl,const char *user,char *host); -/*client must provide permanent storage for user and host*/ -epicsShareFunc long epicsShareAPI asChangeClient( - ASCLIENTPVT asClientPvt,int asl,const char *user,char *host); -epicsShareFunc long epicsShareAPI asRemoveClient(ASCLIENTPVT *asClientPvt); -epicsShareFunc void * epicsShareAPI asGetClientPvt(ASCLIENTPVT asClientPvt); -epicsShareFunc void epicsShareAPI asPutClientPvt( - ASCLIENTPVT asClientPvt,void *userPvt); -epicsShareFunc long epicsShareAPI asRegisterClientCallback( - ASCLIENTPVT asClientPvt, ASCLIENTCALLBACK pcallback); -epicsShareFunc long epicsShareAPI asComputeAllAsg(void); -/* following declared below after ASG is declared -epicsShareFunc long epicsShareAPI asComputeAsg(ASG *pasg); -*/ -epicsShareFunc long epicsShareAPI asCompute(ASCLIENTPVT asClientPvt); -epicsShareFunc int epicsShareAPI asDump( - void (*memcallback)(ASMEMBERPVT,FILE *), - void (*clientcallback)(ASCLIENTPVT,FILE *),int verbose); -epicsShareFunc int epicsShareAPI asDumpFP(FILE *fp, - void (*memcallback)(ASMEMBERPVT,FILE *), - void (*clientcallback)(ASCLIENTPVT,FILE *),int verbose); -epicsShareFunc int epicsShareAPI asDumpUag(const char *uagname); -epicsShareFunc int epicsShareAPI asDumpUagFP(FILE *fp,const char *uagname); -epicsShareFunc int epicsShareAPI asDumpHag(const char *hagname); -epicsShareFunc int epicsShareAPI asDumpHagFP(FILE *fp,const char *hagname); -epicsShareFunc int epicsShareAPI asDumpRules(const char *asgname); -epicsShareFunc int epicsShareAPI asDumpRulesFP(FILE *fp,const char *asgname); -epicsShareFunc int epicsShareAPI asDumpMem(const char *asgname, - void (*memcallback)(ASMEMBERPVT,FILE *),int clients); -epicsShareFunc int epicsShareAPI asDumpMemFP(FILE *fp,const char *asgname, - void (*memcallback)(ASMEMBERPVT,FILE *),int clients); -epicsShareFunc int epicsShareAPI asDumpHash(void); -epicsShareFunc int epicsShareAPI asDumpHashFP(FILE *fp); - -epicsShareFunc void * epicsShareAPI asTrapWriteBeforeWithData( - const char *userid, const char *hostid, void *addr, - int dbrType, int no_elements, void *data); - -epicsShareFunc void epicsShareAPI asTrapWriteAfterWrite(void *pvt); - -#define S_asLib_clientsExist (M_asLib| 1) /*Client Exists*/ -#define S_asLib_noUag (M_asLib| 2) /*User Access Group does not exist*/ -#define S_asLib_noHag (M_asLib| 3) /*Host Access Group does not exist*/ -#define S_asLib_noAccess (M_asLib| 4) /*access security: no access allowed*/ -#define S_asLib_noModify (M_asLib| 5) /*access security: no modification allowed*/ -#define S_asLib_badConfig (M_asLib| 6) /*access security: bad configuration file*/ -#define S_asLib_badCalc (M_asLib| 7) /*access security: bad calculation espression*/ -#define S_asLib_dupAsg (M_asLib| 8) /*Duplicate Access Security Group */ -#define S_asLib_InitFailed (M_asLib| 9) /*access security: Init failed*/ -#define S_asLib_asNotActive (M_asLib|10) /*access security is not active*/ -#define S_asLib_badMember (M_asLib|11) /*access security: bad ASMEMBERPVT*/ -#define S_asLib_badClient (M_asLib|12) /*access security: bad ASCLIENTPVT*/ -#define S_asLib_badAsg (M_asLib|13) /*access security: bad ASG*/ -#define S_asLib_noMemory (M_asLib|14) /*access security: no Memory */ - -/*Private declarations */ -epicsShareExtern int asActive; - -/* definition of access rights*/ -typedef enum{asNOACCESS,asREAD,asWRITE} asAccessRights; - -struct gphPvt; - -/*Base pointers for access security*/ -typedef struct asBase{ - ELLLIST uagList; - ELLLIST hagList; - ELLLIST asgList; - struct gphPvt *phash; -} ASBASE; - -epicsShareExtern volatile ASBASE *pasbase; - -/*Defs for User Access Groups*/ -typedef struct{ - ELLNODE node; - char *user; -} UAGNAME; -typedef struct uag{ - ELLNODE node; - char *name; - ELLLIST list; /*list of UAGNAME*/ -} UAG; -/*Defs for Host Access Groups*/ -typedef struct{ - ELLNODE node; - char *host; -} HAGNAME; -typedef struct hag{ - ELLNODE node; - char *name; - ELLLIST list; /*list of HAGNAME*/ -} HAG; -/*Defs for Access SecurityGroups*/ -typedef struct { - ELLNODE node; - UAG *puag; -}ASGUAG; -typedef struct { - ELLNODE node; - HAG *phag; -}ASGHAG; -#define AS_TRAP_WRITE 1 -typedef struct{ - ELLNODE node; - asAccessRights access; - int level; - unsigned long inpUsed; /*bitmap of which inputs are used*/ - int result; /*Result of calc converted to TRUE/FALSE*/ - char *calc; - void *rpcl; - ELLLIST uagList; /*List of ASGUAG*/ - ELLLIST hagList; /*List of ASGHAG*/ - int trapMask; -} ASGRULE; -typedef struct{ - ELLNODE node; - char *inp; - void *capvt; - struct asg *pasg; - int inpIndex; -}ASGINP; - -typedef struct asg{ - ELLNODE node; - char *name; - ELLLIST inpList; - ELLLIST ruleList; - ELLLIST memberList; - double *pavalue; /*pointer to array of input values*/ - unsigned long inpBad; /*bitmap of which inputs are bad*/ - unsigned long inpChanged; /*bitmap of inputs that changed*/ -} ASG; -typedef struct asgMember { - ELLNODE node; - ASG *pasg; - ELLLIST clientList; - const char *asgName; - void *userPvt; -} ASGMEMBER; - -typedef struct asgClient { - ELLNODE node; - ASGMEMBER *pasgMember; - const char *user; - char *host; - void *userPvt; - ASCLIENTCALLBACK pcallback; - int level; - asAccessRights access; - int trapMask; -} ASGCLIENT; - -epicsShareFunc long epicsShareAPI asComputeAsg(ASG *pasg); -/*following is "friend" function*/ -epicsShareFunc void * epicsShareAPI asCalloc(size_t nobj,size_t size); -epicsShareFunc char * epicsShareAPI asStrdup(unsigned char *str); -epicsShareFunc void asFreeAll(ASBASE *pasbase); -#ifdef __cplusplus -} -#endif - -#endif /*INCasLibh*/ diff --git a/src/libCom/as/asLib.y b/src/libCom/as/asLib.y deleted file mode 100644 index 55d48ebad..000000000 --- a/src/libCom/as/asLib.y +++ /dev/null @@ -1,230 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -%{ -static int yyerror(char *); -static int yy_start; -#include "asLibRoutines.c" -static int yyFailed = FALSE; -static int line_num=1; -static UAG *yyUag=NULL; -static HAG *yyHag=NULL; -static ASG *yyAsg=NULL; -static ASGRULE *yyAsgRule=NULL; -%} - -%start asconfig - -%token tokenUAG tokenHAG tokenASG tokenRULE tokenCALC -%token tokenINP -%token tokenINTEGER -%token tokenSTRING - -%union -{ - int Int; - char *Str; -} - -%% - -asconfig: asconfig asconfig_item - | asconfig_item - -asconfig_item: tokenUAG uag_head uag_body - | tokenUAG uag_head - | tokenHAG hag_head hag_body - | tokenHAG hag_head - | tokenASG asg_head asg_body - | tokenASG asg_head - ; - -uag_head: '(' tokenSTRING ')' - { - yyUag = asUagAdd($2); - if(!yyUag) yyerror(""); - free((void *)$2); - } - ; - -uag_body: '{' uag_user_list '}' - { - ; - } - ; - -uag_user_list: uag_user_list ',' uag_user_list_name - | uag_user_list_name - ; - -uag_user_list_name: tokenSTRING - { - if (asUagAddUser(yyUag,$1)) - yyerror(""); - free((void *)$1); - } - ; - -hag_head: '(' tokenSTRING ')' - { - yyHag = asHagAdd($2); - if(!yyHag) yyerror(""); - free((void *)$2); - } - ; - -hag_body: '{' hag_host_list '}' - ; - -hag_host_list: hag_host_list ',' hag_host_list_name - | hag_host_list_name - ; - -hag_host_list_name: tokenSTRING - { - if (asHagAddHost(yyHag,$1)) - yyerror(""); - free((void *)$1); - } - ; - -asg_head: '(' tokenSTRING ')' - { - yyAsg = asAsgAdd($2); - if(!yyAsg) yyerror(""); - free((void *)$2); - } - ; - -asg_body: '{' asg_body_list '}' - { - } - -asg_body_list: asg_body_list asg_body_item - | asg_body_item - -asg_body_item: inp_config | rule_config - ; - -inp_config: tokenINP '(' tokenSTRING ')' - { - if (asAsgAddInp(yyAsg,$3,$1)) - yyerror(""); - free((void *)$3); - } - ; - -rule_config: tokenRULE rule_head rule_body - | tokenRULE rule_head - -rule_head: rule_head_manditory rule_head_options - -rule_head_manditory: '(' tokenINTEGER ',' tokenSTRING - { - asAccessRights rights; - - if((strcmp($4,"NONE")==0)) { - rights=asNOACCESS; - } else if((strcmp($4,"READ")==0)) { - rights=asREAD; - } else if((strcmp($4,"WRITE")==0)) { - rights=asWRITE; - } else { - yyerror("Access rights must be NONE, READ or WRITE"); - rights = asNOACCESS; - } - yyAsgRule = asAsgAddRule(yyAsg,rights,$2); - free((void *)$4); - } - ; - -rule_head_options: ')' - | rule_log_options - -rule_log_options: ',' tokenSTRING ')' - { - if((strcmp($2,"TRAPWRITE")==0)) { - long status; - status = asAsgAddRuleOptions(yyAsgRule,AS_TRAP_WRITE); - if(status) yyerror(""); - } else if((strcmp($2,"NOTRAPWRITE")!=0)) { - yyerror("Log options must be TRAPWRITE or NOTRAPWRITE"); - } - free((void *)$2); - } - ; - -rule_body: '{' rule_list '}' - ; - -rule_list: rule_list rule_list_item - | rule_list_item - ; - -rule_list_item: tokenUAG '(' rule_uag_list ')' - | tokenHAG '(' rule_hag_list ')' - | tokenCALC '(' tokenSTRING ')' - { - if (asAsgRuleCalc(yyAsgRule,$3)) - yyerror(""); - free((void *)$3); - } - ; - -rule_uag_list: rule_uag_list ',' rule_uag_list_name - | rule_uag_list_name - ; - -rule_uag_list_name: tokenSTRING - { - if (asAsgRuleUagAdd(yyAsgRule,$1)) - yyerror(""); - free((void *)$1); - } - ; - -rule_hag_list: rule_hag_list ',' rule_hag_list_name - | rule_hag_list_name - ; - -rule_hag_list_name: tokenSTRING - { - if (asAsgRuleHagAdd(yyAsgRule,$1)) - yyerror(""); - free((void *)$1); - } - ; -%% - -#include "asLib_lex.c" - -static int yyerror(char *str) -{ - if (strlen(str)) - errlogPrintf("%s at line %d\n", str, line_num); - else - errlogPrintf("Error at line %d\n", line_num); - yyFailed = TRUE; - return 0; -} -static int myParse(ASINPUTFUNCPTR inputfunction) -{ - static int FirstFlag = 1; - int rtnval; - - my_yyinput = &inputfunction; - if (!FirstFlag) { - line_num=1; - yyFailed = FALSE; - yyreset(); - yyrestart(NULL); - } - FirstFlag = 0; - rtnval = yyparse(); - if(rtnval!=0 || yyFailed) return(-1); else return(0); -} diff --git a/src/libCom/as/asLibRoutines.c b/src/libCom/as/asLibRoutines.c deleted file mode 100644 index e7f1d90bf..000000000 --- a/src/libCom/as/asLibRoutines.c +++ /dev/null @@ -1,1352 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 10-15-93 */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "dbDefs.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "gpHash.h" -#include "freeList.h" -#include "macLib.h" -#include "postfix.h" -#include "asLib.h" - -static epicsMutexId asLock; -#define LOCK epicsMutexMustLock(asLock) -#define UNLOCK epicsMutexUnlock(asLock) - -/*following must be global because asCa nneeds it*/ -epicsShareDef ASBASE volatile *pasbase=NULL; -static ASBASE *pasbasenew=NULL; -epicsShareDef int asActive = FALSE; - -static void *freeListPvt = NULL; - - -#define DEFAULT "DEFAULT" - -/* Defined in asLib.y */ -static int myParse(ASINPUTFUNCPTR inputfunction); - -/*private routines */ -static long asAddMemberPvt(ASMEMBERPVT *pasMemberPvt,const char *asgName); -static long asComputeAllAsgPvt(void); -static long asComputeAsgPvt(ASG *pasg); -static long asComputePvt(ASCLIENTPVT asClientPvt); -static UAG *asUagAdd(const char *uagName); -static long asUagAddUser(UAG *puag,const char *user); -static HAG *asHagAdd(const char *hagName); -static long asHagAddHost(HAG *phag,const char *host); -static ASG *asAsgAdd(const char *asgName); -static long asAsgAddInp(ASG *pasg,const char *inp,int inpIndex); -static ASGRULE *asAsgAddRule(ASG *pasg,asAccessRights access,int level); -static long asAsgAddRuleOptions(ASGRULE *pasgrule,int trapMask); -static long asAsgRuleUagAdd(ASGRULE *pasgrule,const char *name); -static long asAsgRuleHagAdd(ASGRULE *pasgrule,const char *name); -static long asAsgRuleCalc(ASGRULE *pasgrule,const char *calc); - -/* - asInitialize can be called while access security is already active. - This is accomplished by doing the following: - - The version pointed to by pasbase is kept as is but locked against changes - A new version is created and pointed to by pasbasenew - If anything goes wrong. The original version is kept. This results is some - wasted space but at least things still work. - If the new access security configuration is successfully read then: - the old memberList is moved from old to new. - the old structures are freed. -*/ -static void asInitializeOnce(void *arg) -{ - asLock = epicsMutexMustCreate(); -} -long epicsShareAPI asInitialize(ASINPUTFUNCPTR inputfunction) -{ - ASG *pasg; - long status; - ASBASE *pasbaseold; - GPHENTRY *pgphentry; - UAG *puag; - UAGNAME *puagname; - HAG *phag; - HAGNAME *phagname; - static epicsThreadOnceId asInitializeOnceFlag = EPICS_THREAD_ONCE_INIT; - - epicsThreadOnce(&asInitializeOnceFlag,asInitializeOnce,(void *)0); - LOCK; - pasbasenew = asCalloc(1,sizeof(ASBASE)); - if(!freeListPvt) freeListInitPvt(&freeListPvt,sizeof(ASGCLIENT),20); - ellInit(&pasbasenew->uagList); - ellInit(&pasbasenew->hagList); - ellInit(&pasbasenew->asgList); - asAsgAdd(DEFAULT); - status = myParse(inputfunction); - if(status) { - status = S_asLib_badConfig; - /*Not safe to call asFreeAll */ - UNLOCK; - return(status); - } - pasg = (ASG *)ellFirst(&pasbasenew->asgList); - while(pasg) { - pasg->pavalue = asCalloc(CALCPERFORM_NARGS, sizeof(double)); - pasg = (ASG *)ellNext(&pasg->node); - } - gphInitPvt(&pasbasenew->phash, 256); - /*Hash each uagname and each hagname*/ - puag = (UAG *)ellFirst(&pasbasenew->uagList); - while(puag) { - puagname = (UAGNAME *)ellFirst(&puag->list); - while(puagname) { - pgphentry = gphAdd(pasbasenew->phash,puagname->user,puag); - if(!pgphentry) { - errlogPrintf("Duplicated user '%s' in UAG '%s'\n", - puagname->user, puag->name); - } - puagname = (UAGNAME *)ellNext(&puagname->node); - } - puag = (UAG *)ellNext(&puag->node); - } - phag = (HAG *)ellFirst(&pasbasenew->hagList); - while(phag) { - phagname = (HAGNAME *)ellFirst(&phag->list); - while(phagname) { - pgphentry = gphAdd(pasbasenew->phash,phagname->host,phag); - if(!pgphentry) { - errlogPrintf("Duplicated host '%s' in HAG '%s'\n", - phagname->host, phag->name); - } - phagname = (HAGNAME *)ellNext(&phagname->node); - } - phag = (HAG *)ellNext(&phag->node); - } - pasbaseold = (ASBASE *)pasbase; - pasbase = (ASBASE volatile *)pasbasenew; - if(pasbaseold) { - ASG *poldasg; - ASGMEMBER *poldmem; - ASGMEMBER *pnextoldmem; - - poldasg = (ASG *)ellFirst(&pasbaseold->asgList); - while(poldasg) { - poldmem = (ASGMEMBER *)ellFirst(&poldasg->memberList); - while(poldmem) { - pnextoldmem = (ASGMEMBER *)ellNext(&poldmem->node); - ellDelete(&poldasg->memberList,&poldmem->node); - status = asAddMemberPvt(&poldmem,poldmem->asgName); - poldmem = pnextoldmem; - } - poldasg = (ASG *)ellNext(&poldasg->node); - } - asFreeAll(pasbaseold); - } - asActive = TRUE; - UNLOCK; - return(0); -} - -long epicsShareAPI asInitFile(const char *filename,const char *substitutions) -{ - FILE *fp; - long status; - - fp = fopen(filename,"r"); - if(!fp) { - errlogPrintf("asInitFile: Can't open file '%s'\n", filename); - return(S_asLib_badConfig); - } - status = asInitFP(fp,substitutions); - if(fclose(fp)==EOF) { - errMessage(0,"asInitFile: fclose failed!"); - if(!status) status = S_asLib_badConfig; - } - return(status); -} - -#define BUF_SIZE 200 -static char *my_buffer; -static char *my_buffer_ptr; -static FILE *stream; -static char *mac_input_buffer=NULL; -static MAC_HANDLE *macHandle = NULL; - -static int myInputFunction(char *buf, int max_size) -{ - int l,n; - char *fgetsRtn; - - if(*my_buffer_ptr==0) { - if(macHandle) { - fgetsRtn = fgets(mac_input_buffer,BUF_SIZE,stream); - if(fgetsRtn) { - n = macExpandString(macHandle,mac_input_buffer, - my_buffer,BUF_SIZE); - if(n<0) { - errlogPrintf("access security: macExpandString failed\n" - "input line: %s\n",mac_input_buffer); - return(0); - } - } - } else { - fgetsRtn = fgets(my_buffer,BUF_SIZE,stream); - } - if(fgetsRtn==NULL) return(0); - my_buffer_ptr = my_buffer; - } - l = strlen(my_buffer_ptr); - n = (l<=max_size ? l : max_size); - memcpy(buf,my_buffer_ptr,n); - my_buffer_ptr += n; - return(n); -} - -long epicsShareAPI asInitFP(FILE *fp,const char *substitutions) -{ - char buffer[BUF_SIZE]; - char mac_buffer[BUF_SIZE]; - long status; - char **macPairs; - - buffer[0] = 0; - my_buffer = buffer; - my_buffer_ptr = my_buffer; - stream = fp; - if(substitutions) { - if((status = macCreateHandle(&macHandle,NULL))) { - errMessage(status,"asInitFP: macCreateHandle error"); - return(status); - } - macParseDefns(macHandle,substitutions,&macPairs); - if(macPairs ==NULL) { - macDeleteHandle(macHandle); - macHandle = NULL; - } else { - macInstallMacros(macHandle,macPairs); - free(macPairs); - mac_input_buffer = mac_buffer; - } - } - status = asInitialize(myInputFunction); - if(macHandle) { - macDeleteHandle(macHandle); - macHandle = NULL; - } - return(status); -} - -long epicsShareAPI asAddMember(ASMEMBERPVT *pasMemberPvt,const char *asgName) -{ - long status; - - if(!asActive) return(S_asLib_asNotActive); - LOCK; - status = asAddMemberPvt(pasMemberPvt,asgName); - UNLOCK; - return(status); -} - -long epicsShareAPI asRemoveMember(ASMEMBERPVT *asMemberPvt) -{ - ASGMEMBER *pasgmember; - - if(!asActive) return(S_asLib_asNotActive); - pasgmember = *asMemberPvt; - if(!pasgmember) return(S_asLib_badMember); - LOCK; - if (ellCount(&pasgmember->clientList) > 0) { - UNLOCK; - return(S_asLib_clientsExist); - } - if(pasgmember->pasg) { - ellDelete(&pasgmember->pasg->memberList,&pasgmember->node); - } else { - errMessage(-1,"Logic error in asRemoveMember"); - UNLOCK; - return(-1); - } - free(pasgmember); - *asMemberPvt = NULL; - UNLOCK; - return(0); -} - -long epicsShareAPI asChangeGroup(ASMEMBERPVT *asMemberPvt,const char *newAsgName) -{ - ASGMEMBER *pasgmember; - long status; - - if(!asActive) return(S_asLib_asNotActive); - pasgmember = *asMemberPvt; - if(!pasgmember) return(S_asLib_badMember); - LOCK; - if(pasgmember->pasg) { - ellDelete(&pasgmember->pasg->memberList,&pasgmember->node); - } else { - errMessage(-1,"Logic error in asChangeGroup"); - UNLOCK; - return(-1); - } - status = asAddMemberPvt(asMemberPvt,newAsgName); - UNLOCK; - return(status); -} - -void * epicsShareAPI asGetMemberPvt(ASMEMBERPVT asMemberPvt) -{ - ASGMEMBER *pasgmember = asMemberPvt; - - if(!asActive) return(NULL); - if(!pasgmember) return(NULL); - return(pasgmember->userPvt); -} - -void epicsShareAPI asPutMemberPvt(ASMEMBERPVT asMemberPvt,void *userPvt) -{ - ASGMEMBER *pasgmember = asMemberPvt; - - if(!asActive) return; - if(!pasgmember) return; - pasgmember->userPvt = userPvt; - return; -} - -long epicsShareAPI asAddClient(ASCLIENTPVT *pasClientPvt,ASMEMBERPVT asMemberPvt, - int asl,const char *user,char *host) -{ - ASGMEMBER *pasgmember = asMemberPvt; - ASGCLIENT *pasgclient; - int len, i; - - long status; - if(!asActive) return(S_asLib_asNotActive); - if(!pasgmember) return(S_asLib_badMember); - pasgclient = freeListCalloc(freeListPvt); - if(!pasgclient) return(S_asLib_noMemory); - len = strlen(host); - for (i = 0; i < len; i++) { - host[i] = (char)tolower((int)host[i]); - } - *pasClientPvt = pasgclient; - pasgclient->pasgMember = asMemberPvt; - pasgclient->level = asl; - pasgclient->user = user; - pasgclient->host = host; - LOCK; - ellAdd(&pasgmember->clientList,&pasgclient->node); - status = asComputePvt(pasgclient); - UNLOCK; - return(status); -} - -long epicsShareAPI asChangeClient( - ASCLIENTPVT asClientPvt,int asl,const char *user,char *host) -{ - ASGCLIENT *pasgclient = asClientPvt; - long status; - int len, i; - - if(!asActive) return(S_asLib_asNotActive); - if(!pasgclient) return(S_asLib_badClient); - len = strlen(host); - for (i = 0; i < len; i++) { - host[i] = (char)tolower((int)host[i]); - } - LOCK; - pasgclient->level = asl; - pasgclient->user = user; - pasgclient->host = host; - status = asComputePvt(pasgclient); - UNLOCK; - return(status); -} - -long epicsShareAPI asRemoveClient(ASCLIENTPVT *asClientPvt) -{ - ASGCLIENT *pasgclient = *asClientPvt; - ASGMEMBER *pasgMember; - - if(!asActive) return(S_asLib_asNotActive); - if(!pasgclient) return(S_asLib_badClient); - LOCK; - pasgMember = pasgclient->pasgMember; - if(!pasgMember) { - errMessage(-1,"asRemoveClient: No ASGMEMBER"); - UNLOCK; - return(-1); - } - ellDelete(&pasgMember->clientList,&pasgclient->node); - UNLOCK; - freeListFree(freeListPvt,pasgclient); - *asClientPvt = NULL; - return(0); -} - -long epicsShareAPI asRegisterClientCallback(ASCLIENTPVT asClientPvt, - ASCLIENTCALLBACK pcallback) -{ - ASGCLIENT *pasgclient = asClientPvt; - - if(!asActive) return(S_asLib_asNotActive); - if(!pasgclient) return(S_asLib_badClient); - LOCK; - pasgclient->pcallback = pcallback; - (*pasgclient->pcallback)(pasgclient,asClientCOAR); - UNLOCK; - return(0); -} - -void * epicsShareAPI asGetClientPvt(ASCLIENTPVT asClientPvt) -{ - ASGCLIENT *pasgclient = asClientPvt; - - if(!asActive) return(NULL); - if(!pasgclient) return(NULL); - return(pasgclient->userPvt); -} - -void epicsShareAPI asPutClientPvt(ASCLIENTPVT asClientPvt,void *userPvt) -{ - ASGCLIENT *pasgclient = asClientPvt; - if(!asActive) return; - if(!pasgclient) return; - LOCK; - pasgclient->userPvt = userPvt; - UNLOCK; -} - -long epicsShareAPI asComputeAllAsg(void) -{ - long status; - - if(!asActive) return(S_asLib_asNotActive); - LOCK; - status = asComputeAllAsgPvt(); - UNLOCK; - return(status); -} - -long epicsShareAPI asComputeAsg(ASG *pasg) -{ - long status; - - if(!asActive) return(S_asLib_asNotActive); - LOCK; - status = asComputeAsgPvt(pasg); - UNLOCK; - return(status); -} - -long epicsShareAPI asCompute(ASCLIENTPVT asClientPvt) -{ - long status; - - if(!asActive) return(S_asLib_asNotActive); - LOCK; - status = asComputePvt(asClientPvt); - UNLOCK; - return(status); -} - -/*The dump routines do not lock. Thus they may get inconsistant data.*/ -/*HOWEVER if they did lock and a user interrupts one of then then BAD BAD*/ -static const char *asAccessName[] = {"NONE","READ","WRITE"}; -static const char *asTrapOption[] = {"NOTRAPWRITE","TRAPWRITE"}; -static const char *asLevelName[] = {"ASL0","ASL1"}; -int epicsShareAPI asDump( - void (*memcallback)(struct asgMember *,FILE *), - void (*clientcallback)(struct asgClient *,FILE *), - int verbose) -{ - return asDumpFP(stdout,memcallback,clientcallback,verbose); -} - -int epicsShareAPI asDumpFP( - FILE *fp, - void (*memcallback)(struct asgMember *,FILE *), - void (*clientcallback)(struct asgClient *,FILE *), - int verbose) -{ - UAG *puag; - UAGNAME *puagname; - HAG *phag; - HAGNAME *phagname; - ASG *pasg; - ASGINP *pasginp; - ASGRULE *pasgrule; - ASGHAG *pasghag; - ASGUAG *pasguag; - ASGMEMBER *pasgmember; - ASGCLIENT *pasgclient; - - if(!asActive) return(0); - puag = (UAG *)ellFirst(&pasbase->uagList); - if(!puag) fprintf(fp,"No UAGs\n"); - while(puag) { - fprintf(fp,"UAG(%s)",puag->name); - puagname = (UAGNAME *)ellFirst(&puag->list); - if(puagname) fprintf(fp," {"); else fprintf(fp,"\n"); - while(puagname) { - fprintf(fp,"%s",puagname->user); - puagname = (UAGNAME *)ellNext(&puagname->node); - if(puagname) fprintf(fp,","); else fprintf(fp,"}\n"); - } - puag = (UAG *)ellNext(&puag->node); - } - phag = (HAG *)ellFirst(&pasbase->hagList); - if(!phag) fprintf(fp,"No HAGs\n"); - while(phag) { - fprintf(fp,"HAG(%s)",phag->name); - phagname = (HAGNAME *)ellFirst(&phag->list); - if(phagname) fprintf(fp," {"); else fprintf(fp,"\n"); - while(phagname) { - fprintf(fp,"%s",phagname->host); - phagname = (HAGNAME *)ellNext(&phagname->node); - if(phagname) fprintf(fp,","); else fprintf(fp,"}\n"); - } - phag = (HAG *)ellNext(&phag->node); - } - pasg = (ASG *)ellFirst(&pasbase->asgList); - if(!pasg) fprintf(fp,"No ASGs\n"); - while(pasg) { - int print_end_brace; - - fprintf(fp,"ASG(%s)",pasg->name); - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - if(pasginp || pasgrule) { - fprintf(fp," {\n"); - print_end_brace = TRUE; - } else { - fprintf(fp,"\n"); - print_end_brace = FALSE; - } - while(pasginp) { - - fprintf(fp,"\tINP%c(%s)",(pasginp->inpIndex + 'A'),pasginp->inp); - if(verbose) { - if((pasg->inpBad & (1ul << pasginp->inpIndex))) - fprintf(fp," INVALID"); - else - fprintf(fp," VALID"); - fprintf(fp," value=%f",pasg->pavalue[pasginp->inpIndex]); - } - fprintf(fp,"\n"); - pasginp = (ASGINP *)ellNext(&pasginp->node); - } - while(pasgrule) { - int print_end_brace; - - fprintf(fp,"\tRULE(%d,%s,%s)", - pasgrule->level,asAccessName[pasgrule->access], - asTrapOption[pasgrule->trapMask]); - pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList); - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - if(pasguag || pasghag || pasgrule->calc) { - fprintf(fp," {\n"); - print_end_brace = TRUE; - } else { - fprintf(fp,"\n"); - print_end_brace = FALSE; - } - if(pasguag) fprintf(fp,"\t\tUAG("); - while(pasguag) { - fprintf(fp,"%s",pasguag->puag->name); - pasguag = (ASGUAG *)ellNext(&pasguag->node); - if(pasguag) fprintf(fp,","); else fprintf(fp,")\n"); - } - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - if(pasghag) fprintf(fp,"\t\tHAG("); - while(pasghag) { - fprintf(fp,"%s",pasghag->phag->name); - pasghag = (ASGHAG *)ellNext(&pasghag->node); - if(pasghag) fprintf(fp,","); else fprintf(fp,")\n"); - } - if(pasgrule->calc) { - fprintf(fp,"\t\tCALC(\"%s\")",pasgrule->calc); - if(verbose) - fprintf(fp," result=%s",(pasgrule->result==1 ? "TRUE" : "FALSE")); - fprintf(fp,"\n"); - } - if(print_end_brace) fprintf(fp,"\t}\n"); - pasgrule = (ASGRULE *)ellNext(&pasgrule->node); - } - pasgmember = (ASGMEMBER *)ellFirst(&pasg->memberList); - if(!verbose) pasgmember = NULL; - if(pasgmember) fprintf(fp,"\tMEMBERLIST\n"); - while(pasgmember) { - if(strlen(pasgmember->asgName)==0) - fprintf(fp,"\t\t"); - else - fprintf(fp,"\t\t%s",pasgmember->asgName); - if(memcallback) memcallback(pasgmember,fp); - fprintf(fp,"\n"); - pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); - while(pasgclient) { - fprintf(fp,"\t\t\t %s %s",pasgclient->user,pasgclient->host); - if(pasgclient->level>=0 && pasgclient->level<=1) - fprintf(fp," %s",asLevelName[pasgclient->level]); - else - fprintf(fp," Illegal Level %d",pasgclient->level); - if(pasgclient->access<=2) - fprintf(fp," %s %s", - asAccessName[pasgclient->access], - asTrapOption[pasgclient->trapMask]); - else - fprintf(fp," Illegal Access %d",pasgclient->access); - if(clientcallback) clientcallback(pasgclient,fp); - fprintf(fp,"\n"); - pasgclient = (ASGCLIENT *)ellNext(&pasgclient->node); - } - pasgmember = (ASGMEMBER *)ellNext(&pasgmember->node); - } - if(print_end_brace) fprintf(fp,"}\n"); - pasg = (ASG *)ellNext(&pasg->node); - } - return(0); -} - -int epicsShareAPI asDumpUag(const char *uagname) -{ - return asDumpUagFP(stdout,uagname); -} - -int epicsShareAPI asDumpUagFP(FILE *fp,const char *uagname) -{ - UAG *puag; - UAGNAME *puagname; - - if(!asActive) return(0); - puag = (UAG *)ellFirst(&pasbase->uagList); - if(!puag) fprintf(fp,"No UAGs\n"); - while(puag) { - if(uagname && strcmp(uagname,puag->name)!=0) { - puag = (UAG *)ellNext(&puag->node); - continue; - } - fprintf(fp,"UAG(%s)",puag->name); - puagname = (UAGNAME *)ellFirst(&puag->list); - if(puagname) fprintf(fp," {"); else fprintf(fp,"\n"); - while(puagname) { - fprintf(fp,"%s",puagname->user); - puagname = (UAGNAME *)ellNext(&puagname->node); - if(puagname) fprintf(fp,","); else fprintf(fp,"}\n"); - } - puag = (UAG *)ellNext(&puag->node); - } - return(0); -} - -int epicsShareAPI asDumpHag(const char *hagname) -{ - return asDumpHagFP(stdout,hagname); -} - -int epicsShareAPI asDumpHagFP(FILE *fp,const char *hagname) -{ - HAG *phag; - HAGNAME *phagname; - - if(!asActive) return(0); - phag = (HAG *)ellFirst(&pasbase->hagList); - if(!phag) fprintf(fp,"No HAGs\n"); - while(phag) { - if(hagname && strcmp(hagname,phag->name)!=0) { - phag = (HAG *)ellNext(&phag->node); - continue; - } - fprintf(fp,"HAG(%s)",phag->name); - phagname = (HAGNAME *)ellFirst(&phag->list); - if(phagname) fprintf(fp," {"); else fprintf(fp,"\n"); - while(phagname) { - fprintf(fp,"%s",phagname->host); - phagname = (HAGNAME *)ellNext(&phagname->node); - if(phagname) fprintf(fp,","); else fprintf(fp,"}\n"); - } - phag = (HAG *)ellNext(&phag->node); - } - return(0); -} - -int epicsShareAPI asDumpRules(const char *asgname) -{ - return asDumpRulesFP(stdout,asgname); -} - -int epicsShareAPI asDumpRulesFP(FILE *fp,const char *asgname) -{ - ASG *pasg; - ASGINP *pasginp; - ASGRULE *pasgrule; - ASGHAG *pasghag; - ASGUAG *pasguag; - - if(!asActive) return(0); - pasg = (ASG *)ellFirst(&pasbase->asgList); - if(!pasg) fprintf(fp,"No ASGs\n"); - while(pasg) { - int print_end_brace; - - if(asgname && strcmp(asgname,pasg->name)!=0) { - pasg = (ASG *)ellNext(&pasg->node); - continue; - } - fprintf(fp,"ASG(%s)",pasg->name); - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - if(pasginp || pasgrule) { - fprintf(fp," {\n"); - print_end_brace = TRUE; - } else { - fprintf(fp,"\n"); - print_end_brace = FALSE; - } - while(pasginp) { - - fprintf(fp,"\tINP%c(%s)",(pasginp->inpIndex + 'A'),pasginp->inp); - if ((pasg->inpBad & (1ul << pasginp->inpIndex))) - fprintf(fp," INVALID"); - fprintf(fp," value=%f",pasg->pavalue[pasginp->inpIndex]); - fprintf(fp,"\n"); - pasginp = (ASGINP *)ellNext(&pasginp->node); - } - while(pasgrule) { - int print_end_brace; - - fprintf(fp,"\tRULE(%d,%s,%s)", - pasgrule->level,asAccessName[pasgrule->access], - asTrapOption[pasgrule->trapMask]); - pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList); - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - if(pasguag || pasghag || pasgrule->calc) { - fprintf(fp," {\n"); - print_end_brace = TRUE; - } else { - fprintf(fp,"\n"); - print_end_brace = FALSE; - } - if(pasguag) fprintf(fp,"\t\tUAG("); - while(pasguag) { - fprintf(fp,"%s",pasguag->puag->name); - pasguag = (ASGUAG *)ellNext(&pasguag->node); - if(pasguag) fprintf(fp,","); else fprintf(fp,")\n"); - } - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - if(pasghag) fprintf(fp,"\t\tHAG("); - while(pasghag) { - fprintf(fp,"%s",pasghag->phag->name); - pasghag = (ASGHAG *)ellNext(&pasghag->node); - if(pasghag) fprintf(fp,","); else fprintf(fp,")\n"); - } - if(pasgrule->calc) { - fprintf(fp,"\t\tCALC(\"%s\")",pasgrule->calc); - fprintf(fp," result=%s",(pasgrule->result==1 ? "TRUE" : "FALSE")); - fprintf(fp,"\n"); - } - if(print_end_brace) fprintf(fp,"\t}\n"); - pasgrule = (ASGRULE *)ellNext(&pasgrule->node); - } - if(print_end_brace) fprintf(fp,"}\n"); - pasg = (ASG *)ellNext(&pasg->node); - } - return(0); -} - -int epicsShareAPI asDumpMem(const char *asgname,void (*memcallback)(ASMEMBERPVT,FILE *), - int clients) -{ - return asDumpMemFP(stdout,asgname,memcallback,clients); -} - -int epicsShareAPI asDumpMemFP(FILE *fp,const char *asgname, - void (*memcallback)(ASMEMBERPVT,FILE *),int clients) -{ - ASG *pasg; - ASGMEMBER *pasgmember; - ASGCLIENT *pasgclient; - - if(!asActive) return(0); - pasg = (ASG *)ellFirst(&pasbase->asgList); - if(!pasg) fprintf(fp,"No ASGs\n"); - while(pasg) { - - if(asgname && strcmp(asgname,pasg->name)!=0) { - pasg = (ASG *)ellNext(&pasg->node); - continue; - } - fprintf(fp,"ASG(%s)\n",pasg->name); - pasgmember = (ASGMEMBER *)ellFirst(&pasg->memberList); - if(pasgmember) fprintf(fp,"\tMEMBERLIST\n"); - while(pasgmember) { - if(strlen(pasgmember->asgName)==0) - fprintf(fp,"\t\t"); - else - fprintf(fp,"\t\t%s",pasgmember->asgName); - if(memcallback) memcallback(pasgmember,fp); - fprintf(fp,"\n"); - pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); - if(!clients) pasgclient = NULL; - while(pasgclient) { - fprintf(fp,"\t\t\t %s %s", - pasgclient->user,pasgclient->host); - if(pasgclient->level>=0 && pasgclient->level<=1) - fprintf(fp," %s",asLevelName[pasgclient->level]); - else - fprintf(fp," Illegal Level %d",pasgclient->level); - if(pasgclient->access<=2) - fprintf(fp," %s %s", - asAccessName[pasgclient->access], - asTrapOption[pasgclient->trapMask]); - else - fprintf(fp," Illegal Access %d",pasgclient->access); - fprintf(fp,"\n"); - pasgclient = (ASGCLIENT *)ellNext(&pasgclient->node); - } - pasgmember = (ASGMEMBER *)ellNext(&pasgmember->node); - } - pasg = (ASG *)ellNext(&pasg->node); - } - return(0); -} - -epicsShareFunc int epicsShareAPI asDumpHash(void) -{ - return asDumpHashFP(stdout); -} - -epicsShareFunc int epicsShareAPI asDumpHashFP(FILE *fp) -{ - if(!asActive) return(0); - gphDumpFP(fp,pasbase->phash); - return(0); -} - -/*Start of private routines*/ -/* asCalloc is "friend" function */ -epicsShareFunc void * epicsShareAPI asCalloc(size_t nobj,size_t size) -{ - void *p; - - p=callocMustSucceed(nobj,size,"asCalloc"); - return(p); -} -epicsShareFunc char * epicsShareAPI asStrdup(unsigned char *str) -{ - size_t len = strlen((char *) str); - char *buf = asCalloc(1, len + 1); - strcpy(buf, (char *) str); - return buf; -} - -static long asAddMemberPvt(ASMEMBERPVT *pasMemberPvt,const char *asgName) -{ - ASGMEMBER *pasgmember; - ASG *pgroup; - ASGCLIENT *pasgclient; - - if(*pasMemberPvt) { - pasgmember = *pasMemberPvt; - } else { - pasgmember = asCalloc(1,sizeof(ASGMEMBER)); - ellInit(&pasgmember->clientList); - *pasMemberPvt = pasgmember; - } - pasgmember->asgName = asgName; - pgroup = (ASG *)ellFirst(&pasbase->asgList); - while(pgroup) { - if(strcmp(pgroup->name,pasgmember->asgName)==0) goto got_it; - pgroup = (ASG *)ellNext(&pgroup->node); - } - /* Put it in DEFAULT*/ - pgroup = (ASG *)ellFirst(&pasbase->asgList); - while(pgroup) { - if(strcmp(pgroup->name,DEFAULT)==0) goto got_it; - pgroup = (ASG *)ellNext(&pgroup->node); - } - errMessage(-1,"Logic Error in asAddMember"); - return(-1); -got_it: - pasgmember->pasg = pgroup; - ellAdd(&pgroup->memberList,&pasgmember->node); - pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); - while(pasgclient) { - asComputePvt((ASCLIENTPVT)pasgclient); - pasgclient = (ASGCLIENT *)ellNext(&pasgclient->node); - } - return(0); -} - -static long asComputeAllAsgPvt(void) -{ - ASG *pasg; - - if(!asActive) return(S_asLib_asNotActive); - pasg = (ASG *)ellFirst(&pasbase->asgList); - while(pasg) { - asComputeAsgPvt(pasg); - pasg = (ASG *)ellNext(&pasg->node); - } - return(0); -} - -static long asComputeAsgPvt(ASG *pasg) -{ - ASGRULE *pasgrule; - ASGMEMBER *pasgmember; - ASGCLIENT *pasgclient; - - if(!asActive) return(S_asLib_asNotActive); - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - while(pasgrule) { - double result = pasgrule->result; /* set for VAL */ - long status; - - if(pasgrule->calc && (pasg->inpChanged & pasgrule->inpUsed)) { - status = calcPerform(pasg->pavalue,&result,pasgrule->rpcl); - if(status) { - pasgrule->result = 0; - errMessage(status,"asComputeAsg"); - } else { - pasgrule->result = ((result>.99) && (result<1.01)) ? 1 : 0; - } - } - pasgrule = (ASGRULE *)ellNext(&pasgrule->node); - } - pasg->inpChanged = FALSE; - pasgmember = (ASGMEMBER *)ellFirst(&pasg->memberList); - while(pasgmember) { - pasgclient = (ASGCLIENT *)ellFirst(&pasgmember->clientList); - while(pasgclient) { - asComputePvt((ASCLIENTPVT)pasgclient); - pasgclient = (ASGCLIENT *)ellNext(&pasgclient->node); - } - pasgmember = (ASGMEMBER *)ellNext(&pasgmember->node); - } - return(0); -} - -static long asComputePvt(ASCLIENTPVT asClientPvt) -{ - asAccessRights access=asNOACCESS; - int trapMask=0; - ASGCLIENT *pasgclient = asClientPvt; - ASGMEMBER *pasgMember; - ASG *pasg; - ASGRULE *pasgrule; - asAccessRights oldaccess; - GPHENTRY *pgphentry; - - if(!asActive) return(S_asLib_asNotActive); - if(!pasgclient) return(S_asLib_badClient); - pasgMember = pasgclient->pasgMember; - if(!pasgMember) return(S_asLib_badMember); - pasg = pasgMember->pasg; - if(!pasg) return(S_asLib_badAsg); - oldaccess=pasgclient->access; - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - while(pasgrule) { - if(access == asWRITE) break; - if(access>=pasgrule->access) goto next_rule; - if(pasgclient->level > pasgrule->level) goto next_rule; - /*if uagList is empty then no need to check uag*/ - if(ellCount(&pasgrule->uagList)>0){ - ASGUAG *pasguag; - UAG *puag; - - pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList); - while(pasguag) { - if((puag = pasguag->puag)) { - pgphentry = gphFind(pasbase->phash,pasgclient->user,puag); - if(pgphentry) goto check_hag; - } - pasguag = (ASGUAG *)ellNext(&pasguag->node); - } - goto next_rule; - } -check_hag: - /*if hagList is empty then no need to check hag*/ - if(ellCount(&pasgrule->hagList)>0) { - ASGHAG *pasghag; - HAG *phag; - - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - while(pasghag) { - if((phag = pasghag->phag)) { - pgphentry=gphFind(pasbase->phash,pasgclient->host,phag); - if(pgphentry) goto check_calc; - } - pasghag = (ASGHAG *)ellNext(&pasghag->node); - } - goto next_rule; - } -check_calc: - if(!pasgrule->calc - || (!(pasg->inpBad & pasgrule->inpUsed) && (pasgrule->result==1))) { - access = pasgrule->access; - trapMask = pasgrule->trapMask; - } -next_rule: - pasgrule = (ASGRULE *)ellNext(&pasgrule->node); - } - pasgclient->access = access; - pasgclient->trapMask = trapMask; - if(pasgclient->pcallback && oldaccess!=access) { - (*pasgclient->pcallback)(pasgclient,asClientCOAR); - } - return(0); -} - -void asFreeAll(ASBASE *pasbase) -{ - UAG *puag; - UAGNAME *puagname; - HAG *phag; - HAGNAME *phagname; - ASG *pasg; - ASGINP *pasginp; - ASGRULE *pasgrule; - ASGHAG *pasghag; - ASGUAG *pasguag; - void *pnext; - - puag = (UAG *)ellFirst(&pasbase->uagList); - while(puag) { - puagname = (UAGNAME *)ellFirst(&puag->list); - while(puagname) { - pnext = ellNext(&puagname->node); - ellDelete(&puag->list,&puagname->node); - free(puagname); - puagname = pnext; - } - pnext = ellNext(&puag->node); - ellDelete(&pasbase->uagList,&puag->node); - free(puag); - puag = pnext; - } - phag = (HAG *)ellFirst(&pasbase->hagList); - while(phag) { - phagname = (HAGNAME *)ellFirst(&phag->list); - while(phagname) { - pnext = ellNext(&phagname->node); - ellDelete(&phag->list,&phagname->node); - free(phagname); - phagname = pnext; - } - pnext = ellNext(&phag->node); - ellDelete(&pasbase->hagList,&phag->node); - free(phag); - phag = pnext; - } - pasg = (ASG *)ellFirst(&pasbase->asgList); - while(pasg) { - free(pasg->pavalue); - pasginp = (ASGINP *)ellFirst(&pasg->inpList); - while(pasginp) { - pnext = ellNext(&pasginp->node); - ellDelete(&pasg->inpList,&pasginp->node); - free(pasginp); - pasginp = pnext; - } - pasgrule = (ASGRULE *)ellFirst(&pasg->ruleList); - while(pasgrule) { - free(pasgrule->calc); - free(pasgrule->rpcl); - pasguag = (ASGUAG *)ellFirst(&pasgrule->uagList); - while(pasguag) { - pnext = ellNext(&pasguag->node); - ellDelete(&pasgrule->uagList,&pasguag->node); - free(pasguag); - pasguag = pnext; - } - pasghag = (ASGHAG *)ellFirst(&pasgrule->hagList); - while(pasghag) { - pnext = ellNext(&pasghag->node); - ellDelete(&pasgrule->hagList,&pasghag->node); - free(pasghag); - pasghag = pnext; - } - pnext = ellNext(&pasgrule->node); - ellDelete(&pasg->ruleList,&pasgrule->node); - free(pasgrule); - pasgrule = pnext; - } - pnext = ellNext(&pasg->node); - ellDelete(&pasbase->asgList,&pasg->node); - free(pasg); - pasg = pnext; - } - gphFreeMem(pasbase->phash); - free(pasbase); -} - -/*Beginning of routines called by lex code*/ -static UAG *asUagAdd(const char *uagName) -{ - UAG *pprev; - UAG *pnext; - UAG *puag; - int cmpvalue; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - /*Insert in alphabetic order*/ - pnext = (UAG *)ellFirst(&pasbase->uagList); - while(pnext) { - cmpvalue = strcmp(uagName,pnext->name); - if(cmpvalue < 0) break; - if(cmpvalue==0) { - errlogPrintf("Duplicate User Access Group named '%s'\n", uagName); - return(NULL); - } - pnext = (UAG *)ellNext(&pnext->node); - } - puag = asCalloc(1,sizeof(UAG)+strlen(uagName)+1); - ellInit(&puag->list); - puag->name = (char *)(puag+1); - strcpy(puag->name,uagName); - if(pnext==NULL) { /*Add to end of list*/ - ellAdd(&pasbase->uagList,&puag->node); - } else { - pprev = (UAG *)ellPrevious(&pnext->node); - ellInsert(&pasbase->uagList,&pprev->node,&puag->node); - } - return(puag); -} - -static long asUagAddUser(UAG *puag,const char *user) -{ - UAGNAME *puagname; - - if(!puag) return(0); - puagname = asCalloc(1,sizeof(UAGNAME)+strlen(user)+1); - puagname->user = (char *)(puagname+1); - strcpy(puagname->user,user); - ellAdd(&puag->list,&puagname->node); - return(0); -} - -static HAG *asHagAdd(const char *hagName) -{ - HAG *pprev; - HAG *pnext; - HAG *phag; - int cmpvalue; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - /*Insert in alphabetic order*/ - pnext = (HAG *)ellFirst(&pasbase->hagList); - while(pnext) { - cmpvalue = strcmp(hagName,pnext->name); - if(cmpvalue < 0) break; - if(cmpvalue==0) { - errlogPrintf("Duplicate Host Access Group named '%s'\n", hagName); - return(NULL); - } - pnext = (HAG *)ellNext(&pnext->node); - } - phag = asCalloc(1,sizeof(HAG)+strlen(hagName)+1); - ellInit(&phag->list); - phag->name = (char *)(phag+1); - strcpy(phag->name,hagName); - if(pnext==NULL) { /*Add to end of list*/ - ellAdd(&pasbase->hagList,&phag->node); - } else { - pprev = (HAG *)ellPrevious(&pnext->node); - ellInsert(&pasbase->hagList,&pprev->node,&phag->node); - } - return(phag); -} - -static long asHagAddHost(HAG *phag,const char *host) -{ - HAGNAME *phagname; - int len, i; - - if (!phag) return 0; - len = strlen(host); - phagname = asCalloc(1, sizeof(HAGNAME) + len + 1); - phagname->host = (char *)(phagname + 1); - for (i = 0; i < len; i++) { - phagname->host[i] = (char)tolower((int)host[i]); - } - ellAdd(&phag->list, &phagname->node); - return 0; -} - -static ASG *asAsgAdd(const char *asgName) -{ - ASG *pprev; - ASG *pnext; - ASG *pasg; - int cmpvalue; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - /*Insert in alphabetic order*/ - pnext = (ASG *)ellFirst(&pasbase->asgList); - while(pnext) { - cmpvalue = strcmp(asgName,pnext->name); - if(cmpvalue < 0) break; - if(cmpvalue==0) { - if(strcmp(DEFAULT,pnext->name)==0) { - if(ellCount(&pnext->inpList)==0 - && ellCount(&pnext->ruleList)==0) - return(pnext); - } - errlogPrintf("Duplicate Access Security Group named '%s'\n", asgName); - return(NULL); - } - pnext = (ASG *)ellNext(&pnext->node); - } - pasg = asCalloc(1,sizeof(ASG)+strlen(asgName)+1); - ellInit(&pasg->inpList); - ellInit(&pasg->ruleList); - ellInit(&pasg->memberList); - pasg->name = (char *)(pasg+1); - strcpy(pasg->name,asgName); - if(pnext==NULL) { /*Add to end of list*/ - ellAdd(&pasbase->asgList,&pasg->node); - } else { - pprev = (ASG *)ellPrevious(&pnext->node); - ellInsert(&pasbase->asgList,&pprev->node,&pasg->node); - } - return(pasg); -} - -static long asAsgAddInp(ASG *pasg,const char *inp,int inpIndex) -{ - ASGINP *pasginp; - - if(!pasg) return(0); - pasginp = asCalloc(1,sizeof(ASGINP)+strlen(inp)+1); - pasginp->inp = (char *)(pasginp+1); - strcpy(pasginp->inp,inp); - pasginp->pasg = pasg; - pasginp->inpIndex = inpIndex; - ellAdd(&pasg->inpList,&pasginp->node); - return(0); -} - -static ASGRULE *asAsgAddRule(ASG *pasg,asAccessRights access,int level) -{ - ASGRULE *pasgrule; - - if(!pasg) return(0); - pasgrule = asCalloc(1,sizeof(ASGRULE)); - pasgrule->access = access; - pasgrule->trapMask = 0; - pasgrule->level = level; - ellInit(&pasgrule->uagList); - ellInit(&pasgrule->hagList); - ellAdd(&pasg->ruleList,&pasgrule->node); - return(pasgrule); -} - -static long asAsgAddRuleOptions(ASGRULE *pasgrule,int trapMask) -{ - if(!pasgrule) return(0); - pasgrule->trapMask = trapMask; - return(0); -} - -static long asAsgRuleUagAdd(ASGRULE *pasgrule, const char *name) -{ - ASGUAG *pasguag; - UAG *puag; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - if (!pasgrule) - return 0; - - puag = (UAG *)ellFirst(&pasbase->uagList); - while (puag) { - if (strcmp(puag->name, name)==0) - break; - puag = (UAG *)ellNext(&puag->node); - } - if (!puag){ - errlogPrintf("No User Access Group named '%s' defined\n", name); - return S_asLib_noUag; - } - - pasguag = asCalloc(1, sizeof(ASGUAG)); - pasguag->puag = puag; - ellAdd(&pasgrule->uagList, &pasguag->node); - return 0; -} - -static long asAsgRuleHagAdd(ASGRULE *pasgrule, const char *name) -{ - ASGHAG *pasghag; - HAG *phag; - ASBASE *pasbase = (ASBASE *)pasbasenew; - - if (!pasgrule) - return 0; - - phag = (HAG *)ellFirst(&pasbase->hagList); - while (phag) { - if (strcmp(phag->name, name)==0) - break; - phag = (HAG *)ellNext(&phag->node); - } - if (!phag){ - errlogPrintf("No Host Access Group named '%s' defined\n", name); - return S_asLib_noHag; - } - - pasghag = asCalloc(1, sizeof(ASGHAG)); - pasghag->phag = phag; - ellAdd(&pasgrule->hagList, &pasghag->node); - return 0; -} - -static long asAsgRuleCalc(ASGRULE *pasgrule,const char *calc) -{ - short err; - long status; - size_t insize; - unsigned long stores; - - if (!pasgrule) return 0; - insize = strlen(calc) + 1; - pasgrule->calc = asCalloc(1, insize); - strcpy(pasgrule->calc, calc); - pasgrule->rpcl = asCalloc(1, INFIX_TO_POSTFIX_SIZE(insize)); - status = postfix(pasgrule->calc, pasgrule->rpcl, &err); - if(status) { - free(pasgrule->calc); - free(pasgrule->rpcl); - pasgrule->calc = NULL; - pasgrule->rpcl = NULL; - status = S_asLib_badCalc; - errlogPrintf("%s in CALC expression '%s'\n", calcErrorStr(err), calc); - return status; - } - calcArgUsage(pasgrule->rpcl, &pasgrule->inpUsed, &stores); - /* Until someone proves stores are not dangerous, don't allow them */ - if (stores) { - free(pasgrule->calc); - free(pasgrule->rpcl); - pasgrule->calc = NULL; - pasgrule->rpcl = NULL; - status = S_asLib_badCalc; - errlogPrintf("Assignment operator used in CALC expression '%s'\n", - calc); - } - return(status); -} diff --git a/src/libCom/as/asLib_lex.l b/src/libCom/as/asLib_lex.l deleted file mode 100644 index 924105c14..000000000 --- a/src/libCom/as/asLib_lex.l +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -newline "\n" -backslash "\\" -doublequote "\"" -comment "#" -whitespace [ \t\r] -escape {backslash}. -stringchar [^"\n\\] - -name [a-zA-Z0-9_\-+:.\[\]<>;] -digit [0-9] -punctuation [(){},] -link [A-L] - -%{ -static ASINPUTFUNCPTR *my_yyinput; -#undef YY_INPUT -#define YY_INPUT(b,r,ms) (r=(*my_yyinput)((char *)b,ms)) - -static int yyreset(void) -{ - line_num=1; - BEGIN INITIAL; - return(0); -} - -%} - -%% - -UAG { return(tokenUAG); } -HAG { return(tokenHAG); } -ASG { return(tokenASG); } -RULE { return(tokenRULE); } -CALC { return(tokenCALC); } - -INP{link} { - yylval.Int = (unsigned char)yytext[3]; - yylval.Int -= 'A'; - return(tokenINP); -} - -{digit}+ { /*integer*/ - yylval.Int = atoi((char *)yytext); - return(tokenINTEGER); -} - -{name}+ { /*unquoted string*/ - yylval.Str=asStrdup(yytext); - return(tokenSTRING); -} - -{doublequote}({stringchar}|{escape})*{doublequote} { /* quoted string */ - yylval.Str=asStrdup(yytext+1); - yylval.Str[strlen(yylval.Str)-1] = '\0'; - return(tokenSTRING); -} - -{doublequote}({stringchar}|{escape})*{newline} { /* bad string */ - yyerror("Newline in quoted string, closing quote missing"); -} - -{punctuation} { return(yytext[0]); } - -{newline} { line_num++; } - -{comment}.* ; -{whitespace} ; - -. { - char message[40]; - YY_BUFFER_STATE *dummy=0; - - if (isprint((int) yytext[0])) { - sprintf(message, "Invalid character '%c'", yytext[0]); - } - else { - sprintf(message, "Invalid character 0x%2.2x", yytext[0]); - } - yyerror(message); - - /*The following suppress compiler warning messages*/ - if (0) yyunput('c',(unsigned char *) message); - if (0) yy_switch_to_buffer(*dummy); -} - -%% diff --git a/src/libCom/as/asTrapWrite.c b/src/libCom/as/asTrapWrite.c deleted file mode 100644 index 544e9a211..000000000 --- a/src/libCom/as/asTrapWrite.c +++ /dev/null @@ -1,175 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*asTrapWrite.c */ -/* Author: Marty Kraimer Date: 07NOV2000 */ - -/* Matthias Clausen and Vladis Korobov at DESY - * implemented the first logging of Channel Access Puts - * This implementation uses many ideas from their implementation -*/ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "ellLib.h" -#include "freeList.h" -#include "epicsStdio.h" -#include "cantProceed.h" -#include "epicsMutex.h" -#include "ellLib.h" - -#include "asLib.h" -#include "asTrapWrite.h" - -typedef struct listenerPvt { - ELLNODE node; - struct listener *plistener; - void *userPvt; -}listenerPvt; - -typedef struct listener{ - ELLNODE node; - asTrapWriteListener func; -}listener; - -typedef struct writeMessage { - ELLNODE node; - asTrapWriteMessage message; - ELLLIST listenerPvtList; -}writeMessage; - - -typedef struct asTrapWritePvt -{ - ELLLIST listenerList; - ELLLIST writeMessageList; - void *freeListWriteMessage; - void *freeListListenerPvt; - epicsMutexId lock; -}asTrapWritePvt; - -static asTrapWritePvt *pasTrapWritePvt = 0; - -static void asTrapWriteInit(void) -{ - pasTrapWritePvt = callocMustSucceed(1,sizeof(asTrapWritePvt),"asTrapWriteInit"); - ellInit(&pasTrapWritePvt->listenerList); - ellInit(&pasTrapWritePvt->writeMessageList); - freeListInitPvt( - &pasTrapWritePvt->freeListWriteMessage,sizeof(writeMessage),20); - freeListInitPvt( - &pasTrapWritePvt->freeListListenerPvt,sizeof(listenerPvt),20); - pasTrapWritePvt->lock = epicsMutexMustCreate(); -} - -asTrapWriteId epicsShareAPI asTrapWriteRegisterListener( - asTrapWriteListener func) -{ - listener *plistener; - if(pasTrapWritePvt==0) asTrapWriteInit(); - plistener = callocMustSucceed(1,sizeof(listener),"asTrapWriteRegisterListener"); - plistener->func = func; - epicsMutexMustLock(pasTrapWritePvt->lock); - ellAdd(&pasTrapWritePvt->listenerList,&plistener->node); - epicsMutexUnlock(pasTrapWritePvt->lock); - return((asTrapWriteId)plistener); -} - -void epicsShareAPI asTrapWriteUnregisterListener(asTrapWriteId id) -{ - listener *plistener = (listener *)id; - writeMessage *pwriteMessage; - - if(pasTrapWritePvt==0) return; - epicsMutexMustLock(pasTrapWritePvt->lock); - pwriteMessage = (writeMessage *)ellFirst(&pasTrapWritePvt->writeMessageList); - while(pwriteMessage) { - listenerPvt *plistenerPvt - = (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList); - while(plistenerPvt) { - listenerPvt *pnext - = (listenerPvt *)ellNext(&plistenerPvt->node); - if(plistenerPvt->plistener == plistener) { - ellDelete(&pwriteMessage->listenerPvtList,&plistenerPvt->node); - freeListFree(pasTrapWritePvt->freeListListenerPvt, plistenerPvt); - } - plistenerPvt = pnext; - } - pwriteMessage = (writeMessage *)ellNext(&pwriteMessage->node); - } - ellDelete(&pasTrapWritePvt->listenerList,&plistener->node); - free(plistener); - epicsMutexUnlock(pasTrapWritePvt->lock); -} - -void * epicsShareAPI asTrapWriteBeforeWithData( - const char *userid, const char *hostid, void *addr, - int dbrType, int no_elements, void *data) -{ - writeMessage *pwriteMessage; - listener *plistener; - - if (pasTrapWritePvt == 0 || - ellCount(&pasTrapWritePvt->listenerList) <= 0) return 0; - - pwriteMessage = (writeMessage *)freeListCalloc( - pasTrapWritePvt->freeListWriteMessage); - pwriteMessage->message.userid = userid; - pwriteMessage->message.hostid = hostid; - pwriteMessage->message.serverSpecific = addr; - pwriteMessage->message.dbrType = dbrType; - pwriteMessage->message.no_elements = no_elements; - pwriteMessage->message.data = data; - ellInit(&pwriteMessage->listenerPvtList); - - epicsMutexMustLock(pasTrapWritePvt->lock); - ellAdd(&pasTrapWritePvt->writeMessageList, &pwriteMessage->node); - plistener = (listener *)ellFirst(&pasTrapWritePvt->listenerList); - while (plistener) { - listenerPvt *plistenerPvt = (listenerPvt *)freeListCalloc( - pasTrapWritePvt->freeListListenerPvt); - - plistenerPvt->plistener = plistener; - pwriteMessage->message.userPvt = 0; - plistener->func(&pwriteMessage->message, 0); - plistenerPvt->userPvt = pwriteMessage->message.userPvt; - ellAdd(&pwriteMessage->listenerPvtList, &plistenerPvt->node); - plistener = (listener *)ellNext(&plistener->node); - } - epicsMutexUnlock(pasTrapWritePvt->lock); - return pwriteMessage; -} - -void epicsShareAPI asTrapWriteAfterWrite(void *pvt) -{ - writeMessage *pwriteMessage = (writeMessage *)pvt; - listenerPvt *plistenerPvt; - - if (pwriteMessage == 0 || - pasTrapWritePvt == 0) return; - - epicsMutexMustLock(pasTrapWritePvt->lock); - plistenerPvt = (listenerPvt *)ellFirst(&pwriteMessage->listenerPvtList); - while (plistenerPvt) { - listenerPvt *pnext = (listenerPvt *)ellNext(&plistenerPvt->node); - listener *plistener = plistenerPvt->plistener; - - pwriteMessage->message.userPvt = plistenerPvt->userPvt; - plistener->func(&pwriteMessage->message, 1); - ellDelete(&pwriteMessage->listenerPvtList, &plistenerPvt->node); - freeListFree(pasTrapWritePvt->freeListListenerPvt, plistenerPvt); - plistenerPvt = pnext; - } - ellDelete(&pasTrapWritePvt->writeMessageList, &pwriteMessage->node); - freeListFree(pasTrapWritePvt->freeListWriteMessage, pwriteMessage); - epicsMutexUnlock(pasTrapWritePvt->lock); -} diff --git a/src/libCom/as/asTrapWrite.h b/src/libCom/as/asTrapWrite.h deleted file mode 100644 index b8033cb94..000000000 --- a/src/libCom/as/asTrapWrite.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*asTrapWrite.h*/ -/* Author: Marty Kraimer Date: 07NOV2000 */ - -#ifndef INCasTrapWriteh -#define INCasTrapWriteh - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct asTrapWriteMessage { - const char *userid; - const char *hostid; - void *serverSpecific; - void *userPvt; - int dbrType; /* Data type from ca/db_access.h, NOT dbFldTypes.h */ - int no_elements; - void *data; /* Might be NULL if no data is available */ -} asTrapWriteMessage; - - -typedef void *asTrapWriteId; -typedef void(*asTrapWriteListener)(asTrapWriteMessage *pmessage,int after); - -epicsShareFunc asTrapWriteId epicsShareAPI asTrapWriteRegisterListener( - asTrapWriteListener func); -epicsShareFunc void epicsShareAPI asTrapWriteUnregisterListener( - asTrapWriteId id); - -/* - * asTrapWriteListener is called before and after the write is performed. - * The listener can set userPvt on the before call and retrieve it after - * after = (0,1) (before,after) the put. - * - * Each asTrapWriteMessage can change or may be deleted after - * the user's asTrapWriteListener returns - * - * asTrapWriteListener delays the associated server thread so it must not - * do anything that causes to to block. -*/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCasTrapWriteh*/ diff --git a/src/libCom/bucketLib/Makefile b/src/libCom/bucketLib/Makefile deleted file mode 100644 index f66dc7d47..000000000 --- a/src/libCom/bucketLib/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/bucketLib -INC += bucketLib.h -Com_SRCS += bucketLib.c diff --git a/src/libCom/bucketLib/bucketLib.c b/src/libCom/bucketLib/bucketLib.c deleted file mode 100644 index 40df596a4..000000000 --- a/src/libCom/bucketLib/bucketLib.c +++ /dev/null @@ -1,522 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * hill@atdiv.lanl.gov - * (505) 665 1831 - * Date: 9-93 - * - * NOTES: - * .01 Storage for identifier must persist until an item is deleted - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "freeList.h" /* bucketLib uses freeListLib inside the DLL */ -#include "bucketLib.h" - -/* - * these data type dependent routines are - * provided in the bucketLib.c - */ -typedef BUCKETID bucketHash(BUCKET *pb, const void *pId); -typedef ITEM **bucketCompare(ITEM **ppi, const void *pId); - -static bucketCompare bucketUnsignedCompare; -static bucketCompare bucketPointerCompare; -static bucketCompare bucketStringCompare; -static bucketHash bucketUnsignedHash; -static bucketHash bucketPointerHash; -static bucketHash bucketStringHash; - -typedef struct { - bucketHash *pHash; - bucketCompare *pCompare; - buckTypeOfId type; -}bucketSET; - -static bucketSET BSET[] = { - {bucketUnsignedHash, bucketUnsignedCompare, bidtUnsigned}, - {bucketPointerHash, bucketPointerCompare, bidtPointer}, - {bucketStringHash, bucketStringCompare, bidtString} -}; - -static int bucketAddItem(BUCKET *prb, bucketSET *pBSET, - const void *pId, const void *pApp); -static void *bucketLookupItem(BUCKET *pb, bucketSET *pBSET, const void *pId); - - - -/* - * bucket id bit width - */ -#define BUCKETID_BIT_WIDTH (sizeof(BUCKETID)*CHAR_BIT) - -/* - * Maximum bucket size - */ -#define BUCKET_MAX_WIDTH 12 - - -/* - * bucketUnsignedCompare() - */ -static ITEM **bucketUnsignedCompare (ITEM **ppi, const void *pId) -{ - unsigned id; - unsigned *pItemId; - ITEM *pi; - - id = * (unsigned *) pId; - while ( (pi = *ppi) ) { - if (bidtUnsigned == pi->type) { - pItemId = (unsigned *) pi->pId; - if (id == *pItemId) { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketPointerCompare() - */ -static ITEM **bucketPointerCompare (ITEM **ppi, const void *pId) -{ - void *ptr; - void **pItemId; - ITEM *pi; - - ptr = * (void **) pId; - while ( (pi = *ppi) ) { - if (bidtPointer == pi->type ) { - pItemId = (void **) pi->pId; - if (ptr == *pItemId) { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketStringCompare () - */ -static ITEM **bucketStringCompare (ITEM **ppi, const void *pId) -{ - const char *pStr = pId; - ITEM *pi; - int status; - - while ( (pi = *ppi) ) { - if (bidtString == pi->type) { - status = strcmp (pStr, (char *)pi->pId); - if (status == '\0') { - return ppi; - } - } - ppi = &pi->pItem; - } - return NULL; -} - - -/* - * bucketUnsignedHash () - */ -static BUCKETID bucketUnsignedHash (BUCKET *pb, const void *pId) -{ - const unsigned *pUId = (const unsigned *) pId; - unsigned src; - BUCKETID hashid; - - src = *pUId; - hashid = src; - src = src >> pb->hashIdNBits; - while (src) { - hashid = hashid ^ src; - src = src >> pb->hashIdNBits; - } - hashid = hashid & pb->hashIdMask; - - return hashid; -} - - -/* - * bucketPointerHash () - */ -static BUCKETID bucketPointerHash (BUCKET *pb, const void *pId) -{ - void * const *ppId = (void * const *) pId; - size_t src; - BUCKETID hashid; - - /* - * This makes the assumption that size_t - * can be used to hold a pointer value - * (this assumption may not port to all - * CPU architectures) - */ - src = (size_t) *ppId; - hashid = src; - src = src >> pb->hashIdNBits; - while(src){ - hashid = hashid ^ src; - src = src >> pb->hashIdNBits; - } - hashid = hashid & pb->hashIdMask; - - return hashid; -} - - -/* - * bucketStringHash () - */ -static BUCKETID bucketStringHash (BUCKET *pb, const void *pId) -{ - const char *pStr = (const char *) pId; - BUCKETID hashid; - unsigned i; - - hashid = 0; - i = 1; - while(*pStr){ - hashid += *pStr * i; - pStr++; - i++; - } - - hashid = hashid % (pb->hashIdMask+1); - - return hashid; -} - - - -/* - * bucketCreate() - */ -epicsShareFunc BUCKET * epicsShareAPI bucketCreate (unsigned nHashTableEntries) -{ - BUCKETID mask; - unsigned nbits; - BUCKET *pb; - - /* - * no absurd sized buckets - */ - if (nHashTableEntries<=1) { - fprintf (stderr, "Tiny bucket create failed\n"); - return NULL; - } - - /* - * count the number of bits in the bucket id - */ - if ( BUCKETID_BIT_WIDTH > 0 ) { - for (nbits=0; nbits=BUCKETID_BIT_WIDTH) { - fprintf ( - stderr, - "%s at %d: Requested index width=%d to large. max=%ld\n", - __FILE__, - __LINE__, - nbits, - (long)(BUCKETID_BIT_WIDTH-1)); - return NULL; - } - - pb = (BUCKET *) calloc(1, sizeof(*pb)); - if (!pb) { - return pb; - } - - pb->hashIdMask = mask; - pb->hashIdNBits = nbits; - freeListInitPvt(&pb->freeListPVT, sizeof(ITEM), 1024); - - pb->pTable = (ITEM **) calloc (mask+1, sizeof(*pb->pTable)); - if (!pb->pTable) { - freeListCleanup(pb->freeListPVT); - free (pb); - return NULL; - } - return pb; -} - - -/* - * bucketFree() - */ -epicsShareFunc int epicsShareAPI bucketFree (BUCKET *prb) -{ - /* - * deleting a bucket with entries in use - * will cause memory leaks and is not allowed - */ - assert (prb->nInUse==0); - - /* - * free the free list - */ - freeListCleanup(prb->freeListPVT); - free (prb->pTable); - free (prb); - - return S_bucket_success; -} - - -/* - * bucketAddItem() - */ -epicsShareFunc int epicsShareAPI - bucketAddItemUnsignedId(BUCKET *prb, const unsigned *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtUnsigned], pId, pApp); -} -epicsShareFunc int epicsShareAPI - bucketAddItemPointerId(BUCKET *prb, void * const *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtPointer], pId, pApp); -} -epicsShareFunc int epicsShareAPI - bucketAddItemStringId(BUCKET *prb, const char *pId, const void *pApp) -{ - return bucketAddItem(prb, &BSET[bidtString], pId, pApp); -} -static int bucketAddItem(BUCKET *prb, bucketSET *pBSET, const void *pId, const void *pApp) -{ - BUCKETID hashid; - ITEM **ppi; - ITEM **ppiExists; - ITEM *pi; - - /* - * try to get it off the free list first. If - * that fails then malloc() - */ - pi = (ITEM *) freeListMalloc(prb->freeListPVT); - if (!pi) { - return S_bucket_noMemory; - } - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (prb, pId); - - pi->pApp = pApp; - pi->pId = pId; - pi->type = pBSET->type; - assert ((hashid & ~prb->hashIdMask) == 0); - ppi = &prb->pTable[hashid]; - /* - * Dont reuse a resource id ! - */ - ppiExists = (*pBSET->pCompare) (ppi, pId); - if (ppiExists) { - freeListFree(prb->freeListPVT,pi); - return S_bucket_idInUse; - } - pi->pItem = *ppi; - prb->pTable[hashid] = pi; - prb->nInUse++; - - return S_bucket_success; -} - -/* - * bucketLookupAndRemoveItem () - */ -static void *bucketLookupAndRemoveItem (BUCKET *prb, bucketSET *pBSET, const void *pId) -{ - BUCKETID hashid; - ITEM **ppi; - ITEM *pi; - void *pApp; - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (prb, pId); - - assert((hashid & ~prb->hashIdMask) == 0); - ppi = &prb->pTable[hashid]; - ppi = (*pBSET->pCompare) (ppi, pId); - if(!ppi){ - return NULL; - } - prb->nInUse--; - pi = *ppi; - *ppi = pi->pItem; - - pApp = (void *) pi->pApp; - - /* - * stuff it on the free list - */ - freeListFree(prb->freeListPVT, pi); - - return pApp; -} -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtUnsigned], pId); -} -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemPointerId (BUCKET *prb, void * const *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtPointer], pId); -} -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemStringId (BUCKET *prb, const char *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtString], pId); -} - - -/* - * bucketRemoveItem() - */ -epicsShareFunc int epicsShareAPI - bucketRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtUnsigned], pId)?S_bucket_success:S_bucket_uknId; -} -epicsShareFunc int epicsShareAPI - bucketRemoveItemPointerId (BUCKET *prb, void * const *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtPointer], pId)?S_bucket_success:S_bucket_uknId; -} -epicsShareFunc int epicsShareAPI - bucketRemoveItemStringId (BUCKET *prb, const char *pId) -{ - return bucketLookupAndRemoveItem(prb, &BSET[bidtString], pId)?S_bucket_success:S_bucket_uknId; -} - - -/* - * bucketLookupItem() - */ -epicsShareFunc void * epicsShareAPI - bucketLookupItemUnsignedId (BUCKET *prb, const unsigned *pId) -{ - return bucketLookupItem(prb, &BSET[bidtUnsigned], pId); -} -epicsShareFunc void * epicsShareAPI - bucketLookupItemPointerId (BUCKET *prb, void * const *pId) -{ - return bucketLookupItem(prb, &BSET[bidtPointer], pId); -} -epicsShareFunc void * epicsShareAPI - bucketLookupItemStringId (BUCKET *prb, const char *pId) -{ - return bucketLookupItem(prb, &BSET[bidtString], pId); -} -static void *bucketLookupItem (BUCKET *pb, bucketSET *pBSET, const void *pId) -{ - BUCKETID hashid; - ITEM **ppi; - - /* - * create the hash index - */ - hashid = (*pBSET->pHash) (pb, pId); - assert((hashid & ~pb->hashIdMask) == 0); - - /* - * at the bottom level just - * linear search for it. - */ - ppi = (*pBSET->pCompare) (&pb->pTable[hashid], pId); - if(ppi){ - return (void *) (*ppi)->pApp; - } - return NULL; -} - - - -/* - * bucketShow() - */ -epicsShareFunc int epicsShareAPI bucketShow(BUCKET *pb) -{ - ITEM **ppi; - ITEM *pi; - unsigned nElem; - double X; - double XX; - double mean; - double stdDev; - unsigned count; - unsigned maxEntries; - - printf( " Bucket entries in use = %d bytes in use = %ld\n", - pb->nInUse, - (long) (sizeof(*pb)+(pb->hashIdMask+1)* - sizeof(ITEM *)+pb->nInUse*sizeof(ITEM))); - - ppi = pb->pTable; - nElem = pb->hashIdMask+1; - X = 0.0; - XX = 0.0; - maxEntries = 0; - while (ppi < &pb->pTable[nElem]) { - pi = *ppi; - count = 0; - while (pi) { - count++; - pi = pi->pItem; - } - X += count; - XX += count*count; - if (count > maxEntries) maxEntries = count; - ppi++; - } - - mean = X/nElem; - stdDev = sqrt(XX/nElem - mean*mean); - printf( " Bucket entries/hash id - mean = %f std dev = %f max = %d\n", - mean, - stdDev, - maxEntries); - - return S_bucket_success; -} - - diff --git a/src/libCom/bucketLib/bucketLib.h b/src/libCom/bucketLib/bucketLib.h deleted file mode 100644 index 60d73b459..000000000 --- a/src/libCom/bucketLib/bucketLib.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - * hill@luke.lanl.gov - * (505) 665 1831 - * Date: 9-93 - * - * NOTES: - * .01 Storage for identifier must persist until an item is deleted - */ - -#ifndef INCbucketLibh -#define INCbucketLibh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "errMdef.h" -#include "epicsTypes.h" -#include "shareLib.h" - -typedef unsigned BUCKETID; - -typedef enum {bidtUnsigned, bidtPointer, bidtString} buckTypeOfId; - -typedef struct item{ - struct item *pItem; - const void *pId; - const void *pApp; - buckTypeOfId type; -}ITEM; - -typedef struct bucket{ - ITEM **pTable; - void *freeListPVT; - unsigned hashIdMask; - unsigned hashIdNBits; - unsigned nInUse; -}BUCKET; - -epicsShareFunc BUCKET * epicsShareAPI bucketCreate (unsigned nHashTableEntries); -epicsShareFunc int epicsShareAPI bucketFree (BUCKET *prb); -epicsShareFunc int epicsShareAPI bucketShow (BUCKET *pb); - -/* - * !! Identifier must exist (and remain constant) at the specified address until - * the item is deleted from the bucket !! - */ -epicsShareFunc int epicsShareAPI bucketAddItemUnsignedId (BUCKET *prb, - const unsigned *pId, const void *pApp); -epicsShareFunc int epicsShareAPI bucketAddItemPointerId (BUCKET *prb, - void * const *pId, const void *pApp); -epicsShareFunc int epicsShareAPI bucketAddItemStringId (BUCKET *prb, - const char *pId, const void *pApp); - -epicsShareFunc int epicsShareAPI bucketRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId); -epicsShareFunc int epicsShareAPI bucketRemoveItemPointerId (BUCKET *prb, void * const *pId); -epicsShareFunc int epicsShareAPI bucketRemoveItemStringId (BUCKET *prb, const char *pId); - -epicsShareFunc void * epicsShareAPI bucketLookupItemUnsignedId (BUCKET *prb, const unsigned *pId); -epicsShareFunc void * epicsShareAPI bucketLookupItemPointerId (BUCKET *prb, void * const *pId); -epicsShareFunc void * epicsShareAPI bucketLookupItemStringId (BUCKET *prb, const char *pId); - -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemUnsignedId (BUCKET *prb, const unsigned *pId); -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemPointerId (BUCKET *prb, void * const *pId); -epicsShareFunc void * epicsShareAPI bucketLookupAndRemoveItemStringId (BUCKET *prb, const char *pId); - - -/* - * Status returned by bucketLib functions - */ -#define BUCKET_SUCCESS S_bucket_success -#define S_bucket_success 0 -#define S_bucket_noMemory (M_bucket | 1) /*Memory allocation failed*/ -#define S_bucket_idInUse (M_bucket | 2) /*Identifier already in use*/ -#define S_bucket_uknId (M_bucket | 3) /*Unknown identifier*/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCbucketLibh*/ - diff --git a/src/libCom/calc/Makefile b/src/libCom/calc/Makefile deleted file mode 100644 index 493cb3245..000000000 --- a/src/libCom/calc/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/calc -INC += postfix.h -Com_SRCS += postfix.c -Com_SRCS += calcPerform.c - diff --git a/src/libCom/calc/calcPerform.c b/src/libCom/calc/calcPerform.c deleted file mode 100644 index c0f4aebb8..000000000 --- a/src/libCom/calc/calcPerform.c +++ /dev/null @@ -1,504 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Julie Sander and Bob Dalesio - * Date: 07-27-87 - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "osiUnistd.h" -#include "dbDefs.h" -#include "epicsMath.h" -#include "epicsTypes.h" -#include "errlog.h" -#include "postfix.h" -#include "postfixPvt.h" - -static double calcRandom(void); -static int cond_search(const char **ppinst, int match); - -#ifndef PI -#define PI 3.14159265358979323 -#endif - -/* Turn off global optimization for 64-bit MSVC builds */ -#if defined(_WIN32) && defined(_M_X64) && !defined(_MINGW) -# pragma optimize("g", off) -#endif - -/* calcPerform - * - * Evalutate the postfix expression - */ -epicsShareFunc long - calcPerform(double *parg, double *presult, const char *pinst) -{ - double stack[CALCPERFORM_STACK+1]; /* zero'th entry not used */ - double *ptop; /* stack pointer */ - double top; /* value from top of stack */ - epicsInt32 itop; /* integer from top of stack */ - epicsUInt32 utop; /* unsigned integer from top of stack */ - int op; - int nargs; - - /* initialize */ - ptop = stack; - - /* RPN evaluation loop */ - while ((op = *pinst++) != END_EXPRESSION){ - switch (op){ - - case LITERAL_DOUBLE: - memcpy(++ptop, pinst, sizeof(double)); - pinst += sizeof(double); - break; - - case LITERAL_INT: - memcpy(&itop, pinst, sizeof(epicsInt32)); - *++ptop = itop; - pinst += sizeof(epicsInt32); - break; - - case FETCH_VAL: - *++ptop = *presult; - break; - - case FETCH_A: - case FETCH_B: - case FETCH_C: - case FETCH_D: - case FETCH_E: - case FETCH_F: - case FETCH_G: - case FETCH_H: - case FETCH_I: - case FETCH_J: - case FETCH_K: - case FETCH_L: - *++ptop = parg[op - FETCH_A]; - break; - - case STORE_A: - case STORE_B: - case STORE_C: - case STORE_D: - case STORE_E: - case STORE_F: - case STORE_G: - case STORE_H: - case STORE_I: - case STORE_J: - case STORE_K: - case STORE_L: - parg[op - STORE_A] = *ptop--; - break; - - case CONST_PI: - *++ptop = PI; - break; - - case CONST_D2R: - *++ptop = PI/180.; - break; - - case CONST_R2D: - *++ptop = 180./PI; - break; - - case UNARY_NEG: - *ptop = - *ptop; - break; - - case ADD: - top = *ptop--; - *ptop += top; - break; - - case SUB: - top = *ptop--; - *ptop -= top; - break; - - case MULT: - top = *ptop--; - *ptop *= top; - break; - - case DIV: - top = *ptop--; - *ptop /= top; - break; - - case MODULO: - itop = (epicsInt32) *ptop--; - if (itop) - *ptop = (epicsInt32) *ptop % itop; - else - *ptop = epicsNAN; - break; - - case POWER: - top = *ptop--; - *ptop = pow(*ptop, top); - break; - - case ABS_VAL: - *ptop = fabs(*ptop); - break; - - case EXP: - *ptop = exp(*ptop); - break; - - case LOG_10: - *ptop = log10(*ptop); - break; - - case LOG_E: - *ptop = log(*ptop); - break; - - case MAX: - nargs = *pinst++; - while (--nargs) { - top = *ptop--; - if (*ptop < top || isnan(top)) - *ptop = top; - } - break; - - case MIN: - nargs = *pinst++; - while (--nargs) { - top = *ptop--; - if (*ptop > top || isnan(top)) - *ptop = top; - } - break; - - case SQU_RT: - *ptop = sqrt(*ptop); - break; - - case ACOS: - *ptop = acos(*ptop); - break; - - case ASIN: - *ptop = asin(*ptop); - break; - - case ATAN: - *ptop = atan(*ptop); - break; - - case ATAN2: - top = *ptop--; - *ptop = atan2(top, *ptop); /* Ouch!: Args backwards! */ - break; - - case COS: - *ptop = cos(*ptop); - break; - - case SIN: - *ptop = sin(*ptop); - break; - - case TAN: - *ptop = tan(*ptop); - break; - - case COSH: - *ptop = cosh(*ptop); - break; - - case SINH: - *ptop = sinh(*ptop); - break; - - case TANH: - *ptop = tanh(*ptop); - break; - - case CEIL: - *ptop = ceil(*ptop); - break; - - case FLOOR: - *ptop = floor(*ptop); - break; - - case FINITE: - nargs = *pinst++; - top = finite(*ptop); - while (--nargs) { - --ptop; - top = top && finite(*ptop); - } - *ptop = top; - break; - - case ISINF: - *ptop = isinf(*ptop); - break; - - case ISNAN: - nargs = *pinst++; - top = isnan(*ptop); - while (--nargs) { - --ptop; - top = top || isnan(*ptop); - } - *ptop = top; - break; - - case NINT: - top = *ptop; - *ptop = (epicsInt32) (top >= 0 ? top + 0.5 : top - 0.5); - break; - - case RANDOM: - *++ptop = calcRandom(); - break; - - case REL_OR: - top = *ptop--; - *ptop = *ptop || top; - break; - - case REL_AND: - top = *ptop--; - *ptop = *ptop && top; - break; - - case REL_NOT: - *ptop = ! *ptop; - break; - - /* For bitwise operations on values with bit 31 set, double values - * must first be cast to unsigned to correctly set that bit; the - * double value must be negative in that case. The result must be - * cast to a signed integer before converting to the double result. - */ - - case BIT_OR: - utop = *ptop--; - *ptop = (epicsInt32) ((epicsUInt32) *ptop | utop); - break; - - case BIT_AND: - utop = *ptop--; - *ptop = (epicsInt32) ((epicsUInt32) *ptop & utop); - break; - - case BIT_EXCL_OR: - utop = *ptop--; - *ptop = (epicsInt32) ((epicsUInt32) *ptop ^ utop); - break; - - case BIT_NOT: - utop = *ptop; - *ptop = (epicsInt32) ~utop; - break; - - /* The shift operators use signed integers, so a right-shift will - * extend the sign bit into the left-hand end of the value. The - * double-casting through unsigned here is important, see above. - */ - - case RIGHT_SHIFT: - utop = *ptop--; - *ptop = ((epicsInt32) (epicsUInt32) *ptop) >> (utop & 31); - break; - - case LEFT_SHIFT: - utop = *ptop--; - *ptop = ((epicsInt32) (epicsUInt32) *ptop) << (utop & 31); - break; - - case NOT_EQ: - top = *ptop--; - *ptop = *ptop != top; - break; - - case LESS_THAN: - top = *ptop--; - *ptop = *ptop < top; - break; - - case LESS_OR_EQ: - top = *ptop--; - *ptop = *ptop <= top; - break; - - case EQUAL: - top = *ptop--; - *ptop = *ptop == top; - break; - - case GR_OR_EQ: - top = *ptop--; - *ptop = *ptop >= top; - break; - - case GR_THAN: - top = *ptop--; - *ptop = *ptop > top; - break; - - case COND_IF: - if (*ptop-- == 0.0 && - cond_search(&pinst, COND_ELSE)) return -1; - break; - - case COND_ELSE: - if (cond_search(&pinst, COND_END)) return -1; - break; - - case COND_END: - break; - - default: - errlogPrintf("calcPerform: Bad Opcode %d at %p\n", op, pinst-1); - return -1; - } - } - - /* The stack should now have one item on it, the expression value */ - if (ptop != stack + 1) - return -1; - *presult = *ptop; - return 0; -} -#if defined(_WIN32) && defined(_M_X64) && !defined(_MINGW) -# pragma optimize("", on) -#endif - - -epicsShareFunc long -calcArgUsage(const char *pinst, unsigned long *pinputs, unsigned long *pstores) -{ - unsigned long inputs = 0; - unsigned long stores = 0; - char op; - while ((op = *pinst++) != END_EXPRESSION) { - switch (op) { - - case LITERAL_DOUBLE: - pinst += sizeof(double); - break; - case LITERAL_INT: - pinst += sizeof(epicsInt32); - break; - case MIN: - case MAX: - case FINITE: - case ISNAN: - pinst++; - break; - - case FETCH_A: - case FETCH_B: - case FETCH_C: - case FETCH_D: - case FETCH_E: - case FETCH_F: - case FETCH_G: - case FETCH_H: - case FETCH_I: - case FETCH_J: - case FETCH_K: - case FETCH_L: - /* Don't claim to use an arg we already stored to */ - inputs |= (1 << (op - FETCH_A)) & ~stores; - break; - - case STORE_A: - case STORE_B: - case STORE_C: - case STORE_D: - case STORE_E: - case STORE_F: - case STORE_G: - case STORE_H: - case STORE_I: - case STORE_J: - case STORE_K: - case STORE_L: - stores |= (1 << (op - STORE_A)); - break; - - default: - break; - } - } - if (pinputs) *pinputs = inputs; - if (pstores) *pstores = stores; - return 0; -} - -/* Generate a random number between 0 and 1 using the algorithm - * seed = (multy * seed) + addy Random Number Generator by Knuth - * SemiNumerical Algorithms - * Chapter 1 - * randy = seed / 65535.0 To normalize the number between 0 - 1 - */ -static unsigned short seed = 0xa3bf; -static unsigned short multy = 191 * 8 + 5; /* 191 % 8 == 5 */ -static unsigned short addy = 0x3141; - -static double calcRandom(void) -{ - seed = (seed * multy) + addy; - - /* between 0 - 1 */ - return (double) seed / 65535.0; -} - -/* Search the instruction stream for a matching operator, skipping any - * other conditional instructions found, and leave *ppinst pointing to - * the next instruction to be executed. - */ -static int cond_search(const char **ppinst, int match) -{ - const char *pinst = *ppinst; - int count = 1; - int op; - - while ((op = *pinst++) != END_EXPRESSION) { - if (op == match && --count == 0) { - *ppinst = pinst; - return 0; - } - switch (op) { - case LITERAL_DOUBLE: - pinst += sizeof(double); - break; - case LITERAL_INT: - pinst += sizeof(epicsInt32); - break; - case MIN: - case MAX: - case FINITE: - case ISNAN: - pinst++; - break; - case COND_IF: - count++; - break; - } - } - return 1; -} diff --git a/src/libCom/calc/postfix.c b/src/libCom/calc/postfix.c deleted file mode 100644 index 463ceea82..000000000 --- a/src/libCom/calc/postfix.c +++ /dev/null @@ -1,626 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Subroutines used to convert an infix expression to a postfix expression - * - * Original Author: Bob Dalesio - * Date: 12-12-86 -*/ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "epicsAssert.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "epicsTypes.h" -#include "postfix.h" -#include "postfixPvt.h" -#include "shareLib.h" - - -/* declarations for postfix */ - -/* element types */ -typedef enum { - OPERAND, - LITERAL_OPERAND, - STORE_OPERATOR, - UNARY_OPERATOR, - VARARG_OPERATOR, - BINARY_OPERATOR, - SEPERATOR, - CLOSE_PAREN, - CONDITIONAL, - EXPR_TERMINATOR, -} element_type; - - -/* element table - * - * structure of an element - */ -typedef struct expression_element{ - char *name; /* character representation of an element */ - char in_stack_pri; /* priority on translation stack */ - char in_coming_pri; /* priority in input string */ - signed char runtime_effect; /* stack change, positive means push */ - element_type type; /* element type */ - rpn_opcode code; /* postfix opcode */ -} ELEMENT; - -/* - * NOTE: Keep these lists sorted. Elements are searched in reverse order, - * and where two names start with the same substring we must pick out the - * longest name first (hence the sort requirement). - * NOTE: All VARARG_OPERATORs have to be made known to the calcExprDump() - * routine at the end of this file. - */ -static const ELEMENT operands[] = { -/* name prio's stack element type opcode */ -{"!", 7, 8, 0, UNARY_OPERATOR, REL_NOT}, -{"(", 0, 8, 0, UNARY_OPERATOR, NOT_GENERATED}, -{"-", 7, 8, 0, UNARY_OPERATOR, UNARY_NEG}, -{".", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"0", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"0X", 0, 0, 1, LITERAL_OPERAND,LITERAL_INT}, -{"1", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"2", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"3", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"4", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"5", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"6", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"7", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"8", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"9", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"A", 0, 0, 1, OPERAND, FETCH_A}, -{"ABS", 7, 8, 0, UNARY_OPERATOR, ABS_VAL}, -{"ACOS", 7, 8, 0, UNARY_OPERATOR, ACOS}, -{"ASIN", 7, 8, 0, UNARY_OPERATOR, ASIN}, -{"ATAN", 7, 8, 0, UNARY_OPERATOR, ATAN}, -{"ATAN2", 7, 8, -1, UNARY_OPERATOR, ATAN2}, -{"B", 0, 0, 1, OPERAND, FETCH_B}, -{"C", 0, 0, 1, OPERAND, FETCH_C}, -{"CEIL", 7, 8, 0, UNARY_OPERATOR, CEIL}, -{"COS", 7, 8, 0, UNARY_OPERATOR, COS}, -{"COSH", 7, 8, 0, UNARY_OPERATOR, COSH}, -{"D", 0, 0, 1, OPERAND, FETCH_D}, -{"D2R", 0, 0, 1, OPERAND, CONST_D2R}, -{"E", 0, 0, 1, OPERAND, FETCH_E}, -{"EXP", 7, 8, 0, UNARY_OPERATOR, EXP}, -{"F", 0, 0, 1, OPERAND, FETCH_F}, -{"FINITE", 7, 8, 0, VARARG_OPERATOR,FINITE}, -{"FLOOR", 7, 8, 0, UNARY_OPERATOR, FLOOR}, -{"G", 0, 0, 1, OPERAND, FETCH_G}, -{"H", 0, 0, 1, OPERAND, FETCH_H}, -{"I", 0, 0, 1, OPERAND, FETCH_I}, -{"INF", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"ISINF", 7, 8, 0, UNARY_OPERATOR, ISINF}, -{"ISNAN", 7, 8, 0, VARARG_OPERATOR,ISNAN}, -{"J", 0, 0, 1, OPERAND, FETCH_J}, -{"K", 0, 0, 1, OPERAND, FETCH_K}, -{"L", 0, 0, 1, OPERAND, FETCH_L}, -{"LN", 7, 8, 0, UNARY_OPERATOR, LOG_E}, -{"LOG", 7, 8, 0, UNARY_OPERATOR, LOG_10}, -{"LOGE", 7, 8, 0, UNARY_OPERATOR, LOG_E}, -{"MAX", 7, 8, 0, VARARG_OPERATOR,MAX}, -{"MIN", 7, 8, 0, VARARG_OPERATOR,MIN}, -{"NINT", 7, 8, 0, UNARY_OPERATOR, NINT}, -{"NAN", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE}, -{"NOT", 7, 8, 0, UNARY_OPERATOR, BIT_NOT}, -{"PI", 0, 0, 1, OPERAND, CONST_PI}, -{"R2D", 0, 0, 1, OPERAND, CONST_R2D}, -{"RNDM", 0, 0, 1, OPERAND, RANDOM}, -{"SIN", 7, 8, 0, UNARY_OPERATOR, SIN}, -{"SINH", 7, 8, 0, UNARY_OPERATOR, SINH}, -{"SQR", 7, 8, 0, UNARY_OPERATOR, SQU_RT}, -{"SQRT", 7, 8, 0, UNARY_OPERATOR, SQU_RT}, -{"TAN", 7, 8, 0, UNARY_OPERATOR, TAN}, -{"TANH", 7, 8, 0, UNARY_OPERATOR, TANH}, -{"VAL", 0, 0, 1, OPERAND, FETCH_VAL}, -{"~", 7, 8, 0, UNARY_OPERATOR, BIT_NOT}, -}; - -static const ELEMENT operators[] = { -/* name prio's stack element type opcode */ -{"!=", 3, 3, -1, BINARY_OPERATOR,NOT_EQ}, -{"#", 3, 3, -1, BINARY_OPERATOR,NOT_EQ}, -{"%", 5, 5, -1, BINARY_OPERATOR,MODULO}, -{"&", 2, 2, -1, BINARY_OPERATOR,BIT_AND}, -{"&&", 2, 2, -1, BINARY_OPERATOR,REL_AND}, -{")", 0, 0, 0, CLOSE_PAREN, NOT_GENERATED}, -{"*", 5, 5, -1, BINARY_OPERATOR,MULT}, -{"**", 6, 6, -1, BINARY_OPERATOR,POWER}, -{"+", 4, 4, -1, BINARY_OPERATOR,ADD}, -{",", 0, 0, 0, SEPERATOR, NOT_GENERATED}, -{"-", 4, 4, -1, BINARY_OPERATOR,SUB}, -{"/", 5, 5, -1, BINARY_OPERATOR,DIV}, -{":", 0, 0, -1, CONDITIONAL, COND_ELSE}, -{":=", 0, 0, -1, STORE_OPERATOR, STORE_A}, -{";", 0, 0, 0, EXPR_TERMINATOR,NOT_GENERATED}, -{"<", 3, 3, -1, BINARY_OPERATOR,LESS_THAN}, -{"<<", 2, 2, -1, BINARY_OPERATOR,LEFT_SHIFT}, -{"<=", 3, 3, -1, BINARY_OPERATOR,LESS_OR_EQ}, -{"=", 3, 3, -1, BINARY_OPERATOR,EQUAL}, -{"==", 3, 3, -1, BINARY_OPERATOR,EQUAL}, -{">", 3, 3, -1, BINARY_OPERATOR,GR_THAN}, -{">=", 3, 3, -1, BINARY_OPERATOR,GR_OR_EQ}, -{">>", 2, 2, -1, BINARY_OPERATOR,RIGHT_SHIFT}, -{"?", 0, 0, -1, CONDITIONAL, COND_IF}, -{"AND", 2, 2, -1, BINARY_OPERATOR,BIT_AND}, -{"OR", 1, 1, -1, BINARY_OPERATOR,BIT_OR}, -{"XOR", 1, 1, -1, BINARY_OPERATOR,BIT_EXCL_OR}, -{"^", 6, 6, -1, BINARY_OPERATOR,POWER}, -{"|", 1, 1, -1, BINARY_OPERATOR,BIT_OR}, -{"||", 1, 1, -1, BINARY_OPERATOR,REL_OR}, -}; - - -/* get_element - * - * find the next expression element in the infix expression - */ -static int - get_element(int opnd, const char **ppsrc, const ELEMENT **ppel) -{ - const ELEMENT *ptable, *pel; - - *ppel = NULL; - - while (isspace((int) (unsigned char) **ppsrc)) ++*ppsrc; - if (**ppsrc == '\0') return FALSE; - - if (opnd) { - ptable = operands; - pel = ptable + NELEMENTS(operands) - 1; - } else { - ptable = operators; - pel = ptable + NELEMENTS(operators) - 1; - } - - while (pel >= ptable) { - size_t len = strlen(pel->name); - - if (epicsStrnCaseCmp(*ppsrc, pel->name, len) == 0) { - *ppel = pel; - *ppsrc += len; - return TRUE; - } - --pel; - } - return FALSE; -} - - -/* postfix - * - * convert an infix expression to a postfix expression - */ -epicsShareFunc long - postfix(const char *psrc, char *pout, short *perror) -{ - ELEMENT stack[80]; - ELEMENT *pstacktop = stack; - const ELEMENT *pel; - int operand_needed = TRUE; - int runtime_depth = 0; - int cond_count = 0; - char * const pdest = pout; - char *pnext; - - if (psrc == NULL || *psrc == '\0' || - pout == NULL || perror == NULL) { - if (perror) *perror = CALC_ERR_NULL_ARG; - if (pout) *pout = END_EXPRESSION; - return -1; - } - - /* place the expression elements into postfix */ - *pout = END_EXPRESSION; - *perror = CALC_ERR_NONE; - - while (get_element(operand_needed, &psrc, &pel)) { - switch (pel->type) { - - case OPERAND: - *pout++ = pel->code; - runtime_depth += pel->runtime_effect; - operand_needed = FALSE; - break; - - case LITERAL_OPERAND: - runtime_depth += pel->runtime_effect; - - psrc -= strlen(pel->name); - if (pel->code == LITERAL_DOUBLE) { - double lit_d; - epicsInt32 lit_i; - - if (epicsParseDouble(psrc, &lit_d, &pnext)) { - *perror = CALC_ERR_BAD_LITERAL; - goto bad; - } - psrc = pnext; - lit_i = (epicsInt32) lit_d; - if (lit_d != (double) lit_i) { - *pout++ = pel->code; - memcpy(pout, &lit_d, sizeof(double)); - pout += sizeof(double); - } else { - *pout++ = LITERAL_INT; - memcpy(pout, &lit_i, sizeof(epicsInt32)); - pout += sizeof(epicsInt32); - } - } - else { - epicsUInt32 lit_ui; - - assert(pel->code == LITERAL_INT); - if (epicsParseUInt32(psrc, &lit_ui, 0, &pnext)) { - *perror = CALC_ERR_BAD_LITERAL; - goto bad; - } - psrc = pnext; - *pout++ = LITERAL_INT; - memcpy(pout, &lit_ui, sizeof(epicsUInt32)); - pout += sizeof(epicsUInt32); - } - - operand_needed = FALSE; - break; - - case STORE_OPERATOR: - if (pout == pdest || pstacktop > stack || - *--pout < FETCH_A || *pout > FETCH_L) { - *perror = CALC_ERR_BAD_ASSIGNMENT; - goto bad; - } - /* Convert fetch into a store on the stack */ - *++pstacktop = *pel; - pstacktop->code = STORE_A + *pout - FETCH_A; - runtime_depth -= 1; - operand_needed = TRUE; - break; - - case UNARY_OPERATOR: - case VARARG_OPERATOR: - /* Move operators of >= priority to the output */ - while ((pstacktop > stack) && - (pstacktop->in_stack_pri >= pel->in_coming_pri)) { - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - - /* Push new operator onto stack */ - pstacktop++; - *pstacktop = *pel; - break; - - case BINARY_OPERATOR: - /* Move operators of >= priority to the output */ - while ((pstacktop > stack) && - (pstacktop->in_stack_pri >= pel->in_coming_pri)) { - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - - /* Push new operator onto stack */ - pstacktop++; - *pstacktop = *pel; - - operand_needed = TRUE; - break; - - case SEPERATOR: - /* Move operators to the output until open paren */ - while (pstacktop->name[0] != '(') { - if (pstacktop <= stack+1) { - *perror = CALC_ERR_BAD_SEPERATOR; - goto bad; - } - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - operand_needed = TRUE; - pstacktop->runtime_effect -= 1; - break; - - case CLOSE_PAREN: - /* Move operators to the output until matching paren */ - while (pstacktop->name[0] != '(') { - if (pstacktop <= stack+1) { - *perror = CALC_ERR_PAREN_NOT_OPEN; - goto bad; - } - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - pstacktop--; /* remove ( from stack */ - /* if there is a vararg operator before the opening paren, - it inherits the (opening) paren's stack effect */ - if ((pstacktop > stack) && - pstacktop->type == VARARG_OPERATOR) { - pstacktop->runtime_effect = (pstacktop+1)->runtime_effect; - /* check for no arguments */ - if (pstacktop->runtime_effect > 0) { - *perror = CALC_ERR_INCOMPLETE; - goto bad; - } - } - break; - - case CONDITIONAL: - /* Move operators of > priority to the output */ - while ((pstacktop > stack) && - (pstacktop->in_stack_pri > pel->in_coming_pri)) { - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - - /* Add new element to the output */ - *pout++ = pel->code; - runtime_depth += pel->runtime_effect; - - /* For : operator, also push COND_END code to stack */ - if (pel->name[0] == ':') { - if (--cond_count < 0) { - *perror = CALC_ERR_CONDITIONAL; - goto bad; - } - pstacktop++; - *pstacktop = *pel; - pstacktop->code = COND_END; - pstacktop->runtime_effect = 0; - } else { - cond_count++; - } - - operand_needed = TRUE; - break; - - case EXPR_TERMINATOR: - /* Move everything from stack to the output */ - while (pstacktop > stack) { - if (pstacktop->name[0] == '(') { - *perror = CALC_ERR_PAREN_OPEN; - goto bad; - } - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - - if (cond_count != 0) { - *perror = CALC_ERR_CONDITIONAL; - goto bad; - } - if (runtime_depth > 1) { - *perror = CALC_ERR_TOOMANY; - goto bad; - } - - operand_needed = TRUE; - break; - - default: - *perror = CALC_ERR_INTERNAL; - goto bad; - } - - if (runtime_depth < 0) { - *perror = CALC_ERR_UNDERFLOW; - goto bad; - } - if (runtime_depth >= CALCPERFORM_STACK) { - *perror = CALC_ERR_OVERFLOW; - goto bad; - } - } - - if (*psrc != '\0') { - *perror = CALC_ERR_SYNTAX; - goto bad; - } - - /* Move everything from stack to the output */ - while (pstacktop > stack) { - if (pstacktop->name[0] == '(') { - *perror = CALC_ERR_PAREN_OPEN; - goto bad; - } - *pout++ = pstacktop->code; - if (pstacktop->type == VARARG_OPERATOR) { - *pout++ = 1 - pstacktop->runtime_effect; - } - runtime_depth += pstacktop->runtime_effect; - pstacktop--; - } - *pout = END_EXPRESSION; - - if (cond_count != 0) { - *perror = CALC_ERR_CONDITIONAL; - goto bad; - } - if (operand_needed || runtime_depth != 1) { - *perror = CALC_ERR_INCOMPLETE; - goto bad; - } - return 0; - -bad: - *pdest = END_EXPRESSION; - return -1; -} - - -/* calcErrorStr - * - * Return a message string appropriate for the given error code - */ -epicsShareFunc const char * - calcErrorStr(short error) -{ - static const char *errStrs[] = { - "No error", - "Too many results returned", - "Badly formed numeric literal", - "Bad assignment target", - "Comma without enclosing parentheses", - "Close parenthesis found without open", - "Parenthesis still open at end of expression", - "Unbalanced conditional ?: operators", - "Incomplete expression, operand missing", - "Not enough operands provided", - "Runtime stack overflow", - "Syntax error, unknown operator/operand", - "NULL or empty input argument to postfix()", - "Internal error, unknown element type", - }; - - if (error < CALC_ERR_NONE || error > CALC_ERR_INTERNAL) - return NULL; - return errStrs[error]; -} - - -/* calcExprDump - * - * Disassemble the given postfix instructions to stdout - */ -epicsShareFunc void - calcExprDump(const char *pinst) -{ - static const char *opcodes[] = { - "End Expression", - /* Operands */ - "LITERAL_DOUBLE", "LITERAL_INT", "VAL", - "FETCH_A", "FETCH_B", "FETCH_C", "FETCH_D", "FETCH_E", "FETCH_F", - "FETCH_G", "FETCH_H", "FETCH_I", "FETCH_J", "FETCH_K", "FETCH_L", - /* Assignment */ - "STORE_A", "STORE_B", "STORE_C", "STORE_D", "STORE_E", "STORE_F", - "STORE_G", "STORE_H", "STORE_I", "STORE_J", "STORE_K", "STORE_L", - /* Trigonometry Constants */ - "CONST_PI", - "CONST_D2R", - "CONST_R2D", - /* Arithmetic */ - "UNARY_NEG", - "ADD", - "SUB", - "MULT", - "DIV", - "MODULO", - "POWER", - /* Algebraic */ - "ABS_VAL", - "EXP", - "LOG_10", - "LOG_E", - "MAX", - "MIN", - "SQU_RT", - /* Trigonometric */ - "ACOS", - "ASIN", - "ATAN", - "ATAN2", - "COS", - "COSH", - "SIN", - "SINH", - "TAN", - "TANH", - /* Numeric */ - "CEIL", - "FLOOR", - "FINITE", - "ISINF", - "ISNAN", - "NINT", - "RANDOM", - /* Boolean */ - "REL_OR", - "REL_AND", - "REL_NOT", - /* Bitwise */ - "BIT_OR", - "BIT_AND", - "BIT_EXCL_OR", - "BIT_NOT", - "RIGHT_SHIFT", - "LEFT_SHIFT", - /* Relationals */ - "NOT_EQ", - "LESS_THAN", - "LESS_OR_EQ", - "EQUAL", - "GR_OR_EQ", - "GR_THAN", - /* Conditional */ - "COND_IF", - "COND_ELSE", - "COND_END", - /* Misc */ - "NOT_GENERATED" - }; - char op; - double lit_d; - epicsInt32 lit_i; - - while ((op = *pinst) != END_EXPRESSION) { - switch (op) { - case LITERAL_DOUBLE: - memcpy(&lit_d, ++pinst, sizeof(double)); - printf("\tDouble %g\n", lit_d); - pinst += sizeof(double); - break; - case LITERAL_INT: - memcpy(&lit_i, ++pinst, sizeof(epicsInt32)); - printf("\tInteger %d (0x%x)\n", lit_i, lit_i); - pinst += sizeof(epicsInt32); - break; - case MIN: - case MAX: - case FINITE: - case ISNAN: - printf("\t%s, %d arg(s)\n", opcodes[(int) op], *++pinst); - pinst++; - break; - default: - printf("\t%s\n", opcodes[(int) op]); - pinst++; - } - } -} diff --git a/src/libCom/calc/postfix.h b/src/libCom/calc/postfix.h deleted file mode 100644 index b90492012..000000000 --- a/src/libCom/calc/postfix.h +++ /dev/null @@ -1,89 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* postfix.h - * Original Author: Bob Dalesio - * Date: 9-21-88 - */ - -#ifndef INCpostfixh -#define INCpostfixh - -#include "shareLib.h" - -#define CALCPERFORM_NARGS 12 -#define CALCPERFORM_STACK 80 - -#define INFIX_TO_POSTFIX_SIZE(n) ((n)*21/6) -/* The above expression is an estimate of the maximum postfix buffer - * size needed for a given infix expression buffer (the argument must count - * the trailing nil byte in the input expression string). The actual size - * needed is never larger than this value, although it is actually a - * few bytes smaller for some sizes. - * - * The maximum expansion from infix to postfix is for the sub-expression - * .1?.1: - * which is 6 characters long and results in 21 bytes of postfix: - * .1 => LITERAL_DOUBLE + 8 byte value - * ? => COND_IF - * .1 => LITERAL_DOUBLE + 8 byte value - * : => COND_ELSE - * ... - * => COND_END - * For other short expressions the factor 21/6 always gives a big enough - * postfix buffer (proven by hand, look at '1+' and '.1+' as well). - */ - -/* These are not hard limits, just default sizes for the database */ -#define MAX_INFIX_SIZE 100 -#define MAX_POSTFIX_SIZE INFIX_TO_POSTFIX_SIZE(MAX_INFIX_SIZE) - - -/* Error numbers from postfix */ - -#define CALC_ERR_NONE 0 /* No error */ -#define CALC_ERR_TOOMANY 1 /* Too many results returned */ -#define CALC_ERR_BAD_LITERAL 2 /* Bad numeric literal */ -#define CALC_ERR_BAD_ASSIGNMENT 3 /* Bad assignment target */ -#define CALC_ERR_BAD_SEPERATOR 4 /* Comma without parentheses */ -#define CALC_ERR_PAREN_NOT_OPEN 5 /* Close parenthesis without open */ -#define CALC_ERR_PAREN_OPEN 6 /* Open parenthesis at end of expression */ -#define CALC_ERR_CONDITIONAL 7 /* Unbalanced conditional ?: operators */ -#define CALC_ERR_INCOMPLETE 8 /* Incomplete expression, operand missing */ -#define CALC_ERR_UNDERFLOW 9 /* Runtime stack would underflow */ -#define CALC_ERR_OVERFLOW 10 /* Runtime stack would overflow */ -#define CALC_ERR_SYNTAX 11 /* Syntax error */ -#define CALC_ERR_NULL_ARG 12 /* NULL or empty input argument */ -#define CALC_ERR_INTERNAL 13 /* Internal error, bad element type */ -/* Changes in the above errors must also be made in calcErrorStr() */ - - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc long - postfix(const char *pinfix, char *ppostfix, short *perror); - -epicsShareFunc long - calcPerform(double *parg, double *presult, const char *ppostfix); - -epicsShareFunc long - calcArgUsage(const char *ppostfix, unsigned long *pinputs, unsigned long *pstores); - -epicsShareFunc const char * - calcErrorStr(short error); - -epicsShareFunc void - calcExprDump(const char *pinst); - -#ifdef __cplusplus -} -#endif - -#endif /* INCpostfixh */ diff --git a/src/libCom/calc/postfixPvt.h b/src/libCom/calc/postfixPvt.h deleted file mode 100644 index 53efb32e0..000000000 --- a/src/libCom/calc/postfixPvt.h +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* postfixPvt.h - * Original Author: Bob Dalesio - * Date: 9-21-88 - */ - -/* Notes: - * 1. The FETCH_A through FETCH_L and STORE_A through STORE_L opcodes must - * be contiguous. - * 2. The LITERAL opcodes are followed by a binary representation of their - * values, but these are not aligned properly. - * 3. The var-arg functions MIN, MAX, FINITE and ISNAN are followed by - * a byte giving the number of arguments to process. - * 4. You can't use strlen() on an RPN buffer since the literal values - * can contain zero bytes. - */ - -#ifndef INCpostfixPvth -#define INCpostfixPvth - - -/* RPN opcodes */ -typedef enum { - END_EXPRESSION = 0, - /* Operands */ - LITERAL_DOUBLE, LITERAL_INT, FETCH_VAL, - FETCH_A, FETCH_B, FETCH_C, FETCH_D, FETCH_E, FETCH_F, - FETCH_G, FETCH_H, FETCH_I, FETCH_J, FETCH_K, FETCH_L, - /* Assignment */ - STORE_A, STORE_B, STORE_C, STORE_D, STORE_E, STORE_F, - STORE_G, STORE_H, STORE_I, STORE_J, STORE_K, STORE_L, - /* Trigonometry Constants */ - CONST_PI, - CONST_D2R, - CONST_R2D, - /* Arithmetic */ - UNARY_NEG, - ADD, - SUB, - MULT, - DIV, - MODULO, - POWER, - /* Algebraic */ - ABS_VAL, - EXP, - LOG_10, - LOG_E, - MAX, - MIN, - SQU_RT, - /* Trigonometric */ - ACOS, - ASIN, - ATAN, - ATAN2, - COS, - COSH, - SIN, - SINH, - TAN, - TANH, - /* Numeric */ - CEIL, - FLOOR, - FINITE, - ISINF, - ISNAN, - NINT, - RANDOM, - /* Boolean */ - REL_OR, - REL_AND, - REL_NOT, - /* Bitwise */ - BIT_OR, - BIT_AND, - BIT_EXCL_OR, - BIT_NOT, - RIGHT_SHIFT, - LEFT_SHIFT, - /* Relationals */ - NOT_EQ, - LESS_THAN, - LESS_OR_EQ, - EQUAL, - GR_OR_EQ, - GR_THAN, - /* Conditional */ - COND_IF, - COND_ELSE, - COND_END, - /* Misc */ - NOT_GENERATED -} rpn_opcode; - -#endif /* INCpostfixPvth */ diff --git a/src/libCom/cppStd/Makefile b/src/libCom/cppStd/Makefile deleted file mode 100644 index 782c4da25..000000000 --- a/src/libCom/cppStd/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/cppStd -INC += epicsAlgorithm.h -INC += epicsExcept.h - diff --git a/src/libCom/cppStd/epicsAlgorithm.h b/src/libCom/cppStd/epicsAlgorithm.h deleted file mode 100644 index 20850242d..000000000 --- a/src/libCom/cppStd/epicsAlgorithm.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// epicsAlgorithm.h -// Authors: Jeff Hill & Andrew Johnson - -#ifndef __EPICS_ALGORITHM_H__ -#define __EPICS_ALGORITHM_H__ - -#include "epicsMath.h" - -// The C++ standard only requires types to be less-than comparable, so -// the epicsMin and epicsMax templates only use operator < - -// epicsMin - -template -inline const T& epicsMin (const T& a, const T& b) -{ - return (b < a) ? b : a; -} - -// If b is a NaN the above template returns a, but should return NaN. -// These specializations ensure that epicsMin(x,NaN) == NaN - -template <> -inline const float& epicsMin (const float& a, const float& b) -{ - return (b < a) || isnan(b) ? b : a; -} - -template <> -inline const double& epicsMin (const double& a, const double& b) -{ - return (b < a) || isnan(b) ? b : a; -} - - -// epicsMax - -template -inline const T& epicsMax (const T& a, const T& b) -{ - return (a < b) ? b : a; -} - -// If b is a NaN the above template returns a, but should return NaN. -// These specializations ensure that epicsMax(x,NaN) == NaN - -template <> -inline const float& epicsMax (const float& a, const float& b) -{ - return (a < b) || isnan(b) ? b : a; -} - -template <> -inline const double& epicsMax (const double& a, const double& b) -{ - return (a < b) || isnan(b) ? b : a; -} - - -// epicsSwap - -template -inline void epicsSwap(T& a, T& b) -{ - T temp = a; - a = b; - b = temp; -} - -#endif // __EPICS_ALGORITHM_H__ diff --git a/src/libCom/cppStd/epicsExcept.h b/src/libCom/cppStd/epicsExcept.h deleted file mode 100644 index e68999735..000000000 --- a/src/libCom/cppStd/epicsExcept.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// Author: Andrew Johnson & Jeff Hill -// Date: December 2000 - -#ifndef __EPICS_EXCEPT_H__ -#define __EPICS_EXCEPT_H__ - -#define epicsThrowHere(exc) \ - throw locationException(exc, __FILE__, __LINE__) - -class sourceLocation { -public: // Functions - sourceLocation(const char *fileName, int lineNumber); -// sourceLocation(const sourceLocation&); Copy constructable -// sourceLocation& operator=(const sourceLocation&); Assignable - - const char *fileName() const; - int lineNumber() const; - -private: // Hide compiler-generated member functions - sourceLocation(); // default constructor - -private: // Data - const char *file; - int line; -}; - -template -class locationException : public T, public sourceLocation { -public: - locationException(const T& exc, const char *fileName, int lineNumber); -}; - - -/* Example: - * if (status) epicsThrowHere(std::logic_error("operation failed!")); - * try { ... } catch(sourceLocation& where) { ... } - */ - -// END OF DECLARATIONS - -// INLINE FUNCTIONS - -// sourceFileLocation -inline sourceLocation::sourceLocation (const char *fileName, int lineNumber) : - file(fileName), line(lineNumber) {} - -inline const char* sourceLocation::fileName () const { - return this->file; -} - -inline int sourceLocation::lineNumber () const { - return this->line; -} - -// locationException -template -inline locationException::locationException - (const char *fileName, int lineNumber, const E& exc) : - T(exc), sourceLocation(fileName, lineNumber) {} - - -#endif // __EPICS_EXCEPT_H__ diff --git a/src/libCom/cvtFast/Makefile b/src/libCom/cvtFast/Makefile deleted file mode 100644 index 473693c83..000000000 --- a/src/libCom/cvtFast/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/cvtFast -INC += cvtFast.h -Com_SRCS += cvtFast.c - diff --git a/src/libCom/cvtFast/cvtFast.c b/src/libCom/cvtFast/cvtFast.c deleted file mode 100644 index 4e04b4515..000000000 --- a/src/libCom/cvtFast/cvtFast.c +++ /dev/null @@ -1,523 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Fast numeric to string conversions - * - * Original Authors: - * Bob Dalesio, Mark Anderson and Marty Kraimer - * Date: 12 January 1993 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "cvtFast.h" -#include "epicsMath.h" -#include "epicsStdio.h" - -/* - * These routines convert numbers up to +/- 10,000,000. - * They defer to sprintf() for numbers requiring more than - * 8 places of precision. - */ -static epicsInt32 frac_multiplier[] = - {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000}; - -int cvtFloatToString(float flt_value, char *pdest, - epicsUInt16 precision) -{ - int got_one, i; - epicsInt32 whole, iplace, number, fraction, fplace; - float ftemp; - char *startAddr; - - /* can this routine handle this conversion */ - if (isnan(flt_value) || precision > 8 || - flt_value > 10000000.0 || flt_value < -10000000.0) { - if (precision > 8 || flt_value >= 1e8 || flt_value <= -1e8) { - if (precision > 12) precision = 12; /* FIXME */ - sprintf(pdest, "%*.*e", precision+6, precision, (double) flt_value); - } else { - if (precision > 3) precision = 3; /* FIXME */ - sprintf(pdest, "%.*f", precision, (double) flt_value); - } - return((int)strlen(pdest)); - } - startAddr = pdest; - - /* determine the sign */ - if (flt_value < 0){ - *pdest++ = '-'; - flt_value = -flt_value; - }; - - /* remove the whole number portion */ - whole = (epicsInt32)flt_value; - ftemp = flt_value - whole; - - /* multiplier to convert fractional portion to integer */ - fplace = frac_multiplier[precision]; - fraction = (epicsInt32)(ftemp * fplace * 10); - fraction = (fraction + 5) / 10; /* round up */ - - /* determine rounding into the whole number portion */ - if ((fraction / fplace) >= 1){ - whole++; - fraction -= fplace; - } - - /* whole numbers */ - got_one = 0; - for (iplace = 10000000; iplace >= 1; iplace /= 10){ - if (whole >= iplace){ - got_one = 1; - number = whole / iplace; - whole = whole - (number * iplace); - *pdest = number + '0'; - pdest++; - }else if (got_one){ - *pdest = '0'; - pdest++; - } - } - if (!got_one){ - *pdest = '0'; - pdest++; - } - - /* fraction */ - if (precision > 0){ - /* convert fractional portional to ASCII */ - *pdest = '.'; - pdest++; - for (fplace /= 10, i = precision; i > 0; fplace /= 10,i--){ - number = fraction / fplace; - fraction -= number * fplace; - *pdest = number + '0'; - pdest++; - } - } - *pdest = 0; - - return((int)(pdest - startAddr)); -} - -int cvtDoubleToString( - double flt_value, - char *pdest, - epicsUInt16 precision) -{ - epicsUInt16 got_one,i; - epicsInt32 whole,iplace,number,fraction,fplace; - double ftemp; - char *startAddr; - - /* can this routine handle this conversion */ - if (isnan(flt_value) || precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) { - if (precision > 8 || flt_value > 1e16 || flt_value < -1e16) { - if(precision>17) precision=17; - sprintf(pdest,"%*.*e",precision+7,precision, - flt_value); - } else { - if(precision>3) precision=3; - sprintf(pdest,"%.*f",precision,flt_value); - } - return((int)strlen(pdest)); - } - startAddr = pdest; - - /* determine the sign */ - if (flt_value < 0){ - *pdest++ = '-'; - flt_value = -flt_value; - }; - - /* remove the whole number portion */ - whole = (epicsInt32)flt_value; - ftemp = flt_value - whole; - - /* multiplier to convert fractional portion to integer */ - fplace = frac_multiplier[precision]; - fraction = (epicsInt32)(ftemp * fplace * 10); - fraction = (fraction + 5) / 10; /* round up */ - - /* determine rounding into the whole number portion */ - if ((fraction / fplace) >= 1){ - whole++; - fraction -= fplace; - } - - /* whole numbers */ - got_one = 0; - for (iplace = 10000000; iplace >= 1; iplace /= 10){ - if (whole >= iplace){ - got_one = 1; - number = whole / iplace; - whole = whole - (number * iplace); - *pdest = number + '0'; - pdest++; - }else if (got_one){ - *pdest = '0'; - pdest++; - } - } - if (!got_one){ - *pdest = '0'; - pdest++; - } - - /* fraction */ - if (precision > 0){ - /* convert fractional portional to ASCII */ - *pdest = '.'; - pdest++; - for (fplace /= 10, i = precision; i > 0; fplace /= 10,i--){ - number = fraction / fplace; - fraction -= number * fplace; - *pdest = number + '0'; - pdest++; - } - } - *pdest = 0; - - return((int)(pdest - startAddr)); -} - -/* - * These routines are provided for backwards compatibility, - * extensions such as MEDM, edm and histtool use them. - */ - -/* - * cvtFloatToExpString - * - * Converts a float to a %e formatted string - */ -int cvtFloatToExpString(float val, char *pdest, epicsUInt16 precision) -{ - return epicsSnprintf(pdest, MAX_STRING_SIZE, "%.*e", precision, val); -} - -/* - * cvtFloatToCompactString - * - * Converts a float to a %g formatted string. - * The result uses %f notation for 10e-4 < |value| < 10e+4, - * otherwise %e notation. - */ -int cvtFloatToCompactString(float val, char *pdest, epicsUInt16 precision) -{ - if ((val < 1.e4 && val > 1.e-4) || - (val > -1.e4 && val < -1.e-4) || - val == 0.0) - return cvtFloatToString(val, pdest, precision); - - return cvtFloatToExpString(val, pdest, precision); -} - - -/* - * cvtDoubleToExpString - * - * Converts a double to a %e formatted string - */ - -int cvtDoubleToExpString(double val, char *pdest, epicsUInt16 precision) -{ - return epicsSnprintf(pdest, MAX_STRING_SIZE, "%.*e", precision, val); -} - - -/* - * cvtDoubleToCompactString - * - * Converts a double to %g formatted string. - * The result uses %f notation for 10e-4 < |value| < 10e+4, - * otherwise %e notation. - */ -int cvtDoubleToCompactString(double val, char *pdest, epicsUInt16 precision) -{ - if ((val < 1.e4 && val > 1.e-4) || - (val > -1.e4 && val < -1.e-4) || - val == 0.0) - return cvtDoubleToString(val, pdest, precision); - - return cvtDoubleToExpString(val, pdest, precision); -} - - -/* Integer conversion primitives */ - -static size_t - UInt32ToDec(epicsUInt32 val, char *pdest) -{ - int i; - char digit[10]; - size_t len; - - for (i = 0; val; i++) { - epicsUInt32 tenth = val / 10; - - digit[i] = val - tenth * 10 + '0'; - val = tenth; - } - len = i; - - while (i > 0) - *pdest++ = digit[--i]; - - *pdest = 0; - return len; -} - -static size_t - UInt32ToBase(epicsUInt32 val, char *pdest, int base) -{ - int i; - char digit, digits[32]; - size_t len; - - for (i = 0; val; i++) { - epicsUInt32 tenth = val / base; - - digit = val - tenth * base; - digits[i] = digit < 10 ? digit + '0' : digit - 10 + 'a'; - val = tenth; - } - len = i; - - while (i > 0) - *pdest++ = digits[--i]; - - *pdest = 0; - return len; -} - -static size_t - UInt64ToDec(epicsUInt64 val, char *pdest) -{ - int i; - char digit[20]; - size_t len; - - for (i = 0; val; i++) { - epicsUInt64 tenth = val / 10; - - digit[i] = val - tenth * 10 + '0'; - val = tenth; - } - - len = i; - while (i > 0) - *pdest++ = digit[--i]; - - *pdest = 0; - return len; -} - -static size_t - UInt64ToBase(epicsUInt64 val, char *pdest, int base) -{ - int i; - char digit, digits[64]; - size_t len; - - for (i = 0; val; i++) { - epicsUInt64 tenth = val / base; - - digit = val - tenth * base; - digits[i] = digit < 10 ? digit + '0' : digit - 10 + 'a'; - val = tenth; - } - len = i; - - while (i > 0) - *pdest++ = digits[--i]; - - *pdest = 0; - return len; -} - - -/* Integer conversion routines */ - -size_t - cvtUInt32ToString(epicsUInt32 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - return UInt32ToDec(val, pdest); -} - -size_t - cvtInt32ToString(epicsInt32 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - if (val > 0) - return UInt32ToDec(val, pdest); - - if (val == -0x80000000) { - strcpy(pdest, "-2147483648"); - return strlen(pdest); - } - - *pdest++ = '-'; - return 1 + UInt32ToDec(-val, pdest); -} - - -size_t - cvtUInt64ToString(epicsUInt64 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - return UInt64ToDec(val, pdest); -} - -size_t - cvtInt64ToString(epicsInt64 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - if (val > 0) - return UInt64ToDec(val, pdest); - - if (val == -0x8000000000000000LL) { - strcpy(pdest, "-9223372036854775808"); - return strlen(pdest); - } - - *pdest++ = '-'; - return 1 + UInt64ToDec(-val, pdest); -} - - -size_t - cvtInt32ToHexString(epicsInt32 val, char *pdest) -{ - if (val < 0) - *pdest++ = '-'; - - *pdest++ = '0'; - *pdest++ = 'x'; - - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 3; - } - - if (val > 0) - return 2 + UInt32ToBase(val, pdest, 16); - - if (val == -0x80000000) { - strcpy(pdest, "80000000"); - return 11; - } - - return 3 + UInt32ToBase(-val, pdest, 16); -} - -size_t - cvtUInt32ToHexString(epicsUInt32 val, char *pdest) -{ - *pdest++ = '0'; - *pdest++ = 'x'; - - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 3; - } - - return 2 + UInt32ToBase(val, pdest, 16); -} - -size_t - cvtInt32OctalString(epicsInt32 val, char *pdest) -{ - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 1; - } - - if (val > 0) { - *pdest++ = '0'; - return 1 + UInt32ToBase(val, pdest, 8); - } - - if (val == -0x80000000) { - strcpy(pdest, "-020000000000"); - return strlen(pdest); - } - - *pdest++ = '-'; - *pdest++ = '0'; - return 2 + UInt32ToBase(-val, pdest, 8); -} - -size_t - cvtInt64ToHexString(epicsInt64 val, char *pdest) -{ - if (val < 0) - *pdest++ = '-'; - - *pdest++ = '0'; - *pdest++ = 'x'; - - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 3; - } - - if (val > 0) - return 2 + UInt64ToBase(val, pdest, 16); - - if (val == -0x8000000000000000LL) { - strcpy(pdest, "8000000000000000"); - return 19; - } - - return 3 + UInt64ToBase(-val, pdest, 16); -} - -size_t - cvtUInt64ToHexString(epicsUInt64 val, char *pdest) -{ - *pdest++ = '0'; - *pdest++ = 'x'; - - if (val == 0) { - *pdest++ = '0'; - *pdest = 0; - return 3; - } - - return 2 + UInt64ToBase(val, pdest, 16); -} - diff --git a/src/libCom/cvtFast/cvtFast.h b/src/libCom/cvtFast/cvtFast.h deleted file mode 100644 index db06dda53..000000000 --- a/src/libCom/cvtFast/cvtFast.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Fast numeric to string conversions - * - * Original Authors: - * Bob Dalesio, Mark Anderson and Marty Kraimer - * Date: 12 January 1993 - */ - -#ifndef INCcvtFasth -#define INCcvtFasth - -#include - -#include "epicsTypes.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * All functions return the number of characters in the output - */ -epicsShareFunc int - cvtFloatToString(float val, char *pdest, epicsUInt16 prec); -epicsShareFunc int - cvtDoubleToString(double val, char *pdest, epicsUInt16 prec); - -epicsShareFunc int - cvtFloatToExpString(float val, char *pdest, epicsUInt16 prec); -epicsShareFunc int - cvtDoubleToExpString(double val, char *pdest, epicsUInt16 prec); -epicsShareFunc int - cvtFloatToCompactString(float val, char *pdest, epicsUInt16 prec); -epicsShareFunc int - cvtDoubleToCompactString(double val, char *pdest, epicsUInt16 prec); - -epicsShareFunc size_t - cvtInt32ToString(epicsInt32 val, char *pdest); -epicsShareFunc size_t - cvtUInt32ToString(epicsUInt32 val, char *pdest); -epicsShareFunc size_t - cvtInt64ToString(epicsInt64 val, char *pdest); -epicsShareFunc size_t - cvtUInt64ToString(epicsUInt64 val, char *pdest); - -epicsShareFunc size_t - cvtInt32ToHexString(epicsInt32 val, char *pdest); -epicsShareFunc size_t - cvtUInt32ToHexString(epicsUInt32 val, char *pdest); -epicsShareFunc size_t - cvtInt32ToOctalString(epicsInt32 val, char *pdest); -epicsShareFunc size_t - cvtInt64ToHexString(epicsInt64 val, char *pdest); -epicsShareFunc size_t - cvtUInt64ToHexString(epicsUInt64 val, char *pdest); - -/* Support the original names */ - -#define cvtCharToString(val, str) cvtInt32ToString(val, str) -#define cvtUcharToString(val, str) cvtUInt32ToString(val, str) -#define cvtShortToString(val, str) cvtInt32ToString(val, str) -#define cvtUshortToString(val, str) cvtUInt32ToString(val, str) -#define cvtLongToString(val, str) cvtInt32ToString(val, str) -#define cvtUlongToString(val, str) cvtUInt32ToString(val, str) - -#define cvtLongToHexString(val, str) cvtInt32ToHexString(val, str) -#define cvtULongToHexString(val, str) cvtUInt32ToHexString(val, str) -#define cvtLongToOctalString(val, str) cvtInt32ToOctalString(val, str) - -#ifdef __cplusplus -} -#endif - -#endif /*INCcvtFasth*/ diff --git a/src/libCom/cxxTemplates/Makefile b/src/libCom/cxxTemplates/Makefile deleted file mode 100644 index c67668f55..000000000 --- a/src/libCom/cxxTemplates/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/cxxTemplates -INC += resourceLib.h -INC += tsDLList.h -INC += tsSLList.h -INC += tsMinMax.h -INC += tsFreeList.h -INC += epicsSingleton.h -INC += epicsGuard.h -Com_SRCS += resourceLib.cpp -Com_SRCS += epicsSingletonMutex.cpp - diff --git a/src/libCom/cxxTemplates/README b/src/libCom/cxxTemplates/README deleted file mode 100644 index 786c598b3..000000000 --- a/src/libCom/cxxTemplates/README +++ /dev/null @@ -1,35 +0,0 @@ - -C++ templates: -tsSLList.h - type safe single linked list template -tsDLList.h - type safe double linked list template -resourceLib.h - hash table template -tsFreeeList.h - free list allocator / deallocator - -the test subdir contains examples - -Since I am using templates the linked lists are type safe -(no casting of pointers ala ellList and dllList). -Also, the node class in embedded in the item on the -list (more efficient use of pool). - -The file resourceLib.h provides a core hashing library -"resTable " where "itemClass" objects -are stored in the hash table and "idClass" is the data type -of the key for the hash table. The identifier class provides -the hash alg. I have provided simple string "stringId" and -unsigned integer "uintId" key types in resourceLib.h. It -is easy to implement a new key class. - -There are examples under cxxTemplate/test. The list/hashing -templates all depend on a particular inheritance hierarchy. -If the inheritance hierarchy is wrong nothing will compile. -For instance, in tsDLList.h the template data type "T" -must derive from tsDLNode. Likewise, in tsSLList.h -"T" must derive from tsSLNode. Likewise, in resourceLib.h -class "T" (the type stored in the hash table) must derive -from class "ID" (the hash table key type) and also derive from -tsSLNode. - - - - diff --git a/src/libCom/cxxTemplates/epicsGuard.h b/src/libCom/cxxTemplates/epicsGuard.h deleted file mode 100644 index f0aa401a5..000000000 --- a/src/libCom/cxxTemplates/epicsGuard.h +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsGuardh -#define epicsGuardh - -#ifndef assert // allow use of epicsAssert.h -# include -#endif - -/* - * Author: Jeffrey O. Hill - */ - -template < class T > class epicsGuardRelease; - -// Automatically applies and releases the mutex. -// This class is also useful in situations where -// C++ exceptions are possible. -template < class T > -class epicsGuard { -public: - typedef epicsGuardRelease release_t; - epicsGuard ( T & ); - void assertIdenticalMutex ( const T & ) const; - ~epicsGuard (); -private: - T * _pTargetMutex; - epicsGuard ( const epicsGuard & ); - epicsGuard & operator = ( const epicsGuard & ); - friend class epicsGuardRelease < T >; -}; - -// Automatically releases and reapplies the mutex. -// This class is also useful in situations where -// C++ exceptions are possible. -template < class T > -class epicsGuardRelease { -public: - typedef epicsGuard guard_t; - epicsGuardRelease ( epicsGuard < T > & ); - ~epicsGuardRelease (); -private: - epicsGuard < T > & _guard; - T * _pTargetMutex; - epicsGuardRelease ( const epicsGuardRelease & ); - epicsGuardRelease & operator = ( const epicsGuardRelease & ); -}; - -// same interface as epicsMutex -class epicsMutexNOOP { -public: - void lock (); - bool tryLock (); - void unlock (); - void show ( unsigned level ) const; -}; - -template < class T > -inline epicsGuard < T > :: epicsGuard ( T & mutexIn ) : - _pTargetMutex ( & mutexIn ) -{ - _pTargetMutex->lock (); -} - -template < class T > -inline epicsGuard < T > :: ~epicsGuard () -{ - _pTargetMutex->unlock (); -} - -template < class T > -inline void epicsGuard < T > :: assertIdenticalMutex ( - const T & mutexToVerify ) const -{ - assert ( _pTargetMutex == & mutexToVerify ); -} - -template < class T > -inline epicsGuardRelease < T > :: - epicsGuardRelease ( epicsGuard & guardIn ) : - _guard ( guardIn ), - _pTargetMutex ( guardIn._pTargetMutex ) -{ - // Setting the guard's _pTargetMutex to nill will - // allow assertIdenticalMutex to catch situations - // where a guard is being used and it has been - // released, and also situations where ~epicsGuard () - // runs and an epicsGuardRelease is still referencing - // the guard will be detected. - _guard._pTargetMutex = 0; - _pTargetMutex->unlock (); -} - -template < class T > -inline epicsGuardRelease < T > :: ~epicsGuardRelease () -{ - _pTargetMutex->lock (); - _guard._pTargetMutex = _pTargetMutex; -} - -inline void epicsMutexNOOP::lock () {} -inline bool epicsMutexNOOP::tryLock () { return true; } -inline void epicsMutexNOOP::unlock () {} -inline void epicsMutexNOOP::show ( unsigned ) const {} - -#endif // epicsGuardh diff --git a/src/libCom/cxxTemplates/epicsSingleton.h b/src/libCom/cxxTemplates/epicsSingleton.h deleted file mode 100644 index 2c63d3ff7..000000000 --- a/src/libCom/cxxTemplates/epicsSingleton.h +++ /dev/null @@ -1,216 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - */ - -#ifndef epicsSingleton_h -#define epicsSingleton_h - -#include -#include - -#include "shareLib.h" -#include "epicsAssert.h" - -class epicsShareClass SingletonUntyped { -public: - SingletonUntyped (); - ~SingletonUntyped (); - typedef void * ( * PBuild ) (); - void incrRefCount ( PBuild ); - typedef void ( * PDestroy ) ( void * ); - void decrRefCount ( PDestroy ); - void * pInstance () const; -private: - void * _pInstance; - std :: size_t _refCount; - SingletonUntyped ( const SingletonUntyped & ); - SingletonUntyped & operator = ( const SingletonUntyped & ); -}; - -// This class exists for the purpose of avoiding file scope -// object chicken and egg problems. It implements thread safe -// lazy initialization. To avoid locking overhead retain a -// copy of the epicsSingleton :: reference for future use. -template < class TYPE > -class epicsSingleton { -public: - class reference { - public: - reference ( epicsSingleton & ); - reference ( const reference & ); - ~reference (); - // this somewhat convoluted reference of the return - // type ref through the epicsSingleton template is - // required for the archaic Tornado gnu compiler - typename epicsSingleton < TYPE > :: reference & - operator = ( const reference & ); - TYPE * operator -> (); - const TYPE * operator -> () const; - TYPE & operator * (); - const TYPE & operator * () const; - private: - epicsSingleton * _pSingleton; - }; - friend class reference; - epicsSingleton () {} - // mutex lock/unlock pair overhead incured - // when either of these are called - reference getReference (); - const reference getReference () const; -private: - SingletonUntyped _singletonUntyped; - static void * _build (); - static void _destroy ( void * ); - epicsSingleton ( const epicsSingleton & ); - epicsSingleton & operator = ( const epicsSingleton & ); -}; - -template < class TYPE > -inline epicsSingleton < TYPE > :: reference :: - reference ( epicsSingleton & es ): - _pSingleton ( & es ) -{ - es._singletonUntyped. - incrRefCount ( & epicsSingleton < TYPE > :: _build ); -} - -template < class TYPE > -inline epicsSingleton < TYPE > :: reference :: - reference ( const reference & ref ) : - _pSingleton ( ref._pSingleton ) -{ - assert ( _pSingleton ); - _pSingleton->_singletonUntyped. - incrRefCount ( & epicsSingleton < TYPE > :: _build ); -} - -template < class TYPE > -inline epicsSingleton < TYPE > :: reference :: - ~reference () -{ - assert ( _pSingleton ); - _pSingleton->_singletonUntyped. - decrRefCount ( & epicsSingleton < TYPE > :: _destroy ); -} - -template < class TYPE > -typename epicsSingleton < TYPE > :: reference & - epicsSingleton < TYPE > :: reference :: - operator = ( const reference & ref ) -{ - if ( _pSingleton != ref._pSingleton ) { - assert ( _pSingleton ); - _pSingleton->_singletonUntyped. - decrRefCount ( epicsSingleton < TYPE > :: _destroy ); - _pSingleton = ref._pSingleton; - assert ( _pSingleton ); - _pSingleton->_singletonUntyped. - incrRefCount ( & epicsSingleton < TYPE > :: _build ); - } - return *this; -} - -template < class TYPE > -inline TYPE * - epicsSingleton < TYPE > :: reference :: - operator -> () -{ - assert ( _pSingleton ); - return reinterpret_cast < TYPE * > - ( _pSingleton->_singletonUntyped.pInstance () ); -} - -template < class TYPE > -inline const TYPE * - epicsSingleton < TYPE > :: reference :: - operator -> () const -{ - assert ( _pSingleton ); - return reinterpret_cast < const TYPE * > - ( _pSingleton->_singletonUntyped.pInstance () ); -} - -template < class TYPE > -inline TYPE & - epicsSingleton < TYPE > :: reference :: - operator * () -{ - return * this->operator -> (); -} - -template < class TYPE > -inline const TYPE & - epicsSingleton < TYPE > :: reference :: - operator * () const -{ - return * this->operator -> (); -} - -inline SingletonUntyped :: SingletonUntyped () : - _pInstance ( 0 ), _refCount ( 0 ) -{ -} - -inline void * SingletonUntyped :: pInstance () const -{ - return _pInstance; -} - -inline SingletonUntyped :: ~SingletonUntyped () -{ - // we dont assert fail on non-zero _refCount - // and or non nill _pInstance here because this - // is designed to tolarate situations where - // file scope epicsSingleton objects (which - // theoretically dont have storage lifespan - // issues) are deleted in a non-determanistic - // order -# if 0 - assert ( _refCount == 0 ); - assert ( _pInstance == 0 ); -# endif -} - -template < class TYPE > -void * epicsSingleton < TYPE > :: _build () -{ - return new TYPE (); -} - -template < class TYPE > -void epicsSingleton < TYPE > :: - _destroy ( void * pDestroyTypeless ) -{ - TYPE * pDestroy = - reinterpret_cast < TYPE * > ( pDestroyTypeless ); - delete pDestroy; -} - -template < class TYPE > -inline typename epicsSingleton < TYPE > :: reference - epicsSingleton < TYPE > :: getReference () -{ - return reference ( * this ); -} - -template < class TYPE > -inline const typename epicsSingleton < TYPE > :: reference - epicsSingleton < TYPE > :: getReference () const -{ - epicsSingleton < TYPE > * pConstCastAway = - const_cast < epicsSingleton < TYPE > * > ( this ); - return pConstCastAway->getReference (); -} - -#endif // epicsSingleton_h - diff --git a/src/libCom/cxxTemplates/epicsSingletonBase.cpp b/src/libCom/cxxTemplates/epicsSingletonBase.cpp deleted file mode 100644 index bf9a466d4..000000000 --- a/src/libCom/cxxTemplates/epicsSingletonBase.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey O. Hill - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsThread.h" -#include "epicsSingleton.h" -#include "epicsExit.h" - -static epicsThreadOnceId epicsSingletonOnceId = EPICS_THREAD_ONCE_INIT; -static epicsMutex *pSingletonBaseMutexEPICS; - -static void epicsSingletonCleanup (void *) -{ - delete pSingletonBaseMutexEPICS; -} - -static void epicsSingletonOnce ( void * ) -{ - pSingletonBaseMutexEPICS = newEpicsMutex; - epicsAtExit ( epicsSingletonCleanup,0 ); -} - -epicsSingletonBase::epicsSingletonBase () : pSingleton ( 0 ) -{ -} - -void * epicsSingletonBase::singletonPointer () const -{ - return this->pSingleton; -} - -epicsSingletonBase::~epicsSingletonBase () -{ -} - -void epicsSingletonBase::lockedFactory () -{ - if ( ! this->pSingleton ) { - epicsThreadOnce ( & epicsSingletonOnceId, epicsSingletonOnce, 0 ); - epicsGuard < epicsMutex > guard ( *pSingletonBaseMutexEPICS ); - if ( ! this->pSingleton ) { - this->pSingleton = this->factory (); - } - } -} diff --git a/src/libCom/cxxTemplates/epicsSingletonMutex.cpp b/src/libCom/cxxTemplates/epicsSingletonMutex.cpp deleted file mode 100644 index 8cd69d969..000000000 --- a/src/libCom/cxxTemplates/epicsSingletonMutex.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff O. Hill - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsThread.h" -#include "epicsSingleton.h" - -#ifndef SIZE_MAX -# define SIZE_MAX UINT_MAX -#endif - -static epicsThreadOnceId epicsSigletonOnceFlag ( EPICS_THREAD_ONCE_INIT ); -static epicsMutex * pEPICSSigletonMutex = 0; - -extern "C" void SingletonMutexOnce ( void * /* pParm */ ) -{ - // This class exists for the purpose of avoiding file scope - // object chicken and egg problems. Therefore, pEPICSSigletonMutex - // is never destroyed. - pEPICSSigletonMutex = newEpicsMutex; -} - -void SingletonUntyped :: incrRefCount ( PBuild pBuild ) -{ - epicsThreadOnce ( & epicsSigletonOnceFlag, SingletonMutexOnce, 0 ); - epicsGuard < epicsMutex > - guard ( *pEPICSSigletonMutex ); - assert ( _refCount < SIZE_MAX ); - if ( _refCount == 0 ) { - _pInstance = ( * pBuild ) (); - } - _refCount++; -} - -void SingletonUntyped :: decrRefCount ( PDestroy pDestroy ) -{ - epicsGuard < epicsMutex > - guard ( *pEPICSSigletonMutex ); - assert ( _refCount > 0 ); - _refCount--; - if ( _refCount == 0 ) { - ( *pDestroy ) ( _pInstance ); - _pInstance = 0; - } -} diff --git a/src/libCom/cxxTemplates/resourceLib.cpp b/src/libCom/cxxTemplates/resourceLib.cpp deleted file mode 100644 index f3a9a9993..000000000 --- a/src/libCom/cxxTemplates/resourceLib.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#include "resourceLib.h" - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class intId < unsigned, 8u, sizeof(unsigned)*CHAR_BIT >; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif diff --git a/src/libCom/cxxTemplates/resourceLib.h b/src/libCom/cxxTemplates/resourceLib.h deleted file mode 100644 index 7b61e238d..000000000 --- a/src/libCom/cxxTemplates/resourceLib.h +++ /dev/null @@ -1,1170 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * General hash table templates for fast indexing of resources - * of any base resource type and any resource identifier type. Fast - * indexing is implemented with a hash lookup. The identifier type - * implements the hash algorithm (or derives from one of the supplied - * identifier types which provide a hashing routine). The table expands - * dynamically depending on load, and without introducing non-determanistic - * latency. - * - * Unsigned integer and string identifier classes are supplied here. - * - * Authors Jeffrey O. Hill - * Marty Kraimer (string hash algorithm) - * influenced by papers by Peter K. Pearson and Per-Ake Larson - * - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef INCresourceLibh -#define INCresourceLibh - -#include -#include - -#include -#include -#include -#include -#ifndef assert // allow use of epicsAssert.h -#include -#endif - -#include "tsSLList.h" -#include "epicsString.h" -#include "shareLib.h" -typedef size_t resTableIndex; - -template < class T, class ID > class resTableIter; -template < class T, class ID > class resTableIterConst; - -// -// class resTable -// -// This class stores resource entries of type T which can be efficiently -// located with a hash key of type ID. -// -// NOTES: -// 1) class T must derive from class ID and also from class tsSLNode -// -// 2) If the "resTable::show (unsigned level)" member function is called then -// class T must also implement a "show (unsigned level)" member function which -// dumps increasing diagnostics information with increasing "level" to -// standard out. -// -// 3) Classes of type ID must implement the following member functions: -// -// // equivalence test -// bool operator == (const ID &); -// -// // ID to hash index convert (see examples below) -// resTableIndex hash (unsigned nBitsHashIndex) const; -// -// 4) Storage for identifier of type ID must persist until the item of type -// T is deleted from the resTable -// -template -class resTable { -public: - resTable (); - virtual ~resTable(); - // Call " void T::show (unsigned level)" for each entry - void show ( unsigned level ) const; - void verify () const; - int add ( T & res ); // returns -1 (id exists in table), 0 (success) - T * remove ( const ID &idIn ); // remove entry - void removeAll ( tsSLList & destination ); // remove all entries - T * lookup ( const ID &idIn ) const; // locate entry - // Call (pT->*pCB) () for each entry but expect poor performance - // with sparcely populated tables - void traverse ( void (T::*pCB)() ); - void traverseConst ( void (T::*pCB)() const ) const; - unsigned numEntriesInstalled () const; - void setTableSize ( const unsigned newTableSize ); - // iterate through all entries but expect poor performance - // with sparcely populated tables - typedef resTableIter < T, ID > iterator; - typedef resTableIterConst < T, ID > iteratorConst; - iterator firstIter (); - iteratorConst firstIter () const; -private: - tsSLList < T > * pTable; - unsigned nextSplitIndex; - unsigned hashIxMask; - unsigned hashIxSplitMask; - unsigned nBitsHashIxSplitMask; - unsigned logBaseTwoTableSize; - unsigned nInUse; - resTableIndex hash ( const ID & idIn ) const; - T * find ( tsSLList & list, const ID & idIn ) const; - void splitBucket (); - unsigned tableSize () const; - bool setTableSizePrivate ( unsigned logBaseTwoTableSize ); - resTable ( const resTable & ); - resTable & operator = ( const resTable & ); - static unsigned resTableBitMask ( const unsigned nBits ); - friend class resTableIter < T, ID >; - friend class resTableIterConst < T, ID >; -}; - -// -// class resTableIter -// -// an iterator for the resource table class -// -template < class T, class ID > -class resTableIter { -public: - resTableIter (); - bool valid () const; - bool operator == ( const resTableIter < T,ID > & rhs ) const; - bool operator != ( const resTableIter < T,ID > & rhs ) const; - resTableIter < T, ID > & operator = ( const resTableIter < T, ID > & ); - T & operator * () const; - T * operator -> () const; - resTableIter < T, ID > & operator ++ (); - resTableIter < T, ID > operator ++ ( int ); - T * pointer (); -private: - tsSLIter < T > iter; - unsigned index; - resTable < T,ID > * pResTable; - resTableIter ( resTable < T,ID > & tableIn ); - void findNextEntry (); - friend class resTable < T, ID >; -}; - -// -// class resTableIterConst -// -// an iterator for a const resource table class -// -template < class T, class ID > -class resTableIterConst { -public: - resTableIterConst (); - bool valid () const; - bool operator == ( const resTableIterConst < T,ID > & rhs ) const; - bool operator != ( const resTableIterConst < T,ID > & rhs ) const; - resTableIterConst < T, ID > & operator = ( const resTableIterConst < T, ID > & ); - const T & operator * () const; - const T * operator -> () const; - resTableIterConst < T, ID > & operator ++ (); - resTableIterConst < T, ID > operator ++ ( int ); - const T * pointer () const; -private: - tsSLIterConst < T > iter; - unsigned index; - const resTable < T,ID > * pResTable; - resTableIterConst ( const resTable < T,ID > & tableIn ); - void findNextEntry (); - friend class resTable < T, ID >; -}; - -// -// Some ID classes that work with the above template -// - -// -// class intId -// -// signed or unsigned integer identifier (class T must be -// a signed or unsigned integer type) -// -// this class works as type ID in resTable -// -// 1<. -// Set this parameter to zero if unsure of the correct minimum -// hash table size. -// -// MAX_ID_WIDTH specifies the maximum number of ls bits in an -// integer identifier which might be set at any time. -// -// MIN_INDEX_WIDTH and MAX_ID_WIDTH are specified here at -// compile time so that the hash index can be produced -// efficiently. Hash indexes are produced more efficiently -// when (MAX_ID_WIDTH - MIN_INDEX_WIDTH) is minimized. -// -template -class intId { -public: - intId (const T &idIn); - bool operator == (const intId &idIn) const; - resTableIndex hash () const; - const T getId() const; -protected: - T id; -}; - -// -// class chronIntIdResTable -// -// a specialized resTable which uses unsigned integer keys which are -// allocated in chronological sequence -// -// NOTE: ITEM must public inherit from chronIntIdRes -// -class chronIntId : public intId -{ -public: - chronIntId ( const unsigned &idIn ); -}; - -template -class chronIntIdResTable : public resTable { -public: - chronIntIdResTable (); - virtual ~chronIntIdResTable (); - void idAssignAdd ( ITEM & item ); -private: - unsigned allocId; - chronIntIdResTable ( const chronIntIdResTable & ); - chronIntIdResTable & operator = ( const chronIntIdResTable & ); -}; - -// -// class chronIntIdRes -// -// resource with unsigned chronological identifier -// -template -class chronIntIdRes : public chronIntId, public tsSLNode { -public: - chronIntIdRes (); -private: - void setId (unsigned newId); - chronIntIdRes (const chronIntIdRes & ); - friend class chronIntIdResTable; -}; - -// -// class stringId -// -// character string identifier -// -class epicsShareClass stringId { -public: - enum allocationType {copyString, refString}; - stringId (const char * idIn, allocationType typeIn=copyString); - virtual ~stringId(); - resTableIndex hash () const; - bool operator == (const stringId &idIn) const; - const char * resourceName() const; // return the pointer to the string - void show (unsigned level) const; -private: - stringId & operator = ( const stringId & ); - stringId ( const stringId &); - const char * pStr; - const allocationType allocType; -}; - -///////////////////////////////////////////////// -// resTable member functions -///////////////////////////////////////////////// - -// -// resTable::resTable () -// -template -inline resTable::resTable () : - pTable ( 0 ), nextSplitIndex ( 0 ), hashIxMask ( 0 ), - hashIxSplitMask ( 0 ), nBitsHashIxSplitMask ( 0 ), - logBaseTwoTableSize ( 0 ), nInUse ( 0 ) {} - -template -inline unsigned resTable::resTableBitMask ( const unsigned nBits ) -{ - return ( 1 << nBits ) - 1; -} - -// -// resTable::remove () -// -// remove a res from the resTable -// -template -T * resTable::remove ( const ID & idIn ) -{ - if ( this->pTable ) { - // search list for idIn and remove the first match - tsSLList & list = this->pTable [ this->hash(idIn) ]; - tsSLIter pItem = list.firstIter (); - T *pPrev = 0; - while ( pItem.valid () ) { - const ID & idOfItem = *pItem; - if ( idOfItem == idIn ) { - if ( pPrev ) { - list.remove ( *pPrev ); - } - else { - list.get (); - } - this->nInUse--; - break; - } - pPrev = pItem.pointer (); - pItem++; - } - return pItem.pointer (); - } - else { - return 0; - } -} - -template -void resTable::removeAll ( tsSLList & destination ) -{ - const unsigned N = this->tableSize (); - for ( unsigned i = 0u; i < N; i++ ) { - while ( T * pItem = this->pTable[i].get() ) { - destination.add ( *pItem ); - } - } - this->nInUse = 0; -} - -// -// resTable::lookup () -// -template -inline T * resTable::lookup ( const ID & idIn ) const -{ - if ( this->pTable ) { - tsSLList & list = this->pTable [ this->hash ( idIn ) ]; - return this->find ( list, idIn ); - } - else { - return 0; - } -} - -// -// resTable::hash () -// -template -inline resTableIndex resTable::hash ( const ID & idIn ) const -{ - resTableIndex h = idIn.hash (); - resTableIndex h0 = h & this->hashIxMask; - if ( h0 >= this->nextSplitIndex ) { - return h0; - } - return h & this->hashIxSplitMask; -} - -// -// resTable::show -// -template -void resTable::show ( unsigned level ) const -{ - const unsigned N = this->tableSize (); - - printf ( "Hash table with %u buckets and %u items of type %s installed\n", - N, this->nInUse, typeid(T).name() ); - - if ( level >= 1u && N ) { - - if ( level >= 2u ) { - tsSLList * pList = this->pTable; - while ( pList < & this->pTable[N] ) { - tsSLIter pItem = pList->firstIter (); - while ( pItem.valid () ) { - tsSLIter pNext = pItem; - pNext++; - pItem.pointer()->show ( level - 2u ); - pItem = pNext; - } - pList++; - } - } - - double X = 0.0; - double XX = 0.0; - unsigned maxEntries = 0u; - unsigned empty = 0; - for ( unsigned i = 0u; i < N; i++ ) { - tsSLIter pItem = this->pTable[i].firstIter (); - unsigned count = 0; - while ( pItem.valid () ) { - if ( level >= 3u ) { - pItem->show ( level ); - } - count++; - pItem++; - } - if ( count > 0u ) { - X += count; - XX += count * count; - if ( count > maxEntries ) { - maxEntries = count; - } - } else - empty++; - } - - double mean = X / N; - double stdDev = sqrt( XX / N - mean * mean ); - printf ( - "entries per bucket: mean = %f std dev = %f max = %u\n", - mean, stdDev, maxEntries ); - printf("%u empty buckets\n", empty); - if ( X != this->nInUse ) { - printf ("this->nInUse didnt match items counted which was %f????\n", X ); - } - } -} - -// self test -template -void resTable::verify () const -{ - const unsigned N = this->tableSize (); - - if ( this->pTable ) { - assert ( this->nextSplitIndex <= this->hashIxMask + 1 ); - assert ( this->hashIxMask ); - assert ( this->hashIxMask == ( this->hashIxSplitMask >> 1 ) ); - assert ( this->hashIxSplitMask ); - assert ( this->nBitsHashIxSplitMask ); - assert ( resTableBitMask ( this->nBitsHashIxSplitMask ) - == this->hashIxSplitMask ); - assert ( this->logBaseTwoTableSize ); - assert ( this->nBitsHashIxSplitMask <= this->logBaseTwoTableSize ); - } - else { - assert ( this->nextSplitIndex == 0 ); - assert ( this->hashIxMask == 0 ); - assert ( this->hashIxSplitMask == 0 ); - assert ( this->nBitsHashIxSplitMask == 0 ); - assert ( this->logBaseTwoTableSize == 0 ); - } - - unsigned total = 0u; - for ( unsigned i = 0u; i < N; i++ ) { - tsSLIter pItem = this->pTable[i].firstIter (); - unsigned count = 0; - while ( pItem.valid () ) { - resTableIndex index = this->hash ( *pItem ); - assert ( index == i ); - count++; - pItem++; - } - total += count; - } - assert ( total == this->nInUse ); -} - - -// -// resTable::traverse -// -template -void resTable::traverse ( void (T::*pCB)() ) -{ - const unsigned N = this->tableSize (); - for ( unsigned i = 0u; i < N; i++ ) { - tsSLIter pItem = this->pTable[i].firstIter (); - while ( pItem.valid () ) { - tsSLIter pNext = pItem; - pNext++; - ( pItem.pointer ()->*pCB ) (); - pItem = pNext; - } - } -} - -// -// resTable::traverseConst -// -template -void resTable::traverseConst ( void (T::*pCB)() const ) const -{ - const unsigned N = this->tableSize (); - for ( unsigned i = 0u; i < N; i++ ) { - const tsSLList < T > & table = this->pTable[i]; - tsSLIterConst pItem = table.firstIter (); - while ( pItem.valid () ) { - tsSLIterConst pNext = pItem; - pNext++; - ( pItem.pointer ()->*pCB ) (); - pItem = pNext; - } - } -} - -template -inline unsigned resTable::numEntriesInstalled () const -{ - return this->nInUse; -} - -template -inline unsigned resTable::tableSize () const -{ - if ( this->pTable ) { - return ( this->hashIxMask + 1 ) + this->nextSplitIndex; - } - else { - return 0; - } -} - -// it will be more efficent to call this once prior to installing -// the first entry -template -void resTable::setTableSize ( const unsigned newTableSize ) -{ - if ( newTableSize == 0u ) { - return; - } - - // - // count the number of bits in newTableSize and round up - // to the next power of two - // - unsigned newMask = newTableSize - 1; - unsigned nbits; - for ( nbits = 0; nbits < sizeof (newTableSize) * CHAR_BIT; nbits++ ) { - unsigned nBitsMask = resTableBitMask ( nbits ); - if ( ( newMask & ~nBitsMask ) == 0){ - break; - } - } - setTableSizePrivate ( nbits ); -} - -template -bool resTable::setTableSizePrivate ( unsigned logBaseTwoTableSizeIn ) -{ - // dont shrink - if ( this->logBaseTwoTableSize >= logBaseTwoTableSizeIn ) { - return true; - } - - // dont allow ridiculously small tables - if ( logBaseTwoTableSizeIn < 4 ) { - logBaseTwoTableSizeIn = 4; - } - - const unsigned newTableSize = 1 << logBaseTwoTableSizeIn; -# if ! defined (__GNUC__) || __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 92 ) - const unsigned oldTableSize = this->pTable ? 1 << this->logBaseTwoTableSize : 0; -# endif - const unsigned oldTableOccupiedSize = this->tableSize (); - - tsSLList * pNewTable; - try { - pNewTable = ( tsSLList * ) - ::operator new ( newTableSize * sizeof ( tsSLList ) ); - } - catch ( ... ){ - if ( ! this->pTable ) { - throw; - } - return false; - } - - // run the constructors using placement new - unsigned i; - for ( i = 0u; i < oldTableOccupiedSize; i++ ) { - new ( &pNewTable[i] ) tsSLList ( this->pTable[i] ); - } - for ( i = oldTableOccupiedSize; i < newTableSize; i++ ) { - new ( &pNewTable[i] ) tsSLList; - } - // Run the destructors explicitly. Currently this destructor is a noop. - // The Tornado II compiler and RedHat 6.2 will not compile ~tsSLList() but - // since its a NOOP we can find an ugly workaround -# if ! defined (__GNUC__) || __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 92 ) - for ( i = 0; i < oldTableSize; i++ ) { - this->pTable[i].~tsSLList(); - } -# endif - - if ( ! this->pTable ) { - this->hashIxSplitMask = resTableBitMask ( logBaseTwoTableSizeIn ); - this->nBitsHashIxSplitMask = logBaseTwoTableSizeIn; - this->hashIxMask = this->hashIxSplitMask >> 1; - this->nextSplitIndex = 0; - } - - operator delete ( this->pTable ); - this->pTable = pNewTable; - this->logBaseTwoTableSize = logBaseTwoTableSizeIn; - - return true; -} - -template -void resTable::splitBucket () -{ - // double the hash table when necessary - // (this results in only a memcpy overhead, but - // no hashing or entry redistribution) - if ( this->nextSplitIndex > this->hashIxMask ) { - bool success = this->setTableSizePrivate ( this->nBitsHashIxSplitMask + 1 ); - if ( ! success ) { - return; - } - this->nBitsHashIxSplitMask += 1; - this->hashIxSplitMask = resTableBitMask ( this->nBitsHashIxSplitMask ); - this->hashIxMask = this->hashIxSplitMask >> 1; - this->nextSplitIndex = 0; - } - - // rehash only the items in the split bucket - tsSLList tmp ( this->pTable[ this->nextSplitIndex ] ); - this->nextSplitIndex++; - T *pItem = tmp.get(); - while ( pItem ) { - resTableIndex index = this->hash ( *pItem ); - this->pTable[index].add ( *pItem ); - pItem = tmp.get(); - } -} - -// -// add a res to the resTable -// -template -int resTable::add ( T &res ) -{ - if ( ! this->pTable ) { - this->setTableSizePrivate ( 10 ); - } - else if ( this->nInUse >= this->tableSize() ) { - this->splitBucket (); - tsSLList &list = this->pTable[this->hash(res)]; - if ( this->find ( list, res ) != 0 ) { - return -1; - } - } - tsSLList &list = this->pTable[this->hash(res)]; - if ( this->find ( list, res ) != 0 ) { - return -1; - } - list.add ( res ); - this->nInUse++; - return 0; -} - -// -// find -// searches from where the iterator points to the -// end of the list for idIn -// -// iterator points to the item found upon return -// (or NULL if nothing matching was found) -// -template -T * resTable::find ( tsSLList &list, const ID &idIn ) const -{ - tsSLIter pItem = list.firstIter (); - while ( pItem.valid () ) { - const ID & idOfItem = *pItem; - if ( idOfItem == idIn ) { - break; - } - pItem++; - } - return pItem.pointer (); -} - -// -// ~resTable::resTable() -// -template -resTable::~resTable() -{ - operator delete ( this->pTable ); -} - -// -// resTable::resTable ( const resTable & ) -// private - not to be used - implemented to eliminate warnings -// -template -inline resTable::resTable ( const resTable & ) -{ -} - -// -// resTable::resTable & operator = ( const resTable & ) -// private - not to be used - implemented to eliminate warnings -// -template -inline resTable & resTable::operator = ( const resTable & ) -{ - return *this; -} - -template -inline resTableIterConst < T, ID > resTable::firstIter () const -{ - return resTableIterConst < T, ID > ( *this ); -} - -template -inline resTableIter < T, ID > resTable::firstIter () -{ - return resTableIter < T, ID > ( *this ); -} - -////////////////////////////////////////////// -// resTableIter member functions -////////////////////////////////////////////// - -template < class T, class ID > -inline resTableIter::resTableIter ( resTable < T,ID > & tableIn ) : - index ( 0 ), pResTable ( & tableIn ) -{ - this->findNextEntry (); -} - -template < class T, class ID > -inline resTableIter::resTableIter () : - iter ( tsSLList::invalidIter() ), - index ( 0 ), pResTable ( 0 ) -{ -} - -template < class T, class ID > -inline void resTableIter::findNextEntry () -{ - if ( this->pResTable ) { - while ( this->index < this->pResTable->tableSize() ) { - this->iter = this->pResTable->pTable[this->index++].firstIter (); - if ( this->iter.valid () ) { - break; - } - } - } -} - -template < class T, class ID > -inline bool resTableIter::valid () const -{ - return this->iter.valid (); -} - -template < class T, class ID > -inline bool resTableIter::operator == - ( const resTableIter < T,ID > & rhs ) const -{ - return ( this->pResTable == rhs.pResTable - && this->index == rhs.index - && this->iter == rhs.iter ); -} - -template < class T, class ID > -inline bool resTableIter::operator != - ( const resTableIter < T,ID > & rhs ) const -{ - return ! this->operator == ( rhs ); -} - -template < class T, class ID > -inline resTableIter < T, ID > & resTableIter::operator = - ( const resTableIter < T, ID > & rhs ) -{ - this->pResTable = rhs.pResTable; - this->index = rhs.index; - this->iter = rhs.iter; - return *this; -} - -template < class T, class ID > -inline T & resTableIter::operator * () const -{ - return this->iter.operator * (); -} - -template < class T, class ID > -inline T * resTableIter::operator -> () const -{ - return this->iter.operator -> (); -} - -template < class T, class ID > -inline resTableIter & resTableIter::operator ++ () -{ - this->iter++; - if ( ! this->iter.valid() ) { - this->findNextEntry (); - } - return *this; -} - -template < class T, class ID > -inline resTableIter resTableIter::operator ++ ( int ) -{ - resTableIter tmp = *this; - this->operator ++ (); - return tmp; -} - -template < class T, class ID > -inline T * resTableIter::pointer () -{ - return this->iter.pointer (); -} - -////////////////////////////////////////////// -// resTableIterConst member functions -////////////////////////////////////////////// - -template < class T, class ID > -inline resTableIterConst::resTableIterConst ( const resTable < T,ID > & tableIn ) : - index ( 0 ), pResTable ( & tableIn ) -{ - this->findNextEntry (); -} - -template < class T, class ID > -inline resTableIterConst::resTableIterConst () : - iter ( tsSLList::invalidIter() ), - index ( 0 ), pResTable ( 0 ) -{ -} - -template < class T, class ID > -inline void resTableIterConst::findNextEntry () -{ - if ( this->pResTable ) { - while ( this->index < this->pResTable->tableSize() ) { - const tsSLList * pList = & this->pResTable->pTable[this->index++]; - this->iter = pList->firstIter (); - if ( this->iter.valid () ) { - break; - } - } - } -} - -template < class T, class ID > -inline bool resTableIterConst::valid () const -{ - return this->iter.valid (); -} - -template < class T, class ID > -inline bool resTableIterConst::operator == - ( const resTableIterConst < T,ID > & rhs ) const -{ - return ( this->pResTable == rhs.pResTable - && this->index == rhs.index - && this->iter == rhs.iter ); -} - -template < class T, class ID > -inline bool resTableIterConst::operator != - ( const resTableIterConst < T,ID > & rhs ) const -{ - return ! this->operator == ( rhs ); -} - -template < class T, class ID > -inline resTableIterConst < T, ID > & resTableIterConst::operator = - ( const resTableIterConst < T, ID > & rhs ) -{ - this->pResTable = rhs.pResTable; - this->index = rhs.index; - this->iter = rhs.iter; - return *this; -} - -template < class T, class ID > -inline const T & resTableIterConst::operator * () const -{ - return this->iter.operator * (); -} - -template < class T, class ID > -inline const T * resTableIterConst::operator -> () const -{ - return this->iter.operator -> (); -} - -template < class T, class ID > -inline resTableIterConst & resTableIterConst::operator ++ () -{ - this->iter++; - if ( ! this->iter.valid() ) { - this->findNextEntry (); - } - return *this; -} - -template < class T, class ID > -inline resTableIterConst resTableIterConst::operator ++ ( int ) -{ - resTableIterConst tmp = *this; - this->operator ++ (); - return tmp; -} - -template < class T, class ID > -inline const T * resTableIterConst::pointer () const -{ - return this->iter.pointer (); -} - -////////////////////////////////////////////// -// chronIntIdResTable member functions -////////////////////////////////////////////// -inline chronIntId::chronIntId ( const unsigned &idIn ) : - intId ( idIn ) {} - -// -// chronIntIdResTable::chronIntIdResTable() -// -template -inline chronIntIdResTable::chronIntIdResTable () : - resTable (), allocId(1u) {} - -template -inline chronIntIdResTable::chronIntIdResTable ( const chronIntIdResTable & ) : - resTable (), allocId(1u) {} - -template -inline chronIntIdResTable & chronIntIdResTable:: - operator = ( const chronIntIdResTable & ) -{ - return *this; -} - -// -// chronIntIdResTable::~chronIntIdResTable() -// (not inline because it is virtual) -// -template -chronIntIdResTable::~chronIntIdResTable() {} - -// -// chronIntIdResTable::add() -// -// NOTE: This detects (and avoids) the case where -// the PV id wraps around and we attempt to have two -// resources with the same id. -// -template -inline void chronIntIdResTable::idAssignAdd (ITEM &item) -{ - int status; - do { - item.chronIntIdRes::setId (allocId++); - status = this->resTable::add (item); - } - while (status); -} - -///////////////////////////////////////////////// -// chronIntIdRes member functions -///////////////////////////////////////////////// - -// -// chronIntIdRes::chronIntIdRes -// -template -inline chronIntIdRes::chronIntIdRes () : chronIntId (UINT_MAX) {} - -// -// id::setId () -// -// workaround for bug in DEC compiler -// -template -inline void chronIntIdRes::setId (unsigned newId) -{ - this->id = newId; -} - -///////////////////////////////////////////////// -// intId member functions -///////////////////////////////////////////////// - -// -// intId::intId -// -// (if this is inline SUN PRO botches the template instantiation) -template -intId::intId (const T &idIn) - : id (idIn) {} - -// -// intId::operator == () -// -template -inline bool intId::operator == - (const intId &idIn) const -{ - return this->id == idIn.id; -} - -// -// intId::getId () -// -template -inline const T intId::getId () const -{ - return this->id; -} - -// -// integerHash() -// -// converts any integer into a hash table index -// -template < class T > -inline resTableIndex integerHash ( unsigned MIN_INDEX_WIDTH, - unsigned MAX_ID_WIDTH, const T &id ) -{ - resTableIndex hashid = static_cast ( id ); - - // - // the intent here is to gurantee that all components of the - // integer contribute even if the resTableIndex returned might - // index a small table. - // - // On most compilers the optimizer will unroll this loop so this - // is actually a very small inline function - // - // Experiments using the microsoft compiler show that this isnt - // slower than switching on the architecture size and unrolling the - // loop explicitly (that solution has resulted in portability - // problems in the past). - // - unsigned width = MAX_ID_WIDTH; - do { - width >>= 1u; - hashid ^= hashid>>width; - } while (width>MIN_INDEX_WIDTH); - - // - // the result here is always masked to the - // proper size after it is returned to the "resTable" class - // - return hashid; -} - - -// -// intId::hash() -// -template -inline resTableIndex intId::hash () const -{ - return integerHash ( MIN_INDEX_WIDTH, MAX_ID_WIDTH, this->id ); -} - -//////////////////////////////////////////////////// -// stringId member functions -//////////////////////////////////////////////////// - -// -// stringId::operator == () -// -inline bool stringId::operator == - (const stringId &idIn) const -{ - if (this->pStr!=NULL && idIn.pStr!=NULL) { - return strcmp(this->pStr,idIn.pStr)==0; - } - return false; // not equal -} - -// -// stringId::resourceName () -// -inline const char * stringId::resourceName () const -{ - return this->pStr; -} - -#ifdef instantiateRecourceLib - -// -// stringId::stringId() -// -stringId::stringId (const char * idIn, allocationType typeIn) : - allocType (typeIn) -{ - if (typeIn==copyString) { - unsigned nChars = strlen (idIn) + 1u; - this->pStr = new char [nChars]; - memcpy ( (void *) this->pStr, idIn, nChars ); - } - else { - this->pStr = idIn; - } -} - -// -// stringId::show () -// -void stringId::show (unsigned level) const -{ - if (level>2u) { - printf ("resource id = %s\n", this->pStr); - } -} - -// -// stringId::~stringId() -// -// -// this needs to be instantiated only once (normally in libCom) -// -stringId::~stringId() -{ - if (this->allocType==copyString) { - if (this->pStr!=NULL) { - // - // the microsoft and solaris compilers will - // not allow a pointer to "const char" - // to be deleted - // - // the HP-UX compiler gives us a warning on - // each cast away of const, but in this case - // it cant be avoided. - // - // The DEC compiler complains that const isnt - // really significant in a cast if it is present. - // - // I hope that deleting a pointer to "char" - // is the same as deleting a pointer to - // "const char" on all compilers - // - delete [] const_cast(this->pStr); - } - } -} - -// -// stringId::hash() -// -resTableIndex stringId::hash() const -{ - if (!this->pStr) { - return 0u; - } - return epicsStrHash(this->pStr, 0); -} - -#endif // if instantiateRecourceLib is defined - -#endif // INCresourceLibh - diff --git a/src/libCom/cxxTemplates/test/Makefile b/src/libCom/cxxTemplates/test/Makefile deleted file mode 100644 index 61d807c65..000000000 --- a/src/libCom/cxxTemplates/test/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -resourceLibTest_SRCS += resourceLibTest.cc -TESTPROD_HOST += resourceLibTest - -tsDLListBench_SRCS += tsDLListBench.cc -TESTPROD_HOST += tsDLListBench - -tsDLListTest_SRCS += tsDLListTest.cc -TESTPROD_HOST += tsDLListTest - -tsSLListBench_SRCS += tsSLListBench.cc -TESTPROD_HOST += tsSLListBench - -tsSLListTest_SRCS += tsSLListTest.cc -TESTPROD_HOST += tsSLListTest - -minmaxTest_SRCS += minmaxTest.cc -TESTPROD_HOST += minmaxTest - -PROD_LIBS = Com - -include $(TOP)/configure/RULES - diff --git a/src/libCom/cxxTemplates/test/minmaxTest.cc b/src/libCom/cxxTemplates/test/minmaxTest.cc deleted file mode 100644 index b5cf5b110..000000000 --- a/src/libCom/cxxTemplates/test/minmaxTest.cc +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "tsMinMax.h" - -int main () -{ - float f1 = 3.3f; - float f2 = 3.4f; - float f3; - - f3 = tsMin(f1,f2); - assert(f3==f1); - - f3 = tsMax(f1,f2); - assert(f3==f2); - - int i1 = 3; - int i2 = 4; - int i3; - - i3 = tsMin(i1,i2); - assert(i3==i1); - - i3 = tsMax(i1,i2); - assert(i3==i2); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/resourceLibTest.cc b/src/libCom/cxxTemplates/test/resourceLibTest.cc deleted file mode 100644 index 1a6a2c1f9..000000000 --- a/src/libCom/cxxTemplates/test/resourceLibTest.cc +++ /dev/null @@ -1,309 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#define instantiateRecourceLib -#include "resourceLib.h" - -#if defined(__GNUC__) && ( __GNUC__<2 || (__GNUC__==2 && __GNUC__<8) ) -typedef intId testIntId; -#else -typedef intId testIntId; -#endif - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -static void empty() -{ -} - -class albert : public testIntId, public tsSLNode { -public: - albert (resTable< albert, testIntId > &atIn, unsigned idIn) : - testIntId(idIn), at(atIn) - { - verify (at.add (*this)==0); - } - void show (unsigned /* level */) - { - } - void destroy() - { - at.remove(*this); - delete this; - } -private: - resTable< albert, testIntId > &at; -}; - -class fred : public testIntId, public tsSLNode { -public: - fred (const char *pNameIn, unsigned idIn) : - testIntId(idIn), pName(pNameIn) {} - void show (unsigned) - { - printf("fred %s\n", pName); - } - void destroy() - { - // always on stack so noop - } -private: - const char * const pName; -}; - -class jane : public stringId, public tsSLNode { -public: - jane (const char *pNameIn) : stringId (pNameIn) {} - - void testTraverse(); - - void destroy() - { - // always on stack so noop - } -}; - -// -// jane::testTraverse() -// -void jane::testTraverse() -{ - printf("Traverse Test\n"); - this->show(10); -} - -int main() -{ - unsigned i; - clock_t start, finish; - double duration; - const unsigned LOOPS = 500000; - resTable < fred, testIntId > intTbl; - resTable < jane, stringId> strTbl; - fred fred0("fred0",0); - fred fred1("fred1",0x1000a432); - fred fred2("fred2",0x0000a432); - fred fred3("fred3",1); - fred fred4("fred4",2); - fred fred5("fred5",3); - fred fred6("fred6",4); - fred fred7("fred7",5); - fred fred8("fred8",6); - fred fred9("fred9",7); - jane jane1("rrrrrrrrrrrrrrrrrrrrrrrrrr1"); - jane jane2("rrrrrrrrrrrrrrrrrrrrrrrrrr2"); - fred *pFred; - jane *pJane; - testIntId intId0 (0); - testIntId intId1 (0x1000a432); - testIntId intId2 (0x0000a432); - testIntId intId3 (1); - testIntId intId4 (2); - testIntId intId5 (3); - testIntId intId6 (4); - testIntId intId7 (5); - testIntId intId8 (6); - testIntId intId9 (7); - - stringId strId1("rrrrrrrrrrrrrrrrrrrrrrrrrr1"); - strTbl.verify (); - stringId strId2("rrrrrrrrrrrrrrrrrrrrrrrrrr2"); - strTbl.verify (); - - intTbl.setTableSize ( 100000 ); - - verify (intTbl.add(fred0)==0); - intTbl.verify (); - verify (intTbl.add(fred1)==0); - intTbl.verify (); - verify (intTbl.add(fred2)==0); - intTbl.verify (); - verify (intTbl.add(fred3)==0); - intTbl.verify (); - verify (intTbl.add(fred4)==0); - intTbl.verify (); - - intTbl.setTableSize ( 200000 ); - - verify (intTbl.add(fred5)==0); - intTbl.verify (); - verify (intTbl.add(fred6)==0); - intTbl.verify (); - verify (intTbl.add(fred7)==0); - intTbl.verify (); - verify (intTbl.add(fred8)==0); - intTbl.verify (); - verify (intTbl.add(fred9)==0); - intTbl.verify (); - - start = clock(); - for (i=0; i alTbl; - - for (i=0; i alTblIter ( alTbl.firstIter() ); - albert *pa; - i=0; - while ( ( pa = alTblIter.pointer() ) ) { - i++; - alTblIter++; - } - verify ( i == elementCount ); - alTbl.verify (); - - for ( i = 0; i < elementCount; i++ ) { - verify ( pAlbert[i] == alTbl.lookup( pAlbert[i]->getId() ) ); - } - alTbl.verify (); - - for ( i = 0; i < elementCount; i += 2 ) { - verify ( pAlbert[i] == alTbl.remove ( pAlbert[i]->getId() ) ); - } - alTbl.verify (); - - for ( i = 0; i < elementCount; i += 2 ) { - verify ( 0 == alTbl.lookup ( pAlbert[i]->getId() ) ); - } - alTbl.verify (); - - for ( i = 1; i < elementCount; i += 2 ) { - verify ( pAlbert[i] == alTbl.lookup ( pAlbert[i]->getId() ) ); - } - alTbl.verify (); - - return 0; -} - - - diff --git a/src/libCom/cxxTemplates/test/tsDLListBench.cc b/src/libCom/cxxTemplates/test/tsDLListBench.cc deleted file mode 100644 index 577a3829d..000000000 --- a/src/libCom/cxxTemplates/test/tsDLListBench.cc +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "tsDLList.h" -#include -#include -#include - -class fred : public tsDLNode { -public: - fred() : count(0) {} - void inc () {count++;} -private: - unsigned count; -}; - -class jane : public fred, public tsDLNode { -public: - jane() {} -private: -}; - -#define LOOPCOUNT 100000 - -int main () -{ - tsDLList list; - tsDLIter iter = list.firstIter(); - fred *pFred; - unsigned i; - clock_t clk; - clock_t diff; - double delay; - - for (i=0; iinc(); - iter++; - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - pFred = new fred(); - clk = clock(); - for (i=0; iinc(); - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsDLListTest.cc b/src/libCom/cxxTemplates/test/tsDLListTest.cc deleted file mode 100644 index 02fe0dcd9..000000000 --- a/src/libCom/cxxTemplates/test/tsDLListTest.cc +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - - -#include "tsDLList.h" -#include -#include - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -class fred : public tsDLNode { -public: - fred(const char * const pNameIn) : pName(pNameIn){} - void show () {printf("%s\n", pName);} -private: - const char * const pName; -}; - -class jane : public fred, public tsDLNode { -public: - jane(const char * const pNameIn) : fred(pNameIn){} -private: -}; - -int main () -{ - unsigned i; - tsDLList list; - fred *pFred; - fred *pFredII; - fred *pFredBack; - tsDLList janeList; - tsDLIter janeFwdIter = janeList.firstIter(); - tsDLIter janeBwdIter = janeList.lastIter(); - jane *pJane; - - pFred = new fred ("A"); - pFredII = new fred ("B"); - - list.add (*pFred); - list.add (*pFredII); - tsDLIter iter = list.firstIter(); - verify (iter.pointer() == pFred); - iter++; - verify (iter.pointer() == pFredII); - list.remove(*pFred); - list.add(*pFred); - pFredBack = list.get(); - verify (pFredBack == pFredII); - pFredBack = list.get(); - verify (pFredBack == pFred); - verify (list.count() == 0u); - list.add(*pFred); - list.add(*pFredII); - list.add(* new fred("C")); - list.add(* new fred("D")); - - iter = list.firstIter(); - while ( iter.valid() ) { - iter->show(); - iter++; - } - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - verify ( janeList.find ( *pJane ) == -1 ); - janeList.add(*pJane); - verify ( janeList.find ( *pJane ) == 1 ); - - while ( janeFwdIter.valid() ) { - janeFwdIter->show(); - janeFwdIter++; - } - - while ( janeBwdIter.valid() ) { - janeBwdIter->show(); - janeBwdIter--; - } - - iter = list.firstIter(); - while ( iter.valid() ) { - iter->show(); - iter++; - } - - tsDLIter < jane > bdIter = janeList.firstIter (); - i = 0; - while ( bdIter.valid () ) { - i++; - bdIter++; - } - verify ( i == janeList.count () ); - - iter = list.firstIter(); - while ( iter.pointer() ) { - list.remove( * iter.pointer() ); - iter++; - } - verify (list.count()==0); - - janeFwdIter = janeList.firstIter(); - while ( janeFwdIter.valid() ) { - janeList.remove( * janeFwdIter.pointer() ); - janeFwdIter++; - } - verify (janeList.count()==0); - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - janeList.add(*pJane); - janeBwdIter = janeList.lastIter(); - while ( janeBwdIter.valid() ) { - janeList.remove( * janeBwdIter.pointer() ); - janeBwdIter--; - } - verify (janeList.count()==0); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsSLListBench.cc b/src/libCom/cxxTemplates/test/tsSLListBench.cc deleted file mode 100644 index 0b786dfd3..000000000 --- a/src/libCom/cxxTemplates/test/tsSLListBench.cc +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - - -#include "tsSLList.h" -#include -#include -#include - -/* - * gnuc does not provide this under sunos4 - */ -#if !defined(CLOCKS_PER_SEC) && defined(SUNOS4) -# define CLOCKS_PER_SEC 1000000 -#endif - -class fred : public tsSLNode { -public: - fred() : count(0) {} - void inc () {count++;} -private: - unsigned count; -}; - -class jane : public fred, public tsSLNode { -public: - jane() {} -private: -}; - -#define LOOPCOUNT 100000 - -int main () -{ - tsSLList list; - fred *pFred; - unsigned i; - clock_t clk; - clock_t diff; - double delay; - - for (i=0; i iter ( list.firstIter () ); - while ( iter.valid () ) { - iter->inc (); - iter++; - } - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - pFred = new fred(); - clk = clock(); - { - tsSLIter iter ( list.firstIter () ); - for ( i=0; iinc(); - } - } - diff = clock() - clk; - delay = diff; - delay = delay/CLOCKS_PER_SEC; - delay = delay/LOOPCOUNT; - printf("delay = %15.10f\n", delay); - - return 0; -} - diff --git a/src/libCom/cxxTemplates/test/tsSLListTest.cc b/src/libCom/cxxTemplates/test/tsSLListTest.cc deleted file mode 100644 index 32f96359d..000000000 --- a/src/libCom/cxxTemplates/test/tsSLListTest.cc +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - - -#include "tsSLList.h" -#include -#include - -class fred : public tsSLNode { -public: - fred(const char * const pNameIn) : pName(pNameIn){} - void show () {printf("%s\n", pName);} -private: - const char * const pName; -}; - -class jane : public fred, public tsSLNode { -public: - jane(const char * const pNameIn) : fred(pNameIn){} -private: -}; - -int main () -{ - tsSLList list; - fred *pFred; - fred *pFredII; - fred *pFredBack; - tsSLList janeList; - jane *pJane; - - pFred = new fred("A"); - pFredII = new fred("B"); - - list.add(*pFred); - list.add(*pFredII); - { - tsSLIter iter1 = list.firstIter (); - tsSLIter iter2 = iter1; - tsSLIter iter3 = iter1; - assert ( iter1 == iter3++ ); - assert ( iter3 == ++iter2 ); - list.remove ( *pFredII ); // removes pFred - } - list.add ( *pFred ); - pFredBack = list.get(); - assert (pFredBack == pFred); - pFredBack = list.get(); - assert (pFredBack == pFredII); - list.add(*pFredII); - list.add(*pFred); - while ( list.get () ); - pFredBack = list.get(); - assert (pFredBack == 0); - list.add(*pFred); - list.add(*pFredII); - list.add(* new fred("C")); - list.add(* new fred("D")); - - { - tsSLIter < fred > iter = list.firstIter(); - while ( iter.valid () ) { - iter->show(); - ++iter; - } - } - - pJane = new jane("JA"); - janeList.add(*pJane); - pJane = new jane("JB"); - janeList.add(*pJane); - - { - tsSLIter < jane > iter = janeList.firstIter (); - while ( iter.valid () ) { - iter->show(); - ++iter; - } - } - - { - tsSLIter < fred > iter = list.firstIter (); - while ( iter.valid () ) { - iter->show (); - iter++; - } - } - - while ( list.get () ); - - { - tsSLIter < fred > iter = list.firstIter (); - assert ( ! iter.valid () ); - } - - return 0; -} - diff --git a/src/libCom/cxxTemplates/tsDLList.h b/src/libCom/cxxTemplates/tsDLList.h deleted file mode 100644 index a315ecaab..000000000 --- a/src/libCom/cxxTemplates/tsDLList.h +++ /dev/null @@ -1,684 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * type safe doubly linked list templates - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef tsDLListH_include -#define tsDLListH_include - -template class tsDLList; -template class tsDLIterConst; -template class tsDLIter; - -// -// class tsDLNode -// -// a node in a doubly linked list containing entries of type T -// ( class T must publicly derive from class tsDLNode ) -// -template < class T > -class tsDLNode { -public: - tsDLNode (); - tsDLNode ( const tsDLNode & ); - const tsDLNode & operator = ( const tsDLNode & ); -private: - T * pNext; - T * pPrev; - friend class tsDLList; - friend class tsDLIter; - friend class tsDLIterConst; -}; - -// -// class tsDLList -// -// a doubly linked list containing entries of type T -// ( class T must publicly derive from class tsDLNode ) -// -template < class T > -class tsDLList { -public: - tsDLList (); // create empty list - unsigned count () const; // number of items on list - void add ( T & item ); // add item to end of list - void add ( tsDLList & addList ); // add to end of list - addList left empty - void push ( T & item ); // add item to beginning of list - void push ( tsDLList & pushList ); // add to beg of list - pushList left empty - void remove ( T & item ); // remove item from list - void removeAll ( tsDLList & destination ); - T * get (); // removes first item on list - T * pop (); // same as get () - void insertAfter ( T & item, T & itemBefore ); // insert item immediately after itemBefore - void insertBefore ( T & item, T & itemAfter ); // insert item immediately before itemAfter - int find ( const T & item ) const; // returns -1 if not present, node number if present - T * first ( void ) const; // ptr to first item on list - T * last ( void ) const; // ptr to last item on list - tsDLIterConst firstIter () const; - tsDLIter firstIter (); - tsDLIterConst lastIter () const; - tsDLIter lastIter (); - static tsDLIterConst invalidConstIter (); - static tsDLIter invalidIter (); -private: - T * pFirst; - T * pLast; - unsigned itemCount; - void clear (); - tsDLList ( const tsDLList & ); // not allowed - const tsDLList & operator = ( const tsDLList & ); // not allowed -}; - -// -// class tsDLIterConst -// -// bi-directional iterator for a const doubly linked list -// -template -class tsDLIterConst { -public: - tsDLIterConst (); - bool valid () const; - bool operator == ( const tsDLIterConst & rhs ) const; - bool operator != ( const tsDLIterConst & rhs ) const; - tsDLIterConst & operator = ( const tsDLIterConst & ); - const T & operator * () const; - const T * operator -> () const; - tsDLIterConst & operator ++ (); - tsDLIterConst operator ++ (int); - tsDLIterConst & operator -- (); - tsDLIterConst operator -- (int); - const T * pointer () const; -private: - const T * pEntry; - tsDLIterConst ( const T * pInitialEntry ); - friend class tsDLList ; -}; - -// -// class tsDLIter -// -// bi-directional iterator for a doubly linked list -// -template -class tsDLIter { -public: - tsDLIter (); - bool valid () const; - bool operator == ( const tsDLIter & rhs ) const; - bool operator != ( const tsDLIter & rhs ) const; - tsDLIter & operator = ( const tsDLIter & ); - T & operator * () const; - T * operator -> () const; - tsDLIter & operator ++ (); - tsDLIter operator ++ ( int ); - tsDLIter & operator -- (); - tsDLIter operator -- ( int ); - T * pointer () const; -private: - T * pEntry; - tsDLIter ( T *pInitialEntry ); - friend class tsDLList ; -}; - -/////////////////////////////////// -// tsDLNode member functions -/////////////////////////////////// - -// -// tsDLNode::tsDLNode () -// -template -inline tsDLNode::tsDLNode() : pNext(0), pPrev(0) {} - -template -inline tsDLNode::tsDLNode ( const tsDLNode & ) : - pNext (0), pPrev(0) {} - -// -// tsDLNode::operator = () -// -// when someone tries to copy another node into a node -// do _not_ change the node pointers -// -template -inline const tsDLNode & tsDLNode::operator = ( const tsDLNode & ) -{ - return * this; -} - -////////////////////////////////////// -// tsDLList member functions -////////////////////////////////////// - -// -// tsDLList::tsDLList () -// -template -inline tsDLList::tsDLList () -{ - this->clear (); -} - -// -// tsDLList::count () -// -// (returns the number of items on the list) -// -template -inline unsigned tsDLList::count () const -{ - return this->itemCount; -} - -// -// tsDLList::first () -// -template -inline T * tsDLList::first (void) const -{ - return this->pFirst; -} - -// -// tsDLList::last () -// -template -inline T *tsDLList::last (void) const -{ - return this->pLast; -} - -// -// tsDLList::clear () -// -template -inline void tsDLList::clear () -{ - this->pFirst = 0; - this->pLast = 0; - this->itemCount = 0u; -} - -// -// tsDLList::remove () -// -template -inline void tsDLList::remove ( T &item ) -{ - tsDLNode &theNode = item; - - if ( this->pLast == &item ) { - this->pLast = theNode.pPrev; - } - else { - tsDLNode &nextNode = *theNode.pNext; - nextNode.pPrev = theNode.pPrev; - } - - if ( this->pFirst == &item ) { - this->pFirst = theNode.pNext; - } - else { - tsDLNode &prevNode = *theNode.pPrev; - prevNode.pNext = theNode.pNext; - } - - this->itemCount--; -} - -// -// tsDLList::removeAll () -// -template -inline void tsDLList::removeAll ( - tsDLList & destination ) -{ - destination.pFirst = this->pFirst; - destination.pLast = this->pLast; - destination.itemCount = this->itemCount; - this->pFirst = 0; - this->pLast = 0; - this->itemCount = 0; -} - -// -// tsDLList::get () -// -template -inline T * tsDLList::get() -{ - T *pItem = this->pFirst; - - if ( pItem ) { - this->remove ( *pItem ); - } - - return pItem; -} - -// -// tsDLList::pop () -// -// (returns the first item on the list) -template -inline T * tsDLList::pop () -{ - return this->get (); -} - -// -// tsDLList::add () -// -// adds addList to the end of the list -// (and removes all items from addList) -// -template -inline void tsDLList::add ( tsDLList &addList ) -{ - if ( addList.itemCount != 0u ) { - if ( this->itemCount == 0u ) { - this->pFirst = addList.pFirst; - } - else { - tsDLNode *pLastNode = this->pLast; - tsDLNode *pAddListFirstNode = addList.pFirst; - pLastNode->pNext = addList.pFirst; - pAddListFirstNode->pPrev = addList.pLast; - } - this->pLast = addList.pLast; - this->itemCount += addList.itemCount; - addList.clear(); - } -} - -// -// tsDLList::add () -// -// add an item to the end of the list -// -template -inline void tsDLList::add (T &item) -{ - tsDLNode &theNode = item; - - theNode.pNext = 0; - theNode.pPrev = this->pLast; - - if ( this->itemCount ) { - tsDLNode &lastNode = *this->pLast; - lastNode.pNext = &item; - } - else { - this->pFirst = &item; - } - - this->pLast = &item; - - this->itemCount++; -} - -// -// tsDLList::insertAfter () -// -// place item in the list immediately after itemBefore -// -template -inline void tsDLList::insertAfter (T &item, T &itemBefore) -{ - tsDLNode &nodeItem = item; - tsDLNode &nodeBefore = itemBefore; - - nodeItem.pPrev = &itemBefore; - nodeItem.pNext = nodeBefore.pNext; - nodeBefore.pNext = &item; - - if (nodeItem.pNext) { - tsDLNode *pNextNode = nodeItem.pNext; - pNextNode->pPrev = &item; - } - else { - this->pLast = &item; - } - - this->itemCount++; -} - -// -// tsDLList::insertBefore () -// -// place item in the list immediately before itemAfter -// -template -inline void tsDLList::insertBefore (T &item, T &itemAfter) -{ - tsDLNode &node = item; - tsDLNode &nodeAfter = itemAfter; - - node.pNext = &itemAfter; - node.pPrev = nodeAfter.pPrev; - nodeAfter.pPrev = &item; - - if (node.pPrev) { - tsDLNode &prevNode = *node.pPrev; - prevNode.pNext = &item; - } - else { - this->pFirst = &item; - } - - this->itemCount++; -} - -// -// tsDLList::push () -// -// adds pushList to the beginning of the list -// (and removes all items from pushList) -// -template -inline void tsDLList::push ( tsDLList & pushList ) -{ - if ( pushList.itemCount != 0u ) { - if ( this->itemCount ) { - tsDLNode * pFirstNode = this->pFirst; - tsDLNode * pAddListLastNode = pushList.pLast; - pFirstNode->pPrev = pushList.pLast; - pAddListLastNode->pNext = this->pFirst; - } - else { - this->pLast = pushList.pLast; - } - this->pFirst = pushList.pFirst; - this->itemCount += pushList.itemCount; - pushList.clear(); - } -} - -// -// tsDLList::push () -// -// add an item at the beginning of the list -// -template -inline void tsDLList::push (T &item) -{ - tsDLNode &theNode = item; - theNode.pPrev = 0; - theNode.pNext = this->pFirst; - - if ( this->itemCount ) { - tsDLNode *pFirstNode = this->pFirst; - pFirstNode->pPrev = & item; - } - else { - this->pLast = & item; - } - - this->pFirst = &item; - - this->itemCount++; -} - -// -// tsDLList::find () -// returns -1 if the item isnt on the list -// and the node number (beginning with zero if -// it is) -// -template < class T > -int tsDLList < T > :: find ( const T &item ) const -{ - tsDLIterConst < T > thisItem ( &item ); - tsDLIterConst < T > iter ( this->first () ); - int itemNo = 0; - - while ( iter.valid () ) { - if ( iter == thisItem ) { - return itemNo; - } - itemNo++; - iter++; - } - return -1; -} - -template < class T > -inline tsDLIterConst tsDLList < T > :: firstIter () const -{ - return tsDLIterConst < T > ( this->pFirst ); -} - -template < class T > -inline tsDLIter tsDLList < T > :: firstIter () -{ - return tsDLIter < T > ( this->pFirst ); -} - -template < class T > -inline tsDLIterConst tsDLList < T > :: lastIter () const -{ - return tsDLIterConst < T > ( this->pLast ); -} - -template < class T > -inline tsDLIter tsDLList < T > :: lastIter () -{ - return tsDLIter < T > ( this->pLast ); -} - -template < class T > -inline tsDLIterConst tsDLList < T > :: invalidConstIter () -{ - return tsDLIterConst < T > ( 0 ); -} - -template < class T > -inline tsDLIter tsDLList < T > :: invalidIter () -{ - return tsDLIter < T > ( 0 ); -} - -////////////////////////////////////////// -// tsDLIterConst member functions -////////////////////////////////////////// -template -inline tsDLIterConst::tsDLIterConst ( const T *pInitialEntry ) : - pEntry ( pInitialEntry ) {} - -template -inline tsDLIterConst::tsDLIterConst () : - pEntry ( 0 ) {} - -template -inline bool tsDLIterConst::valid () const -{ - return this->pEntry != 0; -} - -template -inline bool tsDLIterConst::operator == (const tsDLIterConst &rhs) const -{ - return this->pEntry == rhs.pEntry; -} - -template -inline bool tsDLIterConst::operator != (const tsDLIterConst &rhs) const -{ - return this->pEntry != rhs.pEntry; -} - -template -inline tsDLIterConst & tsDLIterConst::operator = ( const tsDLIterConst & rhs ) -{ - this->pEntry = rhs.pEntry; - return *this; -} - -template -inline const T & tsDLIterConst::operator * () const -{ - return *this->pEntry; -} - -template -inline const T * tsDLIterConst::operator -> () const -{ - return this->pEntry; -} - -// -// prefix ++ -// -template -inline tsDLIterConst & tsDLIterConst::operator ++ () -{ - const tsDLNode &node = *this->pEntry; - this->pEntry = node.pNext; - return *this; -} - -// -// postfix ++ -// -template -inline tsDLIterConst tsDLIterConst::operator ++ (int) -{ - const tsDLIterConst tmp = *this; - const tsDLNode &node = *this->pEntry; - this->pEntry = node.pNext; - return tmp; -} - -// -// prefix -- -// -template -inline tsDLIterConst & tsDLIterConst::operator -- () -{ - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pPrev; - return *this; -} - -// -// postfix -- -// -template -inline tsDLIterConst tsDLIterConst::operator -- (int) -{ - const tsDLIterConst tmp = *this; - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pPrev; - return tmp; -} - -template -inline const T * tsDLIterConst::pointer () const -{ - return this->pEntry; -} - -////////////////////////////////////////// -// tsDLIter member functions -////////////////////////////////////////// - -template -inline tsDLIter::tsDLIter ( T * pInitialEntry ) : - pEntry ( pInitialEntry ) {} - -template -inline tsDLIter::tsDLIter () : - pEntry ( 0 ) {} - -template -inline bool tsDLIter::valid () const -{ - return this->pEntry != 0; -} - -template -inline bool tsDLIter::operator == (const tsDLIter &rhs) const -{ - return this->pEntry == rhs.pEntry; -} - -template -inline bool tsDLIter::operator != (const tsDLIter &rhs) const -{ - return this->pEntry != rhs.pEntry; -} - -template -inline tsDLIter & tsDLIter::operator = ( const tsDLIter & rhs ) -{ - this->pEntry = rhs.pEntry; - return *this; -} - -template -inline T & tsDLIter::operator * () const -{ - return *this->pEntry; -} - -template -inline T * tsDLIter::operator -> () const -{ - return this->pEntry; -} - -template -inline tsDLIter & tsDLIter::operator ++ () // prefix ++ -{ - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pNext; - return *this; -} - -template -inline tsDLIter tsDLIter::operator ++ (int) // postfix ++ -{ - const tsDLIter tmp = *this; - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pNext; - return tmp; -} - -template -inline tsDLIter & tsDLIter::operator -- () // prefix -- -{ - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pPrev; - return *this; -} - -template -inline tsDLIter tsDLIter::operator -- (int) // postfix -- -{ - const tsDLIter tmp = *this; - const tsDLNode &entryNode = *this->pEntry; - this->pEntry = entryNode.pPrev; - return tmp; -} - -template -inline T * tsDLIter::pointer () const -{ - return this->pEntry; -} - -#endif // tsDLListH_include - diff --git a/src/libCom/cxxTemplates/tsFreeList.h b/src/libCom/cxxTemplates/tsFreeList.h deleted file mode 100644 index 55787ac6b..000000000 --- a/src/libCom/cxxTemplates/tsFreeList.h +++ /dev/null @@ -1,191 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef tsFreeList_h -#define tsFreeList_h - -/* - * Author: Jeff Hill - */ - -// -// TODO: this should allow free list chaining so that a free -// list (in a different lock domain) is used to provide the -// tsFreeListChunk. -// - -// -// To allow your class to be allocated off of a free list -// using the new operator: -// -// 1) add the following static, private free list data members -// to your class -// -// static tsFreeList < class classXYZ > freeList; -// -// 2) add the following member functions to your class -// -// inline void * classXYZ::operator new ( size_t size ) -// { -// return freeList.allocate ( size ); -// } -// -// inline void classXYZ::operator delete ( void *pCadaver, size_t size ) -// { -// freeList.release ( pCadaver, size ); -// } -// -// NOTES: -// -// 1) A NOOP mutex class may be specified if mutual exclusion isnt required -// -// 2) If you wish to force use of the new operator, then declare your class's -// destructor as a protected member function. -// -// 3) Setting N to zero causes the free list to be bypassed -// - -#ifdef EPICS_FREELIST_DEBUG -# define tsFreeListDebugBypass 1 -# define tsFreeListMemSetNew(P,SIZE) memset ( (P), 0xaa, (SIZE) ) -# define tsFreeListMemSetDelete(P,SIZE) memset ( (P), 0xdd, (SIZE) ) -#else -# define tsFreeListDebugBypass 0 -# define tsFreeListMemSetNew(P,SIZE) -# define tsFreeListMemSetDelete(P,SIZE) -#endif - -#include -#include "string.h" - -#include "compilerDependencies.h" -#include "epicsMutex.h" -#include "epicsGuard.h" - -// ms visual studio 6.0 and before incorrectly -// warn about a missing delete operator if only the -// newly preferred delete operator with a size argument -// is present -#if defined ( _MSC_VER ) && _MSC_VER <= 1200 -# pragma warning ( disable : 4291 ) -#endif - -template < class T > union tsFreeListItem; -template < class T, unsigned N> struct tsFreeListChunk; - -template < class T, unsigned N = 0x400, - class MUTEX = epicsMutex > -class tsFreeList { -public: - tsFreeList (); - ~tsFreeList (); - void * allocate ( size_t size ); - void release ( void * p ); - void release ( void * p, size_t size ); -private: - MUTEX mutex; - tsFreeListItem < T > * pFreeList; - tsFreeListChunk < T, N > * pChunkList; - void * allocateFromNewChunk (); -}; - -template < class T > -union tsFreeListItem { -public: - char pad [ sizeof ( T ) ]; - tsFreeListItem < T > * pNext; -}; - -template < class T, unsigned N = 0x400 > -struct tsFreeListChunk { - tsFreeListItem < T > items [N]; - tsFreeListChunk < T, N > * pNext; -}; - -template < class T, unsigned N, class MUTEX > -inline tsFreeList < T, N, MUTEX > :: tsFreeList () : - pFreeList ( 0 ), pChunkList ( 0 ) {} - -template < class T, unsigned N, class MUTEX > -tsFreeList < T, N, MUTEX > :: ~tsFreeList () -{ - while ( tsFreeListChunk < T, N > *pChunk = this->pChunkList ) { - this->pChunkList = this->pChunkList->pNext; - delete pChunk; - } -} - -template < class T, unsigned N, class MUTEX > -void * tsFreeList < T, N, MUTEX >::allocate ( size_t size ) -{ - if ( size != sizeof ( T ) || N == 0u || tsFreeListDebugBypass ) { - void * p = ::operator new ( size ); - tsFreeListMemSetNew ( p, size ); - return p; - } - - epicsGuard < MUTEX > guard ( this->mutex ); - - tsFreeListItem < T > * p = this->pFreeList; - if ( p ) { - this->pFreeList = p->pNext; - return static_cast < void * > ( p ); - } - return this->allocateFromNewChunk (); -} - -template < class T, unsigned N, class MUTEX > -void * tsFreeList < T, N, MUTEX >::allocateFromNewChunk () -{ - tsFreeListChunk < T, N > * pChunk = - new tsFreeListChunk < T, N >; - - for ( unsigned i=1u; i < N-1; i++ ) { - pChunk->items[i].pNext = &pChunk->items[i+1]; - } - pChunk->items[N-1].pNext = 0; - if ( N > 1 ) { - this->pFreeList = &pChunk->items[1u]; - } - pChunk->pNext = this->pChunkList; - this->pChunkList = pChunk; - - return static_cast ( &pChunk->items[0] ); -} - -template < class T, unsigned N, class MUTEX > -void tsFreeList < T, N, MUTEX >::release ( void * pCadaver, size_t size ) -{ - if ( size != sizeof ( T ) ) { - tsFreeListMemSetDelete ( pCadaver, size ); - ::operator delete ( pCadaver ); - } - else { - this->release ( pCadaver ); - } -} - -template < class T, unsigned N, class MUTEX > -void tsFreeList < T, N, MUTEX >::release ( void * pCadaver ) -{ - if ( N == 0u || tsFreeListDebugBypass ) { - tsFreeListMemSetDelete ( pCadaver, sizeof ( T ) ); - ::operator delete ( pCadaver ); - } - else if ( pCadaver ) { - epicsGuard < MUTEX > guard ( this->mutex ); - tsFreeListItem < T > * p = - static_cast < tsFreeListItem < T > * > ( pCadaver ); - p->pNext = this->pFreeList; - this->pFreeList = p; - } -} - -#endif // tsFreeList_h diff --git a/src/libCom/cxxTemplates/tsMinMax.h b/src/libCom/cxxTemplates/tsMinMax.h deleted file mode 100644 index 5adac3ef2..000000000 --- a/src/libCom/cxxTemplates/tsMinMax.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// simple type safe inline template functions to replace -// the min() and max() macros -// - -#ifndef tsMinMaxh -#define tsMinMaxh - -template -inline const T & tsMax ( const T & a, const T & b ) -{ - return ( a > b ) ? a : b; -} - -template -inline const T & tsMin ( const T & a, const T & b ) -{ - return ( a < b ) ? a : b; -} - -#endif // tsMinMaxh diff --git a/src/libCom/cxxTemplates/tsSLList.h b/src/libCom/cxxTemplates/tsSLList.h deleted file mode 100644 index ce29a6f5c..000000000 --- a/src/libCom/cxxTemplates/tsSLList.h +++ /dev/null @@ -1,443 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * type safe singly linked list templates - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef tsSLListh -#define tsSLListh - -#ifndef assert // allow use of epicsAssert.h -#include -#endif - -// -// the hp compiler complains about parameterized friend -// class that has not been declared without this? -// -template < class T > class tsSLList; -template < class T > class tsSLIter; -template < class T > class tsSLIterConst; - -// -// tsSLNode -// NOTE: class T must derive from tsSLNode -// -template -class tsSLNode { -public: - tsSLNode (); - tsSLNode < T > & operator = ( const tsSLNode < T > & ); -private: - void removeNextItem (); // removes the item after this node - T *pNext; - tsSLNode ( const tsSLNode < T > & ); - friend class tsSLList < T >; - friend class tsSLIter < T >; - friend class tsSLIterConst < T >; -}; - - -// -// tsSLList -// NOTE: class T must derive from tsSLNode -// -template < class T > -class tsSLList : public tsSLNode < T > { -public: - tsSLList (); // creates an empty list - tsSLList ( tsSLList & ); - void insert ( T &item, tsSLNode < T > &itemBefore ); // insert after item before - void add ( T &item ); // add to the beginning of the list - T * get (); // remove from the beginning of the list - T * pop (); // same as get - void push ( T &item ); // same as add - T * first () const; - void remove ( T &itemBefore ); - tsSLIterConst firstIter () const; - tsSLIter firstIter (); - static tsSLIterConst invalidConstIter (); - static tsSLIter invalidIter (); -private: - const tsSLList < T > & operator = ( const tsSLList < T > & ); -}; - -// -// tsSLIterConst -// -template < class T > -class tsSLIterConst { -public: - tsSLIterConst (); - bool valid () const; - bool operator == (const tsSLIterConst &rhs) const; - bool operator != (const tsSLIterConst &rhs) const; - tsSLIterConst & operator = (const tsSLIterConst &); - const T & operator * () const; - const T * operator -> () const; - tsSLIterConst & operator ++ (); - tsSLIterConst operator ++ (int); - const T * pointer () const; -protected: - const T * pEntry; - tsSLIterConst ( const T *pInitialEntry ); - friend class tsSLList < T >; -}; - -// -// tsSLIter -// -template < class T > -class tsSLIter { -public: - tsSLIter (); - bool valid () const; - bool operator == (const tsSLIter &rhs) const; - bool operator != (const tsSLIter &rhs) const; - tsSLIter & operator = (const tsSLIter &); - T & operator * () const; - T * operator -> () const; - tsSLIter & operator ++ (); - tsSLIter operator ++ (int); - T * pointer () const; -private: - T *pEntry; - tsSLIter ( T *pInitialEntry ); - friend class tsSLList < T >; -}; - -////////////////////////////////////////// -// -// tsSLNode inline member functions -// -////////////////////////////////////////// - -// -// tsSLNode::tsSLNode () -// -template < class T > -inline tsSLNode < T > :: tsSLNode () : pNext ( 0 ) {} - -// -// tsSLNode::tsSLNode ( const tsSLNode < T > & ) -// private - not to be used - implemented to eliminate warnings -// -template < class T > -inline tsSLNode < T > :: tsSLNode ( const tsSLNode < T > & ) -{ -} - -// -// tsSLNode::operator = -// -// when someone copies into a class deriving from this -// do _not_ change the node pointers -// -template < class T > -inline tsSLNode < T > & tsSLNode < T >::operator = - ( const tsSLNode < T > & ) -{ - return *this; -} - -// -// removeNextItem () -// -// removes the item after this node -// -template -inline void tsSLNode::removeNextItem () -{ - T *pItem = this->pNext; - if ( pItem ) { - tsSLNode < T > *pNode = pItem; - this->pNext = pNode->pNext; - } -} - -////////////////////////////////////////// -// -// tsSLList inline member functions -// -////////////////////////////////////////// - -// -// tsSLList::tsSLList() -// create an empty list -// -template < class T > -inline tsSLList < T > :: tsSLList () -{ -} - -// -// tsSLList::tsSLList( tsSLList & ) -// -template < class T > -inline tsSLList < T > :: tsSLList ( tsSLList &listIn ) -{ - this->pNext = listIn.pNext; - listIn.pNext = 0; -} - -// -// tsSLList::insert() -// (itemBefore might be the list header object and therefore -// will not always be of type T) -// -template < class T > -inline void tsSLList < T > :: insert ( T &item, tsSLNode < T > &itemBefore ) -{ - tsSLNode < T > &node = item; - node.pNext = itemBefore.pNext; - itemBefore.pNext = &item; -} - -// -// tsSLList::add () -// -template < class T > -inline void tsSLList < T > :: add ( T &item ) -{ - this->insert ( item, *this ); -} - -// -// tsSLList::get () -// -template < class T > -inline T * tsSLList < T > :: get () -{ - tsSLNode < T > *pThisNode = this; - T *pItem = pThisNode->pNext; - pThisNode->removeNextItem (); - return pItem; -} - -// -// tsSLList::pop () -// -template < class T > -inline T * tsSLList < T > :: pop () -{ - return this->get (); -} - -// -// tsSLList::push () -// -template -inline void tsSLList < T > :: push ( T &item ) -{ - this->add (item); -} - -template -inline T * tsSLList < T > :: first () const -{ - const tsSLNode < T > *pThisNode = this; - return pThisNode->pNext; -} - -template -inline void tsSLList < T > :: remove ( T &itemBefore ) -{ - tsSLNode < T > *pBeforeNode = &itemBefore; - tsSLNode < T > *pAfterNode = pBeforeNode->pNext; - pBeforeNode->pNext = pAfterNode->pNext; -} - -template -inline tsSLIterConst tsSLList < T > :: firstIter () const -{ - const tsSLNode < T > *pThisNode = this; - return tsSLIterConst ( pThisNode->pNext ); -} - -template -inline tsSLIter tsSLList < T > :: firstIter () -{ - tsSLNode < T > *pThisNode = this; - return tsSLIter ( pThisNode->pNext ); -} - -template -inline tsSLIterConst tsSLList < T > :: invalidConstIter () -{ - return tsSLIterConst ( 0 ); -} - -template -inline tsSLIter tsSLList < T > :: invalidIter () -{ - return tsSLIter ( 0 ); -} - -////////////////////////////////////////// -// -// tsSLIterConst inline member functions -// -////////////////////////////////////////// - -template < class T > -inline tsSLIterConst::tsSLIterConst ( const T *pInitialEntry ) : - pEntry ( pInitialEntry ) -{ -} - -template < class T > -inline tsSLIterConst::tsSLIterConst () : - pEntry ( 0 ) -{ -} - -template < class T > -inline bool tsSLIterConst::valid () const -{ - return this->pEntry != 0; -} - -template < class T > -inline bool tsSLIterConst::operator == ( const tsSLIterConst &rhs ) const -{ - return this->pEntry == rhs.pConstEntry; -} - -template < class T > -inline bool tsSLIterConst::operator != (const tsSLIterConst &rhs) const -{ - return this->pEntry != rhs.pConstEntry; -} - -template < class T > -inline tsSLIterConst & tsSLIterConst::operator = ( const tsSLIterConst & rhs ) -{ - this->pEntry = rhs.pEntry; - return *this; -} - -template < class T > -inline const T & tsSLIterConst::operator * () const -{ - return *this->pEntry; -} - -template < class T > -inline const T * tsSLIterConst::operator -> () const -{ - return this->pEntry; -} - -template < class T > -inline tsSLIterConst & tsSLIterConst::operator ++ () // prefix ++ -{ - const tsSLNode < T > *pCurNode = this->pEntry; - this->pEntry = pCurNode->pNext; - return *this; -} - -template < class T > -inline tsSLIterConst tsSLIterConst::operator ++ ( int ) // postfix ++ -{ - const tsSLIterConst tmp = *this; - const tsSLNode < T > *pCurNode = this->pEntry; - this->pEntry = pCurNode->pNext; - return tmp; -} - -template -inline const T * tsSLIterConst < T > :: pointer () const -{ - return this->pEntry; -} - -////////////////////////////////////////// -// -// tsSLIter inline member functions -// -////////////////////////////////////////// - -template < class T > -inline tsSLIter::tsSLIter ( T *pInitialEntry ) : - pEntry ( pInitialEntry ) -{ -} - -template < class T > -inline tsSLIter::tsSLIter () : - pEntry ( 0 ) -{ -} - -template < class T > -inline bool tsSLIter::valid () const -{ - return this->pEntry != 0; -} - -template < class T > -inline bool tsSLIter::operator == ( const tsSLIter &rhs ) const -{ - return this->pEntry == rhs.pEntry; -} - -template < class T > -inline bool tsSLIter::operator != ( const tsSLIter &rhs ) const -{ - return this->pEntry != rhs.pEntry; -} - -template < class T > -inline tsSLIter & tsSLIter::operator = ( const tsSLIter & rhs ) -{ - this->pEntry = rhs.pEntry; - return *this; -} - -template < class T > -inline T & tsSLIter::operator * () const -{ - return *this->pEntry; -} - -template < class T > -inline T * tsSLIter::operator -> () const -{ - return this->pEntry; -} - -template < class T > -inline tsSLIter & tsSLIter::operator ++ () // prefix ++ -{ - const tsSLNode < T > *pCurNode = this->pEntry; - this->pEntry = pCurNode->pNext; - return *this; -} - -template < class T > -inline tsSLIter tsSLIter::operator ++ ( int ) // postfix ++ -{ - const tsSLIter tmp = *this; - const tsSLNode < T > *pCurNode = this->pEntry; - this->pEntry = pCurNode->pNext; - return tmp; -} - -template -inline T * tsSLIter < T > :: pointer () const -{ - return this->pEntry; -} - -#endif // tsSLListh diff --git a/src/libCom/dbmf/Makefile b/src/libCom/dbmf/Makefile deleted file mode 100644 index 2a190eac6..000000000 --- a/src/libCom/dbmf/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/dbmf -INC += dbmf.h -Com_SRCS += dbmf.c - diff --git a/src/libCom/dbmf/dbmf.c b/src/libCom/dbmf/dbmf.c deleted file mode 100644 index e04a7bedf..000000000 --- a/src/libCom/dbmf/dbmf.c +++ /dev/null @@ -1,299 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jim Kowalkowski and Marty Kraimer - * Date: 4/97 - * - * Intended for applications that create and free requently - * - */ - -#include -#include -#include -#include - -#include "valgrind/valgrind.h" - -#ifndef NVALGRIND -/* buffer around allocations to detect out of bounds access */ -#define REDZONE sizeof(double) -#else -#define REDZONE 0 -#endif - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsMutex.h" -#include "ellLib.h" -#include "dbmf.h" -/* -#define DBMF_FREELIST_DEBUG 1 -*/ -#ifndef DBMF_FREELIST_DEBUG - -/*Default values for dblfInit */ -#define DBMF_SIZE 64 -#define DBMF_INITIAL_ITEMS 10 - -typedef struct chunkNode {/*control block for each set of chunkItems*/ - ELLNODE node; - void *pchunk; - int nNotFree; -}chunkNode; - -typedef struct itemHeader{ - void *pnextFree; - chunkNode *pchunkNode; -}itemHeader; - -typedef struct dbmfPrivate { - ELLLIST chunkList; - epicsMutexId lock; - size_t size; - size_t allocSize; - int chunkItems; - size_t chunkSize; - int nAlloc; - int nFree; - int nGtSize; - void *freeList; -} dbmfPrivate; -dbmfPrivate dbmfPvt; -static dbmfPrivate *pdbmfPvt = NULL; -int dbmfDebug=0; - -int dbmfInit(size_t size, int chunkItems) -{ - if(pdbmfPvt) { - printf("dbmfInit: Already initialized\n"); - return(-1); - } - pdbmfPvt = &dbmfPvt; - ellInit(&pdbmfPvt->chunkList); - pdbmfPvt->lock = epicsMutexMustCreate(); - /*allign to at least a double*/ - pdbmfPvt->size = size + size%sizeof(double); - /* layout is - * | itemHeader | REDZONE | size | REDZONE | - */ - pdbmfPvt->allocSize = pdbmfPvt->size + sizeof(itemHeader) + 2*REDZONE; - pdbmfPvt->chunkItems = chunkItems; - pdbmfPvt->chunkSize = pdbmfPvt->allocSize * pdbmfPvt->chunkItems; - pdbmfPvt->nAlloc = 0; - pdbmfPvt->nFree = 0; - pdbmfPvt->nGtSize = 0; - pdbmfPvt->freeList = NULL; - VALGRIND_CREATE_MEMPOOL(pdbmfPvt, REDZONE, 0); - return(0); -} - - -void* dbmfMalloc(size_t size) -{ - void **pnextFree; - void **pfreeList; - char *pmem = NULL; - chunkNode *pchunkNode; - itemHeader *pitemHeader; - - if(!pdbmfPvt) dbmfInit(DBMF_SIZE,DBMF_INITIAL_ITEMS); - epicsMutexMustLock(pdbmfPvt->lock); - pfreeList = &pdbmfPvt->freeList; - if(*pfreeList == NULL) { - int i; - size_t nbytesTotal; - - if(dbmfDebug) printf("dbmfMalloc allocating new storage\n"); - nbytesTotal = pdbmfPvt->chunkSize + sizeof(chunkNode); - pmem = (char *)malloc(nbytesTotal); - if(!pmem) { - epicsMutexUnlock(pdbmfPvt->lock); - cantProceed("dbmfMalloc malloc failed\n"); - return(NULL); - } - pchunkNode = (chunkNode *)(pmem + pdbmfPvt->chunkSize); - pchunkNode->pchunk = pmem; - pchunkNode->nNotFree=0; - ellAdd(&pdbmfPvt->chunkList,&pchunkNode->node); - for(i=0; ichunkItems; i++) { - pitemHeader = (itemHeader *)pmem; - pitemHeader->pchunkNode = pchunkNode; - pnextFree = &pitemHeader->pnextFree; - *pnextFree = *pfreeList; *pfreeList = (void *)pmem; - pdbmfPvt->nFree++; - pmem += pdbmfPvt->allocSize; - } - } - if(size<=pdbmfPvt->size) { - pnextFree = *pfreeList; *pfreeList = *pnextFree; - pmem = (void *)pnextFree; - pdbmfPvt->nAlloc++; pdbmfPvt->nFree--; - pitemHeader = (itemHeader *)pnextFree; - pitemHeader->pchunkNode->nNotFree += 1; - } else { - pmem = malloc(sizeof(itemHeader) + 2*REDZONE + size); - if(!pmem) { - epicsMutexUnlock(pdbmfPvt->lock); - cantProceed("dbmfMalloc malloc failed\n"); - return(NULL); - } - pdbmfPvt->nAlloc++; - pdbmfPvt->nGtSize++; - pitemHeader = (itemHeader *)pmem; - pitemHeader->pchunkNode = NULL; /* not part of free list */ - if(dbmfDebug) printf("dbmfMalloc: size %lu mem %p\n", - (unsigned long)size,pmem); - } - epicsMutexUnlock(pdbmfPvt->lock); - pmem += sizeof(itemHeader) + REDZONE; - VALGRIND_MEMPOOL_ALLOC(pdbmfPvt, pmem, size); - return((void *)pmem); -} - -char * dbmfStrdup(const char *str) -{ - size_t len = strlen(str); - char *buf = dbmfMalloc(len + 1); /* FIXME Can return NULL */ - - return strcpy(buf, str); -} - -char * dbmfStrndup(const char *str, size_t len) -{ - char *buf = dbmfMalloc(len + 1); /* FIXME Can return NULL */ - - buf[len] = '\0'; - return strncpy(buf, str, len); -} - -void dbmfFree(void* mem) -{ - char *pmem = (char *)mem; - chunkNode *pchunkNode; - itemHeader *pitemHeader; - - if(!mem) return; - if(!pdbmfPvt) { - printf("dbmfFree called but dbmfInit never called\n"); - return; - } - VALGRIND_MEMPOOL_FREE(pdbmfPvt, mem); - pmem -= sizeof(itemHeader) + REDZONE; - epicsMutexMustLock(pdbmfPvt->lock); - pitemHeader = (itemHeader *)pmem; - if(!pitemHeader->pchunkNode) { - if(dbmfDebug) printf("dbmfGree: mem %p\n",pmem); - free((void *)pmem); pdbmfPvt->nAlloc--; - }else { - void **pfreeList = &pdbmfPvt->freeList; - void **pnextFree = &pitemHeader->pnextFree; - - pchunkNode = pitemHeader->pchunkNode; - pchunkNode->nNotFree--; - *pnextFree = *pfreeList; *pfreeList = pnextFree; - pdbmfPvt->nAlloc--; pdbmfPvt->nFree++; - } - epicsMutexUnlock(pdbmfPvt->lock); -} - -int dbmfShow(int level) -{ - if(pdbmfPvt==NULL) { - printf("Never initialized\n"); - return(0); - } - printf("size %lu allocSize %lu chunkItems %d ", - (unsigned long)pdbmfPvt->size, - (unsigned long)pdbmfPvt->allocSize,pdbmfPvt->chunkItems); - printf("nAlloc %d nFree %d nChunks %d nGtSize %d\n", - pdbmfPvt->nAlloc,pdbmfPvt->nFree, - ellCount(&pdbmfPvt->chunkList),pdbmfPvt->nGtSize); - if(level>0) { - chunkNode *pchunkNode; - - pchunkNode = (chunkNode *)ellFirst(&pdbmfPvt->chunkList); - while(pchunkNode) { - printf("pchunkNode %p nNotFree %d\n", - (void*)pchunkNode,pchunkNode->nNotFree); - pchunkNode = (chunkNode *)ellNext(&pchunkNode->node); - } - } - if(level>1) { - void **pnextFree;; - - epicsMutexMustLock(pdbmfPvt->lock); - pnextFree = (void**)pdbmfPvt->freeList; - while(pnextFree) { - printf("%p\n",*pnextFree); - pnextFree = (void**)*pnextFree; - } - epicsMutexUnlock(pdbmfPvt->lock); - } - return(0); -} - -void dbmfFreeChunks(void) -{ - chunkNode *pchunkNode; - chunkNode *pnext;; - - if(!pdbmfPvt) { - printf("dbmfFreeChunks called but dbmfInit never called\n"); - return; - } - epicsMutexMustLock(pdbmfPvt->lock); - if(pdbmfPvt->nFree - != (pdbmfPvt->chunkItems * ellCount(&pdbmfPvt->chunkList))) { - printf("dbmfFinish: not all free\n"); - epicsMutexUnlock(pdbmfPvt->lock); - return; - } - pchunkNode = (chunkNode *)ellFirst(&pdbmfPvt->chunkList); - while(pchunkNode) { - pnext = (chunkNode *)ellNext(&pchunkNode->node); - ellDelete(&pdbmfPvt->chunkList,&pchunkNode->node); - free(pchunkNode->pchunk); - pchunkNode = pnext; - } - pdbmfPvt->nFree = 0; pdbmfPvt->freeList = NULL; - epicsMutexUnlock(pdbmfPvt->lock); -} - -#else /* DBMF_FREELIST_DEBUG */ - -int dbmfInit(size_t size, int chunkItems) -{ return 0; } - -void* dbmfMalloc(size_t size) -{ return malloc(size); } - -char * dbmfStrdup(const char *str) -{ return strdup((char*)str); } - -void dbmfFree(void* mem) -{ free(mem); } - -int dbmfShow(int level) -{ return 0; } - -void dbmfFreeChunks(void) {} - -#endif /* DBMF_FREELIST_DEBUG */ - -char * dbmfStrcat3(const char *lhs, const char *mid, const char *rhs) -{ - size_t len = strlen(lhs) + strlen(mid) + strlen(rhs) + 1; - char *buf = dbmfMalloc(len); - strcpy(buf, lhs); - strcat(buf, mid); - strcat(buf, rhs); - return buf; -} - diff --git a/src/libCom/dbmf/dbmf.h b/src/libCom/dbmf/dbmf.h deleted file mode 100644 index 2c8a28f2c..000000000 --- a/src/libCom/dbmf/dbmf.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jim Kowalkowski and Marty Kraimer - * Date: 4/97 - * - * A library to manage storage that is allocated and then freed. - */ -#ifndef DBMF_H -#define DBMF_H - -#include -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int dbmfInit(size_t size, int chunkItems); -epicsShareFunc void * dbmfMalloc(size_t bytes); -epicsShareFunc char * dbmfStrdup(const char *str); -epicsShareFunc char * dbmfStrndup(const char *str, size_t len); -epicsShareFunc char * dbmfStrcat3(const char *lhs, const char *mid, - const char *rhs); -epicsShareFunc void dbmfFree(void *bytes); -epicsShareFunc void dbmfFreeChunks(void); -epicsShareFunc int dbmfShow(int level); - -/* Rules: - * 1) Size is always made a multiple of 8. - * 2) if dbmfInit is not called before one of the other routines then it - * is automatically called with size=64 and chunkItems=10 - * 3) These routines should only be used to allocate storage that will - * shortly thereafter be freed. - * 4) dbmfFreeChunks can only free chunks that contain only free items -*/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/ellLib/Makefile b/src/libCom/ellLib/Makefile deleted file mode 100644 index 9a5cb3e67..000000000 --- a/src/libCom/ellLib/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/ellLib -INC += ellLib.h -Com_SRCS += ellLib.c -Com_SRCS += ellSort.c diff --git a/src/libCom/ellLib/ellLib.c b/src/libCom/ellLib/ellLib.c deleted file mode 100644 index c539a843f..000000000 --- a/src/libCom/ellLib/ellLib.c +++ /dev/null @@ -1,331 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: John Winans (ANL) - * Date: 07-02-92 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "ellLib.h" - - /**************************************************************************** - * - * This function adds a node to the end of a linked list. - * - *****************************************************************************/ -void ellAdd (ELLLIST *pList, ELLNODE *pNode) -{ - pNode->next = NULL; - pNode->previous = pList->node.previous; - - if (pList->count) - pList->node.previous->next = pNode; - else - pList->node.next = pNode; - - pList->node.previous = pNode; - pList->count++; - - return; -} - /**************************************************************************** - * - * This function concatinates the second linked list to the end of the first - * list. The second list is left empty. Either list (or both) lists may - * be empty at the begining of the operation. - * - *****************************************************************************/ -void ellConcat (ELLLIST *pDstList, ELLLIST *pAddList) -{ - if (pAddList->count == 0) - return; /* Add list is empty, nothing to add. */ - - if (pDstList->count == 0) { - /* Destination list is empty... just transfer the add list over. */ - pDstList->node.next = pAddList->node.next; - pDstList->node.previous = pAddList->node.previous; - pDstList->count = pAddList->count; - } else { - /* Destination list not empty... append the add list. */ - pDstList->node.previous->next = pAddList->node.next; - pAddList->node.next->previous = pDstList->node.previous; - pDstList->node.previous = pAddList->node.previous; - pDstList->count += pAddList->count; - } - - pAddList->count = 0; - pAddList->node.next = NULL; - pAddList->node.previous = NULL; - - return; -} - /**************************************************************************** - * - * This function deletes a specific node from a specified list; - * - *****************************************************************************/ -void ellDelete (ELLLIST *pList, ELLNODE *pNode) -{ - if (pList->node.previous == pNode) - pList->node.previous = pNode->previous; - else - pNode->next->previous = pNode->previous; - - if (pList->node.next == pNode) - pList->node.next = pNode->next; - else - pNode->previous->next = pNode->next; - - pList->count--; - - return; -} - /**************************************************************************** - * - * This function extracts a sublist that starts with pStartNode and ends with - * pEndNode from pSrcList and places it in pDstList. - * - * WRS is unclear as to what happens when pDstList is non-empty at the start - * of the operation. We will place the extracted list at the END of pDstList - * when it is non-empty. - * - *****************************************************************************/ -void ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList) -{ - ELLNODE *pnode; - int count; - - /* Cut the list out of the source list (update count later) */ - if (pStartNode->previous != NULL) - pStartNode->previous->next = pEndNode->next; - else - pSrcList->node.next = pEndNode->next; - - if (pEndNode->next != NULL) { - pEndNode->next->previous = pStartNode->previous; - pEndNode->next = NULL; - } - else - pSrcList->node.previous = pStartNode->previous; - - /* Place the sublist into the destination list */ - pStartNode->previous = pDstList->node.previous; - if (pDstList->count) - pDstList->node.previous->next = pStartNode; - else - pDstList->node.next = pStartNode; - - pDstList->node.previous = pEndNode; - - /* Adjust the counts */ - pnode = pStartNode; - count = 1; - while(pnode != pEndNode) - { - pnode = pnode->next; - count++; - } - pSrcList->count -= count; - pDstList->count += count; - - return; -} - /**************************************************************************** - * - * This function returns the first node in the specified list. The node is - * removed from the list. If the list is empty, NULL will be returned. - * - *****************************************************************************/ -ELLNODE * ellGet (ELLLIST *pList) -{ - ELLNODE *pnode = pList->node.next; - - if (pnode != NULL) - ellDelete(pList, pnode); - - return pnode; -} -/**************************************************************************** -* -* This function returns the last node in the specified list. The node is -* removed from the list. If the list is empty, NULL will be returned. -* -*****************************************************************************/ -ELLNODE * ellPop (ELLLIST *pList) -{ - ELLNODE *pnode = pList->node.previous; - - if (pnode != NULL) - ellDelete(pList, pnode); - - return pnode; -} - /**************************************************************************** - * - * This function inserts the specified node pNode after pPrev in the list - * plist. If pPrev is NULL, then pNode will be inserted at the head of the - * list. - * - *****************************************************************************/ -void ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode) -{ - if (pPrev != NULL) { - pNode->previous = pPrev; - pNode->next = pPrev->next; - pPrev->next = pNode; - } else { - pNode->previous = NULL; - pNode->next = plist->node.next; - plist->node.next = pNode; - } - - if (pNode->next == NULL) - plist->node.previous = pNode; - else - pNode->next->previous = pNode; - - plist->count++; - - return; -} - /**************************************************************************** - * - * This function returns the nodeNum'th element in pList. If there is no - * nodeNum'th node in the list, NULL will be returned. - * - *****************************************************************************/ -ELLNODE * ellNth (ELLLIST *pList, int nodeNum) -{ - ELLNODE *pnode; - - if ((nodeNum < 1) || (pList->count == 0)) - return NULL; - - if (nodeNum > pList->count/2) { - if (nodeNum > pList->count) - return NULL; - - pnode = pList->node.previous; - nodeNum = pList->count - nodeNum; - while(nodeNum) { - pnode = pnode->previous; - nodeNum--; - } - return pnode; - } - - pnode = pList->node.next; - while (--nodeNum > 0) - pnode = pnode->next; - - return pnode; -} - /**************************************************************************** - * - * This function returns the node, nStep nodes forward from pNode. If there is - * no node that many steps from pNode, NULL will be returned. - * - *****************************************************************************/ -ELLNODE * ellNStep (ELLNODE *pNode, int nStep) -{ - if (nStep > 0) { - while ((pNode != NULL) && nStep) { - pNode = pNode->next; - nStep--; - } - } else { - while ((pNode != NULL) && nStep) { - pNode = pNode->previous; - nStep++; - } - } - return pNode; -} - /**************************************************************************** - * - * This function returns the node number of pNode within pList. If the node is - * not in pList, -1 is returned. Note that the first node is 1. - * - *****************************************************************************/ -int ellFind (ELLLIST *pList, ELLNODE *pNode) -{ - ELLNODE *got = pList->node.next; - int count = 1; - - while ((got != pNode) && (got != NULL)) { - got = got->next; - count++; - } - if (got == NULL) - return -1; - - return count; -} - /**************************************************************************** - * - * This function frees the nodes in a list. It makes the list into an empty - * list, and calls freeFunc() for all the nodes that are (were) in that list. - * - * NOTE: the nodes in the list are free()'d on the assumption that the node - * structures were malloc()'d one-at-a-time and that the ELLNODE structure is - * the first member of the parent structure. - * - *****************************************************************************/ -void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc) -{ - ELLNODE *nnode = pList->node.next; - ELLNODE *pnode; - - while (nnode != NULL) - { - pnode = nnode; - nnode = nnode->next; - freeFunc(pnode); - } - pList->node.next = NULL; - pList->node.previous = NULL; - pList->count = 0; -} - - /**************************************************************************** - * - * This function verifies that the list is consistent. - * joh 12-12-97 - * - *****************************************************************************/ -void ellVerify (ELLLIST *pList) -{ - ELLNODE *pNode; - ELLNODE *pNext; - int count = 0; - - assert (pList); - - pNode = ellFirst(pList); - if (pNode) { - assert (ellPrevious(pNode) == NULL); - while (1) { - count++; - pNext = ellNext(pNode); - if (pNext) { - assert (ellPrevious(pNext) == pNode); - } else { - break; - } - pNode = pNext; - } - assert (ellNext(pNode) == NULL); - } - - assert (pNode == ellLast(pList)); - assert (count == ellCount(pList)); -} diff --git a/src/libCom/ellLib/ellLib.h b/src/libCom/ellLib/ellLib.h deleted file mode 100644 index 52b58d169..000000000 --- a/src/libCom/ellLib/ellLib.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: John Winans (ANL) - * Andrew Johnson - */ -#ifndef INC_ellLib_H -#define INC_ellLib_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ELLNODE { - struct ELLNODE *next; - struct ELLNODE *previous; -} ELLNODE; - -#define ELLNODE_INIT {NULL, NULL} - -typedef struct ELLLIST { - ELLNODE node; - int count; -} ELLLIST; - -#define ELLLIST_INIT {ELLNODE_INIT, 0} - -typedef void (*FREEFUNC)(void *); - -#define ellInit(PLIST) {\ - (PLIST)->node.next = (PLIST)->node.previous = NULL;\ - (PLIST)->count = 0;\ -} -#define ellCount(PLIST) ((PLIST)->count) -#define ellFirst(PLIST) ((PLIST)->node.next) -#define ellLast(PLIST) ((PLIST)->node.previous) -#define ellNext(PNODE) ((PNODE)->next) -#define ellPrevious(PNODE) ((PNODE)->previous) -#define ellFree(PLIST) ellFree2(PLIST, free) - -epicsShareFunc void ellAdd (ELLLIST *pList, ELLNODE *pNode); -epicsShareFunc void ellConcat (ELLLIST *pDstList, ELLLIST *pAddList); -epicsShareFunc void ellDelete (ELLLIST *pList, ELLNODE *pNode); -epicsShareFunc void ellExtract (ELLLIST *pSrcList, ELLNODE *pStartNode, ELLNODE *pEndNode, ELLLIST *pDstList); -epicsShareFunc ELLNODE * ellGet (ELLLIST *pList); -epicsShareFunc ELLNODE * ellPop (ELLLIST *pList); -epicsShareFunc void ellInsert (ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode); -epicsShareFunc ELLNODE * ellNth (ELLLIST *pList, int nodeNum); -epicsShareFunc ELLNODE * ellNStep (ELLNODE *pNode, int nStep); -epicsShareFunc int ellFind (ELLLIST *pList, ELLNODE *pNode); -typedef int (*pListCmp)(const ELLNODE* A, const ELLNODE* B); -epicsShareFunc void ellSortStable(ELLLIST *pList, pListCmp); -epicsShareFunc void ellFree2 (ELLLIST *pList, FREEFUNC freeFunc); -epicsShareFunc void ellVerify (ELLLIST *pList); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_ellLib_H */ diff --git a/src/libCom/ellLib/ellSort.c b/src/libCom/ellLib/ellSort.c deleted file mode 100644 index 2f8f2748b..000000000 --- a/src/libCom/ellLib/ellSort.c +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc., as Operator of Argonne -* National Laboratory. -* Copyright (c) 2016 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Use of mergesort algorithm based on analysis by - * http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html - */ -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "ellLib.h" - -static void ellMoveN(ELLLIST* pTo, ELLLIST* pFrom, int count ) -{ - for(;count && ellCount(pFrom); count--) { - ELLNODE *node = ellGet(pFrom); - ellAdd(pTo, node); - } -} - -/* Stable (MergeSort) to given list. - * The comparison function cmp(A,B) is expected - * to return -1 for AB. - */ -void ellSortStable(ELLLIST *pList, pListCmp cmp) -{ - ELLLIST INP, P, Q; - size_t insize = 1; /* initial sub-list size */ - if(ellCount(pList)<=1) - return; - - ellInit(&INP); - ellInit(&P); - ellInit(&Q); - - /* Process is to iteratively sort - * a sequence of sub-lists of size 'insize' - */ - - while(insize < ellCount(pList)) { - - assert(ellCount(&INP)==0); - - /* shift previous results to inputs */ - ellConcat(&INP, pList); - - while(ellCount(&INP)) - { - ELLNODE *p, *q; - - /* Pull out the next pair of sub-lists */ - ellMoveN(&Q, &INP, insize); - ellMoveN(&P, &INP, insize); - - /* merge these sub-lists */ - while((p=ellFirst(&P)) && (q=ellFirst(&Q))) - { - if((*cmp)(p,q) < 0) { - ellAdd(pList, ellGet(&P)); - } else { - ellAdd(pList, ellGet(&Q)); - } - } - - /* concatenate any remaining to result */ - if(ellFirst(&P)) - ellConcat(pList, &P); - else if(ellFirst(&Q)) - ellConcat(pList, &Q); - - assert(!ellFirst(&P) && !ellFirst(&Q)); - } - - insize *= 2; - } - -} diff --git a/src/libCom/env/Makefile b/src/libCom/env/Makefile deleted file mode 100644 index 69c9d253b..000000000 --- a/src/libCom/env/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/env - -INC += envDefs.h - -Com_SRCS += envSubr.c -Com_SRCS += envData.c - -CLEANS += envData.c diff --git a/src/libCom/env/RULES b/src/libCom/env/RULES deleted file mode 100644 index 2737d5d4a..000000000 --- a/src/libCom/env/RULES +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -envData.c: $(LIBCOM)/env/envDefs.h $(LIBCOM)/env/bldEnvData.pl \ - $(CONFIG)/CONFIG_ENV $(CONFIG)/CONFIG_SITE_ENV \ - $(wildcard $(CONFIG)/os/CONFIG_SITE_ENV.$(T_A)) - $(PERL) $(LIBCOM)/env/bldEnvData.pl $(QUIET_FLAG) -t $(T_A) \ - -c $(CMPLR_CLASS) -s $(OS_CLASS) $(CONFIG) diff --git a/src/libCom/env/bldEnvData.pl b/src/libCom/env/bldEnvData.pl deleted file mode 100644 index 9df15a535..000000000 --- a/src/libCom/env/bldEnvData.pl +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/perl -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# Author: Kay-Uwe Kasemir -# Date: 1-30-97 - -use strict; - -# This program is never installed, so it can't use FindBin to get -# the path to the lib/perl directory. However it can load the -# EPICS:: modules directly from the src/tools directory instead: -use lib '../../tools'; - -use Getopt::Std; -use File::Basename; -use EPICS::Path; -use EPICS::Release; -use Text::Wrap; - -my $tool = basename($0); - -our ($opt_h, $opt_q, $opt_t, $opt_s, $opt_c); -our $opt_o = 'envData.c'; - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; -$Text::Wrap::columns = 75; - -HELP_MESSAGE() unless getopts('ho:qt:s:c:') && @ARGV == 1; -HELP_MESSAGE() if $opt_h; - -my $config = AbsPath(shift); -my $env_defs = AbsPath('../env/envDefs.h'); - -# Parse the ENV_PARAM declarations in envDefs.h -# to get the param names we are interested in -# -open SRC, '<', $env_defs - or die "$tool: Cannot open $env_defs: $!\n"; - -my @vars; -while () { - if (m/epicsShareExtern\s+const\s+ENV_PARAM\s+([A-Za-z_]\w*)\s*;/) { - push @vars, $1; - } -} -close SRC; - -# A list of configure/CONFIG_* files to read -# -my @configs = ("$config/CONFIG_ENV", "$config/CONFIG_SITE_ENV"); - -if ($opt_t) { - my $config_arch_env = "$config/os/CONFIG_SITE_ENV.$opt_t"; - push @configs, $config_arch_env - if -f $config_arch_env; -} - -my @sources = ($env_defs, @configs); - -# Get values from the config files -# -my (%values, @dummy); -readRelease($_, \%values, \@dummy) foreach @configs; -expandRelease(\%values); - -# Get values from the command-line -# -$values{EPICS_BUILD_COMPILER_CLASS} = $opt_c if $opt_c; -$values{EPICS_BUILD_OS_CLASS} = $opt_s if $opt_s; -$values{EPICS_BUILD_TARGET_ARCH} = $opt_t if $opt_t; - -# Warn about vars with no configured value -# -my @undefs = grep {!exists $values{$_}} @vars; -warn "$tool: No value given for $_\n" foreach @undefs; - -print "Generating $opt_o\n" unless $opt_q; - -# Start creating the output -# -open OUT, '>', $opt_o - or die "$tool: Cannot create $opt_o: $!\n"; - -my $sources = join "\n", map {" * $_"} @sources; - -print OUT << "END"; -/* Generated file $opt_o - * - * Created from -$sources - */ - -#include -#define epicsExportSharedSymbols -#include "envDefs.h" - -END - -# Define a default value for each named parameter -# -foreach my $var (@vars) { - my $default = $values{$var}; - if (defined $default) { - $default =~ s/^"//; - $default =~ s/"$//; - } - else { - $default = ''; - } - - print OUT "epicsShareDef const ENV_PARAM $var =\n", - " {\"$var\", \"$default\"};\n"; -} - -# Also provide a list of all defined parameters -# -print OUT "\n", - "epicsShareDef const ENV_PARAM* env_param_list[] = {\n", - wrap(' ', ' ', join(', ', map("&$_", @vars), 'NULL')), - "\n};\n"; -close OUT; - -sub HELP_MESSAGE { - print STDERR "Usage: $tool [options] configure\n", - " -h Help: Print this message\n", - " -q Quiet: Only print errors\n", - " -o file Output filename, default is $opt_o\n", - " -t arch Target architecture \$(T_A) name\n", - " -s os Operating system \$(OS_CLASS)\n", - " -c comp Compiler class \$(CMPLR_CLASS)\n", - "\n"; - - exit 1; -} diff --git a/src/libCom/env/envDefs.h b/src/libCom/env/envDefs.h deleted file mode 100644 index 650f8ee58..000000000 --- a/src/libCom/env/envDefs.h +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Roger A. Cole - * Date: 07-20-91 - * - */ -/**************************************************************************** -* TITLE envDefs.h - definitions for environment get/set routines -* -* DESCRIPTION -* This file defines the environment parameters for EPICS. These -* ENV_PARAM's are created in envData.c by bldEnvData for -* use by EPICS programs running under UNIX and VxWorks. -* -* User programs can define their own environment parameters for their -* own use--the only caveat is that such parameters aren't automatically -* setup by EPICS. -* -*****************************************************************************/ - -#ifndef envDefsH -#define envDefsH - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -typedef struct envParam { - char *name; /* text name of the parameter */ - char *pdflt; -} ENV_PARAM; - -/* - * bldEnvData.pl looks for "epicsShareExtern const ENV_PARAM ;" - */ -epicsShareExtern const ENV_PARAM EPICS_CA_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CA_CONN_TMO; -epicsShareExtern const ENV_PARAM EPICS_CA_AUTO_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CA_REPEATER_PORT; -epicsShareExtern const ENV_PARAM EPICS_CA_SERVER_PORT; -epicsShareExtern const ENV_PARAM EPICS_CA_MAX_ARRAY_BYTES; -epicsShareExtern const ENV_PARAM EPICS_CA_AUTO_ARRAY_BYTES; -epicsShareExtern const ENV_PARAM EPICS_CA_MAX_SEARCH_PERIOD; -epicsShareExtern const ENV_PARAM EPICS_CA_NAME_SERVERS; -epicsShareExtern const ENV_PARAM EPICS_CA_MCAST_TTL; -epicsShareExtern const ENV_PARAM EPICS_CAS_INTF_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CAS_IGNORE_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CAS_AUTO_BEACON_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_ADDR_LIST; -epicsShareExtern const ENV_PARAM EPICS_CAS_SERVER_PORT; -epicsShareExtern const ENV_PARAM EPICS_CA_BEACON_PERIOD; /* deprecated */ -epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_PERIOD; -epicsShareExtern const ENV_PARAM EPICS_CAS_BEACON_PORT; -epicsShareExtern const ENV_PARAM EPICS_BUILD_COMPILER_CLASS; -epicsShareExtern const ENV_PARAM EPICS_BUILD_OS_CLASS; -epicsShareExtern const ENV_PARAM EPICS_BUILD_TARGET_ARCH; -epicsShareExtern const ENV_PARAM EPICS_TIMEZONE; -epicsShareExtern const ENV_PARAM EPICS_TS_NTP_INET; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_PORT; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_INET; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_FILE_LIMIT; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_FILE_NAME; -epicsShareExtern const ENV_PARAM EPICS_IOC_LOG_FILE_COMMAND; -epicsShareExtern const ENV_PARAM EPICS_CMD_PROTO_PORT; -epicsShareExtern const ENV_PARAM EPICS_AR_PORT; -epicsShareExtern const ENV_PARAM IOCSH_PS1; -epicsShareExtern const ENV_PARAM IOCSH_HISTSIZE; -epicsShareExtern const ENV_PARAM IOCSH_HISTEDIT_DISABLE; - -epicsShareExtern const ENV_PARAM *env_param_list[]; - -struct in_addr; - -epicsShareFunc char * epicsShareAPI - envGetConfigParam(const ENV_PARAM *pParam, int bufDim, char *pBuf); -epicsShareFunc const char * epicsShareAPI - envGetConfigParamPtr(const ENV_PARAM *pParam); -epicsShareFunc long epicsShareAPI - envPrtConfigParam(const ENV_PARAM *pParam); -epicsShareFunc long epicsShareAPI - envGetInetAddrConfigParam(const ENV_PARAM *pParam, struct in_addr *pAddr); -epicsShareFunc long epicsShareAPI - envGetDoubleConfigParam(const ENV_PARAM *pParam, double *pDouble); -epicsShareFunc long epicsShareAPI - envGetLongConfigParam(const ENV_PARAM *pParam, long *pLong); -epicsShareFunc unsigned short epicsShareAPI envGetInetPortConfigParam - (const ENV_PARAM *pEnv, unsigned short defaultPort); -epicsShareFunc long epicsShareAPI - envGetBoolConfigParam(const ENV_PARAM *pParam, int *pBool); -epicsShareFunc long epicsShareAPI epicsPrtEnvParams(void); -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value); -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /*envDefsH*/ - diff --git a/src/libCom/env/envSubr.c b/src/libCom/env/envSubr.c deleted file mode 100644 index 283b13290..000000000 --- a/src/libCom/env/envSubr.c +++ /dev/null @@ -1,426 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Roger A. Cole - * Date: 07-20-91 - */ -/*+/mod*********************************************************************** -* TITLE envSubr.c - routines to get and set EPICS environment parameters -* -* DESCRIPTION -* These routines are oriented for use with EPICS environment -* parameters under UNIX and VxWorks. They may be used for other -* purposes, as well. -* -* Many EPICS environment parameters are predefined in envDefs.h. -* -* QUICK REFERENCE -* #include "envDefs.h" -* ENV_PARAM param; -* char *envGetConfigParamPtr( pParam ) -* char *envGetConfigParam( pParam, bufDim, pBuf ) -* long envGetLongConfigParam( pParam, pLong ) -* long envGetDoubleConfigParam( pParam, pDouble ) -* long envGetInetAddrConfigParam( pParam, pAddr ) -* long envPrtConfigParam( pParam ) -* -* SEE ALSO -* $epics/share/bin/envSetupParams, envDefs.h -* -*-***************************************************************************/ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdlib.h" -#include "epicsStdio.h" -#include "epicsString.h" -#include "errMdef.h" -#include "errlog.h" -#include "envDefs.h" -#include "epicsAssert.h" -#include "osiSock.h" - - -/*+/subr********************************************************************** -* NAME envGetConfigParamPtr - returns a pointer to the configuration -* parameter value string -* -* DESCRIPTION -* Returns a pointer to a configuration parameter value. -* If the configuration parameter isn't found in the environment, -* then a pointer to the default value for the parameter is copied. -* If no parameter is found and there is no default, then -* NULL is returned. -* -* RETURNS -* pointer to the environment variable value string, or -* NULL if no parameter value and no default value was found -* -* EXAMPLES -* 1. Get the value for the EPICS-defined environment parameter -* EPICS_TS_NTP_INET. -* -* #include "envDefs.h" -* const char *pStr; -* -* pStr = envGetConfigParamPtr(&EPICS_TS_NTP_INET); -* if (pStr) { -* printf("NTP time server is: %s\n", pStr); -* } -* -*-*/ -const char * epicsShareAPI envGetConfigParamPtr( -const ENV_PARAM *pParam /* I pointer to config param structure */ -) -{ - const char *pEnv; /* pointer to environment string */ - - pEnv = getenv(pParam->name); - - if (pEnv == NULL) { - pEnv = pParam->pdflt; - } - - if (pEnv) { - if (pEnv[0u] == '\0') { - pEnv = NULL; - } - } - - return pEnv; -} - - -/*+/subr********************************************************************** -* NAME envGetConfigParam - get value of a configuration parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it -* into the caller's buffer. If the configuration parameter -* isn't found in the environment, then the default value for -* the parameter is copied. If no parameter is found and there -* is no default, then '\0' is copied and NULL is returned. -* -* RETURNS -* pointer to callers buffer, or -* NULL if no parameter value or default value was found -* -* EXAMPLES -* 1. Get the value for the EPICS-defined environment parameter -* EPICS_TS_NTP_INET. -* -* #include "envDefs.h" -* char temp[80]; -* -* printf("NTP time server is: %s\n", -* envGetConfigParam(&EPICS_TS_NTP_INET, sizeof(temp), temp)); -* -* 2. Get the value for the DISPLAY environment parameter under UNIX. -* -* #include "envDefs.h" -* char temp[80]; -* ENV_PARAM display={"DISPLAY",""} -* -* if (envGetConfigParam(&display, sizeof(temp), temp) == NULL) -* printf("DISPLAY isn't defined\n"); -* else -* printf("DISPLAY is %s\n", temp); -* -*-*/ -char * epicsShareAPI envGetConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -int bufDim, /* I dimension of parameter buffer */ -char *pBuf /* I pointer to parameter buffer */ -) -{ - const char *pEnv; /* pointer to environment string */ - - pEnv = envGetConfigParamPtr(pParam); - if (!pEnv) { - return NULL; - } - - strncpy(pBuf, pEnv, bufDim-1); - pBuf[bufDim-1] = '\0'; - - return pBuf; -} - -/*+/subr********************************************************************** -* NAME envGetDoubleConfigParam - get value of a double configuration parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it into the -* caller's real (double) buffer. If the configuration parameter isn't -* found in the environment, then the default value for the parameter -* is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the caller's buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value for the real environment parameter EPICS_THRESHOLD. -* -* #include "envDefs.h" -* double threshold; -* long status; -* -* status = envGetDoubleConfigParam(&EPICS_THRESHOLD, &threshold); -* if (status == 0) { -* printf("the threshold is: %lf\n", threshold); -* } -* else { -* printf("%s could not be found or was not a real number\n", -* EPICS_THRESHOLD.name); -* } -* -*-*/ -long epicsShareAPI envGetDoubleConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -double *pDouble /* O pointer to place to store value */ -) -{ - char text[128]; - char *ptext; - int count; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext != NULL) { - count = epicsScanDouble(text, pDouble); - if (count == 1) { - return 0; - } - (void)fprintf(stderr,"Unable to find a real number in %s=%s\n", - pParam->name, text); - } - - return -1; -} - -/*+/subr********************************************************************** -* NAME envGetInetAddrConfigParam - get value of an inet addr config parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it into -* the caller's (struct in_addr) buffer. If the configuration parameter -* isn't found in the environment, then the default value for -* the parameter is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the callers buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value for the inet address environment parameter EPICS_INET. -* -* #include "envDefs.h" -* struct in_addr addr; -* long status; -* -* status = envGetInetAddrConfigParam(&EPICS_INET, &addr); -* if (status == 0) { -* printf("the s_addr is: %x\n", addr.s_addr); -* } -* else { -* printf("%s could not be found or was not an inet address\n", -* EPICS_INET.name); -* } -* -*-*/ -long epicsShareAPI envGetInetAddrConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -struct in_addr *pAddr /* O pointer to struct to receive inet addr */ -) -{ - char text[128]; - char *ptext; - long status; - struct sockaddr_in sin; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext) { - status = aToIPAddr (text, 0u, &sin); - if (status == 0) { - *pAddr = sin.sin_addr; - return 0; - } - (void)fprintf(stderr,"Unable to find an IP address or valid host name in %s=%s\n", - pParam->name, text); - } - return -1; -} - -/*+/subr********************************************************************** -* NAME envGetLongConfigParam - get value of an integer config parameter -* -* DESCRIPTION -* Gets the value of a configuration parameter and copies it -* into the caller's integer (long) buffer. If the configuration -* parameter isn't found in the environment, then the default value for -* the parameter is copied. -* -* If no parameter is found and there is no default, then -1 is -* returned and the callers buffer is unmodified. -* -* RETURNS -* 0, or -* -1 if an error is encountered -* -* EXAMPLE -* 1. Get the value as a long for the integer environment parameter -* EPICS_NUMBER_OF_ITEMS. -* -* #include "envDefs.h" -* long count; -* long status; -* -* status = envGetLongConfigParam(&EPICS_NUMBER_OF_ITEMS, &count); -* if (status == 0) { -* printf("and the count is: %d\n", count); -* } -* else { -* printf("%s could not be found or was not an integer\n", -* EPICS_NUMBER_OF_ITEMS.name); -* } -* -*-*/ -long epicsShareAPI envGetLongConfigParam( -const ENV_PARAM *pParam,/* I pointer to config param structure */ -long *pLong /* O pointer to place to store value */ -) -{ - char text[128]; - char *ptext; - int count; - - ptext = envGetConfigParam(pParam, sizeof text, text); - if (ptext) { - count = sscanf(text, "%ld", pLong); - if (count == 1) - return 0; - (void)fprintf(stderr,"Unable to find an integer in %s=%s\n", - pParam->name, text); - } - return -1; -} - - -long epicsShareAPI -envGetBoolConfigParam(const ENV_PARAM *pParam, int *pBool) -{ - char text[20]; - - if(!envGetConfigParam(pParam, sizeof(text), text)) - return -1; - *pBool = epicsStrCaseCmp(text, "yes")==0; - return 0; -} - -/*+/subr********************************************************************** -* NAME envPrtConfigParam - print value of a configuration parameter -* -* DESCRIPTION -* Prints the value of a configuration parameter. -* -* RETURNS -* 0 -* -* EXAMPLE -* 1. Print the value for the EPICS-defined environment parameter -* EPICS_TS_NTP_INET. -* -* #include "envDefs.h" -* -* envPrtConfigParam(&EPICS_TS_NTP_INET); -* -*-*/ -long epicsShareAPI envPrtConfigParam( -const ENV_PARAM *pParam) /* pointer to config param structure */ -{ - const char *pVal; - - pVal = envGetConfigParamPtr(pParam); - if (pVal == NULL) - fprintf(stdout, "%s is undefined\n", pParam->name); - else - fprintf(stdout,"%s: %s\n", pParam->name, pVal); - return 0; -} - -/*+/subr********************************************************************** -* NAME epicsPrtEnvParams - print value of all configuration parameters -* -* DESCRIPTION -* Prints all configuration parameters and their current value. -* -* RETURNS -* 0 -* -* EXAMPLE -* 1. Print the value for all EPICS-defined environment parameters. -* -* #include "envDefs.h" -* -* epicsPrtEnvParams(); -* -*-*/ -long epicsShareAPI -epicsPrtEnvParams(void) -{ - const ENV_PARAM **ppParam = env_param_list; - - while (*ppParam != NULL) - envPrtConfigParam(*(ppParam++)); - - return 0; -} - -/* - * envGetInetPortConfigParam () - */ -epicsShareFunc unsigned short epicsShareAPI envGetInetPortConfigParam - (const ENV_PARAM *pEnv, unsigned short defaultPort) -{ - long longStatus; - long epicsParam; - - longStatus = envGetLongConfigParam (pEnv, &epicsParam); - if (longStatus!=0) { - epicsParam = (long) defaultPort; - errlogPrintf ("EPICS Environment \"%s\" integer fetch failed\n", pEnv->name); - errlogPrintf ("setting \"%s\" = %ld\n", pEnv->name, epicsParam); - } - - if (epicsParam<=IPPORT_USERRESERVED || epicsParam>USHRT_MAX) { - errlogPrintf ("EPICS Environment \"%s\" out of range\n", pEnv->name); - /* - * Quit if the port is wrong due coding error - */ - assert (epicsParam != (long) defaultPort); - epicsParam = (long) defaultPort; - errlogPrintf ("Setting \"%s\" = %ld\n", pEnv->name, epicsParam); - } - - /* - * ok to clip to unsigned short here because we checked the range - */ - return (unsigned short) epicsParam; -} - diff --git a/src/libCom/error/Makefile b/src/libCom/error/Makefile deleted file mode 100644 index 0a99b0def..000000000 --- a/src/libCom/error/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/error - -INC += epicsPrint.h -INC += errMdef.h -INC += errSymTbl.h -INC += errlog.h -INC += error.h - -Com_SRCS += errlog.c -Com_SRCS += errSymLib.c -Com_SRCS += errSymTbl.c - -# For bldErrSymTbl -# -ERR_S_FILES += $(LIBCOM)/osi/devLib.h -ERR_S_FILES += $(LIBCOM)/osi/epicsTime.h -ERR_S_FILES += $(LIBCOM)/as/asLib.h -ERR_S_FILES += $(LIBCOM)/misc/epicsStdlib.h -ERR_S_FILES += $(LIBCOM)/pool/epicsThreadPool.h -ERR_S_FILES += $(SRC)/ioc/db/dbAccessDefs.h -ERR_S_FILES += $(SRC)/ioc/dbStatic/devSup.h -ERR_S_FILES += $(SRC)/ioc/dbStatic/drvSup.h -ERR_S_FILES += $(SRC)/ioc/dbStatic/recSup.h -ERR_S_FILES += $(SRC)/ioc/dbStatic/dbStaticLib.h -ERR_S_FILES += $(LIBCOM)/error/errMdef.h -ERR_S_FILES += $(SRC)/ca/legacy/pcas/generic/casdef.h -ERR_S_FILES += $(SRC)/ca/legacy/gdd/gddAppFuncTable.h - -CLEANS += errSymTbl.c diff --git a/src/libCom/error/RULES b/src/libCom/error/RULES deleted file mode 100644 index dc2926ff3..000000000 --- a/src/libCom/error/RULES +++ /dev/null @@ -1,11 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -errSymTbl.c: $(ERR_S_FILES) $(LIBCOM)/error/makeStatTbl.pl - $(PERL) $(LIBCOM)/error/makeStatTbl.pl $(ERR_S_FILES) diff --git a/src/libCom/error/epicsPrint.h b/src/libCom/error/epicsPrint.h deleted file mode 100644 index db889794a..000000000 --- a/src/libCom/error/epicsPrint.h +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsPrint.h */ - -/*This is now obsolete. Replaced by errlog.h */ -#ifndef INCepicsPrintH -#define INCepicsPrintH - -#include "errlog.h" - -#endif /*INCepicsPrintH*/ diff --git a/src/libCom/error/errMdef.h b/src/libCom/error/errMdef.h deleted file mode 100644 index 4dbbecaf1..000000000 --- a/src/libCom/error/errMdef.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Error Handling definitions */ -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - -#ifndef INCerrMdefh -#define INCerrMdefh - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define RTN_SUCCESS(STATUS) ((STATUS)==0) - -#define M_dbAccess (501 <<16) /*Database Access Routines */ -#define M_drvSup (503 <<16) /*Driver Support*/ -#define M_devSup (504 <<16) /*Device Support*/ -#define M_recSup (505 <<16) /*Record Support*/ -#define M_recType (506 <<16) /*Record Type*/ -#define M_record (507 <<16) /*Database Records*/ -#define M_ar (508 <<16) /*Archiver; see arDefs.h*/ -#define M_ts (509 <<16) /*Time Stamp Routines; see tsDefs.h*/ -#define M_arAcc (510 <<16) /*Archive Access Library Routines*/ -#define M_bf (511 <<16) /*Block File Routines; see bfDefs.h*/ -#define M_syd (512 <<16) /*Sync Data Routines; see sydDefs.h*/ -#define M_ppr (513 <<16) /*Portable Plot Routines; see pprPlotDefs.h*/ -#define M_env (514 <<16) /*Environment Routines; see envDefs.h*/ -#define M_gen (515 <<16) /*General Purpose Routines; see genDefs.h*/ -#define M_gpib (516 <<16) /*Gpib driver & device support; see drvGpibInterface.h*/ -#define M_bitbus (517 <<16) /*Bitbus driver & device support; see drvBitBusInterface.h*/ -#define M_dbLib (519 <<16) /*Static Database Access */ -#define M_epvxi (520 <<16) /*VXI Driver*/ -#define M_devLib (521 <<16) /*Device Resource Registration*/ -#define M_asLib (522 <<16) /*Access Security */ -#define M_cas (523 <<16) /*CA server*/ -#define M_casApp (524 <<16) /*CA server application*/ -#define M_bucket (525 <<16) /*Bucket Hash*/ -#define M_gddFuncTbl (526 <<16) /*gdd jump table*/ -#define M_stdlib (527 <<16) /*EPICS Standard library*/ -#define M_pool (528 <<16) /*Thread pool*/ -#define M_time (529 <<16) /*epicsTime*/ - -epicsShareFunc void epicsShareAPI errSymLookup(long status, char *pBuf, unsigned bufLength); -epicsShareFunc const char* errSymMsg(long status); -epicsShareFunc void epicsShareAPI errSymTest(unsigned short modnum, unsigned short begErrNum, unsigned short endErrNum); -epicsShareFunc void epicsShareAPI errSymTestPrint(long errNum); -epicsShareFunc int epicsShareAPI errSymBld(void); -epicsShareFunc int epicsShareAPI errSymbolAdd (long errNum,char *name); -epicsShareFunc void epicsShareAPI errSymDump(void); -epicsShareFunc void epicsShareAPI tstErrSymFind(void); - -#ifdef __cplusplus -} -#endif - -#endif /*INCerrMdefh*/ diff --git a/src/libCom/error/errSymLib.c b/src/libCom/error/errSymLib.c deleted file mode 100644 index aa1f3961c..000000000 --- a/src/libCom/error/errSymLib.c +++ /dev/null @@ -1,334 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * errSymLib.c - * Author: Marty Kraimer - * Date: 6-1-90 - * - *************************************************************************** - * This must ultimately be replaced by a facility that allows remote - * nodes access to the error messages. A message handling communication - * task should be written that allows multiple remote nodes to request - * notification of all error messages. - * For now lets just print messages and last errno via logMsg or printf - *************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsAssert.h" -#include "dbDefs.h" -#include "errMdef.h" -#include "errSymTbl.h" -#include "ellLib.h" -#include "errlog.h" - - -static unsigned short errhash(long errNum); - -typedef struct errnumnode { - ELLNODE node; - long errNum; - struct errnumnode *hashnode; - char *message; - long pad; -} ERRNUMNODE; -#define NHASH 256 - - -static ELLLIST errnumlist = ELLLIST_INIT; -static ERRNUMNODE **hashtable; -static int initialized = FALSE; -extern ERRSYMTAB_ID errSymTbl; - -/**************************************************************** - * ERRSYMBLD - * - * Create the normal ell LIST of sorted error messages nodes - * Followed by linked hash lists - that link together those - * ell nodes that have a common hash number. - * - ***************************************************************/ -int epicsShareAPI errSymBld(void) -{ - ERRSYMBOL *errArray = errSymTbl->symbols; - ERRNUMNODE *perrNumNode = NULL; - ERRNUMNODE *pNextNode = NULL; - ERRNUMNODE **phashnode = NULL; - int i; - int modnum; - unsigned short hashInd; - - if(initialized) return(0); - hashtable = (ERRNUMNODE**)callocMustSucceed - (NHASH, sizeof(ERRNUMNODE*),"errSymBld"); - for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { - modnum = errArray->errNum >> 16; - if (modnum < 501) { - fprintf(stderr, "errSymBld: ERROR - Module number in errSymTbl < 501 was Module=%lx Name=%s\n", - errArray->errNum, errArray->name); - continue; - } - if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) { - fprintf(stderr, "errSymBld: ERROR - errSymbolAdd() failed \n"); - continue; - } - } - perrNumNode = (ERRNUMNODE *) ellFirst(&errnumlist); - while (perrNumNode) { - /* hash each perrNumNode->errNum */ - hashInd = errhash(perrNumNode->errNum); - phashnode = (ERRNUMNODE**)&hashtable[hashInd]; - pNextNode = (ERRNUMNODE*) *phashnode; - /* search for last node (NULL) of hashnode linked list */ - while (pNextNode) { - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - *phashnode = perrNumNode; - perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); - } - initialized = TRUE; - return(0); -} - - - -/**************************************************************** - * HASH - * returns the hash index of errNum -****************************************************************/ -static unsigned short errhash(long errNum) -{ -unsigned short modnum; -unsigned short errnum; - - modnum = (unsigned short) (errNum >> 16); - errnum = (unsigned short) (errNum & 0xffff); - return((unsigned short)(((modnum - 500) * 20) + errnum) % NHASH); -} - -/**************************************************************** - * ERRSYMBOLADD - * adds symbols to the master errnumlist as compiled from errSymTbl.c - ***************************************************************/ -int epicsShareAPI errSymbolAdd (long errNum,char *name) -{ - ERRNUMNODE *pNew; - - pNew = (ERRNUMNODE*)callocMustSucceed(1,sizeof(ERRNUMNODE),"errSymbolAdd"); - pNew->errNum = errNum; - pNew->message = name; - ellAdd(&errnumlist,(ELLNODE*)pNew); - return(0); -} - -/**************************************************************** - * errRawCopy - ***************************************************************/ -static void errRawCopy ( long statusToDecode, char *pBuf, unsigned bufLength ) -{ - unsigned modnum, errnum; - unsigned nChar; - int status; - - modnum = (unsigned) statusToDecode; - modnum >>= 16; - modnum &= 0xffff; - errnum = (unsigned) statusToDecode; - errnum &= 0xffff; - - if ( bufLength ) { - if ( modnum == 0 ) { - if ( bufLength > 11 ) { - status = sprintf ( pBuf, "err = %d", errnum ); - } - else if ( bufLength > 5 ) { - status = sprintf ( pBuf, "%d", errnum ); - } - else { - strncpy ( pBuf,"", bufLength ); - pBuf[bufLength-1] = '\0'; - status = 0; - } - } - else { - if ( bufLength > 50 ) { - status = sprintf ( pBuf, - "status = (%d,%d) not in symbol table", modnum, errnum ); - } - else if ( bufLength > 25 ) { - status = sprintf ( pBuf, - "status = (%d,%d)", modnum, errnum ); - } - else if ( bufLength > 15 ) { - status = sprintf ( pBuf, - "(%d,%d)", modnum, errnum ); - } - else { - strncpy ( pBuf, - "", bufLength); - pBuf[bufLength-1] = '\0'; - status = 0; - } - } - assert (status >= 0 ); - nChar = (unsigned) status; - assert ( nChar < bufLength ); - } -} - -static -const char* errSymLookupInternal(long status) -{ - unsigned modNum; - unsigned hashInd; - ERRNUMNODE *pNextNode; - ERRNUMNODE **phashnode = NULL; - - if(!initialized) errSymBld(); - - modNum = (unsigned) status; - modNum >>= 16; - modNum &= 0xffff; - if ( modNum <= 500 ) { - const char * pStr = strerror ((int) status); - if ( pStr ) { - return pStr; - } - } - else { - hashInd = errhash(status); - phashnode = (ERRNUMNODE**)&hashtable[hashInd]; - pNextNode = *phashnode; - while(pNextNode) { - if(pNextNode->errNum==status){ - return pNextNode->message; - } - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - } - return NULL; -} - -const char* errSymMsg(long status) -{ - const char* msg = errSymLookupInternal(status); - return msg ? msg : ""; -} - -/**************************************************************** - * errSymLookup - ***************************************************************/ -void epicsShareAPI errSymLookup (long status, char * pBuf, unsigned bufLength) -{ - const char* msg = errSymLookupInternal(status); - if(msg) { - strncpy(pBuf, msg, bufLength); - pBuf[bufLength-1] = '\0'; - return; - } - errRawCopy(status, pBuf, bufLength); -} - -/**************************************************************** - * errSymDump - ***************************************************************/ -void epicsShareAPI errSymDump(void) -{ -ERRNUMNODE **phashnode = NULL; -ERRNUMNODE *pNextNode; -int i; -int modnum; -int errnum; -int msgcount; -int firstTime; - - if (!initialized) errSymBld(); - - msgcount = 0; - printf("errSymDump: number of hash slots=%d\n", NHASH); - for ( i=0; i < NHASH; i++) { - phashnode = &hashtable[i]; - pNextNode = *phashnode; - firstTime=1; - while (pNextNode) { - if (firstTime) { - printf("HASHNODE=%d\n", i); - firstTime=0; - } - modnum = pNextNode->errNum >> 16; - errnum = pNextNode->errNum & 0xffff; - printf("\tmod %d num %d \"%s\"\n" - , modnum , errnum , pNextNode->message); - msgcount++; - phashnode = &pNextNode->hashnode; - pNextNode = *phashnode; - } - } - printf("\nerrSymDump: total number of error messages=%d\n", msgcount); -} - - -/**************************************************************** - * errSymTestPrint - ***************************************************************/ -void epicsShareAPI errSymTestPrint(long errNum) -{ - char message[256]; - unsigned short modnum; - unsigned short errnum; - - if (!initialized) errSymBld(); - - message[0] = '\0'; - modnum = (unsigned short) (errNum >> 16); - errnum = (unsigned short) (errNum & 0xffff); - if (modnum < 501) { - fprintf(stderr, "Usage: errSymTestPrint(long errNum) \n"); - fprintf(stderr, "errSymTestPrint: module number < 501 \n"); - return; - } - errSymLookup(errNum, message, sizeof(message)); - if ( message[0] == '\0' ) return; - printf("module %hu number %hu message=\"%s\"\n", - modnum, errnum, message); - return; -} - -/**************************************************************** - * ERRSYMTEST -****************************************************************/ -void epicsShareAPI errSymTest(unsigned short modnum, - unsigned short begErrNum, unsigned short endErrNum) -{ - long errNum; - unsigned short errnum; - - if(!initialized) errSymBld(); - if (modnum < 501) - return; - - /* print range of error messages */ - for (errnum = begErrNum; errnum <= endErrNum; errnum++) { - errNum = modnum << 16; - errNum |= (errnum & 0xffff); - errSymTestPrint(errNum); - } -} diff --git a/src/libCom/error/errSymTbl.h b/src/libCom/error/errSymTbl.h deleted file mode 100644 index 2b1712621..000000000 --- a/src/libCom/error/errSymTbl.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INCerrSymTblh -#define INCerrSymTblh 1 - -#ifndef NELEMENTS -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) -#endif -#define LOCAL static - -typedef struct /* ERRSYMBOL - entry in symbol table */ - { - char *name; /* pointer to symbol name */ - long errNum; /* errMessage symbol number */ - } ERRSYMBOL; -typedef struct /* ERRSYMTAB - symbol table */ - { - int nsymbols; /* current number of symbols in table */ - ERRSYMBOL *symbols; /* ptr to array of symbol entries */ - } ERRSYMTAB; -typedef ERRSYMTAB *ERRSYMTAB_ID; - - -#endif /* INCerrSymTblh */ diff --git a/src/libCom/error/errlog.c b/src/libCom/error/errlog.c deleted file mode 100644 index b6789978a..000000000 --- a/src/libCom/error/errlog.c +++ /dev/null @@ -1,703 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Original Author: Marty Kraimer - * Date: 07JAN1998 - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#define ERRLOG_INIT -#include "adjustment.h" -#include "dbDefs.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsInterrupt.h" -#include "errMdef.h" -#include "error.h" -#include "ellLib.h" -#include "errlog.h" -#include "epicsStdio.h" -#include "epicsExit.h" - - -#define BUFFER_SIZE 1280 -#define MAX_MESSAGE_SIZE 256 - -/*Declare storage for errVerbose */ -epicsShareDef int errVerbose = 0; - -static void errlogExitHandler(void *); -static void errlogThread(void); - -static char *msgbufGetFree(int noConsoleMessage); -static void msgbufSetSize(int size); /* Send 'size' chars plus trailing '\0' */ -static char *msgbufGetSend(int *noConsoleMessage); -static void msgbufFreeSend(void); - -typedef struct listenerNode{ - ELLNODE node; - errlogListener listener; - void *pPrivate; -} listenerNode; - -/*each message consists of a msgNode immediately followed by the message */ -typedef struct msgNode { - ELLNODE node; - char *message; - int length; - int noConsoleMessage; -} msgNode; - -static struct { - epicsEventId waitForWork; /*errlogThread waits for this*/ - epicsMutexId msgQueueLock; - epicsMutexId listenerLock; - epicsEventId waitForFlush; /*errlogFlush waits for this*/ - epicsEventId flush; /*errlogFlush sets errlogThread does a Try*/ - epicsMutexId flushLock; - epicsEventId waitForExit; /*errlogExitHandler waits for this*/ - int atExit; /*TRUE when errlogExitHandler is active*/ - ELLLIST listenerList; - ELLLIST msgQueue; - msgNode *pnextSend; - int errlogInitFailed; - int buffersize; - int maxMsgSize; - int msgNeeded; - int sevToLog; - int toConsole; - FILE *console; - int missedMessages; - char *pbuffer; -} pvtData; - - -/* - * vsnprintf with truncation message - */ -static int tvsnPrint(char *str, size_t size, const char *format, va_list ap) -{ - static const char tmsg[] = "<>\n"; - int nchar = epicsVsnprintf(str, size, format ? format : "", ap); - - if (nchar >= size) { - if (size > sizeof tmsg) - strcpy(str + size - sizeof tmsg, tmsg); - nchar = size - 1; - } - return nchar; -} - -epicsShareFunc int errlogPrintf(const char *pFormat, ...) -{ - va_list pvar; - char *pbuffer; - int nchar; - int isOkToBlock; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogPrintf called from interrupt level\n"); - return 0; - } - - errlogInit(0); - isOkToBlock = epicsThreadIsOkToBlock(); - - if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - va_start(pvar, pFormat); - nchar = vfprintf(console, pFormat, pvar); - va_end (pvar); - fflush(console); - } - - if (pvtData.atExit) - return nchar; - - pbuffer = msgbufGetFree(isOkToBlock); - if (!pbuffer) - return 0; - - va_start(pvar, pFormat); - nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar); - va_end(pvar); - msgbufSetSize(nchar); - return nchar; -} - -epicsShareFunc int errlogVprintf( - const char *pFormat,va_list pvar) -{ - int nchar; - char *pbuffer; - int isOkToBlock; - FILE *console; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogVprintf called from interrupt level\n"); - return 0; - } - - errlogInit(0); - if (pvtData.atExit) - return 0; - isOkToBlock = epicsThreadIsOkToBlock(); - - pbuffer = msgbufGetFree(isOkToBlock); - if (!pbuffer) { - console = pvtData.console ? pvtData.console : stderr; - vfprintf(console, pFormat, pvar); - fflush(console); - return 0; - } - - nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar); - if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { - console = pvtData.console ? pvtData.console : stderr; - fprintf(console, "%s", pbuffer); - fflush(console); - } - msgbufSetSize(nchar); - return nchar; -} - -epicsShareFunc int epicsShareAPI errlogMessage(const char *message) -{ - errlogPrintf("%s", message); - return 0; -} - -epicsShareFunc int errlogPrintfNoConsole( const char *pFormat, ...) -{ - va_list pvar; - int nchar; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogPrintfNoConsole called from interrupt level\n"); - return 0; - } - - errlogInit(0); - va_start(pvar, pFormat); - nchar = errlogVprintfNoConsole(pFormat, pvar); - va_end(pvar); - return nchar; -} - -epicsShareFunc int errlogVprintfNoConsole( - const char *pFormat,va_list pvar) -{ - int nchar; - char *pbuffer; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogVprintfNoConsole called from interrupt level\n"); - return 0; - } - - errlogInit(0); - if (pvtData.atExit) - return 0; - - pbuffer = msgbufGetFree(1); - if (!pbuffer) - return 0; - - nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar); - msgbufSetSize(nchar); - return nchar; -} - - -epicsShareFunc int errlogSevPrintf( - const errlogSevEnum severity,const char *pFormat, ...) -{ - va_list pvar; - int nchar; - int isOkToBlock; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogSevPrintf called from interrupt level\n"); - return 0; - } - - errlogInit(0); - if (pvtData.sevToLog > severity) - return 0; - - isOkToBlock = epicsThreadIsOkToBlock(); - if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - fprintf(console, "sevr=%s ", errlogGetSevEnumString(severity)); - va_start(pvar, pFormat); - vfprintf(console, pFormat, pvar); - va_end(pvar); - fflush(console); - } - - va_start(pvar, pFormat); - nchar = errlogSevVprintf(severity, pFormat, pvar); - va_end(pvar); - return nchar; -} - -epicsShareFunc int errlogSevVprintf( - const errlogSevEnum severity,const char *pFormat,va_list pvar) -{ - char *pnext; - int nchar; - int totalChar = 0; - int isOkToBlock; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage - ("errlogSevVprintf called from interrupt level\n"); - return 0; - } - - errlogInit(0); - if (pvtData.atExit) - return 0; - - isOkToBlock = epicsThreadIsOkToBlock(); - pnext = msgbufGetFree(isOkToBlock); - if (!pnext) - return 0; - - nchar = sprintf(pnext, "sevr=%s ", errlogGetSevEnumString(severity)); - pnext += nchar; totalChar += nchar; - nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pFormat, pvar); - pnext += nchar; totalChar += nchar; - if (pnext[-1] != '\n') { - strcpy(pnext,"\n"); - totalChar++; - } - msgbufSetSize(totalChar); - return nchar; -} - - -epicsShareFunc char * epicsShareAPI errlogGetSevEnumString( - const errlogSevEnum severity) -{ - errlogInit(0); - if (severity > 3) - return "unknown"; - return errlogSevEnumString[severity]; -} - -epicsShareFunc void epicsShareAPI errlogSetSevToLog( - const errlogSevEnum severity) -{ - errlogInit(0); - pvtData.sevToLog = severity; -} - -epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog(void) -{ - errlogInit(0); - return pvtData.sevToLog; -} - -epicsShareFunc void epicsShareAPI errlogAddListener( - errlogListener listener, void *pPrivate) -{ - listenerNode *plistenerNode; - - errlogInit(0); - if (pvtData.atExit) - return; - - plistenerNode = callocMustSucceed(1,sizeof(listenerNode), - "errlogAddListener"); - epicsMutexMustLock(pvtData.listenerLock); - plistenerNode->listener = listener; - plistenerNode->pPrivate = pPrivate; - ellAdd(&pvtData.listenerList,&plistenerNode->node); - epicsMutexUnlock(pvtData.listenerLock); -} - -epicsShareFunc int epicsShareAPI errlogRemoveListeners( - errlogListener listener, void *pPrivate) -{ - listenerNode *plistenerNode; - int count = 0; - - errlogInit(0); - if (!pvtData.atExit) - epicsMutexMustLock(pvtData.listenerLock); - - plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList); - while (plistenerNode) { - listenerNode *pnext = (listenerNode *)ellNext(&plistenerNode->node); - - if (plistenerNode->listener == listener && - plistenerNode->pPrivate == pPrivate) { - ellDelete(&pvtData.listenerList, &plistenerNode->node); - free(plistenerNode); - ++count; - } - plistenerNode = pnext; - } - - if (!pvtData.atExit) - epicsMutexUnlock(pvtData.listenerLock); - - if (count == 0) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - fprintf(console, - "errlogRemoveListeners: No listeners found\n"); - } - return count; -} - -epicsShareFunc int epicsShareAPI eltc(int yesno) -{ - errlogInit(0); - errlogFlush(); - pvtData.toConsole = yesno; - return 0; -} - -epicsShareFunc int errlogSetConsole(FILE *stream) -{ - errlogInit(0); - pvtData.console = stream; - return 0; -} - -epicsShareFunc void errPrintf(long status, const char *pFileName, - int lineno, const char *pformat, ...) -{ - va_list pvar; - char *pnext; - int nchar; - int totalChar=0; - int isOkToBlock; - char name[256]; - - if (epicsInterruptIsInterruptContext()) { - epicsInterruptContextMessage("errPrintf called from interrupt level\n"); - return; - } - - errlogInit(0); - isOkToBlock = epicsThreadIsOkToBlock(); - if (status == 0) - status = errno; - - if (status > 0) { - errSymLookup(status, name, sizeof(name)); - } - - if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - if (pFileName) - fprintf(console, "filename=\"%s\" line number=%d\n", - pFileName, lineno); - if (status > 0) - fprintf(console, "%s ", name); - - va_start(pvar, pformat); - vfprintf(console, pformat, pvar); - va_end(pvar); - fputc('\n', console); - fflush(console); - } - - if (pvtData.atExit) - return; - - pnext = msgbufGetFree(isOkToBlock); - if (!pnext) - return; - - if (pFileName) { - nchar = sprintf(pnext,"filename=\"%s\" line number=%d\n", - pFileName, lineno); - pnext += nchar; totalChar += nchar; - } - - if (status > 0) { - nchar = sprintf(pnext,"%s ",name); - pnext += nchar; totalChar += nchar; - } - va_start(pvar, pformat); - nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pformat, pvar); - va_end(pvar); - if (nchar>0) { - pnext += nchar; - totalChar += nchar; - } - strcpy(pnext, "\n"); - totalChar++ ; /*include the \n */ - msgbufSetSize(totalChar); -} - - -static void errlogExitHandler(void *pvt) -{ - pvtData.atExit = 1; - epicsEventSignal(pvtData.waitForWork); - epicsEventMustWait(pvtData.waitForExit); -} - -struct initArgs { - int bufsize; - int maxMsgSize; -}; - -static void errlogInitPvt(void *arg) -{ - struct initArgs *pconfig = (struct initArgs *) arg; - epicsThreadId tid; - - pvtData.errlogInitFailed = TRUE; - pvtData.buffersize = pconfig->bufsize; - pvtData.maxMsgSize = pconfig->maxMsgSize; - pvtData.msgNeeded = adjustToWorstCaseAlignment(pvtData.maxMsgSize + - sizeof(msgNode)); - ellInit(&pvtData.listenerList); - ellInit(&pvtData.msgQueue); - pvtData.toConsole = TRUE; - pvtData.console = NULL; - pvtData.waitForWork = epicsEventMustCreate(epicsEventEmpty); - pvtData.listenerLock = epicsMutexMustCreate(); - pvtData.msgQueueLock = epicsMutexMustCreate(); - pvtData.waitForFlush = epicsEventMustCreate(epicsEventEmpty); - pvtData.flush = epicsEventMustCreate(epicsEventEmpty); - pvtData.flushLock = epicsMutexMustCreate(); - pvtData.waitForExit = epicsEventMustCreate(epicsEventEmpty); - pvtData.pbuffer = callocMustSucceed(1, pvtData.buffersize, - "errlogInitPvt"); - - errSymBld(); /* Better not to do this lazily... */ - - tid = epicsThreadCreate("errlog", epicsThreadPriorityLow, - epicsThreadGetStackSize(epicsThreadStackSmall), - (EPICSTHREADFUNC)errlogThread, 0); - if (tid) { - pvtData.errlogInitFailed = FALSE; - } -} - - -epicsShareFunc int epicsShareAPI errlogInit2(int bufsize, int maxMsgSize) -{ - static epicsThreadOnceId errlogOnceFlag = EPICS_THREAD_ONCE_INIT; - struct initArgs config; - - if (pvtData.atExit) - return 0; - - if (bufsize < BUFFER_SIZE) - bufsize = BUFFER_SIZE; - config.bufsize = bufsize; - - if (maxMsgSize < MAX_MESSAGE_SIZE) - maxMsgSize = MAX_MESSAGE_SIZE; - config.maxMsgSize = maxMsgSize; - - epicsThreadOnce(&errlogOnceFlag, errlogInitPvt, &config); - if (pvtData.errlogInitFailed) { - fprintf(stderr,"errlogInit failed\n"); - exit(1); - } - return 0; -} - -epicsShareFunc int epicsShareAPI errlogInit(int bufsize) -{ - return errlogInit2(bufsize, MAX_MESSAGE_SIZE); -} - -epicsShareFunc void epicsShareAPI errlogFlush(void) -{ - int count; - - errlogInit(0); - if (pvtData.atExit) - return; - - /*If nothing in queue dont wake up errlogThread*/ - epicsMutexMustLock(pvtData.msgQueueLock); - count = ellCount(&pvtData.msgQueue); - epicsMutexUnlock(pvtData.msgQueueLock); - if (count <= 0) - return; - - /*must let errlogThread empty queue*/ - epicsMutexMustLock(pvtData.flushLock); - epicsEventSignal(pvtData.flush); - epicsEventSignal(pvtData.waitForWork); - epicsEventMustWait(pvtData.waitForFlush); - epicsMutexUnlock(pvtData.flushLock); -} - -static void errlogThread(void) -{ - listenerNode *plistenerNode; - int noConsoleMessage; - char *pmessage; - - epicsAtExit(errlogExitHandler,0); - while (TRUE) { - epicsEventMustWait(pvtData.waitForWork); - while ((pmessage = msgbufGetSend(&noConsoleMessage))) { - epicsMutexMustLock(pvtData.listenerLock); - if (pvtData.toConsole && !noConsoleMessage) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - fprintf(console, "%s", pmessage); - fflush(console); - } - - plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList); - while (plistenerNode) { - (*plistenerNode->listener)(plistenerNode->pPrivate, pmessage); - plistenerNode = (listenerNode *)ellNext(&plistenerNode->node); - } - - epicsMutexUnlock(pvtData.listenerLock); - msgbufFreeSend(); - } - - if (pvtData.atExit) - break; - if (epicsEventTryWait(pvtData.flush) != epicsEventWaitOK) - continue; - - epicsThreadSleep(.2); /*just wait an extra .2 seconds*/ - epicsEventSignal(pvtData.waitForFlush); - } - epicsEventSignal(pvtData.waitForExit); -} - - -static msgNode *msgbufGetNode(void) -{ - char *pbuffer = pvtData.pbuffer; - char *pnextFree; - msgNode *pnextSend; - - if (ellCount(&pvtData.msgQueue) == 0 ) { - pnextFree = pbuffer; /* Reset if empty */ - } - else { - msgNode *pfirst = (msgNode *)ellFirst(&pvtData.msgQueue); - msgNode *plast = (msgNode *)ellLast(&pvtData.msgQueue); - char *plimit = pbuffer + pvtData.buffersize; - - pnextFree = plast->message + adjustToWorstCaseAlignment(plast->length); - if (pfirst > plast) { - plimit = (char *)pfirst; - } - else if (pnextFree + pvtData.msgNeeded > plimit) { - pnextFree = pbuffer; /* Hit end, wrap to start */ - plimit = (char *)pfirst; - } - if (pnextFree + pvtData.msgNeeded > plimit) { - return 0; /* No room */ - } - } - - pnextSend = (msgNode *)pnextFree; - pnextSend->message = pnextFree + sizeof(msgNode); - pnextSend->length = 0; - return pnextSend; -} - -static char *msgbufGetFree(int noConsoleMessage) -{ - msgNode *pnextSend; - - if (epicsMutexLock(pvtData.msgQueueLock) != epicsMutexLockOK) - return 0; - - if ((ellCount(&pvtData.msgQueue) == 0) && pvtData.missedMessages) { - int nchar; - - pnextSend = msgbufGetNode(); - nchar = sprintf(pnextSend->message, - "errlog: %d messages were discarded\n", pvtData.missedMessages); - pnextSend->length = nchar + 1; - pvtData.missedMessages = 0; - ellAdd(&pvtData.msgQueue, &pnextSend->node); - } - - pvtData.pnextSend = pnextSend = msgbufGetNode(); - if (pnextSend) { - pnextSend->noConsoleMessage = noConsoleMessage; - pnextSend->length = 0; - return pnextSend->message; /* NB: msgQueueLock is still locked */ - } - - ++pvtData.missedMessages; - epicsMutexUnlock(pvtData.msgQueueLock); - return 0; -} - -static void msgbufSetSize(int size) -{ - msgNode *pnextSend = pvtData.pnextSend; - - pnextSend->length = size+1; - ellAdd(&pvtData.msgQueue, &pnextSend->node); - epicsMutexUnlock(pvtData.msgQueueLock); - epicsEventSignal(pvtData.waitForWork); -} - - -static char * msgbufGetSend(int *noConsoleMessage) -{ - msgNode *pnextSend; - - epicsMutexMustLock(pvtData.msgQueueLock); - pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue); - epicsMutexUnlock(pvtData.msgQueueLock); - if (!pnextSend) - return 0; - - *noConsoleMessage = pnextSend->noConsoleMessage; - return pnextSend->message; -} - -static void msgbufFreeSend(void) -{ - msgNode *pnextSend; - - epicsMutexMustLock(pvtData.msgQueueLock); - pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue); - if (!pnextSend) { - FILE *console = pvtData.console ? pvtData.console : stderr; - - fprintf(console, "errlog: msgbufFreeSend logic error\n"); - epicsThreadSuspendSelf(); - } - ellDelete(&pvtData.msgQueue, &pnextSend->node); - epicsMutexUnlock(pvtData.msgQueueLock); -} diff --git a/src/libCom/error/errlog.h b/src/libCom/error/errlog.h deleted file mode 100644 index 14061bb87..000000000 --- a/src/libCom/error/errlog.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INCerrlogh -#define INCerrlogh - -#include -#include - -#include "shareLib.h" -#include "compilerDependencies.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* define errMessage with a macro so we can print the file and line number*/ -#define errMessage(S, PM) \ - errPrintf(S, __FILE__, __LINE__, "%s", PM) -/* epicsPrintf and epicsVprintf old versions of errlog routines*/ -#define epicsPrintf errlogPrintf -#define epicsVprintf errlogVprintf - -typedef void (*errlogListener)(void *pPrivate, const char *message); - -typedef enum {errlogInfo, errlogMinor, errlogMajor, errlogFatal} errlogSevEnum; - -#ifdef ERRLOG_INIT -epicsShareDef char * errlogSevEnumString[] = {"info","minor","major","fatal"}; -#else -epicsShareExtern char * errlogSevEnumString[]; -#endif - -epicsShareFunc int errlogPrintf( - const char *pformat, ...) EPICS_PRINTF_STYLE(1,2); -epicsShareFunc int errlogVprintf( - const char *pformat,va_list pvar); -epicsShareFunc int errlogSevPrintf( - const errlogSevEnum severity,const char *pformat, ...) EPICS_PRINTF_STYLE(2,3); -epicsShareFunc int errlogSevVprintf( - const errlogSevEnum severity,const char *pformat,va_list pvar); -epicsShareFunc int epicsShareAPI errlogMessage( - const char *message); - -epicsShareFunc char * epicsShareAPI errlogGetSevEnumString( - const errlogSevEnum severity); -epicsShareFunc void epicsShareAPI errlogSetSevToLog( - const errlogSevEnum severity ); -epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog(void); - -epicsShareFunc void epicsShareAPI errlogAddListener( - errlogListener listener, void *pPrivate); -epicsShareFunc int epicsShareAPI errlogRemoveListeners( - errlogListener listener, void *pPrivate); - -epicsShareFunc int epicsShareAPI eltc(int yesno); -epicsShareFunc int errlogSetConsole(FILE *stream); - -epicsShareFunc int epicsShareAPI errlogInit(int bufsize); -epicsShareFunc int epicsShareAPI errlogInit2(int bufsize, int maxMsgSize); -epicsShareFunc void epicsShareAPI errlogFlush(void); - -/*other routines that write to log file*/ -epicsShareFunc void errPrintf(long status, const char *pFileName, - int lineno, const char *pformat, ...) EPICS_PRINTF_STYLE(4,5); - -epicsShareExtern int errVerbose; - -/* The following are added so that logMsg on vxWorks does not cause - * the message to appear twice on the console - */ -epicsShareFunc int errlogPrintfNoConsole( - const char *pformat, ...) EPICS_PRINTF_STYLE(1,2); -epicsShareFunc int errlogVprintfNoConsole( - const char *pformat,va_list pvar); - -#ifdef __cplusplus -} -#endif - -#endif /*INCerrlogh*/ diff --git a/src/libCom/error/error.h b/src/libCom/error/error.h deleted file mode 100644 index 18cf7eebd..000000000 --- a/src/libCom/error/error.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* error.h - errMessage symbol table header */ - -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - - -#ifndef INCerrorh -#define INCerrorh 1 - -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct /* ERRSYMBOL - entry in symbol table */ - { - char *name; /* pointer to symbol name */ - long errNum; /* errMessage symbol number */ - } ERRSYMBOL; -typedef struct /* ERRSYMTAB - symbol table */ - { - short nsymbols; /* current number of symbols in table */ - ERRSYMBOL *symbols; /* ptr to array of symbol entries */ - } ERRSYMTAB; -typedef ERRSYMTAB *ERRSYMTAB_ID; - -/*************************************************************/ -struct errSet { /* This defines one module error set */ - long number; /* dimension of err strings */ - char **papName; /* ptr to arr of ptr to error string */ -}; -struct errDes { /* An array of error sets for modules */ - long number; /* number of err modules */ - struct errSet **papErrSet; /* ptr to arr of ptr to errSet */ -}; -extern struct errDes *dbErrDes; -/*************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif /*INCerrorh*/ diff --git a/src/libCom/error/makeStatTbl.pl b/src/libCom/error/makeStatTbl.pl deleted file mode 100644 index 4f53901f3..000000000 --- a/src/libCom/error/makeStatTbl.pl +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/perl -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# makeStatTbl.pl - Create Error Symbol Table -# -# Kay-Uwe Kasemir, 1-31-97, -# based on makeStatTbl shell script. -# -# SYNOPSIS -# perl makeStatTbl.pl hdir [...] -# -# DESCRIPTION -# This tool creates a symbol table (ERRSYMTAB) structure which contains the -# names and values of all the status codes defined in the .h files in the -# specified directory(s). The status codes must be prefixed with "S_" -# in order to be included in this table. -# A "err.h" file must exist in each hdir which defines the module -# numbers, eg. "M_". The table is created on standard output. -# -# This tool's primary use is for creating an error status table used -# by errPrint, and errSymLookup. -# -# FILES -# errMdef.h module number file for each h directory -# -# SEE ALSO: errnoLib(1), symLib(1) -#*/ - -use Cwd; - -die "No args (files to parse) given" if ($#ARGV < 0); - -# parse all lines of all files given: -while (<>) -{ - if (m'^#define[ /t]*S_') - { - chomp; - push @err_sym_line, $_; - } - if (m'^#[ \t]*define[ /t]+M_') - { - chomp; - push @err_facility_line, $_; - } -} - -$out_name = "errSymTbl.c"; -$dir = cwd(); - -open OUT, ">$out_name" or die "Cannot open $out_name"; - -print OUT "/*\n"; -print OUT " * status code symbol table\n"; -print OUT " *\n"; -print OUT " * CREATED BY makeStatTbl.pl\n"; -print OUT " * FROM $dir\n"; -print OUT " * ON " . localtime() . "\n"; -print OUT " */\n"; -print OUT "\n"; -print OUT "#include \"errMdef.h\"\n"; -print OUT "#include \"errSymTbl.h\"\n"; -print OUT "\n"; - - -foreach $line ( @err_facility_line ) -{ - if ($line =~ m'^#[ \t]*define[ \t]+(M_[A-Za-z0-9_]+)[ \t]+(.*)') - { - printf OUT "#ifndef %s\n", $1; - printf OUT "#define %s %s\n", $1, $2; - printf OUT "#endif /* ifdef %s */\n", $1; - } -} - -$count = 0; -foreach $line ( @err_sym_line ) -{ - print OUT "$line\n"; - # define S_symbol /* comment */ - if ($line =~ m'[ \t#]define[ \t]*(S_[A-Za-z0-9_]+).*\/\* ?(.+?) ?\*\/') - { - $symbol[$count] = $1; - $comment[$count]= $2; - ++$count; - } - else - { - # Some status values for '0' (=OK) have no comment: - unless ($line =~ m'[ \t#]define[ \t]*(S_[A-Za-z0-9_]+)') - { - die "cannot decode this line:\n$line\n"; - } - } -} - - -print OUT "\n"; -print OUT "static ERRSYMBOL symbols[] =\n"; -print OUT "{\n"; - -for ($i=0; $i<$count; ++$i) -{ - printf OUT "\t{ \"%s\", (long) %s },\n", - $comment[$i], $symbol[$i]; -} - -print OUT "};\n"; -print OUT "\n"; -print OUT "static ERRSYMTAB symTbl =\n"; -print OUT "{\n"; -print OUT "\tNELEMENTS(symbols), /* current number of symbols in table */\n"; -print OUT "\tsymbols, /* ptr to symbol array */\n"; -print OUT "};\n"; -print OUT "\n"; -print OUT "ERRSYMTAB_ID errSymTbl = &symTbl;\n"; -print OUT "\n"; -print OUT "/*\tEOF $out_name */\n"; - diff --git a/src/libCom/fdmgr/Makefile b/src/libCom/fdmgr/Makefile deleted file mode 100644 index 34b1a3dbc..000000000 --- a/src/libCom/fdmgr/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/fdmgr -INC += fdManager.h -INC += fdmgr.h -Com_SRCS += fdmgr.cpp -Com_SRCS += fdManager.cpp diff --git a/src/libCom/fdmgr/fdManager.cpp b/src/libCom/fdmgr/fdManager.cpp deleted file mode 100644 index 00f4d4a87..000000000 --- a/src/libCom/fdmgr/fdManager.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// File descriptor management C++ class library -// (for multiplexing IO in a single threaded environment) -// -// Author Jeffrey O. Hill -// johill@lanl.gov -// 505 665 1831 -// -// NOTES: -// 1) This library is not thread safe -// - -#include - -#define instantiateRecourceLib -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "epicsThread.h" -#include "fdManager.h" -#include "locationException.h" - -using std :: max; - -epicsShareDef fdManager fileDescriptorManager; - -const unsigned mSecPerSec = 1000u; -const unsigned uSecPerSec = 1000u * mSecPerSec; - -// -// fdManager::fdManager() -// -// hopefully its a reasonable guess that select() and epicsThreadSleep() -// will have the same sleep quantum -// -epicsShareFunc fdManager::fdManager () : - sleepQuantum ( epicsThreadSleepQuantum () ), - fdSetsPtr ( new fd_set [fdrNEnums] ), - pTimerQueue ( 0 ), maxFD ( 0 ), processInProg ( false ), - pCBReg ( 0 ) -{ - int status = osiSockAttach (); - assert (status); - - for ( size_t i = 0u; i < fdrNEnums; i++ ) { - FD_ZERO ( &fdSetsPtr[i] ); - } -} - -// -// fdManager::~fdManager() -// -epicsShareFunc fdManager::~fdManager() -{ - fdReg *pReg; - - while ( (pReg = this->regList.get()) ) { - pReg->state = fdReg::limbo; - pReg->destroy(); - } - while ( (pReg = this->activeList.get()) ) { - pReg->state = fdReg::limbo; - pReg->destroy(); - } - delete this->pTimerQueue; - delete [] this->fdSetsPtr; - osiSockRelease(); -} - -// -// fdManager::process() -// -epicsShareFunc void fdManager::process (double delay) -{ - this->lazyInitTimerQueue (); - - // - // no recursion - // - if (this->processInProg) { - return; - } - this->processInProg = true; - - // - // One shot at expired timers prior to going into - // select. This allows zero delay timers to arm - // fd writes. We will never process the timer queue - // more than once here so that fd activity get serviced - // in a reasonable length of time. - // - double minDelay = this->pTimerQueue->process(epicsTime::getCurrent()); - - if ( minDelay >= delay ) { - minDelay = delay; - } - - bool ioPending = false; - tsDLIter < fdReg > iter = this->regList.firstIter (); - while ( iter.valid () ) { - FD_SET(iter->getFD(), &this->fdSetsPtr[iter->getType()]); - ioPending = true; - ++iter; - } - - if ( ioPending ) { - struct timeval tv; - tv.tv_sec = static_cast ( minDelay ); - tv.tv_usec = static_cast ( (minDelay-tv.tv_sec) * uSecPerSec ); - - fd_set * pReadSet = & this->fdSetsPtr[fdrRead]; - fd_set * pWriteSet = & this->fdSetsPtr[fdrWrite]; - fd_set * pExceptSet = & this->fdSetsPtr[fdrException]; - int status = select (this->maxFD, pReadSet, pWriteSet, pExceptSet, &tv); - - this->pTimerQueue->process(epicsTime::getCurrent()); - - if ( status > 0 ) { - - // - // Look for activity - // - iter=this->regList.firstIter (); - while ( iter.valid () && status > 0 ) { - tsDLIter < fdReg > tmp = iter; - tmp++; - if (FD_ISSET(iter->getFD(), &this->fdSetsPtr[iter->getType()])) { - FD_CLR(iter->getFD(), &this->fdSetsPtr[iter->getType()]); - this->regList.remove(*iter); - this->activeList.add(*iter); - iter->state = fdReg::active; - status--; - } - iter = tmp; - } - - // - // I am careful to prevent problems if they access the - // above list while in a "callBack()" routine - // - fdReg * pReg; - while ( (pReg = this->activeList.get()) ) { - pReg->state = fdReg::limbo; - - // - // Tag current fdReg so that we - // can detect if it was deleted - // during the call back - // - this->pCBReg = pReg; - pReg->callBack(); - if (this->pCBReg != NULL) { - // - // check only after we see that it is non-null so - // that we dont trigger bounds-checker dangling pointer - // error - // - assert (this->pCBReg==pReg); - this->pCBReg = 0; - if (pReg->onceOnly) { - pReg->destroy(); - } - else { - this->regList.add(*pReg); - pReg->state = fdReg::pending; - } - } - } - } - else if ( status < 0 ) { - int errnoCpy = SOCKERRNO; - - // dont depend on flags being properly set if - // an error is retuned from select - for ( size_t i = 0u; i < fdrNEnums; i++ ) { - FD_ZERO ( &fdSetsPtr[i] ); - } - - // - // print a message if its an unexpected error - // - if ( errnoCpy != SOCK_EINTR ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf ( stderr, - "fdManager: select failed because \"%s\"\n", - sockErrBuf ); - } - } - } - else { - /* - * recover from subtle differences between - * windows sockets and UNIX sockets implementation - * of select() - */ - epicsThreadSleep(minDelay); - this->pTimerQueue->process(epicsTime::getCurrent()); - } - this->processInProg = false; - return; -} - -// -// fdReg::destroy() -// (default destroy method) -// -void fdReg::destroy() -{ - delete this; -} - -// -// fdReg::~fdReg() -// -fdReg::~fdReg() -{ - this->manager.removeReg(*this); -} - -// -// fdReg::show() -// -void fdReg::show(unsigned level) const -{ - printf ("fdReg at %p\n", (void *) this); - if (level>1u) { - printf ("\tstate = %d, onceOnly = %d\n", - this->state, this->onceOnly); - } - this->fdRegId::show(level); -} - -// -// fdRegId::show() -// -void fdRegId::show ( unsigned level ) const -{ - printf ( "fdRegId at %p\n", - static_cast ( this ) ); - if ( level > 1u ) { - printf ( "\tfd = %d, type = %d\n", - this->fd, this->type ); - } -} - -// -// fdManager::installReg () -// -void fdManager::installReg (fdReg ®) -{ - this->maxFD = max ( this->maxFD, reg.getFD()+1 ); - // Most applications will find that its important to push here to - // the front of the list so that transient writes get executed - // first allowing incoming read protocol to find that outgoing - // buffer space is newly available. - this->regList.push ( reg ); - reg.state = fdReg::pending; - - int status = this->fdTbl.add ( reg ); - if ( status != 0 ) { - throwWithLocation ( fdInterestSubscriptionAlreadyExits () ); - } -} - -// -// fdManager::removeReg () -// -void fdManager::removeReg (fdReg ®In) -{ - fdReg *pItemFound; - - pItemFound = this->fdTbl.remove (regIn); - if (pItemFound!=®In) { - fprintf(stderr, - "fdManager::removeReg() bad fd registration object\n"); - return; - } - - // - // signal fdManager that the fdReg was deleted - // during the call back - // - if (this->pCBReg == ®In) { - this->pCBReg = 0; - } - - switch (regIn.state) { - case fdReg::active: - this->activeList.remove (regIn); - break; - case fdReg::pending: - this->regList.remove (regIn); - break; - case fdReg::limbo: - break; - default: - // - // here if memory corrupted - // - assert(0); - } - regIn.state = fdReg::limbo; - - FD_CLR(regIn.getFD(), &this->fdSetsPtr[regIn.getType()]); -} - -// -// fdManager::reschedule () -// NOOP - this only runs single threaded, and therefore they can only -// add a new timer from places that will always end up in a reschedule -// -void fdManager::reschedule () -{ -} - -double fdManager::quantum () -{ - return this->sleepQuantum; -} - -// -// lookUpFD() -// -epicsShareFunc fdReg *fdManager::lookUpFD (const SOCKET fd, const fdRegType type) -{ - if (fd<0) { - return NULL; - } - fdRegId id (fd,type); - return this->fdTbl.lookup(id); -} - -// -// fdReg::fdReg() -// -fdReg::fdReg (const SOCKET fdIn, const fdRegType typIn, - const bool onceOnlyIn, fdManager &managerIn) : - fdRegId (fdIn,typIn), state (limbo), - onceOnly (onceOnlyIn), manager (managerIn) -{ - if (!FD_IN_FDSET(fdIn)) { - fprintf (stderr, "%s: fd > FD_SETSIZE ignored\n", - __FILE__); - return; - } - this->manager.installReg (*this); -} - -template class resTable; diff --git a/src/libCom/fdmgr/fdManager.h b/src/libCom/fdmgr/fdManager.h deleted file mode 100644 index 59a2f355f..000000000 --- a/src/libCom/fdmgr/fdManager.h +++ /dev/null @@ -1,204 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * File descriptor management C++ class library - * (for multiplexing IO in a single threaded environment) - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef fdManagerH_included -#define fdManagerH_included - -#include "shareLib.h" // reset share lib defines -#include "tsDLList.h" -#include "resourceLib.h" -#include "epicsTime.h" -#include "osiSock.h" -#include "epicsTimer.h" - -enum fdRegType {fdrRead, fdrWrite, fdrException, fdrNEnums}; - -// -// fdRegId -// -// file descriptor interest id -// -class epicsShareClass fdRegId -{ -public: - - fdRegId (const SOCKET fdIn, const fdRegType typeIn) : - fd(fdIn), type(typeIn) {} - - SOCKET getFD () const - { - return this->fd; - } - - fdRegType getType () const - { - return this->type; - } - - bool operator == (const fdRegId &idIn) const - { - return this->fd == idIn.fd && this->type==idIn.type; - } - - resTableIndex hash () const; - - virtual void show (unsigned level) const; - - virtual ~fdRegId() {} -private: - SOCKET fd; - fdRegType type; -}; - -// -// fdManager -// -// file descriptor manager -// -class fdManager : public epicsTimerQueueNotify { -public: - // - // exceptions - // - class fdInterestSubscriptionAlreadyExits {}; - - epicsShareFunc fdManager (); - epicsShareFunc virtual ~fdManager (); - epicsShareFunc void process ( double delay ); // delay parameter is in seconds - - // returns NULL if the fd is unknown - epicsShareFunc class fdReg *lookUpFD (const SOCKET fd, const fdRegType type); - - epicsTimer & createTimer (); - -private: - tsDLList < fdReg > regList; - tsDLList < fdReg > activeList; - resTable < fdReg, fdRegId > fdTbl; - const double sleepQuantum; - fd_set * fdSetsPtr; - epicsTimerQueuePassive * pTimerQueue; - SOCKET maxFD; - bool processInProg; - // - // Set to fdreg when in call back - // and nill otherwise - // - fdReg * pCBReg; - void reschedule (); - double quantum (); - void installReg (fdReg ®); - void removeReg (fdReg ®); - void lazyInitTimerQueue (); - fdManager ( const fdManager & ); - fdManager & operator = ( const fdManager & ); - friend class fdReg; -}; - -// -// default file descriptor manager -// -epicsShareExtern fdManager fileDescriptorManager; - -// -// fdReg -// -// file descriptor registration -// -class epicsShareClass fdReg : - public fdRegId, public tsDLNode, public tsSLNode { - friend class fdManager; - -public: - - fdReg (const SOCKET fdIn, const fdRegType type, - const bool onceOnly=false, fdManager &manager = fileDescriptorManager); - virtual ~fdReg (); - - virtual void show (unsigned level) const; - - // - // Called by the file descriptor manager: - // 1) If the fdManager is deleted and there are still - // fdReg objects attached - // 2) Immediately after calling "callBack()" if - // the constructor specified "onceOnly" - // - // fdReg::destroy() does a "delete this" - // - virtual void destroy (); - -private: - enum state {active, pending, limbo}; - - // - // called when there is activity on the fd - // NOTES - // 1) the fdManager will call this only once during the - // lifetime of a fdReg object if the constructor - // specified "onceOnly" - // - virtual void callBack ()=0; - - unsigned char state; // state enums go here - unsigned char onceOnly; - fdManager &manager; - - fdReg ( const fdReg & ); - fdReg & operator = ( const fdReg & ); -}; - -// -// fdRegId::hash() -// -inline resTableIndex fdRegId::hash () const -{ - const unsigned fdManagerHashTableMinIndexBits = 8; - const unsigned fdManagerHashTableMaxIndexBits = sizeof(SOCKET)*CHAR_BIT; - resTableIndex hashid; - - hashid = integerHash ( fdManagerHashTableMinIndexBits, - fdManagerHashTableMaxIndexBits, this->fd ); - - // - // also evenly distribute based on the type of fdRegType - // - hashid ^= this->type; - - // - // the result here is always masked to the - // proper size after it is returned to the resource class - // - return hashid; -} - -inline void fdManager::lazyInitTimerQueue () -{ - if ( ! this->pTimerQueue ) { - this->pTimerQueue = & epicsTimerQueuePassive::create ( *this ); - } -} - -inline epicsTimer & fdManager::createTimer () -{ - this->lazyInitTimerQueue (); - return this->pTimerQueue->createTimer (); -} - -#endif // fdManagerH_included - diff --git a/src/libCom/fdmgr/fdmgr.cpp b/src/libCom/fdmgr/fdmgr.cpp deleted file mode 100644 index 342bae862..000000000 --- a/src/libCom/fdmgr/fdmgr.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// File descriptor management C++ class library -// (for multiplexing IO in a single threaded environment) -// -// Author Jeffrey O. Hill -// johill@lanl.gov -// 505 665 1831 -// -// NOTES: -// 1) the routines in this file provide backward compatibility with the original -// "C" based file descriptor manager API -// 2) This library is _not_ thread safe -// - -#include -#define epicsExportSharedSymbols -#include "locationException.h" -#include "epicsAssert.h" -#include "fdManager.h" -#include "fdmgr.h" - -static const fdRegType fdiToFdRegType[] = {fdrRead, fdrWrite, fdrException}; -static const unsigned fdiToFdRegTypeNElements = sizeof (fdiToFdRegType) / sizeof (fdiToFdRegType[0]); -const unsigned mSecPerSec = 1000u; -const unsigned uSecPerSec = 1000u * mSecPerSec; - -class fdRegForOldFdmgr : public fdReg { -public: - // - // exceptions - // - class noFunctionSpecified {}; - class doubleDelete {}; - - epicsShareFunc fdRegForOldFdmgr (const SOCKET fdIn, const fdRegType type, - const bool onceOnly, fdManager &manager, pCallBackFDMgr pFunc, void *pParam); - epicsShareFunc ~fdRegForOldFdmgr (); - -private: - pCallBackFDMgr pFunc; - void *pParam; - epicsShareFunc virtual void callBack (); - fdRegForOldFdmgr ( const fdRegForOldFdmgr & ); - fdRegForOldFdmgr & operator = ( const fdRegForOldFdmgr & ); -}; - -class oldFdmgr; - -// -// timerForOldFdmgr -// -class timerForOldFdmgr : public epicsTimerNotify, public chronIntIdRes { -public: - epicsShareFunc timerForOldFdmgr (oldFdmgr &fdmgr, double delay, pCallBackFDMgr pFunc, void *pParam); - epicsShareFunc virtual ~timerForOldFdmgr (); - - // - // exceptions - // - class noFunctionSpecified {}; - class doubleDelete {}; -private: - epicsTimer &timer; - oldFdmgr &fdmgr; - pCallBackFDMgr pFunc; - void *pParam; - unsigned id; - epicsShareFunc expireStatus expire ( const epicsTime & currentTime ); - timerForOldFdmgr ( const timerForOldFdmgr & ); - timerForOldFdmgr & operator = ( const timerForOldFdmgr & ); -}; - -class oldFdmgr : public fdManager { - friend class timerForOldFdmgr; - friend epicsShareFunc int epicsShareAPI fdmgr_clear_timeout (fdctx *pfdctx, fdmgrAlarmId id); - -public: - oldFdmgr (); - -private: - chronIntIdResTable resTbl; - oldFdmgr ( const oldFdmgr & ); - oldFdmgr & operator = ( const oldFdmgr & ); -}; - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class chronIntIdResTable ; -template class resTable; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -epicsShareFunc fdRegForOldFdmgr::fdRegForOldFdmgr - (const SOCKET fdIn, const fdRegType typeIn, - const bool onceOnlyIn, fdManager &managerIn, - pCallBackFDMgr pFuncIn, void *pParamIn) : - fdReg (fdIn, typeIn, onceOnlyIn, managerIn), - pFunc (pFuncIn), pParam (pParamIn) -{ - if (pFuncIn==NULL) { - throwWithLocation ( noFunctionSpecified () ); - } -} - -epicsShareFunc fdRegForOldFdmgr::~fdRegForOldFdmgr () -{ - if (this->pFunc==NULL) { - throwWithLocation ( doubleDelete () ); - } -} - -epicsShareFunc void fdRegForOldFdmgr::callBack () -{ - (*this->pFunc) (this->pParam); -} - -timerForOldFdmgr::timerForOldFdmgr ( oldFdmgr &fdmgrIn, - double delayIn, pCallBackFDMgr pFuncIn, void * pParamIn ) : - timer ( fdmgrIn.createTimer() ), - fdmgr ( fdmgrIn ), pFunc ( pFuncIn ), pParam( pParamIn ) -{ - if ( pFuncIn == NULL ) { - throwWithLocation ( noFunctionSpecified () ); - } - this->fdmgr.resTbl.idAssignAdd (*this); - this->timer.start ( *this, delayIn ); -} - -timerForOldFdmgr::~timerForOldFdmgr () -{ - this->fdmgr.resTbl.remove ( this->getId() ); - this->timer.destroy (); -} - -epicsTimerNotify::expireStatus timerForOldFdmgr::expire ( const epicsTime & ) -{ - (*this->pFunc) (this->pParam); - return noRestart; -} - -oldFdmgr::oldFdmgr () {} - -extern "C" epicsShareFunc fdctx * epicsShareAPI fdmgr_init (void) -{ - oldFdmgr *pfdm; - - try { - pfdm = new oldFdmgr(); - } - catch (...) - { - pfdm = NULL; - } - - return (fdctx *) pfdm; -} - -extern "C" epicsShareFunc fdmgrAlarmId epicsShareAPI fdmgr_add_timeout ( - fdctx *pfdctx, struct timeval *ptimeout, pCallBackFDMgr pFunc, void *pParam) -{ - double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast (uSecPerSec); - oldFdmgr *pfdm = static_cast (pfdctx); - timerForOldFdmgr *pTimer; - unsigned id = fdmgrNoAlarm; - - if (!pfdm) { - return fdmgrNoAlarm; - } - - while (true) { - try { - pTimer = new timerForOldFdmgr - (*pfdm, delay, pFunc, pParam); - } - catch (...) - { - pTimer = NULL; - } - if (pTimer) { - id = pTimer->getId (); - if (id!=fdmgrNoAlarm) { - break; - } - else { - delete pTimer; - } - } - else { - break; - } - } - - return id; -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_timeout (fdctx *pfdctx, fdmgrAlarmId id) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - timerForOldFdmgr *pTimer; - - try { - pTimer = pfdm->resTbl.remove (id); - } - catch (...) - { - pTimer = NULL; - } - - if (pTimer==NULL) { - return -1; - } - delete pTimer; - return 0; -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_add_callback ( - fdctx *pfdctx, SOCKET fd, enum fdi_type fdi, pCallBackFDMgr pFunc, void *pParam) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - fdRegForOldFdmgr *pfdrbc; - bool onceOnly = (fdi==fdi_write); - unsigned fdiType; - - if (pfdm==NULL) { - return -1; - } - - if (pFunc==NULL) { - return -1; - } - - if (fdi<0) { - return -1; - } - - fdiType = (unsigned) fdi; - - if (fdiType>=fdiToFdRegTypeNElements) { - return -1; - } - - try { - pfdrbc = new fdRegForOldFdmgr (fd, fdiToFdRegType[fdiType], onceOnly, *pfdm, pFunc, pParam); - } - catch (...) - { - pfdrbc = NULL; - } - - if (pfdrbc==NULL) { - return -1; - } - else { - return 0; - } -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_callback ( - fdctx *pfdctx, SOCKET fd, enum fdi_type fdi) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - fdReg *pFDR; - - if (pfdm==NULL) { - return -1; - } - - try { - pFDR = pfdm->lookUpFD (fd, fdiToFdRegType[fdi]); - } - catch (...) - { - pFDR = NULL; - } - - if (pFDR==NULL) { - return -1; - } - else { - delete pFDR; - return 0; - } -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_pend_event (fdctx *pfdctx, struct timeval *ptimeout) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - double delay = ptimeout->tv_sec + ptimeout->tv_usec / static_cast (uSecPerSec); - - try { - pfdm->process (delay); - } - catch (...) { - return -1; - } - - return 0; -} - -extern "C" epicsShareFunc int epicsShareAPI fdmgr_delete (fdctx *pfdctx) -{ - oldFdmgr *pfdm = static_cast (pfdctx); - delete pfdm; - return 0; -} - -/* - * depricated interface - */ -extern "C" epicsShareFunc int epicsShareAPI fdmgr_clear_fd (fdctx *pfdctx, SOCKET fd) -{ - return fdmgr_clear_callback(pfdctx, fd, fdi_read); -} - -/* - * depricated interface - */ -extern "C" epicsShareFunc int epicsShareAPI fdmgr_add_fd ( - fdctx *pfdctx, SOCKET fd, void (*pfunc)(void *pParam), void *param) -{ - return fdmgr_add_callback (pfdctx, fd, fdi_read, pfunc, param); -} diff --git a/src/libCom/fdmgr/fdmgr.h b/src/libCom/fdmgr/fdmgr.h deleted file mode 100644 index a227335e7..000000000 --- a/src/libCom/fdmgr/fdmgr.h +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* fdmgr.h - * - * Header file associated with a file descriptor manager - * for use with the UNIX system call select - * - * Author Jeffrey O. Hill - * hill@atdiv.lanl.gov - * 505 665 1831 - */ - -#ifndef includeFdmgrH -#define includeFdmgrH - -#include "ellLib.h" -#include "bucketLib.h" -#include "osiSock.h" -#include "epicsThread.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -enum fdi_type {fdi_read, fdi_write, fdi_excp}; -enum alarm_list_type {alt_invalid, alt_alarm, alt_expired, alt_free}; - -typedef void fdctx; -typedef void (*pCallBackFDMgr)(void *); - -/* - * C "typedef" name "alarm" was changed to "fdmgrAlarm" to avoid collisions - * with other libraries. Next the identifier was changed again to - * an unsigned integer type "fdmgrAlarmId". - * - * This "#define" is for codes that used to use a pointer to the old typedef - * "alarm" or "fdmgrAlarm" types to identify an alarm. - * - * ie the following code will allow compilation against - * all versions: - * - * #if defined (NEW_FDMGR_ALARMID) - * fdmgrAlarmId XXXX - * #elif defined (NEW_FDMGR_ALARM) - * fdmgrAlarm *XXXX; - * #else - * alarm *XXXX; - * #endif - * - * XXXX = fdmgrAlarmId fdmgr_add_timeout() - */ -typedef unsigned fdmgrAlarmId; -#define NEW_FDMGR_ALARMID - -/* - * - * Initialize a file descriptor manager session - * - */ -epicsShareFunc fdctx * epicsShareAPI fdmgr_init(void); - -/* - * Specify a function to be called with a specified parameter - * after a specified delay relative to the current time - * - * Returns fdmgrNoAlarm (zero) if alarm cant be created - */ -#define fdmgrNoAlarm 0 -epicsShareFunc fdmgrAlarmId epicsShareAPI fdmgr_add_timeout( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -struct timeval *ptimeout, /* relative delay from current time */ -pCallBackFDMgr pfunc, /* function (handler) to call */ -void *param /* first parameter passed to the func */ -); - -/* - * Clear a timeout which has not executed its function (handler) - * yet. - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_timeout( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -fdmgrAlarmId id /* alarm to delete */ -); - -/* - * - * Specify a function (handler) to be called with a specified parameter - * when a file descriptor becomes active. The parameter fdi (file - * descriptor interest) specifies the type of activity (IO) we wish - * to be informed of: read, write, or exception. For more - * info on this see the man pages for the UNIX system call select(). - * - * read and exception callbacks are permanent( ie the application's - * function (handler) continues to be called each time the - * file descriptor becomes active until fdmgr_add_callback() - * is called). - * - * write callbacks are called only once after each call to - * fdmgr_add_callback() - * - */ -epicsShareFunc int epicsShareAPI fdmgr_add_callback( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, /* file descriptor */ -enum fdi_type fdi, /* file descriptor interest type */ -pCallBackFDMgr pfunc, /* function (handler) to call */ -void *param /* first parameter passed to the func */ -); - -/* - * - * Clear nterest in a type of file descriptor activity (IO). - * - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_callback( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, /* file descriptor */ -enum fdi_type fdi /* file descriptor interest type */ -); - -/* - * - * Wait a specified delay relative from the current time for file - * descriptor activity (IO) or timeouts (timer expiration). Application - * specified functions (handlers) will not be called unless the - * application waits in this function or polls it frequently - * enough. - * - */ -epicsShareFunc int epicsShareAPI fdmgr_pend_event( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -struct timeval *ptimeout -); - - -/* - * obsolete interface - */ -epicsShareFunc int epicsShareAPI fdmgr_clear_fd( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd -); - -/* - * obsolete interface - */ -epicsShareFunc int epicsShareAPI fdmgr_add_fd( -fdctx *pfdctx, /* fd mgr ctx from fdmgr_init() */ -SOCKET fd, -pCallBackFDMgr pfunc, /* function (handler) to call */ -void *param -); - -epicsShareFunc int epicsShareAPI fdmgr_delete(fdctx *pfdctx); - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef includeFdmgrH (last line in this file) */ - diff --git a/src/libCom/flex/COPYING b/src/libCom/flex/COPYING deleted file mode 100644 index 9b01361ca..000000000 --- a/src/libCom/flex/COPYING +++ /dev/null @@ -1,38 +0,0 @@ -Flex carries the copyright used for BSD software, slightly modified -because it originated at the Lawrence Berkeley (not Livermore!) Laboratory, -which operates under a contract with the Department of Energy: - - Copyright (c) 1990 The Regents of the University of California. - All rights reserved. - - This code is derived from software contributed to Berkeley by - Vern Paxson. - - The United States Government has rights in this work pursuant - to contract no. DE-AC03-76SF00098 between the United States - Department of Energy and the University of California. - - Redistribution and use in source and binary forms are permitted - provided that: (1) source distributions retain this entire - copyright notice and comment, and (2) distributions including - binaries display the following acknowledgement: ``This product - includes software developed by the University of California, - Berkeley and its contributors'' in the documentation or other - materials provided with the distribution and in all advertising - materials mentioning features or use of this software. Neither the - name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. - -This basically says "do whatever you please with this software except -remove this notice or take advantage of the University's (or the flex -authors') name". - -Note that the "flex.skel" scanner skeleton carries no copyright notice. -You are free to do whatever you please with scanners generated using flex; -for them, you are not even bound by the above copyright. diff --git a/src/libCom/flex/Changes b/src/libCom/flex/Changes deleted file mode 100644 index 0111a1f21..000000000 --- a/src/libCom/flex/Changes +++ /dev/null @@ -1,345 +0,0 @@ -Changes between 2.3 Patch #7 (28Mar91) and 2.3 Patch #6: - - - Fixed out-of-bounds array access that caused bad tables - to be produced on machines where the bad reference happened - to yield a 1. This caused problems installing or running - flex on some Suns, in particular. - - -Changes between 2.3 Patch #6 (29Aug90) and 2.3 Patch #5: - - - Fixed a serious bug in yymore() which basically made it - completely broken. Thanks goes to Jean Christophe of - the Nethack development team for finding the problem - and passing along the fix. - - -Changes between 2.3 Patch #5 (16Aug90) and 2.3 Patch #4: - - - An up-to-date version of initscan.c so "make test" will - work after applying the previous patches - - -Changes between 2.3 Patch #4 (14Aug90) and 2.3 Patch #3: - - - Fixed bug in hexadecimal escapes which allowed only digits, - not letters, in escapes - - Fixed bug in previous "Changes" file! - - -Changes between 2.3 Patch #3 (03Aug90) and 2.3 Patch #2: - - - Correction to patch #2 for gcc compilation; thanks goes to - Paul Eggert for catching this. - - -Changes between 2.3 Patch #2 (02Aug90) and original 2.3 release: - - - Fixed (hopefully) headaches involving declaring malloc() - and free() for gcc, which defines __STDC__ but (often) doesn't - come with the standard include files such as . - Reordered #ifdef maze in the scanner skeleton in the hope of - getting the declarations right for cfront and g++, too. - - - Note that this patch supercedes patch #1 for release 2.3, - which was never announced but was available briefly for - anonymous ftp. - - -Changes between 2.3 (full) release of 28Jun90 and 2.2 (alpha) release: - - User-visible: - - - A lone <> rule (that is, one which is not qualified with - a list of start conditions) now specifies the EOF action for - *all* start conditions which haven't already had <> actions - given. To specify an end-of-file action for just the initial - state, use <>. - - - -d debug output is now contigent on the global yy_flex_debug - being set to a non-zero value, which it is by default. - - - A new macro, YY_USER_INIT, is provided for the user to specify - initialization action to be taken on the first call to the - scanner. This action is done before the scanner does its - own initialization. - - - yy_new_buffer() has been added as an alias for yy_create_buffer() - - - Comments beginning with '#' and extending to the end of the line - now work, but have been deprecated (in anticipation of making - flex recognize #line directives). - - - The funky restrictions on when semi-colons could follow the - YY_NEW_FILE and yyless macros have been removed. They now - behave identically to functions. - - - A bug in the sample redefinition of YY_INPUT in the documentation - has been corrected. - - - A bug in the sample simple tokener in the documentation has - been corrected. - - - The documentation on the incompatibilities between flex and - lex has been reordered so that the discussion of yylineno - and input() come first, as it's anticipated that these will - be the most common source of headaches. - - - Things which didn't used to be documented but now are: - - - flex interprets "^foo|bar" differently from lex. flex interprets - it as "match either a 'foo' or a 'bar', providing it comes at the - beginning of a line", whereas lex interprets it as "match either - a 'foo' at the beginning of a line, or a 'bar' anywhere". - - - flex initializes the global "yyin" on the first call to the - scanner, while lex initializes it at compile-time. - - - yy_switch_to_buffer() can be used in the yywrap() macro/routine. - - - flex scanners do not use stdio for their input, and hence when - writing an interactive scanner one must explictly call fflush() - after writing out a prompt. - - - flex scanner can be made reentrant (after a fashion) by using - "yyrestart( yyin );". This is useful for interactive scanners - which have interrupt handlers that long-jump out of the scanner. - - - a defense of why yylineno is not supported is included, along - with a suggestion on how to convert scanners which rely on it. - - - Other changes: - - - Prototypes and proper declarations of void routines have - been added to the flex source code, courtesy of Kevin B. Kenny. - - - Routines dealing with memory allocation now use void* pointers - instead of char* - see Makefile for porting implications. - - - Error-checking is now done when flex closes a file. - - - Various lint tweaks were added to reduce the number of gripes. - - - Makefile has been further parameterized to aid in porting. - - - Support for SCO Unix added. - - - Flex now sports the latest & greatest UC copyright notice - (which is only slightly different from the previous one). - - - A note has been added to flexdoc.1 mentioning work in progress - on modifying flex to generate straight C code rather than a - table-driven automaton, with an email address of whom to contact - if you are working along similar lines. - - -Changes between 2.2 Patch #3 (30Mar90) and 2.2 Patch #2: - - - fixed bug which caused -I scanners to bomb - - -Changes between 2.2 Patch #2 (27Mar90) and 2.2 Patch #1: - - - fixed bug writing past end of input buffer in yyunput() - - fixed bug detecting NUL's at the end of a buffer - - -Changes between 2.2 Patch #1 (23Mar90) and 2.2 (alpha) release: - - - Makefile fixes: definition of MAKE variable for systems - which don't have it; installation of flexdoc.1 along with - flex.1; fixed two bugs which could cause "bigtest" to fail. - - - flex.skel fix for compiling with g++. - - - README and flexdoc.1 no longer list an out-of-date BITNET address - for contacting me. - - - minor typos and formatting changes to flex.1 and flexdoc.1. - - -Changes between 2.2 (alpha) release of March '90 and previous release: - - User-visible: - - - Full user documentation now available. - - - Support for 8-bit scanners. - - - Scanners now accept NUL's. - - - A facility has been added for dealing with multiple - input buffers. - - - Two manual entries now. One which fully describes flex - (rather than just its differences from lex), and the - other for quick(er) reference. - - - A number of changes to bring flex closer into compliance - with the latest POSIX lex draft: - - %t support - flex now accepts multiple input files and concatenates - them together to form its input - previous -c (compress) flag renamed -C - do-nothing -c and -n flags added - Any indented code or code within %{}'s in section 2 is - now copied to the output - - - yyleng is now a bona fide global integer. - - - -d debug information now gives the line number of the - matched rule instead of which number rule it was from - the beginning of the file. - - - -v output now includes a summary of the flags used to generate - the scanner. - - - unput() and yyrestart() are now globally callable. - - - yyrestart() no longer closes the previous value of yyin. - - - C++ support; generated scanners can be compiled with C++ compiler. - - - Primitive -lfl library added, containing default main() - which calls yylex(). A number of routines currently living - in the scanner skeleton will probably migrate to here - in the future (in particular, yywrap() will probably cease - to be a macro and instead be a function in the -lfl library). - - - Hexadecimal (\x) escape sequences added. - - - Support for MS-DOS, VMS, and Turbo-C integrated. - - - The %used/%unused operators have been deprecated. They - may go away soon. - - - Other changes: - - - Makefile enhanced for easier testing and installation. - - The parser has been tweaked to detect some erroneous - constructions which previously were missed. - - Scanner input buffer overflow is now detected. - - Bugs with missing "const" declarations fixed. - - Out-of-date Minix/Atari patches provided. - - Scanners no longer require printf() unless FLEX_DEBUG is being used. - - A subtle input() bug has been fixed. - - Line numbers for "continued action" rules (those following - the special '|' action) are now correct. - - unput() bug fixed; had been causing problems porting flex to VMS. - - yymore() handling rewritten to fix bug with interaction - between yymore() and trailing context. - - EOF in actions now generates an error message. - - Bug involving -CFe and generating equivalence classes fixed. - - Bug which made -CF be treated as -Cf fixed. - - Support for SysV tmpnam() added. - - Unused #define's for scanner no longer generated. - - Error messages which are associated with a particular input - line are now all identified with their input line in standard - format. - - % directives which are valid to lex but not to flex are - now ignored instead of generating warnings. - - -DSYS_V flag can now also be specified -DUSG for System V - compilation. - - -Changes between 2.1 beta-test release of June '89 and previous release: - - User-visible: - - - -p flag generates a performance report to stderr. The report - consists of comments regarding features of the scanner rules - which result in slower scanners. - - - -b flag generates backtracking information to lex.backtrack. - This is a list of scanner states which require backtracking - and the characters on which they do so. By adding rules - one can remove backtracking states. If all backtracking states - are eliminated, the generated scanner will run faster. - Backtracking is not yet documented in the manual entry. - - - Variable trailing context now works, i.e., one can have - rules like "(foo)*/[ \t]*bletch". Some trailing context - patterns still cannot be properly matched and generate - error messages. These are patterns where the ending of the - first part of the rule matches the beginning of the second - part, such as "zx*/xy*", where the 'x*' matches the 'x' at - the beginning of the trailing context. Lex won't get these - patterns right either. - - - Faster scanners. - - - End-of-file rules. The special rule "<>" indicates - actions which are to be taken when an end-of-file is - encountered and yywrap() returns non-zero (i.e., indicates - no further files to process). See manual entry for example. - - - The -r (reject used) flag is gone. flex now scans the input - for occurrences of the string "REJECT" to determine if the - action is needed. It tries to be intelligent about this but - can be fooled. One can force the presence or absence of - REJECT by adding a line in the first section of the form - "%used REJECT" or "%unused REJECT". - - - yymore() has been implemented. Similarly to REJECT, flex - detects the use of yymore(), which can be overridden using - "%used" or "%unused". - - - Patterns like "x{0,3}" now work (i.e., with lower-limit == 0). - - - Removed '\^x' for ctrl-x misfeature. - - - Added '\a' and '\v' escape sequences. - - - \ now works for octal escape sequences; previously - \0 was required. - - - Better error reporting; line numbers are associated with rules. - - - yyleng is a macro; it cannot be accessed outside of the - scanner source file. - - - yytext and yyleng should not be modified within a flex action. - - - Generated scanners #define the name FLEX_SCANNER. - - - Rules are internally separated by YY_BREAK in lex.yy.c rather - than break, to allow redefinition. - - - The macro YY_USER_ACTION can be redefined to provide an action - which is always executed prior to the matched rule's action. - - - yyrestart() is a new action which can be used to restart - the scanner after it has seen an end-of-file (a "real" one, - that is, one for which yywrap() returned non-zero). It takes - a FILE* argument indicating a new file to scan and sets - things up so that a subsequent call to yylex() will start - scanning that file. - - - Internal scanner names all preceded by "yy_" - - - lex.yy.c is deleted if errors are encountered during processing. - - - Comments may be put in the first section of the input by preceding - them with '#'. - - - - Other changes: - - - Some portability-related bugs fixed, in particular for machines - with unsigned characters or sizeof( int* ) != sizeof( int ). - Also, tweaks for VMS and Microsoft C (MS-DOS), and identifiers all - trimmed to be 31 or fewer characters. Shortened file names - for dinosaur OS's. Checks for allocating > 64K memory - on 16 bit'ers. Amiga tweaks. Compiles using gcc on a Sun-3. - - Compressed and fast scanner skeletons merged. - - Skeleton header files done away with. - - Generated scanner uses prototypes and "const" for __STDC__. - - -DSV flag is now -DSYS_V for System V compilation. - - Removed all references to FTL language. - - Software now covered by BSD Copyright. - - flex will replace lex in subsequent BSD releases. diff --git a/src/libCom/flex/EPICS_READ_THIS b/src/libCom/flex/EPICS_READ_THIS deleted file mode 100644 index a1d04b97d..000000000 --- a/src/libCom/flex/EPICS_READ_THIS +++ /dev/null @@ -1,32 +0,0 @@ -This is a version of the BSD flex that has had its skeleton file munged in -order to force it to build lex programs that have all their functions and -variables defined as static. - -The file flex.skel.static is simply a copy of flex.skel that has been altered -to make all the components into static variables. - -In order to be able to actually use the lex files produced by this flavor of -flex, you must #include them into your C programs. Otherwise they will -be uncallable (all functions are static). This is typical of lex programs -that are used by yacc programs anyway. - -The scan.c file is actually the output of scan.l.DISTRIB when run through -itself, using the regular flex.skel skeleton with the -i option. - -To regenerate scan.c, make sure you have a build of a working e_flex binary -somewhere, then in this directory (not an O. build directory): - -% mv scan.l.DISTRIB scan.l -% /path/to/e_flex -Sflex.skel -8 -i scan.l -% mv lex.yy.c scan.c -% make - -Then use the new binary to make sure it can build itself: - -% O./e_flex -Sflex.skel -8 -i scan.l -% mv lex.yy.c scan.c -% make - -If that succeeds, don't forget to rename scan.l back again: - -% mv scan.l scan.l.DISTRIB diff --git a/src/libCom/flex/Flex.doc b/src/libCom/flex/Flex.doc deleted file mode 100644 index 3a37128e1..000000000 --- a/src/libCom/flex/Flex.doc +++ /dev/null @@ -1,1792 +0,0 @@ - 26 May 1990 FLEX(1) - - NAME - flex - fast lexical analyzer generator - - SYNOPSIS - flex [-bcdfinpstvFILT8 -C[efmF] -Sskeleton] [filename ...] - - DESCRIPTION - flex is a tool for generating scanners: programs which recognized lexi- - cal patterns in text. flex reads the given input files, or its standard - input if no file names are given, for a description of a scanner to gen- - erate. The description is in the form of pairs of regular expressions - and C code, called rules. flex generates as output a C source file, - lex.yy.c, which defines a routine yylex(). This file is compiled and - linked with the -lfl library to produce an executable. When the execut- - able is run, it analyzes its input for occurrences of the regular - expressions. Whenever it finds one, it executes the corresponding C - code. - - SOME SIMPLE EXAMPLES - - First some simple examples to get the flavor of how one uses flex. The - following flex input specifies a scanner which whenever it encounters - the string "username" will replace it with the user's login name: - - %% - username printf( "%s", getlogin() ); - - By default, any text not matched by a flex scanner is copied to the out- - put, so the net effect of this scanner is to copy its input file to its - output with each occurrence of "username" expanded. In this input, - there is just one rule. "username" is the pattern and the "printf" is - the action. The "%%" marks the beginning of the rules. - - Here's another simple example: - - int num_lines = 0, num_chars = 0; - - %% - \n ++num_lines; ++num_chars; - . ++num_chars; - - %% - main() - { - yylex(); - printf( "# of lines = %d, # of chars = %d\n", - num_lines, num_chars ); - } - - This scanner counts the number of characters and the number of lines in - its input (it produces no output other than the final report on the - counts). The first line declares two globals, "num_lines" and - "num_chars", which are accessible both inside yylex() and in the main() - - Version 2.3 1 - - FLEX(1) 26 May 1990 - - routine declared after the second "%%". There are two rules, one which - matches a newline ("\n") and increments both the line count and the - character count, and one which matches any character other than a new- - line (indicated by the "." regular expression). - - A somewhat more complicated example: - - /* scanner for a toy Pascal-like language */ - - %{ - /* need this for the call to atof() below */ - #include - %} - - DIGIT [0-9] - ID [a-z][a-z0-9]* - - %% - - {DIGIT}+ { - printf( "An integer: %s (%d)\n", yytext, - atoi( yytext ) ); - } - - {DIGIT}+"."{DIGIT}* { - printf( "A float: %s (%g)\n", yytext, - atof( yytext ) ); - } - - if|then|begin|end|procedure|function { - printf( "A keyword: %s\n", yytext ); - } - - {ID} printf( "An identifier: %s\n", yytext ); - - "+"|"-"|"*"|"/" printf( "An operator: %s\n", yytext ); - - "{"[^}\n]*"}" /* eat up one-line comments */ - - [ \t\n]+ /* eat up whitespace */ - - . printf( "Unrecognized character: %s\n", yytext ); - - %% - - main( argc, argv ) - int argc; - char **argv; - { - ++argv, --argc; /* skip over program name */ - if ( argc > 0 ) - yyin = fopen( argv[0], "r" ); - else - yyin = stdin; - - 2 Version 2.3 - - 26 May 1990 FLEX(1) - - yylex(); - } - - This is the beginnings of a simple scanner for a language like Pascal. - It identifies different types of tokens and reports on what it has seen. - - The details of this example will be explained in the following sections. - - FORMAT OF THE INPUT FILE - The flex input file consists of three sections, separated by a line with - just %% in it: - - definitions - %% - rules - %% - user code - - The definitions section contains declarations of simple name definitions - to simplify the scanner specification, and declarations of start condi- - tions, which are explained in a later section. - - Name definitions have the form: - - name definition - - The "name" is a word beginning with a letter or an underscore ('_') fol- - lowed by zero or more letters, digits, '_', or '-' (dash). The defini- - tion is taken to begin at the first non-white-space character following - the name and continuing to the end of the line. The definition can sub- - sequently be referred to using "{name}", which will expand to "(defini- - tion)". For example, - - DIGIT [0-9] - ID [a-z][a-z0-9]* - - defines "DIGIT" to be a regular expression which matches a single digit, - and "ID" to be a regular expression which matches a letter followed by - zero-or-more letters-or-digits. A subsequent reference to - - {DIGIT}+"."{DIGIT}* - - is identical to - - ([0-9])+"."([0-9])* - - and matches one-or-more digits followed by a '.' followed by zero-or- - more digits. - - The rules section of the flex input contains a series of rules of the - form: - - pattern action - - Version 2.3 3 - - FLEX(1) 26 May 1990 - - where the pattern must be unindented and the action must begin on the - same line. - - See below for a further description of patterns and actions. - - Finally, the user code section is simply copied to lex.yy.c verbatim. - It is used for companion routines which call or are called by the - scanner. The presence of this section is optional; if it is missing, - the second %% in the input file may be skipped, too. - - In the definitions and rules sections, any indented text or text - enclosed in %{ and %} is copied verbatim to the output (with the %{}'s - removed). The %{}'s must appear unindented on lines by themselves. - - In the rules section, any indented or %{} text appearing before the - first rule may be used to declare variables which are local to the scan- - ning routine and (after the declarations) code which is to be executed - whenever the scanning routine is entered. Other indented or %{} text in - the rule section is still copied to the output, but its meaning is not - well-defined and it may well cause compile-time errors (this feature is - present for POSIX compliance; see below for other such features). - - In the definitions section, an unindented comment (i.e., a line begin- - ning with "/*") is also copied verbatim to the output up to the next - "*/". Also, any line in the definitions section beginning with '#' is - ignored, though this style of comment is deprecated and may go away in - the future. - - PATTERNS - The patterns in the input are written using an extended set of regular - expressions. These are: - - x match the character 'x' - . any character except newline - [xyz] a "character class"; in this case, the pattern - matches either an 'x', a 'y', or a 'z' - [abj-oZ] a "character class" with a range in it; matches - an 'a', a 'b', any letter from 'j' through 'o', - or a 'Z' - [^A-Z] a "negated character class", i.e., any character - but those in the class. In this case, any - character EXCEPT an uppercase letter. - [^A-Z\n] any character EXCEPT an uppercase letter or - a newline - r* zero or more r's, where r is any regular expression - r+ one or more r's - r? zero or one r's (that is, "an optional r") - r{2,5} anywhere from two to five r's - r{2,} two or more r's - r{4} exactly 4 r's - {name} the expansion of the "name" definition - (see above) - "[xyz]\"foo" - - 4 Version 2.3 - - 26 May 1990 FLEX(1) - - the literal string: [xyz]"foo - \X if X is an 'a', 'b', 'f', 'n', 'r', 't', or 'v', - then the ANSI-C interpretation of \x. - Otherwise, a literal 'X' (used to escape - operators such as '*') - \123 the character with octal value 123 - \x2a the character with hexadecimal value 2a - (r) match an r; parentheses are used to override - precedence (see below) - - rs the regular expression r followed by the - regular expression s; called "concatenation" - - r|s either an r or an s - - r/s an r but only if it is followed by an s. The - s is not part of the matched text. This type - of pattern is called as "trailing context". - ^r an r, but only at the beginning of a line - r$ an r, but only at the end of a line. Equivalent - to "r/\n". - - r an r, but only in start condition s (see - below for discussion of start conditions) - r - same, but in any of start conditions s1, - s2, or s3 - - <> an end-of-file - <> - an end-of-file when in start condition s1 or s2 - - The regular expressions listed above are grouped according to pre- - cedence, from highest precedence at the top to lowest at the bottom. - Those grouped together have equal precedence. For example, - - foo|bar* - - is the same as - - (foo)|(ba(r*)) - - since the '*' operator has higher precedence than concatenation, and - concatenation higher than alternation ('|'). This pattern therefore - matches either the string "foo" or the string "ba" followed by zero-or- - more r's. To match "foo" or zero-or-more "bar"'s, use: - - foo|(bar)* - - Version 2.3 5 - - FLEX(1) 26 May 1990 - - and to match zero-or-more "foo"'s-or-"bar"'s: - - (foo|bar)* - - Some notes on patterns: - - - A negated character class such as the example "[^A-Z]" above will - match a newline unless "\n" (or an equivalent escape sequence) is - one of the characters explicitly present in the negated character - class (e.g., "[^A-Z\n]"). This is unlike how many other regular - expression tools treat negated character classes, but unfortunately - the inconsistency is historically entrenched. Matching newlines - means that a pattern like [^"]* can match an entire input (over- - flowing the scanner's input buffer) unless there's another quote in - the input. - - - A rule can have at most one instance of trailing context (the '/' - operator or the '$' operator). The start condition, '^', and - "<>" patterns can only occur at the beginning of a pattern, - and, as well as with '/' and '$', cannot be grouped inside - parentheses. A '^' which does not occur at the beginning of a rule - or a '$' which does not occur at the end of a rule loses its spe- - cial properties and is treated as a normal character. - - The following are illegal: - - foo/bar$ - foobar - - Note that the first of these, can be written "foo/bar\n". - - The following will result in '$' or '^' being treated as a normal - character: - - foo|(bar$) - foo|^bar - - If what's wanted is a "foo" or a bar-followed-by-a-newline, the - following could be used (the special '|' action is explained - below): - - foo | - bar$ /* action goes here */ - - A similar trick will work for matching a foo or a bar-at-the- - beginning-of-a-line. - - HOW THE INPUT IS MATCHED - When the generated scanner is run, it analyzes its input looking for - strings which match any of its patterns. If it finds more than one - match, it takes the one matching the most text (for trailing context - rules, this includes the length of the trailing part, even though it - will then be returned to the input). If it finds two or more matches of - - 6 Version 2.3 - - 26 May 1990 FLEX(1) - - the same length, the rule listed first in the flex input file is chosen. - - Once the match is determined, the text corresponding to the match - (called the token) is made available in the global character pointer - yytext, and its length in the global integer yyleng. The action - corresponding to the matched pattern is then executed (a more detailed - description of actions follows), and then the remaining input is scanned - for another match. - - If no match is found, then the default rule is executed: the next char- - acter in the input is considered matched and copied to the standard out- - put. Thus, the simplest legal flex input is: - - %% - - which generates a scanner that simply copies its input (one character at - a time) to its output. - - ACTIONS - Each pattern in a rule has a corresponding action, which can be any - arbitrary C statement. The pattern ends at the first non-escaped whi- - tespace character; the remainder of the line is its action. If the - action is empty, then when the pattern is matched the input token is - simply discarded. For example, here is the specification for a program - which deletes all occurrences of "zap me" from its input: - - %% - "zap me" - - (It will copy all other characters in the input to the output since they - will be matched by the default rule.) - - Here is a program which compresses multiple blanks and tabs down to a - single blank, and throws away whitespace found at the end of a line: - - %% - [ \t]+ putchar( ' ' ); - [ \t]+$ /* ignore this token */ - - If the action contains a '{', then the action spans till the balancing - '}' is found, and the action may cross multiple lines. flex knows about - C strings and comments and won't be fooled by braces found within them, - but also allows actions to begin with %{ and will consider the action to - be all the text up to the next %} (regardless of ordinary braces inside - the action). - - An action consisting solely of a vertical bar ('|') means "same as the - action for the next rule." See below for an illustration. - - Actions can include arbitrary C code, including return statements to - return a value to whatever routine called yylex(). Each time yylex() is - called it continues processing tokens from where it last left off until - it either reaches the end of the file or executes a return. Once it - - Version 2.3 7 - - FLEX(1) 26 May 1990 - - reaches an end-of-file, however, then any subsequent call to yylex() - will simply immediately return, unless yyrestart() is first called (see - below). - - Actions are not allowed to modify yytext or yyleng. - - There are a number of special directives which can be included within an - action: - - - ECHO copies yytext to the scanner's output. - - - BEGIN followed by the name of a start condition places the scanner - in the corresponding start condition (see below). - - - REJECT directs the scanner to proceed on to the "second best" rule - which matched the input (or a prefix of the input). The rule is - chosen as described above in "How the Input is Matched", and yytext - and yyleng set up appropriately. It may either be one which - matched as much text as the originally chosen rule but came later - in the flex input file, or one which matched less text. For exam- - ple, the following will both count the words in the input and call - the routine special() whenever "frob" is seen: - - int word_count = 0; - %% - - frob special(); REJECT; - [^ \t\n]+ ++word_count; - - Without the REJECT, any "frob"'s in the input would not be counted - as words, since the scanner normally executes only one action per - token. Multiple REJECT's are allowed, each one finding the next - best choice to the currently active rule. For example, when the - following scanner scans the token "abcd", it will write "abcdab- - caba" to the output: - - %% - a | - ab | - abc | - abcd ECHO; REJECT; - .|\n /* eat up any unmatched character */ - - (The first three rules share the fourth's action since they use the - special '|' action.) REJECT is a particularly expensive feature in - terms scanner performance; if it is used in any of the scanner's - actions it will slow down all of the scanner's matching. Further- - more, REJECT cannot be used with the -f or -F options (see below). - - Note also that unlike the other special actions, REJECT is a - branch; code immediately following it in the action will not be - executed. - - - yymore() tells the scanner that the next time it matches a rule, - - 8 Version 2.3 - - 26 May 1990 FLEX(1) - - the corresponding token should be appended onto the current value - of yytext rather than replacing it. For example, given the input - "mega-kludge" the following will write "mega-mega-kludge" to the - output: - - %% - mega- ECHO; yymore(); - kludge ECHO; - - First "mega-" is matched and echoed to the output. Then "kludge" - is matched, but the previous "mega-" is still hanging around at the - beginning of yytext so the ECHO for the "kludge" rule will actually - write "mega-kludge". The presence of yymore() in the scanner's - action entails a minor performance penalty in the scanner's match- - ing speed. - - - yyless(n) returns all but the first n characters of the current - token back to the input stream, where they will be rescanned when - the scanner looks for the next match. yytext and yyleng are - adjusted appropriately (e.g., yyleng will now be equal to n ). For - example, on the input "foobar" the following will write out - "foobarbar": - - %% - foobar ECHO; yyless(3); - [a-z]+ ECHO; - - An argument of 0 to yyless will cause the entire current input - string to be scanned again. Unless you've changed how the scanner - will subsequently process its input (using BEGIN, for example), - this will result in an endless loop. - - - unput(c) puts the character c back onto the input stream. It will - be the next character scanned. The following action will take the - current token and cause it to be rescanned enclosed in parentheses. - - { - int i; - unput( ')' ); - for ( i = yyleng - 1; i >= 0; --i ) - unput( yytext[i] ); - unput( '(' ); - } - - Note that since each unput() puts the given character back at the - beginning of the input stream, pushing back strings must be done - back-to-front. - - - input() reads the next character from the input stream. For exam- - ple, the following is one way to eat up C comments: - - %% - "/*" { - register int c; - - Version 2.3 9 - - FLEX(1) 26 May 1990 - - for ( ; ; ) - { - while ( (c = input()) != '*' && - c != EOF ) - ; /* eat up text of comment */ - - if ( c == '*' ) - { - while ( (c = input()) == '*' ) - ; - if ( c == '/' ) - break; /* found the end */ - } - - if ( c == EOF ) - { - error( "EOF in comment" ); - break; - } - } - } - - (Note that if the scanner is compiled using C++, then input() is - instead referred to as yyinput(), in order to avoid a name clash - with the C++ stream by the name of input.) - - - yyterminate() can be used in lieu of a return statement in an - action. It terminates the scanner and returns a 0 to the scanner's - caller, indicating "all done". Subsequent calls to the scanner - will immediately return unless preceded by a call to yyrestart() - (see below). By default, yyterminate() is also called when an - end-of-file is encountered. It is a macro and may be redefined. - - THE GENERATED SCANNER - The output of flex is the file lex.yy.c, which contains the scanning - routine yylex(), a number of tables used by it for matching tokens, and - a number of auxiliary routines and macros. By default, yylex() is - declared as follows: - - int yylex() - { - ... various definitions and the actions in here ... - } - - (If your environment supports function prototypes, then it will be "int - yylex( void )".) This definition may be changed by redefining the - "YY_DECL" macro. For example, you could use: - - #undef YY_DECL - #define YY_DECL float lexscan( a, b ) float a, b; - - to give the scanning routine the name lexscan, returning a float, and - taking two floats as arguments. Note that if you give arguments to the - - 10 Version 2.3 - - 26 May 1990 FLEX(1) - - scanning routine using a K&R-style/non-prototyped function declaration, - you must terminate the definition with a semi-colon (;). - - Whenever yylex() is called, it scans tokens from the global input file - yyin (which defaults to stdin). It continues until it either reaches an - end-of-file (at which point it returns the value 0) or one of its - actions executes a return statement. In the former case, when called - again the scanner will immediately return unless yyrestart() is called - to point yyin at the new input file. ( yyrestart() takes one argument, - a FILE * pointer.) In the latter case (i.e., when an action executes a - return), the scanner may then be called again and it will resume scan- - ning where it left off. - - By default (and for purposes of efficiency), the scanner uses block- - reads rather than simple getc() calls to read characters from yyin. The - nature of how it gets its input can be controlled by redefining the - YY_INPUT macro. YY_INPUT's calling sequence is - "YY_INPUT(buf,result,max_size)". Its action is to place up to max_size - characters in the character array buf and return in the integer variable - result either the number of characters read or the constant YY_NULL (0 - on Unix systems) to indicate EOF. The default YY_INPUT reads from the - global file-pointer "yyin". - - A sample redefinition of YY_INPUT (in the definitions section of the - input file): - - %{ - #undef YY_INPUT - #define YY_INPUT(buf,result,max_size) \ - { \ - int c = getchar(); \ - result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \ - } - %} - - This definition will change the input processing to occur one character - at a time. - - You also can add in things like keeping track of the input line number - this way; but don't expect your scanner to go very fast. - - When the scanner receives an end-of-file indication from YY_INPUT, it - then checks the yywrap() function. If yywrap() returns false (zero), - then it is assumed that the function has gone ahead and set up yyin to - point to another input file, and scanning continues. If it returns true - (non-zero), then the scanner terminates, returning 0 to its caller. - - The default yywrap() always returns 1. Presently, to redefine it you - must first "#undef yywrap", as it is currently implemented as a macro. - As indicated by the hedging in the previous sentence, it may be changed - to a true function in the near future. - - The scanner writes its ECHO output to the yyout global (default, - stdout), which may be redefined by the user simply by assigning it to - - Version 2.3 11 - - FLEX(1) 26 May 1990 - - some other FILE pointer. - - START CONDITIONS - flex provides a mechanism for conditionally activating rules. Any rule - whose pattern is prefixed with "" will only be active when the - scanner is in the start condition named "sc". For example, - - [^"]* { /* eat up the string body ... */ - ... - } - - will be active only when the scanner is in the "STRING" start condition, - and - - \. { /* handle an escape ... */ - ... - } - - will be active only when the current start condition is either "INI- - TIAL", "STRING", or "QUOTE". - - Start conditions are declared in the definitions (first) section of the - input using unindented lines beginning with either %s or %x followed by - a list of names. The former declares inclusive start conditions, the - latter exclusive start conditions. A start condition is activated using - the BEGIN action. Until the next BEGIN action is executed, rules with - the given start condition will be active and rules with other start con- - ditions will be inactive. If the start condition is inclusive, then - rules with no start conditions at all will also be active. If it is - exclusive, then only rules qualified with the start condition will be - active. A set of rules contingent on the same exclusive start condition - describe a scanner which is independent of any of the other rules in the - flex input. Because of this, exclusive start conditions make it easy to - specify "mini-scanners" which scan portions of the input that are syn- - tactically different from the rest (e.g., comments). - - If the distinction between inclusive and exclusive start conditions is - still a little vague, here's a simple example illustrating the connec- - tion between the two. The set of rules: - - %s example - %% - foo /* do something */ - - is equivalent to - - %x example - %% - foo /* do something */ - - The default rule (to ECHO any unmatched character) remains active in - start conditions. - - 12 Version 2.3 - - 26 May 1990 FLEX(1) - - BEGIN(0) returns to the original state where only the rules with no - start conditions are active. This state can also be referred to as the - start-condition "INITIAL", so BEGIN(INITIAL) is equivalent to BEGIN(0). - (The parentheses around the start condition name are not required but - are considered good style.) - - BEGIN actions can also be given as indented code at the beginning of the - rules section. For example, the following will cause the scanner to - enter the "SPECIAL" start condition whenever yylex() is called and the - global variable enter_special is true: - - int enter_special; - - %x SPECIAL - %% - if ( enter_special ) - BEGIN(SPECIAL); - - blahblahblah - ...more rules follow... - - To illustrate the uses of start conditions, here is a scanner which pro- - vides two different interpretations of a string like "123.456". By - default it will treat it as as three tokens, the integer "123", a dot - ('.'), and the integer "456". But if the string is preceded earlier in - the line by the string "expect-floats" it will treat it as a single - token, the floating-point number 123.456: - - %{ - #include - %} - %s expect - - %% - expect-floats BEGIN(expect); - - [0-9]+"."[0-9]+ { - printf( "found a float, = %f\n", - atof( yytext ) ); - } - \n { - /* that's the end of the line, so - * we need another "expect-number" - * before we'll recognize any more - * numbers - */ - BEGIN(INITIAL); - } - - [0-9]+ { - printf( "found an integer, = %d\n", - atoi( yytext ) ); - } - - Version 2.3 13 - - FLEX(1) 26 May 1990 - - "." printf( "found a dot\n" ); - - Here is a scanner which recognizes (and discards) C comments while main- - taining a count of the current input line. - - %x comment - %% - int line_num = 1; - - "/*" BEGIN(comment); - - [^*\n]* /* eat anything that's not a '*' */ - "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ - \n ++line_num; - "*"+"/" BEGIN(INITIAL); - - Note that start-conditions names are really integer values and can be - stored as such. Thus, the above could be extended in the following - fashion: - - %x comment foo - %% - int line_num = 1; - int comment_caller; - - "/*" { - comment_caller = INITIAL; - BEGIN(comment); - } - - ... - - "/*" { - comment_caller = foo; - BEGIN(comment); - } - - [^*\n]* /* eat anything that's not a '*' */ - "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ - \n ++line_num; - "*"+"/" BEGIN(comment_caller); - - One can then implement a "stack" of start conditions using an array of - integers. (It is likely that such stacks will become a full-fledged - flex feature in the future.) Note, though, that start conditions do not - have their own name-space; %s's and %x's declare names in the same - fashion as #define's. - - MULTIPLE INPUT BUFFERS - Some scanners (such as those which support "include" files) require - reading from several input streams. As flex scanners do a large amount - of buffering, one cannot control where the next input will be read from - by simply writing a YY_INPUT which is sensitive to the scanning context. - - 14 Version 2.3 - - 26 May 1990 FLEX(1) - - YY_INPUT is only called when the scanner reaches the end of its buffer, - which may be a long time after scanning a statement such as an "include" - which requires switching the input source. - - To negotiate these sorts of problems, flex provides a mechanism for - creating and switching between multiple input buffers. An input buffer - is created by using: - - YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) - - which takes a FILE pointer and a size and creates a buffer associated - with the given file and large enough to hold size characters (when in - doubt, use YY_BUF_SIZE for the size). It returns a YY_BUFFER_STATE han- - dle, which may then be passed to other routines: - - void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) - - switches the scanner's input buffer so subsequent tokens will come from - new_buffer. Note that yy_switch_to_buffer() may be used by yywrap() to - sets things up for continued scanning, instead of opening a new file and - pointing yyin at it. - - void yy_delete_buffer( YY_BUFFER_STATE buffer ) - - is used to reclaim the storage associated with a buffer. - - yy_new_buffer() is an alias for yy_create_buffer(), provided for compa- - tibility with the C++ use of new and delete for creating and destroying - dynamic objects. - - Finally, the YY_CURRENT_BUFFER macro returns a YY_BUFFER_STATE handle to - the current buffer. - - Here is an example of using these features for writing a scanner which - expands include files (the <> feature is discussed below): - - /* the "incl" state is used for picking up the name - * of an include file - */ - %x incl - - %{ - #define MAX_INCLUDE_DEPTH 10 - YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; - int include_stack_ptr = 0; - %} - - %% - include BEGIN(incl); - - [a-z]+ ECHO; - [^a-z\n]*\n? ECHO; - - [ \t]* /* eat the whitespace */ - - Version 2.3 15 - - FLEX(1) 26 May 1990 - - [^ \t\n]+ { /* got the include file name */ - if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) - { - fprintf( stderr, "Includes nested too deeply" ); - exit( 1 ); - } - - include_stack[include_stack_ptr++] = - YY_CURRENT_BUFFER; - - yyin = fopen( yytext, "r" ); - - if ( ! yyin ) - error( ... ); - - yy_switch_to_buffer( - yy_create_buffer( yyin, YY_BUF_SIZE ) ); - - BEGIN(INITIAL); - } - - <> { - if ( --include_stack_ptr < 0 ) - { - yyterminate(); - } - - else - yy_switch_to_buffer( - include_stack[include_stack_ptr] ); - } - - END-OF-FILE RULES - The special rule "<>" indicates actions which are to be taken when - an end-of-file is encountered and yywrap() returns non-zero (i.e., indi- - cates no further files to process). The action must finish by doing one - of four things: - - - the special YY_NEW_FILE action, if yyin has been pointed at a new - file to process; - - - a return statement; - - - the special yyterminate() action; - - - or, switching to a new buffer using yy_switch_to_buffer() as shown - in the example above. - - <> rules may not be used with other patterns; they may only be - qualified with a list of start conditions. If an unqualified <> - rule is given, it applies to all start conditions which do not already - have <> actions. To specify an <> rule for only the initial - start condition, use - - 16 Version 2.3 - - 26 May 1990 FLEX(1) - - <> - - These rules are useful for catching things like unclosed comments. An - example: - - %x quote - %% - - ...other rules for dealing with quotes... - - <> { - error( "unterminated quote" ); - yyterminate(); - } - <> { - if ( *++filelist ) - { - yyin = fopen( *filelist, "r" ); - YY_NEW_FILE; - } - else - yyterminate(); - } - - MISCELLANEOUS MACROS - The macro YY_USER_ACTION can be redefined to provide an action which is - always executed prior to the matched rule's action. For example, it - could be #define'd to call a routine to convert yytext to lower-case. - - The macro YY_USER_INIT may be redefined to provide an action which is - always executed before the first scan (and before the scanner's internal - initializations are done). For example, it could be used to call a rou- - tine to read in a data table or open a logging file. - - In the generated scanner, the actions are all gathered in one large - switch statement and separated using YY_BREAK, which may be redefined. - By default, it is simply a "break", to separate each rule's action from - the following rule's. Redefining YY_BREAK allows, for example, C++ - users to #define YY_BREAK to do nothing (while being very careful that - every rule ends with a "break" or a "return"!) to avoid suffering from - unreachable statement warnings where because a rule's action ends with - "return", the YY_BREAK is inaccessible. - - INTERFACING WITH YACC - One of the main uses of flex is as a companion to the yacc parser- - generator. yacc parsers expect to call a routine named yylex() to find - the next input token. The routine is supposed to return the type of the - next token as well as putting any associated value in the global yylval. - To use flex with yacc, one specifies the -d option to yacc to instruct - it to generate the file y.tab.h containing definitions of all the - %tokens appearing in the yacc input. This file is then included in the - - Version 2.3 17 - - FLEX(1) 26 May 1990 - - flex scanner. For example, if one of the tokens is "TOK_NUMBER", part - of the scanner might look like: - - %{ - #include "y.tab.h" - %} - - %% - - [0-9]+ yylval = atoi( yytext ); return TOK_NUMBER; - - TRANSLATION TABLE - In the name of POSIX compliance, flex supports a translation table for - mapping input characters into groups. The table is specified in the - first section, and its format looks like: - - %t - 1 abcd - 2 ABCDEFGHIJKLMNOPQRSTUVWXYZ - 52 0123456789 - 6 \t\ \n - %t - - This example specifies that the characters 'a', 'b', 'c', and 'd' are to - all be lumped into group #1, upper-case letters in group #2, digits in - group #52, tabs, blanks, and newlines into group #6, and no other char- - acters will appear in the patterns. The group numbers are actually - disregarded by flex; %t serves, though, to lump characters together. - Given the above table, for example, the pattern "a(AA)*5" is equivalent - to "d(ZQ)*0". They both say, "match any character in group #1, followed - by zero-or-more pairs of characters from group #2, followed by a charac- - ter from group #52." Thus %t provides a crude way for introducing - equivalence classes into the scanner specification. - - Note that the -i option (see below) coupled with the equivalence classes - which flex automatically generates take care of virtually all the - instances when one might consider using %t. But what the hell, it's - there if you want it. - - OPTIONS - flex has the following options: - - -b Generate backtracking information to lex.backtrack. This is a list - of scanner states which require backtracking and the input charac- - ters on which they do so. By adding rules one can remove back- - tracking states. If all backtracking states are eliminated and -f - or -F is used, the generated scanner will run faster (see the -p - flag). Only users who wish to squeeze every last cycle out of - their scanners need worry about this option. (See the section on - PERFORMANCE CONSIDERATIONS below.) - - -c is a do-nothing, deprecated option included for POSIX compliance. - - 18 Version 2.3 - - 26 May 1990 FLEX(1) - - NOTE: in previous releases of flex -c specified table-compression - options. This functionality is now given by the -C flag. To ease - the the impact of this change, when flex encounters -c, it - currently issues a warning message and assumes that -C was desired - instead. In the future this "promotion" of -c to -C will go away - in the name of full POSIX compliance (unless the POSIX meaning is - removed first). - - -d makes the generated scanner run in debug mode. Whenever a pattern - is recognized and the global yy_flex_debug is non-zero (which is - the default), the scanner will write to stderr a line of the form: - - --accepting rule at line 53 ("the matched text") - - The line number refers to the location of the rule in the file - defining the scanner (i.e., the file that was fed to flex). Mes- - sages are also generated when the scanner backtracks, accepts the - default rule, reaches the end of its input buffer (or encounters a - NUL; at this point, the two look the same as far as the scanner's - concerned), or reaches an end-of-file. - - -f specifies (take your pick) full table or fast scanner. No table - compression is done. The result is large but fast. This option is - equivalent to -Cf (see below). - - -i instructs flex to generate a case-insensitive scanner. The case of - letters given in the flex input patterns will be ignored, and - tokens in the input will be matched regardless of case. The - matched text given in yytext will have the preserved case (i.e., it - will not be folded). - - -n is another do-nothing, deprecated option included only for POSIX - compliance. - - -p generates a performance report to stderr. The report consists of - comments regarding features of the flex input file which will cause - a loss of performance in the resulting scanner. Note that the use - of REJECT and variable trailing context (see the BUGS section in - flex(1)) entails a substantial performance penalty; use of - yymore(), the ^ operator, and the -I flag entail minor performance - penalties. - - -s causes the default rule (that unmatched scanner input is echoed to - stdout) to be suppressed. If the scanner encounters input that - does not match any of its rules, it aborts with an error. This - option is useful for finding holes in a scanner's rule set. - - -t instructs flex to write the scanner it generates to standard output - instead of lex.yy.c. - - -v specifies that flex should write to stderr a summary of statistics - regarding the scanner it generates. Most of the statistics are - meaningless to the casual flex user, but the first line identifies - the version of flex, which is useful for figuring out where you - - Version 2.3 19 - - FLEX(1) 26 May 1990 - - stand with respect to patches and new releases, and the next two - lines give the date when the scanner was created and a summary of - the flags which were in effect. - - -F specifies that the fast scanner table representation should be - used. This representation is about as fast as the full table - representation (-f), and for some sets of patterns will be consid- - erably smaller (and for others, larger). In general, if the pat- - tern set contains both "keywords" and a catch-all, "identifier" - rule, such as in the set: - - "case" return TOK_CASE; - "switch" return TOK_SWITCH; - ... - "default" return TOK_DEFAULT; - [a-z]+ return TOK_ID; - - then you're better off using the full table representation. If - only the "identifier" rule is present and you then use a hash table - or some such to detect the keywords, you're better off using -F. - - This option is equivalent to -CF (see below). - - -I instructs flex to generate an interactive scanner. Normally, - scanners generated by flex always look ahead one character before - deciding that a rule has been matched. At the cost of some scan- - ning overhead, flex will generate a scanner which only looks ahead - when needed. Such scanners are called interactive because if you - want to write a scanner for an interactive system such as a command - shell, you will probably want the user's input to be terminated - with a newline, and without -I the user will have to type a charac- - ter in addition to the newline in order to have the newline recog- - nized. This leads to dreadful interactive performance. - - If all this seems to confusing, here's the general rule: if a human - will be typing in input to your scanner, use -I, otherwise don't; - if you don't care about squeezing the utmost performance from your - scanner and you don't want to make any assumptions about the input - to your scanner, use -I. - - - Note, -I cannot be used in conjunction with full or fast tables, - i.e., the -f, -F, -Cf, or -CF flags. - - -L instructs flex not to generate #line directives. Without this - option, flex peppers the generated scanner with #line directives so - error messages in the actions will be correctly located with - respect to the original flex input file, and not to the fairly - meaningless line numbers of lex.yy.c. (Unfortunately flex does not - presently generate the necessary directives to "retarget" the line - numbers for those parts of lex.yy.c which it generated. So if - there is an error in the generated code, a meaningless line number - is reported.) - - -T makes flex run in trace mode. It will generate a lot of messages - - 20 Version 2.3 - - 26 May 1990 FLEX(1) - - to stdout concerning the form of the input and the resultant non- - deterministic and deterministic finite automata. This option is - mostly for use in maintaining flex. - - -8 instructs flex to generate an 8-bit scanner, i.e., one which can - recognize 8-bit characters. On some sites, flex is installed with - this option as the default. On others, the default is 7-bit char- - acters. To see which is the case, check the verbose (-v) output - for "equivalence classes created". If the denominator of the - number shown is 128, then by default flex is generating 7-bit char- - acters. If it is 256, then the default is 8-bit characters and the - -8 flag is not required (but may be a good idea to keep the scanner - specification portable). Feeding a 7-bit scanner 8-bit characters - will result in infinite loops, bus errors, or other such fireworks, - so when in doubt, use the flag. Note that if equivalence classes - are used, 8-bit scanners take only slightly more table space than - 7-bit scanners (128 bytes, to be exact); if equivalence classes are - not used, however, then the tables may grow up to twice their 7-bit - size. - - -C[efmF] - controls the degree of table compression. - - -Ce directs flex to construct equivalence classes, i.e., sets of - characters which have identical lexical properties (for example, if - the only appearance of digits in the flex input is in the character - class "[0-9]" then the digits '0', '1', ..., '9' will all be put in - the same equivalence class). Equivalence classes usually give - dramatic reductions in the final table/object file sizes (typically - a factor of 2-5) and are pretty cheap performance-wise (one array - look-up per character scanned). - - -Cf specifies that the full scanner tables should be generated - - flex should not compress the tables by taking advantages of similar - transition functions for different states. - - -CF specifies that the alternate fast scanner representation - (described above under the -F flag) should be used. - - -Cm directs flex to construct meta-equivalence classes, which are - sets of equivalence classes (or characters, if equivalence classes - are not being used) that are commonly used together. Meta- - equivalence classes are often a big win when using compressed - tables, but they have a moderate performance impact (one or two - "if" tests and one array look-up per character scanned). - - A lone -C specifies that the scanner tables should be compressed - but neither equivalence classes nor meta-equivalence classes should - be used. - - The options -Cf or -CF and -Cm do not make sense together - there - is no opportunity for meta-equivalence classes if the table is not - being compressed. Otherwise the options may be freely mixed. - - Version 2.3 21 - - FLEX(1) 26 May 1990 - - The default setting is -Cem, which specifies that flex should gen- - erate equivalence classes and meta-equivalence classes. This set- - ting provides the highest degree of table compression. You can - trade off faster-executing scanners at the cost of larger tables - with the following generally being true: - - slowest & smallest - -Cem - -Cm - -Ce - -C - -C{f,F}e - -C{f,F} - fastest & largest - - Note that scanners with the smallest tables are usually generated - and compiled the quickest, so during development you will usually - want to use the default, maximal compression. - - -Cfe is often a good compromise between speed and size for produc- - tion scanners. - - -C options are not cumulative; whenever the flag is encountered, - the previous -C settings are forgotten. - - -Sskeleton_file - overrides the default skeleton file from which flex constructs its - scanners. You'll never need this option unless you are doing flex - maintenance or development. - - PERFORMANCE CONSIDERATIONS - The main design goal of flex is that it generate high-performance - scanners. It has been optimized for dealing well with large sets of - rules. Aside from the effects of table compression on scanner speed - outlined above, there are a number of options/actions which degrade per- - formance. These are, from most expensive to least: - - REJECT - - pattern sets that require backtracking - arbitrary trailing context - - '^' beginning-of-line operator - yymore() - - with the first three all being quite expensive and the last two being - quite cheap. - - REJECT should be avoided at all costs when performance is important. It - is a particularly expensive option. - - Getting rid of backtracking is messy and often may be an enormous amount - of work for a complicated scanner. In principal, one begins by using - the -b flag to generate a lex.backtrack file. For example, on the input - - 22 Version 2.3 - - 26 May 1990 FLEX(1) - - %% - foo return TOK_KEYWORD; - foobar return TOK_KEYWORD; - - the file looks like: - - State #6 is non-accepting - - associated rule line numbers: - 2 3 - out-transitions: [ o ] - jam-transitions: EOF [ \001-n p-\177 ] - - State #8 is non-accepting - - associated rule line numbers: - 3 - out-transitions: [ a ] - jam-transitions: EOF [ \001-` b-\177 ] - - State #9 is non-accepting - - associated rule line numbers: - 3 - out-transitions: [ r ] - jam-transitions: EOF [ \001-q s-\177 ] - - Compressed tables always backtrack. - - The first few lines tell us that there's a scanner state in which it can - make a transition on an 'o' but not on any other character, and that in - that state the currently scanned text does not match any rule. The - state occurs when trying to match the rules found at lines 2 and 3 in - the input file. If the scanner is in that state and then reads some- - thing other than an 'o', it will have to backtrack to find a rule which - is matched. With a bit of headscratching one can see that this must be - the state it's in when it has seen "fo". When this has happened, if - anything other than another 'o' is seen, the scanner will have to back - up to simply match the 'f' (by the default rule). - - The comment regarding State #8 indicates there's a problem when "foob" - has been scanned. Indeed, on any character other than a 'b', the - scanner will have to back up to accept "foo". Similarly, the comment - for State #9 concerns when "fooba" has been scanned. - - The final comment reminds us that there's no point going to all the - trouble of removing backtracking from the rules unless we're using -f or - -F, since there's no performance gain doing so with compressed scanners. - - The way to remove the backtracking is to add "error" rules: - - %% - foo return TOK_KEYWORD; - foobar return TOK_KEYWORD; - - fooba | - - Version 2.3 23 - - FLEX(1) 26 May 1990 - - foob | - fo { - /* false alarm, not really a keyword */ - return TOK_ID; - } - - Eliminating backtracking among a list of keywords can also be done using - a "catch-all" rule: - - %% - foo return TOK_KEYWORD; - foobar return TOK_KEYWORD; - - [a-z]+ return TOK_ID; - - This is usually the best solution when appropriate. - - Backtracking messages tend to cascade. With a complicated set of rules - it's not uncommon to get hundreds of messages. If one can decipher - them, though, it often only takes a dozen or so rules to eliminate the - backtracking (though it's easy to make a mistake and have an error rule - accidentally match a valid token. A possible future flex feature will - be to automatically add rules to eliminate backtracking). - - Variable trailing context (where both the leading and trailing parts do - not have a fixed length) entails almost the same performance loss as - REJECT (i.e., substantial). So when possible a rule like: - - %% - mouse|rat/(cat|dog) run(); - - is better written: - - %% - mouse/cat|dog run(); - rat/cat|dog run(); - - or as - - %% - mouse|rat/cat run(); - mouse|rat/dog run(); - - Note that here the special '|' action does not provide any savings, and - can even make things worse (see BUGS in flex(1)). - - Another area where the user can increase a scanner's performance (and - one that's easier to implement) arises from the fact that the longer the - tokens matched, the faster the scanner will run. This is because with - long tokens the processing of most input characters takes place in the - (short) inner scanning loop, and does not often have to go through the - additional work of setting up the scanning environment (e.g., yytext) - for the action. Recall the scanner for C comments: - - 24 Version 2.3 - - 26 May 1990 FLEX(1) - - %x comment - %% - int line_num = 1; - - "/*" BEGIN(comment); - - [^*\n]* - "*"+[^*/\n]* - \n ++line_num; - "*"+"/" BEGIN(INITIAL); - - This could be sped up by writing it as: - - %x comment - %% - int line_num = 1; - - "/*" BEGIN(comment); - - [^*\n]* - [^*\n]*\n ++line_num; - "*"+[^*/\n]* - "*"+[^*/\n]*\n ++line_num; - "*"+"/" BEGIN(INITIAL); - - Now instead of each newline requiring the processing of another action, - recognizing the newlines is "distributed" over the other rules to keep - the matched text as long as possible. Note that adding rules does not - slow down the scanner! The speed of the scanner is independent of the - number of rules or (modulo the considerations given at the beginning of - this section) how complicated the rules are with regard to operators - such as '*' and '|'. - - A final example in speeding up a scanner: suppose you want to scan - through a file containing identifiers and keywords, one per line and - with no other extraneous characters, and recognize all the keywords. A - natural first approach is: - - %% - asm | - auto | - break | - ... etc ... - volatile | - while /* it's a keyword */ - - .|\n /* it's not a keyword */ - - To eliminate the back-tracking, introduce a catch-all rule: - - %% - asm | - auto | - - Version 2.3 25 - - FLEX(1) 26 May 1990 - - break | - ... etc ... - volatile | - while /* it's a keyword */ - - [a-z]+ | - .|\n /* it's not a keyword */ - - Now, if it's guaranteed that there's exactly one word per line, then we - can reduce the total number of matches by a half by merging in the - recognition of newlines with that of the other tokens: - - %% - asm\n | - auto\n | - break\n | - ... etc ... - volatile\n | - while\n /* it's a keyword */ - - [a-z]+\n | - .|\n /* it's not a keyword */ - - One has to be careful here, as we have now reintroduced backtracking - into the scanner. In particular, while we know that there will never be - any characters in the input stream other than letters or newlines, flex - can't figure this out, and it will plan for possibly needing backtrack- - ing when it has scanned a token like "auto" and then the next character - is something other than a newline or a letter. Previously it would then - just match the "auto" rule and be done, but now it has no "auto" rule, - only a "auto\n" rule. To eliminate the possibility of backtracking, we - could either duplicate all rules but without final newlines, or, since - we never expect to encounter such an input and therefore don't how it's - classified, we can introduce one more catch-all rule, this one which - doesn't include a newline: - - %% - asm\n | - auto\n | - break\n | - ... etc ... - volatile\n | - while\n /* it's a keyword */ - - [a-z]+\n | - [a-z]+ | - .|\n /* it's not a keyword */ - - Compiled with -Cf, this is about as fast as one can get a flex scanner - to go for this particular problem. - - A final note: flex is slow when matching NUL's, particularly when a - token contains multiple NUL's. It's best to write rules which match - short amounts of text if it's anticipated that the text will often - - 26 Version 2.3 - - 26 May 1990 FLEX(1) - - include NUL's. - - INCOMPATIBILITIES WITH LEX AND POSIX - flex is a rewrite of the Unix lex tool (the two implementations do not - share any code, though), with some extensions and incompatibilities, - both of which are of concern to those who wish to write scanners accept- - able to either implementation. At present, the POSIX lex draft is very - close to the original lex implementation, so some of these incompatibil- - ities are also in conflict with the POSIX draft. But the intent is that - except as noted below, flex as it presently stands will ultimately be - POSIX conformant (i.e., that those areas of conflict with the POSIX - draft will be resolved in flex's favor). Please bear in mind that all - the comments which follow are with regard to the POSIX draft standard of - Summer 1989, and not the final document (or subsequent drafts); they are - included so flex users can be aware of the standardization issues and - those areas where flex may in the near future undergo changes incompati- - ble with its current definition. - - flex is fully compatible with lex with the following exceptions: - - - The undocumented lex scanner internal variable yylineno is not sup- - ported. It is difficult to support this option efficiently, since - it requires examining every character scanned and reexamining the - characters when the scanner backs up. Things get more complicated - when the end of buffer or file is reached or a NUL is scanned - (since the scan must then be restarted with the proper line number - count), or the user uses the yyless(), unput(), or REJECT actions, - or the multiple input buffer functions. - - The fix is to add rules which, upon seeing a newline, increment - yylineno. This is usually an easy process, though it can be a drag - if some of the patterns can match multiple newlines along with - other characters. - - yylineno is not part of the POSIX draft. - - - The input() routine is not redefinable, though it may be called to - read characters following whatever has been matched by a rule. If - input() encounters an end-of-file the normal yywrap() processing is - done. A ``real'' end-of-file is returned by input() as EOF. - - Input is instead controlled by redefining the YY_INPUT macro. - - The flex restriction that input() cannot be redefined is in accor- - dance with the POSIX draft, but YY_INPUT has not yet been accepted - into the draft (and probably won't; it looks like the draft will - simply not specify any way of controlling the scanner's input other - than by making an initial assignment to yyin). - - - flex scanners do not use stdio for input. Because of this, when - writing an interactive scanner one must explicitly call fflush() on - the stream associated with the terminal after writing out a prompt. - With lex such writes are automatically flushed since lex scanners - use getchar() for their input. Also, when writing interactive - - Version 2.3 27 - - FLEX(1) 26 May 1990 - - scanners with flex, the -I flag must be used. - - - flex scanners are not as reentrant as lex scanners. In particular, - if you have an interactive scanner and an interrupt handler which - long-jumps out of the scanner, and the scanner is subsequently - called again, you may get the following message: - - fatal flex scanner internal error--end of buffer missed - - To reenter the scanner, first use - - yyrestart( yyin ); - - - output() is not supported. Output from the ECHO macro is done to - the file-pointer yyout (default stdout). - - The POSIX draft mentions that an output() routine exists but - currently gives no details as to what it does. - - - lex does not support exclusive start conditions (%x), though they - are in the current POSIX draft. - - - When definitions are expanded, flex encloses them in parentheses. - With lex, the following: - - NAME [A-Z][A-Z0-9]* - %% - foo{NAME}? printf( "Found it\n" ); - %% - - will not match the string "foo" because when the macro is expanded - the rule is equivalent to "foo[A-Z][A-Z0-9]*?" and the precedence - is such that the '?' is associated with "[A-Z0-9]*". With flex, - the rule will be expanded to "foo([A-Z][A-Z0-9]*)?" and so the - string "foo" will match. Note that because of this, the ^, $, , - /, and <> operators cannot be used in a flex definition. - - The POSIX draft interpretation is the same as flex's. - - - To specify a character class which matches anything but a left - bracket (']'), in lex one can use "[^]]" but with flex one must use - "[^\]]". The latter works with lex, too. - - - The lex %r (generate a Ratfor scanner) option is not supported. It - is not part of the POSIX draft. - - - If you are providing your own yywrap() routine, you must include a - "#undef yywrap" in the definitions section (section 1). Note that - the "#undef" will have to be enclosed in %{}'s. - - The POSIX draft specifies that yywrap() is a function and this is - very unlikely to change; so flex users are warned that yywrap() is - likely to be changed to a function in the near future. - - 28 Version 2.3 - - 26 May 1990 FLEX(1) - - - After a call to unput(), yytext and yyleng are undefined until the - next token is matched. This is not the case with lex or the - present POSIX draft. - - - The precedence of the {} (numeric range) operator is different. - lex interprets "abc{1,3}" as "match one, two, or three occurrences - of 'abc'", whereas flex interprets it as "match 'ab' followed by - one, two, or three occurrences of 'c'". The latter is in agreement - with the current POSIX draft. - - - The precedence of the ^ operator is different. lex interprets - "^foo|bar" as "match either 'foo' at the beginning of a line, or - 'bar' anywhere", whereas flex interprets it as "match either 'foo' - or 'bar' if they come at the beginning of a line". The latter is - in agreement with the current POSIX draft. - - - To refer to yytext outside of the scanner source file, the correct - definition with flex is "extern char *yytext" rather than "extern - char yytext[]". This is contrary to the current POSIX draft but a - point on which flex will not be changing, as the array representa- - tion entails a serious performance penalty. It is hoped that the - POSIX draft will be emended to support the flex variety of declara- - tion (as this is a fairly painless change to require of lex users). - - - yyin is initialized by lex to be stdin; flex, on the other hand, - initializes yyin to NULL and then assigns it to stdin the first - time the scanner is called, providing yyin has not already been - assigned to a non-NULL value. The difference is subtle, but the - net effect is that with flex scanners, yyin does not have a valid - value until the scanner has been called. - - - The special table-size declarations such as %a supported by lex are - not required by flex scanners; flex ignores them. - - - The name FLEX_SCANNER is #define'd so scanners may be written for - use with either flex or lex. - - The following flex features are not included in lex or the POSIX draft - standard: - - yyterminate() - <> - YY_DECL - #line directives - %{}'s around actions - yyrestart() - comments beginning with '#' (deprecated) - multiple actions on a line - - This last feature refers to the fact that with flex you can put multiple - actions on the same line, separated with semi-colons, while with lex, - the following - - foo handle_foo(); ++num_foos_seen; - - Version 2.3 29 - - FLEX(1) 26 May 1990 - - is (rather surprisingly) truncated to - - foo handle_foo(); - - flex does not truncate the action. Actions that are not enclosed in - braces are simply terminated at the end of the line. - - DIAGNOSTICS - reject_used_but_not_detected undefined or yymore_used_but_not_detected - undefined - These errors can occur at compile time. They indicate that - the scanner uses REJECT or yymore() but that flex failed to notice the - fact, meaning that flex scanned the first two sections looking for - occurrences of these actions and failed to find any, but somehow you - snuck some in (via a #include file, for example). Make an explicit - reference to the action in your flex input file. (Note that previously - flex supported a %used/%unused mechanism for dealing with this problem; - this feature is still supported but now deprecated, and will go away - soon unless the author hears from people who can argue compellingly that - they need it.) - - flex scanner jammed - a scanner compiled with -s has encountered an - input string which wasn't matched by any of its rules. - - flex input buffer overflowed - a scanner rule matched a string long - enough to overflow the scanner's internal input buffer (16K bytes by - default - controlled by YY_BUF_SIZE in "flex.skel". Note that to rede- - fine this macro, you must first #undefine it). - - scanner requires -8 flag - Your scanner specification includes recogniz- - ing 8-bit characters and you did not specify the -8 flag (and your site - has not installed flex with -8 as the default). - - fatal flex scanner internal error--end of buffer missed - This can occur - in an scanner which is reentered after a long-jump has jumped out (or - over) the scanner's activation frame. Before reentering the scanner, - use: - - yyrestart( yyin ); - - too many %t classes! - You managed to put every single character into - its own %t class. flex requires that at least one of the classes share - characters. - - DEFICIENCIES / BUGS - See flex(1). - - SEE ALSO - - flex(1), lex(1), yacc(1), sed(1), awk(1). - - M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator - - 30 Version 2.3 - - 26 May 1990 FLEX(1) - - AUTHOR - Vern Paxson, with the help of many ideas and much inspiration from Van - Jacobson. Original version by Jef Poskanzer. The fast table represen- - tation is a partial implementation of a design done by Van Jacobson. - The implementation was done by Kevin Gong and Vern Paxson. - - Thanks to the many flex beta-testers, feedbackers, and contributors, - especially Casey Leedom, benson@odi.com, Keith Bostic, Frederic Brehm, - Nick Christopher, Jason Coughlin, Scott David Daniels, Leo Eskin, Chris - Faylor, Eric Goldman, Eric Hughes, Jeffrey R. Jones, Kevin B. Kenny, - Ronald Lamprecht, Greg Lee, Craig Leres, Mohamed el Lozy, Jim Meyering, - Marc Nozell, Esmond Pitt, Jef Poskanzer, Jim Roskind, Dave Tallman, - Frank Whaley, Ken Yap, and those whose names have slipped my marginal - mail-archiving skills but whose contributions are appreciated all the - same. - - Thanks to Keith Bostic, John Gilmore, Craig Leres, Bob Mulcahy, Rich - Salz, and Richard Stallman for help with various distribution headaches. - - Thanks to Esmond Pitt and Earle Horton for 8-bit character support; to - Benson Margulies and Fred Burke for C++ support; to Ove Ewerlid for the - basics of support for NUL's; and to Eric Hughes for the basics of sup- - port for multiple buffers. - - Work is being done on extending flex to generate scanners in which the - state machine is directly represented in C code rather than tables. - These scanners may well be substantially faster than those generated - using -f or -F. If you are working in this area and are interested in - comparing notes and seeing whether redundant work can be avoided, con- - tact Ove Ewerlid (ewerlid@mizar.DoCS.UU.SE). - - This work was primarily done when I was at the Real Time Systems Group - at the Lawrence Berkeley Laboratory in Berkeley, CA. Many thanks to all - there for the support I received. - - Send comments to: - - Vern Paxson - Computer Science Department - 4126 Upson Hall - Cornell University - Ithaca, NY 14853-7501 - - vern@cs.cornell.edu - decvax!cornell!vern - - Version 2.3 31 - -99 diff --git a/src/libCom/flex/Makefile b/src/libCom/flex/Makefile deleted file mode 100644 index 20cce5d30..000000000 --- a/src/libCom/flex/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/flex - -parse_YACCOPT = -l -d - -SKELETON_FILE = flex.skel.static - -parse_CPPFLAGS = -DDEFAULT_SKELETON_FILE=$(SKELETON_FILE) - -INC += flex.skel.static - -# flex.c is included in parse.c -e_flex_SRCS += ccl.c -e_flex_SRCS += dfa.c -e_flex_SRCS += ecs.c -e_flex_SRCS += gen.c -e_flex_SRCS += misc.c -e_flex_SRCS += nfa.c -e_flex_SRCS += sym.c -e_flex_SRCS += tblcmp.c -e_flex_SRCS += parse.c -e_flex_OBJS += epicsTempFile$(OBJ) - -PROD_HOST += e_flex - -CLEANS += parse.c parse.h diff --git a/src/libCom/flex/README b/src/libCom/flex/README deleted file mode 100644 index 210290892..000000000 --- a/src/libCom/flex/README +++ /dev/null @@ -1,76 +0,0 @@ -This is release 2.3 of flex - a full release. - -The flex distribution consists of the following files: - - README This message - - Makefile - flexdef.h - parse.y - scan.l - ccl.c - dfa.c - ecs.c flex sources - gen.c - main.c - misc.c - nfa.c - sym.c - tblcmp.c - yylex.c - - libmain.c flex library (-lfl) source - - initscan.c pre-flex'd version of scan.l - - flex.skel skeleton for generated scanners - - flexdoc.1 full user documentation - flex.1 reference documentation - - Changes Differences between this release and the previous one - - COPYING flex's copyright - - MISC/ a directory containing miscellaneous porting-related - notes (for Atari, MS-DOS, Turbo-C, and VMS) - - -Decide where you want to keep flex.skel (suggestion: /usr/local/lib), -but don't move it there yet. Edit "Makefile" and change the definition -of SKELETON_FILE to reflect the full pathname of flex.skel. - -Read the "Porting considerations" note in the Makefile and make -the necessary changes. - -To make flex for the first time, use: - - make first_flex - -which uses the pre-generated copy of the flex scanner (the scanner -itself is written using flex). - -Assuming it builds successfully, you can test it using - - make test - -The "diff" should not show any differences. - -If you're feeling adventurous, issue "make bigtest" and be prepared -to wait a while. - -Install flex using: - - make install - - -Please send problems and feedback to: - - vern@cs.cornell.edu - decvax!cornell!vern - - Vern Paxson - CS Department - 4126 Upson Hall - Cornell University - Ithaca, NY 14853-7501 diff --git a/src/libCom/flex/RULES b/src/libCom/flex/RULES deleted file mode 100644 index 65406f4c5..000000000 --- a/src/libCom/flex/RULES +++ /dev/null @@ -1,13 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -# Ensure that the lexer is built before it is needed -parse.c: $(EPICS_BASE_HOST_BIN)/antelope$(HOSTEXE) diff --git a/src/libCom/flex/ccl.c b/src/libCom/flex/ccl.c deleted file mode 100644 index 36841d9b1..000000000 --- a/src/libCom/flex/ccl.c +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* ccl - routines for character classes */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - -/* ccladd - add a single character to a ccl - * - * synopsis - * int cclp; - * int ch; - * ccladd( cclp, ch ); - */ - -void ccladd(int cclp, int ch) -{ - int ind, len, newpos, i; - - len = ccllen[cclp]; - ind = cclmap[cclp]; - - /* check to see if the character is already in the ccl */ - - for ( i = 0; i < len; ++i ) - if ( ccltbl[ind + i] == ch ) - return; - - newpos = ind + len; - - if ( newpos >= current_max_ccl_tbl_size ) - { - current_max_ccl_tbl_size += MAX_CCL_TBL_SIZE_INCREMENT; - - ++num_reallocs; - - ccltbl = reallocate_character_array( ccltbl, current_max_ccl_tbl_size ); - } - - ccllen[cclp] = len + 1; - ccltbl[newpos] = ch; - } - - -/* cclinit - make an empty ccl - * - * synopsis - * int cclinit(); - * new_ccl = cclinit(); - */ - -int cclinit(void) -{ - if ( ++lastccl >= current_maxccls ) - { - current_maxccls += MAX_CCLS_INCREMENT; - - ++num_reallocs; - - cclmap = reallocate_integer_array( cclmap, current_maxccls ); - ccllen = reallocate_integer_array( ccllen, current_maxccls ); - cclng = reallocate_integer_array( cclng, current_maxccls ); - } - - if ( lastccl == 1 ) - /* we're making the first ccl */ - cclmap[lastccl] = 0; - - else - /* the new pointer is just past the end of the last ccl. Since - * the cclmap points to the \first/ character of a ccl, adding the - * length of the ccl to the cclmap pointer will produce a cursor - * to the first free space - */ - cclmap[lastccl] = cclmap[lastccl - 1] + ccllen[lastccl - 1]; - - ccllen[lastccl] = 0; - cclng[lastccl] = 0; /* ccl's start out life un-negated */ - - return ( lastccl ); - } - - -/* cclnegate - negate a ccl - * - * synopsis - * int cclp; - * cclnegate( ccl ); - */ - -void cclnegate(int cclp) -{ - cclng[cclp] = 1; - } - - -/* list_character_set - list the members of a set of characters in CCL form - * - * synopsis - * int cset[CSIZE]; - * FILE *file; - * list_character_set( cset ); - * - * writes to the given file a character-class representation of those - * characters present in the given set. A character is present if it - * has a non-zero value in the set array. - */ - -void list_character_set(FILE *file, int cset[]) -{ - int i; - char *readable_form(); - - putc( '[', file ); - - for ( i = 0; i < csize; ++i ) - { - if ( cset[i] ) - { - int start_char = i; - - putc( ' ', file ); - - fputs( readable_form( i ), file ); - - while ( ++i < csize && cset[i] ) - ; - - if ( i - 1 > start_char ) - /* this was a run */ - fprintf( file, "-%s", readable_form( i - 1 ) ); - - putc( ' ', file ); - } - } - - putc( ']', file ); - } diff --git a/src/libCom/flex/dfa.c b/src/libCom/flex/dfa.c deleted file mode 100644 index 559a12fd1..000000000 --- a/src/libCom/flex/dfa.c +++ /dev/null @@ -1,1056 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* dfa - DFA construction routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declare functions that have forward references */ - -void dump_associated_rules (FILE*, int); -void dump_transitions (FILE*, int[]); -void sympartition (int[], int, int[], int[]); -int symfollowset (int[], int, int, int[]); - - -/* check_for_backtracking - check a DFA state for backtracking - * - * synopsis - * int ds, state[numecs]; - * check_for_backtracking( ds, state ); - * - * ds is the number of the state to check and state[] is its out-transitions, - * indexed by equivalence class, and state_rules[] is the set of rules - * associated with this state - */ - -void check_for_backtracking(int ds, int state[]) -{ - if ( (reject && ! dfaacc[ds].dfaacc_set) || ! dfaacc[ds].dfaacc_state ) - { /* state is non-accepting */ - ++num_backtracking; - - if ( backtrack_report ) - { - fprintf( backtrack_file, "State #%d is non-accepting -\n", ds ); - - /* identify the state */ - dump_associated_rules( backtrack_file, ds ); - - /* now identify it further using the out- and jam-transitions */ - dump_transitions( backtrack_file, state ); - - putc( '\n', backtrack_file ); - } - } - } - - -/* check_trailing_context - check to see if NFA state set constitutes - * "dangerous" trailing context - * - * synopsis - * int nfa_states[num_states+1], num_states; - * int accset[nacc+1], nacc; - * check_trailing_context( nfa_states, num_states, accset, nacc ); - * - * NOTES - * Trailing context is "dangerous" if both the head and the trailing - * part are of variable size \and/ there's a DFA state which contains - * both an accepting state for the head part of the rule and NFA states - * which occur after the beginning of the trailing context. - * When such a rule is matched, it's impossible to tell if having been - * in the DFA state indicates the beginning of the trailing context - * or further-along scanning of the pattern. In these cases, a warning - * message is issued. - * - * nfa_states[1 .. num_states] is the list of NFA states in the DFA. - * accset[1 .. nacc] is the list of accepting numbers for the DFA state. - */ - -void check_trailing_context(int *nfa_states, int num_states, int *accset, int nacc) -{ - int i, j; - - for ( i = 1; i <= num_states; ++i ) - { - int ns = nfa_states[i]; - int type = state_type[ns]; - int ar = assoc_rule[ns]; - - if ( type == STATE_NORMAL || rule_type[ar] != RULE_VARIABLE ) - { /* do nothing */ - } - - else if ( type == STATE_TRAILING_CONTEXT ) - { - /* potential trouble. Scan set of accepting numbers for - * the one marking the end of the "head". We assume that - * this looping will be fairly cheap since it's rare that - * an accepting number set is large. - */ - for ( j = 1; j <= nacc; ++j ) - if ( accset[j] & YY_TRAILING_HEAD_MASK ) - { - fprintf( stderr, - "%s: Dangerous trailing context in rule at line %d\n", - program_name, rule_linenum[ar] ); - return; - } - } - } - } - - -/* dump_associated_rules - list the rules associated with a DFA state - * - * synopisis - * int ds; - * FILE *file; - * dump_associated_rules( file, ds ); - * - * goes through the set of NFA states associated with the DFA and - * extracts the first MAX_ASSOC_RULES unique rules, sorts them, - * and writes a report to the given file - */ - -void dump_associated_rules(FILE *file, int ds) -{ - int i, j; - int num_associated_rules = 0; - int rule_set[MAX_ASSOC_RULES + 1]; - int *dset = dss[ds]; - int size = dfasiz[ds]; - - for ( i = 1; i <= size; ++i ) - { - int rule_num = rule_linenum[assoc_rule[dset[i]]]; - - for ( j = 1; j <= num_associated_rules; ++j ) - if ( rule_num == rule_set[j] ) - break; - - if ( j > num_associated_rules ) - { /* new rule */ - if ( num_associated_rules < MAX_ASSOC_RULES ) - rule_set[++num_associated_rules] = rule_num; - } - } - - bubble( rule_set, num_associated_rules ); - - fprintf( file, " associated rule line numbers:" ); - - for ( i = 1; i <= num_associated_rules; ++i ) - { - if ( i % 8 == 1 ) - putc( '\n', file ); - - fprintf( file, "\t%d", rule_set[i] ); - } - - putc( '\n', file ); - } - - -/* dump_transitions - list the transitions associated with a DFA state - * - * synopisis - * int state[numecs]; - * FILE *file; - * dump_transitions( file, state ); - * - * goes through the set of out-transitions and lists them in human-readable - * form (i.e., not as equivalence classes); also lists jam transitions - * (i.e., all those which are not out-transitions, plus EOF). The dump - * is done to the given file. - */ - -void dump_transitions(FILE *file, int state[]) -{ - int i, ec; - int out_char_set[CSIZE]; - - for ( i = 0; i < csize; ++i ) - { - ec = abs( ecgroup[i] ); - out_char_set[i] = state[ec]; - } - - fprintf( file, " out-transitions: " ); - - list_character_set( file, out_char_set ); - - /* now invert the members of the set to get the jam transitions */ - for ( i = 0; i < csize; ++i ) - out_char_set[i] = ! out_char_set[i]; - - fprintf( file, "\n jam-transitions: EOF " ); - - list_character_set( file, out_char_set ); - - putc( '\n', file ); - } - - -/* epsclosure - construct the epsilon closure of a set of ndfa states - * - * synopsis - * int t[current_max_dfa_size], numstates, accset[num_rules + 1], nacc; - * int hashval; - * int *epsclosure(); - * t = epsclosure( t, &numstates, accset, &nacc, &hashval ); - * - * NOTES - * the epsilon closure is the set of all states reachable by an arbitrary - * number of epsilon transitions which themselves do not have epsilon - * transitions going out, unioned with the set of states which have non-null - * accepting numbers. t is an array of size numstates of nfa state numbers. - * Upon return, t holds the epsilon closure and numstates is updated. accset - * holds a list of the accepting numbers, and the size of accset is given - * by nacc. t may be subjected to reallocation if it is not large enough - * to hold the epsilon closure. - * - * hashval is the hash value for the dfa corresponding to the state set - */ - -int *epsclosure(int *t, int *ns_addr, int accset[], int *nacc_addr, int *hv_addr) -{ - int stkpos, ns, tsp; - int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum; - int stkend, nstate; - static int did_stk_init = false, *stk; - -#define MARK_STATE(state) \ - trans1[state] = trans1[state] - MARKER_DIFFERENCE; - -#define IS_MARKED(state) (trans1[state] < 0) - -#define UNMARK_STATE(state) \ - trans1[state] = trans1[state] + MARKER_DIFFERENCE; - -#define CHECK_ACCEPT(state) \ - { \ - nfaccnum = accptnum[state]; \ - if ( nfaccnum != NIL ) \ - accset[++nacc] = nfaccnum; \ - } - -#define DO_REALLOCATION \ - { \ - current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \ - ++num_reallocs; \ - t = reallocate_integer_array( t, current_max_dfa_size ); \ - stk = reallocate_integer_array( stk, current_max_dfa_size ); \ - } \ - -#define PUT_ON_STACK(state) \ - { \ - if ( ++stkend >= current_max_dfa_size ) \ - DO_REALLOCATION \ - stk[stkend] = state; \ - MARK_STATE(state) \ - } - -#define ADD_STATE(state) \ - { \ - if ( ++numstates >= current_max_dfa_size ) \ - DO_REALLOCATION \ - t[numstates] = state; \ - hashval = hashval + state; \ - } - -#define STACK_STATE(state) \ - { \ - PUT_ON_STACK(state) \ - CHECK_ACCEPT(state) \ - if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \ - ADD_STATE(state) \ - } - - if ( ! did_stk_init ) - { - stk = allocate_integer_array( current_max_dfa_size ); - did_stk_init = true; - } - - nacc = stkend = hashval = 0; - - for ( nstate = 1; nstate <= numstates; ++nstate ) - { - ns = t[nstate]; - - /* the state could be marked if we've already pushed it onto - * the stack - */ - if ( ! IS_MARKED(ns) ) - PUT_ON_STACK(ns) - - CHECK_ACCEPT(ns) - hashval = hashval + ns; - } - - for ( stkpos = 1; stkpos <= stkend; ++stkpos ) - { - ns = stk[stkpos]; - transsym = transchar[ns]; - - if ( transsym == SYM_EPSILON ) - { - tsp = trans1[ns] + MARKER_DIFFERENCE; - - if ( tsp != NO_TRANSITION ) - { - if ( ! IS_MARKED(tsp) ) - STACK_STATE(tsp) - - tsp = trans2[ns]; - - if ( tsp != NO_TRANSITION ) - if ( ! IS_MARKED(tsp) ) - STACK_STATE(tsp) - } - } - } - - /* clear out "visit" markers */ - - for ( stkpos = 1; stkpos <= stkend; ++stkpos ) - { - if ( IS_MARKED(stk[stkpos]) ) - { - UNMARK_STATE(stk[stkpos]) - } - else - flexfatal( "consistency check failed in epsclosure()" ); - } - - *ns_addr = numstates; - *hv_addr = hashval; - *nacc_addr = nacc; - - return ( t ); - } - - -/* increase_max_dfas - increase the maximum number of DFAs */ - -void increase_max_dfas(void) -{ - current_max_dfas += MAX_DFAS_INCREMENT; - - ++num_reallocs; - - base = reallocate_integer_array( base, current_max_dfas ); - def = reallocate_integer_array( def, current_max_dfas ); - dfasiz = reallocate_integer_array( dfasiz, current_max_dfas ); - accsiz = reallocate_integer_array( accsiz, current_max_dfas ); - dhash = reallocate_integer_array( dhash, current_max_dfas ); - dss = reallocate_int_ptr_array( dss, current_max_dfas ); - dfaacc = reallocate_dfaacc_union( dfaacc, current_max_dfas ); - - if ( nultrans ) - nultrans = reallocate_integer_array( nultrans, current_max_dfas ); - } - - -/* ntod - convert an ndfa to a dfa - * - * synopsis - * ntod(); - * - * creates the dfa corresponding to the ndfa we've constructed. the - * dfa starts out in state #1. - */ - -void ntod(void) -{ - int *accset, ds, nacc, newds; - int sym, hashval, numstates, dsize; - int num_full_table_rows = 0; /* used only for -f */ - int *nset, *dset; - int targptr, totaltrans, i, comstate, comfreq, targ; - int *epsclosure(int *t, int *ns_addr, int *accset, int *nacc_addr, int *hv_addr); - int snstods(int *sns, int numstates, int *accset, int nacc, int hashval, int *newds_addr); - int symlist[CSIZE + 1]; - int num_start_states; - int todo_head, todo_next; - - /* note that the following are indexed by *equivalence classes* - * and not by characters. Since equivalence classes are indexed - * beginning with 1, even if the scanner accepts NUL's, this - * means that (since every character is potentially in its own - * equivalence class) these arrays must have room for indices - * from 1 to CSIZE, so their size must be CSIZE + 1. - */ - int duplist[CSIZE + 1], state[CSIZE + 1]; - int targfreq[CSIZE + 1], targstate[CSIZE + 1]; - - /* this is so find_table_space(...) will know where to start looking in - * chk/nxt for unused records for space to put in the state - */ - if ( fullspd ) - firstfree = 0; - - accset = allocate_integer_array( num_rules + 1 ); - nset = allocate_integer_array( current_max_dfa_size ); - - /* the "todo" queue is represented by the head, which is the DFA - * state currently being processed, and the "next", which is the - * next DFA state number available (not in use). We depend on the - * fact that snstods() returns DFA's \in increasing order/, and thus - * need only know the bounds of the dfas to be processed. - */ - todo_head = todo_next = 0; - - for ( i = 0; i <= csize; ++i ) - { - duplist[i] = NIL; - symlist[i] = false; - } - - for ( i = 0; i <= num_rules; ++i ) - accset[i] = NIL; - - if ( trace ) - { - dumpnfa( scset[1] ); - fputs( "\n\nDFA Dump:\n\n", stderr ); - } - - inittbl(); - - /* check to see whether we should build a separate table for transitions - * on NUL characters. We don't do this for full-speed (-F) scanners, - * since for them we don't have a simple state number lying around with - * which to index the table. We also don't bother doing it for scanners - * unless (1) NUL is in its own equivalence class (indicated by a - * positive value of ecgroup[NUL]), (2) NUL's equilvalence class is - * the last equivalence class, and (3) the number of equivalence classes - * is the same as the number of characters. This latter case comes about - * when useecs is false or when its true but every character still - * manages to land in its own class (unlikely, but it's cheap to check - * for). If all these things are true then the character code needed - * to represent NUL's equivalence class for indexing the tables is - * going to take one more bit than the number of characters, and therefore - * we won't be assured of being able to fit it into a YY_CHAR variable. - * This rules out storing the transitions in a compressed table, since - * the code for interpreting them uses a YY_CHAR variable (perhaps it - * should just use an integer, though; this is worth pondering ... ###). - * - * Finally, for full tables, we want the number of entries in the - * table to be a power of two so the array references go fast (it - * will just take a shift to compute the major index). If encoding - * NUL's transitions in the table will spoil this, we give it its - * own table (note that this will be the case if we're not using - * equivalence classes). - */ - - /* note that the test for ecgroup[0] == numecs below accomplishes - * both (1) and (2) above - */ - if ( ! fullspd && ecgroup[0] == numecs ) - { /* NUL is alone in its equivalence class, which is the last one */ - int use_NUL_table = (numecs == csize); - - if ( fulltbl && ! use_NUL_table ) - { /* we still may want to use the table if numecs is a power of 2 */ - int power_of_two; - - for ( power_of_two = 1; power_of_two <= csize; power_of_two *= 2 ) - if ( numecs == power_of_two ) - { - use_NUL_table = true; - break; - } - } - - if ( use_NUL_table ) - nultrans = allocate_integer_array( current_max_dfas ); - /* from now on, nultrans != nil indicates that we're - * saving null transitions for later, separate encoding - */ - } - - - if ( fullspd ) - { - for ( i = 0; i <= numecs; ++i ) - state[i] = 0; - place_state( state, 0, 0 ); - } - - else if ( fulltbl ) - { - if ( nultrans ) - /* we won't be including NUL's transitions in the table, - * so build it for entries from 0 .. numecs - 1 - */ - num_full_table_rows = numecs; - - else - /* take into account the fact that we'll be including - * the NUL entries in the transition table. Build it - * from 0 .. numecs. - */ - num_full_table_rows = numecs + 1; - - /* declare it "short" because it's a real long-shot that that - * won't be large enough. - */ - printf( "static short int yy_nxt[][%d] =\n {\n", - /* '}' so vi doesn't get too confused */ - num_full_table_rows ); - - /* generate 0 entries for state #0 */ - for ( i = 0; i < num_full_table_rows; ++i ) - mk2data( 0 ); - - /* force ',' and dataflush() next call to mk2data */ - datapos = NUMDATAITEMS; - - /* force extra blank line next dataflush() */ - dataline = NUMDATALINES; - } - - /* create the first states */ - - num_start_states = lastsc * 2; - - for ( i = 1; i <= num_start_states; ++i ) - { - numstates = 1; - - /* for each start condition, make one state for the case when - * we're at the beginning of the line (the '%' operator) and - * one for the case when we're not - */ - if ( i % 2 == 1 ) - nset[numstates] = scset[(i / 2) + 1]; - else - nset[numstates] = mkbranch( scbol[i / 2], scset[i / 2] ); - - nset = epsclosure( nset, &numstates, accset, &nacc, &hashval ); - - if ( snstods( nset, numstates, accset, nacc, hashval, &ds ) ) - { - numas += nacc; - totnst += numstates; - ++todo_next; - - if ( variable_trailing_context_rules && nacc > 0 ) - check_trailing_context( nset, numstates, accset, nacc ); - } - } - - if ( ! fullspd ) - { - if ( ! snstods( nset, 0, accset, 0, 0, &end_of_buffer_state ) ) - flexfatal( "could not create unique end-of-buffer state" ); - - ++numas; - ++num_start_states; - ++todo_next; - } - - while ( todo_head < todo_next ) - { - targptr = 0; - totaltrans = 0; - - for ( i = 1; i <= numecs; ++i ) - state[i] = 0; - - ds = ++todo_head; - - dset = dss[ds]; - dsize = dfasiz[ds]; - - if ( trace ) - fprintf( stderr, "state # %d:\n", ds ); - - sympartition( dset, dsize, symlist, duplist ); - - for ( sym = 1; sym <= numecs; ++sym ) - { - if ( symlist[sym] ) - { - symlist[sym] = 0; - - if ( duplist[sym] == NIL ) - { /* symbol has unique out-transitions */ - numstates = symfollowset( dset, dsize, sym, nset ); - nset = epsclosure( nset, &numstates, accset, - &nacc, &hashval ); - - if ( snstods( nset, numstates, accset, - nacc, hashval, &newds ) ) - { - totnst = totnst + numstates; - ++todo_next; - numas += nacc; - - if ( variable_trailing_context_rules && nacc > 0 ) - check_trailing_context( nset, numstates, - accset, nacc ); - } - - state[sym] = newds; - - if ( trace ) - fprintf( stderr, "\t%d\t%d\n", sym, newds ); - - targfreq[++targptr] = 1; - targstate[targptr] = newds; - ++numuniq; - } - - else - { - /* sym's equivalence class has the same transitions - * as duplist(sym)'s equivalence class - */ - targ = state[duplist[sym]]; - state[sym] = targ; - - if ( trace ) - fprintf( stderr, "\t%d\t%d\n", sym, targ ); - - /* update frequency count for destination state */ - - i = 0; - while ( targstate[++i] != targ ) - ; - - ++targfreq[i]; - ++numdup; - } - - ++totaltrans; - duplist[sym] = NIL; - } - } - - numsnpairs = numsnpairs + totaltrans; - - if ( caseins && ! useecs ) - { - int j; - - for ( i = 'A', j = 'a'; i <= 'Z'; ++i, ++j ) - state[i] = state[j]; - } - - if ( ds > num_start_states ) - check_for_backtracking( ds, state ); - - if ( nultrans ) - { - nultrans[ds] = state[NUL_ec]; - state[NUL_ec] = 0; /* remove transition */ - } - - if ( fulltbl ) - { - /* supply array's 0-element */ - if ( ds == end_of_buffer_state ) - mk2data( -end_of_buffer_state ); - else - mk2data( end_of_buffer_state ); - - for ( i = 1; i < num_full_table_rows; ++i ) - /* jams are marked by negative of state number */ - mk2data( state[i] ? state[i] : -ds ); - - /* force ',' and dataflush() next call to mk2data */ - datapos = NUMDATAITEMS; - - /* force extra blank line next dataflush() */ - dataline = NUMDATALINES; - } - - else if ( fullspd ) - place_state( state, ds, totaltrans ); - - else if ( ds == end_of_buffer_state ) - /* special case this state to make sure it does what it's - * supposed to, i.e., jam on end-of-buffer - */ - stack1( ds, 0, 0, JAMSTATE ); - - else /* normal, compressed state */ - { - /* determine which destination state is the most common, and - * how many transitions to it there are - */ - - comfreq = 0; - comstate = 0; - - for ( i = 1; i <= targptr; ++i ) - if ( targfreq[i] > comfreq ) - { - comfreq = targfreq[i]; - comstate = targstate[i]; - } - - bldtbl( state, ds, totaltrans, comstate, comfreq ); - } - } - - if ( fulltbl ) - dataend(); - - else if ( ! fullspd ) - { - cmptmps(); /* create compressed template entries */ - - /* create tables for all the states with only one out-transition */ - while ( onesp > 0 ) - { - mk1tbl( onestate[onesp], onesym[onesp], onenext[onesp], - onedef[onesp] ); - --onesp; - } - - mkdeftbl(); - } - } - - -/* snstods - converts a set of ndfa states into a dfa state - * - * synopsis - * int sns[numstates], numstates, newds, accset[num_rules + 1], nacc, hashval; - * int snstods(); - * is_new_state = snstods( sns, numstates, accset, nacc, hashval, &newds ); - * - * on return, the dfa state number is in newds. - */ - -int snstods(int sns[], int numstates, int accset[], int nacc, int hashval, int *newds_addr) -{ - int didsort = 0; - int i, j; - int newds, *oldsns; - - for ( i = 1; i <= lastdfa; ++i ) - if ( hashval == dhash[i] ) - { - if ( numstates == dfasiz[i] ) - { - oldsns = dss[i]; - - if ( ! didsort ) - { - /* we sort the states in sns so we can compare it to - * oldsns quickly. we use bubble because there probably - * aren't very many states - */ - bubble( sns, numstates ); - didsort = 1; - } - - for ( j = 1; j <= numstates; ++j ) - if ( sns[j] != oldsns[j] ) - break; - - if ( j > numstates ) - { - ++dfaeql; - *newds_addr = i; - return ( 0 ); - } - - ++hshcol; - } - - else - ++hshsave; - } - - /* make a new dfa */ - - if ( ++lastdfa >= current_max_dfas ) - increase_max_dfas(); - - newds = lastdfa; - - dss[newds] = (int *) malloc( (unsigned) ((numstates + 1) * sizeof( int )) ); - - if ( ! dss[newds] ) - flexfatal( "dynamic memory failure in snstods()" ); - - /* if we haven't already sorted the states in sns, we do so now, so that - * future comparisons with it can be made quickly - */ - - if ( ! didsort ) - bubble( sns, numstates ); - - for ( i = 1; i <= numstates; ++i ) - dss[newds][i] = sns[i]; - - dfasiz[newds] = numstates; - dhash[newds] = hashval; - - if ( nacc == 0 ) - { - if ( reject ) - dfaacc[newds].dfaacc_set = (int *) 0; - else - dfaacc[newds].dfaacc_state = 0; - - accsiz[newds] = 0; - } - - else if ( reject ) - { - /* we sort the accepting set in increasing order so the disambiguating - * rule that the first rule listed is considered match in the event of - * ties will work. We use a bubble sort since the list is probably - * quite small. - */ - - bubble( accset, nacc ); - - dfaacc[newds].dfaacc_set = - (int *) malloc( (unsigned) ((nacc + 1) * sizeof( int )) ); - - if ( ! dfaacc[newds].dfaacc_set ) - flexfatal( "dynamic memory failure in snstods()" ); - - /* save the accepting set for later */ - for ( i = 1; i <= nacc; ++i ) - dfaacc[newds].dfaacc_set[i] = accset[i]; - - accsiz[newds] = nacc; - } - - else - { /* find lowest numbered rule so the disambiguating rule will work */ - j = num_rules + 1; - - for ( i = 1; i <= nacc; ++i ) - if ( accset[i] < j ) - j = accset[i]; - - dfaacc[newds].dfaacc_state = j; - } - - *newds_addr = newds; - - return ( 1 ); - } - - -/* symfollowset - follow the symbol transitions one step - * - * synopsis - * int ds[current_max_dfa_size], dsize, transsym; - * int nset[current_max_dfa_size], numstates; - * numstates = symfollowset( ds, dsize, transsym, nset ); - */ - -int symfollowset(int ds[], int dsize, int transsym, int nset[]) -{ - int ns, tsp, sym, i, j, lenccl, ch, numstates; - int ccllist; - - numstates = 0; - - for ( i = 1; i <= dsize; ++i ) - { /* for each nfa state ns in the state set of ds */ - ns = ds[i]; - sym = transchar[ns]; - tsp = trans1[ns]; - - if ( sym < 0 ) - { /* it's a character class */ - sym = -sym; - ccllist = cclmap[sym]; - lenccl = ccllen[sym]; - - if ( cclng[sym] ) - { - for ( j = 0; j < lenccl; ++j ) - { /* loop through negated character class */ - ch = ccltbl[ccllist + j]; - - if ( ch == 0 ) - ch = NUL_ec; - - if ( ch > transsym ) - break; /* transsym isn't in negated ccl */ - - else if ( ch == transsym ) - /* next 2 */ goto bottom; - } - - /* didn't find transsym in ccl */ - nset[++numstates] = tsp; - } - - else - for ( j = 0; j < lenccl; ++j ) - { - ch = ccltbl[ccllist + j]; - - if ( ch == 0 ) - ch = NUL_ec; - - if ( ch > transsym ) - break; - - else if ( ch == transsym ) - { - nset[++numstates] = tsp; - break; - } - } - } - - else if ( sym >= 'A' && sym <= 'Z' && caseins ) - flexfatal( "consistency check failed in symfollowset" ); - - else if ( sym == SYM_EPSILON ) - { /* do nothing */ - } - - else if ( abs( ecgroup[sym] ) == transsym ) - nset[++numstates] = tsp; - -bottom: - ; - } - - return ( numstates ); - } - - -/* sympartition - partition characters with same out-transitions - * - * synopsis - * integer ds[current_max_dfa_size], numstates, duplist[numecs]; - * symlist[numecs]; - * sympartition( ds, numstates, symlist, duplist ); - */ - -void sympartition(int ds[], int numstates, int symlist[], int duplist[]) -{ - int tch, i, j, k, ns, dupfwd[CSIZE + 1], lenccl, cclp, ich; - - /* partitioning is done by creating equivalence classes for those - * characters which have out-transitions from the given state. Thus - * we are really creating equivalence classes of equivalence classes. - */ - - for ( i = 1; i <= numecs; ++i ) - { /* initialize equivalence class list */ - duplist[i] = i - 1; - dupfwd[i] = i + 1; - } - - duplist[1] = NIL; - dupfwd[numecs] = NIL; - - for ( i = 1; i <= numstates; ++i ) - { - ns = ds[i]; - tch = transchar[ns]; - - if ( tch != SYM_EPSILON ) - { - if ( tch < -lastccl || tch > csize ) - { - if ( tch > csize && tch <= CSIZE ) - flexerror( "scanner requires -8 flag" ); - - else - flexfatal( - "bad transition character detected in sympartition()" ); - } - - if ( tch >= 0 ) - { /* character transition */ - /* abs() needed for fake %t ec's */ - int ec = abs( ecgroup[tch] ); - - mkechar( ec, dupfwd, duplist ); - symlist[ec] = 1; - } - - else - { /* character class */ - tch = -tch; - - lenccl = ccllen[tch]; - cclp = cclmap[tch]; - mkeccl( ccltbl + cclp, lenccl, dupfwd, duplist, numecs, - NUL_ec ); - - if ( cclng[tch] ) - { - j = 0; - - for ( k = 0; k < lenccl; ++k ) - { - ich = ccltbl[cclp + k]; - - if ( ich == 0 ) - ich = NUL_ec; - - for ( ++j; j < ich; ++j ) - symlist[j] = 1; - } - - for ( ++j; j <= numecs; ++j ) - symlist[j] = 1; - } - - else - for ( k = 0; k < lenccl; ++k ) - { - ich = ccltbl[cclp + k]; - - if ( ich == 0 ) - ich = NUL_ec; - - symlist[ich] = 1; - } - } - } - } - } diff --git a/src/libCom/flex/ecs.c b/src/libCom/flex/ecs.c deleted file mode 100644 index 416ea601a..000000000 --- a/src/libCom/flex/ecs.c +++ /dev/null @@ -1,342 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* ecs - equivalence class routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - -/* ccl2ecl - convert character classes to set of equivalence classes - * - * synopsis - * ccl2ecl(); - */ - -void ccl2ecl(void) -{ - int i, ich, newlen, cclp, ccls, cclmec; - - for ( i = 1; i <= lastccl; ++i ) - { - /* we loop through each character class, and for each character - * in the class, add the character's equivalence class to the - * new "character" class we are creating. Thus when we are all - * done, character classes will really consist of collections - * of equivalence classes - */ - - newlen = 0; - cclp = cclmap[i]; - - for ( ccls = 0; ccls < ccllen[i]; ++ccls ) - { - ich = ccltbl[cclp + ccls]; - cclmec = ecgroup[ich]; - - if ( xlation && cclmec < 0 ) - { - /* special hack--if we're doing %t tables then it's - * possible that no representative of this character's - * equivalence class is in the ccl. So waiting till - * we see the representative would be disastrous. Instead, - * we add this character's equivalence class anyway, if it's - * not already present. - */ - int j; - - /* this loop makes this whole process n^2; but we don't - * really care about %t performance anyway - */ - for ( j = 0; j < newlen; ++j ) - if ( ccltbl[cclp + j] == -cclmec ) - break; - - if ( j >= newlen ) - { /* no representative yet, add this one in */ - ccltbl[cclp + newlen] = -cclmec; - ++newlen; - } - } - - else if ( cclmec > 0 ) - { - ccltbl[cclp + newlen] = cclmec; - ++newlen; - } - } - - ccllen[i] = newlen; - } - } - - -/* cre8ecs - associate equivalence class numbers with class members - * - * synopsis - * int cre8ecs(); - * number of classes = cre8ecs( fwd, bck, num ); - * - * fwd is the forward linked-list of equivalence class members. bck - * is the backward linked-list, and num is the number of class members. - * - * Returned is the number of classes. - */ - -int cre8ecs(int fwd[], int bck[], int num) -{ - int i, j, numcl; - - numcl = 0; - - /* create equivalence class numbers. From now on, abs( bck(x) ) - * is the equivalence class number for object x. If bck(x) - * is positive, then x is the representative of its equivalence - * class. - */ - for ( i = 1; i <= num; ++i ) - if ( bck[i] == NIL ) - { - bck[i] = ++numcl; - for ( j = fwd[i]; j != NIL; j = fwd[j] ) - bck[j] = -numcl; - } - - return ( numcl ); - } - - -/* ecs_from_xlation - associate equivalence class numbers using %t table - * - * synopsis - * numecs = ecs_from_xlation( ecmap ); - * - * Upon return, ecmap will map each character code to its equivalence - * class. The mapping will be positive if the character is the representative - * of its class, negative otherwise. - * - * Returns the number of equivalence classes used. - */ - -int ecs_from_xlation(int ecmap[]) -{ - int i; - int nul_is_alone = false; - int did_default_xlation_class = false; - - if ( xlation[0] != 0 ) - { - /* if NUL shares its translation with other characters, choose one - * of the other characters as the representative for the equivalence - * class. This allows a cheap test later to see whether we can - * do away with NUL's equivalence class. - */ - for ( i = 1; i < csize; ++i ) - if ( xlation[i] == -xlation[0] ) - { - xlation[i] = xlation[0]; - ecmap[0] = -xlation[0]; - break; - } - - if ( i >= csize ) - /* didn't find a companion character--remember this fact */ - nul_is_alone = true; - } - - for ( i = 1; i < csize; ++i ) - if ( xlation[i] == 0 ) - { - if ( did_default_xlation_class ) - ecmap[i] = -num_xlations; - - else - { - /* make an equivalence class for those characters not - * specified in the %t table - */ - ++num_xlations; - ecmap[i] = num_xlations; - did_default_xlation_class = true; - } - } - - else - ecmap[i] = xlation[i]; - - if ( nul_is_alone ) - /* force NUL's equivalence class to be the last one */ - { - ++num_xlations; - ecmap[0] = num_xlations; - - /* there's actually a bug here: if someone is fanatic enough to - * put every character in its own translation class, then right - * now we just promoted NUL's equivalence class to be csize + 1; - * we can handle NUL's class number being == csize (by instead - * putting it in its own table), but we can't handle some *other* - * character having to be put in its own table, too. So in - * this case we bail out. - */ - if ( num_xlations > csize ) - flexfatal( "too many %t classes!" ); - } - - return num_xlations; - } - - -/* mkeccl - update equivalence classes based on character class xtions - * - * synopsis - * Char ccls[]; - * int lenccl, fwd[llsiz], bck[llsiz], llsiz, NUL_mapping; - * mkeccl( ccls, lenccl, fwd, bck, llsiz, NUL_mapping ); - * - * where ccls contains the elements of the character class, lenccl is the - * number of elements in the ccl, fwd is the forward link-list of equivalent - * characters, bck is the backward link-list, and llsiz size of the link-list - * - * NUL_mapping is the value which NUL (0) should be mapped to. - */ - -void mkeccl(unsigned char ccls[], int lenccl, int fwd[], int bck[], int llsiz, int NUL_mapping) -{ - int cclp, oldec, newec; - int cclm, i, j; - static unsigned char cclflags[CSIZE]; /* initialized to all '\0' */ - - /* note that it doesn't matter whether or not the character class is - * negated. The same results will be obtained in either case. - */ - - cclp = 0; - - while ( cclp < lenccl ) - { - cclm = ccls[cclp]; - - if ( NUL_mapping && cclm == 0 ) - cclm = NUL_mapping; - - oldec = bck[cclm]; - newec = cclm; - - j = cclp + 1; - - for ( i = fwd[cclm]; i != NIL && i <= llsiz; i = fwd[i] ) - { /* look for the symbol in the character class */ - for ( ; j < lenccl; ++j ) - { - int ccl_char; - - if ( NUL_mapping && ccls[j] == 0 ) - ccl_char = NUL_mapping; - else - ccl_char = ccls[j]; - - if ( ccl_char > i ) - break; - - if ( ccl_char == i && ! cclflags[j] ) - { - /* we found an old companion of cclm in the ccl. - * link it into the new equivalence class and flag it as - * having been processed - */ - - bck[i] = newec; - fwd[newec] = i; - newec = i; - cclflags[j] = 1; /* set flag so we don't reprocess */ - - /* get next equivalence class member */ - /* continue 2 */ - goto next_pt; - } - } - - /* symbol isn't in character class. Put it in the old equivalence - * class - */ - - bck[i] = oldec; - - if ( oldec != NIL ) - fwd[oldec] = i; - - oldec = i; -next_pt: - ; - } - - if ( bck[cclm] != NIL || oldec != bck[cclm] ) - { - bck[cclm] = NIL; - fwd[oldec] = NIL; - } - - fwd[newec] = NIL; - - /* find next ccl member to process */ - - for ( ++cclp; cclflags[cclp] && cclp < lenccl; ++cclp ) - { - /* reset "doesn't need processing" flag */ - cclflags[cclp] = 0; - } - } - } - - -/* mkechar - create equivalence class for single character - * - * synopsis - * int tch, fwd[], bck[]; - * mkechar( tch, fwd, bck ); - */ - -void mkechar(int tch, int fwd[], int bck[]) -{ - /* if until now the character has been a proper subset of - * an equivalence class, break it away to create a new ec - */ - - if ( fwd[tch] != NIL ) - bck[fwd[tch]] = bck[tch]; - - if ( bck[tch] != NIL ) - fwd[bck[tch]] = fwd[tch]; - - fwd[tch] = NIL; - bck[tch] = NIL; - } diff --git a/src/libCom/flex/flex.c b/src/libCom/flex/flex.c deleted file mode 100644 index 196f4e4cc..000000000 --- a/src/libCom/flex/flex.c +++ /dev/null @@ -1,748 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* flex - tool to generate fast lexical analyzers */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#define ENQUOTE(path) #path - -#ifndef lint -char copyright[] = -"@(#) Copyright (c) 1990 The Regents of the University of California.\n\ - All rights reserved.\n"; -#endif /* not lint */ - - -#define epicsExportSharedSymbols -#include "epicsTempFile.h" -#undef epicsExportSharedSymbols - -static char flex_version[] = "2.3"; - - -/* declare functions that have forward references */ - -void flexinit (int, char**); -void readin (void); -void set_up_initial_allocations (void); - - -/* these globals are all defined and commented in flexdef.h */ -int printstats, syntaxerror, eofseen, ddebug, trace, spprdflt; -int interactive, caseins, useecs, fulltbl, usemecs; -int fullspd, gen_line_dirs, performance_report, backtrack_report, csize; -int yymore_used, reject, real_reject, continued_action; -int yymore_really_used, reject_really_used; -int datapos, dataline, linenum; -FILE *skelfile = NULL; -char *infilename = NULL; -int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; -int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; -int current_mns, num_rules, current_max_rules, lastnfa; -int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; -int *accptnum, *assoc_rule, *state_type, *rule_type, *rule_linenum; -int current_state_type; -int variable_trailing_context_rules; -int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; -int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; -int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1]; -int tecbck[CSIZE + 1]; -int *xlation = (int *) 0; -int num_xlations; -int lastsc, current_max_scs, *scset, *scbol, *scxclu, *sceof, *actvsc; -char **scname; -int current_max_dfa_size, current_max_xpairs; -int current_max_template_xpairs, current_max_dfas; -int lastdfa, *nxt, *chk, *tnxt; -int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; -union dfaacc_union *dfaacc; -int *accsiz, *dhash, numas; -int numsnpairs, jambase, jamstate; -int lastccl, current_maxccls, *cclmap, *ccllen, *cclng, cclreuse; -int current_max_ccl_tbl_size; -Char *ccltbl; -char *starttime, *endtime, nmstr[MAXLINE]; -int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; -int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; -int num_backtracking, bol_needed; -FILE *temp_action_file; -FILE *backtrack_file; -int end_of_buffer_state; -char action_file_name[256>L_tmpnam?256:L_tmpnam]; -char **input_files; -int num_input_files; -char *program_name; - -#ifndef SHORT_FILE_NAMES -static char *outfile = "lex.yy.c"; -#else -static char *outfile = "lexyy.c"; -#endif -static int outfile_created = 0; -static int use_stdout; -static char *skelname = NULL; - - -int main(int argc, char *argv[]) -{ - flexinit( argc, argv ); - - readin(); - - if ( syntaxerror ) - flexend( 1 ); - - if ( yymore_really_used == REALLY_USED ) - yymore_used = true; - else if ( yymore_really_used == REALLY_NOT_USED ) - yymore_used = false; - - if ( reject_really_used == REALLY_USED ) - reject = true; - else if ( reject_really_used == REALLY_NOT_USED ) - reject = false; - - if ( performance_report ) - { - if ( interactive ) - fprintf( stderr, - "-I (interactive) entails a minor performance penalty\n" ); - - if ( yymore_used ) - fprintf( stderr, "yymore() entails a minor performance penalty\n" ); - - if ( reject ) - fprintf( stderr, "REJECT entails a large performance penalty\n" ); - - if ( variable_trailing_context_rules ) - fprintf( stderr, -"Variable trailing context rules entail a large performance penalty\n" ); - } - - if ( reject ) - real_reject = true; - - if ( variable_trailing_context_rules ) - reject = true; - - if ( (fulltbl || fullspd) && reject ) - { - if ( real_reject ) - flexerror( "REJECT cannot be used with -f or -F" ); - else - flexerror( - "variable trailing context rules cannot be used with -f or -F" ); - } - - ntod(); - - /* generate the C state transition tables from the DFA */ - make_tables(); - - /* note, flexend does not return. It exits with its argument as status. */ - - flexend( 0 ); - - /*NOTREACHED*/ -} - - -/* flexend - terminate flex - * - * synopsis - * int status; - * flexend( status ); - * - * status is exit status. - * - * note - * This routine does not return. - */ - -void flexend(int status) -{ - int tblsiz; - char *flex_gettime(); - - if ( skelfile != NULL ) - { - if ( ferror( skelfile ) ) - flexfatal( "error occurred when writing skeleton file" ); - - else if ( fclose( skelfile ) ) - flexfatal( "error occurred when closing skeleton file" ); - } - - if ( temp_action_file ) - { - if ( ferror( temp_action_file ) ) - flexfatal( "error occurred when writing temporary action file" ); - - else if ( fclose( temp_action_file ) ) - flexfatal( "error occurred when closing temporary action file" ); - - else if ( unlink( action_file_name ) ) - flexfatal( "error occurred when deleting temporary action file" ); - } - - if ( status != 0 && outfile_created ) - { - if ( ferror( stdout ) ) - flexfatal( "error occurred when writing output file" ); - - else if ( fclose( stdout ) ) - flexfatal( "error occurred when closing output file" ); - - else if ( unlink( outfile ) ) - flexfatal( "error occurred when deleting output file" ); - } - - if ( backtrack_report && backtrack_file ) - { - if ( num_backtracking == 0 ) - fprintf( backtrack_file, "No backtracking.\n" ); - else if ( fullspd || fulltbl ) - fprintf( backtrack_file, - "%d backtracking (non-accepting) states.\n", - num_backtracking ); - else - fprintf( backtrack_file, "Compressed tables always backtrack.\n" ); - - if ( ferror( backtrack_file ) ) - flexfatal( "error occurred when writing backtracking file" ); - - else if ( fclose( backtrack_file ) ) - flexfatal( "error occurred when closing backtracking file" ); - } - - if ( printstats ) - { - endtime = flex_gettime(); - - fprintf( stderr, "%s version %s usage statistics:\n", program_name, - flex_version ); - fprintf( stderr, " started at %s, finished at %s\n", - starttime, endtime ); - - fprintf( stderr, " scanner options: -" ); - - if ( backtrack_report ) - putc( 'b', stderr ); - if ( ddebug ) - putc( 'd', stderr ); - if ( interactive ) - putc( 'I', stderr ); - if ( caseins ) - putc( 'i', stderr ); - if ( ! gen_line_dirs ) - putc( 'L', stderr ); - if ( performance_report ) - putc( 'p', stderr ); - if ( spprdflt ) - putc( 's', stderr ); - if ( use_stdout ) - putc( 't', stderr ); - if ( trace ) - putc( 'T', stderr ); - if ( printstats ) - putc( 'v', stderr ); /* always true! */ - if ( csize == 256 ) - putc( '8', stderr ); - - fprintf( stderr, " -C" ); - - if ( fulltbl ) - putc( 'f', stderr ); - if ( fullspd ) - putc( 'F', stderr ); - if ( useecs ) - putc( 'e', stderr ); - if ( usemecs ) - putc( 'm', stderr ); - - if ( strcmp( skelname, ENQUOTE(DEFAULT_SKELETON_FILE) ) ) - fprintf( stderr, " -S%s", skelname ); - - putc( '\n', stderr ); - - fprintf( stderr, " %d/%d NFA states\n", lastnfa, current_mns ); - fprintf( stderr, " %d/%d DFA states (%d words)\n", lastdfa, - current_max_dfas, totnst ); - fprintf( stderr, - " %d rules\n", num_rules - 1 /* - 1 for def. rule */ ); - - if ( num_backtracking == 0 ) - fprintf( stderr, " No backtracking\n" ); - else if ( fullspd || fulltbl ) - fprintf( stderr, " %d backtracking (non-accepting) states\n", - num_backtracking ); - else - fprintf( stderr, " compressed tables always backtrack\n" ); - - if ( bol_needed ) - fprintf( stderr, " Beginning-of-line patterns used\n" ); - - fprintf( stderr, " %d/%d start conditions\n", lastsc, - current_max_scs ); - fprintf( stderr, " %d epsilon states, %d double epsilon states\n", - numeps, eps2 ); - - if ( lastccl == 0 ) - fprintf( stderr, " no character classes\n" ); - else - fprintf( stderr, - " %d/%d character classes needed %d/%d words of storage, %d reused\n", - lastccl, current_maxccls, - cclmap[lastccl] + ccllen[lastccl], - current_max_ccl_tbl_size, cclreuse ); - - fprintf( stderr, " %d state/nextstate pairs created\n", numsnpairs ); - fprintf( stderr, " %d/%d unique/duplicate transitions\n", - numuniq, numdup ); - - if ( fulltbl ) - { - tblsiz = lastdfa * numecs; - fprintf( stderr, " %d table entries\n", tblsiz ); - } - - else - { - tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; - - fprintf( stderr, " %d/%d base-def entries created\n", - lastdfa + numtemps, current_max_dfas ); - fprintf( stderr, " %d/%d (peak %d) nxt-chk entries created\n", - tblend, current_max_xpairs, peakpairs ); - fprintf( stderr, - " %d/%d (peak %d) template nxt-chk entries created\n", - numtemps * nummecs, current_max_template_xpairs, - numtemps * numecs ); - fprintf( stderr, " %d empty table entries\n", nummt ); - fprintf( stderr, " %d protos created\n", numprots ); - fprintf( stderr, " %d templates created, %d uses\n", - numtemps, tmpuses ); - } - - if ( useecs ) - { - tblsiz = tblsiz + csize; - fprintf( stderr, " %d/%d equivalence classes created\n", - numecs, csize ); - } - - if ( usemecs ) - { - tblsiz = tblsiz + numecs; - fprintf( stderr, " %d/%d meta-equivalence classes created\n", - nummecs, csize ); - } - - fprintf( stderr, " %d (%d saved) hash collisions, %d DFAs equal\n", - hshcol, hshsave, dfaeql ); - fprintf( stderr, " %d sets of reallocations needed\n", num_reallocs ); - fprintf( stderr, " %d total table entries needed\n", tblsiz ); - } - - exit( status ); -} - - -/* flexinit - initialize flex - * - * synopsis - * int argc; - * char **argv; - * flexinit( argc, argv ); - */ - -void flexinit(int argc, char **argv) -{ - int i, sawcmpflag; - char *arg, *flex_gettime(), *mktemp(); - - printstats = syntaxerror = trace = spprdflt = interactive = caseins = false; - backtrack_report = performance_report = ddebug = fulltbl = fullspd = false; - yymore_used = continued_action = reject = false; - yymore_really_used = reject_really_used = false; - gen_line_dirs = usemecs = useecs = true; - - sawcmpflag = false; - use_stdout = false; - - csize = DEFAULT_CSIZE; - - program_name = argv[0]; - - /* read flags */ - for ( --argc, ++argv; argc ; --argc, ++argv ) - { - if ( argv[0][0] != '-' || argv[0][1] == '\0' ) - break; - - arg = argv[0]; - - for ( i = 1; arg[i] != '\0'; ++i ) - switch ( arg[i] ) - { - case 'b': - backtrack_report = true; - break; - - case 'c': - fprintf( stderr, - "%s: Assuming use of deprecated -c flag is really intended to be -C\n", - program_name ); - - /* fall through */ - - case 'C': - if ( i != 1 ) - flexerror( "-C flag must be given separately" ); - - if ( ! sawcmpflag ) - { - useecs = false; - usemecs = false; - fulltbl = false; - sawcmpflag = true; - } - - for ( ++i; arg[i] != '\0'; ++i ) - switch ( arg[i] ) - { - case 'e': - useecs = true; - break; - - case 'F': - fullspd = true; - break; - - case 'f': - fulltbl = true; - break; - - case 'm': - usemecs = true; - break; - - default: - lerrif( "unknown -C option '%c'", - (int) arg[i] ); - break; - } - - goto get_next_arg; - - case 'd': - ddebug = true; - break; - - case 'f': - useecs = usemecs = false; - fulltbl = true; - break; - - case 'F': - useecs = usemecs = false; - fullspd = true; - break; - - case 'I': - interactive = true; - break; - - case 'i': - caseins = true; - break; - - case 'L': - gen_line_dirs = false; - break; - - case 'n': - /* stupid do-nothing deprecated option */ - break; - - case 'p': - performance_report = true; - break; - - case 'S': - if ( i != 1 ) - flexerror( "-S flag must be given separately" ); - - skelname = arg + i + 1; - goto get_next_arg; - - case 's': - spprdflt = true; - break; - - case 't': - use_stdout = true; - break; - - case 'T': - trace = true; - break; - - case 'v': - printstats = true; - break; - - case '8': - csize = CSIZE; - break; - - default: - lerrif( "unknown flag '%c'", (int) arg[i] ); - break; - } - -get_next_arg: /* used by -C and -S flags in lieu of a "continue 2" control */ - ; - } - - if ( (fulltbl || fullspd) && usemecs ) - flexerror( "full table and -Cm don't make sense together" ); - - if ( (fulltbl || fullspd) && interactive ) - flexerror( "full table and -I are (currently) incompatible" ); - - if ( fulltbl && fullspd ) - flexerror( "full table and -F are mutually exclusive" ); - - if ( ! skelname ) - { - static char skeleton_name_storage[400]; - - skelname = skeleton_name_storage; - (void) strcpy( skelname, ENQUOTE(DEFAULT_SKELETON_FILE) ); - } - - if ( ! use_stdout ) - { - FILE *prev_stdout = freopen( outfile, "w", stdout ); - - if ( prev_stdout == NULL ) - lerrsf( "could not create %s", outfile ); - - outfile_created = 1; - } - - num_input_files = argc; - input_files = argv; - set_input_file( num_input_files > 0 ? input_files[0] : NULL ); - - if ( backtrack_report ) - { -#ifndef SHORT_FILE_NAMES - backtrack_file = fopen( "lex.backtrack", "w" ); -#else - backtrack_file = fopen( "lex.bck", "w" ); -#endif - - if ( backtrack_file == NULL ) - flexerror( "could not create lex.backtrack" ); - } - - else - backtrack_file = NULL; - - - lastccl = 0; - lastsc = 0; - - /* initialize the statistics */ - starttime = flex_gettime(); - - if ( (skelfile = fopen( skelname, "r" )) == NULL ) - lerrsf( "can't open skeleton file %s", skelname ); - - epicsTempName ( action_file_name, sizeof ( action_file_name ) ); - if ( action_file_name[0] == '\0' ) - { - lerrsf( "can't create temporary file name", "" ); - } - - if ( ( temp_action_file = fopen ( action_file_name, "w" ) ) == NULL ) - lerrsf( "can't open temporary action file %s", action_file_name ); - - lastdfa = lastnfa = num_rules = numas = numsnpairs = tmpuses = 0; - numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0; - numuniq = numdup = hshsave = eofseen = datapos = dataline = 0; - num_backtracking = onesp = numprots = 0; - variable_trailing_context_rules = bol_needed = false; - - linenum = sectnum = 1; - firstprot = NIL; - - /* used in mkprot() so that the first proto goes in slot 1 - * of the proto queue - */ - lastprot = 1; - - if ( useecs ) - { /* set up doubly-linked equivalence classes */ - /* We loop all the way up to csize, since ecgroup[csize] is the - * position used for NUL characters - */ - ecgroup[1] = NIL; - - for ( i = 2; i <= csize; ++i ) - { - ecgroup[i] = i - 1; - nextecm[i - 1] = i; - } - - nextecm[csize] = NIL; - } - - else - { /* put everything in its own equivalence class */ - for ( i = 1; i <= csize; ++i ) - { - ecgroup[i] = i; - nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ - } - } - - set_up_initial_allocations(); -} - - -/* readin - read in the rules section of the input file(s) - * - * synopsis - * readin(); - */ - -void readin(void) -{ - skelout(); - - if ( ddebug ) - puts( "#define FLEX_DEBUG" ); - - if ( csize == 256 ) - puts( "#define YY_CHAR unsigned char" ); - else - puts( "#define YY_CHAR char" ); - - line_directive_out( stdout ); - - if ( yyparse() ) - { - pinpoint_message( "fatal parse error" ); - flexend( 1 ); - } - - if ( xlation ) - { - numecs = ecs_from_xlation( ecgroup ); - useecs = true; - } - - else if ( useecs ) - numecs = cre8ecs( nextecm, ecgroup, csize ); - - else - numecs = csize; - - /* now map the equivalence class for NUL to its expected place */ - ecgroup[0] = ecgroup[csize]; - NUL_ec = abs( ecgroup[0] ); - - if ( useecs ) - ccl2ecl(); -} - - - -/* set_up_initial_allocations - allocate memory for internal tables */ - -void set_up_initial_allocations(void) -{ - current_mns = INITIAL_MNS; - firstst = allocate_integer_array( current_mns ); - lastst = allocate_integer_array( current_mns ); - finalst = allocate_integer_array( current_mns ); - transchar = allocate_integer_array( current_mns ); - trans1 = allocate_integer_array( current_mns ); - trans2 = allocate_integer_array( current_mns ); - accptnum = allocate_integer_array( current_mns ); - assoc_rule = allocate_integer_array( current_mns ); - state_type = allocate_integer_array( current_mns ); - - current_max_rules = INITIAL_MAX_RULES; - rule_type = allocate_integer_array( current_max_rules ); - rule_linenum = allocate_integer_array( current_max_rules ); - - current_max_scs = INITIAL_MAX_SCS; - scset = allocate_integer_array( current_max_scs ); - scbol = allocate_integer_array( current_max_scs ); - scxclu = allocate_integer_array( current_max_scs ); - sceof = allocate_integer_array( current_max_scs ); - scname = allocate_char_ptr_array( current_max_scs ); - actvsc = allocate_integer_array( current_max_scs ); - - current_maxccls = INITIAL_MAX_CCLS; - cclmap = allocate_integer_array( current_maxccls ); - ccllen = allocate_integer_array( current_maxccls ); - cclng = allocate_integer_array( current_maxccls ); - - current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE; - ccltbl = allocate_character_array( current_max_ccl_tbl_size ); - - current_max_dfa_size = INITIAL_MAX_DFA_SIZE; - - current_max_xpairs = INITIAL_MAX_XPAIRS; - nxt = allocate_integer_array( current_max_xpairs ); - chk = allocate_integer_array( current_max_xpairs ); - - current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS; - tnxt = allocate_integer_array( current_max_template_xpairs ); - - current_max_dfas = INITIAL_MAX_DFAS; - base = allocate_integer_array( current_max_dfas ); - def = allocate_integer_array( current_max_dfas ); - dfasiz = allocate_integer_array( current_max_dfas ); - accsiz = allocate_integer_array( current_max_dfas ); - dhash = allocate_integer_array( current_max_dfas ); - dss = allocate_int_ptr_array( current_max_dfas ); - dfaacc = allocate_dfaacc_union( current_max_dfas ); - - nultrans = (int *) 0; -} diff --git a/src/libCom/flex/flex.html b/src/libCom/flex/flex.html deleted file mode 100644 index 3b6ae9b80..000000000 --- a/src/libCom/flex/flex.html +++ /dev/null @@ -1,611 +0,0 @@ - - -
-
-
-
-

NAME

-     flex - fast lexical analyzer generator
-
-
-
-

SYNOPSIS

-     flex [-bcdfinpstvFILT8 -C[efmF] -Sskeleton] [filename ...]
-
-
-
-

DESCRIPTION

-     flex is a  tool  for  generating  scanners:  programs  which
-     recognized  lexical  patterns in text.  flex reads the given
-     input files, or its standard input  if  no  file  names  are
-     given,  for  a  description  of  a scanner to generate.  The
-     description is in the form of pairs of  regular  expressions
-     and  C  code,  called  rules.  flex  generates as output a C
-     source file, lex.yy.c, which defines a routine yylex(). This
-     file is compiled and linked with the -lfl library to produce
-     an executable.  When the executable is run, it analyzes  its
-     input  for occurrences of the regular expressions.  Whenever
-     it finds one, it executes the corresponding C code.
-
-     For full documentation, see flexdoc(1). This manual entry is
-     intended for use as a quick reference.
-
-
-
-

OPTIONS

-     flex has the following options:
-
-     -b   Generate  backtracking  information  to  lex.backtrack.
-          This  is  a  list of scanner states which require back-
-          tracking and the input characters on which they do  so.
-          By adding rules one can remove backtracking states.  If
-          all backtracking states are eliminated and -f or -F  is
-          used, the generated scanner will run faster.
-
-     -c   is a do-nothing, deprecated option included  for  POSIX
-          compliance.
-
-          NOTE: in previous releases of flex -c specified  table-
-          compression  options.   This functionality is now given
-          by the -C flag.  To ease the the impact of this change,
-          when  flex encounters -c, it currently issues a warning
-          message and assumes that -C was  desired  instead.   In
-          the future this "promotion" of -c to -C will go away in
-          the name of full POSIX  compliance  (unless  the  POSIX
-          meaning is removed first).
-
-     -d   makes the generated scanner run in debug  mode.   When-
-          ever   a   pattern   is   recognized   and  the  global
-          yy_flex_debug is non-zero (which is the  default),  the
-          scanner will write to stderr a line of the form:
-
-              --accepting rule at line 53 ("the matched text")
-
-          The line number refers to the location of the  rule  in
-          the  file defining the scanner (i.e., the file that was
-          fed to flex).  Messages are  also  generated  when  the
-          scanner  backtracks,  accepts the default rule, reaches
-          the end of its input buffer (or encounters a  NUL;  the
-          two  look  the same as far as the scanner's concerned),
-          or reaches an end-of-file.
-
-     -f   specifies (take your pick) full table or fast  scanner.
-          No  table compression is done.  The result is large but
-          fast.  This option is equivalent to -Cf (see below).
-
-     -i   instructs flex to generate a case-insensitive  scanner.
-          The  case  of  letters given in the flex input patterns
-          will be ignored,  and  tokens  in  the  input  will  be
-          matched  regardless of case.  The matched text given in
-          yytext will have the preserved case (i.e., it will  not
-          be folded).
-
-     -n   is another do-nothing, deprecated option included  only
-          for POSIX compliance.
-
-     -p   generates a performance report to stderr.   The  report
-          consists  of  comments  regarding  features of the flex
-          input file which will cause a loss  of  performance  in
-          the resulting scanner.
-
-     -s   causes the default rule (that unmatched  scanner  input
-          is  echoed to stdout) to be suppressed.  If the scanner
-          encounters input that does not match any of its  rules,
-          it aborts with an error.
-
-     -t   instructs flex to write the  scanner  it  generates  to
-          standard output instead of lex.yy.c.
-
-     -v   specifies that flex should write to stderr a summary of
-          statistics regarding the scanner it generates.
-
-     -F   specifies that the fast  scanner  table  representation
-          should  be  used.  This representation is about as fast
-          as the full table representation  (-f),  and  for  some
-          sets  of patterns will be considerably smaller (and for
-          others, larger).  See flexdoc(1) for details.
-
-          This option is equivalent to -CF (see below).
-
-     -I   instructs flex to generate an interactive scanner, that
-          is, a scanner which stops immediately rather than look-
-          ing ahead if it knows that the currently  scanned  text
-          cannot  be  part  of a longer rule's match.  Again, see
-          flexdoc(1) for details.
-
-          Note, -I cannot be used in  conjunction  with  full  or
-          fast tables, i.e., the -f, -F, -Cf, or -CF flags.
-
-     -L   instructs flex not  to  generate  #line  directives  in
-          lex.yy.c. The default is to generate such directives so
-          error messages in the actions will be correctly located
-          with  respect  to the original flex input file, and not
-          to the fairly meaningless line numbers of lex.yy.c.
-
-     -T   makes flex run in trace mode.  It will generate  a  lot
-          of  messages to stdout concerning the form of the input
-          and the resultant non-deterministic  and  deterministic
-          finite  automata.   This  option  is  mostly for use in
-          maintaining flex.
-
-     -8   instructs flex to generate an 8-bit scanner.   On  some
-          sites,  this is the default.  On others, the default is
-          7-bit characters.  To see which is the case, check  the
-          verbose  (-v) output for "equivalence classes created".
-          If the denominator of the number shown is 128, then  by
-          default  flex is generating 7-bit characters.  If it is
-          256, then the default is 8-bit characters.
-
-     -C[efmF]
-          controls the degree of table compression.
-
-          -Ce directs  flex  to  construct  equivalence  classes,
-          i.e.,  sets  of characters which have identical lexical
-          properties.  Equivalence classes usually give  dramatic
-          reductions  in the final table/object file sizes (typi-
-          cally  a  factor  of  2-5)   and   are   pretty   cheap
-          performance-wise   (one  array  look-up  per  character
-          scanned).
-
-          -Cf specifies that the full scanner  tables  should  be
-          generated - flex should not compress the tables by tak-
-          ing advantages of similar transition functions for dif-
-          ferent states.
-
-          -CF specifies that the alternate fast scanner represen-
-          tation (described in flexdoc(1)) should be used.
-
-          -Cm directs flex to construct meta-equivalence classes,
-          which  are  sets of equivalence classes (or characters,
-          if equivalence classes are not  being  used)  that  are
-          commonly  used  together.  Meta-equivalence classes are
-          often a big win when using compressed tables, but  they
-          have  a  moderate  performance  impact (one or two "if"
-          tests and one array look-up per character scanned).
-
-          A lone -C specifies that the scanner tables  should  be
-          compressed  but  neither  equivalence classes nor meta-
-          equivalence classes should be used.
-          The options -Cf or  -CF  and  -Cm  do  not  make  sense
-          together - there is no opportunity for meta-equivalence
-          classes if the table is not being  compressed.   Other-
-          wise the options may be freely mixed.
-
-          The default setting is -Cem, which specifies that  flex
-          should   generate   equivalence   classes   and   meta-
-          equivalence classes.  This setting provides the highest
-          degree   of  table  compression.   You  can  trade  off
-          faster-executing scanners at the cost of larger  tables
-          with the following generally being true:
-
-              slowest & smallest
-                    -Cem
-                    -Cm
-                    -Ce
-                    -C
-                    -C{f,F}e
-                    -C{f,F}
-              fastest & largest
-
-
-          -C options are not cumulative;  whenever  the  flag  is
-          encountered, the previous -C settings are forgotten.
-
-     -Sskeleton_file
-          overrides the default skeleton  file  from  which  flex
-          constructs its scanners.  You'll never need this option
-          unless you are doing flex maintenance or development.
-
-
-
-

SUMMARY OF FLEX REGULAR EXPRESSIONS

-     The patterns in the input are written using an extended  set
-     of regular expressions.  These are:
-
-         x          match the character 'x'
-         .          any character except newline
-         [xyz]      a "character class"; in this case, the pattern
-                      matches either an 'x', a 'y', or a 'z'
-         [abj-oZ]   a "character class" with a range in it; matches
-                      an 'a', a 'b', any letter from 'j' through 'o',
-                      or a 'Z'
-         [^A-Z]     a "negated character class", i.e., any character
-                      but those in the class.  In this case, any
-                      character EXCEPT an uppercase letter.
-         [^A-Z\n]   any character EXCEPT an uppercase letter or
-                      a newline
-         r*         zero or more r's, where r is any regular expression
-         r+         one or more r's
-         r?         zero or one r's (that is, "an optional r")
-         r{2,5}     anywhere from two to five r's
-         r{2,}      two or more r's
-         r{4}       exactly 4 r's
-         {name}     the expansion of the "name" definition
-                    (see above)
-         "[xyz]\"foo"
-                    the literal string: [xyz]"foo
-         \X         if X is an 'a', 'b', 'f', 'n', 'r', 't', or 'v',
-                      then the ANSI-C interpretation of \x.
-                      Otherwise, a literal 'X' (used to escape
-                      operators such as '*')
-         \123       the character with octal value 123
-         \x2a       the character with hexadecimal value 2a
-         (r)        match an r; parentheses are used to override
-                      precedence (see below)
-
-
-         rs         the regular expression r followed by the
-                      regular expression s; called "concatenation"
-
-
-         r|s        either an r or an s
-
-
-         r/s        an r but only if it is followed by an s.  The
-                      s is not part of the matched text.  This type
-                      of pattern is called as "trailing context".
-         ^r         an r, but only at the beginning of a line
-         r$         an r, but only at the end of a line.  Equivalent
-                      to "r/\n".
-
-
-         <s>r       an r, but only in start condition s (see
-                    below for discussion of start conditions)
-         <s1,s2,s3>r
-                    same, but in any of start conditions s1,
-                    s2, or s3
-
-
-         <<EOF>>    an end-of-file
-         <s1,s2><<EOF>>
-                    an end-of-file when in start condition s1 or s2
-
-     The regular expressions listed above are  grouped  according
-     to  precedence, from highest precedence at the top to lowest
-     at the bottom.   Those  grouped  together  have  equal  pre-
-     cedence.
-
-     Some notes on patterns:
-
-     -    Negated character classes match  newlines  unless  "\n"
-          (or  an equivalent escape sequence) is one of the char-
-          acters explicitly  present  in  the  negated  character
-          class (e.g., "[^A-Z\n]").
-
-     -    A rule can have at most one instance of  trailing  con-
-          text (the '/' operator or the '$' operator).  The start
-          condition, '^', and "<<EOF>>" patterns can  only  occur
-          at the beginning of a pattern, and, as well as with '/'
-          and '$', cannot be  grouped  inside  parentheses.   The
-          following are all illegal:
-
-              foo/bar$
-              foo|(bar$)
-              foo|^bar
-              <sc1>foo<sc2>bar
-
-
-
-
-

SUMMARY OF SPECIAL ACTIONS

-     In addition to arbitrary C code, the following can appear in
-     actions:
-
-     -    ECHO copies yytext to the scanner's output.
-
-     -    BEGIN followed by the name of a start condition  places
-          the scanner in the corresponding start condition.
-
-     -    REJECT directs the scanner to proceed on to the "second
-          best"  rule which matched the input (or a prefix of the
-          input).  yytext and yyleng are  set  up  appropriately.
-          Note that REJECT is a particularly expensive feature in
-          terms scanner performance; if it is used in any of  the
-          scanner's   actions  it  will  slow  down  all  of  the
-          scanner's matching.  Furthermore, REJECT cannot be used
-          with the -f or -F options.
-
-          Note also that unlike the other special actions, REJECT
-          is  a  branch;  code  immediately  following  it in the
-          action will not be executed.
-
-     -    yymore() tells  the  scanner  that  the  next  time  it
-          matches  a  rule,  the  corresponding  token  should be
-          appended onto the current value of yytext  rather  than
-          replacing it.
-
-     -    yyless(n) returns all but the first n characters of the
-          current token back to the input stream, where they will
-          be rescanned when the scanner looks for the next match.
-          yytext  and  yyleng  are  adjusted appropriately (e.g.,
-          yyleng will now be equal to n ).
-
-     -    unput(c) puts the  character  c  back  onto  the  input
-          stream.  It will be the next character scanned.
-
-     -    input() reads the next character from the input  stream
-          (this  routine  is  called  yyinput() if the scanner is
-          compiled using C++).
-
-     -    yyterminate() can be used in lieu of a return statement
-          in  an action.  It terminates the scanner and returns a
-          0 to the scanner's caller, indicating "all done".
-
-          By default, yyterminate() is also called when  an  end-
-          of-file is encountered.  It is a macro and may be rede-
-          fined.
-
-     -    YY_NEW_FILE is an  action  available  only  in  <<EOF>>
-          rules.   It  means "Okay, I've set up a new input file,
-          continue scanning".
-
-     -    yy_create_buffer( file, size ) takes a FILE pointer and
-          an integer size. It returns a YY_BUFFER_STATE handle to
-          a new input buffer  large  enough  to  accomodate  size
-          characters and associated with the given file.  When in
-          doubt, use YY_BUF_SIZE for the size.
-
-     -    yy_switch_to_buffer(   new_buffer   )   switches    the
-          scanner's  processing to scan for tokens from the given
-          buffer, which must be a YY_BUFFER_STATE.
-
-     -    yy_delete_buffer( buffer ) deletes the given buffer.
-
-
-
-

VALUES AVAILABLE TO THE USER

-     -    char *yytext holds the text of the current  token.   It
-          may not be modified.
-
-     -    int yyleng holds the length of the current  token.   It
-          may not be modified.
-
-     -    FILE *yyin is the file  which  by  default  flex  reads
-          from.   It  may  be  redefined  but doing so only makes
-          sense before scanning begins.  Changing it in the  mid-
-          dle of scanning will have unexpected results since flex
-          buffers its input.  Once scanning terminates because an
-          end-of-file   has   been  seen,  void  yyrestart(  FILE
-          *new_file ) may be called to  point  yyin  at  the  new
-          input file.
-
-     -    FILE *yyout is the file to which ECHO actions are done.
-          It can be reassigned by the user.
-
-     -    YY_CURRENT_BUFFER returns a YY_BUFFER_STATE  handle  to
-          the current buffer.
-
-
-
-

MACROS THE USER CAN REDEFINE

-     -    YY_DECL controls how the scanning routine is  declared.
-          By  default, it is "int yylex()", or, if prototypes are
-          being used, "int yylex(void)".  This definition may  be
-          changed  by  redefining the "YY_DECL" macro.  Note that
-          if you give arguments to the scanning routine  using  a
-          K&R-style/non-prototyped function declaration, you must
-          terminate the definition with a semi-colon (;).
-
-     -    The nature of how the scanner gets  its  input  can  be
-          controlled    by   redefining   the   YY_INPUT   macro.
-          YY_INPUT's         calling         sequence          is
-          "YY_INPUT(buf,result,max_size)".    Its  action  is  to
-          place up to max_size characters in the character  array
-          buf  and  return  in the integer variable result either
-          the number of characters read or the  constant  YY_NULL
-          (0  on  Unix  systems)  to  indicate  EOF.  The default
-          YY_INPUT reads from the global file-pointer "yyin".   A
-          sample  redefinition  of  YY_INPUT  (in the definitions
-          section of the input file):
-
-              %{
-              #undef YY_INPUT
-              #define YY_INPUT(buf,result,max_size) \
-                  { \
-                  int c = getchar(); \
-                  result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
-                  }
-              %}
-
-
-     -    When the scanner  receives  an  end-of-file  indication
-          from  YY_INPUT,  it  then checks the yywrap() function.
-          If yywrap() returns false (zero), then  it  is  assumed
-          that  the  function  has  gone ahead and set up yyin to
-          point to another input file,  and  scanning  continues.
-          If  it  returns  true (non-zero), then the scanner ter-
-          minates, returning 0 to its caller.
-
-          The default yywrap() always returns 1.   Presently,  to
-          redefine  it  you  must first "#undef yywrap", as it is
-          currently implemented as a macro.  It  is  likely  that
-          yywrap()  will  soon be defined to be a function rather
-          than a macro.
-
-     -    YY_USER_ACTION can be redefined to  provide  an  action
-          which  is  always  executed prior to the matched rule's
-          action.
-
-     -    The macro YY_USER_INIT may be redefined to  provide  an
-          action which is always executed before the first scan.
-
-     -    In the generated scanner, the actions are all  gathered
-          in  one  large  switch  statement  and  separated using
-          YY_BREAK, which may be redefined.  By  default,  it  is
-          simply  a  "break", to separate each rule's action from
-          the following rule's.
-
-
-
-

FILES

-     flex.skel
-          skeleton scanner.
-
-     lex.yy.c
-          generated scanner (called lexyy.c on some systems).
-
-     lex.backtrack
-          backtracking information for -b flag (called lex.bck on
-          some systems).
-
-     -lfl library with which to link the scanners.
-
-
-
-

SEE ALSO

-     flexdoc(1), lex(1), yacc(1), sed(1), awk(1).
-
-     M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator
-
-
-
-

DIAGNOSTICS

-     reject_used_but_not_detected undefined or
-
-     yymore_used_but_not_detected undefined -  These  errors  can
-     occur  at compile time.  They indicate that the scanner uses
-     REJECT or yymore() but that flex failed to notice the  fact,
-     meaning that flex scanned the first two sections looking for
-     occurrences of these actions and failed  to  find  any,  but
-     somehow  you  snuck  some in (via a #include file, for exam-
-     ple).  Make an explicit reference to the action in your flex
-     input   file.    (Note  that  previously  flex  supported  a
-     %used/%unused mechanism for dealing with this problem;  this
-     feature  is  still supported but now deprecated, and will go
-     away soon unless the author hears from people who can  argue
-     compellingly that they need it.)
-
-     flex scanner jammed - a scanner compiled with -s has encoun-
-     tered  an  input  string  which wasn't matched by any of its
-     rules.
-
-     flex input buffer overflowed -  a  scanner  rule  matched  a
-     string  long enough to overflow the scanner's internal input
-     buffer  (16K   bytes   -   controlled   by   YY_BUF_MAX   in
-     "flex.skel").
-
-     scanner  requires  -8  flag  -  Your  scanner  specification
-     includes  recognizing  8-bit  characters  and  you  did  not
-     specify the -8 flag (and your site has  not  installed  flex
-     with -8 as the default).
-
-     fatal flex scanner internal error--end of  buffer  missed  -
-     This  can  occur  in  an  scanner which is reentered after a
-     long-jump has jumped out (or over) the scanner's  activation
-     frame.  Before reentering the scanner, use:
-         yyrestart( yyin );
-
-
-     too many %t classes! - You managed to put every single char-
-     acter  into  its  own %t class.  flex requires that at least
-     one of the classes share characters.
-
-
-
-

AUTHOR

-     Vern Paxson, with the help of many ideas and  much  inspira-
-     tion from Van Jacobson.  Original version by Jef Poskanzer.
-
-     See flexdoc(1) for additional credits  and  the  address  to
-     send comments to.
-
-
-
-

DEFICIENCIES / BUGS

-     Some trailing context patterns cannot  be  properly  matched
-     and  generate  warning  messages  ("Dangerous  trailing con-
-     text").  These are patterns where the ending  of  the  first
-     part  of  the rule matches the beginning of the second part,
-     such as "zx*/xy*", where the 'x*' matches  the  'x'  at  the
-     beginning  of  the  trailing  context.  (Note that the POSIX
-     draft states that the text matched by such patterns is unde-
-     fined.)
-
-     For some trailing context rules, parts  which  are  actually
-     fixed-length  are  not  recognized  as  such, leading to the
-     abovementioned performance loss.  In particular, parts using
-     '|'   or  {n}  (such  as  "foo{3}")  are  always  considered
-     variable-length.
-
-     Combining trailing context with the special '|'  action  can
-     result  in fixed trailing context being turned into the more
-     expensive variable trailing context.  For example, this hap-
-     pens in the following example:
-
-         %%
-         abc      |
-         xyz/def
-
-
-     Use of unput() invalidates yytext and yyleng.
-
-     Use of unput() to push back more text than was  matched  can
-     result  in the pushed-back text matching a beginning-of-line
-     ('^') rule even though it didn't come at  the  beginning  of
-     the line (though this is rare!).
-
-     Pattern-matching  of  NUL's  is  substantially  slower  than
-     matching other characters.
-
-     flex does not generate correct  #line  directives  for  code
-     internal to the scanner; thus, bugs in flex.skel yield bogus
-     line numbers.
-
-     Due to both buffering of input and  read-ahead,  you  cannot
-     intermix  calls to <stdio.h> routines, such as, for example,
-     getchar(), with flex rules and  expect  it  to  work.   Call
-     input() instead.
-
-     The total table entries listed by the -v flag  excludes  the
-     number  of  table  entries needed to determine what rule has
-     been matched.  The number of entries is equal to the  number
-     of  DFA states if the scanner does not use REJECT, and some-
-     what greater than the number of states if it does.
-
-     REJECT cannot be used with the -f or -F options.
-
-     Some of the macros, such as  yywrap(),  may  in  the  future
-     become  functions which live in the -lfl library.  This will
-     doubtless break a lot of  code,  but  may  be  required  for
-     POSIX-compliance.
-
-     The flex internal algorithms need documentation.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Man(1) output converted with -man2html -
- - diff --git a/src/libCom/flex/flex.skel b/src/libCom/flex/flex.skel deleted file mode 100644 index 6b9805b04..000000000 --- a/src/libCom/flex/flex.skel +++ /dev/null @@ -1,748 +0,0 @@ -/* A lexical scanner generated by flex */ - -/* scanner skeleton */ - -#define FLEX_SCANNER - -#include - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include -#include - -#else /* ! __cplusplus */ - -#ifdef __GNUC__ -#include -void *malloc( size_t ); -void free( void* ); -#else -#include -#endif /* __GNUC__ */ - -#endif /* ! __cplusplus */ - - -/* amount of stuff to slurp up with each read */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* returned upon end-of-file */ -#define YY_END_TOK 0 - -/* copy whatever the last rule matched to the standard output */ - -/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */ -/* this used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite() - */ -#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout ) - -/* gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#define YY_INPUT(buf,result,max_size) \ - if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ - YY_FATAL_ERROR( "read() in flex scanner failed" ); -#define YY_NULL 0 - -/* no semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#define yyterminate() return ( YY_NULL ) - -/* report a fatal error */ - -/* The funky do-while is used to turn this macro definition into - * a single C statement (which needs a semi-colon terminator). - * This avoids problems with code like: - * - * if ( something_happens ) - * YY_FATAL_ERROR( "oops, the something happened" ); - * else - * everything_okay(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the YY_FATAL_ERROR() call. - */ - -#define YY_FATAL_ERROR(msg) \ - do \ - { \ - (void) fputs( msg, stderr ); \ - (void) putc( '\n', stderr ); \ - exit( 1 ); \ - } \ - while ( 0 ) - -/* default yywrap function - always treat EOF as an EOF */ -#define yywrap() 1 - -/* enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN - */ -#define BEGIN yy_start = 1 + 2 * - -/* action number for EOF rule of a given start state */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* special action meaning "start processing a new file" */ -#define YY_NEW_FILE \ - do \ - { \ - yy_init_buffer( yy_current_buffer, yyin ); \ - yy_load_buffer_state(); \ - } \ - while ( 0 ) - -/* default declaration of generated scanner - a define so the user can - * easily add parameters - */ -#define YY_DECL int yylex ( void ) - -/* code executed at the end of each rule */ -#define YY_BREAK break; - -#define YY_END_OF_BUFFER_CHAR 0 - -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */ -#endif - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -%% section 1 definitions go here - -/* done after the current pattern has been matched and before the - * corresponding action - sets up yytext - */ -#define YY_DO_BEFORE_ACTION \ - yytext = yy_bp; \ -%% code to fiddle yytext and yyleng for yymore() goes here - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* return all but the first 'n' matched characters back to the input stream */ -#define yyless(n) \ - do \ - { \ - /* undo effects of setting up yytext */ \ - *yy_cp = yy_hold_char; \ - yy_c_buf_p = yy_cp = yy_bp + n; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext ) - - -struct yy_buffer_state - { - FILE *yy_input_file; - - YY_CHAR *yy_ch_buf; /* input buffer */ - YY_CHAR *yy_buf_pos; /* current position in input buffer */ - - /* size of input buffer in bytes, not including room for EOB characters*/ - int yy_buf_size; - - /* number of characters read into yy_ch_buf, not including EOB characters */ - int yy_n_chars; - - int yy_eof_status; /* whether we've seen an EOF on this buffer */ -#define EOF_NOT_SEEN 0 - /* "pending" happens when the EOF has been seen but there's still - * some text process - */ -#define EOF_PENDING 1 -#define EOF_DONE 2 - }; - -static YY_BUFFER_STATE yy_current_buffer; - -/* we provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state" - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed */ -static YY_CHAR yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - - -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -#ifndef YY_USER_INIT -#define YY_USER_INIT -#endif - -extern YY_CHAR *yytext; -extern int yyleng; -extern FILE *yyin, *yyout; - -YY_CHAR *yytext; -int yyleng; - -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; - -%% data tables for the DFA go here - -/* these variables are all declared out here so that section 3 code can - * manipulate them - */ -/* points to current character in buffer */ -static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -static yy_state_type yy_get_previous_state ( void ); -static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); -static int yy_get_next_buffer ( void ); -static void yyunput ( YY_CHAR c, YY_CHAR *buf_ptr ); -void yyrestart ( FILE *input_file ); -void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); -void yy_load_buffer_state ( void ); -YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); -void yy_delete_buffer ( YY_BUFFER_STATE b ); -void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); - -#define yy_new_buffer yy_create_buffer - -#ifdef __cplusplus -static int yyinput ( void ); -#else -static int input ( void ); -#endif - -YY_DECL - { - register yy_state_type yy_current_state; - register YY_CHAR *yy_cp, *yy_bp; - register int yy_act; - -%% user's declarations go here - - if ( yy_init ) - { - YY_USER_INIT; - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( yy_current_buffer ) - yy_init_buffer( yy_current_buffer, yyin ); - else - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - - yy_init = 0; - } - - while ( 1 ) /* loops until end-of-file is reached */ - { -%% yymore()-related code goes here - yy_cp = yy_c_buf_p; - - /* support of yytext */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of the - * current run. - */ - yy_bp = yy_cp; - -%% code to set up and find next match goes here - -yy_find_action: -%% code to find the action number goes here - - YY_DO_BEFORE_ACTION; - YY_USER_ACTION; - -do_action: /* this label is used only to access EOF actions */ - -%% debug code goes here - - switch ( yy_act ) - { -%% actions go here - - case YY_END_OF_BUFFER: - { - /* amount of text matched not including the EOB char */ - int yy_amount_of_matched_text = yy_cp - yytext - 1; - - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - - /* note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the end- - * of-buffer state). Contrast this with the test in yyinput(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* this was really a NUL */ - { - yy_state_type yy_next_state; - - yy_c_buf_p = yytext + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* okay, we're now positioned to make the - * NUL transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we - * don't want to build jamming into it because - * then it will run more slowly) - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* consume the NUL */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { -%% code to do backtracking for compressed tables and set up yy_cp goes here - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* note: because we've taken care in - * yy_get_next_buffer() to have set up yytext, - * we can now set up yy_c_buf_p so that if some - * total hoser (like flex itself) wants - * to call the scanner after we return the - * YY_NULL, it'll still work - another YY_NULL - * will get returned. - */ - yy_c_buf_p = yytext + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF((yy_start - 1) / 2); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - } - break; - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: -#ifdef FLEX_DEBUG - printf( "action # %d\n", yy_act ); -#endif - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } - } - } - - -/* yy_get_next_buffer - try to read in a new buffer - * - * synopsis - * int yy_get_next_buffer(); - * - * returns a code representing an action - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - - { - register YY_CHAR *dest = yy_current_buffer->yy_ch_buf; - register YY_CHAR *source = yytext - 1; /* copy prev. char, too */ - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - /* try to read more data */ - - /* first move last chars to start of buffer */ - number_to_move = yy_c_buf_p - yytext; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_n_chars = 0; - - else - { - int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - else if ( num_to_read <= 0 ) - YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); - - /* read in more data */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == 1 ) - { - ret_val = EOB_ACT_END_OF_FILE; - yy_current_buffer->yy_eof_status = EOF_DONE; - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_eof_status = EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - /* yytext begins at the second character in yy_ch_buf; the first - * character is the one which preceded it before reading in the latest - * buffer; it needs to be kept around in case it's a newline, so - * yy_get_previous_state() will have with '^' rules active - */ - - yytext = &yy_current_buffer->yy_ch_buf[1]; - - return ( ret_val ); - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached - * - * synopsis - * yy_state_type yy_get_previous_state(); - */ - -static yy_state_type yy_get_previous_state() - - { - register yy_state_type yy_current_state; - register YY_CHAR *yy_cp; - -%% code to get the start state into yy_current_state goes here - - for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { -%% code to find the next state goes here - } - - return ( yy_current_state ); - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -static yy_state_type yy_try_NUL_trans( register yy_state_type yy_current_state ) - { - register int yy_is_jam; -%% code to find the next state, and perhaps do backtracking, goes here - - return ( yy_is_jam ? 0 : yy_current_state ); - } - - -static void yyunput( YY_CHAR c, register YY_CHAR *yy_bp ) - { - register YY_CHAR *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */ - register YY_CHAR *dest = - &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2]; - register YY_CHAR *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += dest - source; - yy_bp += dest - source; - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - if ( yy_cp > yy_bp && yy_cp[-1] == '\n' ) - yy_cp[-2] = '\n'; - - *--yy_cp = c; - - /* note: the formal parameter *must* be called "yy_bp" for this - * macro to now work correctly - */ - YY_DO_BEFORE_ACTION; /* set up yytext again */ - } - - -#ifdef __cplusplus -static int yyinput() -#else -static int input(void) -#endif - - { - int c; - YY_CHAR *yy_cp = yy_c_buf_p; - - *yy_cp = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* this was really a NUL */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - yytext = yy_c_buf_p; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - { - yy_c_buf_p = yytext + YY_MORE_ADJ; - return ( EOF ); - } - - YY_NEW_FILE; - -#ifdef __cplusplus - return ( yyinput() ); -#else - return ( input() ); -#endif - } - break; - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext + YY_MORE_ADJ; - break; - - case EOB_ACT_LAST_MATCH: -#ifdef __cplusplus - YY_FATAL_ERROR( "unexpected last match in yyinput()" ); -#else - YY_FATAL_ERROR( "unexpected last match in input()" ); -#endif - } - } - } - - c = *yy_c_buf_p; - yy_hold_char = *++yy_c_buf_p; - - return ( c ); - } - - -void yyrestart( FILE *input_file ) - { - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* flush out information for old buffer */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* we don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -void yy_load_buffer_state( void ) - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) ); - - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) ); - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - yy_init_buffer( b, file ); - - return ( b ); - } - - -void yy_delete_buffer( YY_BUFFER_STATE b ) - { - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - free( (char *) b->yy_ch_buf ); - free( (char *) b ); - } - - -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) - { - b->yy_input_file = file; - - /* we put in the '\n' and start reading from [1] so that an - * initial match-at-newline will be true. - */ - - b->yy_ch_buf[0] = '\n'; - b->yy_n_chars = 1; - - /* we always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[1]; - - b->yy_eof_status = EOF_NOT_SEEN; - } diff --git a/src/libCom/flex/flex.skel.static b/src/libCom/flex/flex.skel.static deleted file mode 100644 index 5e8bf2810..000000000 --- a/src/libCom/flex/flex.skel.static +++ /dev/null @@ -1,754 +0,0 @@ -/* A lexical scanner generated by flex */ - -/* scanner skeleton */ - -/* modified by Jim Kowalkowski to have everything declared static */ - -#define FLEX_SCANNER - -#include -#include - -/* amount of stuff to slurp up with each read */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* returned upon end-of-file */ -#define YY_END_TOK 0 - -/* copy whatever the last rule matched to the standard output */ - -/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */ -/* this used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite() - */ -#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout ) - -/* gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#define YY_INPUT(buf,result,max_size) \ - if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ - YY_FATAL_ERROR( "read() in flex scanner failed" ); -#define YY_NULL 0 - -/* no semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ - -/* #define yyterminate() return ( YY_NULL ) replaced by jbk */ -static int yyterminate_internal( void ); -#define yyterminate() return yyterminate_internal() - -/* report a fatal error */ - -/* The funky do-while is used to turn this macro definition into - * a single C statement (which needs a semi-colon terminator). - * This avoids problems with code like: - * - * if ( something_happens ) - * YY_FATAL_ERROR( "oops, the something happened" ); - * else - * everything_okay(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the YY_FATAL_ERROR() call. - */ - -#define YY_FATAL_ERROR(msg) \ - do \ - { \ - (void) fputs( msg, stderr ); \ - (void) putc( '\n', stderr ); \ - exit( 1 ); \ - } \ - while ( 0 ) - -/* default yywrap function - always treat EOF as an EOF */ -#define yywrap() 1 - -/* enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN - */ -#define BEGIN yy_start = 1 + 2 * - -/* action number for EOF rule of a given start state */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* special action meaning "start processing a new file" */ -#define YY_NEW_FILE \ - do \ - { \ - yy_init_buffer( yy_current_buffer, yyin ); \ - yy_load_buffer_state(); \ - } \ - while ( 0 ) - -/* default declaration of generated scanner - a define so the user can - * easily add parameters - jbk added the static to YY_DECL - */ -#define YY_DECL static int yylex ( void ) - -/* code executed at the end of each rule */ -#define YY_BREAK break; - -#define YY_END_OF_BUFFER_CHAR 0 - -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */ -#endif - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -%% section 1 definitions go here - -/* done after the current pattern has been matched and before the - * corresponding action - sets up yytext - */ -#define YY_DO_BEFORE_ACTION \ - yytext = yy_bp; \ -%% code to fiddle yytext and yyleng for yymore() goes here - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* return all but the first 'n' matched characters back to the input stream */ -#define yyless(n) \ - do \ - { \ - /* undo effects of setting up yytext */ \ - *yy_cp = yy_hold_char; \ - yy_c_buf_p = yy_cp = yy_bp + n; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext ) - - -struct yy_buffer_state - { - FILE *yy_input_file; - - YY_CHAR *yy_ch_buf; /* input buffer */ - YY_CHAR *yy_buf_pos; /* current position in input buffer */ - - /* size of input buffer in bytes, not including room for EOB characters */ - int yy_buf_size; - - /* number of characters read into yy_ch_buf, not including EOB characters */ - int yy_n_chars; - - int yy_eof_status; /* whether we've seen an EOF on this buffer */ -#define EOF_NOT_SEEN 0 - /* "pending" happens when the EOF has been seen but there's still - * some text process - */ -#define EOF_PENDING 1 -#define EOF_DONE 2 - }; - -static YY_BUFFER_STATE yy_current_buffer; - -/* we provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state" - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed */ -static YY_CHAR yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - - -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -#ifndef YY_USER_INIT -#define YY_USER_INIT -#endif - -/* jbk update -extern YY_CHAR *yytext; -extern int yyleng; -extern FILE *yyin, *yyout; -*/ - -static YY_CHAR *yytext; /* jbk added static */ -static int yyleng; /* jbk added static */ - -static FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; /* jbk added static */ - -%% data tables for the DFA go here - -/* these variables are all declared out here so that section 3 code can - * manipulate them - */ -/* points to current character in buffer */ -static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -static yy_state_type yy_get_previous_state ( void ); -static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); -static int yy_get_next_buffer ( void ); -static void yyunput ( YY_CHAR c, YY_CHAR *buf_ptr ); - -/* jbk added static in front all these */ -static void yyrestart ( FILE *input_file ); -static void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); -static void yy_load_buffer_state ( void ); -static YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); -static void yy_delete_buffer ( YY_BUFFER_STATE b ); -static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); - -#define yy_new_buffer yy_create_buffer - -#ifdef yyneed_input -#ifdef __cplusplus -static int yyinput ( void ); -#else -static int input ( void ); -#endif -#endif - -YY_DECL - { - register yy_state_type yy_current_state; - register YY_CHAR *yy_cp, *yy_bp; - register int yy_act; - -%% user's declarations go here - - if ( yy_init ) - { - YY_USER_INIT; - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( yy_current_buffer ) - yy_init_buffer( yy_current_buffer, yyin ); - else - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - - yy_init = 0; - } - - while ( 1 ) /* loops until end-of-file is reached */ - { -%% yymore()-related code goes here - yy_cp = yy_c_buf_p; - - /* support of yytext */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of the - * current run. - */ - yy_bp = yy_cp; - -%% code to set up and find next match goes here - -yy_find_action: -%% code to find the action number goes here - - YY_DO_BEFORE_ACTION; - YY_USER_ACTION; - -do_action: /* this label is used only to access EOF actions */ - -%% debug code goes here - - switch ( yy_act ) - { -%% actions go here - - case YY_END_OF_BUFFER: - { - /* amount of text matched not including the EOB char */ - int yy_amount_of_matched_text = yy_cp - yytext - 1; - - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - - /* note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the end- - * of-buffer state). Contrast this with the test in yyinput(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* this was really a NUL */ - { - yy_state_type yy_next_state; - - yy_c_buf_p = yytext + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* okay, we're now positioned to make the - * NUL transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we - * don't want to build jamming into it because - * then it will run more slowly) - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* consume the NUL */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { -%% code to do backtracking for compressed tables and set up yy_cp goes here - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* note: because we've taken care in - * yy_get_next_buffer() to have set up yytext, - * we can now set up yy_c_buf_p so that if some - * total hoser (like flex itself) wants - * to call the scanner after we return the - * YY_NULL, it'll still work - another YY_NULL - * will get returned. - */ - yy_c_buf_p = yytext + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF((yy_start - 1) / 2); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - } - break; - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: -#ifdef FLEX_DEBUG - printf( "action # %d\n", yy_act ); -#endif - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } - } - } - - -/* yy_get_next_buffer - try to read in a new buffer - * - * synopsis - * int yy_get_next_buffer(); - * - * returns a code representing an action - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer( void ) - - { - register YY_CHAR *dest = yy_current_buffer->yy_ch_buf; - register YY_CHAR *source = yytext - 1; /* copy prev. char, too */ - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - /* try to read more data */ - - /* first move last chars to start of buffer */ - number_to_move = yy_c_buf_p - yytext; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_n_chars = 0; - - else - { - int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - else if ( num_to_read <= 0 ) - YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); - - /* read in more data */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move - YY_MORE_ADJ == 1 ) - { - ret_val = EOB_ACT_END_OF_FILE; - yy_current_buffer->yy_eof_status = EOF_DONE; - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_eof_status = EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - /* yytext begins at the second character in yy_ch_buf; the first - * character is the one which preceded it before reading in the latest - * buffer; it needs to be kept around in case it's a newline, so - * yy_get_previous_state() will have with '^' rules active - */ - - yytext = &yy_current_buffer->yy_ch_buf[1]; - - return ( ret_val ); - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached - * - * synopsis - * yy_state_type yy_get_previous_state(); - */ - -static yy_state_type yy_get_previous_state( void ) - - { - register yy_state_type yy_current_state; - register YY_CHAR *yy_cp; - -%% code to get the start state into yy_current_state goes here - - for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { -%% code to find the next state goes here - } - - return ( yy_current_state ); - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -static yy_state_type yy_try_NUL_trans( register yy_state_type yy_current_state ) - { - register int yy_is_jam; -%% code to find the next state, and perhaps do backtracking, goes here - - return ( yy_is_jam ? 0 : yy_current_state ); - } - - -static void yyunput( YY_CHAR c, register YY_CHAR *yy_bp ) - { - register YY_CHAR *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */ - register YY_CHAR *dest = - &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2]; - register YY_CHAR *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += dest - source; - yy_bp += dest - source; - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - if ( yy_cp > yy_bp && yy_cp[-1] == '\n' ) - yy_cp[-2] = '\n'; - - *--yy_cp = c; - - /* note: the formal parameter *must* be called "yy_bp" for this - * macro to now work correctly - */ - YY_DO_BEFORE_ACTION; /* set up yytext again */ - } - - -#ifdef yyneed_input -#ifdef __cplusplus -static int yyinput( void ) -#else -static int input( void ) -#endif - - { - int c; - YY_CHAR *yy_cp = yy_c_buf_p; - - *yy_cp = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* this was really a NUL */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - yytext = yy_c_buf_p; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - { - yy_c_buf_p = yytext + YY_MORE_ADJ; - return ( EOF ); - } - - YY_NEW_FILE; - -#ifdef __cplusplus - return ( yyinput() ); -#else - return ( input() ); -#endif - } - break; - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext + YY_MORE_ADJ; - break; - - case EOB_ACT_LAST_MATCH: -#ifdef __cplusplus - YY_FATAL_ERROR( "unexpected last match in yyinput()" ); -#else - YY_FATAL_ERROR( "unexpected last match in input()" ); -#endif - } - } - } - - c = *yy_c_buf_p; - yy_hold_char = *++yy_c_buf_p; - - return ( c ); - } -#endif /* yyneed_input */ - - -/* jbk added static in front of func */ -static void yyrestart( FILE *input_file ) - { - if ( yy_current_buffer ) - yy_init_buffer( yy_current_buffer, input_file ); - else - yy_current_buffer = yy_create_buffer( input_file, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - -/* jbk added static in front of func */ -static void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* flush out information for old buffer */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* we don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -/* jbk added static in front of func */ -static void yy_load_buffer_state( void ) - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -/* jbk added static in front of func */ -static YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) ); - - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) ); - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - yy_init_buffer( b, file ); - - return ( b ); - } - - -/* jbk added static in front of func */ -static void yy_delete_buffer( YY_BUFFER_STATE b ) - { - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - free( (char *) b->yy_ch_buf ); - free( (char *) b ); - } - - -/* jbk added static in front of func */ -static void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) - { - b->yy_input_file = file; - - /* we put in the '\n' and start reading from [1] so that an - * initial match-at-newline will be true. - */ - - b->yy_ch_buf[0] = '\n'; - b->yy_n_chars = 1; - - /* we always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[1]; - - b->yy_eof_status = EOF_NOT_SEEN; - } - -static int yyterminate_internal( void ) -{ - /* jbk fix - buffer created by yy_create_buffer needs to be freed */ - yy_delete_buffer(yy_current_buffer); - yy_current_buffer=NULL; - return YY_NULL; -} - diff --git a/src/libCom/flex/flexdef.h b/src/libCom/flex/flexdef.h deleted file mode 100644 index 79cfa9427..000000000 --- a/src/libCom/flex/flexdef.h +++ /dev/null @@ -1,837 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* flexdef - definitions file for flex */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef INC_flexdef_H -#define INC_flexdef_H - -#include -#include -#include -#include -#include - -#ifdef __GNUC__ -#define NORETURN __attribute__((noreturn)) -#else -#define NORETURN -#endif - -/* always be prepared to generate an 8-bit scanner */ -#define FLEX_8_BIT_CHARS - -#ifdef FLEX_8_BIT_CHARS -#define CSIZE 256 -#define Char unsigned char -#else -#define Char char -#define CSIZE 128 -#endif - -/* size of input alphabet - should be size of ASCII set */ -#ifndef DEFAULT_CSIZE -#define DEFAULT_CSIZE 128 -#endif - - -/* maximum line length we'll have to deal with */ -#define MAXLINE BUFSIZ - -/* maximum size of file name */ -#define FILENAMESIZE 1024 - -#ifndef min -#define min(x,y) ((x) < (y) ? (x) : (y)) -#endif -#ifndef max -#define max(x,y) ((x) > (y) ? (x) : (y)) -#endif - -#define true 1 -#define false 0 - - -#ifndef DEFAULT_SKELETON_FILE -#define DEFAULT_SKELETON_FILE "flex.skel" -#endif - -/* special chk[] values marking the slots taking by end-of-buffer and action - * numbers - */ -#define EOB_POSITION -1 -#define ACTION_POSITION -2 - -/* number of data items per line for -f output */ -#define NUMDATAITEMS 10 - -/* number of lines of data in -f output before inserting a blank line for - * readability. - */ -#define NUMDATALINES 10 - -/* transition_struct_out() definitions */ -#define TRANS_STRUCT_PRINT_LENGTH 15 - -/* returns true if an nfa state has an epsilon out-transition slot - * that can be used. This definition is currently not used. - */ -#define FREE_EPSILON(state) \ - (transchar[state] == SYM_EPSILON && \ - trans2[state] == NO_TRANSITION && \ - finalst[state] != state) - -/* returns true if an nfa state has an epsilon out-transition character - * and both slots are free - */ -#define SUPER_FREE_EPSILON(state) \ - (transchar[state] == SYM_EPSILON && \ - trans1[state] == NO_TRANSITION) \ - -/* maximum number of NFA states that can comprise a DFA state. It's real - * big because if there's a lot of rules, the initial state will have a - * huge epsilon closure. - */ -#define INITIAL_MAX_DFA_SIZE 750 -#define MAX_DFA_SIZE_INCREMENT 750 - - -/* a note on the following masks. They are used to mark accepting numbers - * as being special. As such, they implicitly limit the number of accepting - * numbers (i.e., rules) because if there are too many rules the rule numbers - * will overload the mask bits. Fortunately, this limit is \large/ (0x2000 == - * 8192) so unlikely to actually cause any problems. A check is made in - * new_rule() to ensure that this limit is not reached. - */ - -/* mask to mark a trailing context accepting number */ -#define YY_TRAILING_MASK 0x2000 - -/* mask to mark the accepting number of the "head" of a trailing context rule */ -#define YY_TRAILING_HEAD_MASK 0x4000 - -/* maximum number of rules, as outlined in the above note */ -#define MAX_RULE (YY_TRAILING_MASK - 1) - - -/* NIL must be 0. If not, its special meaning when making equivalence classes - * (it marks the representative of a given e.c.) will be unidentifiable - */ -#define NIL 0 - -#define JAM -1 /* to mark a missing DFA transition */ -#define NO_TRANSITION NIL -#define UNIQUE -1 /* marks a symbol as an e.c. representative */ -#define INFINITY -1 /* for x{5,} constructions */ - -#define INITIAL_MAX_CCLS 100 /* max number of unique character classes */ -#define MAX_CCLS_INCREMENT 100 - -/* size of table holding members of character classes */ -#define INITIAL_MAX_CCL_TBL_SIZE 500 -#define MAX_CCL_TBL_SIZE_INCREMENT 250 - -#define INITIAL_MAX_RULES 100 /* default maximum number of rules */ -#define MAX_RULES_INCREMENT 100 - -#define INITIAL_MNS 2000 /* default maximum number of nfa states */ -#define MNS_INCREMENT 1000 /* amount to bump above by if it's not enough */ - -#define INITIAL_MAX_DFAS 1000 /* default maximum number of dfa states */ -#define MAX_DFAS_INCREMENT 1000 - -#define JAMSTATE -32766 /* marks a reference to the state that always jams */ - -/* enough so that if it's subtracted from an NFA state number, the result - * is guaranteed to be negative - */ -#define MARKER_DIFFERENCE 32000 -#define MAXIMUM_MNS 31999 - -/* maximum number of nxt/chk pairs for non-templates */ -#define INITIAL_MAX_XPAIRS 2000 -#define MAX_XPAIRS_INCREMENT 2000 - -/* maximum number of nxt/chk pairs needed for templates */ -#define INITIAL_MAX_TEMPLATE_XPAIRS 2500 -#define MAX_TEMPLATE_XPAIRS_INCREMENT 2500 - -#define SYM_EPSILON (CSIZE + 1) /* to mark transitions on the symbol epsilon */ - -#define INITIAL_MAX_SCS 40 /* maximum number of start conditions */ -#define MAX_SCS_INCREMENT 40 /* amount to bump by if it's not enough */ - -#define ONE_STACK_SIZE 500 /* stack of states with only one out-transition */ -#define SAME_TRANS -1 /* transition is the same as "default" entry for state */ - -/* the following percentages are used to tune table compression: - - * the percentage the number of out-transitions a state must be of the - * number of equivalence classes in order to be considered for table - * compaction by using protos - */ -#define PROTO_SIZE_PERCENTAGE 15 - -/* the percentage the number of homogeneous out-transitions of a state - * must be of the number of total out-transitions of the state in order - * that the state's transition table is first compared with a potential - * template of the most common out-transition instead of with the first - * proto in the proto queue - */ -#define CHECK_COM_PERCENTAGE 50 - -/* the percentage the number of differences between a state's transition - * table and the proto it was first compared with must be of the total - * number of out-transitions of the state in order to keep the first - * proto as a good match and not search any further - */ -#define FIRST_MATCH_DIFF_PERCENTAGE 10 - -/* the percentage the number of differences between a state's transition - * table and the most similar proto must be of the state's total number - * of out-transitions to use the proto as an acceptable close match - */ -#define ACCEPTABLE_DIFF_PERCENTAGE 50 - -/* the percentage the number of homogeneous out-transitions of a state - * must be of the number of total out-transitions of the state in order - * to consider making a template from the state - */ -#define TEMPLATE_SAME_PERCENTAGE 60 - -/* the percentage the number of differences between a state's transition - * table and the most similar proto must be of the state's total number - * of out-transitions to create a new proto from the state - */ -#define NEW_PROTO_DIFF_PERCENTAGE 20 - -/* the percentage the total number of out-transitions of a state must be - * of the number of equivalence classes in order to consider trying to - * fit the transition table into "holes" inside the nxt/chk table. - */ -#define INTERIOR_FIT_PERCENTAGE 15 - -/* size of region set aside to cache the complete transition table of - * protos on the proto queue to enable quick comparisons - */ -#define PROT_SAVE_SIZE 2000 - -#define MSP 50 /* maximum number of saved protos (protos on the proto queue) */ - -/* maximum number of out-transitions a state can have that we'll rummage - * around through the interior of the internal fast table looking for a - * spot for it - */ -#define MAX_XTIONS_FULL_INTERIOR_FIT 4 - -/* maximum number of rules which will be reported as being associated - * with a DFA state - */ -#define MAX_ASSOC_RULES 100 - -/* number that, if used to subscript an array, has a good chance of producing - * an error; should be small enough to fit into a short - */ -#define BAD_SUBSCRIPT -32767 - -/* absolute value of largest number that can be stored in a short, with a - * bit of slop thrown in for general paranoia. - */ -#define MAX_SHORT 32766 - - -/* Declarations for global variables. */ - -/* variables for symbol tables: - * sctbl - start-condition symbol table - * ndtbl - name-definition symbol table - * ccltab - character class text symbol table - */ - -struct hash_entry - { - struct hash_entry *prev, *next; - char *name; - char *str_val; - int int_val; - } ; - -typedef struct hash_entry *hash_table[]; - -#define NAME_TABLE_HASH_SIZE 101 -#define START_COND_HASH_SIZE 101 -#define CCL_HASH_SIZE 101 - -extern struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE]; -extern struct hash_entry *sctbl[START_COND_HASH_SIZE]; -extern struct hash_entry *ccltab[CCL_HASH_SIZE]; - - -/* variables for flags: - * printstats - if true (-v), dump statistics - * syntaxerror - true if a syntax error has been found - * eofseen - true if we've seen an eof in the input file - * ddebug - if true (-d), make a "debug" scanner - * trace - if true (-T), trace processing - * spprdflt - if true (-s), suppress the default rule - * interactive - if true (-I), generate an interactive scanner - * caseins - if true (-i), generate a case-insensitive scanner - * useecs - if true (-Ce flag), use equivalence classes - * fulltbl - if true (-Cf flag), don't compress the DFA state table - * usemecs - if true (-Cm flag), use meta-equivalence classes - * fullspd - if true (-F flag), use Jacobson method of table representation - * gen_line_dirs - if true (i.e., no -L flag), generate #line directives - * performance_report - if true (i.e., -p flag), generate a report relating - * to scanner performance - * backtrack_report - if true (i.e., -b flag), generate "lex.backtrack" file - * listing backtracking states - * csize - size of character set for the scanner we're generating; - * 128 for 7-bit chars and 256 for 8-bit - * yymore_used - if true, yymore() is used in input rules - * reject - if true, generate backtracking tables for REJECT macro - * real_reject - if true, scanner really uses REJECT (as opposed to just - * having "reject" set for variable trailing context) - * continued_action - true if this rule's action is to "fall through" to - * the next rule's action (i.e., the '|' action) - * yymore_really_used - has a REALLY_xxx value indicating whether a - * %used or %notused was used with yymore() - * reject_really_used - same for REJECT - */ - -extern int printstats, syntaxerror, eofseen, ddebug, trace, spprdflt; -extern int interactive, caseins, useecs, fulltbl, usemecs; -extern int fullspd, gen_line_dirs, performance_report, backtrack_report, csize; -extern int yymore_used, reject, real_reject, continued_action; - -#define REALLY_NOT_DETERMINED 0 -#define REALLY_USED 1 -#define REALLY_NOT_USED 2 -extern int yymore_really_used, reject_really_used; - - -/* variables used in the flex input routines: - * datapos - characters on current output line - * dataline - number of contiguous lines of data in current data - * statement. Used to generate readable -f output - * linenum - current input line number - * skelfile - the skeleton file - * yyin - input file - * temp_action_file - temporary file to hold actions - * backtrack_file - file to summarize backtracking states to - * infilename - name of input file - * action_file_name - name of the temporary file - * input_files - array holding names of input files - * num_input_files - size of input_files array - * program_name - name with which program was invoked - */ - -extern int datapos, dataline, linenum; -extern FILE *skelfile, *yyin, *temp_action_file, *backtrack_file; -extern char *infilename; -extern char action_file_name[]; -extern char **input_files; -extern int num_input_files; -extern char *program_name; - - -/* variables for stack of states having only one out-transition: - * onestate - state number - * onesym - transition symbol - * onenext - target state - * onedef - default base entry - * onesp - stack pointer - */ - -extern int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; -extern int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; - - -/* variables for nfa machine data: - * current_mns - current maximum on number of NFA states - * num_rules - number of the last accepting state; also is number of - * rules created so far - * current_max_rules - current maximum number of rules - * lastnfa - last nfa state number created - * firstst - physically the first state of a fragment - * lastst - last physical state of fragment - * finalst - last logical state of fragment - * transchar - transition character - * trans1 - transition state - * trans2 - 2nd transition state for epsilons - * accptnum - accepting number - * assoc_rule - rule associated with this NFA state (or 0 if none) - * state_type - a STATE_xxx type identifying whether the state is part - * of a normal rule, the leading state in a trailing context - * rule (i.e., the state which marks the transition from - * recognizing the text-to-be-matched to the beginning of - * the trailing context), or a subsequent state in a trailing - * context rule - * rule_type - a RULE_xxx type identifying whether this a a ho-hum - * normal rule or one which has variable head & trailing - * context - * rule_linenum - line number associated with rule - */ - -extern int current_mns, num_rules, current_max_rules, lastnfa; -extern int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; -extern int *accptnum, *assoc_rule, *state_type, *rule_type, *rule_linenum; - -/* different types of states; values are useful as masks, as well, for - * routines like check_trailing_context() - */ -#define STATE_NORMAL 0x1 -#define STATE_TRAILING_CONTEXT 0x2 - -/* global holding current type of state we're making */ - -extern int current_state_type; - -/* different types of rules */ -#define RULE_NORMAL 0 -#define RULE_VARIABLE 1 - -/* true if the input rules include a rule with both variable-length head - * and trailing context, false otherwise - */ -extern int variable_trailing_context_rules; - - -/* variables for protos: - * numtemps - number of templates created - * numprots - number of protos created - * protprev - backlink to a more-recently used proto - * protnext - forward link to a less-recently used proto - * prottbl - base/def table entry for proto - * protcomst - common state of proto - * firstprot - number of the most recently used proto - * lastprot - number of the least recently used proto - * protsave contains the entire state array for protos - */ - -extern int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; -extern int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; - - -/* variables for managing equivalence classes: - * numecs - number of equivalence classes - * nextecm - forward link of Equivalence Class members - * ecgroup - class number or backward link of EC members - * nummecs - number of meta-equivalence classes (used to compress - * templates) - * tecfwd - forward link of meta-equivalence classes members - * tecbck - backward link of MEC's - * xlation - maps character codes to their translations, or nil if no %t table - * num_xlations - number of different xlation values - */ - -/* reserve enough room in the equivalence class arrays so that we - * can use the CSIZE'th element to hold equivalence class information - * for the NUL character. Later we'll move this information into - * the 0th element. - */ -extern int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs; - -/* meta-equivalence classes are indexed starting at 1, so it's possible - * that they will require positions from 1 .. CSIZE, i.e., CSIZE + 1 - * slots total (since the arrays are 0-based). nextecm[] and ecgroup[] - * don't require the extra position since they're indexed from 1 .. CSIZE - 1. - */ -extern int tecfwd[CSIZE + 1], tecbck[CSIZE + 1]; - -extern int *xlation; -extern int num_xlations; - - -/* variables for start conditions: - * lastsc - last start condition created - * current_max_scs - current limit on number of start conditions - * scset - set of rules active in start condition - * scbol - set of rules active only at the beginning of line in a s.c. - * scxclu - true if start condition is exclusive - * sceof - true if start condition has EOF rule - * scname - start condition name - * actvsc - stack of active start conditions for the current rule - */ - -extern int lastsc, current_max_scs, *scset, *scbol, *scxclu, *sceof, *actvsc; -extern char **scname; - - -/* variables for dfa machine data: - * current_max_dfa_size - current maximum number of NFA states in DFA - * current_max_xpairs - current maximum number of non-template xtion pairs - * current_max_template_xpairs - current maximum number of template pairs - * current_max_dfas - current maximum number DFA states - * lastdfa - last dfa state number created - * nxt - state to enter upon reading character - * chk - check value to see if "nxt" applies - * tnxt - internal nxt table for templates - * base - offset into "nxt" for given state - * def - where to go if "chk" disallows "nxt" entry - * nultrans - NUL transition for each state - * NUL_ec - equivalence class of the NUL character - * tblend - last "nxt/chk" table entry being used - * firstfree - first empty entry in "nxt/chk" table - * dss - nfa state set for each dfa - * dfasiz - size of nfa state set for each dfa - * dfaacc - accepting set for each dfa state (or accepting number, if - * -r is not given) - * accsiz - size of accepting set for each dfa state - * dhash - dfa state hash value - * numas - number of DFA accepting states created; note that this - * is not necessarily the same value as num_rules, which is the analogous - * value for the NFA - * numsnpairs - number of state/nextstate transition pairs - * jambase - position in base/def where the default jam table starts - * jamstate - state number corresponding to "jam" state - * end_of_buffer_state - end-of-buffer dfa state number - */ - -extern int current_max_dfa_size, current_max_xpairs; -extern int current_max_template_xpairs, current_max_dfas; -extern int lastdfa, lasttemp, *nxt, *chk, *tnxt; -extern int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; -extern union dfaacc_union - { - int *dfaacc_set; - int dfaacc_state; - } *dfaacc; -extern int *accsiz, *dhash, numas; -extern int numsnpairs, jambase, jamstate; -extern int end_of_buffer_state; - -/* variables for ccl information: - * lastccl - ccl index of the last created ccl - * current_maxccls - current limit on the maximum number of unique ccl's - * cclmap - maps a ccl index to its set pointer - * ccllen - gives the length of a ccl - * cclng - true for a given ccl if the ccl is negated - * cclreuse - counts how many times a ccl is re-used - * current_max_ccl_tbl_size - current limit on number of characters needed - * to represent the unique ccl's - * ccltbl - holds the characters in each ccl - indexed by cclmap - */ - -extern int lastccl, current_maxccls, *cclmap, *ccllen, *cclng, cclreuse; -extern int current_max_ccl_tbl_size; -extern Char *ccltbl; - - -/* variables for miscellaneous information: - * starttime - real-time when we started - * endtime - real-time when we ended - * nmstr - last NAME scanned by the scanner - * sectnum - section number currently being parsed - * nummt - number of empty nxt/chk table entries - * hshcol - number of hash collisions detected by snstods - * dfaeql - number of times a newly created dfa was equal to an old one - * numeps - number of epsilon NFA states created - * eps2 - number of epsilon states which have 2 out-transitions - * num_reallocs - number of times it was necessary to realloc() a group - * of arrays - * tmpuses - number of DFA states that chain to templates - * totnst - total number of NFA states used to make DFA states - * peakpairs - peak number of transition pairs we had to store internally - * numuniq - number of unique transitions - * numdup - number of duplicate transitions - * hshsave - number of hash collisions saved by checking number of states - * num_backtracking - number of DFA states requiring back-tracking - * bol_needed - whether scanner needs beginning-of-line recognition - */ - -extern char *starttime, *endtime, nmstr[MAXLINE]; -extern int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; -extern int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; -extern int num_backtracking, bol_needed; - -void *allocate_array(int size, int element_size); -void *reallocate_array(void *array, int size, int element_size); - -#define allocate_integer_array(size) \ - (int *) allocate_array( size, sizeof( int ) ) - -#define reallocate_integer_array(array,size) \ - (int *) reallocate_array( (void *) array, size, sizeof( int ) ) - -#define allocate_int_ptr_array(size) \ - (int **) allocate_array( size, sizeof( int * ) ) - -#define allocate_char_ptr_array(size) \ - (char **) allocate_array( size, sizeof( char * ) ) - -#define allocate_dfaacc_union(size) \ - (union dfaacc_union *) \ - allocate_array( size, sizeof( union dfaacc_union ) ) - -#define reallocate_int_ptr_array(array,size) \ - (int **) reallocate_array( (void *) array, size, sizeof( int * ) ) - -#define reallocate_char_ptr_array(array,size) \ - (char **) reallocate_array( (void *) array, size, sizeof( char * ) ) - -#define reallocate_dfaacc_union(array, size) \ - (union dfaacc_union *) \ - reallocate_array( (void *) array, size, sizeof( union dfaacc_union ) ) - -#define allocate_character_array(size) \ - (Char *) allocate_array( size, sizeof( Char ) ) - -#define reallocate_character_array(array,size) \ - (Char *) reallocate_array( (void *) array, size, sizeof( Char ) ) - -#if 0 /* JRW this might couse truuble... but not for IOC usage */ -/* used to communicate between scanner and parser. The type should really - * be YYSTYPE, but we can't easily get our hands on it. - */ -#ifdef __alpha /* inconsistency with parse.y, line 57... on Alpha */ -extern long yylval; -#else -extern int yylval; -#endif -#endif - - -/* external functions that are cross-referenced among the flex source files */ - - -/* from file ccl.c */ - -extern void ccladd (int, int); /* Add a single character to a ccl */ -extern int cclinit (void); /* make an empty ccl */ -extern void cclnegate (int); /* negate a ccl */ - -/* list the members of a set of characters in CCL form */ -extern void list_character_set (FILE*, int[]); - - -/* from file dfa.c */ - -/* increase the maximum number of dfas */ -extern void increase_max_dfas (void); - -extern void ntod (void); /* convert a ndfa to a dfa */ - - -/* from file ecs.c */ - -/* convert character classes to set of equivalence classes */ -extern void ccl2ecl (void); - -/* associate equivalence class numbers with class members */ -extern int cre8ecs (int[], int[], int); - -/* associate equivalence class numbers using %t table */ -extern int ecs_from_xlation (int[]); - -/* update equivalence classes based on character class transitions */ -extern void mkeccl (Char[], int, int[], int[], int, int); - -/* create equivalence class for single character */ -extern void mkechar (int, int[], int[]); - - -/* from file gen.c */ - -extern void make_tables (void); /* generate transition tables */ - - -/* from file main.c */ - -extern void flexend (int) NORETURN; - - -/* from file misc.c */ - -/* write out the actions from the temporary file to lex.yy.c */ -extern void action_out (void); - -/* true if a string is all lower case */ -extern int all_lower (Char *); - -/* true if a string is all upper case */ -extern int all_upper (Char *); - -/* bubble sort an integer array */ -extern void bubble (int [], int); - -/* shell sort a character array */ -extern void cshell (Char [], int, int); - -extern void dataend (void); /* finish up a block of data declarations */ - -/* report an error message and terminate */ -extern void flexerror (char[]) NORETURN; - -/* report a fatal error message and terminate */ -extern void flexfatal (char[]); - -/* report an error message formatted with one integer argument */ -extern void lerrif (char[], int); - -/* report an error message formatted with one string argument */ -extern void lerrsf (char[], char[]); - -/* spit out a "# line" statement */ -extern void line_directive_out (FILE*); - -/* generate a data statment for a two-dimensional array */ -extern void mk2data (int); - -extern void mkdata (int); /* generate a data statement */ - -/* return the integer represented by a string of digits */ -extern int myctoi (Char []); - -/* write out one section of the skeleton file */ -extern void skelout (void); - -/* output a yy_trans_info structure */ -extern void transition_struct_out (int, int); - - -/* from file nfa.c */ - -/* add an accepting state to a machine */ -extern void add_accept (int, int); - -/* make a given number of copies of a singleton machine */ -extern int copysingl (int, int); - -/* debugging routine to write out an nfa */ -extern void dumpnfa (int); - -/* finish up the processing for a rule */ -extern void finish_rule (int, int, int, int); - -/* connect two machines together */ -extern int link_machines (int, int); - -/* mark each "beginning" state in a machine as being a "normal" (i.e., - * not trailing context associated) state - */ -extern void mark_beginning_as_normal (int); - -/* make a machine that branches to two machines */ -extern int mkbranch (int, int); - -extern int mkclos (int); /* convert a machine into a closure */ -extern int mkopt (int); /* make a machine optional */ - -/* make a machine that matches either one of two machines */ -extern int mkor (int, int); - -/* convert a machine into a positive closure */ -extern int mkposcl (int); - -extern int mkrep (int, int, int); /* make a replicated machine */ - -/* create a state with a transition on a given symbol */ -extern int mkstate (int); - -extern void new_rule (void); /* initialize for a new rule */ - - -/* from file parse.y */ - -/* write out a message formatted with one string, pinpointing its location */ -extern void format_pinpoint_message (char[], char[]); - -/* write out a message, pinpointing its location */ -extern void pinpoint_message (char[]); - -extern void synerr (char []); /* report a syntax error */ -/* extern int yyparse ();*/ /* the YACC parser */ - - -/* from file scan.l */ - -extern int flexscan (); /* the Flex-generated scanner for flex */ - -/* open the given file (if NULL, stdin) for scanning */ -extern void set_input_file (char*); - -extern int yywrap (); /* wrapup a file in the lexical analyzer */ - - -/* from file sym.c */ - -/* save the text of a character class */ -extern void cclinstal (Char [], int); - -/* lookup the number associated with character class */ -extern int ccllookup (Char []); - -extern void ndinstal (char[], Char[]); /* install a name definition */ -extern void scinstal (char[], int); /* make a start condition */ - -/* lookup the number associated with a start condition */ -extern int sclookup (char[]); - - -/* from file tblcmp.c */ - -/* build table entries for dfa state */ -extern void bldtbl (int[], int, int, int, int); - -extern void cmptmps (void); /* compress template table entries */ -extern void inittbl (void); /* initialize transition tables */ -extern void mkdeftbl (void); /* make the default, "jam" table entries */ - -/* create table entries for a state (or state fragment) which has - * only one out-transition */ -extern void mk1tbl (int, int, int, int); - -/* place a state into full speed transition table */ -extern void place_state (int*, int, int); - -/* save states with only one out-transition to be processed later */ -extern void stack1 (int, int, int, int); - - -/* from file yylex.c */ - -extern int yylex (); - - -/* The Unix kernel calls used here */ - -extern int read (int, char*, int); -#ifndef _WIN32 -extern int unlink (char*); -#endif -extern int write (int, char*, int); - - -#endif /* INC_flexdef_H */ - diff --git a/src/libCom/flex/flexdoc.html b/src/libCom/flex/flexdoc.html deleted file mode 100644 index 30ed69521..000000000 --- a/src/libCom/flex/flexdoc.html +++ /dev/null @@ -1,1881 +0,0 @@ - - -
-
-
-
-

NAME

-     flex - fast lexical analyzer generator
-
-
-
-

SYNOPSIS

-     flex [-bcdfinpstvFILT8 -C[efmF] -Sskeleton] [filename ...]
-
-
-
-

DESCRIPTION

-     flex is a  tool  for  generating  scanners:  programs  which
-     recognized  lexical  patterns in text.  flex reads the given
-     input files, or its standard input  if  no  file  names  are
-     given,  for  a  description  of  a scanner to generate.  The
-     description is in the form of pairs of  regular  expressions
-     and  C  code,  called  rules.  flex  generates as output a C
-     source file, lex.yy.c, which defines a routine yylex(). This
-     file is compiled and linked with the -lfl library to produce
-     an executable.  When the executable is run, it analyzes  its
-     input  for occurrences of the regular expressions.  Whenever
-     it finds one, it executes the corresponding C code.
-
-
-
-

SOME SIMPLE EXAMPLES

-     First some simple examples to get the flavor of how one uses
-     flex.  The  following  flex  input specifies a scanner which
-     whenever it encounters the string "username" will replace it
-     with the user's login name:
-
-         %%
-         username    printf( "%s", getlogin() );
-
-     By default, any text not matched by a flex scanner is copied
-     to  the output, so the net effect of this scanner is to copy
-     its input file to its output with each occurrence of  "user-
-     name"  expanded.   In  this  input,  there is just one rule.
-     "username" is the pattern and the "printf"  is  the  action.
-     The "%%" marks the beginning of the rules.
-
-     Here's another simple example:
-
-             int num_lines = 0, num_chars = 0;
-
-         %%
-         \n    ++num_lines; ++num_chars;
-         .     ++num_chars;
-
-         %%
-         main()
-             {
-             yylex();
-             printf( "# of lines = %d, # of chars = %d\n",
-                     num_lines, num_chars );
-             }
-
-     This scanner counts the number of characters and the  number
-     of  lines in its input (it produces no output other than the
-     final report on the counts).  The first  line  declares  two
-     globals,  "num_lines"  and "num_chars", which are accessible
-     both inside yylex() and in the main() routine declared after
-     the  second  "%%".  There are two rules, one which matches a
-     newline ("\n") and increments both the line  count  and  the
-     character  count,  and one which matches any character other
-     than a newline (indicated by the "." regular expression).
-
-     A somewhat more complicated example:
-
-         /* scanner for a toy Pascal-like language */
-
-         %{
-         /* need this for the call to atof() below */
-         #include <math.h>
-         %}
-
-         DIGIT    [0-9]
-         ID       [a-z][a-z0-9]*
-
-         %%
-
-         {DIGIT}+    {
-                     printf( "An integer: %s (%d)\n", yytext,
-                             atoi( yytext ) );
-                     }
-
-         {DIGIT}+"."{DIGIT}*        {
-                     printf( "A float: %s (%g)\n", yytext,
-                             atof( yytext ) );
-                     }
-
-         if|then|begin|end|procedure|function        {
-                     printf( "A keyword: %s\n", yytext );
-                     }
-
-         {ID}        printf( "An identifier: %s\n", yytext );
-
-         "+"|"-"|"*"|"/"   printf( "An operator: %s\n", yytext );
-
-         "{"[^}\n]*"}"     /* eat up one-line comments */
-
-         [ \t\n]+          /* eat up whitespace */
-
-         .           printf( "Unrecognized character: %s\n", yytext );
-
-         %%
-
-         main( argc, argv )
-         int argc;
-         char **argv;
-             {
-             ++argv, --argc;  /* skip over program name */
-             if ( argc > 0 )
-                     yyin = fopen( argv[0], "r" );
-             else
-                     yyin = stdin;
-
-             yylex();
-             }
-
-     This is the beginnings of a simple scanner  for  a  language
-     like  Pascal.   It  identifies different types of tokens and
-     reports on what it has seen.
-
-     The details of this example will be explained in the follow-
-     ing sections.
-
-
-
-

FORMAT OF THE INPUT FILE

-     The flex input file consists of three sections, separated by
-     a line with just %% in it:
-
-         definitions
-         %%
-         rules
-         %%
-         user code
-
-     The definitions section contains declarations of simple name
-     definitions  to  simplify  the  scanner  specification,  and
-     declarations of start conditions, which are explained  in  a
-     later section.
-
-     Name definitions have the form:
-
-         name definition
-
-     The "name" is a word beginning with a letter  or  an  under-
-     score  ('_')  followed by zero or more letters, digits, '_',
-     or '-' (dash).  The definition is  taken  to  begin  at  the
-     first  non-white-space character following the name and con-
-     tinuing to the end of the line.  The definition  can  subse-
-     quently  be referred to using "{name}", which will expand to
-     "(definition)".  For example,
-
-         DIGIT    [0-9]
-         ID       [a-z][a-z0-9]*
-
-     defines "DIGIT" to be a regular expression which  matches  a
-     single  digit,  and  "ID"  to  be a regular expression which
-     matches a letter followed by zero-or-more letters-or-digits.
-     A subsequent reference to
-
-         {DIGIT}+"."{DIGIT}*
-
-     is identical to
-
-         ([0-9])+"."([0-9])*
-
-     and matches one-or-more digits followed by a '.' followed by
-     zero-or-more digits.
-
-     The rules section of the flex input  contains  a  series  of
-     rules of the form:
-
-         pattern   action
-
-     where the pattern must be unindented  and  the  action  must
-     begin on the same line.
-
-     See below for a further description of patterns and actions.
-
-     Finally, the user code section is simply copied to  lex.yy.c
-     verbatim.   It  is used for companion routines which call or
-     are called by the scanner.  The presence of this section  is
-     optional;  if it is missing, the second %% in the input file
-     may be skipped, too.
-
-     In the definitions and rules sections, any indented text  or
-     text  enclosed in %{ and %} is copied verbatim to the output
-     (with the %{}'s removed).  The %{}'s must appear  unindented
-     on lines by themselves.
-
-     In the rules section, any indented  or  %{}  text  appearing
-     before the first rule may be used to declare variables which
-     are local to the scanning routine and  (after  the  declara-
-     tions)  code  which  is to be executed whenever the scanning
-     routine is entered.  Other indented or %{} text in the  rule
-     section  is  still  copied to the output, but its meaning is
-     not well-defined and it may well cause  compile-time  errors
-     (this feature is present for POSIX compliance; see below for
-     other such features).
-
-     In the definitions section, an unindented comment  (i.e.,  a
-     line  beginning  with  "/*")  is also copied verbatim to the
-     output up to the next "*/".  Also, any line in  the  defini-
-     tions  section  beginning  with  '#' is ignored, though this
-     style of comment is  deprecated  and  may  go  away  in  the
-     future.
-
-
-
-

PATTERNS

-     The patterns in the input are written using an extended  set
-     of regular expressions.  These are:
-
-         x          match the character 'x'
-         .          any character except newline
-         [xyz]      a "character class"; in this case, the pattern
-                      matches either an 'x', a 'y', or a 'z'
-         [abj-oZ]   a "character class" with a range in it; matches
-                      an 'a', a 'b', any letter from 'j' through 'o',
-                      or a 'Z'
-         [^A-Z]     a "negated character class", i.e., any character
-                      but those in the class.  In this case, any
-                      character EXCEPT an uppercase letter.
-         [^A-Z\n]   any character EXCEPT an uppercase letter or
-                      a newline
-         r*         zero or more r's, where r is any regular expression
-         r+         one or more r's
-         r?         zero or one r's (that is, "an optional r")
-         r{2,5}     anywhere from two to five r's
-         r{2,}      two or more r's
-         r{4}       exactly 4 r's
-         {name}     the expansion of the "name" definition
-                    (see above)
-         "[xyz]\"foo"
-                    the literal string: [xyz]"foo
-         \X         if X is an 'a', 'b', 'f', 'n', 'r', 't', or 'v',
-                      then the ANSI-C interpretation of \x.
-                      Otherwise, a literal 'X' (used to escape
-                      operators such as '*')
-         \123       the character with octal value 123
-         \x2a       the character with hexadecimal value 2a
-         (r)        match an r; parentheses are used to override
-                      precedence (see below)
-
-
-         rs         the regular expression r followed by the
-                      regular expression s; called "concatenation"
-
-
-         r|s        either an r or an s
-
-
-         r/s        an r but only if it is followed by an s.  The
-                      s is not part of the matched text.  This type
-                      of pattern is called as "trailing context".
-         ^r         an r, but only at the beginning of a line
-         r$         an r, but only at the end of a line.  Equivalent
-                      to "r/\n".
-
-
-         <s>r       an r, but only in start condition s (see
-                    below for discussion of start conditions)
-         <s1,s2,s3>r
-                    same, but in any of start conditions s1,
-                    s2, or s3
-
-         <<EOF>>    an end-of-file
-         <s1,s2><<EOF>>
-                    an end-of-file when in start condition s1 or s2
-
-     The regular expressions listed above are  grouped  according
-     to  precedence, from highest precedence at the top to lowest
-     at the bottom.   Those  grouped  together  have  equal  pre-
-     cedence.  For example,
-
-         foo|bar*
-
-     is the same as
-
-         (foo)|(ba(r*))
-
-     since the '*' operator has higher precedence than concatena-
-     tion, and concatenation higher than alternation ('|').  This
-     pattern therefore matches either the  string  "foo"  or  the
-     string "ba" followed by zero-or-more r's.  To match "foo" or
-     zero-or-more "bar"'s, use:
-
-         foo|(bar)*
-
-     and to match zero-or-more "foo"'s-or-"bar"'s:
-
-         (foo|bar)*
-
-
-     Some notes on patterns:
-
-     -    A negated character class such as the example  "[^A-Z]"
-          above   will   match  a  newline  unless  "\n"  (or  an
-          equivalent escape sequence) is one  of  the  characters
-          explicitly  present  in  the  negated  character  class
-          (e.g., "[^A-Z\n]").  This is unlike how many other reg-
-          ular  expression tools treat negated character classes,
-          but unfortunately  the  inconsistency  is  historically
-          entrenched.   Matching  newlines  means  that a pattern
-          like [^"]* can match an entire input  (overflowing  the
-          scanner's input buffer) unless there's another quote in
-          the input.
-
-     -    A rule can have at most one instance of  trailing  con-
-          text (the '/' operator or the '$' operator).  The start
-          condition, '^', and "<<EOF>>" patterns can  only  occur
-          at the beginning of a pattern, and, as well as with '/'
-          and '$', cannot be grouped inside parentheses.   A  '^'
-          which  does  not  occur at the beginning of a rule or a
-          '$' which does not occur at the end of a rule loses its
-          special  properties  and is treated as a normal charac-
-          ter.
-
-          The following are illegal:
-
-              foo/bar$
-              <sc1>foo<sc2>bar
-
-          Note  that  the  first  of  these,   can   be   written
-          "foo/bar\n".
-
-          The following will result in '$' or '^'  being  treated
-          as a normal character:
-
-              foo|(bar$)
-              foo|^bar
-
-          If what's wanted is a  "foo"  or  a  bar-followed-by-a-
-          newline,  the  following could be used (the special '|'
-          action is explained below):
-
-              foo      |
-              bar$     /* action goes here */
-
-          A similar trick will work for matching a foo or a  bar-
-          at-the-beginning-of-a-line.
-
-
-
-

HOW THE INPUT IS MATCHED

-     When the generated scanner is run,  it  analyzes  its  input
-     looking  for strings which match any of its patterns.  If it
-     finds more than one match, it takes  the  one  matching  the
-     most  text  (for  trailing  context rules, this includes the
-     length of the trailing part, even though  it  will  then  be
-     returned  to the input).  If it finds two or more matches of
-     the same length, the rule listed first  in  the  flex  input
-     file is chosen.
-
-     Once the match is determined, the text corresponding to  the
-     match  (called  the  token)  is made available in the global
-     character pointer yytext,  and  its  length  in  the  global
-     integer yyleng. The action corresponding to the matched pat-
-     tern is  then  executed  (a  more  detailed  description  of
-     actions  follows),  and  then the remaining input is scanned
-     for another match.
-
-     If no match is found, then the default rule is executed: the
-     next character in the input is considered matched and copied
-     to the standard output.  Thus, the simplest legal flex input
-     is:
-
-         %%
-
-     which generates a scanner that simply copies its input  (one
-     character at a time) to its output.
-
-
-
-

ACTIONS

-     Each pattern in a rule has a corresponding action, which can
-     be any arbitrary C statement.  The pattern ends at the first
-     non-escaped whitespace character; the remainder of the  line
-     is  its  action.  If the action is empty, then when the pat-
-     tern is matched the input token is  simply  discarded.   For
-     example,  here  is  the  specification  for  a program which
-     deletes all occurrences of "zap me" from its input:
-
-         %%
-         "zap me"
-
-     (It will copy all other characters in the input to the  out-
-     put since they will be matched by the default rule.)
-
-     Here is a program which compresses multiple blanks and  tabs
-     down  to a single blank, and throws away whitespace found at
-     the end of a line:
-
-         %%
-         [ \t]+        putchar( ' ' );
-         [ \t]+$       /* ignore this token */
-
-
-     If the action contains a '{', then the action spans till the
-     balancing  '}'  is  found, and the action may cross multiple
-     lines.  flex knows about C strings and comments and won't be
-     fooled  by braces found within them, but also allows actions
-     to begin with %{ and will consider the action to be all  the
-     text up to the next %} (regardless of ordinary braces inside
-     the action).
-
-     An action consisting solely of a vertical  bar  ('|')  means
-     "same  as  the  action for the next rule."  See below for an
-     illustration.
-
-     Actions can  include  arbitrary  C  code,  including  return
-     statements  to  return  a  value  to whatever routine called
-     yylex(). Each time yylex() is called it continues processing
-     tokens  from  where it last left off until it either reaches
-     the end of the file or executes a return.  Once  it  reaches
-     an end-of-file, however, then any subsequent call to yylex()
-     will simply immediately return, unless yyrestart() is  first
-     called (see below).
-
-     Actions are not allowed to modify yytext or yyleng.
-
-     There are a  number  of  special  directives  which  can  be
-     included within an action:
-
-     -    ECHO copies yytext to the scanner's output.
-
-     -    BEGIN followed by the name of a start condition  places
-          the  scanner  in the corresponding start condition (see
-          below).
-
-     -    REJECT directs the scanner to proceed on to the "second
-          best"  rule which matched the input (or a prefix of the
-          input).  The rule is chosen as described above in  "How
-          the  Input  is  Matched",  and yytext and yyleng set up
-          appropriately.  It may either be one which  matched  as
-          much  text as the originally chosen rule but came later
-          in the flex input file, or one which matched less text.
-          For example, the following will both count the words in
-          the input  and  call  the  routine  special()  whenever
-          "frob" is seen:
-
-                      int word_count = 0;
-              %%
-
-              frob        special(); REJECT;
-              [^ \t\n]+   ++word_count;
-
-          Without the REJECT, any "frob"'s in the input would not
-          be  counted  as  words, since the scanner normally exe-
-          cutes only one action per token.  Multiple REJECT's are
-          allowed,  each  one finding the next best choice to the
-          currently active rule.  For example, when the following
-          scanner  scans the token "abcd", it will write "abcdab-
-          caba" to the output:
-
-              %%
-              a        |
-              ab       |
-              abc      |
-              abcd     ECHO; REJECT;
-              .|\n     /* eat up any unmatched character */
-
-          (The first three rules share the fourth's action  since
-          they use the special '|' action.)  REJECT is a particu-
-          larly expensive feature in terms  scanner  performance;
-          if  it  is used in any of the scanner's actions it will
-          slow down all of the scanner's matching.   Furthermore,
-          REJECT  cannot  be  used with the -f or -F options (see
-          below).
-
-          Note also that unlike the other special actions, REJECT
-          is  a  branch;  code  immediately  following  it in the
-          action will not be executed.
-
-     -    yymore() tells  the  scanner  that  the  next  time  it
-          matches  a  rule,  the  corresponding  token  should be
-          appended onto the current value of yytext  rather  than
-          replacing  it.   For  example,  given  the input "mega-
-          kludge" the following will write "mega-mega-kludge"  to
-          the output:
-
-              %%
-              mega-    ECHO; yymore();
-              kludge   ECHO;
-
-          First "mega-" is matched  and  echoed  to  the  output.
-          Then  "kludge"  is matched, but the previous "mega-" is
-          still hanging around at the beginning of yytext so  the
-          ECHO  for  the "kludge" rule will actually write "mega-
-          kludge".  The presence of  yymore()  in  the  scanner's
-          action  entails  a  minor  performance  penalty  in the
-          scanner's matching speed.
-
-     -    yyless(n) returns all but the first n characters of the
-          current token back to the input stream, where they will
-          be rescanned when the scanner looks for the next match.
-          yytext  and  yyleng  are  adjusted appropriately (e.g.,
-          yyleng will now be equal to n ).  For example,  on  the
-          input  "foobar"  the  following will write out "foobar-
-          bar":
-
-              %%
-              foobar    ECHO; yyless(3);
-              [a-z]+    ECHO;
-
-          An argument of  0  to  yyless  will  cause  the  entire
-          current  input  string  to  be  scanned  again.  Unless
-          you've changed how the scanner will  subsequently  pro-
-          cess  its  input  (using BEGIN, for example), this will
-          result in an endless loop.
-
-     -    unput(c) puts the  character  c  back  onto  the  input
-          stream.   It  will  be the next character scanned.  The
-          following action will take the current token and  cause
-          it to be rescanned enclosed in parentheses.
-
-              {
-              int i;
-              unput( ')' );
-              for ( i = yyleng - 1; i >= 0; --i )
-                  unput( yytext[i] );
-              unput( '(' );
-              }
-
-          Note that since each unput() puts the  given  character
-          back at the beginning of the input stream, pushing back
-          strings must be done back-to-front.
-
-     -    input() reads the next character from the input stream.
-          For  example,  the  following  is  one  way to eat up C
-          comments:
-
-              %%
-              "/*"        {
-                          register int c;
-
-                          for ( ; ; )
-                              {
-                              while ( (c = input()) != '*' &&
-                                      c != EOF )
-                                  ;    /* eat up text of comment */
-
-                              if ( c == '*' )
-                                  {
-                                  while ( (c = input()) == '*' )
-                                      ;
-                                  if ( c == '/' )
-                                      break;    /* found the end */
-                                  }
-
-                              if ( c == EOF )
-                                  {
-                                  error( "EOF in comment" );
-                                  break;
-                                  }
-                              }
-                          }
-
-          (Note that if the scanner is compiled using  C++,  then
-          input()  is  instead referred to as yyinput(), in order
-          to avoid a name clash with the C++ stream by  the  name
-          of input.)
-
-     -    yyterminate() can be used in lieu of a return statement
-          in  an action.  It terminates the scanner and returns a
-          0 to the scanner's caller, indicating "all done".  Sub-
-          sequent  calls  to  the scanner will immediately return
-          unless preceded by a call to yyrestart()  (see  below).
-          By  default,  yyterminate() is also called when an end-
-          of-file is encountered.  It is a macro and may be rede-
-          fined.
-
-
-
-

THE GENERATED SCANNER

-     The output of flex is the file lex.yy.c, which contains  the
-     scanning  routine yylex(), a number of tables used by it for
-     matching tokens, and a number of auxiliary routines and mac-
-     ros.  By default, yylex() is declared as follows:
-
-         int yylex()
-             {
-             ... various definitions and the actions in here ...
-             }
-
-     (If your environment supports function prototypes,  then  it
-     will  be  "int  yylex(  void  )".)   This  definition may be
-     changed by redefining the "YY_DECL" macro.  For example, you
-     could use:
-
-         #undef YY_DECL
-         #define YY_DECL float lexscan( a, b ) float a, b;
-
-     to give the scanning routine the name lexscan,  returning  a
-     float, and taking two floats as arguments.  Note that if you
-     give  arguments  to  the  scanning  routine  using  a   K&R-
-     style/non-prototyped  function  declaration,  you  must ter-
-     minate the definition with a semi-colon (;).
-
-     Whenever yylex() is called, it scans tokens from the  global
-     input  file  yyin  (which  defaults to stdin).  It continues
-     until it either reaches an end-of-file (at  which  point  it
-     returns the value 0) or one of its actions executes a return
-     statement.  In  the  former  case,  when  called  again  the
-     scanner will immediately return unless yyrestart() is called
-     to point yyin at the new input file.   (  yyrestart()  takes
-     one  argument, a FILE * pointer.)  In the latter case (i.e.,
-     when an action executes a return), the scanner may  then  be
-     called again and it will resume scanning where it left off.
-
-     By default (and for purposes  of  efficiency),  the  scanner
-     uses  block-reads  rather  than  simple getc() calls to read
-     characters from yyin. The nature of how it  gets  its  input
-     can   be   controlled  by  redefining  the  YY_INPUT  macro.
-     YY_INPUT's           calling           sequence           is
-     "YY_INPUT(buf,result,max_size)".   Its action is to place up
-     to max_size characters in the character array buf and return
-     in  the integer variable result either the number of charac-
-     ters read or the constant YY_NULL (0  on  Unix  systems)  to
-     indicate  EOF.   The  default YY_INPUT reads from the global
-     file-pointer "yyin".
-
-     A sample redefinition of YY_INPUT (in the  definitions  sec-
-     tion of the input file):
-
-         %{
-         #undef YY_INPUT
-         #define YY_INPUT(buf,result,max_size) \
-             { \
-             int c = getchar(); \
-             result = (c == EOF) ? YY_NULL : (buf[0] = c, 1); \
-             }
-         %}
-
-     This definition will change the input  processing  to  occur
-     one character at a time.
-
-     You also can add in things like keeping track of  the  input
-     line  number  this  way; but don't expect your scanner to go
-     very fast.
-
-     When the scanner receives  an  end-of-file  indication  from
-     YY_INPUT, it then checks the yywrap() function.  If yywrap()
-     returns false (zero), then it is assumed that  the  function
-     has  gone  ahead  and  set up yyin to point to another input
-     file, and scanning continues.   If  it  returns  true  (non-
-     zero),  then  the  scanner  terminates,  returning  0 to its
-     caller.
-
-     The default yywrap() always returns 1.  Presently, to  rede-
-     fine  it  you must first "#undef yywrap", as it is currently
-     implemented as a macro.  As indicated by the hedging in  the
-     previous  sentence,  it may be changed to a true function in
-     the near future.
-
-     The scanner writes its  ECHO  output  to  the  yyout  global
-     (default, stdout), which may be redefined by the user simply
-     by assigning it to some other FILE pointer.
-
-
-
-

START CONDITIONS

-     flex  provides  a  mechanism  for  conditionally  activating
-     rules.   Any rule whose pattern is prefixed with "<sc>" will
-     only be active when the scanner is in  the  start  condition
-     named "sc".  For example,
-
-         <STRING>[^"]*        { /* eat up the string body ... */
-                     ...
-                     }
-
-     will be active only when the  scanner  is  in  the  "STRING"
-     start condition, and
-
-         <INITIAL,STRING,QUOTE>\.        { /* handle an escape ... */
-                     ...
-                     }
-
-     will be active only when  the  current  start  condition  is
-     either "INITIAL", "STRING", or "QUOTE".
-
-     Start conditions are declared  in  the  definitions  (first)
-     section  of  the input using unindented lines beginning with
-     either %s or %x followed by a list  of  names.   The  former
-     declares  inclusive  start  conditions, the latter exclusive
-     start conditions.  A start condition is activated using  the
-     BEGIN  action.   Until  the  next  BEGIN action is executed,
-     rules with the given start  condition  will  be  active  and
-     rules  with other start conditions will be inactive.  If the
-     start condition is inclusive, then rules with no start  con-
-     ditions  at  all  will  also be active.  If it is exclusive,
-     then only rules qualified with the start condition  will  be
-     active.   A  set  of  rules contingent on the same exclusive
-     start condition describe a scanner which is  independent  of
-     any  of the other rules in the flex input.  Because of this,
-     exclusive start conditions make it easy  to  specify  "mini-
-     scanners"  which scan portions of the input that are syntac-
-     tically different from the rest (e.g., comments).
-
-     If the distinction between  inclusive  and  exclusive  start
-     conditions  is still a little vague, here's a simple example
-     illustrating the connection between the  two.   The  set  of
-     rules:
-
-         %s example
-         %%
-         <example>foo           /* do something */
-
-     is equivalent to
-
-         %x example
-         %%
-         <INITIAL,example>foo   /* do something */
-
-
-     The default rule (to ECHO any unmatched  character)  remains
-     active in start conditions.
-
-     BEGIN(0) returns to the original state where only the  rules
-     with no start conditions are active.  This state can also be
-     referred   to   as   the   start-condition   "INITIAL",   so
-     BEGIN(INITIAL)  is  equivalent to BEGIN(0). (The parentheses
-     around the start condition name are  not  required  but  are
-     considered good style.)
-
-     BEGIN actions can also be given  as  indented  code  at  the
-     beginning  of the rules section.  For example, the following
-     will cause the scanner to enter the "SPECIAL"  start  condi-
-     tion  whenever  yylex()  is  called  and the global variable
-     enter_special is true:
-
-                 int enter_special;
-
-         %x SPECIAL
-         %%
-                 if ( enter_special )
-                     BEGIN(SPECIAL);
-
-         <SPECIAL>blahblahblah
-         ...more rules follow...
-
-
-
-     To illustrate the  uses  of  start  conditions,  here  is  a
-     scanner  which  provides  two different interpretations of a
-     string like "123.456".  By default it will treat  it  as  as
-     three  tokens,  the  integer  "123",  a  dot  ('.'), and the
-     integer "456".  But if the string is preceded earlier in the
-     line  by  the  string  "expect-floats" it will treat it as a
-     single token, the floating-point number 123.456:
-
-         %{
-         #include <math.h>
-         %}
-         %s expect
-
-         %%
-         expect-floats        BEGIN(expect);
-
-         <expect>[0-9]+"."[0-9]+      {
-                     printf( "found a float, = %f\n",
-                             atof( yytext ) );
-                     }
-         <expect>\n           {
-                     /* that's the end of the line, so
-                      * we need another "expect-number"
-                      * before we'll recognize any more
-                      * numbers
-                      */
-                     BEGIN(INITIAL);
-                     }
-
-         [0-9]+      {
-                     printf( "found an integer, = %d\n",
-                             atoi( yytext ) );
-                     }
-
-         "."         printf( "found a dot\n" );
-
-     Here is a scanner which recognizes (and discards) C comments
-     while maintaining a count of the current input line.
-
-         %x comment
-         %%
-                 int line_num = 1;
-
-         "/*"         BEGIN(comment);
-
-         <comment>[^*\n]*        /* eat anything that's not a '*' */
-         <comment>"*"+[^*/\n]*   /* eat up '*'s not followed by '/'s */
-         <comment>\n             ++line_num;
-         <comment>"*"+"/"        BEGIN(INITIAL);
-
-     Note that start-conditions names are really  integer  values
-     and  can  be  stored  as  such.   Thus,  the  above could be
-     extended in the following fashion:
-
-         %x comment foo
-         %%
-                 int line_num = 1;
-                 int comment_caller;
-
-         "/*"         {
-                      comment_caller = INITIAL;
-                      BEGIN(comment);
-                      }
-
-         ...
-
-         <foo>"/*"    {
-                      comment_caller = foo;
-                      BEGIN(comment);
-                      }
-
-         <comment>[^*\n]*        /* eat anything that's not a '*' */
-         <comment>"*"+[^*/\n]*   /* eat up '*'s not followed by '/'s */
-         <comment>\n             ++line_num;
-         <comment>"*"+"/"        BEGIN(comment_caller);
-
-     One can then implement a "stack" of start  conditions  using
-     an  array  of integers.  (It is likely that such stacks will
-     become a full-fledged flex feature in  the  future.)   Note,
-     though,  that  start  conditions do not have their own name-
-     space; %s's and %x's declare names in the  same  fashion  as
-     #define's.
-
-
-
-

MULTIPLE INPUT BUFFERS

-     Some scanners (such as those which support "include"  files)
-     require   reading  from  several  input  streams.   As  flex
-     scanners do a large amount of buffering, one cannot  control
-     where  the  next input will be read from by simply writing a
-     YY_INPUT  which  is  sensitive  to  the  scanning   context.
-     YY_INPUT  is only called when the scanner reaches the end of
-     its buffer, which may be a long time after scanning a state-
-     ment such as an "include" which requires switching the input
-     source.
-
-     To negotiate  these  sorts  of  problems,  flex  provides  a
-     mechanism  for creating and switching between multiple input
-     buffers.  An input buffer is created by using:
-
-         YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
-
-     which takes a FILE pointer and a size and creates  a  buffer
-     associated with the given file and large enough to hold size
-     characters (when in doubt, use YY_BUF_SIZE  for  the  size).
-     It  returns  a  YY_BUFFER_STATE  handle,  which  may then be
-     passed to other routines:
-
-         void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
-
-     switches the scanner's input  buffer  so  subsequent  tokens
-     will  come  from new_buffer. Note that yy_switch_to_buffer()
-     may be used by yywrap() to  sets  things  up  for  continued
-     scanning, instead of opening a new file and pointing yyin at
-     it.
-
-         void yy_delete_buffer( YY_BUFFER_STATE buffer )
-
-     is used to reclaim the storage associated with a buffer.
-
-     yy_new_buffer() is an alias for yy_create_buffer(), provided
-     for  compatibility  with  the  C++ use of new and delete for
-     creating and destroying dynamic objects.
-
-     Finally,   the    YY_CURRENT_BUFFER    macro    returns    a
-     YY_BUFFER_STATE handle to the current buffer.
-
-     Here is an example of using these  features  for  writing  a
-     scanner  which expands include files (the <<EOF>> feature is
-     discussed below):
-
-         /* the "incl" state is used for picking up the name
-          * of an include file
-          */
-         %x incl
-
-         %{
-         #define MAX_INCLUDE_DEPTH 10
-         YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
-         int include_stack_ptr = 0;
-         %}
-
-         %%
-         include             BEGIN(incl);
-
-         [a-z]+              ECHO;
-         [^a-z\n]*\n?        ECHO;
-
-         <incl>[ \t]*      /* eat the whitespace */
-         <incl>[^ \t\n]+   { /* got the include file name */
-                 if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
-                     {
-                     fprintf( stderr, "Includes nested too deeply" );
-                     exit( 1 );
-                     }
-
-                 include_stack[include_stack_ptr++] =
-                     YY_CURRENT_BUFFER;
-
-                 yyin = fopen( yytext, "r" );
-
-                 if ( ! yyin )
-                     error( ... );
-
-                 yy_switch_to_buffer(
-                     yy_create_buffer( yyin, YY_BUF_SIZE ) );
-
-                 BEGIN(INITIAL);
-                 }
-
-         <<EOF>> {
-                 if ( --include_stack_ptr < 0 )
-                     {
-                     yyterminate();
-                     }
-
-                 else
-                     yy_switch_to_buffer(
-                          include_stack[include_stack_ptr] );
-                 }
-
-
-
-
-

END-OF-FILE RULES

-     The special rule "<<EOF>>" indicates actions which are to be
-     taken  when  an  end-of-file  is  encountered  and  yywrap()
-     returns non-zero (i.e., indicates no further files  to  pro-
-     cess).  The action must finish by doing one of four things:
-
-     -    the  special  YY_NEW_FILE  action,  if  yyin  has  been
-          pointed at a new file to process;
-
-     -    a return statement;
-
-     -    the special yyterminate() action;
-
-     -    or,    switching    to    a    new     buffer     using
-          yy_switch_to_buffer() as shown in the example above.
-
-     <<EOF>> rules may not be used with other patterns; they  may
-     only  be  qualified  with a list of start conditions.  If an
-     unqualified <<EOF>> rule is given, it applies to  all  start
-     conditions  which  do  not already have <<EOF>> actions.  To
-     specify an <<EOF>> rule for only the  initial  start  condi-
-     tion, use
-
-         <INITIAL><<EOF>>
-
-
-     These rules are useful for  catching  things  like  unclosed
-     comments.  An example:
-
-         %x quote
-         %%
-
-         ...other rules for dealing with quotes...
-
-         <quote><<EOF>>   {
-                  error( "unterminated quote" );
-                  yyterminate();
-                  }
-         <<EOF>>  {
-                  if ( *++filelist )
-                      {
-                      yyin = fopen( *filelist, "r" );
-                      YY_NEW_FILE;
-                      }
-                  else
-                     yyterminate();
-                  }
-
-
-
-
-

MISCELLANEOUS MACROS

-     The macro YY_USER_ACTION can  be  redefined  to  provide  an
-     action  which is always executed prior to the matched rule's
-     action.  For example, it could be #define'd to call  a  rou-
-     tine to convert yytext to lower-case.
-
-     The macro YY_USER_INIT may be redefined to provide an action
-     which  is  always executed before the first scan (and before
-     the scanner's internal initializations are done).  For exam-
-     ple,  it  could  be used to call a routine to read in a data
-     table or open a logging file.
-
-     In the generated scanner, the actions are  all  gathered  in
-     one  large  switch  statement  and separated using YY_BREAK,
-     which may be redefined.  By default, it is simply a "break",
-     to  separate  each  rule's action from the following rule's.
-     Redefining  YY_BREAK  allows,  for  example,  C++  users  to
-     #define  YY_BREAK  to  do  nothing (while being very careful
-     that every rule ends with a "break" or a "return"!) to avoid
-     suffering  from unreachable statement warnings where because
-     a rule's action ends with "return", the YY_BREAK is inacces-
-     sible.
-
-
-
-

INTERFACING WITH YACC

-     One of the main uses of flex is as a companion to  the  yacc
-     parser-generator.   yacc  parsers  expect  to call a routine
-     named yylex() to find the next input token.  The routine  is
-     supposed  to  return  the  type of the next token as well as
-     putting any associated value in the global  yylval.  To  use
-     flex  with  yacc,  one  specifies  the  -d option to yacc to
-     instruct it to generate the file y.tab.h containing  defini-
-     tions  of all the %tokens appearing in the yacc input.  This
-     file is then included in the flex scanner.  For example,  if
-     one of the tokens is "TOK_NUMBER", part of the scanner might
-     look like:
-
-         %{
-         #include "y.tab.h"
-         %}
-
-         %%
-
-         [0-9]+        yylval = atoi( yytext ); return TOK_NUMBER;
-
-
-
-
-

TRANSLATION TABLE

-     In the name of POSIX compliance, flex supports a translation
-     table  for  mapping input characters into groups.  The table
-     is specified in the first  section,  and  its  format  looks
-     like:
-
-         %t
-         1        abcd
-         2        ABCDEFGHIJKLMNOPQRSTUVWXYZ
-         52       0123456789
-         6        \t\ \n
-         %t
-
-     This example specifies that the characters  'a',  'b',  'c',
-     and  'd'  are  to  all  be  lumped into group #1, upper-case
-     letters in group #2, digits in group #52, tabs, blanks,  and
-     newlines  into group #6, and no other characters will appear
-     in the patterns.  The group numbers are actually disregarded
-     by  flex;  %t  serves,  though, to lump characters together.
-     Given the above table, for example, the pattern "a(AA)*5" is
-     equivalent  to "d(ZQ)*0".  They both say, "match any charac-
-     ter in group #1, followed by zero-or-more pairs  of  charac-
-     ters from group #2, followed by a character from group #52."
-     Thus %t provides a crude  way  for  introducing  equivalence
-     classes into the scanner specification.
-
-     Note that  the  -i  option  (see  below)  coupled  with  the
-     equivalence  classes which flex automatically generates take
-     care of virtually all the instances when one might  consider
-     using %t. But what the hell, it's there if you want it.
-
-
-
-

OPTIONS

-     flex has the following options:
-
-     -b   Generate  backtracking  information  to  lex.backtrack.
-          This  is  a  list of scanner states which require back-
-          tracking and the input characters on which they do  so.
-          By adding rules one can remove backtracking states.  If
-          all backtracking states are eliminated and -f or -F  is
-          used, the generated scanner will run faster (see the -p
-          flag).  Only users who wish to squeeze every last cycle
-          out  of  their  scanners  need worry about this option.
-          (See the section on PERFORMANCE CONSIDERATIONS below.)
-
-     -c   is a do-nothing, deprecated option included  for  POSIX
-          compliance.
-
-          NOTE: in previous releases of flex -c specified  table-
-          compression  options.   This functionality is now given
-          by the -C flag.  To ease the the impact of this change,
-          when  flex encounters -c, it currently issues a warning
-          message and assumes that -C was  desired  instead.   In
-          the future this "promotion" of -c to -C will go away in
-          the name of full POSIX  compliance  (unless  the  POSIX
-          meaning is removed first).
-
-     -d   makes the generated scanner run in debug  mode.   When-
-          ever   a   pattern   is   recognized   and  the  global
-          yy_flex_debug is non-zero (which is the  default),  the
-          scanner will write to stderr a line of the form:
-
-              --accepting rule at line 53 ("the matched text")
-
-          The line number refers to the location of the  rule  in
-          the  file defining the scanner (i.e., the file that was
-          fed to flex).  Messages are  also  generated  when  the
-          scanner  backtracks,  accepts the default rule, reaches
-          the end of its input buffer (or encounters  a  NUL;  at
-          this  point,  the  two  look  the  same  as  far as the
-          scanner's concerned), or reaches an end-of-file.
-
-     -f   specifies (take your pick) full table or fast  scanner.
-          No  table compression is done.  The result is large but
-          fast.  This option is equivalent to -Cf (see below).
-
-     -i   instructs flex to generate a case-insensitive  scanner.
-          The  case  of  letters given in the flex input patterns
-          will be ignored,  and  tokens  in  the  input  will  be
-          matched  regardless of case.  The matched text given in
-          yytext will have the preserved case (i.e., it will  not
-          be folded).
-
-     -n   is another do-nothing, deprecated option included  only
-          for POSIX compliance.
-
-     -p   generates a performance report to stderr.   The  report
-          consists  of  comments  regarding  features of the flex
-          input file which will cause a loss  of  performance  in
-          the resulting scanner.  Note that the use of REJECT and
-          variable trailing context  (see  the  BUGS  section  in
-          flex(1)) entails a substantial performance penalty; use
-          of yymore(), the ^ operator, and  the  -I  flag  entail
-          minor performance penalties.
-
-     -s   causes the default rule (that unmatched  scanner  input
-          is  echoed to stdout) to be suppressed.  If the scanner
-          encounters input that does not match any of its  rules,
-          it  aborts  with  an  error.  This option is useful for
-          finding holes in a scanner's rule set.
-
-     -t   instructs flex to write the  scanner  it  generates  to
-          standard output instead of lex.yy.c.
-
-     -v   specifies that flex should write to stderr a summary of
-          statistics regarding the scanner it generates.  Most of
-          the statistics are meaningless to the casual flex user,
-          but  the  first  line  identifies  the version of flex,
-          which is useful for figuring out where you  stand  with
-          respect  to  patches and new releases, and the next two
-          lines give the date when the scanner was created and  a
-          summary of the flags which were in effect.
-
-     -F   specifies that the fast  scanner  table  representation
-          should  be  used.  This representation is about as fast
-          as the full table representation  (-f),  and  for  some
-          sets  of patterns will be considerably smaller (and for
-          others, larger).  In general, if the pattern  set  con-
-          tains  both  "keywords"  and  a catch-all, "identifier"
-          rule, such as in the set:
-
-              "case"    return TOK_CASE;
-              "switch"  return TOK_SWITCH;
-              ...
-              "default" return TOK_DEFAULT;
-              [a-z]+    return TOK_ID;
-
-          then you're better off using the full table representa-
-          tion.  If only the "identifier" rule is present and you
-          then use a hash table or some such to detect  the  key-
-          words, you're better off using -F.
-
-          This option is equivalent to -CF (see below).
-
-     -I   instructs flex  to  generate  an  interactive  scanner.
-          Normally,  scanners generated by flex always look ahead
-          one character before deciding  that  a  rule  has  been
-          matched.   At  the cost of some scanning overhead, flex
-          will generate a scanner which  only  looks  ahead  when
-          needed.   Such  scanners are called interactive because
-          if you want to write a scanner for an interactive  sys-
-          tem such as a command shell, you will probably want the
-          user's input to  be  terminated  with  a  newline,  and
-          without  -I  the  user will have to type a character in
-          addition to the newline in order to  have  the  newline
-          recognized.  This leads to dreadful interactive perfor-
-          mance.
-
-          If all this seems  to  confusing,  here's  the  general
-          rule:  if  a  human  will  be  typing  in input to your
-          scanner, use -I, otherwise don't;  if  you  don't  care
-          about   squeezing  the  utmost  performance  from  your
-          scanner and you don't  want  to  make  any  assumptions
-          about the input to your scanner, use -I.
-
-          Note, -I cannot be used in  conjunction  with  full  or
-          fast tables, i.e., the -f, -F, -Cf, or -CF flags.
-
-     -L   instructs  flex  not  to  generate  #line   directives.
-          Without this option, flex peppers the generated scanner
-          with #line directives so error messages in the  actions
-          will  be correctly located with respect to the original
-          flex input file, and not to the fairly meaningless line
-          numbers  of  lex.yy.c.  (Unfortunately  flex  does  not
-          presently generate the necessary directives to  "retar-
-          get" the line numbers for those parts of lex.yy.c which
-          it generated.  So if there is an error in the generated
-          code, a meaningless line number is reported.)
-
-     -T   makes flex run in trace mode.  It will generate  a  lot
-          of  messages to stdout concerning the form of the input
-          and the resultant non-deterministic  and  deterministic
-          finite  automata.   This  option  is  mostly for use in
-          maintaining flex.
-
-     -8   instructs flex to generate an 8-bit scanner, i.e.,  one
-          which  can  recognize 8-bit characters.  On some sites,
-          flex is installed with this option as the default.   On
-          others,  the default is 7-bit characters.  To see which
-          is  the  case,  check  the  verbose  (-v)  output   for
-          "equivalence  classes  created".  If the denominator of
-          the number shown is 128, then by default flex  is  gen-
-          erating  7-bit  characters.   If  it  is  256, then the
-          default is 8-bit characters and  the  -8  flag  is  not
-          required  (but  may  be a good idea to keep the scanner
-          specification portable).  Feeding a 7-bit scanner 8-bit
-          characters  will  result in infinite loops, bus errors,
-          or other such fireworks, so  when  in  doubt,  use  the
-          flag.  Note that if equivalence classes are used, 8-bit
-          scanners take only slightly more table space than 7-bit
-          scanners  (128  bytes,  to  be  exact);  if equivalence
-          classes are not used, however, then the tables may grow
-          up to twice their 7-bit size.
-
-     -C[efmF]
-          controls the degree of table compression.
-          -Ce directs  flex  to  construct  equivalence  classes,
-          i.e.,  sets  of characters which have identical lexical
-          properties (for example,  if  the  only  appearance  of
-          digits  in  the  flex  input  is in the character class
-          "[0-9]" then the digits '0', '1', ..., '9' will all  be
-          put   in  the  same  equivalence  class).   Equivalence
-          classes usually give dramatic reductions in  the  final
-          table/object file sizes (typically a factor of 2-5) and
-          are pretty cheap performance-wise  (one  array  look-up
-          per character scanned).
-
-          -Cf specifies that the full scanner  tables  should  be
-          generated - flex should not compress the tables by tak-
-          ing advantages of similar transition functions for dif-
-          ferent states.
-
-          -CF specifies that the alternate fast scanner represen-
-          tation  (described  above  under the -F flag) should be
-          used.
-
-          -Cm directs flex to construct meta-equivalence classes,
-          which  are  sets of equivalence classes (or characters,
-          if equivalence classes are not  being  used)  that  are
-          commonly  used  together.  Meta-equivalence classes are
-          often a big win when using compressed tables, but  they
-          have  a  moderate  performance  impact (one or two "if"
-          tests and one array look-up per character scanned).
-
-          A lone -C specifies that the scanner tables  should  be
-          compressed  but  neither  equivalence classes nor meta-
-          equivalence classes should be used.
-
-          The options -Cf or  -CF  and  -Cm  do  not  make  sense
-          together - there is no opportunity for meta-equivalence
-          classes if the table is not being  compressed.   Other-
-          wise the options may be freely mixed.
-
-          The default setting is -Cem, which specifies that  flex
-          should   generate   equivalence   classes   and   meta-
-          equivalence classes.  This setting provides the highest
-          degree   of  table  compression.   You  can  trade  off
-          faster-executing scanners at the cost of larger  tables
-          with the following generally being true:
-
-              slowest & smallest
-                    -Cem
-                    -Cm
-                    -Ce
-                    -C
-                    -C{f,F}e
-                    -C{f,F}
-              fastest & largest
-
-          Note that scanners with the smallest tables are usually
-          generated and compiled the quickest, so during develop-
-          ment you will usually want to use the default,  maximal
-          compression.
-
-          -Cfe is often a good compromise between speed and  size
-          for production scanners.
-
-          -C options are not cumulative;  whenever  the  flag  is
-          encountered, the previous -C settings are forgotten.
-
-     -Sskeleton_file
-          overrides the default skeleton  file  from  which  flex
-          constructs its scanners.  You'll never need this option
-          unless you are doing flex maintenance or development.
-
-
-
-

PERFORMANCE CONSIDERATIONS

-     The main design goal of  flex  is  that  it  generate  high-
-     performance  scanners.   It  has  been optimized for dealing
-     well with large sets of rules.  Aside from  the  effects  of
-     table compression on scanner speed outlined above, there are
-     a  number  of  options/actions  which  degrade  performance.
-     These are, from most expensive to least:
-
-         REJECT
-
-         pattern sets that require backtracking
-         arbitrary trailing context
-
-         '^' beginning-of-line operator
-         yymore()
-
-     with the first three all being quite expensive and the  last
-     two being quite cheap.
-
-     REJECT should be avoided at all costs  when  performance  is
-     important.  It is a particularly expensive option.
-
-     Getting rid of backtracking is messy and  often  may  be  an
-     enormous amount of work for a complicated scanner.  In prin-
-     cipal, one begins  by  using  the  -b  flag  to  generate  a
-     lex.backtrack file.  For example, on the input
-
-         %%
-         foo        return TOK_KEYWORD;
-         foobar     return TOK_KEYWORD;
-
-     the file looks like:
-
-         State #6 is non-accepting -
-          associated rule line numbers:
-                2       3
-
-          out-transitions: [ o ]
-          jam-transitions: EOF [ \001-n  p-\177 ]
-
-         State #8 is non-accepting -
-          associated rule line numbers:
-                3
-          out-transitions: [ a ]
-          jam-transitions: EOF [ \001-`  b-\177 ]
-
-         State #9 is non-accepting -
-          associated rule line numbers:
-                3
-          out-transitions: [ r ]
-          jam-transitions: EOF [ \001-q  s-\177 ]
-
-         Compressed tables always backtrack.
-
-     The first few lines tell us that there's a scanner state  in
-     which  it  can  make  a  transition on an 'o' but not on any
-     other character,  and  that  in  that  state  the  currently
-     scanned text does not match any rule.  The state occurs when
-     trying to match the rules found at lines  2  and  3  in  the
-     input  file.  If the scanner is in that state and then reads
-     something other than an 'o', it will have  to  backtrack  to
-     find  a rule which is matched.  With a bit of headscratching
-     one can see that this must be the state it's in when it  has
-     seen  "fo".   When this has happened, if anything other than
-     another 'o' is seen, the scanner will have  to  back  up  to
-     simply match the 'f' (by the default rule).
-
-     The comment regarding State #8 indicates there's  a  problem
-     when  "foob"  has  been  scanned.   Indeed, on any character
-     other than a 'b', the scanner will have to back up to accept
-     "foo".   Similarly,  the  comment for State #9 concerns when
-     "fooba" has been scanned.
-
-     The final comment reminds us that there's no point going  to
-     all  the  trouble  of  removing  backtracking from the rules
-     unless we're using -f or -F, since  there's  no  performance
-     gain doing so with compressed scanners.
-
-     The way to remove the backtracking is to add "error" rules:
-
-         %%
-         foo         return TOK_KEYWORD;
-         foobar      return TOK_KEYWORD;
-
-         fooba       |
-         foob        |
-         fo          {
-                     /* false alarm, not really a keyword */
-                     return TOK_ID;
-                     }
-
-
-     Eliminating backtracking among a list of keywords  can  also
-     be done using a "catch-all" rule:
-
-         %%
-         foo         return TOK_KEYWORD;
-         foobar      return TOK_KEYWORD;
-
-         [a-z]+      return TOK_ID;
-
-     This is usually the best solution when appropriate.
-
-     Backtracking messages tend to cascade.  With  a  complicated
-     set  of rules it's not uncommon to get hundreds of messages.
-     If one can decipher them, though,  it  often  only  takes  a
-     dozen or so rules to eliminate the backtracking (though it's
-     easy to make a mistake and have an error  rule  accidentally
-     match a valid token.  A possible future flex feature will be
-     to automatically add rules to eliminate backtracking).
-
-     Variable trailing context (where both the leading and trail-
-     ing  parts  do  not  have a fixed length) entails almost the
-     same performance loss as  REJECT  (i.e.,  substantial).   So
-     when possible a rule like:
-
-         %%
-         mouse|rat/(cat|dog)   run();
-
-     is better written:
-
-         %%
-         mouse/cat|dog         run();
-         rat/cat|dog           run();
-
-     or as
-
-         %%
-         mouse|rat/cat         run();
-         mouse|rat/dog         run();
-
-     Note that here the special '|' action does not  provide  any
-     savings,  and  can  even  make  things  worse  (see  BUGS in
-     flex(1)).
-
-     Another area where the user can increase a scanner's perfor-
-     mance  (and  one that's easier to implement) arises from the
-     fact that the longer the  tokens  matched,  the  faster  the
-     scanner will run.  This is because with long tokens the pro-
-     cessing of most input characters takes place in the  (short)
-     inner  scanning  loop, and does not often have to go through
-     the additional work of setting up the  scanning  environment
-     (e.g.,  yytext)  for  the  action.  Recall the scanner for C
-     comments:
-
-         %x comment
-         %%
-                 int line_num = 1;
-
-         "/*"         BEGIN(comment);
-
-         <comment>[^*\n]*
-         <comment>"*"+[^*/\n]*
-         <comment>\n             ++line_num;
-         <comment>"*"+"/"        BEGIN(INITIAL);
-
-     This could be sped up by writing it as:
-
-         %x comment
-         %%
-                 int line_num = 1;
-
-         "/*"         BEGIN(comment);
-
-         <comment>[^*\n]*
-         <comment>[^*\n]*\n      ++line_num;
-         <comment>"*"+[^*/\n]*
-         <comment>"*"+[^*/\n]*\n ++line_num;
-         <comment>"*"+"/"        BEGIN(INITIAL);
-
-     Now instead of each  newline  requiring  the  processing  of
-     another  action,  recognizing  the newlines is "distributed"
-     over the other rules to keep the matched  text  as  long  as
-     possible.   Note  that  adding  rules does not slow down the
-     scanner!  The speed of the scanner  is  independent  of  the
-     number  of  rules or (modulo the considerations given at the
-     beginning of this section) how  complicated  the  rules  are
-     with regard to operators such as '*' and '|'.
-
-     A final example in speeding up a scanner: suppose  you  want
-     to  scan through a file containing identifiers and keywords,
-     one per line and with no other  extraneous  characters,  and
-     recognize all the keywords.  A natural first approach is:
-
-         %%
-         asm      |
-         auto     |
-         break    |
-         ... etc ...
-         volatile |
-         while    /* it's a keyword */
-
-         .|\n     /* it's not a keyword */
-
-     To eliminate the back-tracking, introduce a catch-all rule:
-
-         %%
-         asm      |
-         auto     |
-         break    |
-         ... etc ...
-         volatile |
-         while    /* it's a keyword */
-
-         [a-z]+   |
-         .|\n     /* it's not a keyword */
-
-     Now, if it's guaranteed that there's exactly  one  word  per
-     line,  then  we  can reduce the total number of matches by a
-     half by merging in the recognition of newlines with that  of
-     the other tokens:
-
-         %%
-         asm\n    |
-         auto\n   |
-         break\n  |
-         ... etc ...
-         volatile\n |
-         while\n  /* it's a keyword */
-
-         [a-z]+\n |
-         .|\n     /* it's not a keyword */
-
-     One has to be careful here,  as  we  have  now  reintroduced
-     backtracking into the scanner.  In particular, while we know
-     that there will never be any characters in the input  stream
-     other  than letters or newlines, flex can't figure this out,
-     and it will plan for possibly needing backtracking  when  it
-     has  scanned a token like "auto" and then the next character
-     is something other than a newline or a  letter.   Previously
-     it  would  then  just match the "auto" rule and be done, but
-     now it has no "auto" rule, only a "auto\n" rule.   To  elim-
-     inate  the  possibility  of  backtracking,  we  could either
-     duplicate all rules but without final newlines, or, since we
-     never  expect to encounter such an input and therefore don't
-     how it's classified, we can  introduce  one  more  catch-all
-     rule, this one which doesn't include a newline:
-
-         %%
-         asm\n    |
-         auto\n   |
-         break\n  |
-         ... etc ...
-         volatile\n |
-         while\n  /* it's a keyword */
-
-         [a-z]+\n |
-         [a-z]+   |
-         .|\n     /* it's not a keyword */
-
-     Compiled with -Cf, this is about as fast as one  can  get  a
-     flex scanner to go for this particular problem.
-
-     A final note:  flex is slow when  matching  NUL's,  particu-
-     larly  when  a  token contains multiple NUL's.  It's best to
-     write rules which match short amounts of text if it's  anti-
-     cipated that the text will often include NUL's.
-
-
-
-

INCOMPATIBILITIES WITH LEX AND POSIX

-     flex is a rewrite of the Unix lex tool (the two  implementa-
-     tions  do  not share any code, though), with some extensions
-     and incompatibilities, both of which are of concern to those
-     who  wish to write scanners acceptable to either implementa-
-     tion.  At present, the POSIX lex draft is very close to  the
-     original lex implementation, so some of these incompatibili-
-     ties are also in conflict with the  POSIX  draft.   But  the
-     intent  is  that except as noted below, flex as it presently
-     stands will ultimately be POSIX conformant (i.e., that those
-     areas  of  conflict with the POSIX draft will be resolved in
-     flex's favor).  Please bear in mind that  all  the  comments
-     which  follow are with regard to the POSIX draft standard of
-     Summer 1989, and  not  the  final  document  (or  subsequent
-     drafts); they are included so flex users can be aware of the
-     standardization issues and those areas where flex may in the
-     near  future  undergo  changes incompatible with its current
-     definition.
-
-     flex is fully compatible with lex with the following  excep-
-     tions:
-
-     -    The undocumented lex scanner internal variable yylineno
-          is  not  supported.   It  is  difficult to support this
-          option efficiently, since it requires  examining  every
-          character  scanned  and reexamining the characters when
-          the scanner backs up.  Things get more complicated when
-          the  end  of  buffer  or  file  is  reached or a NUL is
-          scanned (since the scan must then be restarted with the
-          proper  line  number  count),  or  the  user  uses  the
-          yyless(), unput(), or REJECT actions, or  the  multiple
-          input buffer functions.
-
-          The fix is to add rules which, upon seeing  a  newline,
-          increment  yylineno.   This is usually an easy process,
-          though it can be a drag if some  of  the  patterns  can
-          match multiple newlines along with other characters.
-
-          yylineno is not part of the POSIX draft.
-
-     -    The input() routine is not redefinable, though  it  may
-          be  called  to  read  characters following whatever has
-          been matched by a rule.  If input() encounters an  end-
-          of-file  the  normal  yywrap()  processing  is done.  A
-          ``real'' end-of-file is returned by input() as EOF.
-
-          Input is instead controlled by redefining the  YY_INPUT
-          macro.
-
-          The flex restriction that input() cannot  be  redefined
-          is in accordance with the POSIX draft, but YY_INPUT has
-          not yet been accepted  into  the  draft  (and  probably
-          won't;  it looks like the draft will simply not specify
-          any way of controlling the scanner's input  other  than
-          by making an initial assignment to yyin).
-
-     -    flex scanners do not use stdio for input.   Because  of
-          this,  when  writing  an  interactive  scanner one must
-          explicitly call fflush() on the stream associated  with
-          the terminal after writing out a prompt.  With lex such
-          writes are automatically flushed since lex scanners use
-          getchar() for their input.  Also, when writing interac-
-          tive scanners with flex, the -I flag must be used.
-
-     -    flex scanners are not as reentrant as lex scanners.  In
-          particular,  if  you have an interactive scanner and an
-          interrupt handler which long-jumps out of the  scanner,
-          and  the  scanner is subsequently called again, you may
-          get the following message:
-
-              fatal flex scanner internal error--end of buffer missed
-
-          To reenter the scanner, first use
-
-              yyrestart( yyin );
-
-
-     -    output() is not supported.  Output from the ECHO  macro
-          is done to the file-pointer yyout (default stdout).
-
-          The POSIX  draft  mentions  that  an  output()  routine
-          exists  but  currently  gives  no details as to what it
-          does.
-
-     -    lex does not support exclusive start  conditions  (%x),
-          though they are in the current POSIX draft.
-
-     -    When definitions are expanded, flex  encloses  them  in
-          parentheses.  With lex, the following:
-
-              NAME    [A-Z][A-Z0-9]*
-              %%
-              foo{NAME}?      printf( "Found it\n" );
-              %%
-
-          will not match the string "foo" because when the  macro
-          is  expanded  the rule is equivalent to "foo[A-Z][A-Z0-
-          9]*?"  and the precedence is such that the '?' is asso-
-          ciated  with  "[A-Z0-9]*".  With flex, the rule will be
-          expanded to "foo([A-Z][A-Z0-9]*)?" and  so  the  string
-          "foo" will match.  Note that because of this, the ^, $,
-          <s>, /, and <<EOF>> operators cannot be used in a  flex
-          definition.
-
-          The POSIX draft interpretation is the same as flex's.
-
-     -    To specify a character class which matches anything but
-          a  left  bracket  (']'),  in lex one can use "[^]]" but
-          with flex one must use "[^\]]".  The latter works  with
-          lex, too.
-
-     -    The lex %r (generate a Ratfor scanner)  option  is  not
-          supported.  It is not part of the POSIX draft.
-
-     -    If you are providing your  own  yywrap()  routine,  you
-          must  include a "#undef yywrap" in the definitions sec-
-          tion (section 1).  Note that the "#undef" will have  to
-          be enclosed in %{}'s.
-
-          The POSIX draft specifies that yywrap() is  a  function
-          and  this is very unlikely to change; so flex users are
-          warned that yywrap() is likely to be changed to a func-
-          tion in the near future.
-
-     -    After a call to unput(), yytext and  yyleng  are  unde-
-          fined until the next token is matched.  This is not the
-          case with lex or the present POSIX draft.
-
-     -    The precedence of the {} (numeric  range)  operator  is
-          different.   lex  interprets  "abc{1,3}" as "match one,
-          two, or  three  occurrences  of  'abc'",  whereas  flex
-          interprets  it  as "match 'ab' followed by one, two, or
-          three occurrences of 'c'".  The latter is in  agreement
-          with the current POSIX draft.
-
-     -    The precedence of the ^  operator  is  different.   lex
-          interprets  "^foo|bar"  as  "match  either 'foo' at the
-          beginning of a line, or 'bar' anywhere",  whereas  flex
-          interprets  it  as "match either 'foo' or 'bar' if they
-          come at the beginning of a line".   The  latter  is  in
-          agreement with the current POSIX draft.
-
-     -    To refer to yytext outside of the scanner source  file,
-          the  correct  definition  with  flex  is  "extern  char
-          *yytext" rather than "extern char yytext[]".   This  is
-          contrary  to  the  current  POSIX  draft but a point on
-          which flex will not be changing, as the array represen-
-          tation  entails  a  serious performance penalty.  It is
-          hoped that the POSIX draft will be emended  to  support
-          the  flex  variety  of declaration (as this is a fairly
-          painless change to require of lex users).
-
-     -    yyin is initialized by lex to be stdin;  flex,  on  the
-          other  hand,  initializes yyin to NULL and then assigns
-          it to stdin the first time the scanner is called,  pro-
-          viding yyin has not already been assigned to a non-NULL
-          value.  The difference is subtle, but the net effect is
-          that  with  flex  scanners,  yyin does not have a valid
-          value until the scanner has been called.
-
-     -    The special table-size declarations  such  as  %a  sup-
-          ported  by  lex are not required by flex scanners; flex
-          ignores them.
-
-     -    The name FLEX_SCANNER is #define'd so scanners  may  be
-          written for use with either flex or lex.
-
-     The following flex features are not included in lex  or  the
-     POSIX draft standard:
-
-         yyterminate()
-         <<EOF>>
-         YY_DECL
-         #line directives
-         %{}'s around actions
-         yyrestart()
-         comments beginning with '#' (deprecated)
-         multiple actions on a line
-
-     This last feature refers to the fact that with flex you  can
-     put  multiple actions on the same line, separated with semi-
-     colons, while with lex, the following
-
-         foo    handle_foo(); ++num_foos_seen;
-
-     is (rather surprisingly) truncated to
-
-         foo    handle_foo();
-
-     flex does not truncate the action.   Actions  that  are  not
-     enclosed  in  braces are simply terminated at the end of the
-     line.
-
-
-
-

DIAGNOSTICS

-     reject_used_but_not_detected          undefined           or
-     yymore_used_but_not_detected  undefined  -  These errors can
-     occur at compile time.  They indicate that the scanner  uses
-     REJECT  or yymore() but that flex failed to notice the fact,
-     meaning that flex scanned the first two sections looking for
-     occurrences  of  these  actions  and failed to find any, but
-     somehow you snuck some in (via a #include  file,  for  exam-
-     ple).  Make an explicit reference to the action in your flex
-     input  file.   (Note  that  previously  flex   supported   a
-     %used/%unused  mechanism for dealing with this problem; this
-     feature is still supported but now deprecated, and  will  go
-     away  soon unless the author hears from people who can argue
-     compellingly that they need it.)
-
-     flex scanner jammed - a scanner compiled with -s has encoun-
-     tered  an  input  string  which wasn't matched by any of its
-     rules.
-
-     flex input buffer overflowed -  a  scanner  rule  matched  a
-     string  long enough to overflow the scanner's internal input
-     buffer (16K bytes by default - controlled by YY_BUF_SIZE  in
-     "flex.skel".   Note  that  to  redefine this macro, you must
-     first #undefine it).
-
-     scanner  requires  -8  flag  -  Your  scanner  specification
-     includes  recognizing  8-bit  characters  and  you  did  not
-     specify the -8 flag (and your site has  not  installed  flex
-     with -8 as the default).
-
-     fatal flex scanner internal error--end of  buffer  missed  -
-     This  can  occur  in  an  scanner which is reentered after a
-     long-jump has jumped out (or over) the scanner's  activation
-     frame.  Before reentering the scanner, use:
-
-         yyrestart( yyin );
-
-
-     too many %t classes! - You managed to put every single char-
-     acter  into  its  own %t class.  flex requires that at least
-     one of the classes share characters.
-
-
-
-

DEFICIENCIES / BUGS

-     See flex(1).
-
-
-
-

SEE ALSO

-     flex(1), lex(1), yacc(1), sed(1), awk(1).
-
-     M. E. Lesk and E. Schmidt, LEX - Lexical Analyzer Generator
-
-
-
-

AUTHOR

-     Vern Paxson, with the help of many ideas and  much  inspira-
-     tion  from Van Jacobson.  Original version by Jef Poskanzer.
-     The fast table representation is a partial implementation of
-     a  design done by Van Jacobson.  The implementation was done
-     by Kevin Gong and Vern Paxson.
-
-     Thanks to the many flex beta-testers, feedbackers, and  con-
-     tributors,  especially  Casey  Leedom, benson@odi.com, Keith
-     Bostic, Frederic Brehm, Nick  Christopher,  Jason  Coughlin,
-     Scott  David Daniels, Leo Eskin, Chris Faylor, Eric Goldman,
-     Eric Hughes, Jeffrey R. Jones, Kevin B. Kenny,  Ronald  Lam-
-     precht,  Greg  Lee, Craig Leres, Mohamed el Lozy, Jim Meyer-
-     ing, Marc Nozell, Esmond Pitt, Jef Poskanzer,  Jim  Roskind,
-     Dave  Tallman,  Frank Whaley, Ken Yap, and those whose names
-     have slipped my marginal  mail-archiving  skills  but  whose
-     contributions are appreciated all the same.
-
-     Thanks to Keith Bostic, John Gilmore, Craig Leres, Bob  Mul-
-     cahy,  Rich Salz, and Richard Stallman for help with various
-     distribution headaches.
-
-     Thanks to Esmond Pitt and Earle Horton for  8-bit  character
-     support; to Benson Margulies and Fred Burke for C++ support;
-     to Ove Ewerlid for the basics of support for NUL's;  and  to
-     Eric Hughes for the basics of support for multiple buffers.
-
-     Work is being done on extending flex to generate scanners in
-     which  the  state  machine is directly represented in C code
-     rather than tables.  These scanners  may  well  be  substan-
-     tially  faster  than those generated using -f or -F.  If you
-     are working in this area and  are  interested  in  comparing
-     notes and seeing whether redundant work can be avoided, con-
-     tact Ove Ewerlid (ewerlid@mizar.DoCS.UU.SE).
-
-     This work was primarily done when I was  at  the  Real  Time
-     Systems  Group at the Lawrence Berkeley Laboratory in Berke-
-     ley, CA.  Many  thanks  to  all  there  for  the  support  I
-     received.
-
-     Send comments to:
-
-          Vern Paxson
-          Computer Science Department
-          4126 Upson Hall
-          Cornell University
-          Ithaca, NY 14853-7501
-
-          vern@cs.cornell.edu
-          decvax!cornell!vern
-
-
-
-
-
-
-
-
-
-
-Man(1) output converted with -man2html -
- - diff --git a/src/libCom/flex/gen.c b/src/libCom/flex/gen.c deleted file mode 100644 index aad884074..000000000 --- a/src/libCom/flex/gen.c +++ /dev/null @@ -1,1319 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* gen - actual generation (writing) of flex scanners */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declare functions that have forward references */ - -void gen_next_state (int); -void genecs (void); -void indent_put2s (char [], char []); -void indent_puts (char []); - - -static int indent_level = 0; /* each level is 4 spaces */ - -#define indent_up() (++indent_level) -#define indent_down() (--indent_level) -#define set_indent(indent_val) indent_level = indent_val - -/* *everything* is done in terms of arrays starting at 1, so provide - * a null entry for the zero element of all C arrays - */ -static char C_short_decl[] = "static const short int %s[%d] =\n { 0,\n"; -static char C_long_decl[] = "static const long int %s[%d] =\n { 0,\n"; -static char C_state_decl[] = - "static const yy_state_type %s[%d] =\n { 0,\n"; - - -/* indent to the current level */ - -void do_indent(void) -{ - int i = indent_level * 4; - - while ( i >= 8 ) - { - putchar( '\t' ); - i -= 8; - } - - while ( i > 0 ) - { - putchar( ' ' ); - --i; - } - } - - -/* generate the code to keep backtracking information */ - -void gen_backtracking(void) -{ - if ( reject || num_backtracking == 0 ) - return; - - if ( fullspd ) - indent_puts( "if ( yy_current_state[-1].yy_nxt )" ); - else - indent_puts( "if ( yy_accept[yy_current_state] )" ); - - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_last_accepting_state = yy_current_state;" ); - indent_puts( "yy_last_accepting_cpos = yy_cp;" ); - indent_puts( "}" ); - indent_down(); - } - - -/* generate the code to perform the backtrack */ - -void gen_bt_action(void) -{ - if ( reject || num_backtracking == 0 ) - return; - - set_indent( 3 ); - - indent_puts( "case 0: /* must backtrack */" ); - indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" ); - indent_puts( "*yy_cp = yy_hold_char;" ); - - if ( fullspd || fulltbl ) - indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" ); - else - /* backtracking info for compressed tables is taken \after/ - * yy_cp has been incremented for the next state - */ - indent_puts( "yy_cp = yy_last_accepting_cpos;" ); - - indent_puts( "yy_current_state = yy_last_accepting_state;" ); - indent_puts( "goto yy_find_action;" ); - putchar( '\n' ); - - set_indent( 0 ); - } - - -/* genctbl - generates full speed compressed transition table - * - * synopsis - * genctbl(); - */ - -void genctbl(void) -{ - int i; - int end_of_buffer_action = num_rules + 1; - - /* table of verify for transition and offset to next state */ - printf( "static const struct yy_trans_info yy_transition[%d] =\n", - tblend + numecs + 1 ); - printf( " {\n" ); - - /* We want the transition to be represented as the offset to the - * next state, not the actual state number, which is what it currently is. - * The offset is base[nxt[i]] - base[chk[i]]. That's just the - * difference between the starting points of the two involved states - * (to - from). - * - * first, though, we need to find some way to put in our end-of-buffer - * flags and states. We do this by making a state with absolutely no - * transitions. We put it at the end of the table. - */ - /* at this point, we're guaranteed that there's enough room in nxt[] - * and chk[] to hold tblend + numecs entries. We need just two slots. - * One for the action and one for the end-of-buffer transition. We - * now *assume* that we're guaranteed the only character we'll try to - * index this nxt/chk pair with is EOB, i.e., 0, so we don't have to - * make sure there's room for jam entries for other characters. - */ - - base[lastdfa + 1] = tblend + 2; - nxt[tblend + 1] = end_of_buffer_action; - chk[tblend + 1] = numecs + 1; - chk[tblend + 2] = 1; /* anything but EOB */ - nxt[tblend + 2] = 0; /* so that "make test" won't show arb. differences */ - - /* make sure every state has a end-of-buffer transition and an action # */ - for ( i = 0; i <= lastdfa; ++i ) - { - int anum = dfaacc[i].dfaacc_state; - - chk[base[i]] = EOB_POSITION; - chk[base[i] - 1] = ACTION_POSITION; - nxt[base[i] - 1] = anum; /* action number */ - } - - for ( i = 0; i <= tblend; ++i ) - { - if ( chk[i] == EOB_POSITION ) - transition_struct_out( 0, base[lastdfa + 1] - i ); - - else if ( chk[i] == ACTION_POSITION ) - transition_struct_out( 0, nxt[i] ); - - else if ( chk[i] > numecs || chk[i] == 0 ) - transition_struct_out( 0, 0 ); /* unused slot */ - - else /* verify, transition */ - transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) ); - } - - - /* here's the final, end-of-buffer state */ - transition_struct_out( chk[tblend + 1], nxt[tblend + 1] ); - transition_struct_out( chk[tblend + 2], nxt[tblend + 2] ); - - printf( " };\n" ); - printf( "\n" ); - - /* table of pointers to start states */ - printf( "static const struct yy_trans_info *yy_start_state_list[%d] =\n", - lastsc * 2 + 1 ); - printf( " {\n" ); - - for ( i = 0; i <= lastsc * 2; ++i ) - printf( " &yy_transition[%d],\n", base[i] ); - - dataend(); - - if ( useecs ) - genecs(); - } - - -/* generate equivalence-class tables */ - -void genecs(void) -{ - int i, j; - static char C_char_decl[] = "static const %s %s[%d] =\n { 0,\n"; - int numrows; - Char clower(); - - if ( numecs < csize ) - printf( C_char_decl, "YY_CHAR", "yy_ec", csize ); - else - printf( C_char_decl, "short", "yy_ec", csize ); - - for ( i = 1; i < csize; ++i ) - { - if ( caseins && (i >= 'A') && (i <= 'Z') ) - ecgroup[i] = ecgroup[clower( i )]; - - ecgroup[i] = abs( ecgroup[i] ); - mkdata( ecgroup[i] ); - } - - dataend(); - - if ( trace ) - { - char *readable_form(); - - fputs( "\n\nEquivalence Classes:\n\n", stderr ); - - numrows = csize / 8; - - for ( j = 0; j < numrows; ++j ) - { - for ( i = j; i < csize; i = i + numrows ) - { - fprintf( stderr, "%4s = %-2d", readable_form( i ), ecgroup[i] ); - - putc( ' ', stderr ); - } - - putc( '\n', stderr ); - } - } - } - - -/* generate the code to find the action number */ - -void gen_find_action(void) -{ - if ( fullspd ) - indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" ); - - else if ( fulltbl ) - indent_puts( "yy_act = yy_accept[yy_current_state];" ); - - else if ( reject ) - { - indent_puts( "yy_current_state = *--yy_state_ptr;" ); - indent_puts( "yy_lp = yy_accept[yy_current_state];" ); - - puts( "find_rule: /* we branch to this label when backtracking */" ); - - indent_puts( "for ( ; ; ) /* until we find what rule we matched */" ); - - indent_up(); - - indent_puts( "{" ); - - indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_act = yy_acclist[yy_lp];" ); - - if ( variable_trailing_context_rules ) - { - indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" ); - indent_puts( " yy_looking_for_trail_begin )" ); - indent_up(); - indent_puts( "{" ); - - indent_puts( "if ( yy_act == yy_looking_for_trail_begin )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_looking_for_trail_begin = 0;" ); - indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" ); - indent_puts( "break;" ); - indent_puts( "}" ); - indent_down(); - - indent_puts( "}" ); - indent_down(); - - indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( - "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" ); - indent_puts( - "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" ); - - if ( real_reject ) - { - /* remember matched text in case we back up due to REJECT */ - indent_puts( "yy_full_match = yy_cp;" ); - indent_puts( "yy_full_state = yy_state_ptr;" ); - indent_puts( "yy_full_lp = yy_lp;" ); - } - - indent_puts( "}" ); - indent_down(); - - indent_puts( "else" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_full_match = yy_cp;" ); - indent_puts( "yy_full_state = yy_state_ptr;" ); - indent_puts( "yy_full_lp = yy_lp;" ); - indent_puts( "break;" ); - indent_puts( "}" ); - indent_down(); - - indent_puts( "++yy_lp;" ); - indent_puts( "goto find_rule;" ); - } - - else - { - /* remember matched text in case we back up due to trailing context - * plus REJECT - */ - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_full_match = yy_cp;" ); - indent_puts( "break;" ); - indent_puts( "}" ); - indent_down(); - } - - indent_puts( "}" ); - indent_down(); - - indent_puts( "--yy_cp;" ); - - /* we could consolidate the following two lines with those at - * the beginning, but at the cost of complaints that we're - * branching inside a loop - */ - indent_puts( "yy_current_state = *--yy_state_ptr;" ); - indent_puts( "yy_lp = yy_accept[yy_current_state];" ); - - indent_puts( "}" ); - - indent_down(); - } - - else - /* compressed */ - indent_puts( "yy_act = yy_accept[yy_current_state];" ); - } - - -/* genftbl - generates full transition table - * - * synopsis - * genftbl(); - */ - -void genftbl(void) -{ - int i; - int end_of_buffer_action = num_rules + 1; - - printf( C_short_decl, "yy_accept", lastdfa + 1 ); - - - dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; - - for ( i = 1; i <= lastdfa; ++i ) - { - int anum = dfaacc[i].dfaacc_state; - - mkdata( anum ); - - if ( trace && anum ) - fprintf( stderr, "state # %d accepts: [%d]\n", i, anum ); - } - - dataend(); - - if ( useecs ) - genecs(); - - /* don't have to dump the actual full table entries - they were created - * on-the-fly - */ - } - - -/* generate the code to find the next compressed-table state */ - -void gen_next_compressed_state(char *char_map) -{ - indent_put2s( "YY_CHAR yy_c = %s;", char_map ); - - /* save the backtracking info \before/ computing the next state - * because we always compute one more state than needed - we - * always proceed until we reach a jam state - */ - gen_backtracking(); - - indent_puts( - "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_current_state = yy_def[yy_current_state];" ); - - if ( usemecs ) - { - /* we've arrange it so that templates are never chained - * to one another. This means we can afford make a - * very simple test to see if we need to convert to - * yy_c's meta-equivalence class without worrying - * about erroneously looking up the meta-equivalence - * class twice - */ - do_indent(); - /* lastdfa + 2 is the beginning of the templates */ - printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 ); - - indent_up(); - indent_puts( "yy_c = yy_meta[(int)yy_c];" ); - indent_down(); - } - - indent_puts( "}" ); - indent_down(); - - indent_puts( - "yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];" ); - } - - -/* generate the code to find the next match */ - -void gen_next_match(void) -{ - /* NOTE - changes in here should be reflected in gen_next_state() and - * gen_NUL_trans() - */ - char *char_map = useecs ? "yy_ec[(int)*yy_cp]" : "*yy_cp"; - char *char_map_2 = useecs ? "yy_ec[*++yy_cp]" : "*++yy_cp"; - - if ( fulltbl ) - { - indent_put2s( - "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )", - char_map ); - - indent_up(); - - if ( num_backtracking > 0 ) - { - indent_puts( "{" ); - gen_backtracking(); - putchar( '\n' ); - } - - indent_puts( "++yy_cp;" ); - - if ( num_backtracking > 0 ) - indent_puts( "}" ); - - indent_down(); - - putchar( '\n' ); - indent_puts( "yy_current_state = -yy_current_state;" ); - } - - else if ( fullspd ) - { - indent_puts( "{" ); - indent_puts( "const struct yy_trans_info *yy_trans_info;\n" ); - indent_puts( "YY_CHAR yy_c;\n" ); - indent_put2s( "for ( yy_c = %s;", char_map ); - indent_puts( - " (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;" ); - indent_put2s( " yy_c = %s )", char_map_2 ); - - indent_up(); - - if ( num_backtracking > 0 ) - indent_puts( "{" ); - - indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); - - if ( num_backtracking > 0 ) - { - putchar( '\n' ); - gen_backtracking(); - indent_puts( "}" ); - } - - indent_down(); - indent_puts( "}" ); - } - - else - { /* compressed */ - indent_puts( "do" ); - - indent_up(); - indent_puts( "{" ); - - gen_next_state( false ); - - indent_puts( "++yy_cp;" ); - - indent_puts( "}" ); - indent_down(); - - do_indent(); - - if ( interactive ) - printf( "while ( yy_base[yy_current_state] != %d );\n", jambase ); - else - printf( "while ( yy_current_state != %d );\n", jamstate ); - - if ( ! reject && ! interactive ) - { - /* do the guaranteed-needed backtrack to figure out the match */ - indent_puts( "yy_cp = yy_last_accepting_cpos;" ); - indent_puts( "yy_current_state = yy_last_accepting_state;" ); - } - } - } - - -/* generate the code to find the next state */ - -void gen_next_state(int worry_about_NULs) -{ /* NOTE - changes in here should be reflected in get_next_match() */ - char char_map[256]; - - if ( worry_about_NULs && ! nultrans ) - { - if ( useecs ) - (void) sprintf( char_map, "(*yy_cp ? yy_ec[(int)*yy_cp] : %d)", NUL_ec ); - else - (void) sprintf( char_map, "(*yy_cp ? *yy_cp : %d)", NUL_ec ); - } - - else - (void) strcpy( char_map, useecs ? "yy_ec[(int)*yy_cp]" : "*yy_cp" ); - - if ( worry_about_NULs && nultrans ) - { - if ( ! fulltbl && ! fullspd ) - /* compressed tables backtrack *before* they match */ - gen_backtracking(); - - indent_puts( "if ( *yy_cp )" ); - indent_up(); - indent_puts( "{" ); - } - - if ( fulltbl ) - indent_put2s( "yy_current_state = yy_nxt[yy_current_state][%s];", - char_map ); - - else if ( fullspd ) - indent_put2s( "yy_current_state += yy_current_state[%s].yy_nxt;", - char_map ); - - else - gen_next_compressed_state( char_map ); - - if ( worry_about_NULs && nultrans ) - { - indent_puts( "}" ); - indent_down(); - indent_puts( "else" ); - indent_up(); - indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" ); - indent_down(); - } - - if ( fullspd || fulltbl ) - gen_backtracking(); - - if ( reject ) - indent_puts( "*yy_state_ptr++ = yy_current_state;" ); - } - - -/* generate the code to make a NUL transition */ - -void gen_NUL_trans(void) -{ /* NOTE - changes in here should be reflected in get_next_match() */ - int need_backtracking = (num_backtracking > 0 && ! reject); - - if ( need_backtracking ) - /* we'll need yy_cp lying around for the gen_backtracking() */ - indent_puts( "YY_CHAR *yy_cp = yy_c_buf_p;" ); - - putchar( '\n' ); - - if ( nultrans ) - { - indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" ); - indent_puts( "yy_is_jam = (yy_current_state == 0);" ); - } - - else if ( fulltbl ) - { - do_indent(); - printf( "yy_current_state = yy_nxt[yy_current_state][%d];\n", - NUL_ec ); - indent_puts( "yy_is_jam = (yy_current_state <= 0);" ); - } - - else if ( fullspd ) - { - do_indent(); - printf( "int yy_c = %d;\n", NUL_ec ); - - indent_puts( - "const struct yy_trans_info *yy_trans_info;\n" ); - indent_puts( "yy_trans_info = &yy_current_state[yy_c];" ); - indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); - - indent_puts( "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" ); - } - - else - { - char NUL_ec_str[20]; - - (void) sprintf( NUL_ec_str, "%d", NUL_ec ); - gen_next_compressed_state( NUL_ec_str ); - - if ( reject ) - indent_puts( "*yy_state_ptr++ = yy_current_state;" ); - - do_indent(); - - if ( interactive ) - printf( "yy_is_jam = (yy_base[yy_current_state] == %d);\n", - jambase ); - else - printf( "yy_is_jam = (yy_current_state == %d);\n", jamstate ); - } - - /* if we've entered an accepting state, backtrack; note that - * compressed tables have *already* done such backtracking, so - * we needn't bother with it again - */ - if ( need_backtracking && (fullspd || fulltbl) ) - { - putchar( '\n' ); - indent_puts( "if ( ! yy_is_jam )" ); - indent_up(); - indent_puts( "{" ); - gen_backtracking(); - indent_puts( "}" ); - indent_down(); - } - } - - -/* generate the code to find the start state */ - -void gen_start_state(void) -{ - if ( fullspd ) - indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];", - bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" ); - - else - { - indent_puts( "yy_current_state = yy_start;" ); - - if ( bol_needed ) - { - indent_puts( "if ( yy_bp[-1] == '\\n' )" ); - indent_up(); - indent_puts( "++yy_current_state;" ); - indent_down(); - } - - if ( reject ) - { - /* set up for storing up states */ - indent_puts( "yy_state_ptr = yy_state_buf;" ); - indent_puts( "*yy_state_ptr++ = yy_current_state;" ); - } - } - } - - -/* gentabs - generate data statements for the transition tables - * - * synopsis - * gentabs(); - */ - -void gentabs(void) -{ - int i, j, k, *accset, nacc, *acc_array, total_states; - int end_of_buffer_action = num_rules + 1; - - /* *everything* is done in terms of arrays starting at 1, so provide - * a null entry for the zero element of all C arrays - */ - static char C_char_decl[] = - "static const YY_CHAR %s[%d] =\n { 0,\n"; - - acc_array = allocate_integer_array( current_max_dfas ); - nummt = 0; - - /* the compressed table format jams by entering the "jam state", - * losing information about the previous state in the process. - * In order to recover the previous state, we effectively need - * to keep backtracking information. - */ - ++num_backtracking; - - if ( reject ) - { - /* write out accepting list and pointer list - * - * first we generate the "yy_acclist" array. In the process, we compute - * the indices that will go into the "yy_accept" array, and save the - * indices in the dfaacc array - */ - int EOB_accepting_list[2]; - - /* set up accepting structures for the End Of Buffer state */ - EOB_accepting_list[0] = 0; - EOB_accepting_list[1] = end_of_buffer_action; - accsiz[end_of_buffer_state] = 1; - dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list; - - printf( C_short_decl, "yy_acclist", max( numas, 1 ) + 1 ); - - j = 1; /* index into "yy_acclist" array */ - - for ( i = 1; i <= lastdfa; ++i ) - { - acc_array[i] = j; - - if ( accsiz[i] != 0 ) - { - accset = dfaacc[i].dfaacc_set; - nacc = accsiz[i]; - - if ( trace ) - fprintf( stderr, "state # %d accepts: ", i ); - - for ( k = 1; k <= nacc; ++k ) - { - int accnum = accset[k]; - - ++j; - - if ( variable_trailing_context_rules && - ! (accnum & YY_TRAILING_HEAD_MASK) && - accnum > 0 && accnum <= num_rules && - rule_type[accnum] == RULE_VARIABLE ) - { - /* special hack to flag accepting number as part - * of trailing context rule - */ - accnum |= YY_TRAILING_MASK; - } - - mkdata( accnum ); - - if ( trace ) - { - fprintf( stderr, "[%d]", accset[k] ); - - if ( k < nacc ) - fputs( ", ", stderr ); - else - putc( '\n', stderr ); - } - } - } - } - - /* add accepting number for the "jam" state */ - acc_array[i] = j; - - dataend(); - } - - else - { - dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; - - for ( i = 1; i <= lastdfa; ++i ) - acc_array[i] = dfaacc[i].dfaacc_state; - - /* add accepting number for jam state */ - acc_array[i] = 0; - } - - /* spit out "yy_accept" array. If we're doing "reject", it'll be pointers - * into the "yy_acclist" array. Otherwise it's actual accepting numbers. - * In either case, we just dump the numbers. - */ - - /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays - * beginning at 0 and for "jam" state - */ - k = lastdfa + 2; - - if ( reject ) - /* we put a "cap" on the table associating lists of accepting - * numbers with state numbers. This is needed because we tell - * where the end of an accepting list is by looking at where - * the list for the next state starts. - */ - ++k; - - printf( C_short_decl, "yy_accept", k ); - - for ( i = 1; i <= lastdfa; ++i ) - { - mkdata( acc_array[i] ); - - if ( ! reject && trace && acc_array[i] ) - fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] ); - } - - /* add entry for "jam" state */ - mkdata( acc_array[i] ); - - if ( reject ) - /* add "cap" for the list */ - mkdata( acc_array[i] ); - - dataend(); - - if ( useecs ) - genecs(); - - if ( usemecs ) - { - /* write out meta-equivalence classes (used to index templates with) */ - - if ( trace ) - fputs( "\n\nMeta-Equivalence Classes:\n", stderr ); - - printf( C_char_decl, "yy_meta", numecs + 1 ); - - for ( i = 1; i <= numecs; ++i ) - { - if ( trace ) - fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) ); - - mkdata( abs( tecbck[i] ) ); - } - - dataend(); - } - - total_states = lastdfa + numtemps; - - printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl, - "yy_base", total_states + 1 ); - - for ( i = 1; i <= lastdfa; ++i ) - { - int d = def[i]; - - if ( base[i] == JAMSTATE ) - base[i] = jambase; - - if ( d == JAMSTATE ) - def[i] = jamstate; - - else if ( d < 0 ) - { - /* template reference */ - ++tmpuses; - def[i] = lastdfa - d + 1; - } - - mkdata( base[i] ); - } - - /* generate jam state's base index */ - mkdata( base[i] ); - - for ( ++i /* skip jam state */; i <= total_states; ++i ) - { - mkdata( base[i] ); - def[i] = jamstate; - } - - dataend(); - - printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl, - "yy_def", total_states + 1 ); - - for ( i = 1; i <= total_states; ++i ) - mkdata( def[i] ); - - dataend(); - - printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl, - "yy_nxt", tblend + 1 ); - - for ( i = 1; i <= tblend; ++i ) - { - if ( nxt[i] == 0 || chk[i] == 0 ) - nxt[i] = jamstate; /* new state is the JAM state */ - - mkdata( nxt[i] ); - } - - dataend(); - - printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl, - "yy_chk", tblend + 1 ); - - for ( i = 1; i <= tblend; ++i ) - { - if ( chk[i] == 0 ) - ++nummt; - - mkdata( chk[i] ); - } - - dataend(); - } - - -/* write out a formatted string (with a secondary string argument) at the - * current indentation level, adding a final newline - */ - -void indent_put2s(char *fmt, char *arg) -{ - do_indent(); - printf( fmt, arg ); - putchar( '\n' ); - } - - -/* write out a string at the current indentation level, adding a final - * newline - */ - -void indent_puts(char *str) -{ - do_indent(); - puts( str ); - } - - -/* make_tables - generate transition tables - * - * synopsis - * make_tables(); - * - * Generates transition tables and finishes generating output file - */ - -void make_tables(void) -{ - int i; - int did_eof_rule = false; - - skelout(); - - /* first, take care of YY_DO_BEFORE_ACTION depending on yymore being used */ - set_indent( 2 ); - - if ( yymore_used ) - { - indent_puts( "yytext -= yy_more_len; \\" ); - indent_puts( "yyleng = yy_cp - yytext; \\" ); - } - - else - indent_puts( "yyleng = yy_cp - yy_bp; \\" ); - - set_indent( 0 ); - - skelout(); - - - printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 ); - - if ( fullspd ) - { /* need to define the transet type as a size large - * enough to hold the biggest offset - */ - int total_table_size = tblend + numecs + 1; - char *trans_offset_type = - total_table_size > MAX_SHORT ? "long" : "short"; - - set_indent( 0 ); - indent_puts( "struct yy_trans_info" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "short yy_verify;" ); - - /* in cases where its sister yy_verify *is* a "yes, there is a - * transition", yy_nxt is the offset (in records) to the next state. - * In most cases where there is no transition, the value of yy_nxt - * is irrelevant. If yy_nxt is the -1th record of a state, though, - * then yy_nxt is the action number for that state - */ - - indent_put2s( "%s yy_nxt;", trans_offset_type ); - indent_puts( "};" ); - indent_down(); - - indent_puts( "typedef const struct yy_trans_info *yy_state_type;" ); - } - - else - indent_puts( "typedef int yy_state_type;" ); - - if ( fullspd ) - genctbl(); - - else if ( fulltbl ) - genftbl(); - - else - gentabs(); - - if ( num_backtracking > 0 ) - { - indent_puts( "static yy_state_type yy_last_accepting_state;" ); - indent_puts( "static YY_CHAR *yy_last_accepting_cpos;\n" ); - } - - if ( nultrans ) - { - printf( C_state_decl, "yy_NUL_trans", lastdfa + 1 ); - - for ( i = 1; i <= lastdfa; ++i ) - { - if ( fullspd ) - { - if ( nultrans ) - printf( " &yy_transition[%d],\n", base[i] ); - else - printf( " 0,\n" ); - } - - else - mkdata( nultrans[i] ); - } - - dataend(); - } - - if ( ddebug ) - { /* spit out table mapping rules to line numbers */ - indent_puts( "extern int yy_flex_debug;" ); - indent_puts( "int yy_flex_debug = 1;\n" ); - - printf( C_short_decl, "yy_rule_linenum", num_rules ); - for ( i = 1; i < num_rules; ++i ) - mkdata( rule_linenum[i] ); - dataend(); - } - - if ( reject ) - { - /* declare state buffer variables */ - puts( - "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" ); - puts( "static YY_CHAR *yy_full_match;" ); - puts( "static int yy_lp;" ); - - if ( variable_trailing_context_rules ) - { - puts( "static int yy_looking_for_trail_begin = 0;" ); - puts( "static int yy_full_lp;" ); - puts( "static int *yy_full_state;" ); - printf( "#define YY_TRAILING_MASK 0x%x\n", YY_TRAILING_MASK ); - printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n", - YY_TRAILING_HEAD_MASK ); - } - - puts( "#define REJECT \\" ); - puts( "{ \\" ); - puts( - "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" ); - puts( - "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" ); - - if ( variable_trailing_context_rules ) - { - puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" ); - puts( - "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" ); - puts( - "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" ); - } - - puts( "++yy_lp; \\" ); - puts( "goto find_rule; \\" ); - puts( "}" ); - } - - else - { - puts( "/* the intent behind this definition is that it'll catch" ); - puts( " * any uses of REJECT which flex missed" ); - puts( " */" ); - puts( "#define REJECT reject_used_but_not_detected" ); - } - - if ( yymore_used ) - { - indent_puts( "static int yy_more_flag = 0;" ); - indent_puts( "static int yy_doing_yy_more = 0;" ); - indent_puts( "static int yy_more_len = 0;" ); - indent_puts( - "#define yymore() { yy_more_flag = 1; }" ); - indent_puts( - "#define YY_MORE_ADJ (yy_doing_yy_more ? yy_more_len : 0)" ); - } - - else - { - indent_puts( "#define yymore() yymore_used_but_not_detected" ); - indent_puts( "#define YY_MORE_ADJ 0" ); - } - - skelout(); - - if ( ferror( temp_action_file ) ) - flexfatal( "error occurred when writing temporary action file" ); - - else if ( fclose( temp_action_file ) ) - flexfatal( "error occurred when closing temporary action file" ); - - temp_action_file = fopen( action_file_name, "r" ); - - if ( temp_action_file == NULL ) - flexfatal( "could not re-open temporary action file" ); - - /* copy prolog from action_file to output file */ - action_out(); - - skelout(); - - set_indent( 2 ); - - if ( yymore_used ) - { - indent_puts( "yy_more_len = 0;" ); - indent_puts( "yy_doing_yy_more = yy_more_flag;" ); - indent_puts( "if ( yy_doing_yy_more )" ); - indent_up(); - indent_puts( "{" ); - indent_puts( "yy_more_len = yyleng;" ); - indent_puts( "yy_more_flag = 0;" ); - indent_puts( "}" ); - indent_down(); - } - - skelout(); - - gen_start_state(); - - /* note, don't use any indentation */ - puts( "yy_match:" ); - gen_next_match(); - - skelout(); - set_indent( 2 ); - gen_find_action(); - - skelout(); - if ( ddebug ) - { - indent_puts( "if ( yy_flex_debug )" ); - indent_up(); - - indent_puts( "{" ); - indent_puts( "if ( yy_act == 0 )" ); - indent_up(); - indent_puts( "fprintf( stderr, \"--scanner backtracking\\n\" );" ); - indent_down(); - - do_indent(); - printf( "else if ( yy_act < %d )\n", num_rules ); - indent_up(); - indent_puts( - "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," ); - indent_puts( " yy_rule_linenum[yy_act], yytext );" ); - indent_down(); - - do_indent(); - printf( "else if ( yy_act == %d )\n", num_rules ); - indent_up(); - indent_puts( - "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," ); - indent_puts( " yytext );" ); - indent_down(); - - do_indent(); - printf( "else if ( yy_act == %d )\n", num_rules + 1 ); - indent_up(); - indent_puts( "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" ); - indent_down(); - - do_indent(); - printf( "else\n" ); - indent_up(); - indent_puts( "fprintf( stderr, \"--EOF\\n\" );" ); - indent_down(); - - indent_puts( "}" ); - indent_down(); - } - - /* copy actions from action_file to output file */ - skelout(); - indent_up(); - gen_bt_action(); - action_out(); - - /* generate cases for any missing EOF rules */ - for ( i = 1; i <= lastsc; ++i ) - if ( ! sceof[i] ) - { - do_indent(); - printf( "case YY_STATE_EOF(%s):\n", scname[i] ); - did_eof_rule = true; - } - - if ( did_eof_rule ) - { - indent_up(); - indent_puts( "yyterminate();" ); - indent_down(); - } - - - /* generate code for handling NUL's, if needed */ - - /* first, deal with backtracking and setting up yy_cp if the scanner - * finds that it should JAM on the NUL - */ - skelout(); - set_indent( 7 ); - - if ( fullspd || fulltbl ) - indent_puts( "yy_cp = yy_c_buf_p;" ); - - else - { /* compressed table */ - if ( ! reject && ! interactive ) - { - /* do the guaranteed-needed backtrack to figure out the match */ - indent_puts( "yy_cp = yy_last_accepting_cpos;" ); - indent_puts( "yy_current_state = yy_last_accepting_state;" ); - } - } - - - /* generate code for yy_get_previous_state() */ - set_indent( 1 ); - skelout(); - - if ( bol_needed ) - indent_puts( "YY_CHAR *yy_bp = yytext;\n" ); - - gen_start_state(); - - set_indent( 2 ); - skelout(); - gen_next_state( true ); - - set_indent( 1 ); - skelout(); - gen_NUL_trans(); - - skelout(); - - /* copy remainder of input to output */ - - line_directive_out( stdout ); - (void) flexscan(); /* copy remainder of input to output */ - } diff --git a/src/libCom/flex/libmain.c b/src/libCom/flex/libmain.c deleted file mode 100644 index 878aa21dc..000000000 --- a/src/libCom/flex/libmain.c +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* libmain - flex run-time support library "main" function */ - -extern int yylex(); - -int main(int argc, char *argv[]) -{ - return yylex(); -} diff --git a/src/libCom/flex/misc.c b/src/libCom/flex/misc.c deleted file mode 100644 index b8a7a0399..000000000 --- a/src/libCom/flex/misc.c +++ /dev/null @@ -1,771 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* misc - miscellaneous flex routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include "flexdef.h" -#include - -/* ANSI C does not guarantee that isascii() is defined */ -#ifndef isascii -#define isascii(c) ((c) <= 0177) -#endif - - - -/* declare functions that have forward references */ - -void dataflush (void); -int otoi (Char []); - - -/* action_out - write the actions from the temporary file to lex.yy.c - * - * synopsis - * action_out(); - * - * Copies the action file up to %% (or end-of-file) to lex.yy.c - */ - -void action_out(void) -{ - char buf[MAXLINE]; - - while ( fgets( buf, MAXLINE, temp_action_file ) != NULL ) - if ( buf[0] == '%' && buf[1] == '%' ) - break; - else - fputs( buf, stdout ); - } - - -/* allocate_array - allocate memory for an integer array of the given size */ - -void *allocate_array(int size, int element_size) -{ - void *mem; - - /* on 16-bit int machines (e.g., 80286) we might be trying to - * allocate more than a signed int can hold, and that won't - * work. Cheap test: - */ - if ( element_size * size <= 0 ) - flexfatal( "request for < 1 byte in allocate_array()" ); - - mem = (void *) malloc( (unsigned) (element_size * size) ); - - if ( mem == NULL ) - flexfatal( "memory allocation failed in allocate_array()" ); - - return ( mem ); - } - - -/* all_lower - true if a string is all lower-case - * - * synopsis: - * Char *str; - * int all_lower(); - * true/false = all_lower( str ); - */ - -int all_lower(Char *str) -{ - while ( *str ) - { - if ( ! isascii( (int) *str ) || ! islower( (int) *str ) ) - return ( 0 ); - ++str; - } - - return ( 1 ); - } - - -/* all_upper - true if a string is all upper-case - * - * synopsis: - * Char *str; - * int all_upper(); - * true/false = all_upper( str ); - */ - -int all_upper(Char *str) -{ - while ( *str ) - { - if ( ! isascii( (int) *str ) || ! isupper( (int) *str ) ) - return ( 0 ); - ++str; - } - - return ( 1 ); - } - - -/* bubble - bubble sort an integer array in increasing order - * - * synopsis - * int v[n], n; - * bubble( v, n ); - * - * description - * sorts the first n elements of array v and replaces them in - * increasing order. - * - * passed - * v - the array to be sorted - * n - the number of elements of 'v' to be sorted */ - -void bubble(int v[], int n) -{ - int i, j, k; - - for ( i = n; i > 1; --i ) - for ( j = 1; j < i; ++j ) - if ( v[j] > v[j + 1] ) /* compare */ - { - k = v[j]; /* exchange */ - v[j] = v[j + 1]; - v[j + 1] = k; - } - } - - -/* clower - replace upper-case letter to lower-case - * - * synopsis: - * Char clower(); - * int c; - * c = clower( c ); - */ - -Char clower(int c) -{ - return ( (isascii( c ) && isupper( c )) ? tolower( c ) : c ); - } - - -/* copy_string - returns a dynamically allocated copy of a string - * - * synopsis - * char *str, *copy, *copy_string(); - * copy = copy_string( str ); - */ - -char *copy_string(char *str) -{ - char *c; - char *copy; - - /* find length */ - for ( c = str; *c; ++c ) - ; - - copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) ); - - if ( copy == NULL ) - flexfatal( "dynamic memory failure in copy_string()" ); - - for ( c = copy; (*c++ = *str++); ) - ; - - return ( copy ); - } - - -/* copy_unsigned_string - - * returns a dynamically allocated copy of a (potentially) unsigned string - * - * synopsis - * Char *str, *copy, *copy_unsigned_string(); - * copy = copy_unsigned_string( str ); - */ - -Char *copy_unsigned_string(Char *str) -{ - Char *c; - Char *copy; - - /* find length */ - for ( c = str; *c; ++c ) - ; - - copy = (Char *) malloc( (unsigned) ((c - str + 1) * sizeof( Char )) ); - - if ( copy == NULL ) - flexfatal( "dynamic memory failure in copy_unsigned_string()" ); - - for ( c = copy; (*c++ = *str++); ) - ; - - return ( copy ); - } - - -/* cshell - shell sort a character array in increasing order - * - * synopsis - * - * Char v[n]; - * int n, special_case_0; - * cshell( v, n, special_case_0 ); - * - * description - * does a shell sort of the first n elements of array v. - * If special_case_0 is true, then any element equal to 0 - * is instead assumed to have infinite weight. - * - * passed - * v - array to be sorted - * n - number of elements of v to be sorted - */ - -void cshell(Char *v, int n, int special_case_0) -{ - int gap, i, j, jg; - Char k; - - for ( gap = n / 2; gap > 0; gap = gap / 2 ) - for ( i = gap; i < n; ++i ) - for ( j = i - gap; j >= 0; j = j - gap ) - { - jg = j + gap; - - if ( special_case_0 ) - { - if ( v[jg] == 0 ) - break; - - else if ( v[j] != 0 && v[j] <= v[jg] ) - break; - } - - else if ( v[j] <= v[jg] ) - break; - - k = v[j]; - v[j] = v[jg]; - v[jg] = k; - } - } - - -/* dataend - finish up a block of data declarations - * - * synopsis - * dataend(); - */ - -void dataend(void) -{ - if ( datapos > 0 ) - dataflush(); - - /* add terminator for initialization */ - puts( " } ;\n" ); - - dataline = 0; - datapos = 0; - } - - - -/* dataflush - flush generated data statements - * - * synopsis - * dataflush(); - */ - -void dataflush(void) -{ - putchar( '\n' ); - - if ( ++dataline >= NUMDATALINES ) - { - /* put out a blank line so that the table is grouped into - * large blocks that enable the user to find elements easily - */ - putchar( '\n' ); - dataline = 0; - } - - /* reset the number of characters written on the current line */ - datapos = 0; - } - - -/* flexerror - report an error message and terminate - * - * synopsis - * char msg[]; - * flexerror( msg ); - */ - -void flexerror(char *msg) -{ - fprintf( stderr, "%s: %s\n", program_name, msg ); - - flexend( 1 ); - } - - -/* flexfatal - report a fatal error message and terminate - * - * synopsis - * char msg[]; - * flexfatal( msg ); - */ - -void flexfatal(char *msg) -{ - fprintf( stderr, "%s: fatal internal error, %s\n", program_name, msg ); - flexend( 1 ); - } - - -/* flex_gettime - return current time - * - * synopsis - * char *flex_gettime(), *time_str; - * time_str = flex_gettime(); - * - * note - * the routine name has the "flex_" prefix because of name clashes - * with Turbo-C - */ - -/* include sys/types.h to use time_t and make lint happy */ - -#ifndef MS_DOS -#include -#endif - -#ifdef MS_DOS -#include -typedef long time_t; -#endif - -char *flex_gettime(void) -{ - time_t t, time(time_t *); - char *result, *ctime(const time_t *), *copy_string(char *str); - - t = time( NULL ); - - result = copy_string( ctime( &t ) ); - - /* get rid of trailing newline */ - result[24] = '\0'; - - return ( result ); - } - - -/* lerrif - report an error message formatted with one integer argument - * - * synopsis - * char msg[]; - * int arg; - * lerrif( msg, arg ); - */ - -void lerrif(char *msg, int arg) -{ - char errmsg[MAXLINE]; - (void) sprintf( errmsg, msg, arg ); - flexerror( errmsg ); - } - - -/* lerrsf - report an error message formatted with one string argument - * - * synopsis - * char msg[], arg[]; - * lerrsf( msg, arg ); - */ - -void lerrsf(char *msg, char *arg) -{ - char errmsg[MAXLINE]; - - (void) sprintf( errmsg, msg, arg ); - flexerror( errmsg ); - } - - -/* htoi - convert a hexadecimal digit string to an integer value - * - * synopsis: - * int val, htoi(); - * Char str[]; - * val = htoi( str ); - */ - -int htoi(unsigned char *str) -{ - int result; - - (void) sscanf( (char *) str, "%x", &result ); - - return ( result ); - } - - -/* is_hex_digit - returns true if a character is a valid hex digit, false - * otherwise - * - * synopsis: - * int true_or_false, is_hex_digit(); - * int ch; - * val = is_hex_digit( ch ); - */ - -int is_hex_digit(int ch) -{ - if ( isdigit( ch ) ) - return ( 1 ); - - switch ( clower( ch ) ) - { - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - return ( 1 ); - - default: - return ( 0 ); - } - } - - -/* line_directive_out - spit out a "# line" statement */ - -void line_directive_out(FILE *output_file_name) -{ - if ( infilename && gen_line_dirs ) - fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename ); - } - - -/* mk2data - generate a data statement for a two-dimensional array - * - * synopsis - * int value; - * mk2data( value ); - * - * generates a data statement initializing the current 2-D array to "value" - */ -void mk2data(int value) -{ - if ( datapos >= NUMDATAITEMS ) - { - putchar( ',' ); - dataflush(); - } - - if ( datapos == 0 ) - /* indent */ - fputs( " ", stdout ); - - else - putchar( ',' ); - - ++datapos; - - printf( "%5d", value ); - } - - -/* mkdata - generate a data statement - * - * synopsis - * int value; - * mkdata( value ); - * - * generates a data statement initializing the current array element to - * "value" - */ -void mkdata(int value) -{ - if ( datapos >= NUMDATAITEMS ) - { - putchar( ',' ); - dataflush(); - } - - if ( datapos == 0 ) - /* indent */ - fputs( " ", stdout ); - - else - putchar( ',' ); - - ++datapos; - - printf( "%5d", value ); - } - - -/* myctoi - return the integer represented by a string of digits - * - * synopsis - * Char array[]; - * int val, myctoi(); - * val = myctoi( array ); - * - */ - -int myctoi(Char *array) -{ - int val = 0; - - (void) sscanf( (char *) array, "%d", &val ); - - return ( val ); - } - - -/* myesc - return character corresponding to escape sequence - * - * synopsis - * Char array[], c, myesc(); - * c = myesc( array ); - * - */ - -Char myesc(Char *array) -{ - Char c, esc_char; - int sptr; - - switch ( array[1] ) - { - case 'a': return ( '\a' ); - case 'b': return ( '\b' ); - case 'f': return ( '\f' ); - case 'n': return ( '\n' ); - case 'r': return ( '\r' ); - case 't': return ( '\t' ); - case 'v': return ( '\v' ); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { /* \ */ - sptr = 1; - - while ( isascii( array[sptr] ) && isdigit( array[sptr] ) ) - /* don't increment inside loop control because if - * isdigit() is a macro it might expand into multiple - * increments ... - */ - ++sptr; - - c = array[sptr]; - array[sptr] = '\0'; - - esc_char = otoi( array + 1 ); - - array[sptr] = c; - - return ( esc_char ); - } - - case 'x': - { /* \x */ - int sptr = 2; - - while ( isascii( array[sptr] ) && is_hex_digit( array[sptr] ) ) - /* don't increment inside loop control because if - * isdigit() is a macro it might expand into multiple - * increments ... - */ - ++sptr; - - c = array[sptr]; - array[sptr] = '\0'; - - esc_char = htoi( array + 2 ); - - array[sptr] = c; - - return ( esc_char ); - } - - default: - return ( array[1] ); - } - } - - -/* otoi - convert an octal digit string to an integer value - * - * synopsis: - * int val, otoi(); - * Char str[]; - * val = otoi( str ); - */ - -int otoi(Char *str) -{ - int result; - - (void) sscanf( (char *) str, "%o", &result ); - - return ( result ); - } - - -/* readable_form - return the the human-readable form of a character - * - * synopsis: - * int c; - * char *readable_form(); - * = readable_form( c ); - * - * The returned string is in static storage. - */ - -char *readable_form(int c) -{ - static char rform[10]; - - if ( (c >= 0 && c < 32) || c >= 127 ) - { - switch ( c ) - { - case '\n': return ( "\\n" ); - case '\t': return ( "\\t" ); - case '\f': return ( "\\f" ); - case '\r': return ( "\\r" ); - case '\b': return ( "\\b" ); - - default: - (void) sprintf( rform, "\\%.3o", c ); - return ( rform ); - } - } - - else if ( c == ' ' ) - return ( "' '" ); - - else - { - rform[0] = c; - rform[1] = '\0'; - - return ( rform ); - } - } - - -/* reallocate_array - increase the size of a dynamic array */ - -void *reallocate_array(void *array, int size, int element_size) -{ - void *new_array; - - /* same worry as in allocate_array(): */ - if ( size * element_size <= 0 ) - flexfatal( "attempt to increase array size by less than 1 byte" ); - - new_array = - (void *) realloc( (char *)array, (unsigned) (size * element_size )); - - if ( new_array == NULL ) - flexfatal( "attempt to increase array size failed" ); - - return ( new_array ); - } - - -/* skelout - write out one section of the skeleton file - * - * synopsis - * skelout(); - * - * DESCRIPTION - * Copies from skelfile to stdout until a line beginning with "%%" or - * EOF is found. - */ -void skelout(void) -{ - char buf[MAXLINE]; - - while ( fgets( buf, MAXLINE, skelfile ) != NULL ) - if ( buf[0] == '%' && buf[1] == '%' ) - break; - else - fputs( buf, stdout ); - } - - -/* transition_struct_out - output a yy_trans_info structure - * - * synopsis - * int element_v, element_n; - * transition_struct_out( element_v, element_n ); - * - * outputs the yy_trans_info structure with the two elements, element_v and - * element_n. Formats the output with spaces and carriage returns. - */ - -void transition_struct_out(int element_v, int element_n) -{ - printf( "%7d, %5d,", element_v, element_n ); - - datapos += TRANS_STRUCT_PRINT_LENGTH; - - if ( datapos >= 75 ) - { - putchar( '\n' ); - - if ( ++dataline % 10 == 0 ) - putchar( '\n' ); - - datapos = 0; - } - } diff --git a/src/libCom/flex/nfa.c b/src/libCom/flex/nfa.c deleted file mode 100644 index b57c6d646..000000000 --- a/src/libCom/flex/nfa.c +++ /dev/null @@ -1,689 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* nfa - NFA construction routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declare functions that have forward references */ - -int dupmachine (int); -void mkxtion (int, int); - - -/* add_accept - add an accepting state to a machine - * - * synopsis - * - * add_accept( mach, accepting_number ); - * - * accepting_number becomes mach's accepting number. - */ - -void add_accept(int mach, int accepting_number) -{ - /* hang the accepting number off an epsilon state. if it is associated - * with a state that has a non-epsilon out-transition, then the state - * will accept BEFORE it makes that transition, i.e., one character - * too soon - */ - - if ( transchar[finalst[mach]] == SYM_EPSILON ) - accptnum[finalst[mach]] = accepting_number; - - else - { - int astate = mkstate( SYM_EPSILON ); - accptnum[astate] = accepting_number; - mach = link_machines( mach, astate ); - } - } - - -/* copysingl - make a given number of copies of a singleton machine - * - * synopsis - * - * newsng = copysingl( singl, num ); - * - * newsng - a new singleton composed of num copies of singl - * singl - a singleton machine - * num - the number of copies of singl to be present in newsng - */ - -int copysingl(int singl, int num) -{ - int copy, i; - - copy = mkstate( SYM_EPSILON ); - - for ( i = 1; i <= num; ++i ) - copy = link_machines( copy, dupmachine( singl ) ); - - return ( copy ); - } - - -/* dumpnfa - debugging routine to write out an nfa - * - * synopsis - * int state1; - * dumpnfa( state1 ); - */ - -void dumpnfa(int state1) -{ - int sym, tsp1, tsp2, anum, ns; - - fprintf( stderr, "\n\n********** beginning dump of nfa with start state %d\n", - state1 ); - - /* we probably should loop starting at firstst[state1] and going to - * lastst[state1], but they're not maintained properly when we "or" - * all of the rules together. So we use our knowledge that the machine - * starts at state 1 and ends at lastnfa. - */ - - /* for ( ns = firstst[state1]; ns <= lastst[state1]; ++ns ) */ - for ( ns = 1; ns <= lastnfa; ++ns ) - { - fprintf( stderr, "state # %4d\t", ns ); - - sym = transchar[ns]; - tsp1 = trans1[ns]; - tsp2 = trans2[ns]; - anum = accptnum[ns]; - - fprintf( stderr, "%3d: %4d, %4d", sym, tsp1, tsp2 ); - - if ( anum != NIL ) - fprintf( stderr, " [%d]", anum ); - - fprintf( stderr, "\n" ); - } - - fprintf( stderr, "********** end of dump\n" ); - } - - -/* dupmachine - make a duplicate of a given machine - * - * synopsis - * - * copy = dupmachine( mach ); - * - * copy - holds duplicate of mach - * mach - machine to be duplicated - * - * note that the copy of mach is NOT an exact duplicate; rather, all the - * transition states values are adjusted so that the copy is self-contained, - * as the original should have been. - * - * also note that the original MUST be contiguous, with its low and high - * states accessible by the arrays firstst and lastst - */ - -int dupmachine(int mach) -{ - int i, init, state_offset; - int state = 0; - int last = lastst[mach]; - - for ( i = firstst[mach]; i <= last; ++i ) - { - state = mkstate( transchar[i] ); - - if ( trans1[i] != NO_TRANSITION ) - { - mkxtion( finalst[state], trans1[i] + state - i ); - - if ( transchar[i] == SYM_EPSILON && trans2[i] != NO_TRANSITION ) - mkxtion( finalst[state], trans2[i] + state - i ); - } - - accptnum[state] = accptnum[i]; - } - - if ( state == 0 ) - flexfatal( "empty machine in dupmachine()" ); - - state_offset = state - i + 1; - - init = mach + state_offset; - firstst[init] = firstst[mach] + state_offset; - finalst[init] = finalst[mach] + state_offset; - lastst[init] = lastst[mach] + state_offset; - - return ( init ); - } - - -/* finish_rule - finish up the processing for a rule - * - * synopsis - * - * finish_rule( mach, variable_trail_rule, headcnt, trailcnt ); - * - * An accepting number is added to the given machine. If variable_trail_rule - * is true then the rule has trailing context and both the head and trail - * are variable size. Otherwise if headcnt or trailcnt is non-zero then - * the machine recognizes a pattern with trailing context and headcnt is - * the number of characters in the matched part of the pattern, or zero - * if the matched part has variable length. trailcnt is the number of - * trailing context characters in the pattern, or zero if the trailing - * context has variable length. - */ - -void finish_rule(int mach, int variable_trail_rule, int headcnt, int trailcnt) -{ - add_accept( mach, num_rules ); - - /* we did this in new_rule(), but it often gets the wrong - * number because we do it before we start parsing the current rule - */ - rule_linenum[num_rules] = linenum; - - /* if this is a continued action, then the line-number has - * already been updated, giving us the wrong number - */ - if ( continued_action ) - --rule_linenum[num_rules]; - - fprintf( temp_action_file, "case %d:\n", num_rules ); - - if ( variable_trail_rule ) - { - rule_type[num_rules] = RULE_VARIABLE; - - if ( performance_report ) - fprintf( stderr, "Variable trailing context rule at line %d\n", - rule_linenum[num_rules] ); - - variable_trailing_context_rules = true; - } - - else - { - rule_type[num_rules] = RULE_NORMAL; - - if ( headcnt > 0 || trailcnt > 0 ) - { - /* do trailing context magic to not match the trailing characters */ - char *scanner_cp = "yy_c_buf_p = yy_cp"; - char *scanner_bp = "yy_bp"; - - fprintf( temp_action_file, - "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */\n" ); - - if ( headcnt > 0 ) - fprintf( temp_action_file, "%s = %s + %d;\n", - scanner_cp, scanner_bp, headcnt ); - - else - fprintf( temp_action_file, - "%s -= %d;\n", scanner_cp, trailcnt ); - - fprintf( temp_action_file, - "YY_DO_BEFORE_ACTION; /* set up yytext again */\n" ); - } - } - - line_directive_out( temp_action_file ); - } - - -/* link_machines - connect two machines together - * - * synopsis - * - * new = link_machines( first, last ); - * - * new - a machine constructed by connecting first to last - * first - the machine whose successor is to be last - * last - the machine whose predecessor is to be first - * - * note: this routine concatenates the machine first with the machine - * last to produce a machine new which will pattern-match first first - * and then last, and will fail if either of the sub-patterns fails. - * FIRST is set to new by the operation. last is unmolested. - */ - -int link_machines(int first, int last) -{ - if ( first == NIL ) - return ( last ); - - else if ( last == NIL ) - return ( first ); - - else - { - mkxtion( finalst[first], last ); - finalst[first] = finalst[last]; - lastst[first] = max( lastst[first], lastst[last] ); - firstst[first] = min( firstst[first], firstst[last] ); - - return ( first ); - } - } - - -/* mark_beginning_as_normal - mark each "beginning" state in a machine - * as being a "normal" (i.e., not trailing context- - * associated) states - * - * synopsis - * - * mark_beginning_as_normal( mach ) - * - * mach - machine to mark - * - * The "beginning" states are the epsilon closure of the first state - */ - -void mark_beginning_as_normal(int mach) -{ - switch ( state_type[mach] ) - { - case STATE_NORMAL: - /* oh, we've already visited here */ - return; - - case STATE_TRAILING_CONTEXT: - state_type[mach] = STATE_NORMAL; - - if ( transchar[mach] == SYM_EPSILON ) - { - if ( trans1[mach] != NO_TRANSITION ) - mark_beginning_as_normal( trans1[mach] ); - - if ( trans2[mach] != NO_TRANSITION ) - mark_beginning_as_normal( trans2[mach] ); - } - break; - - default: - flexerror( "bad state type in mark_beginning_as_normal()" ); - break; - } - } - - -/* mkbranch - make a machine that branches to two machines - * - * synopsis - * - * branch = mkbranch( first, second ); - * - * branch - a machine which matches either first's pattern or second's - * first, second - machines whose patterns are to be or'ed (the | operator) - * - * note that first and second are NEITHER destroyed by the operation. Also, - * the resulting machine CANNOT be used with any other "mk" operation except - * more mkbranch's. Compare with mkor() - */ - -int mkbranch(int first, int second) -{ - int eps; - - if ( first == NO_TRANSITION ) - return ( second ); - - else if ( second == NO_TRANSITION ) - return ( first ); - - eps = mkstate( SYM_EPSILON ); - - mkxtion( eps, first ); - mkxtion( eps, second ); - - return ( eps ); - } - - -/* mkclos - convert a machine into a closure - * - * synopsis - * new = mkclos( state ); - * - * new - a new state which matches the closure of "state" - */ - -int mkclos(int state) -{ - return ( mkopt( mkposcl( state ) ) ); - } - - -/* mkopt - make a machine optional - * - * synopsis - * - * new = mkopt( mach ); - * - * new - a machine which optionally matches whatever mach matched - * mach - the machine to make optional - * - * notes: - * 1. mach must be the last machine created - * 2. mach is destroyed by the call - */ - -int mkopt(int mach) -{ - int eps; - - if ( ! SUPER_FREE_EPSILON(finalst[mach]) ) - { - eps = mkstate( SYM_EPSILON ); - mach = link_machines( mach, eps ); - } - - /* can't skimp on the following if FREE_EPSILON(mach) is true because - * some state interior to "mach" might point back to the beginning - * for a closure - */ - eps = mkstate( SYM_EPSILON ); - mach = link_machines( eps, mach ); - - mkxtion( mach, finalst[mach] ); - - return ( mach ); - } - - -/* mkor - make a machine that matches either one of two machines - * - * synopsis - * - * new = mkor( first, second ); - * - * new - a machine which matches either first's pattern or second's - * first, second - machines whose patterns are to be or'ed (the | operator) - * - * note that first and second are both destroyed by the operation - * the code is rather convoluted because an attempt is made to minimize - * the number of epsilon states needed - */ - -int mkor(int first, int second) -{ - int eps, orend; - - if ( first == NIL ) - return ( second ); - - else if ( second == NIL ) - return ( first ); - - else - { - /* see comment in mkopt() about why we can't use the first state - * of "first" or "second" if they satisfy "FREE_EPSILON" - */ - eps = mkstate( SYM_EPSILON ); - - first = link_machines( eps, first ); - - mkxtion( first, second ); - - if ( SUPER_FREE_EPSILON(finalst[first]) && - accptnum[finalst[first]] == NIL ) - { - orend = finalst[first]; - mkxtion( finalst[second], orend ); - } - - else if ( SUPER_FREE_EPSILON(finalst[second]) && - accptnum[finalst[second]] == NIL ) - { - orend = finalst[second]; - mkxtion( finalst[first], orend ); - } - - else - { - eps = mkstate( SYM_EPSILON ); - - first = link_machines( first, eps ); - orend = finalst[first]; - - mkxtion( finalst[second], orend ); - } - } - - finalst[first] = orend; - return ( first ); - } - - -/* mkposcl - convert a machine into a positive closure - * - * synopsis - * new = mkposcl( state ); - * - * new - a machine matching the positive closure of "state" - */ - -int mkposcl(int state) -{ - int eps; - - if ( SUPER_FREE_EPSILON(finalst[state]) ) - { - mkxtion( finalst[state], state ); - return ( state ); - } - - else - { - eps = mkstate( SYM_EPSILON ); - mkxtion( eps, state ); - return ( link_machines( state, eps ) ); - } - } - - -/* mkrep - make a replicated machine - * - * synopsis - * new = mkrep( mach, lb, ub ); - * - * new - a machine that matches whatever "mach" matched from "lb" - * number of times to "ub" number of times - * - * note - * if "ub" is INFINITY then "new" matches "lb" or more occurrences of "mach" - */ - -int mkrep(int mach, int lb, int ub) -{ - int base_mach, tail, copy, i; - - base_mach = copysingl( mach, lb - 1 ); - - if ( ub == INFINITY ) - { - copy = dupmachine( mach ); - mach = link_machines( mach, - link_machines( base_mach, mkclos( copy ) ) ); - } - - else - { - tail = mkstate( SYM_EPSILON ); - - for ( i = lb; i < ub; ++i ) - { - copy = dupmachine( mach ); - tail = mkopt( link_machines( copy, tail ) ); - } - - mach = link_machines( mach, link_machines( base_mach, tail ) ); - } - - return ( mach ); - } - - -/* mkstate - create a state with a transition on a given symbol - * - * synopsis - * - * state = mkstate( sym ); - * - * state - a new state matching sym - * sym - the symbol the new state is to have an out-transition on - * - * note that this routine makes new states in ascending order through the - * state array (and increments LASTNFA accordingly). The routine DUPMACHINE - * relies on machines being made in ascending order and that they are - * CONTIGUOUS. Change it and you will have to rewrite DUPMACHINE (kludge - * that it admittedly is) - */ - -int mkstate(int sym) -{ - if ( ++lastnfa >= current_mns ) - { - if ( (current_mns += MNS_INCREMENT) >= MAXIMUM_MNS ) - lerrif( "input rules are too complicated (>= %d NFA states)", - current_mns ); - - ++num_reallocs; - - firstst = reallocate_integer_array( firstst, current_mns ); - lastst = reallocate_integer_array( lastst, current_mns ); - finalst = reallocate_integer_array( finalst, current_mns ); - transchar = reallocate_integer_array( transchar, current_mns ); - trans1 = reallocate_integer_array( trans1, current_mns ); - trans2 = reallocate_integer_array( trans2, current_mns ); - accptnum = reallocate_integer_array( accptnum, current_mns ); - assoc_rule = reallocate_integer_array( assoc_rule, current_mns ); - state_type = reallocate_integer_array( state_type, current_mns ); - } - - firstst[lastnfa] = lastnfa; - finalst[lastnfa] = lastnfa; - lastst[lastnfa] = lastnfa; - transchar[lastnfa] = sym; - trans1[lastnfa] = NO_TRANSITION; - trans2[lastnfa] = NO_TRANSITION; - accptnum[lastnfa] = NIL; - assoc_rule[lastnfa] = num_rules; - state_type[lastnfa] = current_state_type; - - /* fix up equivalence classes base on this transition. Note that any - * character which has its own transition gets its own equivalence class. - * Thus only characters which are only in character classes have a chance - * at being in the same equivalence class. E.g. "a|b" puts 'a' and 'b' - * into two different equivalence classes. "[ab]" puts them in the same - * equivalence class (barring other differences elsewhere in the input). - */ - - if ( sym < 0 ) - { - /* we don't have to update the equivalence classes since that was - * already done when the ccl was created for the first time - */ - } - - else if ( sym == SYM_EPSILON ) - ++numeps; - - else - { - if ( useecs ) - /* map NUL's to csize */ - mkechar( sym ? sym : csize, nextecm, ecgroup ); - } - - return ( lastnfa ); - } - - -/* mkxtion - make a transition from one state to another - * - * synopsis - * - * mkxtion( statefrom, stateto ); - * - * statefrom - the state from which the transition is to be made - * stateto - the state to which the transition is to be made - */ - -void mkxtion(int statefrom, int stateto) -{ - if ( trans1[statefrom] == NO_TRANSITION ) - trans1[statefrom] = stateto; - - else if ( (transchar[statefrom] != SYM_EPSILON) || - (trans2[statefrom] != NO_TRANSITION) ) - flexfatal( "found too many transitions in mkxtion()" ); - - else - { /* second out-transition for an epsilon state */ - ++eps2; - trans2[statefrom] = stateto; - } - } - -/* new_rule - initialize for a new rule - * - * synopsis - * - * new_rule(); - * - * the global num_rules is incremented and the any corresponding dynamic - * arrays (such as rule_type[]) are grown as needed. - */ - -void new_rule(void) -{ - if ( ++num_rules >= current_max_rules ) - { - ++num_reallocs; - current_max_rules += MAX_RULES_INCREMENT; - rule_type = reallocate_integer_array( rule_type, current_max_rules ); - rule_linenum = - reallocate_integer_array( rule_linenum, current_max_rules ); - } - - if ( num_rules > MAX_RULE ) - lerrif( "too many rules (> %d)!", MAX_RULE ); - - rule_linenum[num_rules] = linenum; - } diff --git a/src/libCom/flex/parse.y b/src/libCom/flex/parse.y deleted file mode 100644 index dff931578..000000000 --- a/src/libCom/flex/parse.y +++ /dev/null @@ -1,702 +0,0 @@ - -/* parse.y - parser for flex input */ - -%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP - -%{ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - -int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen; -int trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule; -Char clower(); - -static int madeany = false; /* whether we've made the '.' character class */ -int previous_continued_action; /* whether the previous rule's action was '|' */ - -%} - -%% -goal : initlex sect1 sect1end sect2 initforrule - { /* add default rule */ - int def_rule; - - pat = cclinit(); - cclnegate( pat ); - - def_rule = mkstate( -pat ); - - finish_rule( def_rule, false, 0, 0 ); - - for ( i = 1; i <= lastsc; ++i ) - scset[i] = mkbranch( scset[i], def_rule ); - - if ( spprdflt ) - fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )", - temp_action_file ); - else - fputs( "ECHO", temp_action_file ); - - fputs( ";\n\tYY_BREAK\n", temp_action_file ); - } - ; - -initlex : - { - /* initialize for processing rules */ - - /* create default DFA start condition */ - scinstal( "INITIAL", false ); - } - ; - -sect1 : sect1 startconddecl WHITESPACE namelist1 '\n' - | - | error '\n' - { synerr( "unknown error processing section 1" ); } - ; - -sect1end : SECTEND - ; - -startconddecl : SCDECL - { - /* these productions are separate from the s1object - * rule because the semantics must be done before - * we parse the remainder of an s1object - */ - - xcluflg = false; - } - - | XSCDECL - { xcluflg = true; } - ; - -namelist1 : namelist1 WHITESPACE NAME - { scinstal( nmstr, xcluflg ); } - - | NAME - { scinstal( nmstr, xcluflg ); } - - | error - { synerr( "bad start condition list" ); } - ; - -sect2 : sect2 initforrule flexrule '\n' - | - ; - -initforrule : - { - /* initialize for a parse of one rule */ - trlcontxt = variable_trail_rule = varlength = false; - trailcnt = headcnt = rulelen = 0; - current_state_type = STATE_NORMAL; - previous_continued_action = continued_action; - new_rule(); - } - ; - -flexrule : scon '^' rule - { - pat = $3; - finish_rule( pat, variable_trail_rule, - headcnt, trailcnt ); - - for ( i = 1; i <= actvp; ++i ) - scbol[actvsc[i]] = - mkbranch( scbol[actvsc[i]], pat ); - - if ( ! bol_needed ) - { - bol_needed = true; - - if ( performance_report ) - pinpoint_message( - "'^' operator results in sub-optimal performance" ); - } - } - - | scon rule - { - pat = $2; - finish_rule( pat, variable_trail_rule, - headcnt, trailcnt ); - - for ( i = 1; i <= actvp; ++i ) - scset[actvsc[i]] = - mkbranch( scset[actvsc[i]], pat ); - } - - | '^' rule - { - pat = $2; - finish_rule( pat, variable_trail_rule, - headcnt, trailcnt ); - - /* add to all non-exclusive start conditions, - * including the default (0) start condition - */ - - for ( i = 1; i <= lastsc; ++i ) - if ( ! scxclu[i] ) - scbol[i] = mkbranch( scbol[i], pat ); - - if ( ! bol_needed ) - { - bol_needed = true; - - if ( performance_report ) - pinpoint_message( - "'^' operator results in sub-optimal performance" ); - } - } - - | rule - { - pat = $1; - finish_rule( pat, variable_trail_rule, - headcnt, trailcnt ); - - for ( i = 1; i <= lastsc; ++i ) - if ( ! scxclu[i] ) - scset[i] = mkbranch( scset[i], pat ); - } - - | scon EOF_OP - { build_eof_action(); } - - | EOF_OP - { - /* this EOF applies to all start conditions - * which don't already have EOF actions - */ - actvp = 0; - - for ( i = 1; i <= lastsc; ++i ) - if ( ! sceof[i] ) - actvsc[++actvp] = i; - - if ( actvp == 0 ) - pinpoint_message( - "warning - all start conditions already have <> rules" ); - - else - build_eof_action(); - } - - | error - { synerr( "unrecognized rule" ); } - ; - -scon : '<' namelist2 '>' - ; - -namelist2 : namelist2 ',' NAME - { - if ( (scnum = sclookup( nmstr )) == 0 ) - format_pinpoint_message( - "undeclared start condition %s", nmstr ); - - else - actvsc[++actvp] = scnum; - } - - | NAME - { - if ( (scnum = sclookup( nmstr )) == 0 ) - format_pinpoint_message( - "undeclared start condition %s", nmstr ); - else - actvsc[actvp = 1] = scnum; - } - - | error - { synerr( "bad start condition list" ); } - ; - -rule : re2 re - { - if ( transchar[lastst[$2]] != SYM_EPSILON ) - /* provide final transition \now/ so it - * will be marked as a trailing context - * state - */ - $2 = link_machines( $2, mkstate( SYM_EPSILON ) ); - - mark_beginning_as_normal( $2 ); - current_state_type = STATE_NORMAL; - - if ( previous_continued_action ) - { - /* we need to treat this as variable trailing - * context so that the backup does not happen - * in the action but before the action switch - * statement. If the backup happens in the - * action, then the rules "falling into" this - * one's action will *also* do the backup, - * erroneously. - */ - if ( ! varlength || headcnt != 0 ) - { - fprintf( stderr, - "%s: warning - trailing context rule at line %d made variable because\n", - program_name, linenum ); - fprintf( stderr, - " of preceding '|' action\n" ); - } - - /* mark as variable */ - varlength = true; - headcnt = 0; - } - - if ( varlength && headcnt == 0 ) - { /* variable trailing context rule */ - /* mark the first part of the rule as the accepting - * "head" part of a trailing context rule - */ - /* by the way, we didn't do this at the beginning - * of this production because back then - * current_state_type was set up for a trail - * rule, and add_accept() can create a new - * state ... - */ - add_accept( $1, num_rules | YY_TRAILING_HEAD_MASK ); - variable_trail_rule = true; - } - - else - trailcnt = rulelen; - - $$ = link_machines( $1, $2 ); - } - - | re2 re '$' - { synerr( "trailing context used twice" ); } - - | re '$' - { - if ( trlcontxt ) - { - synerr( "trailing context used twice" ); - $$ = mkstate( SYM_EPSILON ); - } - - else if ( previous_continued_action ) - { - /* see the comment in the rule for "re2 re" - * above - */ - if ( ! varlength || headcnt != 0 ) - { - fprintf( stderr, - "%s: warning - trailing context rule at line %d made variable because\n", - program_name, linenum ); - fprintf( stderr, - " of preceding '|' action\n" ); - } - - /* mark as variable */ - varlength = true; - headcnt = 0; - } - - trlcontxt = true; - - if ( ! varlength ) - headcnt = rulelen; - - ++rulelen; - trailcnt = 1; - - eps = mkstate( SYM_EPSILON ); - $$ = link_machines( $1, - link_machines( eps, mkstate( '\n' ) ) ); - } - - | re - { - $$ = $1; - - if ( trlcontxt ) - { - if ( varlength && headcnt == 0 ) - /* both head and trail are variable-length */ - variable_trail_rule = true; - else - trailcnt = rulelen; - } - } - ; - - -re : re '|' series - { - varlength = true; - $$ = mkor( $1, $3 ); - } - - | series - { $$ = $1; } - ; - - -re2 : re '/' - { - /* this rule is written separately so - * the reduction will occur before the trailing - * series is parsed - */ - - if ( trlcontxt ) - synerr( "trailing context used twice" ); - else - trlcontxt = true; - - if ( varlength ) - /* we hope the trailing context is fixed-length */ - varlength = false; - else - headcnt = rulelen; - - rulelen = 0; - - current_state_type = STATE_TRAILING_CONTEXT; - $$ = $1; - } - ; - -series : series singleton - { - /* this is where concatenation of adjacent patterns - * gets done - */ - $$ = link_machines( $1, $2 ); - } - - | singleton - { $$ = $1; } - ; - -singleton : singleton '*' - { - varlength = true; - - $$ = mkclos( $1 ); - } - - | singleton '+' - { - varlength = true; - - $$ = mkposcl( $1 ); - } - - | singleton '?' - { - varlength = true; - - $$ = mkopt( $1 ); - } - - | singleton '{' NUMBER ',' NUMBER '}' - { - varlength = true; - - if ( $3 > $5 || $3 < 0 ) - { - synerr( "bad iteration values" ); - $$ = $1; - } - else - { - if ( $3 == 0 ) - $$ = mkopt( mkrep( $1, $3, $5 ) ); - else - $$ = mkrep( $1, $3, $5 ); - } - } - - | singleton '{' NUMBER ',' '}' - { - varlength = true; - - if ( $3 <= 0 ) - { - synerr( "iteration value must be positive" ); - $$ = $1; - } - - else - $$ = mkrep( $1, $3, INFINITY ); - } - - | singleton '{' NUMBER '}' - { - /* the singleton could be something like "(foo)", - * in which case we have no idea what its length - * is, so we punt here. - */ - varlength = true; - - if ( $3 <= 0 ) - { - synerr( "iteration value must be positive" ); - $$ = $1; - } - - else - $$ = link_machines( $1, copysingl( $1, $3 - 1 ) ); - } - - | '.' - { - if ( ! madeany ) - { - /* create the '.' character class */ - anyccl = cclinit(); - ccladd( anyccl, '\n' ); - cclnegate( anyccl ); - - if ( useecs ) - mkeccl( ccltbl + cclmap[anyccl], - ccllen[anyccl], nextecm, - ecgroup, csize, csize ); - - madeany = true; - } - - ++rulelen; - - $$ = mkstate( -anyccl ); - } - - | fullccl - { - if ( ! cclsorted ) - /* sort characters for fast searching. We use a - * shell sort since this list could be large. - */ - cshell( ccltbl + cclmap[$1], ccllen[$1], true ); - - if ( useecs ) - mkeccl( ccltbl + cclmap[$1], ccllen[$1], - nextecm, ecgroup, csize, csize ); - - ++rulelen; - - $$ = mkstate( -$1 ); - } - - | PREVCCL - { - ++rulelen; - - $$ = mkstate( -$1 ); - } - - | '"' string '"' - { $$ = $2; } - - | '(' re ')' - { $$ = $2; } - - | CHAR - { - ++rulelen; - - if ( caseins && $1 >= 'A' && $1 <= 'Z' ) - $1 = clower( $1 ); - - $$ = mkstate( $1 ); - } - ; - -fullccl : '[' ccl ']' - { $$ = $2; } - - | '[' '^' ccl ']' - { - /* *Sigh* - to be compatible Unix lex, negated ccls - * match newlines - */ -#ifdef NOTDEF - ccladd( $3, '\n' ); /* negated ccls don't match '\n' */ - cclsorted = false; /* because we added the newline */ -#endif - cclnegate( $3 ); - $$ = $3; - } - ; - -ccl : ccl CHAR '-' CHAR - { - if ( $2 > $4 ) - synerr( "negative range in character class" ); - - else - { - if ( caseins ) - { - if ( $2 >= 'A' && $2 <= 'Z' ) - $2 = clower( $2 ); - if ( $4 >= 'A' && $4 <= 'Z' ) - $4 = clower( $4 ); - } - - for ( i = $2; i <= $4; ++i ) - ccladd( $1, i ); - - /* keep track if this ccl is staying in alphabetical - * order - */ - cclsorted = cclsorted && ($2 > lastchar); - lastchar = $4; - } - - $$ = $1; - } - - | ccl CHAR - { - if ( caseins ) - if ( $2 >= 'A' && $2 <= 'Z' ) - $2 = clower( $2 ); - - ccladd( $1, $2 ); - cclsorted = cclsorted && ($2 > lastchar); - lastchar = $2; - $$ = $1; - } - - | - { - cclsorted = true; - lastchar = 0; - $$ = cclinit(); - } - ; - -string : string CHAR - { - if ( caseins ) - if ( $2 >= 'A' && $2 <= 'Z' ) - $2 = clower( $2 ); - - ++rulelen; - - $$ = link_machines( $1, mkstate( $2 ) ); - } - - | - { $$ = mkstate( SYM_EPSILON ); } - ; - -%% - - -/* build_eof_action - build the "<>" action for the active start - * conditions - */ - -void build_eof_action() - - { - int i; - - for ( i = 1; i <= actvp; ++i ) - { - if ( sceof[actvsc[i]] ) - format_pinpoint_message( - "multiple <> rules for start condition %s", - scname[actvsc[i]] ); - - else - { - sceof[actvsc[i]] = true; - fprintf( temp_action_file, "case YY_STATE_EOF(%s):\n", - scname[actvsc[i]] ); - } - } - - line_directive_out( temp_action_file ); - } - - -/* synerr - report a syntax error */ - -void synerr( str ) -char str[]; - - { - syntaxerror = true; - pinpoint_message( str ); - } - - -/* format_pinpoint_message - write out a message formatted with one string, - * pinpointing its location - */ - -void format_pinpoint_message( msg, arg ) -char msg[], arg[]; - - { - char errmsg[MAXLINE]; - - (void) sprintf( errmsg, msg, arg ); - pinpoint_message( errmsg ); - } - - -/* pinpoint_message - write out a message, pinpointing its location */ - -void pinpoint_message( str ) -char str[]; - - { - fprintf( stderr, "\"%s\", line %d: %s\n", infilename, linenum, str ); - } - - -/* yyerror - eat up an error message from the parser; - * currently, messages are ignore - */ - -void yyerror( msg ) -char msg[]; - - { - } - -#include "scan.c" -#include "yylex.c" -#include "flex.c" - diff --git a/src/libCom/flex/scan.c b/src/libCom/flex/scan.c deleted file mode 100644 index a12c020bf..000000000 --- a/src/libCom/flex/scan.c +++ /dev/null @@ -1,2251 +0,0 @@ -/* A lexical scanner generated by flex */ - -/* scanner skeleton */ - -#define FLEX_SCANNER - -#include - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include -#include - -#else /* ! __cplusplus */ -#ifdef __GNUC__ -#include -void *malloc( size_t ); -void free( void* ); -#else -#include -#endif /* __GNUC__ */ - -#endif /* ! __cplusplus */ - - -/* amount of stuff to slurp up with each read */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* returned upon end-of-file */ -#define YY_END_TOK 0 - -/* copy whatever the last rule matched to the standard output */ - -/* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */ -/* this used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite() - */ -#define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout ) - -/* gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#define YY_INPUT(buf,result,max_size) \ - if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \ - YY_FATAL_ERROR( "read() in flex scanner failed" ); -#define YY_NULL 0 - -/* no semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#define yyterminate() return ( YY_NULL ) - -/* report a fatal error */ - -/* The funky do-while is used to turn this macro definition into - * a single C statement (which needs a semi-colon terminator). - * This avoids problems with code like: - * - * if ( something_happens ) - * YY_FATAL_ERROR( "oops, the something happened" ); - * else - * everything_okay(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the YY_FATAL_ERROR() call. - */ - -#define YY_FATAL_ERROR(msg) \ - do \ - { \ - (void) fputs( msg, stderr ); \ - (void) putc( '\n', stderr ); \ - exit( 1 ); \ - } \ - while ( 0 ) - -/* default yywrap function - always treat EOF as an EOF */ -#define yywrap() 1 - -/* enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN - */ -#define BEGIN yy_start = 1 + 2 * - -/* action number for EOF rule of a given start state */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* special action meaning "start processing a new file" */ -#define YY_NEW_FILE \ - do \ - { \ - yy_init_buffer( yy_current_buffer, yyin ); \ - yy_load_buffer_state(); \ - } \ - while ( 0 ) - -/* default declaration of generated scanner - a define so the user can - * easily add parameters - */ -#define YY_DECL int yylex ( void ) - -/* code executed at the end of each rule */ -#define YY_BREAK break; - -#define YY_END_OF_BUFFER_CHAR 0 - -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */ -#endif - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -#define YY_CHAR unsigned char -# line 1 "scan.l" -#define INITIAL 0 -/* scan.l - scanner for flex input */ -# line 5 "scan.l" -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#undef yywrap - -#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext ) -#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" ); - -#undef YY_DECL -#define YY_DECL \ - int flexscan() - -#define RETURNCHAR \ - yylval = yytext[0]; \ - return ( CHAR ); - -#define RETURNNAME \ - (void) strcpy( nmstr, (char *) yytext ); \ - return ( NAME ); - -#define PUT_BACK_STRING(str, start) \ - for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \ - unput((str)[i]) - -#define CHECK_REJECT(str) \ - if ( all_upper( str ) ) \ - reject = true; - -#define CHECK_YYMORE(str) \ - if ( all_lower( str ) ) \ - yymore_used = true; -#define SECT2 1 -#define SECT2PROLOG 2 -#define SECT3 3 -#define CODEBLOCK 4 -#define PICKUPDEF 5 -#define SC 6 -#define CARETISBOL 7 -#define NUM 8 -#define QUOTE 9 -#define FIRSTCCL 10 -#define CCL 11 -#define ACTION 12 -#define RECOVER 13 -#define BRACEERROR 14 -#define C_COMMENT 15 -#define ACTION_COMMENT 16 -#define ACTION_STRING 17 -#define PERCENT_BRACE_ACTION 18 -#define USED_LIST 19 -#define CODEBLOCK_2 20 -#define XLATION 21 -# line 76 "scan.l" - -/* done after the current pattern has been matched and before the - * corresponding action - sets up yytext - */ -#define YY_DO_BEFORE_ACTION \ - yytext = yy_bp; \ - yyleng = yy_cp - yy_bp; \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* return all but the first 'n' matched characters back to the input stream */ -#define yyless(n) \ - do \ - { \ - /* undo effects of setting up yytext */ \ - *yy_cp = yy_hold_char; \ - yy_c_buf_p = yy_cp = yy_bp + n; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext ) - - -struct yy_buffer_state - { - FILE *yy_input_file; - - YY_CHAR *yy_ch_buf; /* input buffer */ - YY_CHAR *yy_buf_pos; /* current position in input buffer */ - - /* size of input buffer in bytes, not including room for EOB characters*/ - int yy_buf_size; - - /* number of characters read into yy_ch_buf, not including EOB characters */ - int yy_n_chars; - - int yy_eof_status; /* whether we've seen an EOF on this buffer */ -#define EOF_NOT_SEEN 0 - /* "pending" happens when the EOF has been seen but there's still - * some text process - */ -#define EOF_PENDING 1 -#define EOF_DONE 2 - }; - -static YY_BUFFER_STATE yy_current_buffer; - -/* we provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state" - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed */ -static YY_CHAR yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - - -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -#ifndef YY_USER_INIT -#define YY_USER_INIT -#endif - -extern YY_CHAR *yytext; -extern int yyleng; -extern FILE *yyin, *yyout; - -YY_CHAR *yytext; -int yyleng; - -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; - -#define YY_END_OF_BUFFER 121 -typedef int yy_state_type; -static const short int yy_acclist[482] = - { 0, - 16444,16444, 119, 119, 121, 19, 120, 7, 19, 120, - 18, 120, 19, 120, 19, 120, 16, 19, 120, 1, - 7, 19, 120, 17, 18, 120, 19, 120, 19, 120, - 19, 120, 19, 120, 15, 16, 19, 120, 67, 120, - 59, 67, 120,16444, 8252, 68, 120, 67, 120, 53, - 67, 120, 67, 120, 66, 67, 120, 51, 67, 120, - 67, 120, 67, 120, 67, 120, 50, 59, 67, 120, - 16444, 49, 8252, 61, 68, 120, 67, 120, 67, 120, - 52, 67, 120, 120, 47, 120, 120, 119, 120, 119, - 120, 119, 120, 28, 120, 29, 120, 28, 120, 28, - - 120, 28, 120, 28, 120, 28, 120, 31, 120, 30, - 120, 32, 120, 120, 73, 120, 120, 69, 73, 120, - 70, 73, 120, 72, 73, 120, 74, 120, 88, 120, - 89, 120, 88, 120, 86, 88, 120, 85, 88, 120, - 87, 88, 120, 75, 120, 77, 120, 120, 76, 120, - 75, 120, 81, 120, 80, 81, 120, 81, 120, 81, - 120, 83, 120, 83, 120, 83, 120, 84, 120, 99, - 105, 120, 104, 120, 105, 120, 103, 105, 120, 105, - 120, 105, 120, 100, 105, 120, 100, 105, 120, 100, - 105, 120, 97, 105, 120, 98, 105, 120, 120, 33, - - 120, 120, 91, 120, 120, 90, 120, 22, 120, 24, - 120, 120, 23, 120, 107, 110, 120, 109, 120, 110, - 120, 108, 110, 120, 111, 115, 120, 113, 120, 115, - 120, 114, 115, 120, 115, 120, 95, 120, 95, 120, - 96, 120, 95, 120, 95, 120, 95, 120, 95, 120, - 95, 120, 38, 120, 35, 120, 34, 120, 120, 38, - 120, 38, 120, 44, 120, 42, 44, 120, 45, 120, - 44, 120, 44, 120, 44, 120, 41, 44, 120, 41, - 42, 44, 120, 41, 44, 120, 41, 44, 120, 40, - 41, 44, 120, 41, 44, 120, 7, 18, 16, 1, - - 7, 17, 18, 2, 14, 8, 14, 12, 4, 5, - 3, 15, 16, 59,16444, 8252, 8252, 68, 56, 117, - 117, 117, 55, 54, 55, 50, 59,16444, 49, 8252, - 61, 49, 8252, 61, 68, 63, 50, 47, 46, 119, - 119, 119, 28, 29, 28, 28, 28, 28, 31, 30, - 32, 71, 72, 89, 85, 77, 118, 118, 118, 78, - 79, 82, 99, 104, 102, 101, 100, 100, 100, 33, - 91, 22, 24, 20, 107, 109, 106, 111, 113, 112, - 95, 95, 95, 96, 92, 95, 95, 95, 95, 38, - 35, 34, 38, 38, 42, 45, 43, 43, 43, 42, - - 40, 13, 14, 8, 8, 14, 12, 4, 5, 6, - 57, 58, 64, 117, 117, 55, 55, 65, 63, 28, - 28, 28, 25, 118, 118, 100, 100, 21, 92, 95, - 92, 95, 95, 38, 38, 39, 43, 43, 11, 4, - 11, 13, 5, 117, 28, 28, 118, 100, 100, 95, - 95, 38, 38, 43, 9, 28, 28, 100, 100, 95, - 95, 38, 38, 26, 28, 27, 28, 93, 100, 94, - 100, 93, 95, 94, 95, 36, 38, 37, 38, 10, - 62 - } ; - -static const short int yy_accept[392] = - { 0, - 1, 1, 1, 2, 3, 3, 3, 4, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 6, 8, 11, 13, 15, - 17, 20, 24, 27, 29, 31, 33, 35, 39, 41, - 45, 48, 50, 53, 55, 58, 61, 63, 65, 67, - 72, 77, 79, 81, 84, 85, 87, 88, 90, 92, - 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, - 114, 115, 117, 118, 121, 124, 127, 129, 131, 133, - - 135, 138, 141, 144, 146, 148, 149, 151, 153, 155, - 158, 160, 162, 164, 166, 168, 170, 173, 175, 177, - 180, 182, 184, 187, 190, 193, 196, 199, 200, 202, - 203, 205, 206, 208, 210, 212, 213, 215, 218, 220, - 222, 225, 228, 230, 232, 235, 237, 239, 241, 243, - 245, 247, 249, 251, 253, 255, 257, 259, 260, 262, - 264, 266, 269, 271, 273, 275, 277, 280, 284, 287, - 290, 294, 297, 298, 299, 299, 299, 300, 302, 304, - 304, 304, 305, 305, 306, 308, 308, 309, 310, 310, - 310, 311, 311, 312, 314, 316, 317, 317, 317, 317, - - 319, 320, 320, 320, 320, 321, 322, 323, 324, 325, - 326, 329, 332, 332, 336, 337, 338, 338, 339, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 365, 366, 366, 367, - 368, 369, 370, 370, 371, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 397, 398, 399, 400, 401, 402, 402, 403, 403, - 404, 405, 407, 407, 408, 409, 409, 409, 409, 410, - - 410, 411, 411, 412, 412, 413, 413, 413, 414, 414, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - 424, 424, 424, 425, 426, 427, 428, 428, 429, 429, - 431, 432, 433, 434, 435, 436, 436, 437, 437, 438, - 439, 439, 440, 440, 441, 441, 443, 443, 443, 443, - 444, 444, 444, 444, 445, 446, 447, 448, 449, 450, - 451, 452, 453, 454, 455, 455, 456, 456, 456, 456, - 457, 458, 459, 460, 461, 462, 463, 464, 464, 464, - 466, 468, 470, 472, 474, 476, 478, 480, 481, 482, - 482 - - } ; - -static const YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 6, 1, 7, 8, 9, 10, 1, 11, 12, - 12, 13, 12, 14, 15, 12, 16, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 1, 1, 18, - 1, 19, 12, 1, 25, 26, 27, 28, 29, 30, - 24, 24, 24, 31, 32, 24, 33, 34, 35, 32, - 24, 36, 37, 38, 39, 24, 24, 40, 41, 24, - 20, 21, 22, 23, 24, 1, 25, 26, 27, 28, - - 29, 30, 24, 24, 24, 31, 32, 24, 33, 34, - 35, 32, 24, 36, 37, 38, 39, 24, 24, 40, - 41, 24, 42, 43, 44, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static const YY_CHAR yy_meta[45] = - { 0, - 1, 2, 3, 2, 4, 2, 5, 1, 1, 1, - 6, 1, 7, 1, 8, 6, 9, 1, 1, 1, - 10, 11, 1, 12, 13, 13, 13, 13, 13, 13, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 6, 1, 14 - } ; - -static const short int yy_base[454] = - { 0, - 0, 44, 87, 129, 92, 99, 106, 107, 172, 1520, - 111, 116, 216, 0, 1506, 1464, 123, 258, 141, 148, - 259, 262, 266, 286, 308, 0, 120, 151, 261, 350, - 155, 265, 281, 287, 351, 354, 394, 0, 437, 477, - 0, 0, 517, 537, 1475, 1567, 293, 1567, 1471, 1394, - 0, 360, 1567, 1416, 154, 549, 1405, 0, 1567, 590, - 1567, 1402, 1567, 365, 1567, 1386, 1382, 84, 633, 676, - 1567, 1396, 350, 1567, 158, 0, 161, 301, 1567, 371, - 0, 1567, 1395, 0, 1365, 1352, 1341, 0, 375, 1567, - 1381, 1567, 1567, 1567, 1347, 0, 1567, 1567, 1567, 1360, - - 1567, 1341, 1567, 1567, 1567, 1354, 1567, 427, 1567, 1567, - 428, 1341, 1567, 0, 429, 1567, 0, 1567, 1343, 1567, - 282, 1330, 0, 1313, 1291, 1567, 1567, 375, 1567, 379, - 1567, 1326, 1567, 0, 1567, 1325, 1293, 0, 1567, 1305, - 1279, 0, 1567, 1291, 1567, 0, 0, 381, 1567, 1283, - 1241, 0, 1255, 1242, 0, 384, 1567, 1274, 1241, 1228, - 1567, 445, 1567, 1253, 1217, 431, 1567, 448, 1239, 1203, - 1219, 436, 453, 1567, 1232, 458, 0, 482, 1567, 1218, - 467, 1567, 472, 487, 488, 1210, 493, 0, 498, 239, - 0, 493, 1567, 0, 0, 1567, 1212, 1169, 502, 1567, - - 1567, 1181, 487, 489, 1567, 1185, 0, 0, 1567, 705, - 0, 1567, 1198, 1567, 0, 1567, 507, 0, 511, 1567, - 512, 1567, 521, 0, 1567, 0, 1143, 1140, 749, 0, - 526, 1567, 1567, 0, 1567, 1155, 1567, 1567, 1129, 0, - 1567, 1567, 1567, 0, 1567, 514, 1567, 1140, 1567, 0, - 1108, 1099, 528, 1567, 531, 1567, 0, 1567, 541, 0, - 1567, 1567, 0, 1567, 1567, 0, 546, 1087, 1567, 793, - 0, 1095, 1092, 0, 547, 1567, 1062, 1059, 558, 1567, - 563, 1567, 842, 0, 573, 841, 599, 1567, 854, 604, - 0, 605, 552, 610, 0, 615, 817, 826, 0, 558, - - 1567, 567, 1567, 568, 1567, 577, 819, 1567, 605, 821, - 836, 0, 0, 0, 1567, 0, 816, 809, 0, 1567, - 594, 610, 824, 0, 811, 804, 620, 1567, 625, 0, - 0, 767, 713, 718, 693, 685, 1567, 724, 709, 0, - 626, 1567, 633, 0, 690, 1567, 680, 688, 696, 0, - 693, 680, 835, 1567, 694, 682, 1567, 690, 664, 657, - 596, 597, 562, 1567, 516, 1567, 518, 677, 682, 436, - 437, 241, 238, 132, 136, 105, 98, 78, 79, 0, - 0, 0, 0, 0, 0, 0, 0, 1567, 1567, 1567, - 865, 879, 893, 907, 921, 935, 949, 963, 977, 991, - - 1005, 1019, 1033, 1047, 1061, 1075, 1082, 1095, 1109, 1115, - 1128, 1142, 1156, 1170, 1184, 1198, 1205, 1218, 1225, 1238, - 1252, 1266, 1280, 1291, 1298, 1311, 1325, 1339, 1353, 1367, - 1381, 1388, 1401, 1415, 1429, 693, 695, 1443, 1457, 360, - 1471, 1484, 380, 1498, 700, 1512, 1519, 1525, 701, 1538, - 702, 1552, 703 - } ; - -static const short int yy_def[454] = - { 0, - 390, 390, 391, 391, 392, 392, 393, 393, 390, 9, - 394, 394, 390, 13, 395, 395, 396, 396, 397, 397, - 398, 398, 399, 399, 390, 25, 400, 400, 395, 395, - 401, 401, 402, 402, 403, 403, 390, 37, 404, 404, - 37, 37, 405, 406, 390, 390, 390, 390, 390, 390, - 407, 390, 390, 390, 408, 409, 390, 410, 390, 390, - 390, 390, 390, 390, 390, 390, 411, 412, 390, 390, - 390, 390, 390, 390, 413, 414, 413, 415, 390, 415, - 416, 390, 390, 417, 417, 417, 416, 418, 390, 390, - 390, 390, 390, 390, 390, 419, 390, 390, 390, 390, - - 390, 390, 390, 390, 390, 390, 390, 412, 390, 390, - 420, 421, 390, 422, 412, 390, 423, 390, 390, 390, - 424, 390, 425, 425, 425, 390, 390, 426, 390, 426, - 390, 390, 390, 427, 390, 390, 390, 428, 390, 390, - 390, 429, 390, 390, 390, 430, 431, 431, 390, 390, - 431, 432, 432, 432, 433, 390, 390, 390, 433, 433, - 390, 390, 390, 390, 390, 434, 390, 390, 390, 390, - 390, 434, 390, 390, 390, 390, 407, 390, 390, 390, - 408, 390, 408, 390, 435, 390, 390, 436, 390, 390, - 437, 438, 390, 410, 60, 390, 390, 390, 439, 390, - - 390, 390, 411, 411, 390, 390, 440, 441, 390, 441, - 70, 390, 390, 390, 442, 390, 413, 414, 413, 390, - 415, 390, 415, 416, 390, 417, 417, 417, 390, 418, - 390, 390, 390, 419, 390, 390, 390, 390, 390, 443, - 390, 390, 390, 423, 390, 424, 390, 424, 390, 425, - 425, 425, 426, 390, 426, 390, 427, 390, 444, 428, - 390, 390, 429, 390, 390, 431, 431, 431, 390, 390, - 432, 432, 432, 433, 390, 390, 433, 433, 390, 390, - 390, 390, 390, 445, 390, 390, 390, 390, 390, 390, - 435, 435, 446, 390, 447, 446, 390, 390, 448, 438, - - 390, 438, 390, 439, 390, 439, 390, 390, 411, 411, - 390, 449, 441, 210, 390, 442, 417, 417, 229, 390, - 450, 450, 390, 451, 425, 425, 444, 390, 444, 270, - 452, 432, 432, 433, 433, 390, 390, 390, 390, 453, - 446, 390, 446, 447, 446, 390, 446, 390, 390, 448, - 390, 411, 310, 390, 417, 417, 390, 425, 425, 432, - 432, 433, 433, 390, 390, 390, 390, 411, 411, 417, - 417, 425, 425, 432, 432, 433, 433, 390, 390, 417, - 417, 425, 425, 432, 432, 433, 433, 390, 390, 0, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390 - } ; - -static const short int yy_nxt[1612] = - { 0, - 46, 47, 48, 47, 49, 47, 46, 46, 46, 50, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 46, 46, 46, 46, 52, 53, 52, 54, 52, - 46, 55, 46, 56, 46, 46, 46, 46, 46, 57, - 46, 46, 46, 46, 46, 46, 46, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 46, 46, 46, 60, 61, - 60, 62, 60, 63, 76, 64, 77, 389, 65, 65, - - 206, 76, 65, 77, 66, 388, 67, 68, 79, 79, - 80, 80, 89, 90, 89, 91, 89, 89, 90, 89, - 91, 89, 129, 207, 130, 99, 387, 100, 69, 65, - 70, 71, 70, 72, 70, 63, 101, 64, 73, 102, - 65, 65, 386, 105, 65, 106, 66, 107, 67, 68, - 105, 74, 106, 129, 107, 130, 182, 135, 183, 136, - 218, 108, 219, 218, 385, 219, 103, 137, 108, 384, - 69, 65, 81, 81, 82, 81, 83, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 84, 84, 84, 84, 84, - - 84, 84, 84, 84, 84, 84, 84, 85, 84, 84, - 84, 84, 86, 81, 81, 81, 92, 92, 93, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 94, - 92, 92, 92, 92, 95, 92, 92, 92, 92, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 92, 92, 92, - 99, 93, 100, 131, 93, 132, 383, 135, 93, 136, - 93, 101, 297, 110, 102, 298, 110, 137, 382, 111, - 114, 112, 111, 139, 112, 140, 115, 116, 93, 139, - 93, 140, 247, 141, 173, 174, 173, 175, 173, 141, - - 114, 103, 248, 222, 133, 223, 115, 116, 117, 117, - 118, 117, 119, 117, 120, 117, 117, 117, 121, 117, - 117, 117, 117, 122, 117, 117, 117, 117, 117, 117, - 117, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 124, 123, 123, 123, 123, 125, 126, - 117, 127, 131, 143, 132, 144, 143, 145, 144, 215, - 145, 178, 179, 178, 180, 178, 201, 201, 312, 201, - 201, 146, 312, 222, 146, 223, 231, 254, 231, 255, - 231, 254, 267, 255, 267, 275, 267, 275, 324, 275, - 268, 216, 324, 133, 147, 148, 149, 148, 150, 148, - - 147, 147, 147, 151, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, 152, 153, - 152, 152, 152, 152, 154, 147, 147, 147, 156, 157, - 156, 158, 156, 206, 239, 206, 279, 283, 279, 285, - 279, 285, 283, 285, 173, 174, 173, 175, 173, 287, - 288, 287, 289, 287, 286, 381, 207, 240, 207, 182, - 284, 183, 159, 380, 182, 284, 183, 160, 156, 157, - 156, 158, 156, 178, 179, 178, 180, 178, 290, 292, - 290, 292, 290, 292, 294, 301, 294, 302, 294, 287, - - 288, 287, 289, 296, 305, 309, 306, 204, 308, 218, - 203, 219, 159, 218, 222, 219, 223, 160, 162, 163, - 162, 164, 162, 222, 247, 223, 165, 231, 310, 231, - 254, 231, 255, 254, 248, 255, 379, 166, 168, 163, - 168, 169, 168, 328, 378, 329, 170, 267, 275, 267, - 275, 267, 275, 171, 342, 268, 343, 172, 185, 279, - 301, 279, 302, 279, 336, 337, 336, 338, 336, 301, - 305, 302, 306, 186, 285, 187, 285, 186, 285, 305, - 186, 306, 186, 186, 187, 188, 189, 190, 191, 286, - 192, 195, 196, 195, 197, 195, 320, 377, 321, 198, - - 287, 288, 287, 289, 287, 290, 292, 290, 292, 290, - 292, 294, 320, 294, 321, 294, 345, 346, 345, 347, - 345, 352, 328, 376, 329, 204, 308, 328, 342, 329, - 343, 375, 199, 208, 208, 342, 208, 343, 208, 208, - 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, - 208, 208, 208, 208, 208, 208, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 208, 208, 208, 211, 212, 211, - 213, 211, 346, 374, 343, 198, 336, 337, 336, 338, - 336, 345, 346, 345, 347, 345, 368, 204, 308, 373, - - 204, 308, 204, 308, 295, 295, 299, 299, 340, 354, - 357, 364, 340, 354, 357, 364, 372, 371, 199, 314, - 370, 314, 367, 366, 365, 282, 337, 363, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 362, 361, 315, 319, - 319, 320, 319, 321, 319, 319, 319, 319, 319, 319, - 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - 319, 319, 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - 319, 319, 319, 330, 330, 360, 330, 331, 330, 330, - - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 330, 330, 330, 353, 359, 358, - 238, 204, 308, 356, 355, 353, 353, 353, 353, 353, - 353, 369, 205, 351, 349, 348, 288, 286, 339, 369, - 369, 369, 369, 369, 369, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 78, 78, 78, 78, 78, 78, 78, - - 78, 78, 78, 78, 78, 78, 78, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, - 88, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 98, 98, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 128, 128, 128, 128, 128, 128, 128, 128, 128, - - 128, 128, 128, 128, 128, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 142, 142, 142, 142, 142, 142, 142, - 142, 142, 142, 142, 142, 142, 142, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 177, - 177, 335, 334, 177, 177, 181, 181, 181, 181, 181, - - 181, 181, 181, 181, 181, 181, 181, 181, 181, 184, - 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 194, 194, 333, 332, 194, 194, 203, 203, - 270, 326, 203, 203, 203, 203, 203, 203, 325, 203, - 203, 203, 205, 205, 246, 323, 205, 205, 205, 205, - 205, 205, 205, 205, 205, 205, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 220, 236, 318, 317, 220, 220, 220, 220, 220, 220, - 220, 220, 220, 220, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 221, 221, 221, 221, 224, 224, - - 212, 311, 224, 224, 224, 224, 224, 224, 224, 307, - 303, 224, 226, 226, 196, 293, 226, 226, 230, 230, - 179, 230, 230, 230, 230, 230, 230, 230, 230, 230, - 230, 230, 234, 234, 174, 286, 234, 234, 238, 238, - 281, 280, 238, 238, 238, 238, 238, 238, 238, 238, - 238, 238, 241, 241, 281, 280, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 243, 243, 278, 277, - 243, 243, 243, 243, 243, 243, 276, 243, 243, 243, - 244, 244, 273, 272, 270, 269, 244, 244, 244, 244, - 244, 246, 246, 264, 262, 246, 246, 246, 246, 246, - - 246, 246, 246, 246, 246, 250, 250, 261, 259, 250, - 250, 253, 253, 253, 253, 253, 253, 253, 253, 253, - 253, 253, 253, 253, 253, 257, 257, 258, 256, 257, - 257, 252, 257, 257, 257, 257, 257, 257, 257, 260, - 260, 251, 249, 260, 260, 245, 260, 260, 260, 260, - 260, 260, 260, 263, 263, 242, 237, 236, 263, 263, - 263, 263, 235, 263, 263, 263, 263, 265, 265, 233, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 266, 266, 232, 229, 266, 266, 266, 266, 266, - 266, 266, 228, 227, 266, 271, 271, 225, 214, 271, - - 271, 274, 204, 202, 200, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 282, 282, 193, 179, 282, - 282, 282, 282, 282, 282, 282, 282, 282, 282, 291, - 291, 176, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 300, 300, 300, 300, 300, 300, 300, - 300, 300, 300, 300, 300, 300, 300, 304, 304, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 304, 313, 313, 174, 390, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 316, 316, 97, 316, 316, 316, - 316, 316, 316, 316, 316, 316, 316, 316, 327, 327, - - 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, - 327, 327, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 344, 344, 97, 87, - 344, 344, 350, 350, 390, 390, 350, 350, 322, 322, - 322, 322, 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 331, 331, 390, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 45, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390 - } ; - -static const short int yy_chk[1612] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, - 3, 3, 3, 3, 5, 3, 5, 379, 3, 3, - - 68, 6, 3, 6, 3, 378, 3, 3, 7, 8, - 7, 8, 11, 11, 11, 11, 11, 12, 12, 12, - 12, 12, 27, 68, 27, 17, 377, 17, 3, 3, - 4, 4, 4, 4, 4, 4, 17, 4, 4, 17, - 4, 4, 376, 19, 4, 19, 4, 19, 4, 4, - 20, 4, 20, 28, 20, 28, 55, 31, 55, 31, - 75, 19, 75, 77, 375, 77, 17, 31, 20, 374, - 4, 4, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 18, 21, 18, 29, 22, 29, 373, 32, 23, 32, - 23, 18, 190, 21, 18, 190, 22, 32, 372, 21, - 23, 21, 22, 33, 22, 33, 23, 23, 24, 34, - 24, 34, 121, 33, 47, 47, 47, 47, 47, 34, - - 24, 18, 121, 78, 29, 78, 24, 24, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 30, 35, 30, 35, 36, 35, 36, 73, - 36, 52, 52, 52, 52, 52, 64, 64, 440, 64, - 64, 35, 440, 80, 36, 80, 89, 128, 89, 128, - 89, 130, 148, 130, 148, 156, 148, 156, 443, 156, - 148, 73, 443, 30, 37, 37, 37, 37, 37, 37, - - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 39, 39, - 39, 39, 39, 108, 111, 115, 162, 166, 162, 168, - 162, 168, 172, 168, 173, 173, 173, 173, 173, 176, - 176, 176, 176, 176, 168, 371, 108, 111, 115, 181, - 166, 181, 39, 370, 183, 172, 183, 39, 40, 40, - 40, 40, 40, 178, 178, 178, 178, 178, 184, 185, - 184, 185, 184, 185, 187, 192, 187, 192, 187, 189, - - 189, 189, 189, 189, 199, 204, 199, 203, 203, 217, - 204, 217, 40, 219, 221, 219, 221, 40, 43, 43, - 43, 43, 43, 223, 246, 223, 43, 231, 204, 231, - 253, 231, 253, 255, 246, 255, 367, 43, 44, 44, - 44, 44, 44, 259, 365, 259, 44, 267, 275, 267, - 275, 267, 275, 44, 293, 267, 293, 44, 56, 279, - 300, 279, 300, 279, 281, 281, 281, 281, 281, 302, - 304, 302, 304, 56, 285, 56, 285, 56, 285, 306, - 56, 306, 56, 56, 56, 56, 56, 56, 56, 285, - 56, 60, 60, 60, 60, 60, 321, 363, 321, 60, - - 287, 287, 287, 287, 287, 290, 292, 290, 292, 290, - 292, 294, 322, 294, 322, 294, 296, 296, 296, 296, - 296, 309, 327, 362, 327, 309, 309, 329, 341, 329, - 341, 361, 60, 69, 69, 343, 69, 343, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 70, 70, 70, - 70, 70, 347, 360, 347, 70, 336, 336, 336, 336, - 336, 345, 345, 345, 345, 345, 352, 368, 368, 359, - - 352, 352, 369, 369, 436, 436, 437, 437, 445, 449, - 451, 453, 445, 449, 451, 453, 358, 356, 70, 210, - 355, 210, 351, 349, 348, 339, 338, 335, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 334, 333, 210, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, - 229, 229, 229, 270, 270, 332, 270, 270, 270, 270, - - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 310, 326, 325, - 323, 310, 310, 318, 317, 310, 310, 310, 310, 310, - 310, 353, 311, 307, 298, 297, 289, 286, 283, 353, - 353, 353, 353, 353, 353, 391, 391, 391, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 391, 391, 392, - 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, - 392, 392, 392, 393, 393, 393, 393, 393, 393, 393, - - 393, 393, 393, 393, 393, 393, 393, 394, 394, 394, - 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, - 394, 395, 395, 395, 395, 395, 395, 395, 395, 395, - 395, 395, 395, 395, 395, 396, 396, 396, 396, 396, - 396, 396, 396, 396, 396, 396, 396, 396, 396, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 398, 398, 398, 398, 398, 398, 398, - 398, 398, 398, 398, 398, 398, 398, 399, 399, 399, - 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, - 399, 400, 400, 400, 400, 400, 400, 400, 400, 400, - - 400, 400, 400, 400, 400, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 402, - 402, 402, 402, 402, 402, 402, 402, 402, 402, 402, - 402, 402, 402, 403, 403, 403, 403, 403, 403, 403, - 403, 403, 403, 403, 403, 403, 403, 404, 404, 404, - 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, - 404, 405, 405, 405, 405, 405, 405, 405, 405, 405, - 405, 405, 405, 405, 405, 406, 406, 406, 406, 406, - 406, 406, 406, 406, 406, 406, 406, 406, 406, 407, - 407, 278, 277, 407, 407, 408, 408, 408, 408, 408, - - 408, 408, 408, 408, 408, 408, 408, 408, 408, 409, - 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, - 409, 409, 410, 410, 273, 272, 410, 410, 411, 411, - 268, 252, 411, 411, 411, 411, 411, 411, 251, 411, - 411, 411, 412, 412, 248, 239, 412, 412, 412, 412, - 412, 412, 412, 412, 412, 412, 413, 413, 413, 413, - 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, - 414, 236, 228, 227, 414, 414, 414, 414, 414, 414, - 414, 414, 414, 414, 415, 415, 415, 415, 415, 415, - 415, 415, 415, 415, 415, 415, 415, 415, 416, 416, - - 213, 206, 416, 416, 416, 416, 416, 416, 416, 202, - 198, 416, 417, 417, 197, 186, 417, 417, 418, 418, - 180, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, 419, 419, 175, 171, 419, 419, 420, 420, - 170, 169, 420, 420, 420, 420, 420, 420, 420, 420, - 420, 420, 421, 421, 165, 164, 421, 421, 421, 421, - 421, 421, 421, 421, 421, 421, 422, 422, 160, 159, - 422, 422, 422, 422, 422, 422, 158, 422, 422, 422, - 423, 423, 154, 153, 151, 150, 423, 423, 423, 423, - 423, 424, 424, 144, 141, 424, 424, 424, 424, 424, - - 424, 424, 424, 424, 424, 425, 425, 140, 137, 425, - 425, 426, 426, 426, 426, 426, 426, 426, 426, 426, - 426, 426, 426, 426, 426, 427, 427, 136, 132, 427, - 427, 125, 427, 427, 427, 427, 427, 427, 427, 428, - 428, 124, 122, 428, 428, 119, 428, 428, 428, 428, - 428, 428, 428, 429, 429, 112, 106, 102, 429, 429, - 429, 429, 100, 429, 429, 429, 429, 430, 430, 95, - 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, - 430, 431, 431, 91, 87, 431, 431, 431, 431, 431, - 431, 431, 86, 85, 431, 432, 432, 83, 72, 432, - - 432, 433, 67, 66, 62, 433, 433, 433, 433, 433, - 433, 433, 433, 433, 433, 434, 434, 57, 54, 434, - 434, 434, 434, 434, 434, 434, 434, 434, 434, 435, - 435, 50, 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 438, 438, 438, 438, 438, 438, 438, - 438, 438, 438, 438, 438, 438, 438, 439, 439, 439, - 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, - 439, 441, 441, 49, 45, 441, 441, 441, 441, 441, - 441, 441, 441, 441, 442, 442, 16, 442, 442, 442, - 442, 442, 442, 442, 442, 442, 442, 442, 444, 444, - - 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, - 444, 444, 446, 446, 446, 446, 446, 446, 446, 446, - 446, 446, 446, 446, 446, 446, 447, 447, 15, 10, - 447, 447, 448, 448, 0, 0, 448, 448, 450, 450, - 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, - 450, 450, 452, 452, 0, 452, 452, 452, 452, 452, - 452, 452, 452, 452, 452, 452, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - - 390, 390, 390, 390, 390, 390, 390, 390, 390, 390, - 390 - } ; - -static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; -static YY_CHAR *yy_full_match; -static int yy_lp; -static int yy_looking_for_trail_begin = 0; -static int yy_full_lp; -static int *yy_full_state; -#define YY_TRAILING_MASK 0x2000 -#define YY_TRAILING_HEAD_MASK 0x4000 -#define REJECT \ -{ \ -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ -yy_cp = yy_full_match; /* restore poss. backed-over text */ \ -yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \ -yy_state_ptr = yy_full_state; /* restore orig. state */ \ -yy_current_state = *yy_state_ptr; /* restore curr. state */ \ -++yy_lp; \ -goto find_rule; \ -} -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 - -/* these variables are all declared out here so that section 3 code can - * manipulate them - */ -/* points to current character in buffer */ -static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -static yy_state_type yy_get_previous_state ( void ); -static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); -static int yy_get_next_buffer ( void ); -static void yyunput ( YY_CHAR c, YY_CHAR *buf_ptr ); -void yyrestart ( FILE *input_file ); -void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); -void yy_load_buffer_state ( void ); -YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); -void yy_delete_buffer ( YY_BUFFER_STATE b ); -void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); - -#define yy_new_buffer yy_create_buffer - -YY_DECL - { - yy_state_type yy_current_state; - YY_CHAR *yy_cp, *yy_bp; - int yy_act; - - - static int bracelevel, didadef; - int i, indented_code = false, checking_used = false, new_xlation = false; - int doing_codeblock = false; - Char nmdef[MAXLINE], myesc(); - - - if ( yy_init ) - { - YY_USER_INIT; - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( yy_current_buffer ) - yy_init_buffer( yy_current_buffer, yyin ); - else - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - - yy_init = 0; - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* support of yytext */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of the - * current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; - if ( yy_bp[-1] == '\n' ) - ++yy_current_state; - yy_state_ptr = yy_state_buf; - *yy_state_ptr++ = yy_current_state; -yy_match: - do - { - YY_CHAR yy_c = yy_ec[(int)*yy_cp]; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = yy_def[yy_current_state]; - if ( yy_current_state >= 391 ) - yy_c = yy_meta[(int)yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - *yy_state_ptr++ = yy_current_state; - ++yy_cp; - } - while ( yy_current_state != 390 ); - -yy_find_action: - yy_current_state = *--yy_state_ptr; - yy_lp = yy_accept[yy_current_state]; -find_rule: /* we branch to this label when backtracking */ - for ( ; ; ) /* until we find what rule we matched */ - { - if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) - { - yy_act = yy_acclist[yy_lp]; - if ( yy_act & YY_TRAILING_HEAD_MASK || - yy_looking_for_trail_begin ) - { - if ( yy_act == yy_looking_for_trail_begin ) - { - yy_looking_for_trail_begin = 0; - yy_act &= ~YY_TRAILING_HEAD_MASK; - break; - } - } - else if ( yy_act & YY_TRAILING_MASK ) - { - yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK; - yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK; - } - else - { - yy_full_match = yy_cp; - yy_full_state = yy_state_ptr; - yy_full_lp = yy_lp; - break; - } - ++yy_lp; - goto find_rule; - } - --yy_cp; - yy_current_state = *--yy_state_ptr; - yy_lp = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - YY_USER_ACTION; - -do_action: /* this label is used only to access EOF actions */ - - - switch ( yy_act ) - { -case 1: -# line 82 "scan.l" -indented_code = true; BEGIN(CODEBLOCK); - YY_BREAK -case 2: -# line 83 "scan.l" -++linenum; /* treat as a comment */ - YY_BREAK -case 3: -# line 84 "scan.l" -ECHO; BEGIN(C_COMMENT); - YY_BREAK -case 4: -# line 85 "scan.l" -return ( SCDECL ); - YY_BREAK -case 5: -# line 86 "scan.l" -return ( XSCDECL ); - YY_BREAK -case 6: -# line 87 "scan.l" -{ - ++linenum; - line_directive_out( stdout ); - indented_code = false; - BEGIN(CODEBLOCK); - } - YY_BREAK -case 7: -# line 94 "scan.l" -return ( WHITESPACE ); - YY_BREAK -case 8: -# line 96 "scan.l" -{ - sectnum = 2; - line_directive_out( stdout ); - BEGIN(SECT2PROLOG); - return ( SECTEND ); - } - YY_BREAK -case 9: -# line 103 "scan.l" -{ - pinpoint_message( "warning - %%used/%%unused have been deprecated" ); - checking_used = REALLY_USED; BEGIN(USED_LIST); - } - YY_BREAK -case 10: -# line 107 "scan.l" -{ - checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); - pinpoint_message( "warning - %%used/%%unused have been deprecated" ); - checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); - } - YY_BREAK -case 11: -# line 114 "scan.l" -{ -#ifdef NOTDEF - fprintf( stderr, - "old-style lex command at line %d ignored:\n\t%s", - linenum, yytext ); -#endif - ++linenum; - } - YY_BREAK -case 12: -# line 123 "scan.l" -/* ignore old lex directive */ - YY_BREAK -case 13: -# line 125 "scan.l" -{ - ++linenum; - xlation = - (int *) malloc( sizeof( int ) * (unsigned) csize ); - - if ( ! xlation ) - flexfatal( - "dynamic memory failure building %t table" ); - - for ( i = 0; i < csize; ++i ) - xlation[i] = 0; - - num_xlations = 0; - - BEGIN(XLATION); - } - YY_BREAK -case 14: -# line 142 "scan.l" -synerr( "unrecognized '%' directive" ); - YY_BREAK -case 15: -# line 144 "scan.l" -{ - (void) strcpy( nmstr, (char *) yytext ); - didadef = false; - BEGIN(PICKUPDEF); - } - YY_BREAK -case 16: -# line 150 "scan.l" -RETURNNAME; - YY_BREAK -case 17: -# line 151 "scan.l" -++linenum; /* allows blank lines in section 1 */ - YY_BREAK -case 18: -# line 152 "scan.l" -++linenum; return ( '\n' ); - YY_BREAK -case 19: -# line 153 "scan.l" -synerr( "illegal character" ); BEGIN(RECOVER); - YY_BREAK -case 20: -# line 156 "scan.l" -ECHO; BEGIN(INITIAL); - YY_BREAK -case 21: -# line 157 "scan.l" -++linenum; ECHO; BEGIN(INITIAL); - YY_BREAK -case 22: -# line 158 "scan.l" -ECHO; - YY_BREAK -case 23: -# line 159 "scan.l" -ECHO; - YY_BREAK -case 24: -# line 160 "scan.l" -++linenum; ECHO; - YY_BREAK -case 25: -# line 163 "scan.l" -++linenum; BEGIN(INITIAL); - YY_BREAK -case 26: -# line 164 "scan.l" -ECHO; CHECK_REJECT(yytext); - YY_BREAK -case 27: -# line 165 "scan.l" -ECHO; CHECK_YYMORE(yytext); - YY_BREAK -case 28: -# line 166 "scan.l" -ECHO; - YY_BREAK -case 29: -# line 167 "scan.l" -{ - ++linenum; - ECHO; - if ( indented_code ) - BEGIN(INITIAL); - } - YY_BREAK -case 30: -# line 175 "scan.l" -/* separates name and definition */ - YY_BREAK -case 31: -# line 177 "scan.l" -{ - (void) strcpy( (char *) nmdef, (char *) yytext ); - - for ( i = strlen( (char *) nmdef ) - 1; - i >= 0 && - (nmdef[i] == ' ' || nmdef[i] == '\t'); - --i ) - ; - - nmdef[i + 1] = '\0'; - - ndinstal( nmstr, nmdef ); - didadef = true; - } - YY_BREAK -case 32: -# line 192 "scan.l" -{ - if ( ! didadef ) - synerr( "incomplete name definition" ); - BEGIN(INITIAL); - ++linenum; - } - YY_BREAK -case 33: -# line 199 "scan.l" -++linenum; BEGIN(INITIAL); RETURNNAME; - YY_BREAK -case 34: -# line 202 "scan.l" -++linenum; BEGIN(INITIAL); - YY_BREAK -case 35: -# line 203 "scan.l" - - YY_BREAK -case 36: -# line 204 "scan.l" -{ - if ( all_upper( yytext ) ) - reject_really_used = checking_used; - else - synerr( "unrecognized %used/%unused construct" ); - } - YY_BREAK -case 37: -# line 210 "scan.l" -{ - if ( all_lower( yytext ) ) - yymore_really_used = checking_used; - else - synerr( "unrecognized %used/%unused construct" ); - } - YY_BREAK -case 38: -# line 216 "scan.l" -synerr( "unrecognized %used/%unused construct" ); - YY_BREAK -case 39: -# line 219 "scan.l" -++linenum; BEGIN(INITIAL); - YY_BREAK -case 40: -# line 220 "scan.l" -++num_xlations; new_xlation = true; - YY_BREAK -case 41: -# line 221 "scan.l" -synerr( "bad row in translation table" ); - YY_BREAK -case 42: -# line 222 "scan.l" -/* ignore whitespace */ - YY_BREAK -case 43: -# line 224 "scan.l" -{ - xlation[myesc( yytext )] = - (new_xlation ? num_xlations : -num_xlations); - new_xlation = false; - } - YY_BREAK -case 44: -# line 229 "scan.l" -{ - xlation[yytext[0]] = - (new_xlation ? num_xlations : -num_xlations); - new_xlation = false; - } - YY_BREAK -case 45: -# line 235 "scan.l" -++linenum; - YY_BREAK -case 46: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 238 "scan.l" -{ - ++linenum; - ACTION_ECHO; - MARK_END_OF_PROLOG; - BEGIN(SECT2); - } - YY_BREAK -case 47: -# line 245 "scan.l" -++linenum; ACTION_ECHO; - YY_BREAK -case YY_STATE_EOF(SECT2PROLOG): -# line 247 "scan.l" -MARK_END_OF_PROLOG; yyterminate(); - YY_BREAK -case 49: -# line 249 "scan.l" -++linenum; /* allow blank lines in section 2 */ - YY_BREAK -case 50: -# line 251 "scan.l" -{ - indented_code = (yytext[0] != '%'); - doing_codeblock = true; - bracelevel = 1; - - if ( indented_code ) - ACTION_ECHO; - - BEGIN(CODEBLOCK_2); - } - YY_BREAK -case 51: -# line 262 "scan.l" -BEGIN(SC); return ( '<' ); - YY_BREAK -case 52: -# line 263 "scan.l" -return ( '^' ); - YY_BREAK -case 53: -# line 264 "scan.l" -BEGIN(QUOTE); return ( '"' ); - YY_BREAK -case 54: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 265 "scan.l" -BEGIN(NUM); return ( '{' ); - YY_BREAK -case 55: -# line 266 "scan.l" -BEGIN(BRACEERROR); - YY_BREAK -case 56: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 267 "scan.l" -return ( '$' ); - YY_BREAK -case 57: -# line 269 "scan.l" -{ - bracelevel = 1; - BEGIN(PERCENT_BRACE_ACTION); - return ( '\n' ); - } - YY_BREAK -case 58: -# line 274 "scan.l" -continued_action = true; ++linenum; return ( '\n' ); - YY_BREAK -case 59: -# line 276 "scan.l" -{ - /* this rule is separate from the one below because - * otherwise we get variable trailing context, so - * we can't build the scanner using -{f,F} - */ - bracelevel = 0; - continued_action = false; - BEGIN(ACTION); - return ( '\n' ); - } - YY_BREAK -case 60: -# line 287 "scan.l" -{ - bracelevel = 0; - continued_action = false; - BEGIN(ACTION); - return ( '\n' ); - } - YY_BREAK -case 61: -# line 294 "scan.l" -++linenum; return ( '\n' ); - YY_BREAK -case 62: -# line 296 "scan.l" -return ( EOF_OP ); - YY_BREAK -case 63: -# line 298 "scan.l" -{ - sectnum = 3; - BEGIN(SECT3); - return ( EOF ); /* to stop the parser */ - } - YY_BREAK -case 64: -# line 304 "scan.l" -{ - int cclval; - - (void) strcpy( nmstr, (char *) yytext ); - - /* check to see if we've already encountered this ccl */ - if ( (cclval = ccllookup( (Char *) nmstr )) ) - { - yylval = cclval; - ++cclreuse; - return ( PREVCCL ); - } - else - { - /* we fudge a bit. We know that this ccl will - * soon be numbered as lastccl + 1 by cclinit - */ - cclinstal( (Char *) nmstr, lastccl + 1 ); - - /* push back everything but the leading bracket - * so the ccl can be rescanned - */ - PUT_BACK_STRING((Char *) nmstr, 1); - - BEGIN(FIRSTCCL); - return ( '[' ); - } - } - YY_BREAK -case 65: -# line 333 "scan.l" -{ - Char *nmdefptr; - Char *ndlookup(); - - (void) strcpy( nmstr, (char *) yytext ); - nmstr[yyleng - 1] = '\0'; /* chop trailing brace */ - - /* lookup from "nmstr + 1" to chop leading brace */ - if ( ! (nmdefptr = ndlookup( nmstr + 1 )) ) - synerr( "undefined {name}" ); - - else - { /* push back name surrounded by ()'s */ - unput(')'); - PUT_BACK_STRING(nmdefptr, 0); - unput('('); - } - } - YY_BREAK -case 66: -# line 352 "scan.l" -return ( yytext[0] ); - YY_BREAK -case 67: -# line 353 "scan.l" -RETURNCHAR; - YY_BREAK -case 68: -# line 354 "scan.l" -++linenum; return ( '\n' ); - YY_BREAK -case 69: -# line 357 "scan.l" -return ( ',' ); - YY_BREAK -case 70: -# line 358 "scan.l" -BEGIN(SECT2); return ( '>' ); - YY_BREAK -case 71: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 359 "scan.l" -BEGIN(CARETISBOL); return ( '>' ); - YY_BREAK -case 72: -# line 360 "scan.l" -RETURNNAME; - YY_BREAK -case 73: -# line 361 "scan.l" -synerr( "bad start condition name" ); - YY_BREAK -case 74: -# line 363 "scan.l" -BEGIN(SECT2); return ( '^' ); - YY_BREAK -case 75: -# line 366 "scan.l" -RETURNCHAR; - YY_BREAK -case 76: -# line 367 "scan.l" -BEGIN(SECT2); return ( '"' ); - YY_BREAK -case 77: -# line 369 "scan.l" -{ - synerr( "missing quote" ); - BEGIN(SECT2); - ++linenum; - return ( '"' ); - } - YY_BREAK -case 78: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 377 "scan.l" -BEGIN(CCL); return ( '^' ); - YY_BREAK -case 79: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 378 "scan.l" -return ( '^' ); - YY_BREAK -case 80: -# line 379 "scan.l" -BEGIN(CCL); yylval = '-'; return ( CHAR ); - YY_BREAK -case 81: -# line 380 "scan.l" -BEGIN(CCL); RETURNCHAR; - YY_BREAK -case 82: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -# line 382 "scan.l" -return ( '-' ); - YY_BREAK -case 83: -# line 383 "scan.l" -RETURNCHAR; - YY_BREAK -case 84: -# line 384 "scan.l" -BEGIN(SECT2); return ( ']' ); - YY_BREAK -case 85: -# line 387 "scan.l" -{ - yylval = myctoi( yytext ); - return ( NUMBER ); - } - YY_BREAK -case 86: -# line 392 "scan.l" -return ( ',' ); - YY_BREAK -case 87: -# line 393 "scan.l" -BEGIN(SECT2); return ( '}' ); - YY_BREAK -case 88: -# line 395 "scan.l" -{ - synerr( "bad character inside {}'s" ); - BEGIN(SECT2); - return ( '}' ); - } - YY_BREAK -case 89: -# line 401 "scan.l" -{ - synerr( "missing }" ); - BEGIN(SECT2); - ++linenum; - return ( '}' ); - } - YY_BREAK -case 90: -# line 409 "scan.l" -synerr( "bad name in {}'s" ); BEGIN(SECT2); - YY_BREAK -case 91: -# line 410 "scan.l" -synerr( "missing }" ); ++linenum; BEGIN(SECT2); - YY_BREAK -case 92: -# line 413 "scan.l" -bracelevel = 0; - YY_BREAK -case 93: -# line 414 "scan.l" -{ - ACTION_ECHO; - CHECK_REJECT(yytext); - } - YY_BREAK -case 94: -# line 418 "scan.l" -{ - ACTION_ECHO; - CHECK_YYMORE(yytext); - } - YY_BREAK -case 95: -# line 422 "scan.l" -ACTION_ECHO; - YY_BREAK -case 96: -# line 423 "scan.l" -{ - ++linenum; - ACTION_ECHO; - if ( bracelevel == 0 || - (doing_codeblock && indented_code) ) - { - if ( ! doing_codeblock ) - fputs( "\tYY_BREAK\n", temp_action_file ); - - doing_codeblock = false; - BEGIN(SECT2); - } - } - YY_BREAK - /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */ -case 97: -# line 439 "scan.l" -ACTION_ECHO; ++bracelevel; - YY_BREAK -case 98: -# line 440 "scan.l" -ACTION_ECHO; --bracelevel; - YY_BREAK -case 99: -# line 441 "scan.l" -ACTION_ECHO; - YY_BREAK -case 100: -# line 442 "scan.l" -ACTION_ECHO; - YY_BREAK -case 101: -# line 443 "scan.l" -ACTION_ECHO; BEGIN(ACTION_COMMENT); - YY_BREAK -case 102: -# line 444 "scan.l" -ACTION_ECHO; /* character constant */ - YY_BREAK -case 103: -# line 445 "scan.l" -ACTION_ECHO; BEGIN(ACTION_STRING); - YY_BREAK -case 104: -# line 446 "scan.l" -{ - ++linenum; - ACTION_ECHO; - if ( bracelevel == 0 ) - { - fputs( "\tYY_BREAK\n", temp_action_file ); - BEGIN(SECT2); - } - } - YY_BREAK -case 105: -# line 455 "scan.l" -ACTION_ECHO; - YY_BREAK -case 106: -# line 457 "scan.l" -ACTION_ECHO; BEGIN(ACTION); - YY_BREAK -case 107: -# line 458 "scan.l" -ACTION_ECHO; - YY_BREAK -case 108: -# line 459 "scan.l" -ACTION_ECHO; - YY_BREAK -case 109: -# line 460 "scan.l" -++linenum; ACTION_ECHO; - YY_BREAK -case 110: -# line 461 "scan.l" -ACTION_ECHO; - YY_BREAK -case 111: -# line 463 "scan.l" -ACTION_ECHO; - YY_BREAK -case 112: -# line 464 "scan.l" -ACTION_ECHO; - YY_BREAK -case 113: -# line 465 "scan.l" -++linenum; ACTION_ECHO; - YY_BREAK -case 114: -# line 466 "scan.l" -ACTION_ECHO; BEGIN(ACTION); - YY_BREAK -case 115: -# line 467 "scan.l" -ACTION_ECHO; - YY_BREAK -case YY_STATE_EOF(ACTION): -case YY_STATE_EOF(ACTION_COMMENT): -case YY_STATE_EOF(ACTION_STRING): -# line 469 "scan.l" -{ - synerr( "EOF encountered inside an action" ); - yyterminate(); - } - YY_BREAK -case 117: -# line 475 "scan.l" -{ - yylval = myesc( yytext ); - return ( CHAR ); - } - YY_BREAK -case 118: -# line 480 "scan.l" -{ - yylval = myesc( yytext ); - BEGIN(CCL); - return ( CHAR ); - } - YY_BREAK -case 119: -# line 487 "scan.l" -ECHO; - YY_BREAK -case 120: -# line 488 "scan.l" -ECHO; - YY_BREAK - case YY_STATE_EOF(INITIAL): - case YY_STATE_EOF(SECT2): - case YY_STATE_EOF(SECT3): - case YY_STATE_EOF(CODEBLOCK): - case YY_STATE_EOF(PICKUPDEF): - case YY_STATE_EOF(SC): - case YY_STATE_EOF(CARETISBOL): - case YY_STATE_EOF(NUM): - case YY_STATE_EOF(QUOTE): - case YY_STATE_EOF(FIRSTCCL): - case YY_STATE_EOF(CCL): - case YY_STATE_EOF(RECOVER): - case YY_STATE_EOF(BRACEERROR): - case YY_STATE_EOF(C_COMMENT): - case YY_STATE_EOF(PERCENT_BRACE_ACTION): - case YY_STATE_EOF(USED_LIST): - case YY_STATE_EOF(CODEBLOCK_2): - case YY_STATE_EOF(XLATION): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* amount of text matched not including the EOB char */ - int yy_amount_of_matched_text = yy_cp - yytext - 1; - - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - - /* note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the end- - * of-buffer state). Contrast this with the test in yyinput(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* this was really a NUL */ - { - yy_state_type yy_next_state; - - yy_c_buf_p = yytext + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* okay, we're now positioned to make the - * NUL transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we - * don't want to build jamming into it because - * then it will run more slowly) - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* consume the NUL */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* note: because we've taken care in - * yy_get_next_buffer() to have set up yytext, - * we can now set up yy_c_buf_p so that if some - * total hoser (like flex itself) wants - * to call the scanner after we return the - * YY_NULL, it'll still work - another YY_NULL - * will get returned. - */ - yy_c_buf_p = yytext + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF((yy_start - 1) / 2); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - } - break; - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: -#ifdef FLEX_DEBUG - printf( "action # %d\n", yy_act ); -#endif - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } - } - } - - -/* yy_get_next_buffer - try to read in a new buffer - * - * synopsis - * int yy_get_next_buffer(); - * - * returns a code representing an action - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - - { - YY_CHAR *dest = yy_current_buffer->yy_ch_buf; - YY_CHAR *source = yytext - 1; /* copy prev. char, too */ - int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - /* try to read more data */ - - /* first move last chars to start of buffer */ - number_to_move = yy_c_buf_p - yytext; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_n_chars = 0; - - else - { - int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1; - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - else if ( num_to_read <= 0 ) - YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); - - /* read in more data */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == 1 ) - { - ret_val = EOB_ACT_END_OF_FILE; - yy_current_buffer->yy_eof_status = EOF_DONE; - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_eof_status = EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - /* yytext begins at the second character in yy_ch_buf; the first - * character is the one which preceded it before reading in the latest - * buffer; it needs to be kept around in case it's a newline, so - * yy_get_previous_state() will have with '^' rules active - */ - - yytext = &yy_current_buffer->yy_ch_buf[1]; - - return ( ret_val ); - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached - * - * synopsis - * yy_state_type yy_get_previous_state(); - */ - -static yy_state_type yy_get_previous_state() - - { - yy_state_type yy_current_state; - YY_CHAR *yy_cp; - - YY_CHAR *yy_bp = yytext; - - yy_current_state = yy_start; - if ( yy_bp[-1] == '\n' ) - ++yy_current_state; - yy_state_ptr = yy_state_buf; - *yy_state_ptr++ = yy_current_state; - - for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - YY_CHAR yy_c = (*yy_cp ? yy_ec[(int)*yy_cp] : 1); - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = yy_def[yy_current_state]; - if ( yy_current_state >= 391 ) - yy_c = yy_meta[(int)yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - *yy_state_ptr++ = yy_current_state; - } - - return ( yy_current_state ); - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) - { - int yy_is_jam; - - YY_CHAR yy_c = 1; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = yy_def[yy_current_state]; - if ( yy_current_state >= 391 ) - yy_c = yy_meta[(int)yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - *yy_state_ptr++ = yy_current_state; - yy_is_jam = (yy_current_state == 390); - - return ( yy_is_jam ? 0 : yy_current_state ); - } - - -static void yyunput( YY_CHAR c, YY_CHAR *yy_bp ) - { - YY_CHAR *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */ - YY_CHAR *dest = - &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2]; - YY_CHAR *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += dest - source; - yy_bp += dest - source; - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - if ( yy_cp > yy_bp && yy_cp[-1] == '\n' ) - yy_cp[-2] = '\n'; - - *--yy_cp = c; - - /* note: the formal parameter *must* be called "yy_bp" for this - * macro to now work correctly - */ - YY_DO_BEFORE_ACTION; /* set up yytext again */ - } - - -void yyrestart( FILE *input_file ) - { - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* flush out information for old buffer */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* we don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -void yy_load_buffer_state( void ) - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) ); - - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) ); - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - yy_init_buffer( b, file ); - - return ( b ); - } - - -void yy_delete_buffer( YY_BUFFER_STATE b ) - { - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - free( (char *) b->yy_ch_buf ); - free( (char *) b ); - } - - -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) - { - b->yy_input_file = file; - - /* we put in the '\n' and start reading from [1] so that an - * initial match-at-newline will be true. - */ - - b->yy_ch_buf[0] = '\n'; - b->yy_n_chars = 1; - - /* we always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[1]; - - b->yy_eof_status = EOF_NOT_SEEN; - } -# line 488 "scan.l" - - - -int yywrap() - - { - if ( --num_input_files > 0 ) - { - set_input_file( *++input_files ); - return ( 0 ); - } - - else - return ( 1 ); - } - - -/* set_input_file - open the given file (if NULL, stdin) for scanning */ - -void set_input_file( file ) -char *file; - - { - if ( file ) - { - infilename = file; - yyin = fopen( infilename, "r" ); - - if ( yyin == NULL ) - lerrsf( "can't open %s", file ); - } - - else - { - yyin = stdin; - infilename = ""; - } - } diff --git a/src/libCom/flex/scan.l.DISTRIB b/src/libCom/flex/scan.l.DISTRIB deleted file mode 100644 index a566181d3..000000000 --- a/src/libCom/flex/scan.l.DISTRIB +++ /dev/null @@ -1,525 +0,0 @@ - -/* scan.l - scanner for flex input */ - -%{ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#undef yywrap - -#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext ) -#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" ); - -#undef YY_DECL -#define YY_DECL \ - int flexscan() - -#define RETURNCHAR \ - yylval = yytext[0]; \ - return ( CHAR ); - -#define RETURNNAME \ - (void) strcpy( nmstr, (char *) yytext ); \ - return ( NAME ); - -#define PUT_BACK_STRING(str, start) \ - for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \ - unput((str)[i]) - -#define CHECK_REJECT(str) \ - if ( all_upper( str ) ) \ - reject = true; - -#define CHECK_YYMORE(str) \ - if ( all_lower( str ) ) \ - yymore_used = true; -%} - -%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE -%x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT -%x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2 XLATION - -WS [ \t\f]+ -OPTWS [ \t\f]* -NOT_WS [^ \t\f\r\n] - -NAME [a-z_][a-z_0-9-]* -NOT_NAME [^a-z_\r\n]+ - -SCNAME {NAME} - -ESCSEQ \\([^\r\n]|[0-9]{1,3}|x[0-9a-f]{1,2}) - -%% - static int bracelevel, didadef; - int i, indented_code = false, checking_used = false, new_xlation = false; - int doing_codeblock = false; - Char nmdef[MAXLINE], myesc(); - -^{WS} indented_code = true; BEGIN(CODEBLOCK); -^#.*\r?\n ++linenum; /* treat as a comment */ -^"/*" ECHO; BEGIN(C_COMMENT); -^"%s"{NAME}? return ( SCDECL ); -^"%x"{NAME}? return ( XSCDECL ); -^"%{".*\r?\n { - ++linenum; - line_directive_out( stdout ); - indented_code = false; - BEGIN(CODEBLOCK); - } - -{WS} return ( WHITESPACE ); - -^"%%".* { - sectnum = 2; - line_directive_out( stdout ); - BEGIN(SECT2PROLOG); - return ( SECTEND ); - } - -^"%used" { - pinpoint_message( "warning - %%used/%%unused have been deprecated" ); - checking_used = REALLY_USED; BEGIN(USED_LIST); - } -^"%unused" { - checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); - pinpoint_message( "warning - %%used/%%unused have been deprecated" ); - checking_used = REALLY_NOT_USED; BEGIN(USED_LIST); - } - - -^"%"[aeknopt]" ".*\r?\n { -#ifdef NOTDEF - fprintf( stderr, - "old-style lex command at line %d ignored:\n\t%s", - linenum, yytext ); -#endif - ++linenum; - } - -^"%"[cr]{OPTWS} /* ignore old lex directive */ - -%t{OPTWS}\r?\n { - ++linenum; - xlation = - (int *) malloc( sizeof( int ) * (unsigned) csize ); - - if ( ! xlation ) - flexfatal( - "dynamic memory failure building %t table" ); - - for ( i = 0; i < csize; ++i ) - xlation[i] = 0; - - num_xlations = 0; - - BEGIN(XLATION); - } - -^"%"[^sxanpekotcru{}]{OPTWS} synerr( "unrecognized '%' directive" ); - -^{NAME} { - (void) strcpy( nmstr, (char *) yytext ); - didadef = false; - BEGIN(PICKUPDEF); - } - -{SCNAME} RETURNNAME; -^{OPTWS}\r?\n ++linenum; /* allows blank lines in section 1 */ -{OPTWS}\r?\n ++linenum; return ( '\n' ); -. synerr( "illegal character" ); BEGIN(RECOVER); - - -"*/" ECHO; BEGIN(INITIAL); -"*/".*\r?\n ++linenum; ECHO; BEGIN(INITIAL); -[^*\r\n]+ ECHO; -"*" ECHO; -\r?\n ++linenum; ECHO; - - -^"%}".*\r?\n ++linenum; BEGIN(INITIAL); -"reject" ECHO; CHECK_REJECT(yytext); -"yymore" ECHO; CHECK_YYMORE(yytext); -{NAME}|{NOT_NAME}|. ECHO; -\r?\n { - ++linenum; - ECHO; - if ( indented_code ) - BEGIN(INITIAL); - } - - -{WS} /* separates name and definition */ - -{NOT_WS}.* { - (void) strcpy( (char *) nmdef, (char *) yytext ); - - for ( i = strlen( (char *) nmdef ) - 1; - i >= 0 && - (nmdef[i] == ' ' || nmdef[i] == '\t'); - --i ) - ; - - nmdef[i + 1] = '\0'; - - ndinstal( nmstr, nmdef ); - didadef = true; - } - -\r?\n { - if ( ! didadef ) - synerr( "incomplete name definition" ); - BEGIN(INITIAL); - ++linenum; - } - -.*\r?\n ++linenum; BEGIN(INITIAL); RETURNNAME; - - -\r?\n ++linenum; BEGIN(INITIAL); -{WS} -"reject" { - if ( all_upper( yytext ) ) - reject_really_used = checking_used; - else - synerr( "unrecognized %used/%unused construct" ); - } -"yymore" { - if ( all_lower( yytext ) ) - yymore_really_used = checking_used; - else - synerr( "unrecognized %used/%unused construct" ); - } -{NOT_WS}+ synerr( "unrecognized %used/%unused construct" ); - - -"%t"{OPTWS}\r?\n ++linenum; BEGIN(INITIAL); -^{OPTWS}[0-9]+ ++num_xlations; new_xlation = true; -^. synerr( "bad row in translation table" ); -{WS} /* ignore whitespace */ - -{ESCSEQ} { - xlation[myesc( yytext )] = - (new_xlation ? num_xlations : -num_xlations); - new_xlation = false; - } -. { - xlation[yytext[0]] = - (new_xlation ? num_xlations : -num_xlations); - new_xlation = false; - } - -\r?\n ++linenum; - - -.*\r?\n/{NOT_WS} { - ++linenum; - ACTION_ECHO; - MARK_END_OF_PROLOG; - BEGIN(SECT2); - } - -.*\r?\n ++linenum; ACTION_ECHO; - -<> MARK_END_OF_PROLOG; yyterminate(); - -^{OPTWS}\r?\n ++linenum; /* allow blank lines in section 2 */ - -^({WS}|"%{") { - indented_code = (yytext[0] != '%'); - doing_codeblock = true; - bracelevel = 1; - - if ( indented_code ) - ACTION_ECHO; - - BEGIN(CODEBLOCK_2); - } - -"<" BEGIN(SC); return ( '<' ); -^"^" return ( '^' ); -\" BEGIN(QUOTE); return ( '"' ); -"{"/[0-9] BEGIN(NUM); return ( '{' ); -"{"[^0-9\r\n][^}\r\n]* BEGIN(BRACEERROR); -"$"/[ \t\r\n] return ( '$' ); - -{WS}"%{" { - bracelevel = 1; - BEGIN(PERCENT_BRACE_ACTION); - return ( '\n' ); - } -{WS}"|".*\r?\n continued_action = true; ++linenum; return ( '\n' ); - -{WS} { - /* this rule is separate from the one below because - * otherwise we get variable trailing context, so - * we can't build the scanner using -{f,F} - */ - bracelevel = 0; - continued_action = false; - BEGIN(ACTION); - return ( '\n' ); - } - -{OPTWS}/\r?\n { - bracelevel = 0; - continued_action = false; - BEGIN(ACTION); - return ( '\n' ); - } - -^{OPTWS}\r?\n ++linenum; return ( '\n' ); - -"<>" return ( EOF_OP ); - -^"%%".* { - sectnum = 3; - BEGIN(SECT3); - return ( EOF ); /* to stop the parser */ - } - -"["([^\\\]\r\n]|{ESCSEQ})+"]" { - int cclval; - - (void) strcpy( nmstr, (char *) yytext ); - - /* check to see if we've already encountered this ccl */ - if ( (cclval = ccllookup( (Char *) nmstr )) ) - { - yylval = cclval; - ++cclreuse; - return ( PREVCCL ); - } - else - { - /* we fudge a bit. We know that this ccl will - * soon be numbered as lastccl + 1 by cclinit - */ - cclinstal( (Char *) nmstr, lastccl + 1 ); - - /* push back everything but the leading bracket - * so the ccl can be rescanned - */ - PUT_BACK_STRING((Char *) nmstr, 1); - - BEGIN(FIRSTCCL); - return ( '[' ); - } - } - -"{"{NAME}"}" { - register Char *nmdefptr; - Char *ndlookup(); - - (void) strcpy( nmstr, (char *) yytext ); - nmstr[yyleng - 1] = '\0'; /* chop trailing brace */ - - /* lookup from "nmstr + 1" to chop leading brace */ - if ( ! (nmdefptr = ndlookup( nmstr + 1 )) ) - synerr( "undefined {name}" ); - - else - { /* push back name surrounded by ()'s */ - unput(')'); - PUT_BACK_STRING(nmdefptr, 0); - unput('('); - } - } - -[/|*+?.()] return ( yytext[0] ); -. RETURNCHAR; -\r?\n ++linenum; return ( '\n' ); - - -"," return ( ',' ); -">" BEGIN(SECT2); return ( '>' ); -">"/"^" BEGIN(CARETISBOL); return ( '>' ); -{SCNAME} RETURNNAME; -. synerr( "bad start condition name" ); - -"^" BEGIN(SECT2); return ( '^' ); - - -[^"\r\n] RETURNCHAR; -\" BEGIN(SECT2); return ( '"' ); - -\r?\n { - synerr( "missing quote" ); - BEGIN(SECT2); - ++linenum; - return ( '"' ); - } - - -"^"/[^-\r\n] BEGIN(CCL); return ( '^' ); -"^"/- return ( '^' ); -- BEGIN(CCL); yylval = '-'; return ( CHAR ); -. BEGIN(CCL); RETURNCHAR; - --/[^\]\r\n] return ( '-' ); -[^\]\r\n] RETURNCHAR; -"]" BEGIN(SECT2); return ( ']' ); - - -[0-9]+ { - yylval = myctoi( yytext ); - return ( NUMBER ); - } - -"," return ( ',' ); -"}" BEGIN(SECT2); return ( '}' ); - -. { - synerr( "bad character inside {}'s" ); - BEGIN(SECT2); - return ( '}' ); - } - -\r?\n { - synerr( "missing }" ); - BEGIN(SECT2); - ++linenum; - return ( '}' ); - } - - -"}" synerr( "bad name in {}'s" ); BEGIN(SECT2); -\r?\n synerr( "missing }" ); ++linenum; BEGIN(SECT2); - - -{OPTWS}"%}".* bracelevel = 0; -"reject" { - ACTION_ECHO; - CHECK_REJECT(yytext); - } -"yymore" { - ACTION_ECHO; - CHECK_YYMORE(yytext); - } -{NAME}|{NOT_NAME}|. ACTION_ECHO; -\r?\n { - ++linenum; - ACTION_ECHO; - if ( bracelevel == 0 || - (doing_codeblock && indented_code) ) - { - if ( ! doing_codeblock ) - fputs( "\tYY_BREAK\n", temp_action_file ); - - doing_codeblock = false; - BEGIN(SECT2); - } - } - - - /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */ -"{" ACTION_ECHO; ++bracelevel; -"}" ACTION_ECHO; --bracelevel; -[^a-z_{}"'/\r\n]+ ACTION_ECHO; -{NAME} ACTION_ECHO; -"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT); -"'"([^'\\\r\n]|\\.)*"'" ACTION_ECHO; /* character constant */ -\" ACTION_ECHO; BEGIN(ACTION_STRING); -\r?\n { - ++linenum; - ACTION_ECHO; - if ( bracelevel == 0 ) - { - fputs( "\tYY_BREAK\n", temp_action_file ); - BEGIN(SECT2); - } - } -. ACTION_ECHO; - -"*/" ACTION_ECHO; BEGIN(ACTION); -[^*\r\n]+ ACTION_ECHO; -"*" ACTION_ECHO; -\r?\n ++linenum; ACTION_ECHO; -. ACTION_ECHO; - -[^"\\\r\n]+ ACTION_ECHO; -\\. ACTION_ECHO; -\r?\n ++linenum; ACTION_ECHO; -\" ACTION_ECHO; BEGIN(ACTION); -. ACTION_ECHO; - -<> { - synerr( "EOF encountered inside an action" ); - yyterminate(); - } - - -{ESCSEQ} { - yylval = myesc( yytext ); - return ( CHAR ); - } - -{ESCSEQ} { - yylval = myesc( yytext ); - BEGIN(CCL); - return ( CHAR ); - } - - -.*(\r?\n?) ECHO; -%% - - -int yywrap() - - { - if ( --num_input_files > 0 ) - { - set_input_file( *++input_files ); - return ( 0 ); - } - - else - return ( 1 ); - } - - -/* set_input_file - open the given file (if NULL, stdin) for scanning */ - -void set_input_file( file ) -char *file; - - { - if ( file ) - { - infilename = file; - yyin = fopen( infilename, "r" ); - - if ( yyin == NULL ) - lerrsf( "can't open %s", file ); - } - - else - { - yyin = stdin; - infilename = ""; - } - } diff --git a/src/libCom/flex/sym.c b/src/libCom/flex/sym.c deleted file mode 100644 index 45e1c5409..000000000 --- a/src/libCom/flex/sym.c +++ /dev/null @@ -1,290 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* sym - symbol table routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declare functions that have forward references */ - -int hashfunct (char[], int); - - -struct hash_entry *ndtbl[NAME_TABLE_HASH_SIZE]; -struct hash_entry *sctbl[START_COND_HASH_SIZE]; -struct hash_entry *ccltab[CCL_HASH_SIZE]; - -struct hash_entry *findsym(char *sym, struct hash_entry **table, int table_size); - - -/* addsym - add symbol and definitions to symbol table - * - * synopsis - * char sym[], *str_def; - * int int_def; - * hash_table table; - * int table_size; - * 0 / -1 = addsym( sym, def, int_def, table, table_size ); - * - * -1 is returned if the symbol already exists, and the change not made. - */ - -int addsym(char *sym, char *str_def, int int_def, struct hash_entry **table, int table_size) -{ - int hash_val = hashfunct( sym, table_size ); - struct hash_entry *sym_entry = table[hash_val]; - struct hash_entry *new_entry; - struct hash_entry *successor; - - while ( sym_entry ) - { - if ( ! strcmp( sym, sym_entry->name ) ) - { /* entry already exists */ - return ( -1 ); - } - - sym_entry = sym_entry->next; - } - - /* create new entry */ - new_entry = (struct hash_entry *) malloc( sizeof( struct hash_entry ) ); - - if ( new_entry == NULL ) - flexfatal( "symbol table memory allocation failed" ); - - if ( (successor = table[hash_val]) ) - { - new_entry->next = successor; - successor->prev = new_entry; - } - else - new_entry->next = NULL; - - new_entry->prev = NULL; - new_entry->name = sym; - new_entry->str_val = str_def; - new_entry->int_val = int_def; - - table[hash_val] = new_entry; - - return ( 0 ); - } - - -/* cclinstal - save the text of a character class - * - * synopsis - * Char ccltxt[]; - * int cclnum; - * cclinstal( ccltxt, cclnum ); - */ - -void cclinstal(Char *ccltxt, int cclnum) -{ - /* we don't bother checking the return status because we are not called - * unless the symbol is new - */ - Char *copy_unsigned_string(); - - (void) addsym( (char *) copy_unsigned_string( ccltxt ), (char *) 0, cclnum, - ccltab, CCL_HASH_SIZE ); - } - - -/* ccllookup - lookup the number associated with character class text - * - * synopsis - * Char ccltxt[]; - * int ccllookup, cclval; - * cclval/0 = ccllookup( ccltxt ); - */ - -int ccllookup(Char *ccltxt) -{ - return ( findsym( (char *) ccltxt, ccltab, CCL_HASH_SIZE )->int_val ); - } - - -/* findsym - find symbol in symbol table - * - * synopsis - * char sym[]; - * hash_table table; - * int table_size; - * struct hash_entry *sym_entry, *findsym(); - * sym_entry = findsym( sym, table, table_size ); - */ - -struct hash_entry *findsym(char *sym, struct hash_entry **table, int table_size) -{ - struct hash_entry *sym_entry = table[hashfunct( sym, table_size )]; - static struct hash_entry empty_entry = - { - (struct hash_entry *) 0, (struct hash_entry *) 0, NULL, NULL, 0, - } ; - - while ( sym_entry ) - { - if ( ! strcmp( sym, sym_entry->name ) ) - return ( sym_entry ); - sym_entry = sym_entry->next; - } - - return ( &empty_entry ); - } - - -/* hashfunct - compute the hash value for "str" and hash size "hash_size" - * - * synopsis - * char str[]; - * int hash_size, hash_val; - * hash_val = hashfunct( str, hash_size ); - */ - -int hashfunct(char *str, int hash_size) -{ - int hashval; - int locstr; - - hashval = 0; - locstr = 0; - - while ( str[locstr] ) - hashval = ((hashval << 1) + str[locstr++]) % hash_size; - - return ( hashval ); - } - - -/* ndinstal - install a name definition - * - * synopsis - * char nd[]; - * Char def[]; - * ndinstal( nd, def ); - */ - -void ndinstal(char *nd, Char *def) -{ - char *copy_string(); - Char *copy_unsigned_string(); - - if ( addsym( copy_string( nd ), (char *) copy_unsigned_string( def ), 0, - ndtbl, NAME_TABLE_HASH_SIZE ) ) - synerr( "name defined twice" ); - } - - -/* ndlookup - lookup a name definition - * - * synopsis - * char nd[], *def; - * char *ndlookup(); - * def/NULL = ndlookup( nd ); - */ - -Char *ndlookup(char *nd) -{ - return ( (Char *) findsym( nd, ndtbl, NAME_TABLE_HASH_SIZE )->str_val ); - } - - -/* scinstal - make a start condition - * - * synopsis - * char str[]; - * int xcluflg; - * scinstal( str, xcluflg ); - * - * NOTE - * the start condition is Exclusive if xcluflg is true - */ - -void scinstal(char *str, int xcluflg) -{ - char *copy_string(); - - /* bit of a hack. We know how the default start-condition is - * declared, and don't put out a define for it, because it - * would come out as "#define 0 1" - */ - /* actually, this is no longer the case. The default start-condition - * is now called "INITIAL". But we keep the following for the sake - * of future robustness. - */ - - if ( strcmp( str, "0" ) ) - printf( "#define %s %d\n", str, lastsc ); - - if ( ++lastsc >= current_max_scs ) - { - current_max_scs += MAX_SCS_INCREMENT; - - ++num_reallocs; - - scset = reallocate_integer_array( scset, current_max_scs ); - scbol = reallocate_integer_array( scbol, current_max_scs ); - scxclu = reallocate_integer_array( scxclu, current_max_scs ); - sceof = reallocate_integer_array( sceof, current_max_scs ); - scname = reallocate_char_ptr_array( scname, current_max_scs ); - actvsc = reallocate_integer_array( actvsc, current_max_scs ); - } - - scname[lastsc] = copy_string( str ); - - if ( addsym( scname[lastsc], (char *) 0, lastsc, - sctbl, START_COND_HASH_SIZE ) ) - format_pinpoint_message( "start condition %s declared twice", str ); - - scset[lastsc] = mkstate( SYM_EPSILON ); - scbol[lastsc] = mkstate( SYM_EPSILON ); - scxclu[lastsc] = xcluflg; - sceof[lastsc] = false; - } - - -/* sclookup - lookup the number associated with a start condition - * - * synopsis - * char str[], scnum; - * int sclookup; - * scnum/0 = sclookup( str ); - */ - -int sclookup(char *str) -{ - return ( findsym( str, sctbl, START_COND_HASH_SIZE )->int_val ); - } diff --git a/src/libCom/flex/tblcmp.c b/src/libCom/flex/tblcmp.c deleted file mode 100644 index 3e4c4744b..000000000 --- a/src/libCom/flex/tblcmp.c +++ /dev/null @@ -1,904 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* tblcmp - table compression routines */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "flexdef.h" - - -/* declarations for functions that have forward references */ - -void mkentry (int*, int, int, int, int); -void mkprot (int[], int, int); -void mktemplate (int[], int, int); -void mv2front (int); -int tbldiff (int[], int, int[]); - - -/* bldtbl - build table entries for dfa state - * - * synopsis - * int state[numecs], statenum, totaltrans, comstate, comfreq; - * bldtbl( state, statenum, totaltrans, comstate, comfreq ); - * - * State is the statenum'th dfa state. It is indexed by equivalence class and - * gives the number of the state to enter for a given equivalence class. - * totaltrans is the total number of transitions out of the state. Comstate - * is that state which is the destination of the most transitions out of State. - * Comfreq is how many transitions there are out of State to Comstate. - * - * A note on terminology: - * "protos" are transition tables which have a high probability of - * either being redundant (a state processed later will have an identical - * transition table) or nearly redundant (a state processed later will have - * many of the same out-transitions). A "most recently used" queue of - * protos is kept around with the hope that most states will find a proto - * which is similar enough to be usable, and therefore compacting the - * output tables. - * "templates" are a special type of proto. If a transition table is - * homogeneous or nearly homogeneous (all transitions go to the same - * destination) then the odds are good that future states will also go - * to the same destination state on basically the same character set. - * These homogeneous states are so common when dealing with large rule - * sets that they merit special attention. If the transition table were - * simply made into a proto, then (typically) each subsequent, similar - * state will differ from the proto for two out-transitions. One of these - * out-transitions will be that character on which the proto does not go - * to the common destination, and one will be that character on which the - * state does not go to the common destination. Templates, on the other - * hand, go to the common state on EVERY transition character, and therefore - * cost only one difference. - */ - -void bldtbl(int *state, int statenum, int totaltrans, int comstate, int comfreq) -{ - int extptr, extrct[2][CSIZE + 1]; - int mindiff, minprot, i, d; - int checkcom; - - /* If extptr is 0 then the first array of extrct holds the result of the - * "best difference" to date, which is those transitions which occur in - * "state" but not in the proto which, to date, has the fewest differences - * between itself and "state". If extptr is 1 then the second array of - * extrct hold the best difference. The two arrays are toggled - * between so that the best difference to date can be kept around and - * also a difference just created by checking against a candidate "best" - * proto. - */ - - extptr = 0; - - /* if the state has too few out-transitions, don't bother trying to - * compact its tables - */ - - if ( (totaltrans * 100) < (numecs * PROTO_SIZE_PERCENTAGE) ) - mkentry( state, numecs, statenum, JAMSTATE, totaltrans ); - - else - { - /* checkcom is true if we should only check "state" against - * protos which have the same "comstate" value - */ - - checkcom = comfreq * 100 > totaltrans * CHECK_COM_PERCENTAGE; - - minprot = firstprot; - mindiff = totaltrans; - - if ( checkcom ) - { - /* find first proto which has the same "comstate" */ - for ( i = firstprot; i != NIL; i = protnext[i] ) - if ( protcomst[i] == comstate ) - { - minprot = i; - mindiff = tbldiff( state, minprot, extrct[extptr] ); - break; - } - } - - else - { - /* since we've decided that the most common destination out - * of "state" does not occur with a high enough frequency, - * we set the "comstate" to zero, assuring that if this state - * is entered into the proto list, it will not be considered - * a template. - */ - comstate = 0; - - if ( firstprot != NIL ) - { - minprot = firstprot; - mindiff = tbldiff( state, minprot, extrct[extptr] ); - } - } - - /* we now have the first interesting proto in "minprot". If - * it matches within the tolerances set for the first proto, - * we don't want to bother scanning the rest of the proto list - * to see if we have any other reasonable matches. - */ - - if ( mindiff * 100 > totaltrans * FIRST_MATCH_DIFF_PERCENTAGE ) - { /* not a good enough match. Scan the rest of the protos */ - for ( i = minprot; i != NIL; i = protnext[i] ) - { - d = tbldiff( state, i, extrct[1 - extptr] ); - if ( d < mindiff ) - { - extptr = 1 - extptr; - mindiff = d; - minprot = i; - } - } - } - - /* check if the proto we've decided on as our best bet is close - * enough to the state we want to match to be usable - */ - - if ( mindiff * 100 > totaltrans * ACCEPTABLE_DIFF_PERCENTAGE ) - { - /* no good. If the state is homogeneous enough, we make a - * template out of it. Otherwise, we make a proto. - */ - - if ( comfreq * 100 >= totaltrans * TEMPLATE_SAME_PERCENTAGE ) - mktemplate( state, statenum, comstate ); - - else - { - mkprot( state, statenum, comstate ); - mkentry( state, numecs, statenum, JAMSTATE, totaltrans ); - } - } - - else - { /* use the proto */ - mkentry( extrct[extptr], numecs, statenum, - prottbl[minprot], mindiff ); - - /* if this state was sufficiently different from the proto - * we built it from, make it, too, a proto - */ - - if ( mindiff * 100 >= totaltrans * NEW_PROTO_DIFF_PERCENTAGE ) - mkprot( state, statenum, comstate ); - - /* since mkprot added a new proto to the proto queue, it's possible - * that "minprot" is no longer on the proto queue (if it happened - * to have been the last entry, it would have been bumped off). - * If it's not there, then the new proto took its physical place - * (though logically the new proto is at the beginning of the - * queue), so in that case the following call will do nothing. - */ - - mv2front( minprot ); - } - } - } - - -/* cmptmps - compress template table entries - * - * synopsis - * cmptmps(); - * - * template tables are compressed by using the 'template equivalence - * classes', which are collections of transition character equivalence - * classes which always appear together in templates - really meta-equivalence - * classes. until this point, the tables for templates have been stored - * up at the top end of the nxt array; they will now be compressed and have - * table entries made for them. - */ - -void cmptmps(void) -{ - int tmpstorage[CSIZE + 1]; - int *tmp = tmpstorage, i, j; - int totaltrans, trans; - - peakpairs = numtemps * numecs + tblend; - - if ( usemecs ) - { - /* create equivalence classes base on data gathered on template - * transitions - */ - - nummecs = cre8ecs( tecfwd, tecbck, numecs ); - } - - else - nummecs = numecs; - - if ( lastdfa + numtemps + 1 >= current_max_dfas ) - increase_max_dfas(); - - /* loop through each template */ - - for ( i = 1; i <= numtemps; ++i ) - { - totaltrans = 0; /* number of non-jam transitions out of this template */ - - for ( j = 1; j <= numecs; ++j ) - { - trans = tnxt[numecs * i + j]; - - if ( usemecs ) - { - /* the absolute value of tecbck is the meta-equivalence class - * of a given equivalence class, as set up by cre8ecs - */ - if ( tecbck[j] > 0 ) - { - tmp[tecbck[j]] = trans; - - if ( trans > 0 ) - ++totaltrans; - } - } - - else - { - tmp[j] = trans; - - if ( trans > 0 ) - ++totaltrans; - } - } - - /* it is assumed (in a rather subtle way) in the skeleton that - * if we're using meta-equivalence classes, the def[] entry for - * all templates is the jam template, i.e., templates never default - * to other non-jam table entries (e.g., another template) - */ - - /* leave room for the jam-state after the last real state */ - mkentry( tmp, nummecs, lastdfa + i + 1, JAMSTATE, totaltrans ); - } - } - - - -/* expand_nxt_chk - expand the next check arrays */ - -void expand_nxt_chk(void) -{ - int old_max = current_max_xpairs; - - current_max_xpairs += MAX_XPAIRS_INCREMENT; - - ++num_reallocs; - - nxt = reallocate_integer_array( nxt, current_max_xpairs ); - chk = reallocate_integer_array( chk, current_max_xpairs ); - - memset( (char *) (chk + old_max), 0, - MAX_XPAIRS_INCREMENT * sizeof( int ) / sizeof( char ) ); - } - - -/* find_table_space - finds a space in the table for a state to be placed - * - * synopsis - * int *state, numtrans, block_start; - * int find_table_space(); - * - * block_start = find_table_space( state, numtrans ); - * - * State is the state to be added to the full speed transition table. - * Numtrans is the number of out-transitions for the state. - * - * find_table_space() returns the position of the start of the first block (in - * chk) able to accommodate the state - * - * In determining if a state will or will not fit, find_table_space() must take - * into account the fact that an end-of-buffer state will be added at [0], - * and an action number will be added in [-1]. - */ - -int find_table_space(int *state, int numtrans) -{ - /* firstfree is the position of the first possible occurrence of two - * consecutive unused records in the chk and nxt arrays - */ - int i; - int *state_ptr, *chk_ptr; - int *ptr_to_last_entry_in_state; - - /* if there are too many out-transitions, put the state at the end of - * nxt and chk - */ - if ( numtrans > MAX_XTIONS_FULL_INTERIOR_FIT ) - { - /* if table is empty, return the first available spot in chk/nxt, - * which should be 1 - */ - if ( tblend < 2 ) - return ( 1 ); - - i = tblend - numecs; /* start searching for table space near the - * end of chk/nxt arrays - */ - } - - else - i = firstfree; /* start searching for table space from the - * beginning (skipping only the elements - * which will definitely not hold the new - * state) - */ - - while ( 1 ) /* loops until a space is found */ - { - if ( i + numecs > current_max_xpairs ) - expand_nxt_chk(); - - /* loops until space for end-of-buffer and action number are found */ - while ( 1 ) - { - if ( chk[i - 1] == 0 ) /* check for action number space */ - { - if ( chk[i] == 0 ) /* check for end-of-buffer space */ - break; - - else - i += 2; /* since i != 0, there is no use checking to - * see if (++i) - 1 == 0, because that's the - * same as i == 0, so we skip a space - */ - } - - else - ++i; - - if ( i + numecs > current_max_xpairs ) - expand_nxt_chk(); - } - - /* if we started search from the beginning, store the new firstfree for - * the next call of find_table_space() - */ - if ( numtrans <= MAX_XTIONS_FULL_INTERIOR_FIT ) - firstfree = i + 1; - - /* check to see if all elements in chk (and therefore nxt) that are - * needed for the new state have not yet been taken - */ - - state_ptr = &state[1]; - ptr_to_last_entry_in_state = &chk[i + numecs + 1]; - - for ( chk_ptr = &chk[i + 1]; chk_ptr != ptr_to_last_entry_in_state; - ++chk_ptr ) - if ( *(state_ptr++) != 0 && *chk_ptr != 0 ) - break; - - if ( chk_ptr == ptr_to_last_entry_in_state ) - return ( i ); - - else - ++i; - } - } - - -/* inittbl - initialize transition tables - * - * synopsis - * inittbl(); - * - * Initializes "firstfree" to be one beyond the end of the table. Initializes - * all "chk" entries to be zero. Note that templates are built in their - * own tbase/tdef tables. They are shifted down to be contiguous - * with the non-template entries during table generation. - */ -void inittbl(void) -{ - int i; - - memset( (char *) chk, 0, - current_max_xpairs * sizeof( int ) / sizeof( char ) ); - - tblend = 0; - firstfree = tblend + 1; - numtemps = 0; - - if ( usemecs ) - { - /* set up doubly-linked meta-equivalence classes - * these are sets of equivalence classes which all have identical - * transitions out of TEMPLATES - */ - - tecbck[1] = NIL; - - for ( i = 2; i <= numecs; ++i ) - { - tecbck[i] = i - 1; - tecfwd[i - 1] = i; - } - - tecfwd[numecs] = NIL; - } - } - - -/* mkdeftbl - make the default, "jam" table entries - * - * synopsis - * mkdeftbl(); - */ - -void mkdeftbl(void) -{ - int i; - - jamstate = lastdfa + 1; - - ++tblend; /* room for transition on end-of-buffer character */ - - if ( tblend + numecs > current_max_xpairs ) - expand_nxt_chk(); - - /* add in default end-of-buffer transition */ - nxt[tblend] = end_of_buffer_state; - chk[tblend] = jamstate; - - for ( i = 1; i <= numecs; ++i ) - { - nxt[tblend + i] = 0; - chk[tblend + i] = jamstate; - } - - jambase = tblend; - - base[jamstate] = jambase; - def[jamstate] = 0; - - tblend += numecs; - ++numtemps; - } - - -/* mkentry - create base/def and nxt/chk entries for transition array - * - * synopsis - * int state[numchars + 1], numchars, statenum, deflink, totaltrans; - * mkentry( state, numchars, statenum, deflink, totaltrans ); - * - * "state" is a transition array "numchars" characters in size, "statenum" - * is the offset to be used into the base/def tables, and "deflink" is the - * entry to put in the "def" table entry. If "deflink" is equal to - * "JAMSTATE", then no attempt will be made to fit zero entries of "state" - * (i.e., jam entries) into the table. It is assumed that by linking to - * "JAMSTATE" they will be taken care of. In any case, entries in "state" - * marking transitions to "SAME_TRANS" are treated as though they will be - * taken care of by whereever "deflink" points. "totaltrans" is the total - * number of transitions out of the state. If it is below a certain threshold, - * the tables are searched for an interior spot that will accommodate the - * state array. - */ - -void mkentry(int *state, int numchars, int statenum, int deflink, int totaltrans) -{ - int minec, maxec, i, baseaddr; - int tblbase, tbllast; - - if ( totaltrans == 0 ) - { /* there are no out-transitions */ - if ( deflink == JAMSTATE ) - base[statenum] = JAMSTATE; - else - base[statenum] = 0; - - def[statenum] = deflink; - return; - } - - for ( minec = 1; minec <= numchars; ++minec ) - { - if ( state[minec] != SAME_TRANS ) - if ( state[minec] != 0 || deflink != JAMSTATE ) - break; - } - - if ( totaltrans == 1 ) - { - /* there's only one out-transition. Save it for later to fill - * in holes in the tables. - */ - stack1( statenum, minec, state[minec], deflink ); - return; - } - - for ( maxec = numchars; maxec > 0; --maxec ) - { - if ( state[maxec] != SAME_TRANS ) - if ( state[maxec] != 0 || deflink != JAMSTATE ) - break; - } - - /* Whether we try to fit the state table in the middle of the table - * entries we have already generated, or if we just take the state - * table at the end of the nxt/chk tables, we must make sure that we - * have a valid base address (i.e., non-negative). Note that not only are - * negative base addresses dangerous at run-time (because indexing the - * next array with one and a low-valued character might generate an - * array-out-of-bounds error message), but at compile-time negative - * base addresses denote TEMPLATES. - */ - - /* find the first transition of state that we need to worry about. */ - if ( totaltrans * 100 <= numchars * INTERIOR_FIT_PERCENTAGE ) - { /* attempt to squeeze it into the middle of the tabls */ - baseaddr = firstfree; - - while ( baseaddr < minec ) - { - /* using baseaddr would result in a negative base address below - * find the next free slot - */ - for ( ++baseaddr; chk[baseaddr] != 0; ++baseaddr ) - ; - } - - if ( baseaddr + maxec - minec >= current_max_xpairs ) - expand_nxt_chk(); - - for ( i = minec; i <= maxec; ++i ) - if ( state[i] != SAME_TRANS ) - if ( state[i] != 0 || deflink != JAMSTATE ) - if ( chk[baseaddr + i - minec] != 0 ) - { /* baseaddr unsuitable - find another */ - for ( ++baseaddr; - baseaddr < current_max_xpairs && - chk[baseaddr] != 0; - ++baseaddr ) - ; - - if ( baseaddr + maxec - minec >= current_max_xpairs ) - expand_nxt_chk(); - - /* reset the loop counter so we'll start all - * over again next time it's incremented - */ - - i = minec - 1; - } - } - - else - { - /* ensure that the base address we eventually generate is - * non-negative - */ - baseaddr = max( tblend + 1, minec ); - } - - tblbase = baseaddr - minec; - tbllast = tblbase + maxec; - - if ( tbllast >= current_max_xpairs ) - expand_nxt_chk(); - - base[statenum] = tblbase; - def[statenum] = deflink; - - for ( i = minec; i <= maxec; ++i ) - if ( state[i] != SAME_TRANS ) - if ( state[i] != 0 || deflink != JAMSTATE ) - { - nxt[tblbase + i] = state[i]; - chk[tblbase + i] = statenum; - } - - if ( baseaddr == firstfree ) - /* find next free slot in tables */ - for ( ++firstfree; chk[firstfree] != 0; ++firstfree ) - ; - - tblend = max( tblend, tbllast ); - } - - -/* mk1tbl - create table entries for a state (or state fragment) which - * has only one out-transition - * - * synopsis - * int state, sym, onenxt, onedef; - * mk1tbl( state, sym, onenxt, onedef ); - */ - -void mk1tbl(int state, int sym, int onenxt, int onedef) -{ - if ( firstfree < sym ) - firstfree = sym; - - while ( chk[firstfree] != 0 ) - if ( ++firstfree >= current_max_xpairs ) - expand_nxt_chk(); - - base[state] = firstfree - sym; - def[state] = onedef; - chk[firstfree] = state; - nxt[firstfree] = onenxt; - - if ( firstfree > tblend ) - { - tblend = firstfree++; - - if ( firstfree >= current_max_xpairs ) - expand_nxt_chk(); - } - } - - -/* mkprot - create new proto entry - * - * synopsis - * int state[], statenum, comstate; - * mkprot( state, statenum, comstate ); - */ - -void mkprot(int *state, int statenum, int comstate) -{ - int i, slot, tblbase; - - if ( ++numprots >= MSP || numecs * numprots >= PROT_SAVE_SIZE ) - { - /* gotta make room for the new proto by dropping last entry in - * the queue - */ - slot = lastprot; - lastprot = protprev[lastprot]; - protnext[lastprot] = NIL; - } - - else - slot = numprots; - - protnext[slot] = firstprot; - - if ( firstprot != NIL ) - protprev[firstprot] = slot; - - firstprot = slot; - prottbl[slot] = statenum; - protcomst[slot] = comstate; - - /* copy state into save area so it can be compared with rapidly */ - tblbase = numecs * (slot - 1); - - for ( i = 1; i <= numecs; ++i ) - protsave[tblbase + i] = state[i]; - } - - -/* mktemplate - create a template entry based on a state, and connect the state - * to it - * - * synopsis - * int state[], statenum, comstate, totaltrans; - * mktemplate( state, statenum, comstate, totaltrans ); - */ - -void mktemplate(int *state, int statenum, int comstate) -{ - int i, numdiff, tmpbase, tmp[CSIZE + 1]; - Char transset[CSIZE + 1]; - int tsptr; - - ++numtemps; - - tsptr = 0; - - /* calculate where we will temporarily store the transition table - * of the template in the tnxt[] array. The final transition table - * gets created by cmptmps() - */ - - tmpbase = numtemps * numecs; - - if ( tmpbase + numecs >= current_max_template_xpairs ) - { - current_max_template_xpairs += MAX_TEMPLATE_XPAIRS_INCREMENT; - - ++num_reallocs; - - tnxt = reallocate_integer_array( tnxt, current_max_template_xpairs ); - } - - for ( i = 1; i <= numecs; ++i ) - if ( state[i] == 0 ) - tnxt[tmpbase + i] = 0; - else - { - transset[tsptr++] = i; - tnxt[tmpbase + i] = comstate; - } - - if ( usemecs ) - mkeccl( transset, tsptr, tecfwd, tecbck, numecs, 0 ); - - mkprot( tnxt + tmpbase, -numtemps, comstate ); - - /* we rely on the fact that mkprot adds things to the beginning - * of the proto queue - */ - - numdiff = tbldiff( state, firstprot, tmp ); - mkentry( tmp, numecs, statenum, -numtemps, numdiff ); - } - - -/* mv2front - move proto queue element to front of queue - * - * synopsis - * int qelm; - * mv2front( qelm ); - */ - -void mv2front(int qelm) -{ - if ( firstprot != qelm ) - { - if ( qelm == lastprot ) - lastprot = protprev[lastprot]; - - protnext[protprev[qelm]] = protnext[qelm]; - - if ( protnext[qelm] != NIL ) - protprev[protnext[qelm]] = protprev[qelm]; - - protprev[qelm] = NIL; - protnext[qelm] = firstprot; - protprev[firstprot] = qelm; - firstprot = qelm; - } - } - - -/* place_state - place a state into full speed transition table - * - * synopsis - * int *state, statenum, transnum; - * place_state( state, statenum, transnum ); - * - * State is the statenum'th state. It is indexed by equivalence class and - * gives the number of the state to enter for a given equivalence class. - * Transnum is the number of out-transitions for the state. - */ - -void place_state(int *state, int statenum, int transnum) -{ - int i; - int *state_ptr; - int position = find_table_space( state, transnum ); - - /* base is the table of start positions */ - base[statenum] = position; - - /* put in action number marker; this non-zero number makes sure that - * find_table_space() knows that this position in chk/nxt is taken - * and should not be used for another accepting number in another state - */ - chk[position - 1] = 1; - - /* put in end-of-buffer marker; this is for the same purposes as above */ - chk[position] = 1; - - /* place the state into chk and nxt */ - state_ptr = &state[1]; - - for ( i = 1; i <= numecs; ++i, ++state_ptr ) - if ( *state_ptr != 0 ) - { - chk[position + i] = i; - nxt[position + i] = *state_ptr; - } - - if ( position + numecs > tblend ) - tblend = position + numecs; - } - - -/* stack1 - save states with only one out-transition to be processed later - * - * synopsis - * int statenum, sym, nextstate, deflink; - * stack1( statenum, sym, nextstate, deflink ); - * - * if there's room for another state one the "one-transition" stack, the - * state is pushed onto it, to be processed later by mk1tbl. If there's - * no room, we process the sucker right now. - */ - -void stack1(int statenum, int sym, int nextstate, int deflink) -{ - if ( onesp >= ONE_STACK_SIZE - 1 ) - mk1tbl( statenum, sym, nextstate, deflink ); - - else - { - ++onesp; - onestate[onesp] = statenum; - onesym[onesp] = sym; - onenext[onesp] = nextstate; - onedef[onesp] = deflink; - } - } - - -/* tbldiff - compute differences between two state tables - * - * synopsis - * int state[], pr, ext[]; - * int tbldiff, numdifferences; - * numdifferences = tbldiff( state, pr, ext ) - * - * "state" is the state array which is to be extracted from the pr'th - * proto. "pr" is both the number of the proto we are extracting from - * and an index into the save area where we can find the proto's complete - * state table. Each entry in "state" which differs from the corresponding - * entry of "pr" will appear in "ext". - * Entries which are the same in both "state" and "pr" will be marked - * as transitions to "SAME_TRANS" in "ext". The total number of differences - * between "state" and "pr" is returned as function value. Note that this - * number is "numecs" minus the number of "SAME_TRANS" entries in "ext". - */ - -int tbldiff(int *state, int pr, int *ext) -{ - int i, *sp = state, *ep = ext, *protp; - int numdiff = 0; - - protp = &protsave[numecs * (pr - 1)]; - - for ( i = numecs; i > 0; --i ) - { - if ( *++protp == *++sp ) - *++ep = SAME_TRANS; - else - { - *++ep = *sp; - ++numdiff; - } - } - - return ( numdiff ); - } diff --git a/src/libCom/flex/yylex.c b/src/libCom/flex/yylex.c deleted file mode 100644 index 28f487d6b..000000000 --- a/src/libCom/flex/yylex.c +++ /dev/null @@ -1,218 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* yylex - scanner front-end for flex */ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Vern Paxson. - * - * The United States Government has rights in this work pursuant - * to contract no. DE-AC03-76SF00098 between the United States - * Department of Energy and the University of California. - * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * Neither the name of the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include "flexdef.h" -#include "parse.h" - -/* ANSI C does not guarantee that isascii() is defined */ -#ifndef isascii -#define isascii(c) ((c) <= 0177) -#endif - - -/* yylex - scan for a regular expression token - * - * synopsis - * - * token = yylex(); - * - * token - return token found - */ - -int yylex(void) -{ - int toktype; - static int beglin = false; - - if ( eofseen ) - toktype = EOF; - else - toktype = flexscan(); - - if ( toktype == EOF || toktype == 0 ) - { - eofseen = 1; - - if ( sectnum == 1 ) - { - synerr( "premature EOF" ); - sectnum = 2; - toktype = SECTEND; - } - - else if ( sectnum == 2 ) - { - sectnum = 3; - toktype = 0; - } - - else - toktype = 0; - } - - if ( trace ) - { - if ( beglin ) - { - fprintf( stderr, "%d\t", num_rules + 1 ); - beglin = 0; - } - - switch ( toktype ) - { - case '<': - case '>': - case '^': - case '$': - case '"': - case '[': - case ']': - case '{': - case '}': - case '|': - case '(': - case ')': - case '-': - case '/': - case '\\': - case '?': - case '.': - case '*': - case '+': - case ',': - (void) putc( toktype, stderr ); - break; - - case '\n': - (void) putc( '\n', stderr ); - - if ( sectnum == 2 ) - beglin = 1; - - break; - - case SCDECL: - fputs( "%s", stderr ); - break; - - case XSCDECL: - fputs( "%x", stderr ); - break; - - case WHITESPACE: - (void) putc( ' ', stderr ); - break; - - case SECTEND: - fputs( "%%\n", stderr ); - - /* we set beglin to be true so we'll start - * writing out numbers as we echo rules. flexscan() has - * already assigned sectnum - */ - - if ( sectnum == 2 ) - beglin = 1; - - break; - - case NAME: - fprintf( stderr, "'%s'", nmstr ); - break; - - case CHAR: - switch ( yylval ) - { - case '<': - case '>': - case '^': - case '$': - case '"': - case '[': - case ']': - case '{': - case '}': - case '|': - case '(': - case ')': - case '-': - case '/': - case '\\': - case '?': - case '.': - case '*': - case '+': - case ',': - fprintf( stderr, "\\%c", yylval ); - break; - - default: - if ( ! isascii( yylval ) || ! isprint( yylval ) ) - fprintf( stderr, "\\%.3o", yylval ); - else - (void) putc( yylval, stderr ); - break; - } - - break; - - case NUMBER: - fprintf( stderr, "%d", yylval ); - break; - - case PREVCCL: - fprintf( stderr, "[%d]", yylval ); - break; - - case EOF_OP: - fprintf( stderr, "<>" ); - break; - - case 0: - fprintf( stderr, "End Marker" ); - break; - - default: - fprintf( stderr, "*Something Weird* - tok: %d val: %d\n", - toktype, yylval ); - break; - } - } - - return ( toktype ); -} - diff --git a/src/libCom/freeList/Makefile b/src/libCom/freeList/Makefile deleted file mode 100644 index 3a1e25182..000000000 --- a/src/libCom/freeList/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/freeList - -INC += freeList.h - -Com_SRCS += freeListLib.c diff --git a/src/libCom/freeList/freeList.h b/src/libCom/freeList/freeList.h deleted file mode 100644 index 77ebfb82e..000000000 --- a/src/libCom/freeList/freeList.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 04-19-94 */ - -#ifndef INCfreeListh -#define INCfreeListh - -#include -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void epicsShareAPI freeListInitPvt(void **ppvt,int size,int nmalloc); -epicsShareFunc void * epicsShareAPI freeListCalloc(void *pvt); -epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt); -epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem); -epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt); -epicsShareFunc size_t epicsShareAPI freeListItemsAvail(void *pvt); - -#ifdef __cplusplus -} -#endif - -#endif /*INCfreeListh*/ diff --git a/src/libCom/freeList/freeListLib.c b/src/libCom/freeList/freeListLib.c deleted file mode 100755 index b489a476d..000000000 --- a/src/libCom/freeList/freeListLib.c +++ /dev/null @@ -1,181 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 04-19-94 */ - -#include -#include -#include - -#include "valgrind/valgrind.h" - -#ifndef NVALGRIND -/* buffer around allocations to detect out of bounds access */ -#define REDZONE sizeof(double) -#else -#define REDZONE 0 -#endif - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsMutex.h" -#include "freeList.h" -#include "adjustment.h" - -typedef struct allocMem { - struct allocMem *next; - void *memory; -}allocMem; -typedef struct { - int size; - int nmalloc; - void *head; - allocMem *mallochead; - size_t nBlocksAvailable; - epicsMutexId lock; -}FREELISTPVT; - -epicsShareFunc void epicsShareAPI - freeListInitPvt(void **ppvt,int size,int nmalloc) -{ - FREELISTPVT *pfl; - - pfl = callocMustSucceed(1,sizeof(FREELISTPVT), "freeListInitPvt"); - pfl->size = adjustToWorstCaseAlignment(size); - pfl->nmalloc = nmalloc; - pfl->head = NULL; - pfl->mallochead = NULL; - pfl->nBlocksAvailable = 0u; - pfl->lock = epicsMutexMustCreate(); - *ppvt = (void *)pfl; - VALGRIND_CREATE_MEMPOOL(pfl, REDZONE, 0); - return; -} - -epicsShareFunc void * epicsShareAPI freeListCalloc(void *pvt) -{ - FREELISTPVT *pfl = pvt; -# ifdef EPICS_FREELIST_DEBUG - return callocMustSucceed(1,pfl->size,"freeList Debug Calloc"); -# else - void *ptemp; - - ptemp = freeListMalloc(pvt); - if(ptemp) memset((char *)ptemp,0,pfl->size); - return(ptemp); -# endif -} - -epicsShareFunc void * epicsShareAPI freeListMalloc(void *pvt) -{ - FREELISTPVT *pfl = pvt; -# ifdef EPICS_FREELIST_DEBUG - return callocMustSucceed(1,pfl->size,"freeList Debug Malloc"); -# else - void *ptemp; - void **ppnext; - allocMem *pallocmem; - int i; - - epicsMutexMustLock(pfl->lock); - ptemp = pfl->head; - if(ptemp==0) { - /* layout of each block. nmalloc+1 REDZONEs for nmallocs. - * The first sizeof(void*) bytes are used to store a pointer - * to the next free block. - * - * | RED | size0 ------ | RED | size1 | ... | RED | - * | | next | ----- | - */ - ptemp = (void *)malloc(pfl->nmalloc*(pfl->size+REDZONE)+REDZONE); - if(ptemp==0) { - epicsMutexUnlock(pfl->lock); - return(0); - } - pallocmem = (allocMem *)calloc(1,sizeof(allocMem)); - if(pallocmem==0) { - epicsMutexUnlock(pfl->lock); - free(ptemp); - return(0); - } - pallocmem->memory = ptemp; /* real allocation */ - ptemp = REDZONE + (char *) ptemp; /* skip first REDZONE */ - if(pfl->mallochead) - pallocmem->next = pfl->mallochead; - pfl->mallochead = pallocmem; - for(i=0; inmalloc; i++) { - ppnext = ptemp; - VALGRIND_MEMPOOL_ALLOC(pfl, ptemp, sizeof(void*)); - *ppnext = pfl->head; - pfl->head = ptemp; - ptemp = ((char *)ptemp) + pfl->size+REDZONE; - } - ptemp = pfl->head; - pfl->nBlocksAvailable += pfl->nmalloc; - } - ppnext = pfl->head; - pfl->head = *ppnext; - pfl->nBlocksAvailable--; - epicsMutexUnlock(pfl->lock); - VALGRIND_MEMPOOL_FREE(pfl, ptemp); - VALGRIND_MEMPOOL_ALLOC(pfl, ptemp, pfl->size); - return(ptemp); -# endif -} - -epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem) -{ - FREELISTPVT *pfl = pvt; -# ifdef EPICS_FREELIST_DEBUG - memset ( pmem, 0xdd, pfl->size ); - free(pmem); -# else - void **ppnext; - - VALGRIND_MEMPOOL_FREE(pvt, pmem); - VALGRIND_MEMPOOL_ALLOC(pvt, pmem, sizeof(void*)); - - epicsMutexMustLock(pfl->lock); - ppnext = pmem; - *ppnext = pfl->head; - pfl->head = pmem; - pfl->nBlocksAvailable++; - epicsMutexUnlock(pfl->lock); -# endif -} - -epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt) -{ - FREELISTPVT *pfl = pvt; - allocMem *phead; - allocMem *pnext; - - VALGRIND_DESTROY_MEMPOOL(pvt); - - phead = pfl->mallochead; - while(phead) { - pnext = phead->next; - free(phead->memory); - free(phead); - phead = pnext; - } - epicsMutexDestroy(pfl->lock); - free(pvt); -} - -epicsShareFunc size_t epicsShareAPI freeListItemsAvail(void *pvt) -{ - FREELISTPVT *pfl = pvt; - size_t nBlocksAvailable; - epicsMutexMustLock(pfl->lock); - nBlocksAvailable = pfl->nBlocksAvailable; - epicsMutexUnlock(pfl->lock); - return nBlocksAvailable; -} - diff --git a/src/libCom/gpHash/Makefile b/src/libCom/gpHash/Makefile deleted file mode 100644 index 6fcd3f8a7..000000000 --- a/src/libCom/gpHash/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/gpHash - -INC += gpHash.h - -Com_SRCS += gpHashLib.c diff --git a/src/libCom/gpHash/gpHash.h b/src/libCom/gpHash/gpHash.h deleted file mode 100644 index d9c0dd204..000000000 --- a/src/libCom/gpHash/gpHash.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Marty Kraimer Date: 04-07-94 */ - -/* gph provides a general purpose directory accessed via a hash table*/ - -#ifndef INC_gpHash_H -#define INC_gpHash_H - -#include "shareLib.h" - -#include "ellLib.h" - -typedef struct{ - ELLNODE node; - const char *name; /*address of name placed in directory*/ - void *pvtid; /*private name for subsystem user*/ - void *userPvt; /*private for user*/ -} GPHENTRY; - -struct gphPvt; - -#ifdef __cplusplus -extern "C" { -#endif - -/*tableSize must be power of 2 in range 256 to 65536*/ -epicsShareFunc void epicsShareAPI - gphInitPvt(struct gphPvt **ppvt, int tableSize); -epicsShareFunc GPHENTRY * epicsShareAPI - gphFind(struct gphPvt *pvt, const char *name, void *pvtid); -epicsShareFunc GPHENTRY * epicsShareAPI - gphFindParse(struct gphPvt *pvt, const char *name, size_t len, void *pvtid); -epicsShareFunc GPHENTRY * epicsShareAPI - gphAdd(struct gphPvt *pvt, const char *name, void *pvtid); -epicsShareFunc void epicsShareAPI - gphDelete(struct gphPvt *pvt, const char *name, void *pvtid); -epicsShareFunc void epicsShareAPI gphFreeMem(struct gphPvt *pvt); -epicsShareFunc void epicsShareAPI gphDump(struct gphPvt *pvt); -epicsShareFunc void epicsShareAPI gphDumpFP(FILE *fp, struct gphPvt *pvt); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_gpHash_H */ diff --git a/src/libCom/gpHash/gpHashLib.c b/src/libCom/gpHash/gpHashLib.c deleted file mode 100644 index a56f00a0c..000000000 --- a/src/libCom/gpHash/gpHashLib.c +++ /dev/null @@ -1,244 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 04-07-94 */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsMutex.h" -#include "epicsStdioRedirect.h" -#include "epicsString.h" -#include "dbDefs.h" -#include "ellLib.h" -#include "epicsPrint.h" -#include "gpHash.h" - -typedef struct gphPvt { - int size; - unsigned int mask; - ELLLIST **paplist; /*pointer to array of pointers to ELLLIST */ - epicsMutexId lock; -} gphPvt; - -#define MIN_SIZE 256 -#define DEFAULT_SIZE 512 -#define MAX_SIZE 65536 - - -void epicsShareAPI gphInitPvt(gphPvt **ppvt, int size) -{ - gphPvt *pgphPvt; - - if (size & (size - 1)) { - fprintf(stderr, "gphInitPvt: %d is not a power of 2\n", size); - size = DEFAULT_SIZE; - } - - if (size < MIN_SIZE) - size = MIN_SIZE; - - if (size > MAX_SIZE) - size = MAX_SIZE; - - pgphPvt = callocMustSucceed(1, sizeof(gphPvt), "gphInitPvt"); - pgphPvt->size = size; - pgphPvt->mask = size - 1; - pgphPvt->paplist = callocMustSucceed(size, sizeof(ELLLIST *), "gphInitPvt"); - pgphPvt->lock = epicsMutexMustCreate(); - *ppvt = pgphPvt; - return; -} - -GPHENTRY * epicsShareAPI gphFindParse(gphPvt *pgphPvt, const char *name, size_t len, void *pvtid) -{ - ELLLIST **paplist; - ELLLIST *gphlist; - GPHENTRY *pgphNode; - int hash; - - if (pgphPvt == NULL) return NULL; - paplist = pgphPvt->paplist; - hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0); - hash = epicsMemHash(name, len, hash) & pgphPvt->mask; - - epicsMutexMustLock(pgphPvt->lock); - gphlist = paplist[hash]; - if (gphlist == NULL) { - pgphNode = NULL; - } else { - pgphNode = (GPHENTRY *) ellFirst(gphlist); - } - - while (pgphNode) { - if (pvtid == pgphNode->pvtid && - strlen(pgphNode->name) == len && - strncmp(name, pgphNode->name, len) == 0) break; - pgphNode = (GPHENTRY *) ellNext((ELLNODE *)pgphNode); - } - - epicsMutexUnlock(pgphPvt->lock); - return pgphNode; -} - -GPHENTRY * epicsShareAPI gphFind(gphPvt *pgphPvt, const char *name, void *pvtid) -{ - return gphFindParse(pgphPvt, name, strlen(name), pvtid); -} - -GPHENTRY * epicsShareAPI gphAdd(gphPvt *pgphPvt, const char *name, void *pvtid) -{ - ELLLIST **paplist; - ELLLIST *plist; - GPHENTRY *pgphNode; - int hash; - - if (pgphPvt == NULL) return NULL; - paplist = pgphPvt->paplist; - hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0); - hash = epicsStrHash(name, hash) & pgphPvt->mask; - - epicsMutexMustLock(pgphPvt->lock); - plist = paplist[hash]; - if (plist == NULL) { - plist = calloc(1, sizeof(ELLLIST)); - if(!plist){ - epicsMutexUnlock(pgphPvt->lock); - return NULL; - } - ellInit(plist); - paplist[hash] = plist; - } - - pgphNode = (GPHENTRY *) ellFirst(plist); - while (pgphNode) { - if (pvtid == pgphNode->pvtid && - strcmp(name, pgphNode->name) == 0) { - epicsMutexUnlock(pgphPvt->lock); - return NULL; - } - pgphNode = (GPHENTRY *) ellNext((ELLNODE *)pgphNode); - } - - pgphNode = calloc(1, sizeof(GPHENTRY)); - if(pgphNode) { - pgphNode->name = name; - pgphNode->pvtid = pvtid; - ellAdd(plist, (ELLNODE *)pgphNode); - } - - epicsMutexUnlock(pgphPvt->lock); - return (pgphNode); -} - -void epicsShareAPI gphDelete(gphPvt *pgphPvt, const char *name, void *pvtid) -{ - ELLLIST **paplist; - ELLLIST *plist = NULL; - GPHENTRY *pgphNode; - int hash; - - if (pgphPvt == NULL) return; - paplist = pgphPvt->paplist; - hash = epicsMemHash((char *)&pvtid, sizeof(void *), 0); - hash = epicsStrHash(name, hash) & pgphPvt->mask; - - epicsMutexMustLock(pgphPvt->lock); - if (paplist[hash] == NULL) { - pgphNode = NULL; - } else { - plist = paplist[hash]; - pgphNode = (GPHENTRY *) ellFirst(plist); - } - - while(pgphNode) { - if (pvtid == pgphNode->pvtid && - strcmp(name, pgphNode->name) == 0) { - ellDelete(plist, (ELLNODE*)pgphNode); - free((void *)pgphNode); - break; - } - pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - } - - epicsMutexUnlock(pgphPvt->lock); - return; -} - -void epicsShareAPI gphFreeMem(gphPvt *pgphPvt) -{ - ELLLIST **paplist; - int h; - - /* Caller must ensure that no other thread is using *pvt */ - if (pgphPvt == NULL) return; - - paplist = pgphPvt->paplist; - for (h = 0; h < pgphPvt->size; h++) { - ELLLIST *plist = paplist[h]; - GPHENTRY *pgphNode; - GPHENTRY *next; - - if (plist == NULL) continue; - pgphNode = (GPHENTRY *) ellFirst(plist); - - while (pgphNode) { - next = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - ellDelete(plist, (ELLNODE*)pgphNode); - free(pgphNode); - pgphNode = next; - } - free(paplist[h]); - } - epicsMutexDestroy(pgphPvt->lock); - free(paplist); - free(pgphPvt); -} - -void epicsShareAPI gphDump(gphPvt *pgphPvt) -{ - gphDumpFP(stdout, pgphPvt); -} - -void epicsShareAPI gphDumpFP(FILE *fp, gphPvt *pgphPvt) -{ - unsigned int empty = 0; - ELLLIST **paplist; - int h; - - if (pgphPvt == NULL) - return; - - fprintf(fp, "Hash table has %d buckets", pgphPvt->size); - - paplist = pgphPvt->paplist; - for (h = 0; h < pgphPvt->size; h++) { - ELLLIST *plist = paplist[h]; - GPHENTRY *pgphNode; - int i = 0; - - if (plist == NULL) { - empty++; - continue; - } - pgphNode = (GPHENTRY *) ellFirst(plist); - - fprintf(fp, "\n [%3d] %3d ", h, ellCount(plist)); - while (pgphNode) { - if (!(++i % 3)) - fprintf(fp, "\n "); - fprintf(fp, " %s %p", pgphNode->name, pgphNode->pvtid); - pgphNode = (GPHENTRY *) ellNext((ELLNODE*)pgphNode); - } - } - fprintf(fp, "\n%u buckets empty.\n", empty); -} diff --git a/src/libCom/iocsh/Makefile b/src/libCom/iocsh/Makefile deleted file mode 100644 index 766577354..000000000 --- a/src/libCom/iocsh/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/iocsh -INC += iocsh.h -INC += registry.h -INC += libComRegister.h -Com_SRCS += iocsh.cpp -Com_SRCS += registry.c -Com_SRCS += libComRegister.c diff --git a/src/libCom/iocsh/iocsh.cpp b/src/libCom/iocsh/iocsh.cpp deleted file mode 100644 index d6626de89..000000000 --- a/src/libCom/iocsh/iocsh.cpp +++ /dev/null @@ -1,1097 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* iocsh.cpp */ -/* Author: Marty Kraimer Date: 27APR2000 */ -/* Heavily modified by Eric Norum Date: 03MAY2000 */ -/* Adapted to C++ by Eric Norum Date: 18DEC2000 */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "errlog.h" -#include "macLib.h" -#include "epicsStdio.h" -#include "epicsString.h" -#include "epicsStdlib.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "envDefs.h" -#include "registry.h" -#include "epicsReadline.h" -#include "cantProceed.h" -#include "iocsh.h" - -extern "C" { - -/* - * Global link to pdbbase - */ -epicsShareDef struct dbBase **iocshPpdbbase; - -/* - * File-local information - */ -struct iocshCommand { - iocshCmdDef def; - struct iocshCommand *next; -}; -static struct iocshCommand *iocshCommandHead; -static char iocshCmdID[] = "iocshCmd"; -struct iocshVariable { - iocshVarDef const *pVarDef; - struct iocshVariable *next; -}; -static struct iocshVariable *iocshVariableHead; -static char iocshVarID[] = "iocshVar"; -extern "C" { static void varCallFunc(const iocshArgBuf *); } -static epicsMutexId iocshTableMutex; -static epicsThreadOnceId iocshOnceId = EPICS_THREAD_ONCE_INIT; -static epicsThreadPrivateId iocshMacroHandleId; - -/* - * I/O redirection - */ -#define NREDIRECTS 5 -struct iocshRedirect { - const char *name; - const char *mode; - FILE *fp; - FILE *oldFp; - int mustRestore; -}; - -/* - * Set up module variables - */ -static void iocshOnce (void *) -{ - iocshTableMutex = epicsMutexMustCreate (); - iocshMacroHandleId = epicsThreadPrivateCreate(); -} - -static void iocshInit (void) -{ - epicsThreadOnce (&iocshOnceId, iocshOnce, NULL); -} - -/* - * Lock the table mutex - */ -static void -iocshTableLock (void) -{ - iocshInit(); - epicsMutexMustLock (iocshTableMutex); -} - -/* - * Unlock the table mutex - */ -static void -iocshTableUnlock (void) -{ - epicsMutexUnlock (iocshTableMutex); -} - -/* - * Register a command - */ -void epicsShareAPI iocshRegister (const iocshFuncDef *piocshFuncDef, - iocshCallFunc func) -{ - struct iocshCommand *l, *p, *n; - int i; - - iocshTableLock (); - for (l = NULL, p = iocshCommandHead ; p != NULL ; l = p, p = p->next) { - i = strcmp (piocshFuncDef->name, p->def.pFuncDef->name); - if (i == 0) { - p->def.pFuncDef = piocshFuncDef; - p->def.func = func; - iocshTableUnlock (); - return; - } - if (i < 0) - break; - } - n = (struct iocshCommand *) callocMustSucceed (1, sizeof *n, - "iocshRegister"); - if (!registryAdd(iocshCmdID, piocshFuncDef->name, (void *)n)) { - free (n); - iocshTableUnlock (); - errlogPrintf ("iocshRegister failed to add %s\n", piocshFuncDef->name); - return; - } - if (l == NULL) { - n->next = iocshCommandHead; - iocshCommandHead = n; - } - else { - n->next = l->next; - l->next = n; - } - n->def.pFuncDef = piocshFuncDef; - n->def.func = func; - iocshTableUnlock (); -} - - -/* - * Retrieves a previously registered function with the given name. - */ -const iocshCmdDef * epicsShareAPI iocshFindCommand(const char *name) -{ - return (iocshCmdDef *) registryFind(iocshCmdID, name); -} - -/* - * Register the "var" command and any variable(s) - */ -static const iocshArg varCmdArg0 = { "[variable", iocshArgString}; -static const iocshArg varCmdArg1 = { "[value]]", iocshArgString}; -static const iocshArg *varCmdArgs[2] = {&varCmdArg0, &varCmdArg1}; -static const iocshFuncDef varFuncDef = {"var", 2, varCmdArgs}; - -void epicsShareAPI iocshRegisterVariable (const iocshVarDef *piocshVarDef) -{ - struct iocshVariable *l, *p, *n; - int i; - int found; - - iocshTableLock (); - while ((piocshVarDef != NULL) - && (piocshVarDef->name != NULL) - && (*piocshVarDef->name != '\0')) { - if (iocshVariableHead == NULL) - iocshRegister(&varFuncDef,varCallFunc); - found = 0; - for (l = NULL, p = iocshVariableHead ; p != NULL ; l = p, p = p->next) { - i = strcmp (piocshVarDef->name, p->pVarDef->name); - if (i == 0) { - errlogPrintf("Warning: iocshRegisterVariable redefining %s.\n", - piocshVarDef->name); - p->pVarDef = piocshVarDef; - found = 1; - break; - } - if (i < 0) - break; - } - if (!found) { - n = (struct iocshVariable *) callocMustSucceed(1, sizeof *n, - "iocshRegisterVariable"); - if (!registryAdd(iocshVarID, piocshVarDef->name, (void *)n)) { - free(n); - iocshTableUnlock(); - errlogPrintf("iocshRegisterVariable failed to add %s.\n", - piocshVarDef->name); - return; - } - if (l == NULL) { - n->next = iocshVariableHead; - iocshVariableHead = n; - } - else { - n->next = l->next; - l->next = n; - } - n->pVarDef = piocshVarDef; - } - piocshVarDef++; - } - iocshTableUnlock (); -} - -/* - * Retrieves a previously registered variable with the given name. - */ -const iocshVarDef * epicsShareAPI iocshFindVariable(const char *name) -{ - struct iocshVariable *temp = (iocshVariable *) registryFind(iocshVarID, name); - return temp->pVarDef; -} - -/* - * Free storage created by iocshRegister/iocshRegisterVariable - */ -void epicsShareAPI iocshFree(void) -{ - struct iocshCommand *pc; - struct iocshVariable *pv; - - iocshTableLock (); - for (pc = iocshCommandHead ; pc != NULL ; ) { - struct iocshCommand * nc = pc->next; - free (pc); - pc = nc; - } - for (pv = iocshVariableHead ; pv != NULL ; ) { - struct iocshVariable *nv = pv->next; - free (pv); - pv = nv; - } - iocshCommandHead = NULL; - iocshVariableHead = NULL; - iocshTableUnlock (); -} - -/* - * Report an error - */ -static void -showError (const char *filename, int lineno, const char *msg, ...) -{ - va_list ap; - - va_start (ap, msg); - if (filename) - fprintf(epicsGetStderr(), "%s line %d: ", filename, lineno); - vfprintf (epicsGetStderr(), msg, ap); - fputc ('\n', epicsGetStderr()); - va_end (ap); -} - -static int -cvtArg (const char *filename, int lineno, char *arg, iocshArgBuf *argBuf, - const iocshArg *piocshArg) -{ - char *endp; - - switch (piocshArg->type) { - case iocshArgInt: - if (arg && *arg) { - errno = 0; - argBuf->ival = strtol (arg, &endp, 0); - if (errno == ERANGE) { - errno = 0; - argBuf->ival = strtoul (arg, &endp, 0); - if (errno == ERANGE) { - showError(filename, lineno, "Integer '%s' out of range", - arg); - return 0; - } - } - if (*endp) { - showError(filename, lineno, "Illegal integer '%s'", arg); - return 0; - } - } - else { - argBuf->ival = 0; - } - break; - - case iocshArgDouble: - if (arg && *arg) { - argBuf->dval = epicsStrtod (arg, &endp); - if (*endp) { - showError(filename, lineno, "Illegal double '%s'", arg); - return 0; - } - } - else { - argBuf->dval = 0.0; - } - break; - - case iocshArgString: - argBuf->sval = arg; - break; - - case iocshArgPersistentString: - argBuf->sval = (char *) malloc(strlen(arg) + 1); - if (argBuf->sval == NULL) { - showError(filename, lineno, "Out of memory"); - return 0; - } - strcpy(argBuf->sval, arg); - break; - - case iocshArgPdbbase: - /* Argument must be missing or 0 or pdbbase */ - if(!arg || !*arg || (*arg == '0') || (strcmp(arg, "pdbbase") == 0)) { - if(!iocshPpdbbase || !*iocshPpdbbase) { - showError(filename, lineno, "pdbbase not present"); - return 0; - } - argBuf->vval = *iocshPpdbbase; - break; - } - showError(filename, lineno, "Expecting 'pdbbase' got '%s'", arg); - return 0; - - default: - showError(filename, lineno, "Illegal argument type %d", - piocshArg->type); - return 0; - } - return 1; -} - -/* - * Open redirected I/O - */ -static int -openRedirect(const char *filename, int lineno, struct iocshRedirect *redirect) -{ - int i; - - for (i = 0 ; i < NREDIRECTS ; i++, redirect++) { - if (redirect->name != NULL) { - redirect->fp = fopen(redirect->name, redirect->mode); - if (redirect->fp == NULL) { - showError(filename, lineno, "Can't open \"%s\": %s.", - redirect->name, strerror(errno)); - redirect->name = NULL; - while (i--) { - redirect--; - if (redirect->fp) { - fclose(redirect->fp); - redirect->fp = NULL; - } - redirect->name = NULL; - } - return -1; - } - redirect->mustRestore = 0; - } - } - return 0; -} - -/* - * Start I/O redirection - */ -static void -startRedirect(const char * /*filename*/, int /*lineno*/, - struct iocshRedirect *redirect) -{ - int i; - - for (i = 0 ; i < NREDIRECTS ; i++, redirect++) { - if (redirect->fp != NULL) { - switch(i) { - case 0: - redirect->oldFp = epicsGetThreadStdin(); - epicsSetThreadStdin(redirect->fp); - redirect->mustRestore = 1; - break; - case 1: - redirect->oldFp = epicsGetThreadStdout(); - epicsSetThreadStdout(redirect->fp); - redirect->mustRestore = 1; - break; - case 2: - redirect->oldFp = epicsGetThreadStderr(); - epicsSetThreadStderr(redirect->fp); - redirect->mustRestore = 1; - break; - } - } - } -} - -/* - * Finish up I/O redirection - */ -static void -stopRedirect(const char *filename, int lineno, struct iocshRedirect *redirect) -{ - int i; - - for (i = 0 ; i < NREDIRECTS ; i++, redirect++) { - if (redirect->fp != NULL) { - if (fclose(redirect->fp) != 0) - showError(filename, lineno, "Error closing \"%s\": %s.", - redirect->name, strerror(errno)); - redirect->fp = NULL; - if (redirect->mustRestore) { - switch(i) { - case 0: epicsSetThreadStdin(redirect->oldFp); break; - case 1: epicsSetThreadStdout(redirect->oldFp); break; - case 2: epicsSetThreadStderr(redirect->oldFp); break; - } - } - } - redirect->name = NULL; - } -} - -/* - * "help" command - */ -static const iocshArg helpArg0 = { "[command ...]",iocshArgArgv}; -static const iocshArg *helpArgs[1] = {&helpArg0}; -static const iocshFuncDef helpFuncDef = - {"help",1,helpArgs}; -static void helpCallFunc(const iocshArgBuf *args) -{ - int argc = args[0].aval.ac; - const char * const * argv = args[0].aval.av; - struct iocshFuncDef const *piocshFuncDef; - struct iocshCommand *pcmd; - - if (argc == 1) { - int l, col = 0; - - fprintf(epicsGetStdout(), - "Type 'help ' to see the arguments of .\n"); - iocshTableLock (); - for (pcmd = iocshCommandHead ; pcmd != NULL ; pcmd = pcmd->next) { - piocshFuncDef = pcmd->def.pFuncDef; - l = strlen (piocshFuncDef->name); - if ((l + col) >= 79) { - fputc('\n', epicsGetStdout()); - col = 0; - } - fputs(piocshFuncDef->name, epicsGetStdout()); - col += l; - if (col >= 64) { - fputc('\n', epicsGetStdout()); - col = 0; - } - else { - do { - fputc(' ', epicsGetStdout()); - col++; - } while ((col % 16) != 0); - } - } - if (col) - fputc('\n', epicsGetStdout()); - iocshTableUnlock (); - } - else { - for (int iarg = 1 ; iarg < argc ; iarg++) { - for (pcmd = iocshCommandHead ; pcmd != NULL ; pcmd = pcmd->next) { - piocshFuncDef = pcmd->def.pFuncDef; - if (epicsStrGlobMatch(piocshFuncDef->name, argv[iarg]) != 0) { - fputs(piocshFuncDef->name, epicsGetStdout()); - for (int a = 0 ; a < piocshFuncDef->nargs ; a++) { - const char *cp = piocshFuncDef->arg[a]->name; - if ((piocshFuncDef->arg[a]->type == iocshArgArgv) - || (strchr (cp, ' ') == NULL)) { - fprintf(epicsGetStdout(), " %s", cp); - } - else { - fprintf(epicsGetStdout(), " '%s'", cp); - } - } - fprintf(epicsGetStdout(),"\n");; - } - } - } - } -} - -/* - * The body of the command interpreter - */ -static int -iocshBody (const char *pathname, const char *commandLine, const char *macros) -{ - FILE *fp = NULL; - const char *filename = NULL; - int icin, icout; - char c; - int quote, inword, backslash; - const char *raw = NULL;; - char *line = NULL; - int lineno = 0; - int argc; - char **argv = NULL; - int argvCapacity = 0; - struct iocshRedirect *redirects = NULL; - struct iocshRedirect *redirect = NULL; - int sep; - const char *prompt = NULL; - const char *ifs = " \t(),\r"; - iocshArgBuf *argBuf = NULL; - int argBufCapacity = 0; - struct iocshCommand *found; - void *readlineContext = NULL; - int wasOkToBlock; - static const char * pairs[] = {"", "environ", NULL, NULL}; - MAC_HANDLE *handle; - char ** defines = NULL; - - iocshInit(); - - /* - * See if command interpreter is interactive - */ - if (commandLine == NULL) { - if ((pathname == NULL) || (strcmp (pathname, "") == 0)) { - if ((prompt = envGetConfigParamPtr(&IOCSH_PS1)) == NULL) - prompt = "epics> "; - } - else { - fp = fopen (pathname, "r"); - if (fp == NULL) { - fprintf(epicsGetStderr(), "Can't open %s: %s\n", pathname, - strerror (errno)); - return -1; - } - if ((filename = strrchr (pathname, '/')) == NULL) - filename = pathname; - else - filename++; - prompt = NULL; - } - - /* - * Create a command-line input context - */ - if ((readlineContext = epicsReadlineBegin(fp)) == NULL) { - fprintf(epicsGetStderr(), "Can't allocate command-line object.\n"); - if (fp) - fclose(fp); - return -1; - } - } - - /* - * Set up redirection - */ - redirects = (struct iocshRedirect *)calloc(NREDIRECTS, sizeof *redirects); - if (redirects == NULL) { - fprintf(epicsGetStderr(), "Out of memory!\n"); - return -1; - } - - /* - * Parse macro definitions, this check occurs before creating the - * macro handle to simplify cleanup. - */ - - if (macros) { - if (macParseDefns(NULL, macros, &defines) < 0) { - free(redirects); - return -1; - } - } - - /* - * Check for existing macro context or construct a new one. - */ - handle = (MAC_HANDLE *) epicsThreadPrivateGet(iocshMacroHandleId); - - if (handle == NULL) { - if (macCreateHandle(&handle, pairs)) { - errlogMessage("iocsh: macCreateHandle failed."); - free(redirects); - return -1; - } - - epicsThreadPrivateSet(iocshMacroHandleId, (void *) handle); - } - - macPushScope(handle); - macInstallMacros(handle, defines); - - /* - * Read commands till EOF or exit - */ - argc = 0; - wasOkToBlock = epicsThreadIsOkToBlock(); - epicsThreadSetOkToBlock(1); - for (;;) { - /* - * Read a line - */ - if (commandLine) { - if (raw != NULL) - break; - raw = commandLine; - } - else { - if ((raw = epicsReadline(prompt, readlineContext)) == NULL) - break; - } - lineno++; - - /* - * Skip leading white-space - */ - icin = 0; - while ((c = raw[icin]) && isspace(c)) { - icin++; - } - - /* - * Ignore comment lines other than to echo - * them if they came from a script (disable echoing - * with '#-'). This avoids macLib errors from comments. - */ - if (c == '#') { - if ((prompt == NULL) && (commandLine == NULL)) - if (raw[icin + 1] != '-') - puts(raw); - continue; - } - - /* - * Expand macros - */ - free(line); - if ((line = macDefExpand(raw, handle)) == NULL) - continue; - - /* - * Skip leading white-space coming from a macro - */ - while ((c = line[icin]) && isspace(c)) { - icin++; - } - - /* - * Echo non-empty lines read from a script. - * Comments delineated with '#-' aren't echoed. - */ - if ((prompt == NULL) && *line && (commandLine == NULL)) - if ((c != '#') || (line[icin + 1] != '-')) - puts(line); - - /* - * Ignore lines that became a comment or empty after macro expansion - */ - if (!c || c == '#') - continue; - - /* - * Break line into words - */ - icout = 0; - inword = 0; - argc = 0; - quote = EOF; - backslash = 0; - redirect = NULL; - for (;;) { - if (argc >= argvCapacity) { - char **av; - argvCapacity += 50; - av = (char **)realloc (argv, argvCapacity * sizeof *argv); - if (av == NULL) { - fprintf (epicsGetStderr(), "Out of memory!\n"); - argc = -1; - break; - } - argv = av; - } - c = line[icin++]; - if (c == '\0') - break; - if ((quote == EOF) && !backslash && (strchr (ifs, c))) - sep = 1; - else - sep = 0; - if ((quote == EOF) && !backslash) { - int redirectFd = 1; - if (c == '\\') { - backslash = 1; - continue; - } - if (c == '<') { - if (redirect != NULL) { - break; - } - redirect = &redirects[0]; - sep = 1; - redirect->mode = "r"; - } - if ((c >= '1') && (c <= '9') && (line[icin] == '>')) { - redirectFd = c - '0'; - c = '>'; - icin++; - } - if (c == '>') { - if (redirect != NULL) - break; - if (redirectFd >= NREDIRECTS) { - redirect = &redirects[1]; - break; - } - redirect = &redirects[redirectFd]; - sep = 1; - if (line[icin] == '>') { - icin++; - redirect->mode = "a"; - } - else { - redirect->mode = "w"; - } - } - } - if (inword) { - if (c == quote) { - quote = EOF; - } - else { - if ((quote == EOF) && !backslash) { - if (sep) { - inword = 0; - line[icout++] = '\0'; - } - else if ((c == '"') || (c == '\'')) { - quote = c; - } - else { - line[icout++] = c; - } - } - else { - line[icout++] = c; - } - } - } - else { - if (!sep) { - if (((c == '"') || (c == '\'')) && !backslash) - quote = c; - if (redirect != NULL) { - if (redirect->name != NULL) { - argc = -1; - break; - } - redirect->name = line + icout; - redirect = NULL; - } - else { - argv[argc++] = line + icout; - } - if (quote == EOF) - line[icout++] = c; - inword = 1; - } - } - backslash = 0; - } - if (redirect != NULL) { - showError(filename, lineno, "Illegal redirection."); - continue; - } - if (argc < 0) - break; - if (quote != EOF) { - showError(filename, lineno, "Unbalanced quote."); - continue; - } - if (backslash) { - showError(filename, lineno, "Trailing backslash."); - continue; - } - if (inword) - line[icout++] = '\0'; - argv[argc] = NULL; - - /* - * Special case -- Redirected input but no command - * Treat as if 'iocsh filename'. - */ - if ((argc == 0) && (redirects[0].name != NULL)) { - const char *commandFile = redirects[0].name; - redirects[0].name = NULL; - if (openRedirect(filename, lineno, redirects) < 0) - continue; - startRedirect(filename, lineno, redirects); - iocshBody(commandFile, NULL, macros); - stopRedirect(filename, lineno, redirects); - continue; - } - - /* - * Special command? - */ - if ((argc > 0) && (strcmp(argv[0], "exit") == 0)) - break; - - /* - * Set up redirection - */ - if ((openRedirect(filename, lineno, redirects) == 0) && (argc > 0)) { - /* - * Look up command - */ - found = (iocshCommand *)registryFind (iocshCmdID, argv[0]); - if (found) { - /* - * Process arguments and call function - */ - struct iocshFuncDef const *piocshFuncDef = found->def.pFuncDef; - for (int iarg = 0 ; ; ) { - if (iarg == piocshFuncDef->nargs) { - startRedirect(filename, lineno, redirects); - (*found->def.func)(argBuf); - break; - } - if (iarg >= argBufCapacity) { - void *np; - - argBufCapacity += 20; - np = realloc (argBuf, argBufCapacity * sizeof *argBuf); - if (np == NULL) { - fprintf (epicsGetStderr(), "Out of memory!\n"); - argBufCapacity -= 20; - break; - } - argBuf = (iocshArgBuf *)np; - } - if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) { - argBuf[iarg].aval.ac = argc-iarg; - argBuf[iarg].aval.av = argv+iarg; - iarg = piocshFuncDef->nargs; - } - else { - if (!cvtArg (filename, lineno, - ((iarg < argc) ? argv[iarg+1] : NULL), - &argBuf[iarg], piocshFuncDef->arg[iarg])) - break; - iarg++; - } - } - if ((prompt != NULL) && (strcmp(argv[0], "epicsEnvSet") == 0)) { - const char *newPrompt; - if ((newPrompt = envGetConfigParamPtr(&IOCSH_PS1)) != NULL) - prompt = newPrompt; - } - } - else { - showError(filename, lineno, "Command %s not found.", argv[0]); - } - } - stopRedirect(filename, lineno, redirects); - } - macPopScope(handle); - - if (handle->level == 0) { - macDeleteHandle(handle); - epicsThreadPrivateSet(iocshMacroHandleId, NULL); - } - if (fp && (fp != stdin)) - fclose (fp); - if (redirects != NULL) { - stopRedirect(filename, lineno, redirects); - free (redirects); - } - free(line); - free (argv); - free (argBuf); - errlogFlush(); - if (readlineContext) - epicsReadlineEnd(readlineContext); - epicsThreadSetOkToBlock( wasOkToBlock); - return 0; -} - -/* - * External access to the command interpreter - */ -int epicsShareAPI -iocsh (const char *pathname) -{ - return iocshLoad(pathname, NULL); -} - -int epicsShareAPI -iocshCmd (const char *cmd) -{ - return iocshRun(cmd, NULL); -} - -int epicsShareAPI -iocshLoad(const char *pathname, const char *macros) -{ - if (pathname) - epicsEnvSet("IOCSH_STARTUP_SCRIPT", pathname); - return iocshBody(pathname, NULL, macros); -} - -int epicsShareAPI -iocshRun(const char *cmd, const char *macros) -{ - if (cmd == NULL) - return 0; - return iocshBody(NULL, cmd, macros); -} - -/* - * Needed to work around the necessary limitations of macLib and - * environment variables. In every other case of macro expansion - * it is the expected outcome that defined macros override any - * environment variables. - * - * iocshLoad/Run turn this on its head as it is very likely that - * an epicsEnvSet command may be run within the context of their - * calls. Thus, it would be expected that the new value would be - * returned in any future macro expansion. - * - * To do so, the epicsEnvSet command needs to be able to access - * and update the shared MAC_HANDLE that the iocsh uses. Which is - * what this function is provided for. - */ -void epicsShareAPI -iocshEnvClear(const char *name) -{ - MAC_HANDLE *handle; - - if (iocshMacroHandleId) { - handle = (MAC_HANDLE *) epicsThreadPrivateGet(iocshMacroHandleId); - - if (handle != NULL) { - macPutValue(handle, name, NULL); - } - } -} - -/* - * Internal commands - */ -static void varHandler(const iocshVarDef *v, const char *setString) -{ - switch(v->type) { - default: - fprintf(epicsGetStderr(), "Can't handle variable %s of type %d.\n", - v->name, v->type); - return; - case iocshArgInt: break; - case iocshArgDouble: break; - } - if(setString == NULL) { - switch(v->type) { - default: break; - case iocshArgInt: - fprintf(epicsGetStdout(), "%s = %d\n", v->name, *(int *)v->pval); - break; - case iocshArgDouble: - fprintf(epicsGetStdout(), "%s = %g\n", v->name, *(double *)v->pval); - break; - } - } - else { - switch(v->type) { - default: break; - case iocshArgInt: - { - char *endp; - long ltmp = strtol(setString, &endp, 0); - if((*setString != '\0') && (*endp == '\0')) - *(int *)v->pval = ltmp; - else - fprintf(epicsGetStderr(), - "Invalid integer value. Var %s not changed.\n", v->name); - break; - } - case iocshArgDouble: - { - char *endp; - double dtmp = epicsStrtod(setString, &endp); - if((*setString != '\0') && (*endp == '\0')) - *(double *)v->pval = dtmp; - else - fprintf(epicsGetStderr(), - "Invalid double value. Var %s not changed.\n", v->name); - break; - } - } - } -} - -static void varCallFunc(const iocshArgBuf *args) -{ - struct iocshVariable *v; - if(args[0].sval == NULL) { - for (v = iocshVariableHead ; v != NULL ; v = v->next) - varHandler(v->pVarDef, args[1].sval); - } - else { - v = (iocshVariable *)registryFind(iocshVarID, args[0].sval); - if (v == NULL) { - fprintf(epicsGetStderr(), "Var %s not found.\n", args[0].sval); - } - else { - varHandler(v->pVarDef, args[1].sval); - } - } -} - -/* iocshCmd */ -static const iocshArg iocshCmdArg0 = { "command",iocshArgString}; -static const iocshArg *iocshCmdArgs[1] = {&iocshCmdArg0}; -static const iocshFuncDef iocshCmdFuncDef = {"iocshCmd",1,iocshCmdArgs}; -static void iocshCmdCallFunc(const iocshArgBuf *args) -{ - iocshCmd(args[0].sval); -} - -/* iocshLoad */ -static const iocshArg iocshLoadArg0 = { "pathname",iocshArgString}; -static const iocshArg iocshLoadArg1 = { "macros", iocshArgString}; -static const iocshArg *iocshLoadArgs[2] = {&iocshLoadArg0, &iocshLoadArg1}; -static const iocshFuncDef iocshLoadFuncDef = {"iocshLoad",2,iocshLoadArgs}; -static void iocshLoadCallFunc(const iocshArgBuf *args) -{ - iocshLoad(args[0].sval, args[1].sval); -} - -/* iocshRun */ -static const iocshArg iocshRunArg0 = { "command",iocshArgString}; -static const iocshArg iocshRunArg1 = { "macros", iocshArgString}; -static const iocshArg *iocshRunArgs[2] = {&iocshRunArg0, &iocshRunArg1}; -static const iocshFuncDef iocshRunFuncDef = {"iocshRun",2,iocshRunArgs}; -static void iocshRunCallFunc(const iocshArgBuf *args) -{ - iocshRun(args[0].sval, args[1].sval); -} - -/* - * Dummy internal commands -- register and install in command table - * so they show up in the help display - */ - -/* comment */ -static const iocshArg commentArg0 = { "newline-terminated comment", - iocshArgArgv}; -static const iocshArg *commentArgs[1] = {&commentArg0}; -static const iocshFuncDef commentFuncDef = {"#",1,commentArgs}; -static void commentCallFunc(const iocshArgBuf *) -{ -} - -/* exit */ -static const iocshFuncDef exitFuncDef = - {"exit",0,0}; -static void exitCallFunc(const iocshArgBuf *) -{ -} - -static void localRegister (void) -{ - iocshRegister(&commentFuncDef,commentCallFunc); - iocshRegister(&exitFuncDef,exitCallFunc); - iocshRegister(&helpFuncDef,helpCallFunc); - iocshRegister(&iocshCmdFuncDef,iocshCmdCallFunc); - iocshRegister(&iocshLoadFuncDef,iocshLoadCallFunc); - iocshRegister(&iocshRunFuncDef,iocshRunCallFunc); -} - -} /* extern "C" */ - -/* - * Register local commands on application startup - */ -class IocshRegister { - public: - IocshRegister() { localRegister(); } -}; -static IocshRegister iocshRegisterObj; diff --git a/src/libCom/iocsh/iocsh.h b/src/libCom/iocsh/iocsh.h deleted file mode 100644 index 3ef3d952b..000000000 --- a/src/libCom/iocsh/iocsh.h +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* iocsh.h ioc: call registered function*/ -/* Author: Marty Kraimer Date: 27APR2000 */ - -#ifndef INCiocshH -#define INCiocshH - -#include -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - iocshArgInt, - iocshArgDouble, - iocshArgString, - iocshArgPdbbase, - iocshArgArgv, - iocshArgPersistentString -}iocshArgType; - -typedef union iocshArgBuf { - int ival; - double dval; - char *sval; - void *vval; - struct { - int ac; - char **av; - } aval; -}iocshArgBuf; - -typedef struct iocshVarDef { - const char *name; - iocshArgType type; - void * pval; -}iocshVarDef; - -typedef struct iocshArg { - const char *name; - iocshArgType type; -}iocshArg; - -typedef struct iocshFuncDef { - const char *name; - int nargs; - const iocshArg * const *arg; -}iocshFuncDef; - -typedef void (*iocshCallFunc)(const iocshArgBuf *argBuf); - -typedef struct iocshCmdDef { - iocshFuncDef const *pFuncDef; - iocshCallFunc func; -}iocshCmdDef; - -epicsShareFunc void epicsShareAPI iocshRegister( - const iocshFuncDef *piocshFuncDef, iocshCallFunc func); -epicsShareFunc void epicsShareAPI iocshRegisterVariable ( - const iocshVarDef *piocshVarDef); -epicsShareFunc const iocshCmdDef * epicsShareAPI iocshFindCommand( - const char* name); -epicsShareFunc const iocshVarDef * epicsShareAPI iocshFindVariable( - const char* name); - -/* iocshFree frees storage used by iocshRegister*/ -/* This should only be called when iocsh is no longer needed*/ -epicsShareFunc void epicsShareAPI iocshFree(void); - -epicsShareFunc int epicsShareAPI iocsh(const char *pathname); -epicsShareFunc int epicsShareAPI iocshCmd(const char *cmd); -epicsShareFunc int epicsShareAPI iocshLoad(const char *pathname, const char* macros); -epicsShareFunc int epicsShareAPI iocshRun(const char *cmd, const char* macros); - -/* Makes macros that shadow environment variables work correctly with epicsEnvSet */ -epicsShareFunc void epicsShareAPI iocshEnvClear(const char *name); - -/* 'weak' link to pdbbase */ -epicsShareExtern struct dbBase **iocshPpdbbase; - -#ifdef __cplusplus -} -#endif - -#endif /*INCiocshH*/ diff --git a/src/libCom/iocsh/libComRegister.c b/src/libCom/iocsh/libComRegister.c deleted file mode 100644 index d3a5cfac4..000000000 --- a/src/libCom/iocsh/libComRegister.c +++ /dev/null @@ -1,393 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "iocsh.h" -#include "epicsStdioRedirect.h" -#include "epicsString.h" -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "envDefs.h" -#include "osiUnistd.h" -#include "logClient.h" -#include "errlog.h" -#include "taskwd.h" -#include "registry.h" -#include "epicsGeneralTime.h" -#include "libComRegister.h" - - -void date(const char *format) -{ - epicsTimeStamp now; - char nowText[80] = {'\0'}; - - if (epicsTimeGetCurrent(&now)) { - puts("Current time not available."); - return; - } - if (format == NULL || format[0] == '\0') - format = "%Y/%m/%d %H:%M:%S.%06f"; - epicsTimeToStrftime(nowText, sizeof(nowText), format, &now); - puts(nowText); -} - -/* date */ -static const iocshArg dateArg0 = { "format",iocshArgString}; -static const iocshArg * const dateArgs[] = {&dateArg0}; -static const iocshFuncDef dateFuncDef = {"date", 1, dateArgs}; -static void dateCallFunc (const iocshArgBuf *args) -{ - date(args[0].sval); -} - -/* echo */ -static const iocshArg echoArg0 = { "string",iocshArgString}; -static const iocshArg * const echoArgs[1] = {&echoArg0}; -static const iocshFuncDef echoFuncDef = {"echo",1,echoArgs}; -static void echoCallFunc(const iocshArgBuf *args) -{ - char *str = args[0].sval; - - if (str) - dbTranslateEscape(str, str); /* in-place is safe */ - else - str = ""; - printf("%s\n", str); -} - -/* chdir */ -static const iocshArg chdirArg0 = { "directory name",iocshArgString}; -static const iocshArg * const chdirArgs[1] = {&chdirArg0}; -static const iocshFuncDef chdirFuncDef = {"cd",1,chdirArgs}; -static void chdirCallFunc(const iocshArgBuf *args) -{ - if (args[0].sval == NULL || - chdir(args[0].sval)) { - fprintf(stderr, "Invalid directory path, ignored\n"); - } -} - -/* print current working directory */ -static const iocshFuncDef pwdFuncDef = { "pwd", 0, 0 }; -static void pwdCallFunc (const iocshArgBuf *args) -{ - char buf[256]; - char *pwd = getcwd ( buf, sizeof(buf) - 1 ); - if ( pwd ) { - printf ( "%s\n", pwd ); - } -} - -/* epicsEnvSet */ -static const iocshArg epicsEnvSetArg0 = { "name",iocshArgString}; -static const iocshArg epicsEnvSetArg1 = { "value",iocshArgString}; -static const iocshArg * const epicsEnvSetArgs[2] = {&epicsEnvSetArg0,&epicsEnvSetArg1}; -static const iocshFuncDef epicsEnvSetFuncDef = {"epicsEnvSet",2,epicsEnvSetArgs}; -static void epicsEnvSetCallFunc(const iocshArgBuf *args) -{ - char *name = args[0].sval; - char *value = args[1].sval; - - if (name == NULL) { - fprintf(stderr, "Missing environment variable name argument.\n"); - return; - } - if (value == NULL) { - fprintf(stderr, "Missing environment variable value argument.\n"); - return; - } - epicsEnvSet (name, value); -} - -/* epicsParamShow */ -static const iocshFuncDef epicsParamShowFuncDef = {"epicsParamShow",0,NULL}; -static void epicsParamShowCallFunc(const iocshArgBuf *args) -{ - epicsPrtEnvParams (); -} - -/* epicsPrtEnvParams */ -static const iocshFuncDef epicsPrtEnvParamsFuncDef = {"epicsPrtEnvParams",0,0}; -static void epicsPrtEnvParamsCallFunc(const iocshArgBuf *args) -{ - epicsPrtEnvParams (); -} - -/* epicsEnvShow */ -static const iocshArg epicsEnvShowArg0 = { "[name]",iocshArgString}; -static const iocshArg * const epicsEnvShowArgs[1] = {&epicsEnvShowArg0}; -static const iocshFuncDef epicsEnvShowFuncDef = {"epicsEnvShow",1,epicsEnvShowArgs}; -static void epicsEnvShowCallFunc(const iocshArgBuf *args) -{ - epicsEnvShow (args[0].sval); -} - -/* registryDump */ -static const iocshFuncDef registryDumpFuncDef = {"registryDump",0,NULL}; -static void registryDumpCallFunc(const iocshArgBuf *args) -{ - registryDump (); -} - -/* iocLogInit */ -static const iocshFuncDef iocLogInitFuncDef = {"iocLogInit",0}; -static void iocLogInitCallFunc(const iocshArgBuf *args) -{ - iocLogInit (); -} - -/* iocLogDisable */ -static const iocshArg iocLogDisableArg0 = {"(0,1)=>(false,true)",iocshArgInt}; -static const iocshArg * const iocLogDisableArgs[1] = {&iocLogDisableArg0}; -static const iocshFuncDef iocLogDisableFuncDef = {"setIocLogDisable",1,iocLogDisableArgs}; -static void iocLogDisableCallFunc(const iocshArgBuf *args) -{ - iocLogDisable = args[0].ival; -} - -/* iocLogShow */ -static const iocshArg iocLogShowArg0 = {"level",iocshArgInt}; -static const iocshArg * const iocLogShowArgs[1] = {&iocLogShowArg0}; -static const iocshFuncDef iocLogShowFuncDef = {"iocLogShow",1,iocLogShowArgs}; -static void iocLogShowCallFunc(const iocshArgBuf *args) -{ - iocLogShow (args[0].ival); -} - -/* eltc */ -static const iocshArg eltcArg0 = {"(0,1)=>(false,true)",iocshArgInt}; -static const iocshArg * const eltcArgs[1] = {&eltcArg0}; -static const iocshFuncDef eltcFuncDef = {"eltc",1,eltcArgs}; -static void eltcCallFunc(const iocshArgBuf *args) -{ - eltc(args[0].ival); -} - -/* errlogInit */ -static const iocshArg errlogInitArg0 = { "bufsize",iocshArgInt}; -static const iocshArg * const errlogInitArgs[1] = {&errlogInitArg0}; -static const iocshFuncDef errlogInitFuncDef = - {"errlogInit",1,errlogInitArgs}; -static void errlogInitCallFunc(const iocshArgBuf *args) -{ - errlogInit(args[0].ival); -} - -/* errlogInit2 */ -static const iocshArg errlogInit2Arg0 = { "bufSize",iocshArgInt}; -static const iocshArg errlogInit2Arg1 = { "maxMsgSize",iocshArgInt}; -static const iocshArg * const errlogInit2Args[] = - {&errlogInit2Arg0, &errlogInit2Arg1}; -static const iocshFuncDef errlogInit2FuncDef = - {"errlogInit2", 2, errlogInit2Args}; -static void errlogInit2CallFunc(const iocshArgBuf *args) -{ - errlogInit2(args[0].ival, args[1].ival); -} - -/* errlog */ -static const iocshArg errlogArg0 = { "message",iocshArgString}; -static const iocshArg * const errlogArgs[1] = {&errlogArg0}; -static const iocshFuncDef errlogFuncDef = {"errlog",1,errlogArgs}; -static void errlogCallFunc(const iocshArgBuf *args) -{ - errlogPrintfNoConsole("%s\n", args[0].sval); -} - -/* iocLogPrefix */ -static const iocshArg iocLogPrefixArg0 = { "prefix",iocshArgString}; -static const iocshArg * const iocLogPrefixArgs[1] = {&iocLogPrefixArg0}; -static const iocshFuncDef iocLogPrefixFuncDef = {"iocLogPrefix",1,iocLogPrefixArgs}; -static void iocLogPrefixCallFunc(const iocshArgBuf *args) -{ - iocLogPrefix(args[0].sval); -} - -/* epicsThreadShowAll */ -static const iocshArg epicsThreadShowAllArg0 = { "level",iocshArgInt}; -static const iocshArg * const epicsThreadShowAllArgs[1] = {&epicsThreadShowAllArg0}; -static const iocshFuncDef epicsThreadShowAllFuncDef = - {"epicsThreadShowAll",1,epicsThreadShowAllArgs}; -static void epicsThreadShowAllCallFunc(const iocshArgBuf *args) -{ - epicsThreadShowAll(args[0].ival); -} - -/* epicsThreadShow */ -static const iocshArg threadArg0 = { "[-level] [thread ...]", iocshArgArgv}; -static const iocshArg * const threadArgs[1] = { &threadArg0 }; -static const iocshFuncDef threadFuncDef = {"epicsThreadShow",1,threadArgs}; -static void threadCallFunc(const iocshArgBuf *args) -{ - int i = 1; - int first = 1; - int level = 0; - const char *cp; - epicsThreadId tid; - unsigned long ltmp; - int argc = args[0].aval.ac; - char **argv = args[0].aval.av; - char *endp; - - if ((i < argc) && (*(cp = argv[i]) == '-')) { - level = atoi (cp + 1); - i++; - } - if (i >= argc) { - epicsThreadShowAll (level); - return; - } - for ( ; i < argc ; i++) { - cp = argv[i]; - ltmp = strtoul (cp, &endp, 0); - if (*endp) { - tid = epicsThreadGetId (cp); - if (!tid) { - fprintf(stderr, "\t'%s' is not a known thread name\n", cp); - continue; - } - } - else { - tid = (epicsThreadId)ltmp; - } - if (first) { - epicsThreadShow (0, level); - first = 0; - } - epicsThreadShow (tid, level); - } -} - -/* taskwdShow */ -static const iocshArg taskwdShowArg0 = { "level",iocshArgInt}; -static const iocshArg * const taskwdShowArgs[1] = {&taskwdShowArg0}; -static const iocshFuncDef taskwdShowFuncDef = - {"taskwdShow",1,taskwdShowArgs}; -static void taskwdShowCallFunc(const iocshArgBuf *args) -{ - taskwdShow(args[0].ival); -} - -/* epicsMutexShowAll */ -static const iocshArg epicsMutexShowAllArg0 = { "onlyLocked",iocshArgInt}; -static const iocshArg epicsMutexShowAllArg1 = { "level",iocshArgInt}; -static const iocshArg * const epicsMutexShowAllArgs[2] = - {&epicsMutexShowAllArg0,&epicsMutexShowAllArg1}; -static const iocshFuncDef epicsMutexShowAllFuncDef = - {"epicsMutexShowAll",1,epicsMutexShowAllArgs}; -static void epicsMutexShowAllCallFunc(const iocshArgBuf *args) -{ - epicsMutexShowAll(args[0].ival,args[1].ival); -} - -/* epicsThreadSleep */ -static const iocshArg epicsThreadSleepArg0 = { "seconds",iocshArgDouble}; -static const iocshArg * const epicsThreadSleepArgs[1] = {&epicsThreadSleepArg0}; -static const iocshFuncDef epicsThreadSleepFuncDef = - {"epicsThreadSleep",1,epicsThreadSleepArgs}; -static void epicsThreadSleepCallFunc(const iocshArgBuf *args) -{ - epicsThreadSleep(args[0].dval); -} - -/* epicsThreadResume */ -static const iocshArg epicsThreadResumeArg0 = { "[thread ...]", iocshArgArgv}; -static const iocshArg * const epicsThreadResumeArgs[1] = { &epicsThreadResumeArg0 }; -static const iocshFuncDef epicsThreadResumeFuncDef = {"epicsThreadResume",1,epicsThreadResumeArgs}; -static void epicsThreadResumeCallFunc(const iocshArgBuf *args) -{ - int i; - const char *cp; - epicsThreadId tid; - unsigned long ltmp; - char nameBuf[64]; - int argc = args[0].aval.ac; - char **argv = args[0].aval.av; - char *endp; - - for (i = 1 ; i < argc ; i++) { - cp = argv[i]; - ltmp = strtoul(cp, &endp, 0); - if (*endp) { - tid = epicsThreadGetId(cp); - if (!tid) { - fprintf(stderr, "'%s' is not a valid thread name\n", cp); - continue; - } - } - else { - tid =(epicsThreadId)ltmp; - epicsThreadGetName(tid, nameBuf, sizeof nameBuf); - if (nameBuf[0] == '\0') { - fprintf(stderr, "'%s' is not a valid thread id\n", cp); - continue; - } - - } - if (!epicsThreadIsSuspended(tid)) { - fprintf(stderr, "Thread %s is not suspended\n", cp); - continue; - } - epicsThreadResume(tid); - } -} - -/* generalTimeReport */ -static const iocshArg generalTimeReportArg0 = { "interest_level", iocshArgArgv}; -static const iocshArg * const generalTimeReportArgs[1] = { &generalTimeReportArg0 }; -static const iocshFuncDef generalTimeReportFuncDef = {"generalTimeReport",1,generalTimeReportArgs}; -static void generalTimeReportCallFunc(const iocshArgBuf *args) -{ - generalTimeReport(args[0].ival); -} - -/* installLastResortEventProvider */ -static const iocshFuncDef installLastResortEventProviderFuncDef = {"installLastResortEventProvider", 0, NULL}; -static void installLastResortEventProviderCallFunc(const iocshArgBuf *args) -{ - installLastResortEventProvider(); -} - -void epicsShareAPI libComRegister(void) -{ - iocshRegister(&dateFuncDef, dateCallFunc); - iocshRegister(&echoFuncDef, echoCallFunc); - iocshRegister(&chdirFuncDef, chdirCallFunc); - iocshRegister(&pwdFuncDef, pwdCallFunc); - - iocshRegister(&epicsEnvSetFuncDef, epicsEnvSetCallFunc); - iocshRegister(&epicsParamShowFuncDef, epicsParamShowCallFunc); - iocshRegister(&epicsPrtEnvParamsFuncDef, epicsPrtEnvParamsCallFunc); - iocshRegister(&epicsEnvShowFuncDef, epicsEnvShowCallFunc); - iocshRegister(®istryDumpFuncDef, registryDumpCallFunc); - - iocshRegister(&iocLogInitFuncDef, iocLogInitCallFunc); - iocshRegister(&iocLogDisableFuncDef, iocLogDisableCallFunc); - iocshRegister(&iocLogShowFuncDef, iocLogShowCallFunc); - iocshRegister(&eltcFuncDef, eltcCallFunc); - iocshRegister(&errlogInitFuncDef,errlogInitCallFunc); - iocshRegister(&errlogInit2FuncDef,errlogInit2CallFunc); - iocshRegister(&errlogFuncDef, errlogCallFunc); - iocshRegister(&iocLogPrefixFuncDef, iocLogPrefixCallFunc); - - iocshRegister(&epicsThreadShowAllFuncDef,epicsThreadShowAllCallFunc); - iocshRegister(&threadFuncDef, threadCallFunc); - iocshRegister(&taskwdShowFuncDef,taskwdShowCallFunc); - iocshRegister(&epicsMutexShowAllFuncDef,epicsMutexShowAllCallFunc); - iocshRegister(&epicsThreadSleepFuncDef,epicsThreadSleepCallFunc); - iocshRegister(&epicsThreadResumeFuncDef,epicsThreadResumeCallFunc); - - iocshRegister(&generalTimeReportFuncDef,generalTimeReportCallFunc); - iocshRegister(&installLastResortEventProviderFuncDef, installLastResortEventProviderCallFunc); -} diff --git a/src/libCom/iocsh/libComRegister.h b/src/libCom/iocsh/libComRegister.h deleted file mode 100644 index ef93f4a8d..000000000 --- a/src/libCom/iocsh/libComRegister.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_libComRegister_H -#define INC_libComRegister_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void epicsShareAPI libComRegister(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_libComRegister_H */ diff --git a/src/libCom/iocsh/registry.c b/src/libCom/iocsh/registry.c deleted file mode 100644 index 0b2e312e3..000000000 --- a/src/libCom/iocsh/registry.c +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*registry.c */ - -/* Author: Marty Kraimer Date: 08JUN99 */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "cantProceed.h" -#include "epicsFindSymbol.h" -#include "gpHash.h" -#include "registry.h" - -static struct gphPvt *gphPvt = 0; - -static void registryInit(int tableSize) -{ - if(tableSize==0) tableSize = DEFAULT_TABLE_SIZE; - gphInitPvt(&gphPvt,tableSize); - if(!gphPvt) cantProceed("registry why did gphInitPvt fail\n"); -} - -epicsShareFunc int epicsShareAPI registrySetTableSize(int size) -{ - if(gphPvt) { - printf("registryInit already called\n"); - return(-1); - } - registryInit(size); - return(0); -} - - -epicsShareFunc int epicsShareAPI registryAdd( - void *registryID,const char *name,void *data) -{ - GPHENTRY *pentry; - if(!gphPvt) registryInit(0); - pentry = gphAdd(gphPvt,name,registryID); - if(!pentry) return(FALSE); - pentry->userPvt = data; - return(TRUE); -} - -epicsShareFunc int epicsShareAPI registryChange( - void *registryID,const char *name,void *data) -{ - GPHENTRY *pentry; - if(!gphPvt) registryInit(0); - pentry = gphFind(gphPvt,(char *)name,registryID); - if(!pentry) return(FALSE); - pentry->userPvt = data; - return(TRUE); -} - -epicsShareFunc void * epicsShareAPI registryFind( - void *registryID,const char *name) -{ - GPHENTRY *pentry; - if(name==0) return(0); - if(registryID==0) return(epicsFindSymbol(name)); - if(!gphPvt) registryInit(0); - pentry = gphFind(gphPvt,(char *)name,registryID); - if(!pentry) return(0); - return(pentry->userPvt); -} - -epicsShareFunc void epicsShareAPI registryFree(void) -{ - if(!gphPvt) return; - gphFreeMem(gphPvt); - gphPvt = 0; -} - -epicsShareFunc int epicsShareAPI registryDump(void) -{ - if(!gphPvt) return(0); - gphDump(gphPvt); - return(0); -} diff --git a/src/libCom/iocsh/registry.h b/src/libCom/iocsh/registry.h deleted file mode 100644 index ea1bb7ce7..000000000 --- a/src/libCom/iocsh/registry.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INCregistryh -#define INCregistryh - -#include "shareLib.h" -#ifdef __cplusplus -extern "C" { -#endif - -#define DEFAULT_TABLE_SIZE 1024 - -epicsShareFunc int epicsShareAPI registryAdd( - void *registryID,const char *name,void *data); -epicsShareFunc void *epicsShareAPI registryFind( - void *registryID,const char *name); -epicsShareFunc int epicsShareAPI registryChange( - void *registryID,const char *name,void *data); - -epicsShareFunc int epicsShareAPI registrySetTableSize(int size); -epicsShareFunc void epicsShareAPI registryFree(void); -epicsShareFunc int epicsShareAPI registryDump(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INCregistryh */ diff --git a/src/libCom/log/Makefile b/src/libCom/log/Makefile deleted file mode 100644 index 7d7a6b620..000000000 --- a/src/libCom/log/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/log -INC += iocLog.h -INC += logClient.h -Com_SRCS += iocLog.c -Com_SRCS += logClient.c - -PROD_HOST += iocLogServer - -iocLogServer_SRCS = iocLogServer.c -iocLogServer_LIBS = Com - -iocLogServer_SYS_LIBS_solaris += socket -iocLogServer_SYS_LIBS_WIN32 += user32 ws2_32 - -SCRIPTS_HOST = S99logServer - -EXPAND += S99logServer@ -EXPAND_VARS = INSTALL_BIN=$(abspath $(INSTALL_BIN)) - diff --git a/src/libCom/log/S99logServer@ b/src/libCom/log/S99logServer@ deleted file mode 100644 index 294b2ec01..000000000 --- a/src/libCom/log/S99logServer@ +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh -# -# System-V init script for the EPICS IOC Log Server. -# - -INSTALL_BIN=@INSTALL_BIN@ - -# To change the default values for the EPICS Environment parameters, -# uncomment and modify the relevant lines below. - -# EPICS_IOC_LOG_PORT="6500" export EPICS_IOC_LOG_PORT -# EPICS_IOC_LOG_FILE_NAME="/path/to/iocLog" export EPICS_IOC_LOG_FILE_NAME -# EPICS_IOC_LOG_FILE_LIMIT="1000000" export EPICS_IOC_LOG_FILE_LIMIT - -if [ $1 = "start" ]; then - if [ -x $INSTALL_BIN/iocLogServer ]; then - echo "Starting EPICS Log Server " - $INSTALL_BIN/iocLogServer & - fi -else - if [ $1 = "stop" ]; then - pid=`ps -e | sed -ne '/iocLogSe/s/^ *\([1-9][0-9]*\).*$/\1/p'` - if [ "${pid}" != "" ]; then - echo "Stopping EPICS Log Server " - kill ${pid} - fi - fi -fi - diff --git a/src/libCom/log/iocLog.c b/src/libCom/log/iocLog.c deleted file mode 100644 index e62da2050..000000000 --- a/src/libCom/log/iocLog.c +++ /dev/null @@ -1,137 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* logClient.c,v 1.25.2.6 2004/10/07 13:37:34 mrk Exp */ -/* - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "envDefs.h" -#include "logClient.h" -#include "iocLog.h" - -int iocLogDisable = 0; - -static const int iocLogSuccess = 0; -static const int iocLogError = -1; - -static logClientId iocLogClient; - -/* - * getConfig() - * Get Server Configuration - */ -static int getConfig (struct in_addr *pserver_addr, unsigned short *pserver_port) -{ - long status; - long epics_port; - - status = envGetLongConfigParam (&EPICS_IOC_LOG_PORT, &epics_port); - if (status<0) { - fprintf (stderr, - "iocLog: EPICS environment variable \"%s\" undefined\n", - EPICS_IOC_LOG_PORT.name); - return iocLogError; - } - - if (epics_port<0 || epics_port>USHRT_MAX) { - fprintf (stderr, - "iocLog: EPICS environment variable \"%s\" out of range\n", - EPICS_IOC_LOG_PORT.name); - return iocLogError; - } - *pserver_port = (unsigned short) epics_port; - - status = envGetInetAddrConfigParam (&EPICS_IOC_LOG_INET, pserver_addr); - if (status<0) { - fprintf (stderr, - "iocLog: EPICS environment variable \"%s\" undefined\n", - EPICS_IOC_LOG_INET.name); - return iocLogError; - } - - return iocLogSuccess; -} - -/* - * iocLogFlush () - */ -void epicsShareAPI epicsShareAPI iocLogFlush (void) -{ - if (iocLogClient!=NULL) { - logClientFlush (iocLogClient); - } -} - -/* - * iocLogClientInit() - */ -static logClientId iocLogClientInit (void) -{ - int status; - logClientId id; - struct in_addr addr; - unsigned short port; - - status = getConfig (&addr, &port); - if (status) { - return NULL; - } - id = logClientCreate (addr, port); - return id; -} - -/* - * iocLogInit() - */ -int epicsShareAPI iocLogInit (void) -{ - /* - * check for global disable - */ - if (iocLogDisable) { - return iocLogSuccess; - } - /* - * dont init twice - */ - if (iocLogClient!=NULL) { - return iocLogSuccess; - } - iocLogClient = iocLogClientInit (); - if (iocLogClient) { - return iocLogSuccess; - } - else { - return iocLogError; - } -} - -/* - * iocLogShow () - */ -void epicsShareAPI iocLogShow (unsigned level) -{ - if (iocLogClient!=NULL) { - logClientShow (iocLogClient, level); - } -} - -/* - * logClientInit(); deprecated - */ -logClientId epicsShareAPI logClientInit (void) -{ - return iocLogClientInit (); -} diff --git a/src/libCom/log/iocLog.h b/src/libCom/log/iocLog.h deleted file mode 100644 index b6f7ddf6e..000000000 --- a/src/libCom/log/iocLog.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* logClient.h,v 1.5.2.1 2003/07/08 00:08:06 jhill Exp */ -/* - * - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -#ifndef INCiocLogh -#define INCiocLogh 1 -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * ioc log client interface - */ -epicsShareExtern int iocLogDisable; -epicsShareFunc int epicsShareAPI iocLogInit (void); -epicsShareFunc void epicsShareAPI iocLogShow (unsigned level); -epicsShareFunc void epicsShareAPI iocLogFlush (void); - -#ifdef __cplusplus -} -#endif - -#endif /*INCiocLogh*/ diff --git a/src/libCom/log/iocLogServer.c b/src/libCom/log/iocLogServer.c deleted file mode 100644 index f5694fc0f..000000000 --- a/src/libCom/log/iocLogServer.c +++ /dev/null @@ -1,999 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* iocLogServer.c */ - -/* - * archive logMsg() from several IOC's to a common rotating file - * - * - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -#include -#include -#include -#include -#include -#include - -#ifdef UNIX -#include -#include -#endif - -#include "dbDefs.h" -#include "epicsAssert.h" -#include "fdmgr.h" -#include "envDefs.h" -#include "osiSock.h" -#include "epicsStdio.h" - -static unsigned short ioc_log_port; -static long ioc_log_file_limit; -static char ioc_log_file_name[256]; -static char ioc_log_file_command[256]; - - -struct iocLogClient { - int insock; - struct ioc_log_server *pserver; - size_t nChar; - char recvbuf[1024]; - char name[32]; - char ascii_time[32]; -}; - -struct ioc_log_server { - char outfile[256]; - long filePos; - FILE *poutfile; - void *pfdctx; - SOCKET sock; - long max_file_size; -}; - -#define IOCLS_ERROR (-1) -#define IOCLS_OK 0 - -static void acceptNewClient (void *pParam); -static void readFromClient(void *pParam); -static void logTime (struct iocLogClient *pclient); -static int getConfig(void); -static int openLogFile(struct ioc_log_server *pserver); -static void handleLogFileError(void); -static void envFailureNotify(const ENV_PARAM *pparam); -static void freeLogClient(struct iocLogClient *pclient); -static void writeMessagesToLog (struct iocLogClient *pclient); - -#ifdef UNIX -static int setupSIGHUP(struct ioc_log_server *); -static void sighupHandler(int); -static void serviceSighupRequest(void *pParam); -static int getDirectory(void); -static int sighupPipe[2]; -#endif - - - -/* - * - * main() - * - */ -int main(void) -{ - struct sockaddr_in serverAddr; /* server's address */ - struct timeval timeout; - int status; - struct ioc_log_server *pserver; - - osiSockIoctl_t optval; - - status = getConfig(); - if (status<0) { - fprintf(stderr, "iocLogServer: EPICS environment underspecified\n"); - fprintf(stderr, "iocLogServer: failed to initialize\n"); - return IOCLS_ERROR; - } - - pserver = (struct ioc_log_server *) - calloc(1, sizeof *pserver); - if (!pserver) { - fprintf(stderr, "iocLogServer: %s\n", strerror(errno)); - return IOCLS_ERROR; - } - - pserver->pfdctx = (void *) fdmgr_init(); - if (!pserver->pfdctx) { - fprintf(stderr, "iocLogServer: %s\n", strerror(errno)); - return IOCLS_ERROR; - } - - /* - * Open the socket. Use ARPA Internet address format and stream - * sockets. Format described in . - */ - pserver->sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); - if (pserver->sock == INVALID_SOCKET) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "iocLogServer: sock create err: %s\n", sockErrBuf); - free(pserver); - return IOCLS_ERROR; - } - - epicsSocketEnableAddressReuseDuringTimeWaitState ( pserver->sock ); - - /* Zero the sock_addr structure */ - memset((void *)&serverAddr, 0, sizeof serverAddr); - serverAddr.sin_family = AF_INET; - serverAddr.sin_port = htons(ioc_log_port); - - /* get server's Internet address */ - status = bind ( pserver->sock, - (struct sockaddr *)&serverAddr, - sizeof (serverAddr) ); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "iocLogServer: bind err: %s\n", sockErrBuf ); - fprintf (stderr, - "iocLogServer: a server is already installed on port %u?\n", - (unsigned)ioc_log_port); - return IOCLS_ERROR; - } - - /* listen and accept new connections */ - status = listen(pserver->sock, 10); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "iocLogServer: listen err %s\n", sockErrBuf); - return IOCLS_ERROR; - } - - /* - * Set non blocking IO - * to prevent dead locks - */ - optval = TRUE; - status = socket_ioctl( - pserver->sock, - FIONBIO, - &optval); - if (status < 0){ - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "iocLogServer: ioctl FIONBIO err %s\n", sockErrBuf); - return IOCLS_ERROR; - } - -# ifdef UNIX - status = setupSIGHUP(pserver); - if (status < 0) { - return IOCLS_ERROR; - } -# endif - - status = openLogFile(pserver); - if (status < 0) { - fprintf(stderr, - "File access problems to `%s' because `%s'\n", - ioc_log_file_name, - strerror(errno)); - return IOCLS_ERROR; - } - - status = fdmgr_add_callback( - pserver->pfdctx, - pserver->sock, - fdi_read, - acceptNewClient, - pserver); - if (status < 0) { - fprintf(stderr, - "iocLogServer: failed to add read callback\n"); - return IOCLS_ERROR; - } - - - while (TRUE) { - timeout.tv_sec = 60; /* 1 min */ - timeout.tv_usec = 0; - fdmgr_pend_event(pserver->pfdctx, &timeout); - fflush(pserver->poutfile); - } -} - -/* - * seekLatestLine (struct ioc_log_server *pserver) - */ -static int seekLatestLine (struct ioc_log_server *pserver) -{ - static const time_t invalidTime = (time_t) -1; - time_t theLatestTime = invalidTime; - long latestFilePos = -1; - int status; - - /* - * start at the beginning - */ - rewind (pserver->poutfile); - - while (1) { - struct tm theDate; - int convertStatus; - char month[16]; - - /* - * find the line in the file with the latest date - * - * this assumes ctime() produces dates of the form: - * DayName MonthName dayNum 24hourHourNum:minNum:secNum yearNum - */ - convertStatus = fscanf ( - pserver->poutfile, " %*s %*s %15s %d %d:%d:%d %d %*[^\n] ", - month, &theDate.tm_mday, &theDate.tm_hour, - &theDate.tm_min, &theDate.tm_sec, &theDate.tm_year); - if (convertStatus==6) { - static const char *pMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - static const unsigned nMonths = sizeof(pMonths)/sizeof(pMonths[0]); - time_t lineTime = (time_t) -1; - unsigned iMonth; - - for (iMonth=0; iMonthtm_epoch_year) { - theDate.tm_year -= tm_epoch_year; - theDate.tm_isdst = -1; /* dont know */ - lineTime = mktime (&theDate); - if ( lineTime != invalidTime ) { - if (theLatestTime == invalidTime || - difftime(lineTime, theLatestTime)>=0) { - latestFilePos = ftell (pserver->poutfile); - theLatestTime = lineTime; - } - } - else { - char date[128]; - size_t nChar; - nChar = strftime (date, sizeof(date), "%a %b %d %H:%M:%S %Y\n", &theDate); - if (nChar>0) { - fprintf (stderr, "iocLogServer: strange date in log file: %s\n", date); - } - else { - fprintf (stderr, "iocLogServer: strange date in log file\n"); - } - } - } - else { - fprintf (stderr, "iocLogServer: strange year in log file: %d\n", theDate.tm_year); - } - } - else { - fprintf (stderr, "iocLogServer: strange month in log file: %s\n", month); - } - } - else { - int c = fgetc (pserver->poutfile); - - /* - * bypass the line if it does not match the expected format - */ - while ( c!=EOF && c!='\n' ) { - c = fgetc (pserver->poutfile); - } - - if (c==EOF) { - break; - } - } - } - - /* - * move to the proper location in the file - */ - if (latestFilePos != -1) { - status = fseek (pserver->poutfile, latestFilePos, SEEK_SET); - if (status!=IOCLS_OK) { - fclose (pserver->poutfile); - pserver->poutfile = stderr; - return IOCLS_ERROR; - } - } - else { - status = fseek (pserver->poutfile, 0L, SEEK_END); - if (status!=IOCLS_OK) { - fclose (pserver->poutfile); - pserver->poutfile = stderr; - return IOCLS_ERROR; - } - } - - pserver->filePos = ftell (pserver->poutfile); - - if (theLatestTime==invalidTime) { - if (pserver->filePos!=0) { - fprintf (stderr, "iocLogServer: **** Warning ****\n"); - fprintf (stderr, "iocLogServer: no recognizable dates in \"%s\"\n", - ioc_log_file_name); - fprintf (stderr, "iocLogServer: logging at end of file\n"); - } - } - - return IOCLS_OK; -} - - -/* - * openLogFile() - * - */ -static int openLogFile (struct ioc_log_server *pserver) -{ - enum TF_RETURN ret; - - if (ioc_log_file_limit==0u) { - pserver->poutfile = stderr; - return IOCLS_ERROR; - } - - if (pserver->poutfile && pserver->poutfile != stderr){ - fclose (pserver->poutfile); - pserver->poutfile = NULL; - } - - pserver->poutfile = fopen(ioc_log_file_name, "r+"); - if (pserver->poutfile) { - fclose (pserver->poutfile); - pserver->poutfile = NULL; - ret = truncateFile (ioc_log_file_name, ioc_log_file_limit); - if (ret==TF_ERROR) { - return IOCLS_ERROR; - } - pserver->poutfile = fopen(ioc_log_file_name, "r+"); - } - else { - pserver->poutfile = fopen(ioc_log_file_name, "w"); - } - - if (!pserver->poutfile) { - pserver->poutfile = stderr; - return IOCLS_ERROR; - } - strcpy (pserver->outfile, ioc_log_file_name); - pserver->max_file_size = ioc_log_file_limit; - - return seekLatestLine (pserver); -} - - -/* - * handleLogFileError() - * - */ -static void handleLogFileError(void) -{ - fprintf(stderr, - "iocLogServer: log file access problem (errno=%s)\n", - strerror(errno)); - exit(IOCLS_ERROR); -} - - - -/* - * acceptNewClient() - * - */ -static void acceptNewClient ( void *pParam ) -{ - struct ioc_log_server *pserver = (struct ioc_log_server *) pParam; - struct iocLogClient *pclient; - osiSocklen_t addrSize; - struct sockaddr_in addr; - int status; - osiSockIoctl_t optval; - - pclient = ( struct iocLogClient * ) malloc ( sizeof ( *pclient ) ); - if ( ! pclient ) { - return; - } - - addrSize = sizeof ( addr ); - pclient->insock = epicsSocketAccept ( pserver->sock, (struct sockaddr *)&addr, &addrSize ); - if ( pclient->insock==INVALID_SOCKET || addrSize < sizeof (addr) ) { - static unsigned acceptErrCount; - static int lastErrno; - int thisErrno; - - free ( pclient ); - if ( SOCKERRNO == SOCK_EWOULDBLOCK || SOCKERRNO == SOCK_EINTR ) { - return; - } - - thisErrno = SOCKERRNO; - if ( acceptErrCount % 1000 || lastErrno != thisErrno ) { - fprintf ( stderr, "Accept Error %d\n", SOCKERRNO ); - } - acceptErrCount++; - lastErrno = thisErrno; - - return; - } - - /* - * Set non blocking IO - * to prevent dead locks - */ - optval = TRUE; - status = socket_ioctl( - pclient->insock, - FIONBIO, - &optval); - if(status<0){ - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, "%s:%d ioctl FBIO client er %s\n", - __FILE__, __LINE__, sockErrBuf); - epicsSocketDestroy ( pclient->insock ); - free(pclient); - return; - } - - pclient->pserver = pserver; - pclient->nChar = 0u; - - ipAddrToA (&addr, pclient->name, sizeof(pclient->name)); - - logTime(pclient); - -#if 0 - status = fprintf( - pclient->pserver->poutfile, - "%s %s ----- Client Connect -----\n", - pclient->name, - pclient->ascii_time); - if(status<0){ - handleLogFileError(); - } -#endif - - /* - * turn on KEEPALIVE so if the client crashes - * this task will find out and exit - */ - { - long true = 1; - - status = setsockopt( - pclient->insock, - SOL_SOCKET, - SO_KEEPALIVE, - (char *)&true, - sizeof(true) ); - if(status<0){ - fprintf(stderr, "Keepalive option set failed\n"); - } - } - - status = shutdown(pclient->insock, SHUT_WR); - if(status<0){ - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "%s:%d shutdown err %s\n", __FILE__, __LINE__, - sockErrBuf); - epicsSocketDestroy ( pclient->insock ); - free(pclient); - - return; - } - - status = fdmgr_add_callback( - pserver->pfdctx, - pclient->insock, - fdi_read, - readFromClient, - pclient); - if (status<0) { - epicsSocketDestroy ( pclient->insock ); - free(pclient); - fprintf(stderr, "%s:%d client fdmgr_add_callback() failed\n", - __FILE__, __LINE__); - return; - } -} - - - -/* - * readFromClient() - * - */ -#define NITEMS 1 - -static void readFromClient(void *pParam) -{ - struct iocLogClient *pclient = (struct iocLogClient *)pParam; - int recvLength; - int size; - - logTime(pclient); - - size = (int) (sizeof(pclient->recvbuf) - pclient->nChar); - recvLength = recv(pclient->insock, - &pclient->recvbuf[pclient->nChar], - size, - 0); - if (recvLength <= 0) { - if (recvLength<0) { - int errnoCpy = SOCKERRNO; - if (errnoCpy==SOCK_EWOULDBLOCK || errnoCpy==SOCK_EINTR) { - return; - } - if (errnoCpy != SOCK_ECONNRESET && - errnoCpy != SOCK_ECONNABORTED && - errnoCpy != SOCK_EPIPE && - errnoCpy != SOCK_ETIMEDOUT - ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf(stderr, - "%s:%d socket=%d size=%d read error=%s\n", - __FILE__, __LINE__, pclient->insock, - size, sockErrBuf); - } - } - /* - * disconnect - */ - freeLogClient (pclient); - return; - } - - pclient->nChar += (size_t) recvLength; - - writeMessagesToLog (pclient); -} - -/* - * writeMessagesToLog() - */ -static void writeMessagesToLog (struct iocLogClient *pclient) -{ - int status; - size_t lineIndex = 0; - - while (TRUE) { - size_t nchar; - size_t nTotChar; - size_t crIndex; - int ntci; - - if ( lineIndex >= pclient->nChar ) { - pclient->nChar = 0u; - break; - } - - /* - * find the first carrage return and create - * an entry in the log for the message associated - * with it. If a carrage return does not exist and - * the buffer isnt full then move the partial message - * to the front of the buffer and wait for a carrage - * return to arrive. If the buffer is full and there - * is no carrage return then force the message out and - * insert an artificial carrage return. - */ - nchar = pclient->nChar - lineIndex; - for ( crIndex = lineIndex; crIndex < pclient->nChar; crIndex++ ) { - if ( pclient->recvbuf[crIndex] == '\n' ) { - break; - } - } - if ( crIndex < pclient->nChar ) { - nchar = crIndex - lineIndex; - } - else { - nchar = pclient->nChar - lineIndex; - if ( nchar < sizeof ( pclient->recvbuf ) ) { - if ( lineIndex != 0 ) { - pclient->nChar = nchar; - memmove ( pclient->recvbuf, - & pclient->recvbuf[lineIndex], nchar); - } - break; - } - } - - /* - * reset the file pointer if we hit the end of the file - */ - nTotChar = strlen(pclient->name) + - strlen(pclient->ascii_time) + nchar + 3u; - assert (nTotChar <= INT_MAX); - ntci = (int) nTotChar; - if ( pclient->pserver->filePos+ntci >= pclient->pserver->max_file_size ) { - if ( pclient->pserver->max_file_size >= pclient->pserver->filePos ) { - unsigned nPadChar; - /* - * this gets rid of leftover junk at the end of the file - */ - nPadChar = pclient->pserver->max_file_size - pclient->pserver->filePos; - while (nPadChar--) { - status = putc ( ' ', pclient->pserver->poutfile ); - if ( status == EOF ) { - handleLogFileError(); - } - } - } - -# ifdef DEBUG - fprintf ( stderr, - "ioc log server: resetting the file pointer\n" ); -# endif - fflush ( pclient->pserver->poutfile ); - rewind ( pclient->pserver->poutfile ); - pclient->pserver->filePos = ftell ( pclient->pserver->poutfile ); - } - - /* - * NOTE: !! change format string here then must - * change nTotChar calc above !! - */ - assert (ncharpserver->poutfile, - "%s %s %.*s\n", - pclient->name, - pclient->ascii_time, - (int) nchar, - &pclient->recvbuf[lineIndex]); - if (status<0) { - handleLogFileError(); - } - else { - if (status != ntci) { - fprintf(stderr, "iocLogServer: didnt calculate number of characters correctly?\n"); - } - pclient->pserver->filePos += status; - } - lineIndex += nchar+1u; - } -} - - -/* - * freeLogClient () - */ -static void freeLogClient(struct iocLogClient *pclient) -{ - int status; - -# ifdef DEBUG - if(length == 0){ - fprintf(stderr, "iocLogServer: nil message disconnect\n"); - } -# endif - - /* - * flush any left overs - */ - if (pclient->nChar) { - /* - * this forces a flush - */ - if (pclient->nCharrecvbuf)) { - pclient->recvbuf[pclient->nChar] = '\n'; - } - writeMessagesToLog (pclient); - } - - status = fdmgr_clear_callback( - pclient->pserver->pfdctx, - pclient->insock, - fdi_read); - if (status!=IOCLS_OK) { - fprintf(stderr, "%s:%d fdmgr_clear_callback() failed\n", - __FILE__, __LINE__); - } - - epicsSocketDestroy ( pclient->insock ); - - free (pclient); - - return; -} - - -/* - * - * logTime() - * - */ -static void logTime(struct iocLogClient *pclient) -{ - time_t sec; - char *pcr; - char *pTimeString; - - sec = time (NULL); - pTimeString = ctime (&sec); - strncpy (pclient->ascii_time, - pTimeString, - sizeof (pclient->ascii_time) ); - pclient->ascii_time[sizeof(pclient->ascii_time)-1] = '\0'; - pcr = strchr(pclient->ascii_time, '\n'); - if (pcr) { - *pcr = '\0'; - } -} - - -/* - * - * getConfig() - * Get Server Configuration - * - * - */ -static int getConfig(void) -{ - int status; - char *pstring; - long param; - - status = envGetLongConfigParam( - &EPICS_IOC_LOG_PORT, - ¶m); - if(status>=0){ - ioc_log_port = (unsigned short) param; - } - else { - ioc_log_port = 7004U; - } - - status = envGetLongConfigParam( - &EPICS_IOC_LOG_FILE_LIMIT, - &ioc_log_file_limit); - if(status>=0){ - if (ioc_log_file_limit<=0) { - envFailureNotify (&EPICS_IOC_LOG_FILE_LIMIT); - return IOCLS_ERROR; - } - } - else { - ioc_log_file_limit = 10000; - } - - pstring = envGetConfigParam( - &EPICS_IOC_LOG_FILE_NAME, - sizeof ioc_log_file_name, - ioc_log_file_name); - if(pstring == NULL){ - envFailureNotify(&EPICS_IOC_LOG_FILE_NAME); - return IOCLS_ERROR; - } - - /* - * its ok to not specify the IOC_LOG_FILE_COMMAND - */ - pstring = envGetConfigParam( - &EPICS_IOC_LOG_FILE_COMMAND, - sizeof ioc_log_file_command, - ioc_log_file_command); - return IOCLS_OK; -} - - - -/* - * - * failureNotify() - * - * - */ -static void envFailureNotify(const ENV_PARAM *pparam) -{ - fprintf(stderr, - "iocLogServer: EPICS environment variable `%s' undefined\n", - pparam->name); -} - - - -#ifdef UNIX -static int setupSIGHUP(struct ioc_log_server *pserver) -{ - int status; - struct sigaction sigact; - - status = getDirectory(); - if (status<0){ - fprintf(stderr, "iocLogServer: failed to determine log file " - "directory\n"); - return IOCLS_ERROR; - } - - /* - * Set up SIGHUP handler. SIGHUP will cause the log file to be - * closed and re-opened, possibly with a different name. - */ - sigact.sa_handler = sighupHandler; - sigemptyset (&sigact.sa_mask); - sigact.sa_flags = 0; - if (sigaction(SIGHUP, &sigact, NULL)){ - fprintf(stderr, "iocLogServer: %s\n", strerror(errno)); - return IOCLS_ERROR; - } - - status = pipe(sighupPipe); - if(status<0){ - fprintf(stderr, - "iocLogServer: failed to create pipe because `%s'\n", - strerror(errno)); - return IOCLS_ERROR; - } - - status = fdmgr_add_callback( - pserver->pfdctx, - sighupPipe[0], - fdi_read, - serviceSighupRequest, - pserver); - if(status<0){ - fprintf(stderr, - "iocLogServer: failed to add SIGHUP callback\n"); - return IOCLS_ERROR; - } - return IOCLS_OK; -} - -/* - * - * sighupHandler() - * - * - */ -static void sighupHandler(int signo) -{ - (void) write(sighupPipe[1], "SIGHUP\n", 7); -} - - - -/* - * serviceSighupRequest() - * - */ -static void serviceSighupRequest(void *pParam) -{ - struct ioc_log_server *pserver = (struct ioc_log_server *)pParam; - char buff[256]; - int status; - - /* - * Read and discard message from pipe. - */ - (void) read(sighupPipe[0], buff, sizeof buff); - - /* - * Determine new log file name. - */ - status = getDirectory(); - if (status<0){ - fprintf(stderr, "iocLogServer: failed to determine new log " - "file name\n"); - return; - } - - /* - * Try (re)opening the file. - */ - status = openLogFile(pserver); - if(status<0){ - fprintf(stderr, - "File access problems to `%s' because `%s'\n", - ioc_log_file_name, - strerror(errno)); - /* Revert to old filename */ - strcpy(ioc_log_file_name, pserver->outfile); - status = openLogFile(pserver); - if(status<0){ - fprintf(stderr, - "File access problems to `%s' because `%s'\n", - ioc_log_file_name, - strerror(errno)); - return; - } - else { - fprintf(stderr, - "iocLogServer: re-opened old log file %s\n", - ioc_log_file_name); - } - } - else { - fprintf(stderr, - "iocLogServer: opened new log file %s\n", - ioc_log_file_name); - } -} - - - -/* - * - * getDirectory() - * - * - */ -static int getDirectory(void) -{ - FILE *pipe; - char dir[256]; - int i; - - if (ioc_log_file_command[0] != '\0') { - - /* - * Use popen() to execute command and grab output. - */ - pipe = popen(ioc_log_file_command, "r"); - if (pipe == NULL) { - fprintf(stderr, - "Problem executing `%s' because `%s'\n", - ioc_log_file_command, - strerror(errno)); - return IOCLS_ERROR; - } - if (fgets(dir, sizeof(dir), pipe) == NULL) { - fprintf(stderr, - "Problem reading o/p from `%s' because `%s'\n", - ioc_log_file_command, - strerror(errno)); - (void) pclose(pipe); - return IOCLS_ERROR; - } - (void) pclose(pipe); - - /* - * Terminate output at first newline and discard trailing - * slash character if present.. - */ - for (i=0; dir[i] != '\n' && dir[i] != '\0'; i++) - ; - dir[i] = '\0'; - - i = strlen(dir); - if (i > 1 && dir[i-1] == '/') dir[i-1] = '\0'; - - /* - * Use output as directory part of file name. - */ - if (dir[0] != '\0') { - char *name = ioc_log_file_name; - char *slash = strrchr(ioc_log_file_name, '/'); - char temp[256]; - - if (slash != NULL) name = slash + 1; - strcpy(temp,name); - sprintf(ioc_log_file_name,"%s/%s",dir,temp); - } - } - return IOCLS_OK; -} -#endif diff --git a/src/libCom/log/logClient.c b/src/libCom/log/logClient.c deleted file mode 100644 index 99ee671d9..000000000 --- a/src/libCom/log/logClient.c +++ /dev/null @@ -1,618 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* logClient.c,v 1.25.2.6 2004/10/07 13:37:34 mrk Exp */ -/* - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -/* - * ANSI C - */ -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "epicsEvent.h" -#include "iocLog.h" -#include "errlog.h" -#include "epicsMutex.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "osiSock.h" -#include "epicsAssert.h" -#include "epicsExit.h" -#include "epicsSignal.h" - -#include "logClient.h" - -typedef struct { - char msgBuf[0x4000]; - struct sockaddr_in addr; - char name[64]; - epicsMutexId mutex; - SOCKET sock; - epicsThreadId restartThreadId; - epicsEventId stateChangeNotify; - unsigned connectCount; - unsigned nextMsgIndex; - unsigned connected; - unsigned shutdown; - unsigned shutdownConfirm; - int connFailStatus; -} logClient; - -static const double LOG_RESTART_DELAY = 5.0; /* sec */ -static const double LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT = 5.0; /* sec */ -static const double LOG_SERVER_SHUTDOWN_TIMEOUT = 30.0; /* sec */ - -/* - * If set using iocLogPrefix() this string is prepended to all log messages: - */ -static char* logClientPrefix = NULL; - -/* - * logClientClose () - */ -static void logClientClose ( logClient *pClient ) -{ -# ifdef DEBUG - fprintf (stderr, "log client: lingering for connection close..."); - fflush (stderr); -# endif - - /* - * mutex on - */ - epicsMutexMustLock (pClient->mutex); - - /* - * close any preexisting connection to the log server - */ - if ( pClient->sock != INVALID_SOCKET ) { - epicsSocketDestroy ( pClient->sock ); - pClient->sock = INVALID_SOCKET; - } - - pClient->nextMsgIndex = 0u; - memset ( pClient->msgBuf, '\0', sizeof ( pClient->msgBuf ) ); - pClient->connected = 0u; - - /* - * mutex off - */ - epicsMutexUnlock (pClient->mutex); - -# ifdef DEBUG - fprintf (stderr, "done\n"); -# endif -} - -/* - * logClientDestroy - */ -static void logClientDestroy (logClientId id) -{ - enum epicsSocketSystemCallInterruptMechanismQueryInfo interruptInfo; - logClient *pClient = (logClient *) id; - epicsTimeStamp begin, current; - double diff; - - /* command log client thread to shutdown - taking mutex here */ - /* forces cache flush on SMP machines */ - epicsMutexMustLock ( pClient->mutex ); - pClient->shutdown = 1u; - epicsMutexUnlock ( pClient->mutex ); - - /* unblock log client thread blocking in send() or connect() */ - interruptInfo = - epicsSocketSystemCallInterruptMechanismQuery (); - switch ( interruptInfo ) { - case esscimqi_socketCloseRequired: - logClientClose ( pClient ); - break; - case esscimqi_socketBothShutdownRequired: - shutdown ( pClient->sock, SHUT_WR ); - break; - case esscimqi_socketSigAlarmRequired: - epicsSignalRaiseSigAlarm ( pClient->restartThreadId ); - break; - default: - break; - }; - - /* wait for confirmation that the thread exited - taking */ - /* mutex here forces cache update on SMP machines */ - epicsTimeGetCurrent ( & begin ); - epicsMutexMustLock ( pClient->mutex ); - do { - epicsMutexUnlock ( pClient->mutex ); - epicsEventWaitWithTimeout ( - pClient->stateChangeNotify, - LOG_SERVER_SHUTDOWN_TIMEOUT / 10.0 ); - epicsTimeGetCurrent ( & current ); - diff = epicsTimeDiffInSeconds ( & current, & begin ); - epicsMutexMustLock ( pClient->mutex ); - } - while ( ! pClient->shutdownConfirm && diff < LOG_SERVER_SHUTDOWN_TIMEOUT ); - epicsMutexUnlock ( pClient->mutex ); - - if ( ! pClient->shutdownConfirm ) { - fprintf ( stderr, "log client shutdown: timed out stopping" - " reconnect thread for \"%s\" after %.1f seconds - cleanup aborted\n", - pClient->name, LOG_SERVER_SHUTDOWN_TIMEOUT ); - return; - } - - errlogRemoveListeners ( logClientSendMessage, (void *) pClient ); - - logClientClose ( pClient ); - - epicsMutexDestroy ( pClient->mutex ); - - epicsEventDestroy ( pClient->stateChangeNotify ); - - free ( pClient ); -} - -/* - * This method requires the pClient->mutex be owned already. - */ -static void sendMessageChunk(logClient * pClient, const char * message) { - unsigned strSize; - - strSize = strlen ( message ); - while ( strSize ) { - unsigned msgBufBytesLeft = - sizeof ( pClient->msgBuf ) - pClient->nextMsgIndex; - - if ( strSize > msgBufBytesLeft ) { - int status; - - if ( ! pClient->connected ) { - break; - } - - if ( msgBufBytesLeft > 0u ) { - memcpy ( & pClient->msgBuf[pClient->nextMsgIndex], - message, msgBufBytesLeft ); - pClient->nextMsgIndex += msgBufBytesLeft; - strSize -= msgBufBytesLeft; - message += msgBufBytesLeft; - } - - status = send ( pClient->sock, pClient->msgBuf, - pClient->nextMsgIndex, 0 ); - if ( status > 0 ) { - unsigned nSent = (unsigned) status; - if ( nSent < pClient->nextMsgIndex ) { - unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent; - memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], - newNextMsgIndex ); - pClient->nextMsgIndex = newNextMsgIndex; - } - else { - pClient->nextMsgIndex = 0u; - } - } - else { - if ( ! pClient->shutdown ) { - char sockErrBuf[64]; - if ( status ) { - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - } - else { - strcpy ( sockErrBuf, "server initiated disconnect" ); - } - fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n", - pClient->name, sockErrBuf ); - } - logClientClose ( pClient ); - break; - } - } - else { - memcpy ( & pClient->msgBuf[pClient->nextMsgIndex], - message, strSize ); - pClient->nextMsgIndex += strSize; - break; - } - } -} - - -/* - * logClientSend () - */ -void epicsShareAPI logClientSend ( logClientId id, const char * message ) -{ - logClient * pClient = ( logClient * ) id; - - if ( ! pClient || ! message ) { - return; - } - - epicsMutexMustLock ( pClient->mutex ); - - if (logClientPrefix) { - sendMessageChunk(pClient, logClientPrefix); - } - sendMessageChunk(pClient, message); - - epicsMutexUnlock (pClient->mutex); -} - - -void epicsShareAPI logClientFlush ( logClientId id ) -{ - logClient * pClient = ( logClient * ) id; - - if ( ! pClient ) { - return; - } - - epicsMutexMustLock ( pClient->mutex ); - - while ( pClient->nextMsgIndex && pClient->connected ) { - int status = send ( pClient->sock, pClient->msgBuf, - pClient->nextMsgIndex, 0 ); - if ( status > 0 ) { - unsigned nSent = (unsigned) status; - if ( nSent < pClient->nextMsgIndex ) { - unsigned newNextMsgIndex = pClient->nextMsgIndex - nSent; - memmove ( pClient->msgBuf, & pClient->msgBuf[nSent], - newNextMsgIndex ); - pClient->nextMsgIndex = newNextMsgIndex; - } - else { - pClient->nextMsgIndex = 0u; - } - } - else { - if ( ! pClient->shutdown ) { - char sockErrBuf[64]; - if ( status ) { - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - } - else { - strcpy ( sockErrBuf, "server initiated disconnect" ); - } - fprintf ( stderr, "log client: lost contact with log server at \"%s\" because \"%s\"\n", - pClient->name, sockErrBuf ); - } - logClientClose ( pClient ); - break; - } - } - epicsMutexUnlock ( pClient->mutex ); -} - -/* - * logClientMakeSock () - */ -static void logClientMakeSock (logClient *pClient) -{ - -# ifdef DEBUG - fprintf (stderr, "log client: creating socket..."); -# endif - - epicsMutexMustLock (pClient->mutex); - - /* - * allocate a socket - */ - pClient->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, 0 ); - if ( pClient->sock == INVALID_SOCKET ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf ( stderr, "log client: no socket error %s\n", - sockErrBuf ); - } - - epicsMutexUnlock (pClient->mutex); - -# ifdef DEBUG - fprintf (stderr, "done\n"); -# endif - -} - -/* - * logClientConnect() - */ -static void logClientConnect (logClient *pClient) -{ - osiSockIoctl_t optval; - int errnoCpy; - int status; - - if ( pClient->sock == INVALID_SOCKET ) { - logClientMakeSock ( pClient ); - if ( pClient->sock == INVALID_SOCKET ) { - return; - } - } - - while ( 1 ) { - status = connect (pClient->sock, - (struct sockaddr *)&pClient->addr, sizeof(pClient->addr)); - if ( status >= 0 ) { - break; - } - else { - errnoCpy = SOCKERRNO; - if ( errnoCpy == SOCK_EINTR ) { - continue; - } - else if ( - errnoCpy==SOCK_EINPROGRESS || - errnoCpy==SOCK_EWOULDBLOCK ) { - return; - } - else if ( errnoCpy==SOCK_EALREADY ) { - break; - } - else { - if ( pClient->connFailStatus != errnoCpy && ! pClient->shutdown ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, - "log client: failed to connect to \"%s\" because %d=\"%s\"\n", - pClient->name, errnoCpy, sockErrBuf); - pClient->connFailStatus = errnoCpy; - } - logClientClose ( pClient ); - return; - } - } - } - - epicsMutexMustLock (pClient->mutex); - - pClient->connected = 1u; - pClient->connFailStatus = 0; - - /* - * discover that the connection has expired - * (after a long delay) - */ - optval = TRUE; - status = setsockopt (pClient->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)); - if (status<0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "log client: unable to enable keepalive option because \"%s\"\n", sockErrBuf); - } - - /* - * we don't need full-duplex (clients only write), so we shutdown - * the read end of our socket - */ - status = shutdown (pClient->sock, SHUT_RD); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "%s:%d shutdown(%d,SHUT_RD) error was \"%s\"\n", - __FILE__, __LINE__, pClient->sock, sockErrBuf); - /* not fatal (although it shouldn't happen) */ - } - - /* - * set how long we will wait for the TCP state machine - * to clean up when we issue a close(). This - * guarantees that messages are serialized when we - * switch connections. - */ - { - struct linger lingerval; - - lingerval.l_onoff = TRUE; - lingerval.l_linger = 60*5; - status = setsockopt (pClient->sock, SOL_SOCKET, SO_LINGER, (char *) &lingerval, sizeof(lingerval)); - if (status<0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - fprintf (stderr, "log client: unable to set linger options because \"%s\"\n", sockErrBuf); - } - } - - pClient->connectCount++; - - epicsMutexUnlock ( pClient->mutex ); - - epicsEventSignal ( pClient->stateChangeNotify ); - - fprintf ( stderr, "log client: connected to log server at \"%s\"\n", pClient->name ); -} - -/* - * logClientRestart () - */ -static void logClientRestart ( logClientId id ) -{ - logClient *pClient = (logClient *)id; - - /* SMP safe state inspection */ - epicsMutexMustLock ( pClient->mutex ); - while ( ! pClient->shutdown ) { - unsigned isConn; - - isConn = pClient->connected; - - epicsMutexUnlock ( pClient->mutex ); - - if ( isConn ) { - logClientFlush ( pClient ); - } - else { - logClientConnect ( pClient ); - } - - epicsThreadSleep ( LOG_RESTART_DELAY ); - - epicsMutexMustLock ( pClient->mutex ); - } - epicsMutexUnlock ( pClient->mutex ); - - pClient->shutdownConfirm = 1u; - epicsEventSignal ( pClient->stateChangeNotify ); -} - -/* - * logClientCreate() - */ -logClientId epicsShareAPI logClientCreate ( - struct in_addr server_addr, unsigned short server_port) -{ - epicsTimeStamp begin, current; - logClient *pClient; - double diff; - - pClient = calloc (1, sizeof (*pClient)); - if (pClient==NULL) { - return NULL; - } - - pClient->addr.sin_family = AF_INET; - pClient->addr.sin_addr = server_addr; - pClient->addr.sin_port = htons(server_port); - ipAddrToDottedIP (&pClient->addr, pClient->name, sizeof(pClient->name)); - - pClient->mutex = epicsMutexCreate (); - if ( ! pClient->mutex ) { - free ( pClient ); - return NULL; - } - - pClient->sock = INVALID_SOCKET; - pClient->connected = 0u; - pClient->connFailStatus = 0; - pClient->shutdown = 0; - pClient->shutdownConfirm = 0; - - epicsAtExit (logClientDestroy, (void*) pClient); - - pClient->stateChangeNotify = epicsEventCreate (epicsEventEmpty); - if ( ! pClient->stateChangeNotify ) { - epicsMutexDestroy ( pClient->mutex ); - free ( pClient ); - return NULL; - } - - pClient->restartThreadId = epicsThreadCreate ( - "logRestart", epicsThreadPriorityLow, - epicsThreadGetStackSize(epicsThreadStackSmall), - logClientRestart, pClient ); - if ( pClient->restartThreadId == NULL ) { - epicsMutexDestroy ( pClient->mutex ); - epicsEventDestroy ( pClient->stateChangeNotify ); - free (pClient); - fprintf(stderr, "log client: unable to start log client connection watch dog thread\n"); - return NULL; - } - - /* - * attempt to synchronize with circuit connect - */ - epicsTimeGetCurrent ( & begin ); - epicsMutexMustLock ( pClient->mutex ); - do { - epicsMutexUnlock ( pClient->mutex ); - epicsEventWaitWithTimeout ( - pClient->stateChangeNotify, - LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT / 10.0 ); - epicsTimeGetCurrent ( & current ); - diff = epicsTimeDiffInSeconds ( & current, & begin ); - epicsMutexMustLock ( pClient->mutex ); - } - while ( ! pClient->connected && diff < LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT ); - epicsMutexUnlock ( pClient->mutex ); - - if ( ! pClient->connected ) { - fprintf (stderr, "log client create: timed out synchronizing with circuit connect to \"%s\" after %.1f seconds\n", - pClient->name, LOG_SERVER_CREATE_CONNECT_SYNC_TIMEOUT ); - } - - errlogAddListener ( logClientSendMessage, (void *) pClient ); - - return (void *) pClient; -} - -/* - * logClientShow () - */ -void epicsShareAPI logClientShow (logClientId id, unsigned level) -{ - logClient *pClient = (logClient *) id; - - if ( pClient->connected ) { - printf ("log client: connected to log server at \"%s\"\n", pClient->name); - } - else { - printf ("log client: disconnected from log server at \"%s\"\n", pClient->name); - } - - if (level>1) { - printf ("log client: sock=%s, connect cycles = %u\n", - pClient->sock==INVALID_SOCKET?"INVALID":"OK", - pClient->connectCount); - } - - if (logClientPrefix) { - printf ("log client: prefix is \"%s\"\n", logClientPrefix); - } -} - -/* - * logClientSendMessage (); deprecated - */ -void logClientSendMessage ( logClientId id, const char * message ) -{ - if ( !iocLogDisable ) { - logClientSend (id, message); - } -} - -/* - * iocLogPrefix() - */ -void epicsShareAPI iocLogPrefix(const char * prefix) -{ - - /* If we have already established a log prefix, don't let the user change - * it. The iocLogPrefix command is expected to be run from the IOC startup - * script during initialization; the prefix can't be changed once it has - * been set. - */ - - if (logClientPrefix) { - printf ("iocLogPrefix: The prefix was already set to \"%s\" " - "and can't be changed.\n", logClientPrefix); - return; - } - - if (prefix) { - unsigned prefixLen = strlen(prefix); - if (prefixLen > 0) { - char * localCopy = malloc(prefixLen+1); - strcpy(localCopy, prefix); - logClientPrefix = localCopy; - } - } -} diff --git a/src/libCom/log/logClient.h b/src/libCom/log/logClient.h deleted file mode 100644 index 1797bbb20..000000000 --- a/src/libCom/log/logClient.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* logClient.h,v 1.5.2.1 2003/07/08 00:08:06 jhill Exp */ -/* - * - * Author: Jeffrey O. Hill - * Date: 080791 - */ - -#ifndef INClogClienth -#define INClogClienth 1 -#include "shareLib.h" -#include "osiSock.h" /* for 'struct in_addr' */ - -/* include default log client interface for backward compatibility */ -#include "iocLog.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *logClientId; -epicsShareFunc logClientId epicsShareAPI logClientCreate ( - struct in_addr server_addr, unsigned short server_port); -epicsShareFunc void epicsShareAPI logClientSend (logClientId id, const char *message); -epicsShareFunc void epicsShareAPI logClientShow (logClientId id, unsigned level); -epicsShareFunc void epicsShareAPI logClientFlush (logClientId id); -epicsShareFunc void epicsShareAPI iocLogPrefix(const char* prefix); - -/* deprecated interface; retained for backward compatibility */ -/* note: implementations are in iocLog.c, not logClient.c */ -epicsShareFunc logClientId epicsShareAPI logClientInit (void); -epicsShareFunc void logClientSendMessage (logClientId id, const char *message); - -#ifdef __cplusplus -} -#endif - -#endif /*INClogClienth*/ diff --git a/src/libCom/macLib/Makefile b/src/libCom/macLib/Makefile deleted file mode 100644 index c0be82af8..000000000 --- a/src/libCom/macLib/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/macLib -INC += macLib.h -Com_SRCS += macCore.c -Com_SRCS += macEnv.c -Com_SRCS += macUtil.c diff --git a/src/libCom/macLib/macCore.c b/src/libCom/macLib/macCore.c deleted file mode 100644 index 55d31719e..000000000 --- a/src/libCom/macLib/macCore.c +++ /dev/null @@ -1,950 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Implementation of core macro substitution library (macLib) - * - * The implementation is fairly unsophisticated and linked lists are - * used to store macro values. Typically there will will be only a - * small number of macros and performance won't be a problem. Special - * measures are taken to avoid unnecessary expansion of macros whose - * definitions reference other macros. Whenever a macro is created, - * modified or deleted, a "dirty" flag is set; this causes a full - * expansion of all macros the next time a macro value is read - * - * Original Author: William Lupton, W. M. Keck Observatory - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "errlog.h" -#include "dbmf.h" -#include "macLib.h" - - -/*** Local structure definitions ***/ - -/* - * Entry in linked list of macro definitions - */ -typedef struct mac_entry { - ELLNODE node; /* prev and next pointers */ - char *name; /* entry name */ - char *type; /* entry type */ - char *rawval; /* raw (unexpanded) value */ - char *value; /* expanded macro value */ - size_t length; /* length of value */ - int error; /* error expanding value? */ - int visited; /* ever been visited? */ - int special; /* special (internal) entry? */ - int level; /* scoping level */ -} MAC_ENTRY; - - -/*** Local function prototypes ***/ - -/* - * These static functions peform low-level operations on macro entries - */ -static MAC_ENTRY *first ( MAC_HANDLE *handle ); -static MAC_ENTRY *last ( MAC_HANDLE *handle ); -static MAC_ENTRY *next ( MAC_ENTRY *entry ); -static MAC_ENTRY *previous( MAC_ENTRY *entry ); - -static MAC_ENTRY *create( MAC_HANDLE *handle, const char *name, int special ); -static MAC_ENTRY *lookup( MAC_HANDLE *handle, const char *name, int special ); -static char *rawval( MAC_HANDLE *handle, MAC_ENTRY *entry, const char *value ); -static void delete( MAC_HANDLE *handle, MAC_ENTRY *entry ); -static long expand( MAC_HANDLE *handle ); -static void trans ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level, - const char *term, const char **rawval, char **value, - char *valend ); -static void refer ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level, - const char **rawval, char **value, char *valend ); - -static void cpy2val( const char *src, char **value, char *valend ); -static char *Strdup( const char *string ); - - -/*** Constants ***/ - -/* - * Magic number for validating context. - */ -#define MAC_MAGIC 0xbadcafe /* ...sells sub-standard coffee? */ - -/* - * Flag bits - */ -#define FLAG_SUPPRESS_WARNINGS 0x1 -#define FLAG_USE_ENVIRONMENT 0x80 - - -/*** Library routines ***/ - -/* - * Create a new macro substitution context and return an opaque handle - * associated with the new context. Also optionally load an initial set - * of macro definitions - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macCreateHandle( - MAC_HANDLE **pHandle, /* address of variable to receive pointer */ - /* to new macro substitution context */ - - const char * pairs[] ) /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -{ - MAC_HANDLE *handle; /* pointer to macro substitution context */ - - /* ensure NULL handle pointer is returned on error */ - *pHandle = NULL; - - /* allocate macro substitution context */ - handle = ( MAC_HANDLE * ) dbmfMalloc( sizeof( MAC_HANDLE ) ); - if ( handle == NULL ) { - errlogPrintf( "macCreateHandle: failed to allocate context\n" ); - return -1; - } - - /* initialize context */ - handle->magic = MAC_MAGIC; - handle->dirty = FALSE; - handle->level = 0; - handle->debug = 0; - handle->flags = 0; - ellInit( &handle->list ); - - /* use environment variables if so specified */ - if (pairs && pairs[0] && !strcmp(pairs[0],"") && pairs[1] && !strcmp(pairs[1],"environ") && !pairs[3]) { - handle->flags |= FLAG_USE_ENVIRONMENT; - } - else { - /* if supplied, load macro definitions */ - for ( ; pairs && pairs[0]; pairs += 2 ) { - if ( macPutValue( handle, pairs[0], pairs[1] ) < 0 ) { - dbmfFree( handle ); - return -1; - } - } - } - - /* set returned handle pointer */ - *pHandle = handle; - - return 0; -} - -/* - * Turn on/off suppression of printed warnings from macLib calls - * for the given handle - */ -void -epicsShareAPI macSuppressWarning( - MAC_HANDLE *handle, /* opaque handle */ - int suppress /* 0 means issue, 1 means suppress */ -) -{ - if ( handle && handle->magic == MAC_MAGIC ) { - handle->flags = (handle->flags & ~FLAG_SUPPRESS_WARNINGS) | - (suppress ? FLAG_SUPPRESS_WARNINGS : 0); - } -} - -/* - * Expand a string that may contain macro references and return the - * expanded string - * - * This is a very basic and powerful routine. It's basically a wrapper - * around the the translation "engine" trans() - */ -long /* strlen(dest), <0 if any macros are */ - /* undefined */ -epicsShareAPI macExpandString( - MAC_HANDLE *handle, /* opaque handle */ - - const char *src, /* source string */ - - char *dest, /* destination string */ - - long capacity ) /* capacity of destination buffer (dest) */ -{ - MAC_ENTRY entry; - const char *s; - char *d; - long length; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macExpandString: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macExpandString( %s, capacity = %ld )\n", src, capacity ); - - /* Check size */ - if (capacity <= 1) - return -1; - - /* expand raw values if necessary */ - if ( expand( handle ) < 0 ) - errlogPrintf( "macExpandString: failed to expand raw values\n" ); - - /* fill in necessary fields in fake macro entry structure */ - entry.name = (char *) src; - entry.type = "string"; - entry.error = FALSE; - - /* expand the string */ - s = src; - d = dest; - *d = '\0'; - trans( handle, &entry, 0, "", &s, &d, d + capacity - 1 ); - - /* return +/- #chars copied depending on successful expansion */ - length = d - dest; - length = ( entry.error ) ? -length : length; - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macExpandString() -> %ld\n", length ); - - return length; -} - -/* - * Define the value of a macro. A NULL value deletes the macro if it - * already existed - */ -long /* strlen(value) */ -epicsShareAPI macPutValue( - MAC_HANDLE *handle, /* opaque handle */ - - const char *name, /* macro name */ - - const char *value ) /* macro value */ -{ - MAC_ENTRY *entry; /* pointer to this macro's entry structure */ - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macPutValue: NULL or invalid handle\n" ); - return -1; - } - - if ( handle->debug & 1 ) - printf( "macPutValue( %s, %s )\n", name, value ? value : "NULL" ); - - /* handle NULL value case: if name was found, delete entry (may be - several entries at different scoping levels) */ - if ( value == NULL ) { - /* - * FIXME: shouldn't be able to delete entries from lower scopes - * NOTE: when this is changed, this functionality of removing - * a macro from all scopes will still be needed by iocshEnvClear - */ - while ( ( entry = lookup( handle, name, FALSE ) ) != NULL ) { - int done = strcmp(entry->type, "environment variable") == 0; - delete( handle, entry ); - - if (done) - break; - } - - return 0; - } - - /* look up macro name */ - entry = lookup( handle, name, FALSE ); - - /* new entry must be created if macro doesn't exist or if it only - exists at a lower scoping level */ - if ( entry == NULL || entry->level < handle->level ) { - entry = create( handle, name, FALSE ); - if ( entry == NULL ) { - errlogPrintf( "macPutValue: failed to create macro %s = %s\n", - name, value ); - return -1; - } else { - entry->type = "macro"; - } - } - - /* copy raw value */ - if ( rawval( handle, entry, value ) == NULL ) { - errlogPrintf( "macPutValue: failed to copy macro %s = %s\n", - name, value ) ; - return -1; - } - - /* return length of value */ - return strlen( value ); -} - -/* - * Return the value of a macro - */ -long /* strlen(value), <0 if undefined */ -epicsShareAPI macGetValue( - MAC_HANDLE *handle, /* opaque handle */ - - const char *name, /* macro name or reference */ - - char *value, /* string to receive macro value or name */ - /* argument if macro is undefined */ - - long capacity ) /* capacity of destination buffer (value) */ -{ - MAC_ENTRY *entry; /* pointer to this macro's entry structure */ - long length; /* number of characters returned */ - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macGetValue: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macGetValue( %s )\n", name ); - - /* look up macro name */ - entry = lookup( handle, name, FALSE ); - - /* if capacity <= 1 or VALUE == NULL just return -1 / 0 for undefined / - defined macro */ - if ( capacity <= 1 || value == NULL ) { - return ( entry == NULL ) ? -1 : 0; - } - - /* if not found, copy name to value and return minus #chars copied */ - if ( entry == NULL ) { - strncpy( value, name, capacity ); - return ( value[capacity-1] == '\0' ) ? - (long) strlen( name ) : -capacity; - } - - /* expand raw values if necessary; if fail (can only fail because of - memory allocation failure), return same as if not found */ - if ( expand( handle ) < 0 ) { - errlogPrintf( "macGetValue: failed to expand raw values\n" ); - strncpy( value, name, capacity ); - return ( value[capacity-1] == '\0' ) ? - (long) strlen( name ) : -capacity; - } - - /* copy value and return +/- #chars copied depending on successful - expansion */ - strncpy( value, entry->value, capacity ); - length = ( value[capacity-1] == '\0' ) ? entry->length : capacity; - - return ( entry->error ) ? -length : length; -} - -/* - * Free up all storage associated with and delete a macro substitution - * context - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macDeleteHandle( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry, *nextEntry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macDeleteHandle: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macDeleteHandle()\n" ); - - /* delete all entries */ - for ( entry = first( handle ); entry != NULL; entry = nextEntry ) { - nextEntry = next( entry ); - delete( handle, entry ); - } - - /* clear magic field and free context structure */ - handle->magic = 0; - dbmfFree( handle ); - - return 0; -} - -/* - * Mark the start of a new scoping level - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPushScope( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macPushScope: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macPushScope()\n" ); - - /* increment scoping level */ - handle->level++; - - /* create new "special" entry of name "" */ - entry = create( handle, "", TRUE ); - if ( entry == NULL ) { - handle->level--; - errlogPrintf( "macPushScope: failed to push scope\n" ); - return -1; - } else { - entry->type = "scope marker"; - } - - return 0; -} - -/* - * Pop all macros defined since the last call to macPushScope() - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPopScope( - MAC_HANDLE *handle ) /* opaque handle */ -{ - MAC_ENTRY *entry, *nextEntry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macPopScope: NULL or invalid handle\n" ); - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macPopScope()\n" ); - - /* check scoping level isn't already zero */ - if ( handle->level == 0 ) { - errlogPrintf( "macPopScope: no scope to pop\n" ); - return -1; - } - - /* look up most recent scope entry */ - entry = lookup( handle, "", TRUE ); - if ( entry == NULL ) { - errlogPrintf( "macPopScope: no scope to pop\n" ); - return -1; - } - - /* delete scope entry and all macros defined since it */ - for ( ; entry != NULL; entry = nextEntry ) { - nextEntry = next( entry ); - delete( handle, entry ); - } - - /* decrement scoping level */ - handle->level--; - - return 0; -} - -/* - * Report macro details to standard output - */ -long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macReportMacros( - MAC_HANDLE *handle ) /* opaque handle */ -{ - const char *format = "%-1s %-16s %-16s %s\n"; - MAC_ENTRY *entry; - - /* check handle */ - if ( handle == NULL || handle->magic != MAC_MAGIC ) { - errlogPrintf( "macReportMacros: NULL or invalid handle\n" ); - return -1; - } - - /* expand raw values if necessary; report but ignore failure */ - if ( expand( handle ) < 0 ) - errlogPrintf( "macGetValue: failed to expand raw values\n" ); - - /* loop through macros, reporting names and values */ - printf( format, "e", "name", "rawval", "value" ); - printf( format, "-", "----", "------", "-----" ); - for ( entry = first( handle ); entry != NULL; entry = next( entry ) ) { - - /* differentiate between "special" (scope marker) and ordinary - entries */ - if ( entry->special ) - printf( format, "s", "----", "------", "-----" ); - else - printf( format, entry->error ? "*" : " ", entry->name, - entry->rawval ? entry->rawval : "", - entry->value ? entry->value : ""); - } - - return 0; -} - -/******************** beginning of static functions ********************/ - -/* - * Return pointer to first macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *first( MAC_HANDLE *handle ) -{ - return ( MAC_ENTRY * ) ellFirst( &handle->list ); -} - -/* - * Return pointer to last macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *last( MAC_HANDLE *handle ) -{ - return ( MAC_ENTRY * ) ellLast( &handle->list ); -} - -/* - * Return pointer to next macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *next( MAC_ENTRY *entry ) -{ - return ( MAC_ENTRY * ) ellNext( ( ELLNODE * ) entry ); -} - -/* - * Return pointer to previous macro entry (could be preprocessor macro) - */ -static MAC_ENTRY *previous( MAC_ENTRY *entry ) -{ - return ( MAC_ENTRY * ) ellPrevious( ( ELLNODE * ) entry ); -} - -/* - * Create new macro entry (can assume it doesn't exist) - */ -static MAC_ENTRY *create( MAC_HANDLE *handle, const char *name, int special ) -{ - ELLLIST *list = &handle->list; - MAC_ENTRY *entry = ( MAC_ENTRY * ) dbmfMalloc( sizeof( MAC_ENTRY ) ); - - if ( entry != NULL ) { - entry->name = Strdup( name ); - if ( entry->name == NULL ) { - dbmfFree( entry ); - entry = NULL; - } - else { - entry->type = ""; - entry->rawval = NULL; - entry->value = NULL; - entry->length = 0; - entry->error = FALSE; - entry->visited = FALSE; - entry->special = special; - entry->level = handle->level; - - ellAdd( list, ( ELLNODE * ) entry ); - } - } - - return entry; -} - -/* - * Look up macro entry with matching "special" attribute by name - */ -static MAC_ENTRY *lookup( MAC_HANDLE *handle, const char *name, int special ) -{ - MAC_ENTRY *entry; - - if ( handle->debug & 2 ) - printf( "lookup-> level = %d, name = %s, special = %d\n", - handle->level, name, special ); - - /* search backwards so scoping works */ - for ( entry = last( handle ); entry != NULL; entry = previous( entry ) ) { - if ( entry->special != special ) - continue; - if ( strcmp( name, entry->name ) == 0 ) - break; - } - if ( (special == FALSE) && (entry == NULL) && - (handle->flags & FLAG_USE_ENVIRONMENT) ) { - char *value = getenv(name); - if (value) { - entry = create( handle, name, FALSE ); - if ( entry ) { - entry->type = "environment variable"; - if ( rawval( handle, entry, value ) == NULL ) - entry = NULL; - } - } - } - - if ( handle->debug & 2 ) - printf( "<-lookup level = %d, name = %s, result = %p\n", - handle->level, name, entry ); - - return entry; -} - -/* - * Copy raw value to macro entry - */ -static char *rawval( MAC_HANDLE *handle, MAC_ENTRY *entry, const char *value ) -{ - if ( entry->rawval != NULL ) - dbmfFree( entry->rawval ); - entry->rawval = Strdup( value ); - - handle->dirty = TRUE; - - return entry->rawval; -} - -/* - * Delete a macro entry; requires re-expansion of macro values since this - * macro may be referenced by another one - */ -static void delete( MAC_HANDLE *handle, MAC_ENTRY *entry ) -{ - ELLLIST *list = &handle->list; - - ellDelete( list, ( ELLNODE * ) entry ); - - dbmfFree( entry->name ); - if ( entry->rawval != NULL ) - dbmfFree( entry->rawval ); - if ( entry->value != NULL ) - free( entry->value ); - dbmfFree( entry ); - - handle->dirty = TRUE; -} - -/* - * Expand macro definitions (expensive but done very infrequently) - */ -static long expand( MAC_HANDLE *handle ) -{ - MAC_ENTRY *entry; - const char *rawval; - char *value; - - if ( !handle->dirty ) - return 0; - - for ( entry = first( handle ); entry != NULL; entry = next( entry ) ) { - - if ( handle->debug & 2 ) - printf( "\nexpand %s = %s\n", entry->name, - entry->rawval ? entry->rawval : "" ); - - if ( entry->value == NULL ) { - if ( ( entry->value = malloc( MAC_SIZE + 1 ) ) == NULL ) { - return -1; - } - } - - /* start at level 1 so quotes and escapes will be removed from - expanded value */ - rawval = entry->rawval; - value = entry->value; - *value = '\0'; - entry->error = FALSE; - trans( handle, entry, 1, "", &rawval, &value, entry->value + MAC_SIZE ); - entry->length = value - entry->value; - entry->value[MAC_SIZE] = '\0'; - } - - handle->dirty = FALSE; - - return 0; -} - -/* - * Translate raw macro value (recursive). This is by far the most complicated - * of the macro routines and calls itself recursively both to translate any - * macros referenced in the name and to translate the resulting name - */ -static void trans( MAC_HANDLE *handle, MAC_ENTRY *entry, int level, - const char *term, const char **rawval, char **value, - char *valend ) -{ - char quote; - const char *r; - char *v; - int discard; - int macRef; - - /* return immediately if raw value is NULL */ - if ( *rawval == NULL ) return; - - /* discard quotes and escapes if level is > 0 (i.e. if these aren't - the user's quotes and escapes) */ - discard = ( level > 0 ); - - /* debug output */ - if ( handle->debug & 2 ) - printf( "trans-> entry = %p, level = %d, capacity = %u, discard = %s, " - "rawval = %s\n", entry, level, (unsigned int)(valend - *value), discard ? "T" : "F", *rawval ); - - /* initially not in quotes */ - quote = 0; - - /* scan characters until hit terminator or end of string */ - for ( r = *rawval, v = *value; strchr( term, *r ) == NULL; r++ ) { - - /* handle quoted characters (quotes are discarded if in name) */ - if ( quote ) { - if ( *r == quote ) { - quote = 0; - if ( discard ) continue; - } - } - else if ( *r == '"' || *r == '\'' ) { - quote = *r; - if ( discard ) continue; - } - - /* macro reference if '$' followed by '(' or '{' */ - macRef = ( *r == '$' && - *( r + 1 ) != '\0' && - strchr( "({", *( r + 1 ) ) != NULL ); - - /* macros are not expanded in single quotes */ - if ( macRef && quote != '\'' ) { - /* Handle macro reference */ - refer ( handle, entry, level, &r, &v, valend ); - } - - else { - /* handle escaped characters (escape is discarded if in name) */ - if ( *r == '\\' && *( r + 1 ) != '\0' ) { - if ( v < valend && !discard ) *v++ = '\\'; - if ( v < valend ) *v++ = *++r; - } - - /* copy character to output */ - else { - if ( v < valend ) *v++ = *r; - } - - /* ensure string remains properly terminated */ - if ( v <= valend ) *v = '\0'; - } - } - - /* debug output */ - if ( handle->debug & 2 ) - printf( "<-trans level = %d, length = %4u, value = %s\n", - level, (unsigned int)(v - *value), *value ); - - /* update pointers to next characters to scan in raw value and to fill - in in output value (if at end of input, step back so terminator is - still there to be seen) */ - *rawval = ( *r == '\0' ) ? r - 1 : r; - *value = v; - - return; -} - -/* - * Expand a macro reference, handling default values and defining scoped - * macros as encountered. This code used to part of trans(), but was - * pulled out for ease of understanding. - */ -static void refer ( MAC_HANDLE *handle, MAC_ENTRY *entry, int level, - const char **rawval, char **value, char *valend ) -{ - const char *r = *rawval; - char *v = *value; - char refname[MAC_SIZE + 1] = {'\0'}; - char *rn = refname; - MAC_ENTRY *refentry; - const char *defval = NULL; - const char *macEnd; - const char *errval = NULL; - int pop = FALSE; - - /* debug output */ - if ( handle->debug & 2 ) - printf( "refer-> entry = %p, level = %d, capacity = %u, rawval = %s\n", - entry, level, (unsigned int)(valend - *value), *rawval ); - - /* step over '$(' or '${' */ - r++; - macEnd = ( *r == '(' ) ? "=,)" : "=,}"; - r++; - - /* translate name (may contain macro references); truncated - quietly if too long but always guaranteed zero-terminated */ - trans( handle, entry, level + 1, macEnd, &r, &rn, rn + MAC_SIZE ); - refname[MAC_SIZE] = '\0'; - - /* Is there a default value? */ - if ( *r == '=' ) { - MAC_ENTRY dflt; - int flags = handle->flags; - handle->flags |= FLAG_SUPPRESS_WARNINGS; - - /* store its location in case we need it */ - defval = ++r; - - /* Find the end, discarding its value */ - dflt.name = refname; - dflt.type = "default value"; - dflt.error = FALSE; - trans( handle, &dflt, level + 1, macEnd+1, &r, &v, v); - - handle->flags = flags; - } - - /* extract and set values for any scoped macros */ - if ( *r == ',' ) { - MAC_ENTRY subs; - int flags = handle->flags; - handle->flags |= FLAG_SUPPRESS_WARNINGS; - - subs.type = "scoped macro"; - subs.error = FALSE; - - macPushScope( handle ); - pop = TRUE; - - while ( *r == ',' ) { - char subname[MAC_SIZE + 1] = {'\0'}; - char subval[MAC_SIZE + 1] = {'\0'}; - char *sn = subname; - char *sv = subval; - - /* translate the macro name */ - ++r; - subs.name = refname; - - trans( handle, &subs, level + 1, macEnd, &r, &sn, sn + MAC_SIZE ); - subname[MAC_SIZE] = '\0'; - - /* If it has a value, translate that and assign it */ - if ( *r == '=' ) { - ++r; - subs.name = subname; - - trans( handle, &subs, level + 1, macEnd+1, &r, &sv, - sv + MAC_SIZE); - subval[MAC_SIZE] = '\0'; - - macPutValue( handle, subname, subval ); - handle->dirty = TRUE; /* re-expand with new macro values */ - } - } - - handle->flags = flags; - } - - /* Now we can look up the translated name */ - refentry = lookup( handle, refname, FALSE ); - - if ( refentry ) { - if ( !refentry->visited ) { - /* reference is good, use it */ - if ( !handle->dirty ) { - /* copy the already-expanded value, merge any error status */ - cpy2val( refentry->value, &v, valend ); - entry->error = entry->error || refentry->error; - } else { - /* translate raw value */ - const char *rv = refentry->rawval; - refentry->visited = TRUE; - trans( handle, entry, level + 1, "", &rv, &v, valend ); - refentry->visited = FALSE; - } - goto cleanup; - } - /* reference is recursive */ - entry->error = TRUE; - errval = ",recursive)"; - if ( (handle->flags & FLAG_SUPPRESS_WARNINGS) == 0 ) { - errlogPrintf( "macLib: %s %s is recursive (expanding %s %s)\n", - entry->type, entry->name, - refentry->type, refentry->name ); - } - } else { - /* no macro found by this name */ - if ( defval ) { - /* there was a default value, translate that instead */ - trans( handle, entry, level + 1, macEnd+1, &defval, &v, valend ); - goto cleanup; - } - entry->error = TRUE; - errval = ",undefined)"; - if ( (handle->flags & FLAG_SUPPRESS_WARNINGS) == 0 ) { - errlogPrintf( "macLib: macro %s is undefined (expanding %s %s)\n", - refname, entry->type, entry->name ); - } - } - - /* Bad reference, insert $(name,errval) */ - if ( v < valend ) *v++ = '$'; - if ( v < valend ) *v++ = '('; - cpy2val( refname, &v, valend ); - cpy2val( errval, &v, valend ); - -cleanup: - if (pop) { - macPopScope( handle ); - } - - /* debug output */ - if ( handle->debug & 2 ) - printf( "<-refer level = %d, length = %4u, value = %s\n", - level, (unsigned int)(v - *value), *value ); - - *rawval = r; - *value = v; - return; -} - -/* - * Copy a string, honoring the 'end of destination string' pointer - * Returns with **value pointing to the '\0' terminator - */ -static void cpy2val(const char *src, char **value, char *valend) -{ - char *v = *value; - while ((v < valend) && (*v = *src++)) { v++; } - *v = '\0'; - *value = v; -} - -/* - * strdup() implementation which uses our own memory allocator - */ -static char *Strdup(const char *string ) -{ - char *copy = dbmfMalloc( strlen( string ) + 1 ); - - if ( copy != NULL ) - strcpy( copy, string ); - - return copy; -} - diff --git a/src/libCom/macLib/macEnv.c b/src/libCom/macLib/macEnv.c deleted file mode 100644 index f102748a8..000000000 --- a/src/libCom/macLib/macEnv.c +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Macro expansion of environment variables - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "errlog.h" -#include "epicsString.h" -#include "macLib.h" - -char * epicsShareAPI -macEnvExpand(const char *str) -{ - return macDefExpand(str, NULL); -} - -char * epicsShareAPI -macDefExpand(const char *str, MAC_HANDLE *macros) -{ - MAC_HANDLE *handle; - static const char * pairs[] = { "", "environ", NULL, NULL }; - long destCapacity = 128; - char *dest = NULL; - int n; - - if (macros) { - handle = macros; - } else { - if (macCreateHandle(&handle, pairs)){ - errlogMessage("macDefExpand: macCreateHandle failed."); - return NULL; - } - } - - do { - destCapacity *= 2; - /* - * Use free/malloc rather than realloc since there's no need to - * keep the original contents. - */ - free(dest); - dest = malloc(destCapacity); - if(!dest) - goto done; - - n = macExpandString(handle, str, dest, destCapacity); - } while (n >= (destCapacity - 1)); - - if (n < 0) { - free(dest); - dest = NULL; - } else { - size_t unused = destCapacity - ++n; - - if (unused >= 20) - dest = realloc(dest, n); - } - -done: - if (macros == NULL) { - if (macDeleteHandle(handle)) { - errlogMessage("macDefExpand: macDeleteHandle failed."); - } - } - return dest; -} diff --git a/src/libCom/macLib/macLib.h b/src/libCom/macLib/macLib.h deleted file mode 100644 index 14ecdaa3f..000000000 --- a/src/libCom/macLib/macLib.h +++ /dev/null @@ -1,164 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Definitions for macro substitution library (macLib) - * - * William Lupton, W. M. Keck Observatory - */ - -#ifndef INCmacLibH -#define INCmacLibH - -/* - * EPICS include files needed by this file - */ -#include "ellLib.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Maximum size of macro name or value string (simpler to make fixed) - */ -#define MAC_SIZE 256 - -/* - * Macro substitution context. One of these contexts is allocated each time - * macCreateHandle() is called - */ -typedef struct { - long magic; /* magic number (used for authentication) */ - int dirty; /* values need expanding from raw values? */ - int level; /* scoping level */ - int debug; /* debugging level */ - ELLLIST list; /* macro name / value list */ - int flags; /* operating mode flags */ -} MAC_HANDLE; - -/* - * Function prototypes (core library) - */ -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macCreateHandle( - MAC_HANDLE **handle, /* address of variable to receive pointer */ - /* to new macro substitution context */ - - const char * pairs[] /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -); - -epicsShareFunc void -epicsShareAPI macSuppressWarning( - MAC_HANDLE *handle, /* opaque handle */ - - int falseTrue /*0 means issue, 1 means suppress*/ -); - -epicsShareFunc long /* strlen(dest), <0 if any macros are */ - /* undefined */ -epicsShareAPI macExpandString( - MAC_HANDLE *handle, /* opaque handle */ - - const char *src, /* source string */ - - char *dest, /* destination string */ - - long capacity /* capacity of destination buffer (dest) */ -); - - -epicsShareFunc long /* strlen(value) */ -epicsShareAPI macPutValue( - MAC_HANDLE *handle, /* opaque handle */ - - const char *name, /* macro name */ - - const char *value /* macro value */ -); - -epicsShareFunc long /* strlen(value), <0 if undefined */ -epicsShareAPI macGetValue( - MAC_HANDLE *handle, /* opaque handle */ - - const char *name, /* macro name or reference */ - - char *value, /* string to receive macro value or name */ - /* argument if macro is undefined */ - - long capacity /* capacity of destination buffer (value) */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macDeleteHandle( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPushScope( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macPopScope( - MAC_HANDLE *handle /* opaque handle */ -); - -epicsShareFunc long /* 0 = OK; <0 = ERROR */ -epicsShareAPI macReportMacros( - MAC_HANDLE *handle /* opaque handle */ -); - -/* - * Function prototypes (utility library) - */ -epicsShareFunc long /* #defns encountered; <0 = ERROR */ -epicsShareAPI macParseDefns( - MAC_HANDLE *handle, /* opaque handle; can be NULL if default */ - /* special characters are to be used */ - - const char *defns, /* macro definitions in "a=xxx,b=yyy" */ - /* format */ - - char **pairs[] /* address of variable to receive pointer */ - /* to NULL-terminated array of {name, */ - /* value} pair strings; all storage is */ - /* allocated contiguously */ -); - -epicsShareFunc long /* #macros defined; <0 = ERROR */ -epicsShareAPI macInstallMacros( - MAC_HANDLE *handle, /* opaque handle */ - - char *pairs[] /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -); - -epicsShareFunc char * /* expanded string; NULL if any undefined macros */ -epicsShareAPI macEnvExpand( - const char *str /* string to be expanded */ -); - -epicsShareFunc char * /* expanded string; NULL if any undefined macros */ -epicsShareAPI macDefExpand( - const char *str, /* string to be expanded */ - MAC_HANDLE *macros /* opaque handle; can be NULL if default */ - /* special characters are to be used */ -); - -#ifdef __cplusplus -} -#endif - -#endif /*INCmacLibH*/ diff --git a/src/libCom/macLib/macLibNOTES b/src/libCom/macLib/macLibNOTES deleted file mode 100644 index fc3606254..000000000 --- a/src/libCom/macLib/macLibNOTES +++ /dev/null @@ -1,158 +0,0 @@ -# Test input file for macTest filter, doubling as notes on usage of the -# macro library. Some special strings at start of line are supported: -# -# 1. '#' indicates a comment and is ignored -# -# 2. '%set' is followed by "a=b, c=d" style macro definitions which are -# passed through macParseDefs() and macInstallMacros() -# -# 3. '%push' pushes a scoping level by calling macPushScope() -# -# 4. '%pop' pops a scoping level by calling macPopScope() -# -# 5. '%report' reports macro definitions by calling macReportMacros() -# -# 6. all other lines are expanded by callins macExpandString() -# -introduction ------------- - -See the README file for the library specification and see the header -comments of macCore.c (the core library) for notes on what has been -implemented. - -This file contains tutorial information and examples. It's the -best documentation that there is. - - -simple examples ---------------- - -To define the a, b, c and d macros to be 1, 2, 3 and 4 (note optional -white space is ignored around '=' and ',' characters): - -%set a=1, b=2, c = 3 , d = 4 - -These macros can be dereferenced using '$(xxx)' or '${xxx}' notation: -a = $(a), b = $(b), c = ${c}, d = ${d}. - -Macro values can reference other macros in an arbitrarily complex way. -The only current restrictions are that a macro name or value cannot -exceed 256 characters in length. This restriction could fairly easily -be lifted. - -Here's an example: - -%set x = ${$(y$(z))} - -If this is expanded now: $(x), it won't work because the other macros -aren't defined yet. So: - -%set cash=lucre, ywork=cash, z=work - -Now expansion yields "$(x)" (work -> ywork -> cash -> lucre). - -One can inadvertently set up circular references. For example: - -%set mac1=$(mac2), mac2=$(mac3), mac3=$(mac1) - -An attempt to dereference mac1 gives $(mac1). When a macro expansion -fails, the translation that failed is replaced with the text that could -not be expanded. - -You can get a report of current macro definitions by doing -%report - -The '*' character in the first column indicates a problem expanding that -macro. We'll get rid of these problem macros: -%set mac1, mac2, mac3 - -You can also push a new scoping level by doing -%push - -and pop back to it by doing -%pop - -For example: -%set level = 0 -%push -%set level = 1 -%push -%set level = 2 -%push -%set level = 3 -%report -Level is $(level) -%pop -Level is $(level) -%pop -Level is $(level) -%pop -Level is $(level) -%pop -(That last error was deliberate) - - -quote and escape handling -------------------------- - -Both single and double quotes are supported, as are escapes. Some of the -implications are quite subtle and some of the design choices made may not -meet with universal approval. The basic idea is that a string in which -macro references have been expanded should look like the source string -apart from the where macros have been expanded. This implies that quote -and escape characters should not be removed from the string. - -Single and double quotes are different in that (as in most shells), -macros are substituted within double quotes but not within single -quotes. Back quotes are not special characters. Missing quotes at the -end of a string are automatically and quietly supplied. - -We've already seen some examples but what happens here: $(x)? -Should not that have been expanded? Why wasn't it? The answer is given -later on. As a clue, this is: $(x). This isn't: $(x)! - -Characters may be escaped by preceding them with a \ (back slash). -Escapes work even within quotes, which is more like C than most shells. -Thus, '\'' works, and it doesn't with the C shell. - -Quotes and escapes can also be used in "a=b, c=d" style assignments -but they are not part of macro names. For example: - -%set \= = equal, \' = quote - -defines macros called "=" and "'", not "\=" and "\'". To reference -these macros, "$(=)" ('$(=)') works because "=" is not special in -this context. However the quote must be escaped because quotes are -always special, as in "$(\')" ('$(\')'). - - -miscellaneous notes -------------------- - -In the "a=b, c=d" strings that are parsed by macParseDefns(), a macro -can be set to an empty value by putting nothing after the equals -sign, as in - -%set empty = -resulting in empty = "$(empty)". Omitting the equal sign gives the -macro a NULL rather than empty value (with the result that the macro -is deleted since this is how macPutValue() interprets a NULL value), so - -%set empty -deletes the empty macro, as can be seen when we try to de-reference -it: $(empty). - -The only special characters in these "a=b, c=d" strings are "=", "," -and white space surrounding these characters (plus quotes and escapes -of course). This means that - -%set fred 2 -actually sets a macro called "fred 2" to a NULL value (i.e. it deletes -it if it existed). This is probably wrong and the space should be -taken as an implicit '='. However, to do this and still to support -ignored white space around '=' and ',' characters is a bigger change -than I am prepared to make at present. - -What was the problem expanding "$(x)" before? It was single quotes -from words like "wasn't"! Is this a problem or a feature? diff --git a/src/libCom/macLib/macLibREADME b/src/libCom/macLib/macLibREADME deleted file mode 100644 index f3cda53c2..000000000 --- a/src/libCom/macLib/macLibREADME +++ /dev/null @@ -1,177 +0,0 @@ -1. Macro substitution library ------------------------------ - -This library could be used directly by applications which need to -support macro substitution. It will be implemented on all platforms. - -1.1 Core library ----------------- - -The core library provides a minimal set of basic operations. Some -utility routines, described later, use core routines to provide a more -convenient interface for some purposes. - -a) long macCreateHandle( MAC_HANDLE **handle, char *pairs[] ); - void macSuppressWarning(MAC_HANDLE *handle,int falseTrue); - - Creates a new macro substitution context and returns an opaque handle - to that context. An application can, if it desires, have several - active contexts, although most will not. - - If desired, an initial set of macro definitions may be loaded - ("pairs" is set to NULL to avoid this). The definitions are in the - "standard" pairs format, as described under macParseDefns(). - - Note that MAC_HANDLE is a typedef for the context structure. The - opaque handle is of type "MAC_HANDLE *", which is a pointer to the - context structure. The memory for this context is allocated by this - routine. - - macSuppressWarning can be called to suppress the marning message - when macExpandString cant expand a macro. A non zero value will - suppress the messages. - - -c) long macGetValue ( MAC_HANDLE *handle, char *name, - char *value, long maxlen ); - - Returns up to maxlen characters of the value of macro "name". "value" - will be zero-terminated if the length of the value is less than - maxlen. The function value will be the number of characters copied to - "value" (see below for behavior if the macro is undefined). If maxlen - is zero, no characters will be copied to "value" (which can be NULL) - and the call can be used to check whether the macro is defined. Note - that truncation of the value is therefore not reported. Is this a - problem? - - If the macro is undefined, the macro reference will be returned in - the value string (if permitted by maxlen) and the function value will - be _minus_ the number of characters copied. Note that treatment of - maxlen is intended to be consistent with what people are used to with - strncpy(). - - If the value contains macro references then the references will be - expanded recursively. This expansion will detect a direct or indirect - self reference. - - Macro references begin with a "$" immediately followed by either a - "(" or a "{" character. The macro name comes next, and may optionally - be succeeded by an "=" and a default value, which will be returned if - the named macro is undefined at the moment of expansion. The reference - is terminated by the matching ")" or "}" character. - -d) long macPutValue( MAC_HANDLE *handle, char *name, char *value ); - - Sets the value of the macro "name". If "value" is NULL, it undefines - all instances of "name" at all scoping levels (it's not an error if - "name" is not defined in this case). Macros referenced by "value" - need not be defined at this point. - - The function returns the length of the value string. - -e) long macDeleteHandle( MAC_HANDLE *handle ); - - Marks a handle invalid, and frees all storage associated with it. - - Note that this does not free any strings into which macro values have - been returned. Macro values are always returned into strings which - were pre-allocated by the caller. - -f) long macPushScope( MAC_HANDLE *handle ); - - Marks the start of a new scoping level such that all definitions made - up until the next macPopScope() call will be lost on macPopScope() - and those current at macPushScope() will be re-instated. - -g) long macPopScope( MAC_HANDLE *handle ); - - See macPushScope. - -h) Error handling - - These routines conform to 0 (=OK) for success, -1 (=ERROR) for - failure, and small positive values for extra info. I contravened this - for macGetValue() and macExpandString() because I felt that it was - worth returning information both on success / failure and on value - length. - - Errors and warnings are reported using errlogPrintf(). - - - -1.2 Utility library -------------------- - -These are convenience functions. If other useful functions emerge during -implementation, the list may grow. - -a) macParseDefns( MAC_HANDLE *handle, char *defns, char **pairs[] ); - - This takes a set of macro definitions in "a=xxx,b=yyy" format and - converts them into an array of pointers to character strings which - are, in order, "first name", "first value", "second name", "second - value" etc. The array is terminated with two NULL pointers and all - storage is allocated contiguously so that it can be freed with a - single call to free(). - - This routine is independent of any handle and provides a generally - useful service which may be used elsewhere. Any macro references in - values are not expanded at this point since the referenced macros may - be defined or redefined before the macro actually has to be - translated. - - Shell-style escapes and quotes are supported, as are things like - "A=B,B=$(C$(A)),CA=CA,CB=CB" (sets B to "CB"). White space is - significant within values but ignored elsewhere (i.e. surrounding "=" - and "," characters). - - Probably noone will ever want to, but the special meanings of "$", - "{", "}", "(", ")", "=" and "," can all be changed via macPutXxxx() - calls. This routine does not have a handle argument, so they must be - changed globally for it to use the new definitions. Should it have a - handle argument? This makes it more of a pain to use but guarantees - that there will be no conflicts. I think it should really. - - The function value is the number of definitions encountered, or -1 if - the supplied string is invalid. - -b) long macInstallMacros( MAC_HANDLE *handle, char *pairs[] ); - - This takes an array of pairs as defined above and installs them as - definitions by calling macPutValue(). The pairs array is terminated - by a NULL pointer. - - The function value is the number of macros defined. - -c) long macExpandString( MAC_HANDLE *handle, char *src, - char *dest, long maxlen ); - - This operates on a string which may contain macro references. It - parses the string looking for such references and passes them to - macGetValue() for translation. It returns the expanded string in the - supplied argument. - - The function value is similar to that of macGetValue(). Its absolute - value is the number of characters copied. If negative, at least one - undefined macro has been left unexpanded. - -d) char *macEnvExpand( char *src ); - - This operates on a string which may contain macros defined by - environment variables. It parses the string looking for such - references and passes them to macGetValue() for translation. It uses - malloc() to allocate space for the expanded string and returns a - pointer to this null-terminated string. It returns NULL if the source - string contains any undefined references. - -e) char *macDefExpand( char *src, MAC_HANDLE *macros ); - - This operates in the same manner as macEnvExpand, but takes an - optional macro handle that can contain a set of macro definitions. - These macros are appended to the set of macros from environment - variables when expanding the string. - -f) long macReportMacros( MAC_HANDLE *handle ); - - This reports details of current definitions to standard output, and is - intended purely for debugging purposes. diff --git a/src/libCom/macLib/macUtil.c b/src/libCom/macLib/macUtil.c deleted file mode 100644 index 7bf73542e..000000000 --- a/src/libCom/macLib/macUtil.c +++ /dev/null @@ -1,284 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Implementation of utility macro substitution library (macLib) - * - * William Lupton, W. M. Keck Observatory - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "errlog.h" -#include "macLib.h" - -/* - * Parse macros definitions in "a=xxx,b=yyy" format and convert them to - * a contiguously allocated array pointers to names and values, and the - * name and value strings, terminated with two NULL pointers. Quotes - * and escapes are honored but only removed from macro names (not - * values) - */ -long /* #defns encountered; <0 = ERROR */ -epicsShareAPI macParseDefns( - MAC_HANDLE *handle, /* opaque handle; can be NULL if default */ - /* special characters are to be used */ - - const char *defns, /* macro definitions in "a=xxx,b=yyy" */ - /* format */ - - char **pairs[] ) /* address of variable to receive pointer */ - /* to NULL-terminated array of {name, */ - /* value} pair strings; all storage is */ - /* allocated contiguously */ -{ - static const size_t altNumMax = 4; - size_t numMax; - int i; - int num; - int quote; - int escape; - size_t nbytes; - const char **ptr; - const char **end; - int *del; - char *memCp, **memCpp; - const char *c; - char *s, *d, **p; - enum { preName, inName, preValue, inValue } state; - - /* debug output */ - if ( handle && (handle->debug & 1) ) - printf( "macParseDefns( %s )\n", defns ); - - /* allocate temporary pointer arrays; in worst case they need to have - as many entries as the length of the defns string */ - numMax = strlen( defns ); - if ( numMax < altNumMax ) - numMax = altNumMax; - ptr = (const char **) calloc( numMax, sizeof( char * ) ); - end = (const char **) calloc( numMax, sizeof( char * ) ); - del = (int *) calloc( numMax, sizeof( int ) ); - if ( ptr == NULL || end == NULL || del == NULL ) goto error; - - /* go through definitions, noting pointers to starts and ends of macro - names and values; honor quotes and escapes; ignore white space - around assignment and separator characters */ - num = 0; - del[0] = FALSE; - quote = 0; - state = preName; - for ( c = (const char *) defns; *c != '\0'; c++ ) { - - /* handle quotes */ - if ( quote ) - quote = ( *c == quote ) ? 0 : quote; - else if ( *c == '\'' || *c == '"' ) - quote = *c; - - /* handle escapes (pointer incremented below) */ - escape = ( *c == '\\' && *( c + 1 ) != '\0' ); - - switch ( state ) { - case preName: - if ( !quote && !escape && ( isspace( (int) *c ) || *c == ',' ) ) break; - ptr[num] = c; - state = inName; - /* fall through (may be empty name) */ - - case inName: - if ( quote || escape || ( *c != '=' && *c != ',' ) ) break; - end[num] = c; - while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - state = preValue; - if ( *c != ',' ) break; - del[num] = TRUE; - /* fall through (','; will delete) */ - - case preValue: - if ( !quote && !escape && isspace( (int) *c ) ) break; - ptr[num] = c; - state = inValue; - /* fall through (may be empty value) */ - - case inValue: - if ( quote || escape || *c != ',' ) break; - end[num] = c; - while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - state = preName; - break; - } - - /* if this was escape, increment pointer now (couldn't do - before because could have ignored escape at start of name - or value) */ - if ( escape ) c++; - } - - /* tidy up from state at end of string */ - switch ( state ) { - case preName: - break; - case inName: - end[num] = c; - while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = TRUE; - case preValue: - ptr[num] = c; - case inValue: - end[num] = c; - while ( end[num] > ptr[num] && isspace( (int) *( end[num] - 1 ) ) ) - end[num]--; - num++; - del[num] = FALSE; - } - - /* debug output */ - if ( handle != NULL && handle->debug & 4 ) - for ( i = 0; i < num; i += 2 ) - printf( "[%ld] %.*s = [%ld] %.*s (%s) (%s)\n", - (long) (end[i+0] - ptr[i+0]), (int) (end[i+0] - ptr[i+0]), ptr[i+0], - (long) (end[i+1] - ptr[i+1]), (int) (end[i+1] - ptr[i+1]), ptr[i+1], - del[i+0] ? "del" : "nodel", - del[i+1] ? "del" : "nodel" ); - - /* calculate how much memory to allocate: pointers followed by - strings */ - nbytes = ( num + 2 ) * sizeof( char * ); - for ( i = 0; i < num; i++ ) - nbytes += end[i] - ptr[i] + 1; - - /* allocate memory and set returned pairs pointer */ - memCp = malloc( nbytes ); - if ( memCp == NULL ) goto error; - memCpp = ( char ** ) memCp; - *pairs = memCpp; - - /* copy pointers and strings (memCpp accesses the pointer section - and memCp accesses the string section) */ - memCp += ( num + 2 ) * sizeof( char * ); - for ( i = 0; i < num; i++ ) { - - /* if no '=' followed the name, macro will be deleted */ - if ( del[i] ) - *memCpp++ = NULL; - else - *memCpp++ = memCp; - - /* copy value regardless of the above */ - strncpy( memCp, (const char *) ptr[i], end[i] - ptr[i] ); - memCp += end[i] - ptr[i]; - *memCp++ = '\0'; - } - - /* add two NULL pointers */ - *memCpp++ = NULL; - *memCpp++ = NULL; - - /* remove quotes and escapes from names in place (unlike values, they - will not be re-parsed) */ - for ( p = *pairs; *p != NULL; p += 2 ) { - quote = 0; - for ( s = d = *p; *s != '\0'; s++ ) { - - /* quotes are not copied */ - if ( quote ) { - if ( *s == quote ) { - quote = 0; - continue; - } - } - else if ( *s == '\'' || *s == '"' ) { - quote = *s; - continue; - } - - /* escapes are not copied but next character is */ - if ( *s == '\\' && *( s + 1 ) != '\0' ) - s++; - - /* others are copied */ - *d++ = *s; - } - - /* need to terminate destination */ - *d++ = '\0'; - } - - /* free workspace */ - free( ( void * ) ptr ); - free( ( void * ) end ); - free( ( char * ) del ); - - /* debug output */ - if ( handle != NULL && handle->debug & 1 ) - printf( "macParseDefns() -> %d\n", num / 2 ); - - /* success exit; return number of definitions */ - return num / 2; - - /* error exit */ -error: - errlogPrintf( "macParseDefns: failed to allocate memory\n" ); - if ( ptr != NULL ) free( ( void * ) ptr ); - if ( end != NULL ) free( ( void * ) end ); - if ( del != NULL ) free( ( char * ) del ); - *pairs = NULL; - return -1; -} - -/* - * Install an array of name / value pairs as macro definitions. The - * array should have an even number of elements followed by at least - * one (preferably two) NULL pointers - */ -long /* #macros defined; <0 = ERROR */ -epicsShareAPI macInstallMacros( - MAC_HANDLE *handle, /* opaque handle */ - - char *pairs[] ) /* pointer to NULL-terminated array of */ - /* {name,value} pair strings; a NULL */ - /* value implies undefined; a NULL */ - /* argument implies no macros */ -{ - int n; - char **p; - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macInstallMacros( %s, %s, ... )\n", - pairs && pairs[0] ? pairs[0] : "NULL", - pairs && pairs[1] ? pairs[1] : "NULL" ); - - /* go through array defining macros */ - for ( n = 0, p = pairs; p != NULL && p[0] != NULL; n++, p += 2 ) { - if ( macPutValue( handle, p[0], p[1] ) < 0 ) - return -1; - } - - /* debug output */ - if ( handle->debug & 1 ) - printf( "macInstallMacros() -> %d\n", n ); - - /* return number of macros defined */ - return n; -} - diff --git a/src/libCom/misc/Makefile b/src/libCom/misc/Makefile deleted file mode 100644 index 3d5412dc3..000000000 --- a/src/libCom/misc/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/misc - -INC += alarm.h -INC += alarmString.h -INC += adjustment.h -INC += cantProceed.h -INC += dbDefs.h -INC += epicsConvert.h -INC += epicsExit.h -INC += epicsStdlib.h -INC += epicsString.h -INC += epicsTypes.h -INC += shareLib.h -INC += epicsExport.h -INC += unixFileName.h -INC += locationException.h -INC += ipAddrToAsciiAsynchronous.h -INC += compilerDependencies.h -INC += epicsUnitTest.h -INC += testMain.h - -# epicsVersion.h is created by this Makefile -INC += epicsVersion.h - -Com_SRCS += alarmString.c -Com_SRCS += aToIPAddr.c -Com_SRCS += adjustment.c -Com_SRCS += cantProceed.c -Com_SRCS += epicsConvert.c -Com_SRCS += epicsExit.c -Com_SRCS += epicsStdlib.c -Com_SRCS += epicsString.c -Com_SRCS += truncateFile.c -Com_SRCS += ipAddrToAsciiAsynchronous.cpp -Com_SRCS += epicsUnitTest.c diff --git a/src/libCom/misc/RULES b/src/libCom/misc/RULES deleted file mode 100644 index 2ba358675..000000000 --- a/src/libCom/misc/RULES +++ /dev/null @@ -1,18 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -MAKEVERSION = $(LIBCOM)/misc/makeEpicsVersion.pl -MAKEVERSION_FLAGS = -o $(notdir $@) $(QUIET_FLAG) -MAKEVERSION_FLAGS += $(if $(EPICS_SITE_VERSION),-v "$(EPICS_SITE_VERSION)") - -$(COMMON_DIR)/epicsVersion.h: $(CONFIG)/CONFIG_BASE_VERSION \ - $(CONFIG)/CONFIG_SITE $(MAKEVERSION) - @$(RM) $(notdir $@) - $(PERL) $(MAKEVERSION) $(MAKEVERSION_FLAGS) $< - @$(MV) $(notdir $@) $@ diff --git a/src/libCom/misc/aToIPAddr.c b/src/libCom/misc/aToIPAddr.c deleted file mode 100644 index c21b574f6..000000000 --- a/src/libCom/misc/aToIPAddr.c +++ /dev/null @@ -1,193 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * rational replacement for inet_addr() - * - * author: Jeff Hill - */ -#include -#include - -#define epicsExportSharedSymbols -#include "epicsTypes.h" -#include "osiSock.h" - -#ifndef NELEMENTS -#define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) -#endif /*NELEMENTS*/ - -/* - * addrArrayToUL () - */ -static int addrArrayToUL ( const unsigned *pAddr, - unsigned nElements, struct in_addr *pIpAddr ) -{ - unsigned i; - epicsUInt32 addr = 0ul; - - for ( i=0u; i < nElements; i++ ) { - if ( pAddr[i] > 0xff ) { - return -1; - } - addr <<= 8; - addr |= ( epicsUInt32 ) pAddr[i]; - } - pIpAddr->s_addr = htonl ( addr ); - - return 0; -} - -/* - * initIPAddr() - * !! ipAddr should be passed in in network byte order !! - * !! port is passed in in host byte order !! - */ -static int initIPAddr ( struct in_addr ipAddr, unsigned port, - struct sockaddr_in *pIP ) -{ - if ( port > 0xffff ) { - return -1; - } - { - epicsUInt16 port_16 = (epicsUInt16) port; - memset (pIP, '\0', sizeof(*pIP)); - pIP->sin_family = AF_INET; - pIP->sin_port = htons(port_16); - pIP->sin_addr = ipAddr; - } - return 0; -} - -/* - * rational replacement for inet_addr() - * which allows the limited broadcast address - * 255.255.255.255, allows the user - * to specify a port number, and allows also a - * named host to be specified. - * - * Sets the port number to "defaultPort" only if - * "pAddrString" does not contain an address of the form - * "n.n.n.n:p or host:p" - */ -epicsShareFunc int epicsShareAPI -aToIPAddr( const char *pAddrString, unsigned short defaultPort, - struct sockaddr_in *pIP ) -{ - int status; - unsigned addr[4]; - unsigned long rawAddr; - /* - * !! change n elements here requires change in format below !! - */ - char hostName[512]; - char dummy[8]; - unsigned port; - struct in_addr ina; - - /* - * dotted ip addresses - */ - status = sscanf ( pAddrString, " %u . %u . %u . %u %7s ", - addr, addr+1u, addr+2u, addr+3u, dummy ); - if ( status == 4 ) { - if ( addrArrayToUL ( addr, NELEMENTS ( addr ), & ina ) < 0 ) { - return -1; - } - port = defaultPort; - return initIPAddr ( ina, port, pIP ); - } - - /* - * dotted ip addresses and port - */ - status = sscanf ( pAddrString, " %u . %u . %u . %u : %u %7s", - addr, addr+1u, addr+2u, addr+3u, &port, dummy ); - if ( status >= 5 ) { - if ( status > 5 ) { - /* - * valid at the start but detritus on the end - */ - return -1; - } - if ( addrArrayToUL ( addr, NELEMENTS ( addr ), &ina ) < 0 ) { - return -1; - } - return initIPAddr ( ina, port, pIP ); - } - - /* - * IP address as a raw number - */ - status = sscanf ( pAddrString, " %lu %7s ", &rawAddr, dummy ); - if ( status == 1 ) { - if ( rawAddr > 0xffffffff ) { - return -1; - } - port = defaultPort; - { - epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr; - ina.s_addr = htonl ( rawAddr_32 ); - return initIPAddr ( ina, port, pIP ); - } - } - - /* - * IP address as a raw number, and port - */ - status = sscanf ( pAddrString, " %lu : %u %7s ", &rawAddr, &port, dummy ); - if ( status >= 2 ) { - if ( status > 2 ) { - /* - * valid at the start but detritus on the end - */ - return -1; - } - if ( rawAddr > 0xffffffff ) { - return -1; - } - { - epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr; - ina.s_addr = htonl ( rawAddr_32 ); - return initIPAddr ( ina, port, pIP ); - } - } - - - /* - * host name string - */ - status = sscanf ( pAddrString, " %511[^:] %s ", hostName, dummy ); - if ( status == 1 ) { - port = defaultPort; - status = hostToIPAddr ( hostName, &ina ); - if ( status == 0 ) { - return initIPAddr ( ina, port, pIP ); - } - } - - /* - * host name string, and port - */ - status = sscanf ( pAddrString, " %511[^:] : %u %s ", hostName, - &port, dummy ); - if ( status >= 2 ) { - if ( status > 2 ) { - /* - * valid at the start but detritus on the end - */ - return -1; - } - status = hostToIPAddr ( hostName, &ina ); - if ( status == 0 ) { - return initIPAddr ( ina, port, pIP ); - } - } - - return -1; -} diff --git a/src/libCom/misc/adjustment.c b/src/libCom/misc/adjustment.c deleted file mode 100644 index ac10e28c9..000000000 --- a/src/libCom/misc/adjustment.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* src/libCom/adjustment.c */ - -/* Author: Peregrine McGehee */ - -#include -#include -#include - -/* Up to now epicsShareThings have been declared as imports - * (Appropriate for other stuff) - * After setting the following they will be declared as exports - * (Appropriate for what we implenment) - */ -#define epicsExportSharedSymbols -#include "adjustment.h" - -epicsShareFunc size_t adjustToWorstCaseAlignment(size_t size) -{ - int align_size, adjust; - struct test_long_word { char c; long lw; }; - struct test_double { char c; double d; }; - struct test_ptr { char c; void *p; }; - int test_long_size = sizeof(struct test_long_word) - sizeof(long); - int test_double_size = sizeof(struct test_double) - sizeof(double); - int test_ptr_size = sizeof(struct test_ptr) - sizeof(void *); - size_t adjusted_size = size; - - /* - * Use Jeff's alignment tests to determine worst case of long, - * double or pointer alignment requirements. - */ - align_size = test_long_size > test_ptr_size ? - test_long_size : test_ptr_size; - - align_size = align_size > test_double_size ? - align_size : test_double_size; - - /* - * Increase the size to fit worst case alignment if not already - * properly aligned. - */ - adjust = align_size - size%align_size; - if (adjust != align_size) adjusted_size += adjust; - - return (adjusted_size); -} diff --git a/src/libCom/misc/adjustment.h b/src/libCom/misc/adjustment.h deleted file mode 100644 index 3f152039f..000000000 --- a/src/libCom/misc/adjustment.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* src/libCom/adjustment.h */ - -#ifndef INCadjustmenth -#define INCadjustmenth -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc size_t adjustToWorstCaseAlignment(size_t size); - -#ifdef __cplusplus -} -#endif - - -#endif /*INCadjustmenth*/ - diff --git a/src/libCom/misc/alarm.h b/src/libCom/misc/alarm.h deleted file mode 100644 index 58e2b7313..000000000 --- a/src/libCom/misc/alarm.h +++ /dev/null @@ -1,108 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Alarm definitions, must match menuAlarmSevr.dbd and menuAlarmStat.dbd */ - -/* - * Authors: Bob Dalesio and Marty Kraimer - * Date: 11-7-90 - */ - -#ifndef INC_alarm_H -#define INC_alarm_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#define NO_ALARM 0 - -/* ALARM SEVERITIES - must match menuAlarmSevr.dbd */ - -typedef enum { - epicsSevNone = NO_ALARM, - epicsSevMinor, - epicsSevMajor, - epicsSevInvalid, - ALARM_NSEV -} epicsAlarmSeverity; - -#define firstEpicsAlarmSev epicsSevNone -#define MINOR_ALARM epicsSevMinor -#define MAJOR_ALARM epicsSevMajor -#define INVALID_ALARM epicsSevInvalid -#define lastEpicsAlarmSev epicsSevInvalid - - -/* ALARM STATUS - must match menuAlarmStat.dbd */ - -typedef enum { - epicsAlarmNone = NO_ALARM, - epicsAlarmRead, - epicsAlarmWrite, - epicsAlarmHiHi, - epicsAlarmHigh, - epicsAlarmLoLo, - epicsAlarmLow, - epicsAlarmState, - epicsAlarmCos, - epicsAlarmComm, - epicsAlarmTimeout, - epicsAlarmHwLimit, - epicsAlarmCalc, - epicsAlarmScan, - epicsAlarmLink, - epicsAlarmSoft, - epicsAlarmBadSub, - epicsAlarmUDF, - epicsAlarmDisable, - epicsAlarmSimm, - epicsAlarmReadAccess, - epicsAlarmWriteAccess, - ALARM_NSTATUS -} epicsAlarmCondition; - -#define firstEpicsAlarmCond epicsAlarmNone -#define READ_ALARM epicsAlarmRead -#define WRITE_ALARM epicsAlarmWrite -#define HIHI_ALARM epicsAlarmHiHi -#define HIGH_ALARM epicsAlarmHigh -#define LOLO_ALARM epicsAlarmLoLo -#define LOW_ALARM epicsAlarmLow -#define STATE_ALARM epicsAlarmState -#define COS_ALARM epicsAlarmCos -#define COMM_ALARM epicsAlarmComm -#define TIMEOUT_ALARM epicsAlarmTimeout -#define HW_LIMIT_ALARM epicsAlarmHwLimit -#define CALC_ALARM epicsAlarmCalc -#define SCAN_ALARM epicsAlarmScan -#define LINK_ALARM epicsAlarmLink -#define SOFT_ALARM epicsAlarmSoft -#define BAD_SUB_ALARM epicsAlarmBadSub -#define UDF_ALARM epicsAlarmUDF -#define DISABLE_ALARM epicsAlarmDisable -#define SIMM_ALARM epicsAlarmSimm -#define READ_ACCESS_ALARM epicsAlarmReadAccess -#define WRITE_ACCESS_ALARM epicsAlarmWriteAccess -#define lastEpicsAlarmCond epicsAlarmWriteAccess - - -/* Name string arrays */ - -epicsShareExtern const char *epicsAlarmSeverityStrings [ALARM_NSEV]; -epicsShareExtern const char *epicsAlarmConditionStrings [ALARM_NSTATUS]; - - -#ifdef __cplusplus -} -#endif - -#endif /* INC_alarm_H */ diff --git a/src/libCom/misc/alarmString.c b/src/libCom/misc/alarmString.c deleted file mode 100644 index 4db179dcb..000000000 --- a/src/libCom/misc/alarmString.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* String names for alarm status and severity values */ - -#define epicsExportSharedSymbols -#include "alarm.h" - -/* ALARM SEVERITIES - must match menuAlarmSevr.dbd and alarm.h */ - -epicsShareDef const char * epicsAlarmSeverityStrings[ALARM_NSEV] = { - "NO_ALARM", - "MINOR", - "MAJOR", - "INVALID" -}; - - -/* ALARM STATUS - must match menuAlarmStat.dbd and alarm.h */ - -epicsShareDef const char * epicsAlarmConditionStrings[ALARM_NSTATUS] = { - "NO_ALARM", - "READ", - "WRITE", - "HIHI", - "HIGH", - "LOLO", - "LOW", - "STATE", - "COS", - "COMM", - "TIMEOUT", - "HWLIMIT", - "CALC", - "SCAN", - "LINK", - "SOFT", - "BAD_SUB", - "UDF", - "DISABLE", - "SIMM", - "READ_ACCESS", - "WRITE_ACCESS" -}; diff --git a/src/libCom/misc/alarmString.h b/src/libCom/misc/alarmString.h deleted file mode 100644 index ab320f058..000000000 --- a/src/libCom/misc/alarmString.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This file is deprecated, use alarm.h instead. - * - * Old string names for alarm status and severity values - */ - -#ifndef INC_alarmString_H -#define INC_alarmString_H - -#include "alarm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Old versions of alarmString.h defined these names: */ - -#define alarmSeverityString epicsAlarmSeverityStrings -#define alarmStatusString epicsAlarmConditionStrings - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/misc/cantProceed.c b/src/libCom/misc/cantProceed.c deleted file mode 100644 index 6c35796fd..000000000 --- a/src/libCom/misc/cantProceed.c +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 04JAN99 */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "errlog.h" -#include "cantProceed.h" -#include "epicsThread.h" -#include "epicsStackTrace.h" - -epicsShareFunc void * callocMustSucceed(size_t count, size_t size, const char *msg) -{ - void * mem = NULL; - if (count > 0 && size > 0) { - while ((mem = calloc(count, size)) == NULL) { - errlogPrintf("%s: callocMustSucceed(%lu, %lu) - calloc failed\n", - msg, (unsigned long)count, (unsigned long)size); - errlogPrintf("Thread %s (%p) suspending.\n", - epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf()); - errlogFlush(); - epicsThreadSuspendSelf(); - } - } - return mem; -} - -epicsShareFunc void * mallocMustSucceed(size_t size, const char *msg) -{ - void * mem = NULL; - if (size > 0) { - while ((mem = malloc(size)) == NULL) { - errlogPrintf("%s: mallocMustSucceed(%lu) - malloc failed\n", - msg, (unsigned long)size); - errlogPrintf("Thread %s (%p) suspending.\n", - epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf()); - errlogFlush(); - epicsThreadSuspendSelf(); - } - } - return mem; -} - -epicsShareFunc void cantProceed(const char *msg, ...) -{ - va_list pvar; - va_start(pvar, msg); - if (msg) - errlogVprintf(msg, pvar); - va_end(pvar); - - errlogPrintf("Thread %s (%p) can't proceed, suspending.\n", - epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf()); - - epicsStackTrace(); - - errlogFlush(); - - epicsThreadSleep(1.0); - while (1) - epicsThreadSuspendSelf(); -} diff --git a/src/libCom/misc/cantProceed.h b/src/libCom/misc/cantProceed.h deleted file mode 100644 index 437f96802..000000000 --- a/src/libCom/misc/cantProceed.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INCcantProceedh -#define INCcantProceedh - -#include - -#include "compilerDependencies.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void cantProceed(const char *errorMessage, ...) EPICS_PRINTF_STYLE(1,2); -epicsShareFunc void * callocMustSucceed(size_t count, size_t size, const char *errorMessage); -epicsShareFunc void * mallocMustSucceed(size_t size, const char *errorMessage); - -#ifdef __cplusplus -} -#endif - -#endif /* cantProceedh */ diff --git a/src/libCom/misc/dbDefs.h b/src/libCom/misc/dbDefs.h deleted file mode 100644 index e1de3f200..000000000 --- a/src/libCom/misc/dbDefs.h +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Marty Kraimer - * Date: 6-1-90 - */ - -#ifndef INC_dbDefs_H -#define INC_dbDefs_H - -#include - -#ifdef TRUE -# undef TRUE -#endif -#define TRUE 1 - -#ifdef FALSE -# undef FALSE -#endif -#define FALSE 0 - -/* deprecated, use static */ -#ifndef LOCAL -# define LOCAL static -#endif - -/* number of elements in an array */ -#ifndef NELEMENTS -# define NELEMENTS(array) (sizeof (array) / sizeof ((array) [0])) -#endif - -/* byte offset of member in structure - deprecated, use offsetof */ -#ifndef OFFSET -# define OFFSET(structure, member) offsetof(structure, member) -#endif - -/* Subtract member byte offset, returning pointer to parent object */ -#ifndef CONTAINER -# ifdef __GNUC__ -# define CONTAINER(ptr, structure, member) ({ \ - const __typeof(((structure*)0)->member) *_ptr = (ptr); \ - (structure*)((char*)_ptr - offsetof(structure, member)); \ - }) -# else -# define CONTAINER(ptr, structure, member) \ - ((structure*)((char*)(ptr) - offsetof(structure, member))) -# endif -#endif - -/*Process Variable Name Size */ -/* PVNAME_STRINGSZ includes the nil terminator */ -#define PVNAME_STRINGSZ 61 -#define PVNAME_SZ (PVNAME_STRINGSZ - 1) - -/* Buffer size for the string representation of a DBF_*LINK field */ -#define PVLINK_STRINGSZ 1024 - -/* dbAccess enums/menus can have up to this many choices */ -#define DB_MAX_CHOICES 30 - -#endif /* INC_dbDefs_H */ diff --git a/src/libCom/misc/epicsConvert.c b/src/libCom/misc/epicsConvert.c deleted file mode 100644 index 9318ceb7e..000000000 --- a/src/libCom/misc/epicsConvert.c +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsConvert.c*/ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMath.h" -#include "epicsConvert.h" -#include "cantProceed.h" - -epicsShareFunc float epicsConvertDoubleToFloat(double value) -{ - double abs; - - if (value == 0 || !finite(value)) - return (float) value; - - abs = fabs(value); - - if (abs >= FLT_MAX) - return (value > 0) ? FLT_MAX : -FLT_MAX; - - if (abs <= FLT_MIN) - return (value > 0) ? FLT_MIN : -FLT_MIN; - - return (float) value; -} diff --git a/src/libCom/misc/epicsConvert.h b/src/libCom/misc/epicsConvert.h deleted file mode 100644 index 1c38bc30a..000000000 --- a/src/libCom/misc/epicsConvert.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsConvert.h*/ - -#ifndef INC_epicsConvert_H -#define INC_epicsConvert_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc float epicsConvertDoubleToFloat(double value); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsConvert_H */ diff --git a/src/libCom/misc/epicsExit.c b/src/libCom/misc/epicsExit.c deleted file mode 100644 index 266835eaa..000000000 --- a/src/libCom/misc/epicsExit.c +++ /dev/null @@ -1,212 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsExit.c*/ -/* - * Author: Marty Kraimer - * Date: 23AUG2004 - * Thread exit revisions: Jeff Hill - * Date: 06Dec2006 - * - * Note that epicsExitCallAtThreadExits is currently called directly from the - * thread entry wrapper in OS dependent code. That approach might not work - * correctly if the thread exits indirectly instead of just returning from - * the function specified to epicsThreadCreate. For example the thread might - * exit via the exit() call. There might be OS dependent solutions for that - * weakness. - * - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "ellLib.h" -#include "errlog.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "cantProceed.h" -#include "epicsExit.h" - -void epicsMutexCleanup(void); - -typedef struct exitNode { - ELLNODE node; - epicsExitFunc func; - void *arg; - char name[1]; -}exitNode; - -typedef struct exitPvt { - ELLLIST list; -} exitPvt; - -int atExitDebug = 0; - -static epicsThreadOnceId exitPvtOnce = EPICS_THREAD_ONCE_INIT; -static epicsThreadOnceId exitLaterOnce = EPICS_THREAD_ONCE_INIT; -static exitPvt * pExitPvtPerProcess = 0; -static epicsMutexId exitPvtLock = 0; -static epicsThreadPrivateId exitPvtPerThread = 0; - -static int exitLaterStatus; - -static void destroyExitPvt(exitPvt * pep) -{ - ellFree ( &pep->list ); - free ( pep ); -} - -static exitPvt * createExitPvt(void) -{ - exitPvt * pep = calloc ( 1, sizeof ( * pep ) ); - if ( pep ) { - ellInit ( &pep->list ); - } - return pep; -} - -static void exitPvtOnceFunc(void *pParm) -{ - exitPvtPerThread = epicsThreadPrivateCreate (); - assert ( exitPvtPerThread ); - exitPvtLock = epicsMutexMustCreate (); -} - -static void epicsExitInit(void) -{ - epicsThreadOnce ( & exitPvtOnce, exitPvtOnceFunc, 0 ); -} - -static void epicsExitCallAtExitsPvt(exitPvt *pep) -{ - exitNode *pexitNode; - - while ( ( pexitNode = (exitNode *) ellLast ( & pep->list ) ) ) { - if (atExitDebug && pexitNode->name[0]) - fprintf(stderr, "atExit %s(%p)\n", pexitNode->name, pexitNode->arg); - else if(atExitDebug) - fprintf(stderr, "atExit %p(%p)\n", pexitNode->func, pexitNode->arg); - pexitNode->func ( pexitNode->arg ); - ellDelete ( & pep->list, & pexitNode->node ); - free ( pexitNode ); - } -} - -epicsShareFunc void epicsExitCallAtExits(void) -{ - exitPvt * pep = 0; - - epicsExitInit (); - epicsMutexMustLock ( exitPvtLock ); - if ( pExitPvtPerProcess ) { - pep = pExitPvtPerProcess; - pExitPvtPerProcess = 0; - } - epicsMutexUnlock ( exitPvtLock ); - if ( pep ) { - epicsExitCallAtExitsPvt ( pep ); - destroyExitPvt ( pep ); - } - /* Handle specially to avoid circular reference */ - epicsMutexCleanup(); -} - -epicsShareFunc void epicsExitCallAtThreadExits(void) -{ - exitPvt * pep; - - epicsExitInit (); - pep = epicsThreadPrivateGet ( exitPvtPerThread ); - if ( pep ) { - epicsExitCallAtExitsPvt ( pep ); - destroyExitPvt ( pep ); - epicsThreadPrivateSet ( exitPvtPerThread, 0 ); - } -} - -static int epicsAtExitPvt(exitPvt *pep, epicsExitFunc func, void *arg, const char *name) -{ - int status = -1; - exitNode * pExitNode = calloc ( 1, sizeof( *pExitNode ) + (name?strlen(name):0) ); - - if ( pExitNode ) { - pExitNode->func = func; - pExitNode->arg = arg; - if(name) - strcpy(pExitNode->name, name); - ellAdd ( & pep->list, & pExitNode->node ); - status = 0; - } - return status; -} - -epicsShareFunc int epicsAtThreadExit(epicsExitFunc func, void *arg) -{ - exitPvt * pep; - - epicsExitInit (); - pep = epicsThreadPrivateGet ( exitPvtPerThread ); - if ( ! pep ) { - pep = createExitPvt (); - if ( ! pep ) { - return -1; - } - epicsThreadPrivateSet ( exitPvtPerThread, pep ); - } - return epicsAtExitPvt ( pep, func, arg, NULL ); -} - -epicsShareFunc int epicsAtExit3(epicsExitFunc func, void *arg, const char* name) -{ - int status = -1; - - epicsExitInit (); - epicsMutexMustLock ( exitPvtLock ); - if ( !pExitPvtPerProcess ) { - pExitPvtPerProcess = createExitPvt (); - } - if ( pExitPvtPerProcess ) { - status = epicsAtExitPvt ( pExitPvtPerProcess, func, arg, name ); - } - epicsMutexUnlock ( exitPvtLock ); - return status; -} - -epicsShareFunc void epicsExit(int status) -{ - epicsExitCallAtExits(); - epicsThreadSleep(0.1); - exit(status); -} - -static void exitNow(void *junk) -{ - epicsExit(exitLaterStatus); -} - -static void exitLaterOnceFunc(void *raw) -{ - int *status = raw; - exitLaterStatus = *status; - epicsThreadMustCreate("exitLater", - epicsThreadPriorityLow, - epicsThreadGetStackSize(epicsThreadStackSmall), - &exitNow, NULL); -} - -epicsShareFunc void epicsExitLater(int status) -{ - epicsThreadOnce(&exitLaterOnce, &exitLaterOnceFunc, &status); -} - -#include "epicsExport.h" - -epicsExportAddress(int,atExitDebug); diff --git a/src/libCom/misc/epicsExit.h b/src/libCom/misc/epicsExit.h deleted file mode 100644 index 3e961cbc1..000000000 --- a/src/libCom/misc/epicsExit.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/*epicsExit.h*/ -#ifndef epicsExith -#define epicsExith -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*epicsExitFunc)(void *arg); - -epicsShareFunc void epicsExit(int status); -epicsShareFunc void epicsExitLater(int status); -epicsShareFunc void epicsExitCallAtExits(void); -epicsShareFunc int epicsAtExit3(epicsExitFunc func, void *arg, const char* name); -#define epicsAtExit(F,A) epicsAtExit3(F,A,#F) - -epicsShareFunc void epicsExitCallAtThreadExits(void); -epicsShareFunc int epicsAtThreadExit(epicsExitFunc func, void *arg); - - -#ifdef __cplusplus -} -#endif - -#endif /*epicsExith*/ diff --git a/src/libCom/misc/epicsExport.h b/src/libCom/misc/epicsExport.h deleted file mode 100644 index dea8dd67a..000000000 --- a/src/libCom/misc/epicsExport.h +++ /dev/null @@ -1,43 +0,0 @@ -/*epicsExport.h */ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INCepicsExporth -#define INCepicsExporth - -#ifdef __cplusplus -extern "C" { -#endif - -#define epicsExportSharedSymbols -#include - -typedef void (*REGISTRAR)(void); - -#define EPICS_EXPORT_POBJ(typ,obj) pvar_ ## typ ## _ ## obj -#define EPICS_EXPORT_PFUNC(obj) pvar_func_ ## obj - -#define epicsExportAddress(typ,obj) \ -epicsShareExtern typ *EPICS_EXPORT_POBJ(typ,obj); \ -epicsShareDef typ *EPICS_EXPORT_POBJ(typ,obj) = (typ *)(char *)&obj - -#define epicsExportRegistrar(func) \ -epicsShareFunc REGISTRAR EPICS_EXPORT_PFUNC(func) = (REGISTRAR)(void*)&func - -#define epicsRegisterFunction(func) \ -static void register_func_ ## func(void) { \ - registryFunctionAdd(#func,(REGISTRYFUNCTION)func);} \ -epicsExportRegistrar(register_func_ ## func) - -#ifdef __cplusplus -} -#endif - -#endif /* epicsExporth */ diff --git a/src/libCom/misc/epicsStdlib.c b/src/libCom/misc/epicsStdlib.c deleted file mode 100644 index f4348981b..000000000 --- a/src/libCom/misc/epicsStdlib.c +++ /dev/null @@ -1,401 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonna LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Authors: Eric Norum & Andrew Johnson */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMath.h" -#include "epicsStdlib.h" -#include "epicsString.h" -#include "epicsConvert.h" - - -/* These are the conversion primitives */ - -epicsShareFunc int -epicsParseLong(const char *str, long *to, int base, char **units) -{ - int c; - char *endp; - long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtol(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -epicsShareFunc int -epicsParseULong(const char *str, unsigned long *to, int base, char **units) -{ - int c; - char *endp; - unsigned long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtoul(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -epicsShareFunc int -epicsParseLLong(const char *str, long long *to, int base, char **units) -{ - int c; - char *endp; - long long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtoll(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -epicsShareFunc int -epicsParseULLong(const char *str, unsigned long long *to, int base, char **units) -{ - int c; - char *endp; - unsigned long long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtoull(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -epicsShareFunc int -epicsParseDouble(const char *str, double *to, char **units) -{ - int c; - char *endp; - double value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = epicsStrtod(str, &endp); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == ERANGE) - return (value == 0) ? S_stdlib_underflow : S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - - -/* These call the primitives */ - -epicsShareFunc int -epicsParseInt8(const char *str, epicsInt8 *to, int base, char **units) -{ - long value; - int status = epicsParseLong(str, &value, base, units); - - if (status) - return status; - - if (value < -0x80 || value > 0x7f) - return S_stdlib_overflow; - - *to = (epicsInt8) value; - return 0; -} - -epicsShareFunc int -epicsParseUInt8(const char *str, epicsUInt8 *to, int base, char **units) -{ - unsigned long value; - int status = epicsParseULong(str, &value, base, units); - - if (status) - return status; - - if (value > 0xff && value <= ~0xffUL) - return S_stdlib_overflow; - - *to = (epicsUInt8) value; - return 0; -} - -epicsShareFunc int -epicsParseInt16(const char *str, epicsInt16 *to, int base, char **units) -{ - long value; - int status = epicsParseLong(str, &value, base, units); - - if (status) - return status; - - if (value < -0x8000 || value > 0x7fff) - return S_stdlib_overflow; - - *to = (epicsInt16) value; - return 0; -} - -epicsShareFunc int -epicsParseUInt16(const char *str, epicsUInt16 *to, int base, char **units) -{ - unsigned long value; - int status = epicsParseULong(str, &value, base, units); - - if (status) - return status; - - if (value > 0xffff && value <= ~0xffffUL) - return S_stdlib_overflow; - - *to = (epicsUInt16) value; - return 0; -} - -epicsShareFunc int -epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units) -{ - long value; - int status = epicsParseLong(str, &value, base, units); - - if (status) - return status; - -#if (LONG_MAX > 0x7fffffffLL) - if (value < -0x80000000L || value > 0x7fffffffL) - return S_stdlib_overflow; -#endif - - *to = (epicsInt32) value; - return 0; -} - -epicsShareFunc int -epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units) -{ - unsigned long value; - int status = epicsParseULong(str, &value, base, units); - - if (status) - return status; - -#if (ULONG_MAX > 0xffffffffULL) - if (value > 0xffffffffUL && value <= ~0xffffffffUL) - return S_stdlib_overflow; -#endif - - *to = (epicsUInt32) value; - return 0; -} - -epicsShareFunc int -epicsParseInt64(const char *str, epicsInt64 *to, int base, char **units) -{ -#if (LONG_MAX == 0x7fffffffffffffffLL) - long value; - int status = epicsParseLong(str, &value, base, units); -#else - long long value; - int status = epicsParseLLong(str, &value, base, units); -#endif - - if (status) - return status; - - *to = (epicsInt64) value; - return 0; -} - -epicsShareFunc int -epicsParseUInt64(const char *str, epicsUInt64 *to, int base, char **units) -{ -#if (ULONG_MAX == 0xffffffffffffffffULL) - unsigned long value; - int status = epicsParseULong(str, &value, base, units); -#else - unsigned long long value; - int status = epicsParseULLong(str, &value, base, units); -#endif - - if (status) - return status; - - *to = (epicsUInt64) value; - return 0; -} - - -epicsShareFunc int -epicsParseFloat(const char *str, float *to, char **units) -{ - double value, abs; - int status = epicsParseDouble(str, &value, units); - - if (status) - return status; - - abs = fabs(value); - if (value > 0 && abs <= FLT_MIN) - return S_stdlib_underflow; - if (finite(value) && abs >= FLT_MAX) - return S_stdlib_overflow; - - *to = (float) value; - return 0; -} - - -/* If strtod() works properly, the OS-specific osdStrtod.h does: - * #define epicsStrtod strtod - * - * If strtod() is broken, osdStrtod.h defines this prototype: - * epicsShareFunc double epicsStrtod(const char *str, char **endp); - */ - -#ifndef epicsStrtod -epicsShareFunc double -epicsStrtod(const char *str, char **endp) -{ - const char *cp = str; - int negative = 0; - double res; - - while (isspace((int)*cp)) - cp++; - - if (*cp == '+') { - cp++; - } else if (*cp == '-') { - negative = 1; - cp++; - } - - if (epicsStrnCaseCmp("0x", cp, 2) == 0) { - if (negative) - return strtol(str, endp, 16); - else - return strtoul(str, endp, 16); - } - if (!isalpha((int)*cp)) { - res = strtod(str, endp); - if (isinf(res)) - errno = ERANGE; - return res; - } - - if (epicsStrnCaseCmp("NAN", cp, 3) == 0) { - res = epicsNAN; - cp += 3; - if (*cp == '(') { - cp++; - while (*cp && (*cp++ != ')')) - continue; - } - } - else if (epicsStrnCaseCmp("INF", cp, 3) == 0) { - res = negative ? -epicsINF : epicsINF; - cp += 3; - if (epicsStrnCaseCmp("INITY", cp, 5) == 0) { - cp += 5; - } - } else { - cp = str; - res = 0; - } - - if (endp) - *endp = (char *)cp; - - return res; -} -#endif diff --git a/src/libCom/misc/epicsStdlib.h b/src/libCom/misc/epicsStdlib.h deleted file mode 100644 index 20b7cd26f..000000000 --- a/src/libCom/misc/epicsStdlib.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsStdlib.h */ -/* Author: Eric Norum */ - -#ifndef INC_epicsStdlib_H -#define INC_epicsStdlib_H - -#include -#include - -#include "shareLib.h" -#include "osdStrtod.h" -#include "epicsTypes.h" -#include "errMdef.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define S_stdlib_noConversion (M_stdlib | 1) /* No digits to convert */ -#define S_stdlib_extraneous (M_stdlib | 2) /* Extraneous characters */ -#define S_stdlib_underflow (M_stdlib | 3) /* Too small to represent */ -#define S_stdlib_overflow (M_stdlib | 4) /* Too large to represent */ -#define S_stdlib_badBase (M_stdlib | 5) /* Number base not supported */ - - -epicsShareFunc int - epicsParseLong(const char *str, long *to, int base, char **units); -epicsShareFunc int - epicsParseULong(const char *str, unsigned long *to, int base, char **units); -epicsShareFunc int - epicsParseLLong(const char *str, long long *to, int base, char **units); -epicsShareFunc int - epicsParseULLong(const char *str, unsigned long long *to, int base, char **units); -epicsShareFunc int - epicsParseDouble(const char *str, double *to, char **units); - -epicsShareFunc int - epicsParseFloat(const char *str, float *to, char **units); - -epicsShareFunc int - epicsParseInt8(const char *str, epicsInt8 *to, int base, char **units); -epicsShareFunc int - epicsParseUInt8(const char *str, epicsUInt8 *to, int base, char **units); -epicsShareFunc int - epicsParseInt16(const char *str, epicsInt16 *to, int base, char **units); -epicsShareFunc int - epicsParseUInt16(const char *str, epicsUInt16 *to, int base, char **units); - -epicsShareFunc int - epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units); -epicsShareFunc int - epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units); - -epicsShareFunc int - epicsParseInt64(const char *str, epicsInt64 *to, int base, char **units); -epicsShareFunc int - epicsParseUInt64(const char *str, epicsUInt64 *to, int base, char **units); - -#define epicsParseFloat32(str, to, units) epicsParseFloat(str, to, units) -#define epicsParseFloat64(str, to, units) epicsParseDouble(str, to, units) - -/* These macros return 1 if successful, 0 on failure. - * This is analagous to the return value from sscanf() - */ -#define epicsScanLong(str, to, base) (!epicsParseLong(str, to, base, NULL)) -#define epicsScanULong(str, to, base) (!epicsParseULong(str, to, base, NULL)) -#define epicsScanLLong(str, to, base) (!epicsParseLLong(str, to, base, NULL)) -#define epicsScanULLong(str, to, base) (!epicsParseULLong(str, to, base, NULL)) -#define epicsScanFloat(str, to) (!epicsParseFloat(str, to, NULL)) -#define epicsScanDouble(str, to) (!epicsParseDouble(str, to, NULL)) - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsStdlib_H */ diff --git a/src/libCom/misc/epicsString.c b/src/libCom/misc/epicsString.c deleted file mode 100644 index e41e21b72..000000000 --- a/src/libCom/misc/epicsString.c +++ /dev/null @@ -1,380 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Authors: Jun-ichi Odagiri, Marty Kraimer, Eric Norum, - * Mark Rivers, Andrew Johnson, Ralph Lange - * - * Routines in this file should have corresponding test code in - * libCom/test/epicsStringTest.c - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "cantProceed.h" -#include "epicsString.h" - -/* Deprecated, use epicsStrnRawFromEscaped() instead */ -int dbTranslateEscape(char *dst, const char *src) -{ - size_t big_enough = strlen(src) + 1; - - return epicsStrnRawFromEscaped(dst, big_enough, src, big_enough); -} - -int epicsStrnRawFromEscaped(char *dst, size_t dstlen, const char *src, - size_t srclen) -{ - int rem = dstlen; - int ndst = 0; - - while (srclen--) { - int c = *src++; - #define OUT(chr) if (--rem > 0) ndst++, *dst++ = chr - - if (!c) break; - - input: - if (c != '\\') { - OUT(c); - continue; - } - - if (!srclen-- || !(c = *src++)) break; - - switch (c) { - case 'a': OUT('\a'); break; - case 'b': OUT('\b'); break; - case 'f': OUT('\f'); break; - case 'n': OUT('\n'); break; - case 'r': OUT('\r'); break; - case 't': OUT('\t'); break; - case 'v': OUT('\v'); break; - case '\\': OUT('\\'); break; - case '\'': OUT('\''); break; - case '\"': OUT('\"'); break; - - case '0' :case '1' :case '2' :case '3' : - case '4' :case '5' :case '6' :case '7' : - { /* \ooo */ - unsigned int u = c - '0'; - - if (!srclen-- || !(c = *src++)) { - OUT(u); goto done; - } - if (c < '0' || c > '7') { - OUT(u); goto input; - } - u = u << 3 | (c - '0'); - - if (!srclen-- || !(c = *src++)) { - OUT(u); goto done; - } - if (c < '0' || c > '7') { - OUT(u); goto input; - } - u = u << 3 | (c - '0'); - - if (u > 0377) { - /* Undefined behaviour! */ - } - OUT(u); - } - break; - - case 'x' : - { /* \xXXX... */ - unsigned int u = 0; - - if (!srclen-- || !(c = *src++ & 0xff)) - goto done; - - while (isxdigit(c)) { - u = u << 4 | ((c > '9') ? toupper(c) - 'A' + 10 : c - '0'); - if (u > 0xff) { - /* Undefined behaviour! */ - } - if (!srclen-- || !(c = *src++ & 0xff)) { - OUT(u); - goto done; - } - } - OUT(u); - goto input; - } - - default: - OUT(c); - } - #undef OUT - } -done: - if (dstlen) - *dst = '\0'; - return ndst; -} - -int epicsStrnEscapedFromRaw(char *dst, size_t dstlen, const char *src, - size_t srclen) -{ - int rem = dstlen; - int ndst = 0; - - if (dst == src) - return -1; - - while (srclen--) { - int c = *src++; - #define OUT(chr) ndst++; if (--rem > 0) *dst++ = chr - - switch (c) { - case '\a': OUT('\\'); OUT('a'); break; - case '\b': OUT('\\'); OUT('b'); break; - case '\f': OUT('\\'); OUT('f'); break; - case '\n': OUT('\\'); OUT('n'); break; - case '\r': OUT('\\'); OUT('r'); break; - case '\t': OUT('\\'); OUT('t'); break; - case '\v': OUT('\\'); OUT('v'); break; - case '\\': OUT('\\'); OUT('\\'); break; - case '\'': OUT('\\'); OUT('\''); break; - case '\"': OUT('\\'); OUT('\"'); break; - default: - if (isprint(c & 0xff)) { - OUT(c); - break; - } - OUT('\\'); - OUT('0' + ((c & 0300) >> 6)); - OUT('0' + ((c & 0070) >> 3)); - OUT('0' + (c & 0007)); - } - #undef OUT - } - if (dstlen) - *dst = '\0'; - return ndst; -} - -size_t epicsStrnEscapedFromRawSize(const char *src, size_t srclen) -{ - size_t ndst = srclen; - - while (srclen--) { - int c = *src++; - - switch (c) { - case '\a': case '\b': case '\f': case '\n': - case '\r': case '\t': case '\v': case '\\': - case '\'': case '\"': - ndst++; - break; - default: - if (!isprint(c & 0xff)) - ndst += 3; - } - } - return ndst; -} - -int epicsStrCaseCmp(const char *s1, const char *s2) -{ - while (1) { - int ch1 = toupper((int) *s1); - int ch2 = toupper((int) *s2); - - if (ch2 == 0) return (ch1 != 0); - if (ch1 == 0) return -1; - if (ch1 < ch2) return -1; - if (ch1 > ch2) return 1; - s1++; - s2++; - } -} - -int epicsStrnCaseCmp(const char *s1, const char *s2, size_t len) -{ - size_t i = 0; - - while (i++ < len) { - int ch1 = toupper((int) *s1); - int ch2 = toupper((int) *s2); - - if (ch2 == 0) return (ch1 != 0); - if (ch1 == 0) return -1; - if (ch1 < ch2) return -1; - if (ch1 > ch2) return 1; - s1++; - s2++; - } - return 0; -} - -char * epicsStrnDup(const char *s, size_t len) -{ - char *buf = mallocMustSucceed(len + 1, "epicsStrnDup"); - - strncpy(buf, s, len); - buf[len] = '\0'; - return buf; -} - -char * epicsStrDup(const char *s) -{ - return strcpy(mallocMustSucceed(strlen(s)+1, "epicsStrDup"), s); -} - -int epicsStrPrintEscaped(FILE *fp, const char *s, size_t len) -{ - int nout = 0; - - while (len--) { - char c = *s++; - - switch (c) { - case '\a': nout += fprintf(fp, "\\a"); break; - case '\b': nout += fprintf(fp, "\\b"); break; - case '\f': nout += fprintf(fp, "\\f"); break; - case '\n': nout += fprintf(fp, "\\n"); break; - case '\r': nout += fprintf(fp, "\\r"); break; - case '\t': nout += fprintf(fp, "\\t"); break; - case '\v': nout += fprintf(fp, "\\v"); break; - case '\\': nout += fprintf(fp, "\\\\"); break; - case '\'': nout += fprintf(fp, "\\'"); break; - case '\"': nout += fprintf(fp, "\\\""); break; - default: - if (isprint(0xff & (int)c)) - nout += fprintf(fp, "%c", c); - else - nout += fprintf(fp, "\\%03o", (unsigned char)c); - break; - } - } - return nout; -} - -/* Until Base requires POSIX 2008 we must provide our own implementation */ -size_t epicsStrnLen(const char *s, size_t maxlen) -{ - size_t i; - - for (i=0; i> 5)); - if (!(c = *str++)) break; - hash ^= (hash << 7) ^ c ^ (hash >> 3); - } - return hash; -} - -unsigned int epicsMemHash(const char *str, size_t length, unsigned int seed) -{ - unsigned int hash = seed; - - while (length--) { - hash ^= ~((hash << 11) ^ *str++ ^ (hash >> 5)); - if (!length--) break; - hash ^= (hash << 7) ^ *str++ ^ (hash >> 3); - } - return hash; -} diff --git a/src/libCom/misc/epicsString.h b/src/libCom/misc/epicsString.h deleted file mode 100644 index 093c73df4..000000000 --- a/src/libCom/misc/epicsString.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Authors: Jun-ichi Odagiri, Marty Kraimer, Eric Norum, - * Mark Rivers, Andrew Johnson, Ralph Lange - */ - -#ifndef INC_epicsString_H -#define INC_epicsString_H - -#include -#include "epicsTypes.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int epicsStrnRawFromEscaped(char *outbuf, size_t outsize, - const char *inbuf, size_t inlen); -epicsShareFunc int epicsStrnEscapedFromRaw(char *outbuf, size_t outsize, - const char *inbuf, size_t inlen); -epicsShareFunc size_t epicsStrnEscapedFromRawSize(const char *buf, size_t len); -epicsShareFunc int epicsStrCaseCmp(const char *s1, const char *s2); -epicsShareFunc int epicsStrnCaseCmp(const char *s1, const char *s2, size_t len); -epicsShareFunc char * epicsStrDup(const char *s); -epicsShareFunc char * epicsStrnDup(const char *s, size_t len); -epicsShareFunc int epicsStrPrintEscaped(FILE *fp, const char *s, size_t n); -#define epicsStrSnPrintEscaped epicsStrnEscapedFromRaw -epicsShareFunc size_t epicsStrnLen(const char *s, size_t maxlen); -epicsShareFunc int epicsStrGlobMatch(const char *str, const char *pattern); -epicsShareFunc char * epicsStrtok_r(char *s, const char *delim, char **lasts); -epicsShareFunc unsigned int epicsStrHash(const char *str, unsigned int seed); -epicsShareFunc unsigned int epicsMemHash(const char *str, size_t length, - unsigned int seed); - -/* dbTranslateEscape is deprecated, use epicsStrnRawFromEscaped instead */ -epicsShareFunc int dbTranslateEscape(char *s, const char *ct); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsString_H */ diff --git a/src/libCom/misc/epicsTypes.h b/src/libCom/misc/epicsTypes.h deleted file mode 100644 index efc6a91cb..000000000 --- a/src/libCom/misc/epicsTypes.h +++ /dev/null @@ -1,231 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - * Date: 5-95 - */ - -#ifndef INC_epicsTypes_H -#define INC_epicsTypes_H - -#include "shareLib.h" -#include "compilerDependencies.h" - -#ifndef stringOf -# if defined (__STDC__ ) || defined (__cplusplus) -# define stringOf(TOKEN) #TOKEN -# else -# define stringOf(TOKEN) "TOKEN" -# endif -#endif - -typedef enum { - epicsFalse = 0, - epicsTrue = 1 -} epicsBoolean EPICS_DEPRECATED; - -/* - * Architecture Independent Data Types - * These are sufficient for all our current archs - */ -typedef char epicsInt8; -typedef unsigned char epicsUInt8; -typedef short epicsInt16; -typedef unsigned short epicsUInt16; -typedef int epicsInt32; -typedef unsigned int epicsUInt32; -typedef long long epicsInt64; -typedef unsigned long long epicsUInt64; - -typedef epicsUInt16 epicsEnum16; -typedef float epicsFloat32; -typedef double epicsFloat64; -typedef epicsInt32 epicsStatus; - - -typedef struct { - unsigned length; - char *pString; -} epicsString; - -/* - * !! Dont use this - it may vanish in the future !! - * - * Provided only for backwards compatibility with - * db_access.h - * - */ -#define MAX_STRING_SIZE 40 -typedef char epicsOldString[MAX_STRING_SIZE]; - -/* - * union of all types - * - * Strings included here as pointers only so that we support - * large string types. - * - * Arrays included here as pointers because large arrays will - * not fit in this union. - */ -typedef union epics_any { - epicsInt8 int8; - epicsUInt8 uInt8; - epicsInt16 int16; - epicsUInt16 uInt16; - epicsEnum16 enum16; - epicsInt32 int32; - epicsUInt32 uInt32; - epicsInt64 int64; - epicsUInt64 uInt64; - epicsFloat32 float32; - epicsFloat64 float64; - epicsString string; -} epicsAny; - -/* - * Corresponding Type Codes - * (this enum must start at zero) - * - * !! Update epicsTypeToDBR_XXXX[] and DBR_XXXXToEpicsType - * in db_access.h if you edit this enum !! - */ -typedef enum { - epicsInt8T, - epicsUInt8T, - epicsInt16T, - epicsUInt16T, - epicsEnum16T, - epicsInt32T, - epicsUInt32T, - epicsFloat32T, - epicsFloat64T, - epicsStringT, - epicsOldStringT -} epicsType; -#define firstEpicsType epicsInt8T -#define lastEpicsType epicsOldStringT -#define validEpicsType(x) ((x>=firstEpicsType) && (x<=lastEpicsType)) -#define invalidEpicsType(x) ((xlastEpicsType)) - - -/* - * The enumeration "epicsType" is an index to this array - * of type name strings. - */ -#ifdef epicsTypesGLOBAL -epicsShareDef const char *epicsTypeNames [lastEpicsType+1] = { - "epicsInt8", - "epicsUInt8", - "epicsInt16", - "epicsUInt16", - "epicsEnum16", - "epicsInt32", - "epicsUInt32", - "epicsFloat32", - "epicsFloat64", - "epicsString", - "epicsOldString", -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const char *epicsTypeNames [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -/* - * The enumeration "epicsType" is an index to this array - * of type code name strings. - */ -#ifdef epicsTypesGLOBAL -epicsShareDef const char *epicsTypeCodeNames [lastEpicsType+1] = { - "epicsInt8T", - "epicsUInt8T", - "epicsInt16T", - "epicsUInt16T", - "epicsEnum16T", - "epicsInt32T", - "epicsUInt32T", - "epicsFloat32T", - "epicsFloat64T", - "epicsStringT", - "epicsOldStringT", -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const char *epicsTypeCodeNames [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -#ifdef epicsTypesGLOBAL -epicsShareDef const unsigned epicsTypeSizes [lastEpicsType+1] = { - sizeof (epicsInt8), - sizeof (epicsUInt8), - sizeof (epicsInt16), - sizeof (epicsUInt16), - sizeof (epicsEnum16), - sizeof (epicsInt32), - sizeof (epicsUInt32), - sizeof (epicsFloat32), - sizeof (epicsFloat64), - sizeof (epicsString), - sizeof (epicsOldString), -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const unsigned epicsTypeSizes [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -/* - * The enumeration "epicsType" is an index to this array - * of type class identifiers. - */ -typedef enum { - epicsIntC, - epicsUIntC, - epicsEnumC, - epicsFloatC, - epicsStringC, - epicsOldStringC -} epicsTypeClass; - -#ifdef epicsTypesGLOBAL -epicsShareDef const epicsTypeClass epicsTypeClasses [lastEpicsType+1] = { - epicsIntC, - epicsUIntC, - epicsIntC, - epicsUIntC, - epicsEnumC, - epicsIntC, - epicsUIntC, - epicsFloatC, - epicsFloatC, - epicsStringC, - epicsOldStringC -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const epicsTypeClass epicsTypeClasses [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - - -#ifdef epicsTypesGLOBAL -epicsShareDef const char *epicsTypeAnyFieldName [lastEpicsType+1] = { - "int8", - "uInt8", - "int16", - "uInt16", - "enum16", - "int32", - "uInt32", - "float32", - "float64", - "string", - "", /* Old Style Strings will not be in epicsAny type */ -}; -#else /* epicsTypesGLOBAL */ -epicsShareExtern const char *epicsTypeAnyFieldName [lastEpicsType+1]; -#endif /* epicsTypesGLOBAL */ - -#endif /* INC_epicsTypes_H */ - diff --git a/src/libCom/misc/epicsUnitTest.c b/src/libCom/misc/epicsUnitTest.c deleted file mode 100644 index 4ac18ea1c..000000000 --- a/src/libCom/misc/epicsUnitTest.c +++ /dev/null @@ -1,264 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - * - * Unit test module which generates output in the Test Anything Protocol - * format. See perldoc Test::Harness for details of output format. - * - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsUnitTest.h" -#include "epicsExit.h" -#include "epicsTime.h" -#include "ellLib.h" -#include "errlog.h" -#include "cantProceed.h" - -typedef struct { - ELLNODE node; - const char *name; - int tests; - int failures; - int skips; -} testFailure; - -static epicsMutexId testLock = 0; -static int perlHarness; -static int planned; -static int tested; -static int passed; -static int failed; -static int skipped; -static int bonus; -static const char *todo; - -epicsTimeStamp started; -static int Harness; -static int Programs; -static int Tests; - -ELLLIST faults; -const char *testing = NULL; - -static epicsThreadOnceId onceFlag = EPICS_THREAD_ONCE_INIT; - -static void testOnce(void *dummy) { - testLock = epicsMutexMustCreate(); - perlHarness = (getenv("HARNESS_ACTIVE") != NULL); -} - -void testPlan(int plan) { - epicsThreadOnce(&onceFlag, testOnce, NULL); - epicsMutexMustLock(testLock); - planned = plan; - tested = passed = failed = skipped = bonus = 0; - todo = NULL; - if (plan) printf("1..%d\n", plan); - epicsMutexUnlock(testLock); -} - -int testOkV(int pass, const char *fmt, va_list pvar) { - const char *result = "not ok"; - epicsMutexMustLock(testLock); - tested++; - if (pass) { - result += 4; /* skip "not " */ - passed++; - if (todo) - bonus++; - } else { - if (todo) - passed++; - else - failed++; - } - printf("%s %2d - ", result, tested); - vprintf(fmt, pvar); - if (todo) - printf(" # TODO %s", todo); - putchar('\n'); - fflush(stdout); - epicsMutexUnlock(testLock); - return pass; -} - -int testOk(int pass, const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - testOkV(pass, fmt, pvar); - va_end(pvar); - return pass; -} - -void testPass(const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - testOkV(1, fmt, pvar); - va_end(pvar); -} - -void testFail(const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - testOkV(0, fmt, pvar); - va_end(pvar); -} - -void testSkip(int skip, const char *why) { - epicsMutexMustLock(testLock); - while (skip-- > 0) { - tested++; - passed++; - skipped++; - printf("ok %2d # SKIP %s\n", tested, why); - } - fflush(stdout); - epicsMutexUnlock(testLock); -} - -void testTodoBegin(const char *why) { - epicsMutexMustLock(testLock); - todo = why; - epicsMutexUnlock(testLock); -} - -void testTodoEnd(void) { - todo = NULL; -} - -int testDiag(const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - epicsMutexMustLock(testLock); - printf("# "); - vprintf(fmt, pvar); - putchar('\n'); - fflush(stdout); - epicsMutexUnlock(testLock); - va_end(pvar); - return 0; -} - -void testAbort(const char *fmt, ...) { - va_list pvar; - va_start(pvar, fmt); - printf("Bail out! "); - vprintf(fmt, pvar); - putchar('\n'); - fflush(stdout); - va_end(pvar); - abort(); -} - -static void testResult(const char *result, int count) { - printf("%12.12s: %3d = %5.2f%%\n", result, count, 100.0 * count / tested); -} - -int testDone(void) { - int status = 0; - - epicsMutexMustLock(testLock); - if (perlHarness) { - if (!planned) printf("1..%d\n", tested); - } else { - if (planned && tested > planned) { - printf("\nRan %d tests but only planned for %d!\n", tested, planned); - status = 2; - } else if (planned && tested < planned) { - printf("\nPlanned %d tests but only ran %d\n", planned, tested); - status = 2; - } - printf("\n Results\n =======\n Tests: %-3d\n", tested); - if (tested) { - testResult("Passed", passed); - if (bonus) testResult("Todo Passes", bonus); - if (failed) { - testResult("Failed", failed); - status = 1; - } - if (skipped) testResult("Skipped", skipped); - } - } - if (Harness) { - if (failed) { - testFailure *fault = callocMustSucceed(1, sizeof(testFailure), - "testDone calloc"); - fault->name = testing; - fault->tests = tested; - fault->failures = failed; - fault->skips = skipped; - ellAdd(&faults, &fault->node); - } - Programs++; - Tests += tested; - } - epicsMutexUnlock(testLock); - return (status); -} - - -/* Our test harness, for RTEMS and vxWorks */ - -void testHarnessExit(void *dummy) { - epicsTimeStamp ended; - int Faulty; - - if (!Harness) return; - - epicsTimeGetCurrent(&ended); - - printf("\n\n EPICS Test Harness Results" - "\n ==========================\n\n"); - - Faulty = ellCount(&faults); - if (!Faulty) - printf("All tests successful.\n"); - else { - int Failures = 0; - testFailure *f; - - printf("Failing Program Tests Faults\n" - "---------------------------------------\n"); - while ((f = (testFailure *)ellGet(&faults))) { - Failures += f->failures; - printf("%-25s %5d %5d\n", f->name, f->tests, f->failures); - if (f->skips) - printf("%d subtests skipped\n", f->skips); - free(f); - } - printf("\nFailed %d/%d test programs. %d/%d subtests failed.\n", - Faulty, Programs, Failures, Tests); - } - - printf("Programs=%d, Tests=%d, %.0f wallclock secs\n\n", - Programs, Tests, epicsTimeDiffInSeconds(&ended, &started)); -} - -void testHarness(void) { - epicsThreadOnce(&onceFlag, testOnce, NULL); - epicsAtExit(testHarnessExit, NULL); - Harness = 1; - Programs = 0; - Tests = 0; - ellInit(&faults); - epicsTimeGetCurrent(&started); -} - -void runTestFunc(const char *name, TESTFUNC func) { - printf("\n***** %s *****\n", name); - testing = name; - func(); /* May not return */ - epicsThreadSleep(1.0); -} diff --git a/src/libCom/misc/epicsUnitTest.h b/src/libCom/misc/epicsUnitTest.h deleted file mode 100644 index 9a119ad22..000000000 --- a/src/libCom/misc/epicsUnitTest.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - */ - -#ifndef INC_epicsUnitTest_H -#define INC_epicsUnitTest_H - -#include - -#include "compilerDependencies.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void testPlan(int tests); -epicsShareFunc int testOkV(int pass, const char *fmt, va_list pvar); -epicsShareFunc int testOk(int pass, const char *fmt, ...) - EPICS_PRINTF_STYLE(2, 3); -epicsShareFunc void testPass(const char *fmt, ...) - EPICS_PRINTF_STYLE(1, 2); -epicsShareFunc void testFail(const char *fmt, ...) - EPICS_PRINTF_STYLE(1, 2); -epicsShareFunc void testSkip(int skip, const char *why); -epicsShareFunc void testTodoBegin(const char *why); -epicsShareFunc void testTodoEnd(void); -epicsShareFunc int testDiag(const char *fmt, ...) - EPICS_PRINTF_STYLE(1, 2); -epicsShareFunc void testAbort(const char *fmt, ...) - EPICS_PRINTF_STYLE(1, 2); -epicsShareFunc int testDone(void); - -#define testOk1(cond) testOk(cond, "%s", #cond) - - -typedef int (*TESTFUNC)(void); -epicsShareFunc void testHarness(void); -epicsShareFunc void testHarnessExit(void *dummy); -epicsShareFunc void runTestFunc(const char *name, TESTFUNC func); - -#define runTest(func) runTestFunc(#func, func) -#define testHarnessDone() testHarnessExit(0) - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsUnitTest_H */ diff --git a/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp b/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp deleted file mode 100644 index 4301612c9..000000000 --- a/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp +++ /dev/null @@ -1,473 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#include -#include -#include -#include - -//#define EPICS_FREELIST_DEBUG -#define EPICS_PRIVATE_API - -#define epicsExportSharedSymbols -#include "ipAddrToAsciiAsynchronous.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsGuard.h" -#include "epicsExit.h" -#include "tsDLList.h" -#include "tsFreeList.h" -#include "errlog.h" - -// - this class implements the asynchronous DNS query -// - it completes early with the host name in dotted IP address form -// if the ipAddrToAsciiEngine is destroyed before IO completion -// or if there are too many items already in the engine's queue. -class ipAddrToAsciiTransactionPrivate : - public ipAddrToAsciiTransaction, - public tsDLNode < ipAddrToAsciiTransactionPrivate > { -public: - ipAddrToAsciiTransactionPrivate ( class ipAddrToAsciiEnginePrivate & engineIn ); - virtual ~ipAddrToAsciiTransactionPrivate (); - osiSockAddr address () const; - void show ( unsigned level ) const; - void * operator new ( size_t size, tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > & ); - epicsPlacementDeleteOperator (( void *, tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > & )) - osiSockAddr addr; - ipAddrToAsciiEnginePrivate & engine; - ipAddrToAsciiCallBack * pCB; - bool pending; - void ipAddrToAscii ( const osiSockAddr &, ipAddrToAsciiCallBack & ); - void release (); - void operator delete ( void * ); -private: - ipAddrToAsciiTransactionPrivate & operator = ( const ipAddrToAsciiTransactionPrivate & ); - ipAddrToAsciiTransactionPrivate ( const ipAddrToAsciiTransactionPrivate & ); -}; - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 >; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -extern "C" { -static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * ); -} - -namespace { -struct ipAddrToAsciiGlobal : public epicsThreadRunable { - ipAddrToAsciiGlobal(); - virtual ~ipAddrToAsciiGlobal() {} - - virtual void run (); - - char nameTmp [1024]; - tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > - transactionFreeList; - tsDLList < ipAddrToAsciiTransactionPrivate > labor; - mutable epicsMutex mutex; - epicsEvent laborEvent; - epicsEvent destructorBlockEvent; - epicsThread thread; - // pCurrent may be changed by any thread (worker or other) - ipAddrToAsciiTransactionPrivate * pCurrent; - // pActive may only be changed by the worker - ipAddrToAsciiTransactionPrivate * pActive; - unsigned cancelPendingCount; - bool exitFlag; - bool callbackInProgress; -}; -} - -// - this class executes the synchronous DNS query -// - it creates one thread -class ipAddrToAsciiEnginePrivate : - public ipAddrToAsciiEngine { -public: - ipAddrToAsciiEnginePrivate() :refcount(1u), released(false) {} - virtual ~ipAddrToAsciiEnginePrivate () {} - void show ( unsigned level ) const; - - unsigned refcount; - bool released; - - static ipAddrToAsciiGlobal * pEngine; - ipAddrToAsciiTransaction & createTransaction (); - void release (); - -private: - ipAddrToAsciiEnginePrivate ( const ipAddrToAsciiEngine & ); - ipAddrToAsciiEnginePrivate & operator = ( const ipAddrToAsciiEngine & ); -}; - -ipAddrToAsciiGlobal * ipAddrToAsciiEnginePrivate :: pEngine = 0; -static epicsThreadOnceId ipAddrToAsciiEngineGlobalMutexOnceFlag = EPICS_THREAD_ONCE_INIT; - -// the users are not required to supply a show routine -// for there transaction callback class -void ipAddrToAsciiCallBack::show ( unsigned /* level */ ) const {} - -// some noop pure virtual destructures -ipAddrToAsciiCallBack::~ipAddrToAsciiCallBack () {} -ipAddrToAsciiTransaction::~ipAddrToAsciiTransaction () {} -ipAddrToAsciiEngine::~ipAddrToAsciiEngine () {} - -static void ipAddrToAsciiEngineGlobalMutexConstruct ( void * ) -{ - try { - ipAddrToAsciiEnginePrivate::pEngine = new ipAddrToAsciiGlobal (); - } catch (std::exception& e) { - errlogPrintf("ipAddrToAsciiEnginePrivate ctor fails with: %s\n", e.what()); - } -} - -void ipAddrToAsciiEngine::cleanup() -{ - { - epicsGuard G(ipAddrToAsciiEnginePrivate::pEngine->mutex); - ipAddrToAsciiEnginePrivate::pEngine->exitFlag = true; - } - ipAddrToAsciiEnginePrivate::pEngine->laborEvent.signal(); - ipAddrToAsciiEnginePrivate::pEngine->thread.exitWait(); - delete ipAddrToAsciiEnginePrivate::pEngine; - ipAddrToAsciiEnginePrivate::pEngine = 0; -} - -// for now its probably sufficent to allocate one -// DNS transaction thread for all codes sharing -// the same process that need DNS services but we -// leave our options open for the future -ipAddrToAsciiEngine & ipAddrToAsciiEngine::allocate () -{ - epicsThreadOnce ( - & ipAddrToAsciiEngineGlobalMutexOnceFlag, - ipAddrToAsciiEngineGlobalMutexConstruct, 0 ); - if(!ipAddrToAsciiEnginePrivate::pEngine) - throw std::runtime_error("ipAddrToAsciiEngine::allocate fails"); - return * new ipAddrToAsciiEnginePrivate(); -} - -ipAddrToAsciiGlobal::ipAddrToAsciiGlobal () : - thread ( *this, "ipToAsciiProxy", - epicsThreadGetStackSize(epicsThreadStackBig), - epicsThreadPriorityLow ), - pCurrent ( 0 ), pActive ( 0 ), cancelPendingCount ( 0u ), exitFlag ( false ), - callbackInProgress ( false ) -{ - this->thread.start (); // start the thread -} - - -void ipAddrToAsciiEnginePrivate::release () -{ - bool last; - { - epicsGuard < epicsMutex > guard ( this->pEngine->mutex ); - if(released) - throw std::logic_error("Engine release() called again!"); - - // released==true prevents new transactions - released = true; - - { - // cancel any pending transactions - tsDLIter < ipAddrToAsciiTransactionPrivate > it(pEngine->labor.firstIter()); - while(it.valid()) { - ipAddrToAsciiTransactionPrivate *trn = it.pointer(); - ++it; - - if(this==&trn->engine) { - trn->pending = false; - pEngine->labor.remove(*trn); - } - } - - // cancel transaction in lookup or callback - if (pEngine->pCurrent && this==&pEngine->pCurrent->engine) { - pEngine->pCurrent->pending = false; - pEngine->pCurrent = 0; - } - - // wait for completion of in-progress callback - pEngine->cancelPendingCount++; - while(pEngine->pActive && this==&pEngine->pActive->engine - && ! pEngine->thread.isCurrentThread()) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - pEngine->destructorBlockEvent.wait(); - } - pEngine->cancelPendingCount--; - if(pEngine->cancelPendingCount) - pEngine->destructorBlockEvent.signal(); - } - - assert(refcount>0); - last = 0==--refcount; - } - if(last) { - delete this; - } -} - -void ipAddrToAsciiEnginePrivate::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->pEngine->mutex ); - printf ( "ipAddrToAsciiEngine at %p with %u requests pending\n", - static_cast (this), this->pEngine->labor.count () ); - if ( level > 0u ) { - tsDLIter < ipAddrToAsciiTransactionPrivate > - pItem = this->pEngine->labor.firstIter (); - while ( pItem.valid () ) { - pItem->show ( level - 1u ); - pItem++; - } - } - if ( level > 1u ) { - printf ( "mutex:\n" ); - this->pEngine->mutex.show ( level - 2u ); - printf ( "laborEvent:\n" ); - this->pEngine->laborEvent.show ( level - 2u ); - printf ( "exitFlag boolean = %u\n", this->pEngine->exitFlag ); - printf ( "exit event:\n" ); - } -} - -inline void * ipAddrToAsciiTransactionPrivate::operator new ( size_t size, tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void ipAddrToAsciiTransactionPrivate::operator delete ( void * pTrans, tsFreeList - < ipAddrToAsciiTransactionPrivate, 0x80 > & freeList ) -{ - freeList.release ( pTrans ); -} -#endif - -void ipAddrToAsciiTransactionPrivate::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - - -ipAddrToAsciiTransaction & ipAddrToAsciiEnginePrivate::createTransaction () -{ - epicsGuard G(this->pEngine->mutex); - if(this->released) - throw std::logic_error("createTransaction() on release()'d ipAddrToAsciiEngine"); - - assert(this->refcount>0); - - ipAddrToAsciiTransactionPrivate *ret = new ( this->pEngine->transactionFreeList ) ipAddrToAsciiTransactionPrivate ( *this ); - - this->refcount++; - - return * ret; -} - -void ipAddrToAsciiGlobal::run () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - while ( ! this->exitFlag ) { - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->laborEvent.wait (); - } - while ( true ) { - ipAddrToAsciiTransactionPrivate * pItem = this->labor.get (); - if ( ! pItem ) { - break; - } - osiSockAddr addr = pItem->addr; - this->pCurrent = pItem; - - if ( this->exitFlag ) - { - sockAddrToDottedIP ( & addr.sa, this->nameTmp, - sizeof ( this->nameTmp ) ); - } - else { - epicsGuardRelease < epicsMutex > unguard ( guard ); - // depending on DNS configuration, this could take a very long time - // so we release the lock - sockAddrToA ( &addr.sa, this->nameTmp, sizeof ( this->nameTmp ) ); - } - - // the ipAddrToAsciiTransactionPrivate destructor is allowed to - // set pCurrent to nill and avoid blocking on a slow DNS - // operation - if ( ! this->pCurrent ) { - continue; - } - - // fix for lp:1580623 - // a destructing cac sets pCurrent to NULL, so - // make local copy to avoid race when releasing the guard - ipAddrToAsciiTransactionPrivate *pCur = pActive = pCurrent; - this->callbackInProgress = true; - - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - // dont call callback with lock applied - pCur->pCB->transactionComplete ( this->nameTmp ); - } - - this->callbackInProgress = false; - pActive = 0; - - if ( this->pCurrent ) { - this->pCurrent->pending = false; - this->pCurrent = 0; - } - if ( this->cancelPendingCount ) { - this->destructorBlockEvent.signal (); - } - } - } -} - -ipAddrToAsciiTransactionPrivate::ipAddrToAsciiTransactionPrivate - ( ipAddrToAsciiEnginePrivate & engineIn ) : - engine ( engineIn ), pCB ( 0 ), pending ( false ) -{ - memset ( & this->addr, '\0', sizeof ( this->addr ) ); - this->addr.sa.sa_family = AF_UNSPEC; -} - -void ipAddrToAsciiTransactionPrivate::release () -{ - this->~ipAddrToAsciiTransactionPrivate (); - this->engine.pEngine->transactionFreeList.release ( this ); -} - -ipAddrToAsciiTransactionPrivate::~ipAddrToAsciiTransactionPrivate () -{ - ipAddrToAsciiGlobal *pGlobal = this->engine.pEngine; - bool last; - { - epicsGuard < epicsMutex > guard ( pGlobal->mutex ); - while ( this->pending ) { - if ( pGlobal->pCurrent == this && - pGlobal->callbackInProgress && - ! pGlobal->thread.isCurrentThread() ) { - // cancel from another thread while callback in progress - // waits for callback to complete - assert ( pGlobal->cancelPendingCount < UINT_MAX ); - pGlobal->cancelPendingCount++; - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - pGlobal->destructorBlockEvent.wait (); - } - assert ( pGlobal->cancelPendingCount > 0u ); - pGlobal->cancelPendingCount--; - if ( ! this->pending ) { - if ( pGlobal->cancelPendingCount ) { - pGlobal->destructorBlockEvent.signal (); - } - break; - } - } - else { - if ( pGlobal->pCurrent == this ) { - // cancel from callback, or while lookup in progress - pGlobal->pCurrent = 0; - } - else { - // cancel before lookup starts - pGlobal->labor.remove ( *this ); - } - this->pending = false; - } - } - assert(this->engine.refcount>0); - last = 0==--this->engine.refcount; - } - if(last) { - delete &this->engine; - } -} - -void ipAddrToAsciiTransactionPrivate::ipAddrToAscii ( - const osiSockAddr & addrIn, ipAddrToAsciiCallBack & cbIn ) -{ - bool success; - ipAddrToAsciiGlobal *pGlobal = this->engine.pEngine; - - { - epicsGuard < epicsMutex > guard ( pGlobal->mutex ); - - if (this->engine.released) { - errlogPrintf("Warning: ipAddrToAscii on transaction with release()'d ipAddrToAsciiEngine"); - success = false; - - } else if ( !this->pending && pGlobal->labor.count () < 16u ) { - // put some reasonable limit on queue expansion - this->addr = addrIn; - this->pCB = & cbIn; - this->pending = true; - pGlobal->labor.add ( *this ); - success = true; - } - else { - success = false; - } - } - - if ( success ) { - pGlobal->laborEvent.signal (); - } - else { - char autoNameTmp[256]; - sockAddrToDottedIP ( & addrIn.sa, autoNameTmp, - sizeof ( autoNameTmp ) ); - cbIn.transactionComplete ( autoNameTmp ); - } -} - -osiSockAddr ipAddrToAsciiTransactionPrivate::address () const -{ - return this->addr; -} - -void ipAddrToAsciiTransactionPrivate::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->engine.pEngine->mutex ); - char ipAddr [64]; - sockAddrToDottedIP ( &this->addr.sa, ipAddr, sizeof ( ipAddr ) ); - printf ( "ipAddrToAsciiTransactionPrivate for address %s\n", ipAddr ); - if ( level > 0u ) { - printf ( "\tengine %p\n", - static_cast ( & this->engine ) ); - this->pCB->show ( level - 1u ); - } -} diff --git a/src/libCom/misc/ipAddrToAsciiAsynchronous.h b/src/libCom/misc/ipAddrToAsciiAsynchronous.h deleted file mode 100644 index 9aefca44e..000000000 --- a/src/libCom/misc/ipAddrToAsciiAsynchronous.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef ipAddrToAsciiAsynchronous_h -#define ipAddrToAsciiAsynchronous_h - -#include "osiSock.h" -#include "shareLib.h" - -class epicsShareClass ipAddrToAsciiCallBack { -public: - virtual void transactionComplete ( const char * pHostName ) = 0; - virtual void show ( unsigned level ) const; - virtual ~ipAddrToAsciiCallBack () = 0; -}; - -class epicsShareClass ipAddrToAsciiTransaction { -public: - virtual void release () = 0; - virtual void ipAddrToAscii ( const osiSockAddr &, ipAddrToAsciiCallBack & ) = 0; - virtual osiSockAddr address () const = 0; - virtual void show ( unsigned level ) const = 0; -protected: - virtual ~ipAddrToAsciiTransaction () = 0; -}; - -class epicsShareClass ipAddrToAsciiEngine { -public: - virtual void release () = 0; - virtual ipAddrToAsciiTransaction & createTransaction () = 0; - virtual void show ( unsigned level ) const = 0; - static ipAddrToAsciiEngine & allocate (); -protected: - virtual ~ipAddrToAsciiEngine () = 0; -public: -#ifdef EPICS_PRIVATE_API - static void cleanup(); -#endif -}; - -#endif // ifdef ipAddrToAsciiAsynchronous_h diff --git a/src/libCom/misc/locationException.h b/src/libCom/misc/locationException.h deleted file mode 100644 index 30b187208..000000000 --- a/src/libCom/misc/locationException.h +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// Author: Jeff Hill -// - -#ifndef locationException_h -#define locationException_h - -#include - -#include "cantProceed.h" -#include "errlog.h" - -template -class sourceFileLocation : public T { -public: - sourceFileLocation (const T &parm, const char *fileName, unsigned lineNumber); - sourceFileLocation ( const sourceFileLocation & ); - sourceFileLocation & operator = ( const sourceFileLocation & ); - const char *fileName () const; - unsigned lineNumber () const; -private: - const char *pFileName; - unsigned lineNumberCopy; -}; - -template -inline sourceFileLocation::sourceFileLocation (const T &parm, const char *fileName, unsigned lineNumber) : - T ( parm ), pFileName ( fileName ) , lineNumberCopy ( lineNumber ) {} - -template -inline sourceFileLocation::sourceFileLocation ( const sourceFileLocation &in ) : - T ( in ), pFileName ( in.pFileName ), lineNumberCopy ( in.lineNumberCopy ) -{ -} - -template < class T > -inline sourceFileLocation & sourceFileLocation::operator = ( const sourceFileLocation &in ) -{ - this->pFileName = in.pFileName; - this->lineNumberCopy = in.lineNumberCopy; - return *this; -} - -template < class T > -inline unsigned sourceFileLocation::lineNumber () const -{ - return this->lineNumberCopy; -} - -template -inline const char * sourceFileLocation::fileName () const -{ - return this->pFileName; -} - -#define throwWithLocation(parm) throwExceptionWithLocation (parm, __FILE__, __LINE__); - -template -inline void throwExceptionWithLocation (const T &parm, const char *pFileName, unsigned lineNo) -{ - throw sourceFileLocation (parm, pFileName, lineNo); -} - -#endif // ifdef locationException_h - diff --git a/src/libCom/misc/makeEpicsVersion.pl b/src/libCom/misc/makeEpicsVersion.pl deleted file mode 100644 index c7c9acc39..000000000 --- a/src/libCom/misc/makeEpicsVersion.pl +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/perl -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; - -use Getopt::Std; -use File::Basename; - -my $tool = basename($0); - -our ($opt_h, $opt_q, $opt_v); -our $opt_o = 'epicsVersion.h'; - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; - -HELP_MESSAGE() unless getopts('ho:qv:') && @ARGV == 1; -HELP_MESSAGE() if $opt_h; - -my ($infile) = @ARGV; - -print "Building $opt_o from $infile\n" unless $opt_q; - -open my $VARS, '<', $infile - or die "$tool: Can't open $infile: $!\n"; - -my ($ver, $rev, $mod, $patch, $snapshot); -while (<$VARS>) { - chomp; - next if m/^\s*#/; # Skip comments - if (m/^EPICS_VERSION\s*=\s*(\d+)/) { $ver = $1; } - if (m/^EPICS_REVISION\s*=\s*(\d+)/) { $rev = $1; } - if (m/^EPICS_MODIFICATION\s*=\s*(\d+)/) { $mod = $1; } - if (m/^EPICS_PATCH_LEVEL\s*=\s*(\d+)/) { $patch = $1; } - if (m/^EPICS_DEV_SNAPSHOT\s*=\s*([-\w]*)/) { $snapshot = $1; } -} -close $VARS; - -map { - die "$tool: Variable missing from $infile" unless defined $_; -} $ver, $rev, $mod, $patch, $snapshot; - -my $ver_str = "$ver.$rev.$mod"; -$ver_str .= ".$patch" if $patch > 0; -my $ver_short = $ver_str; -$ver_str .= $snapshot if $snapshot ne ''; -$ver_str .= "-$opt_v" if $opt_v; - -print "Found EPICS Version $ver_str\n" unless $opt_q; - -open my $OUT, '>', $opt_o - or die "$tool: Can't create $opt_o: $!\n"; - -my $obase = basename($opt_o, '.h'); - -print $OUT <<"END"; -/* Generated file $opt_o */ - -#ifndef INC_${obase}_H -#define INC_${obase}_H - -#define EPICS_VERSION $ver -#define EPICS_REVISION $rev -#define EPICS_MODIFICATION $mod -#define EPICS_PATCH_LEVEL $patch -#define EPICS_DEV_SNAPSHOT "$snapshot" -#define EPICS_SITE_VERSION "$opt_v" - -#define EPICS_VERSION_SHORT "$ver_short" -#define EPICS_VERSION_FULL "$ver_str" -#define EPICS_VERSION_STRING "EPICS $ver_str" -#define epicsReleaseVersion "EPICS R$ver_str" - -#ifndef VERSION_INT -# define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P)) -#endif -#define EPICS_VERSION_INT VERSION_INT($ver, $rev, $mod, $patch) - -#endif /* INC_${obase}_H */ -END - -close $OUT; - -sub HELP_MESSAGE { - print STDERR "Usage: $tool [options] CONFIG_BASE_VERSION\n", - " -h Help: Print this message\n", - " -q Quiet: Only print errors\n", - " -o file Output filename, default is $opt_o\n", - " -v vers Site-specific version string\n", - "\n"; - exit 1; -} diff --git a/src/libCom/misc/shareLib.h b/src/libCom/misc/shareLib.h deleted file mode 100644 index 0d376d64a..000000000 --- a/src/libCom/misc/shareLib.h +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Compiler specific key words to set up external symbols and entry points - * - * USAGE: - * There are two distinct classes of keywords in this file: - * - * 1) epicsShareAPI - specifies a multi-language calling mechanism. On windows - * this is the pascal calling convention which is used by visual basic and other - * high level tools. This is only necessary if a C/C++ function needs to be called - * from other languages or from high level tools. The epicsShareAPI keyword - * must be present between the function's returned data type and the function's - * name. All compilers targeting windows accept the __stdcall keyword in this - * location. Functions with variable argument lists should not use the epicsShareAPI - * keyword because __stdcall (pascal) calling convention cannot support variable - * length ed argument lists. - * - * int epicsShareAPI myExtFunc ( int arg ); - * int epicsShareAPI myExtFunc ( int arg ) {} - * - * ** NOTE ** The epicsShareAPI attribute is deprecated and has been removed - * from all IOC-specific APIs. Most libCom APIs still use it, but - * it may get removed from these at some point in the future. - * - * 2) epicsShare{Func,Class,Extern,Def} - specifies shareable library (DLL) - * export/import related information in the source code. On windows these keywords - * allow faster dispatching of calls to DLLs because more is known at compile time. - * It is also not necessary to maintain a linker input files specifying the DLL - * entry points. This maintenance can be more laborious with C++ decorated symbol - * names. These keywords are only necessary if the address of a function or data - * internal to a shareable library (DLL) needs to be visible outside of this shareable - * library (DLL). All compilers targeting windows accept the __declspec(dllexport) - * and __declspec(dllimport) keywords. For GCC version 4 and above the first three - * keywords specify a visibility attribute of "default", which marks the symbol as - * exported even when gcc is given the option -fvisibility=hidden. Doing this can - * significantly reduce the number of symbols exported to a shared library. See the - * URL below for more information. - * - * In header files declare references to externally visible variables, classes and - * functions like this: - * - * #include "shareLib.h" - * epicsShareFunc int myExtFunc ( int arg ); - * epicsShareExtern int myExtVar; - * class epicsShareClass myClass { int func ( void ); }; - * - * In the implementation file, however, you write: - * - * #include - * #define epicsExportSharedSymbols - * #include - * - * epicsShareDef int myExtVar = 4; - * int myExtFunc ( int arg ) {} - * int myClass::func ( void ) {} - * - * By default shareLib.h sets the DLL import / export keywords to import from - * a DLL so that, for DLL consumers (users), nothing special must be done. However, - * DLL implementors must set epicsExportSharedSymbols as above to specify - * which functions are exported from the DLL and which of them are imported - * from other DLLs. - * - * You must first #include what you import and then define epicsExportSharedSymbols - * only right before you #include the prototypes for what you implement! You must - * include shareLib.h again each time that the state of the import/ export keywords - * changes, but this usually occurs as a side effect of including the shareable - * libraries header file(s). - * - * Frequently a header file for a shareable library exported interface will - * have some preprocessor switches like this if this header file must also - * include header files describing interfaces to other shareable libraries. - * - * #ifdef epicsExportSharedSymbols - * # define interfacePDQ_epicsExportSharedSymbols - * # undef epicsExportSharedSymbols - * #endif - * - * #include "epicsTypes.h" - * #include "epicsTime.h" - * - * #ifdef interfacePDQ_epicsExportSharedSymbols - * # define epicsExportSharedSymbols - * # include "shareLib.h" - * #endif - * - * epicsShareFunc int myExtFunc ( int arg ); - * epicsShareExtern int myExtVar; - * class epicsShareClass myClass {}; - * - * Fortunately, the above is only the concern of library authors and will have no - * impact on persons using functions and or external data from a library. - */ - -#undef epicsShareExtern -#undef epicsShareDef -#undef epicsShareClass -#undef epicsShareFunc -#undef epicsShareAPI -#undef READONLY - -#if defined(_WIN32) || defined(__CYGWIN__) -/* - * Check if EPICS_BUILD_DLL or EPICS_CALL_DLL defined and use the dllimport/ - * dllexport keywords if this is a shared library build of base under WIN32. - */ - -# if defined(epicsExportSharedSymbols) -# if defined(EPICS_BUILD_DLL) -# define epicsShareExtern __declspec(dllexport) extern -# define epicsShareClass __declspec(dllexport) -# define epicsShareFunc __declspec(dllexport) -# else -# define epicsShareExtern extern -# define epicsShareClass -# define epicsShareFunc -# endif -# else -# if defined(EPICS_CALL_DLL) -# define epicsShareExtern __declspec(dllimport) extern -# define epicsShareClass __declspec(dllimport) -# define epicsShareFunc __declspec(dllimport) -# else -# define epicsShareExtern extern -# define epicsShareClass -# define epicsShareFunc -# endif -# endif -# define epicsShareDef -# define epicsShareAPI __stdcall /* function removes arguments */ -# define READONLY const - -#elif __GNUC__ >= 4 -/* - * See http://gcc.gnu.org/wiki/Visibility - * For these to work, gcc must be given the flag - * -fvisibility=hidden - * and g++ the flags - * -fvisibility=hidden -fvisibility-inlines-hidden - */ - -# define epicsShareExtern __attribute__ ((visibility("default"))) extern -# define epicsShareClass __attribute__ ((visibility("default"))) -# define epicsShareFunc __attribute__ ((visibility("default"))) - -# define epicsShareDef -# define epicsShareAPI -# if defined(__STDC__) || defined (__cplusplus) -# define READONLY const -# else -# define READONLY -# endif - -/* - * if its the old VAX C Compiler (not DEC C) - */ -#elif defined(VAXC) - - /* - * VAXC creates FORTRAN common blocks when - * we use "extern int fred"/"int fred=4". Therefore, - * the initialization is not loaded unless we - * call a function in that object module. - * - * DEC CXX does not have this problem. - * We suspect (but do not know) that DEC C - * also does not have this problem. - */ -# define epicsShareExtern globalref -# define epicsShareDef globaldef -# define READONLY const -# define epicsShareClass -# define epicsShareFunc -# define epicsShareAPI - -#else - -/* else => no import/export specifiers */ - -# define epicsShareExtern extern -# define epicsShareAPI -# define epicsShareClass -# define epicsShareDef - -# define epicsShareFunc -# if defined(__STDC__) || defined (__cplusplus) -# define READONLY const -# else -# define READONLY -# endif - -#endif - -#ifndef INLINE_defs_EPICS -#define INLINE_defs_EPICS -# ifndef __cplusplus -# if defined (__GNUC__) -# define INLINE static __inline__ -# elif defined (_MSC_VER) -# define INLINE __inline -# elif defined (_SUNPRO_C) -# pragma error_messages (off, E_EXTERN_PRIOR_REDECL_STATIC) -# define INLINE static -# else -# define INLINE static -# endif -# endif /* ifndef __cplusplus */ -#endif /* ifdef INLINE_defs_EPICS */ diff --git a/src/libCom/misc/testMain.h b/src/libCom/misc/testMain.h deleted file mode 100644 index 4db72c39e..000000000 --- a/src/libCom/misc/testMain.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_testMain_H -#define INC_testMain_H - -/* This header defines a convenience macro for use by pure test programs. - * A pure test program cannot take any arguments since it must be fully - * automatable. If your program needs to use argv/argc, it may be doing - * measurements not unit and/or regression testing. On Host architectures - * these programs needs to be named main and take dummy argc/argv args, - * but on vxWorks and RTEMS they must be named as the test program. - * - * Use this macro as follows: - * - * #include "testMain.h" - * #include "epicsUnitTest.h" - * - * MAIN(myProgTest) { - * testPlan(...); - * testOk(...) - * return testDone(); - * } - */ - -#if defined(vxWorks) || defined(__rtems__) - #ifdef __cplusplus - #define MAIN(prog) extern "C" int prog(void) - #else - #define MAIN(prog) int prog() - #endif -#else - #ifdef __cplusplus - #define MAIN(prog) int main(int /*argc*/, char * /*argv*/ [] ) - #else - #define MAIN(prog) int main(int argc, char *argv[] ) - #endif -#endif - - -#endif /* INC_testMain_H */ diff --git a/src/libCom/misc/truncateFile.c b/src/libCom/misc/truncateFile.c deleted file mode 100644 index ccb1450c2..000000000 --- a/src/libCom/misc/truncateFile.c +++ /dev/null @@ -1,136 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -/* - * truncate to specified size (we dont use truncate() - * because it is not portable) - */ -epicsShareFunc enum TF_RETURN truncateFile (const char *pFileName, unsigned long size) -{ - char tmpName[256>L_tmpnam?256:L_tmpnam]; - long filePos; - FILE *pFile; - FILE *ptmp; - int status; - int c; - unsigned charNo; - - /* - * see cast of size to long below - */ - if (size>LONG_MAX) { - return TF_ERROR; - } - - pFile = fopen(pFileName, "r"); - if (!pFile) { - fprintf (stderr, - "File access problems to `%s' because `%s'\n", - pFileName, - strerror(errno)); - return TF_ERROR; - } - - /* - * This is not required under UNIX but does appear - * to be required under WIN32. - */ - status = fseek (pFile, 0L, SEEK_END); - if (status!=TF_OK) { - fclose (pFile); - return TF_ERROR; - } - - filePos = ftell(pFile); - if (filePos <= (long) size) { - fclose (pFile); - return TF_OK; - } - - epicsTempName ( tmpName, sizeof (tmpName) ); - if ( tmpName[0] == '\0' ) { - fprintf (stderr,"Unable to create tmp file name?\n"); - fclose (pFile); - return TF_ERROR; - } - - ptmp = fopen (tmpName, "w"); - if (!ptmp) { - fprintf (stderr, - "File access problems to `%s' because `%s'\n", - tmpName, - strerror(errno)); - fclose (pFile); - return TF_ERROR; - } - rewind (pFile); - charNo = 0u; - while (charNo 2 -# define EPICS_ALWAYS_INLINE __inline__ __attribute__((always_inline)) -#else -# define EPICS_ALWAYS_INLINE __inline__ -#endif - -/* Expands to a 'const char*' which describes the name of the current function scope */ -#define EPICS_FUNCTION __PRETTY_FUNCTION__ - -#ifdef __cplusplus - -/* - * in general we dont like ifdefs but they do allow us to check the - * compiler version and make the optimistic assumption that - * standards incompliance issues will be fixed by future compiler - * releases - */ - -/* - * CXX_PLACEMENT_DELETE - defined if compiler supports placement delete - * CXX_THROW_SPECIFICATION - defined if compiler supports throw specification - */ - -#if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95 ) -# define CXX_THROW_SPECIFICATION -#endif - -#if __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 96 ) -# define CXX_PLACEMENT_DELETE -#endif - -#endif /* __cplusplus */ - -/* - * Enable format-string checking if possible - */ -#define EPICS_PRINTF_STYLE(f,a) __attribute__((format(__printf__,f,a))) - -/* - * Deprecation marker if possible - */ -#if (__GNUC__ > 2) -# define EPICS_DEPRECATED __attribute__((deprecated)) -#endif - -/* - * Unused marker - */ -#define EPICS_UNUSED __attribute__((unused)) - -#endif /* ifndef compilerSpecific_h */ diff --git a/src/libCom/osi/compiler/gcc/epicsAtomicCD.h b/src/libCom/osi/compiler/gcc/epicsAtomicCD.h deleted file mode 100644 index 15b9a6c9a..000000000 --- a/src/libCom/osi/compiler/gcc/epicsAtomicCD.h +++ /dev/null @@ -1,194 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicCD_h -#define epicsAtomicCD_h - -#ifndef __GNUC__ -# error this header is only for use with the gnu compiler -#endif - -#define EPICS_ATOMIC_CMPLR_NAME "GCC" - -#define GCC_ATOMIC_CONCAT( A, B ) GCC_ATOMIC_CONCATR(A,B) -#define GCC_ATOMIC_CONCATR( A, B ) ( A ## B ) - -#define GCC_ATOMIC_INTRINSICS_AVAIL_INT_T \ - GCC_ATOMIC_CONCAT ( \ - __GCC_HAVE_SYNC_COMPARE_AND_SWAP_, \ - __SIZEOF_INT__ ) - -#define GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T \ - GCC_ATOMIC_CONCAT ( \ - __GCC_HAVE_SYNC_COMPARE_AND_SWAP_, \ - __SIZEOF_SIZE_T__ ) - -#define GCC_ATOMIC_INTRINSICS_MIN_X86 \ - ( defined ( __i486 ) || defined ( __pentium ) || \ - defined ( __pentiumpro ) || defined ( __MMX__ ) ) - -#define GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER \ - ( ( __GNUC__ * 100 + __GNUC_MINOR__ ) >= 401 ) - -#define GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER \ - ( GCC_ATOMIC_INTRINSICS_MIN_X86 && \ - GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER ) - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * We are optimistic that __sync_synchronize is implemented - * in all version four gcc invariant of target. The gnu doc - * seems to say that when not supported by architecture a call - * to an external function is generated but in practice - * this isn`t the case for some of the atomic intrinsics, and - * so there is an undefined symbol. So far we have not seen - * that with __sync_synchronize, but we can only guess based - * on experimental evidence. - * - * For example we know that when generating object code for - * 386 most of the atomic intrinsics are not present and - * we see undefined symbols with mingw, but we don`t have - * troubles with __sync_synchronize. - */ -#if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - __sync_synchronize (); -} -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - __sync_synchronize (); -} -#endif - -#else - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#if GCC_ATOMIC_INTRINSICS_MIN_X86 -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - asm("mfence;"); -} -#endif -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#if GCC_ATOMIC_INTRINSICS_MIN_X86 -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - asm("mfence;"); -} -#endif -#endif - -#endif /* if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER */ - -#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T \ - || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER - -#define EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - return __sync_add_and_fetch ( pTarget, 1 ); -} - -#define EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - return __sync_sub_and_fetch ( pTarget, 1 ); -} - -#define EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - return __sync_add_and_fetch ( pTarget, delta ); -} - -#define EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ) -{ - return __sync_val_compare_and_swap ( pTarget, oldVal, newVal); -} - -#endif /* if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T */ - -#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T \ - || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER - -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - return __sync_add_and_fetch ( pTarget, 1u ); -} - -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - return __sync_sub_and_fetch ( pTarget, 1u ); -} - -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ) -{ - return __sync_add_and_fetch ( pTarget, delta ); -} - -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - return __sync_sub_and_fetch ( pTarget, delta ); -} - -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - return __sync_val_compare_and_swap ( pTarget, oldVal, newVal); -} - -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal ) -{ - return __sync_val_compare_and_swap ( pTarget, oldVal, newVal); -} - -#endif /* if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T */ - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -/* - * if currently unavailable as gcc intrinsics we - * will try for an os specific inline solution - */ -#include "epicsAtomicOSD.h" - -#endif /* epicsAtomicCD_h */ diff --git a/src/libCom/osi/compiler/msvc/compilerSpecific.h b/src/libCom/osi/compiler/msvc/compilerSpecific.h deleted file mode 100644 index 75bfa83fb..000000000 --- a/src/libCom/osi/compiler/msvc/compilerSpecific.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: - * Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef compilerSpecific_h -#define compilerSpecific_h - -#ifndef _MSC_VER -# error compiler/msvc/compilerSpecific.h is only for use with the Microsoft compiler -#endif - -#if _MSC_VER >= 1200 -#define EPICS_ALWAYS_INLINE __forceinline -#else -#define EPICS_ALWAYS_INLINE __inline -#endif - -/* Expands to a 'const char*' which describes the name of the current function scope */ -#define EPICS_FUNCTION __FUNCTION__ - -#ifdef __cplusplus - -/* - * in general we dont like ifdefs but they do allow us to check the - * compiler version and make the optimistic assumption that - * standards incompliance issues will be fixed by future compiler - * releases - */ - -/* - * CXX_PLACEMENT_DELETE - defined if compiler supports placement delete - * CXX_THROW_SPECIFICATION - defined if compiler supports throw specification - */ -#if _MSC_VER >= 1200 /* visual studio 6.0 or later */ -# define CXX_PLACEMENT_DELETE -#endif - -#if _MSC_VER > 1300 /* some release after visual studio 7 we hope */ -# define CXX_THROW_SPECIFICATION -#endif - -#endif /* __cplusplus */ - - -#endif /* ifndef compilerSpecific_h */ diff --git a/src/libCom/osi/compiler/msvc/epicsAtomicCD.h b/src/libCom/osi/compiler/msvc/epicsAtomicCD.h deleted file mode 100644 index e7d1c4b77..000000000 --- a/src/libCom/osi/compiler/msvc/epicsAtomicCD.h +++ /dev/null @@ -1,118 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicCD_h -#define epicsAtomicCD_h - -#include "epicsAssert.h" - -#ifndef _MSC_VER -# error this header file is only for use with with the Microsoft Compiler -#endif - -#ifdef _MSC_EXTENSIONS - -#define EPICS_ATOMIC_CMPLR_NAME "MSVC-INTRINSIC" - -#include - -#if defined ( _M_IX86 ) -# pragma warning( push ) -# pragma warning( disable : 4793 ) - EPICS_ATOMIC_INLINE void epicsAtomicMemoryBarrier (void) - { - long fence; - __asm { xchg fence, eax } - } -# pragma warning( pop ) -#elif defined ( _M_X64 ) -# define MS_ATOMIC_64 -# pragma intrinsic ( __faststorefence ) - EPICS_ATOMIC_INLINE void epicsAtomicMemoryBarrier (void) - { - __faststorefence (); - } -#elif defined ( _M_IA64 ) -# define MS_ATOMIC_64 -# pragma intrinsic ( __mf ) - EPICS_ATOMIC_INLINE void epicsAtomicMemoryBarrier (void) - { - __mf (); - } -#else -# error unexpected target architecture, msvc version of epicsAtomicCD.h -#endif - -/* - * The windows doc appears to recommend defining InterlockedExchange - * to be _InterlockedExchange to cause it to be an intrinsic, but that - * creates issues when later, in a windows os specific header, we include - * windows.h. Therefore, we except some code duplication between the msvc - * csAtomic.h and win32 osdAtomic.h to avoid problems, and to keep the - * os specific windows.h header file out of the msvc cdAtomic.h - */ -#define MS_LONG long -#define MS_InterlockedExchange _InterlockedExchange -#define MS_InterlockedCompareExchange _InterlockedCompareExchange -#define MS_InterlockedIncrement _InterlockedIncrement -#define MS_InterlockedDecrement _InterlockedDecrement -#define MS_InterlockedExchange _InterlockedExchange -#define MS_InterlockedExchangeAdd _InterlockedExchangeAdd -#if defined ( MS_ATOMIC_64 ) -# define MS_LONGLONG long long -# define MS_InterlockedIncrement64 _InterlockedIncrement64 -# define MS_InterlockedDecrement64 _InterlockedDecrement64 -# define MS_InterlockedExchange64 _InterlockedExchange64 -# define MS_InterlockedExchangeAdd64 _InterlockedExchangeAdd64 -# define MS_InterlockedCompareExchange64 _InterlockedCompareExchange64 -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - epicsAtomicMemoryBarrier (); -} - -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - epicsAtomicMemoryBarrier (); -} - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#include "epicsAtomicMS.h" -#include "epicsAtomicDefault.h" - -#else /* ifdef _MSC_EXTENSIONS */ - -#define EPICS_ATOMIC_CMPLR_NAME "MSVC-DIRECT" - -/* - * if unavailable as an intrinsic we will try - * for os specific inline solution - */ -#include "epicsAtomicOSD.h" - -#endif /* ifdef _MSC_EXTENSIONS */ - -#endif /* epicsAtomicCD_h */ - diff --git a/src/libCom/osi/compiler/solStudio/compilerSpecific.h b/src/libCom/osi/compiler/solStudio/compilerSpecific.h deleted file mode 100644 index a9d59a5bf..000000000 --- a/src/libCom/osi/compiler/solStudio/compilerSpecific.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: - * Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef compilerSpecific_h -#define compilerSpecific_h - -#if !defined(__SUNPRO_C) && !defined (__SUNPRO_CC) -# error Not Solaris Studio -#endif - -#if (defined(__SUNPRO_C) && __SUNPRO_C < 0x590) || \ - (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) -# define EPICS_ALWAYS_INLINE inline -#else -# define EPICS_ALWAYS_INLINE inline __attribute__((always_inline)) -#endif - -#ifdef __cplusplus - -/* - * CXX_PLACEMENT_DELETE - defined if compiler supports placement delete - * CXX_THROW_SPECIFICATION - defined if compiler supports throw specification - * - * (our default guess is that the compiler implements the C++ 97 standard) - */ -#define CXX_THROW_SPECIFICATION -#define CXX_PLACEMENT_DELETE - -#endif /* __cplusplus */ - - -#endif /* ifndef compilerSpecific_h */ diff --git a/src/libCom/osi/compiler/solStudio/epicsAtomicCD.h b/src/libCom/osi/compiler/solStudio/epicsAtomicCD.h deleted file mode 100644 index 8a733a558..000000000 --- a/src/libCom/osi/compiler/solStudio/epicsAtomicCD.h +++ /dev/null @@ -1,23 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicCD_h -#define epicsAtomicCD_h - -#define EPICS_ATOMIC_CMPLR_NAME "SOLSTUDIO" - -#include "epicsAtomicOSD.h" - -#endif /* epicsAtomicCD_h */ diff --git a/src/libCom/osi/compilerDependencies.h b/src/libCom/osi/compilerDependencies.h deleted file mode 100644 index 3bd835c91..000000000 --- a/src/libCom/osi/compilerDependencies.h +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: - * Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef compilerDependencies_h -#define compilerDependencies_h - -#include "compilerSpecific.h" - -#ifdef __cplusplus - -/* - * usage: void func () epicsThrows (( std::bad_alloc, std::logic_error )) - * - * Note: now a widely accepted concensus (ref Meyers and C++ faq) is that - * one should avoid using throw specifications in C++ code - */ -#if defined ( CXX_THROW_SPECIFICATION ) -# define epicsThrows(X) throw X -#else -# define epicsThrows(X) -#endif - -/* - * usage: epicsPlacementDeleteOperator (( void *, myMemoryManager & )) - */ -#if defined ( CXX_PLACEMENT_DELETE ) -# define epicsPlacementDeleteOperator(X) void operator delete X; -#else -# define epicsPlacementDeleteOperator(X) -#endif - -#endif /* __cplusplus */ - - -#ifndef EPICS_PRINTF_STYLE -/* - * No format-string checking - */ -# define EPICS_PRINTF_STYLE(f,a) -#endif - -#ifndef EPICS_DEPRECATED -/* - * No deprecation markers - */ -#define EPICS_DEPRECATED -#endif - -#ifndef EPICS_UNUSED -# define EPICS_UNUSED -#endif - -#ifndef EPICS_FUNCTION -#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) || (defined(__cplusplus) && __cplusplus>=201103L) -# define EPICS_FUNCTION __func__ -#else -/* Expands to a 'const char*' which describes the name of the current function scope */ -# define EPICS_FUNCTION ("") -#endif -#endif - -#endif /* ifndef compilerDependencies_h */ diff --git a/src/libCom/osi/devLib.h b/src/libCom/osi/devLib.h deleted file mode 100644 index 729f9b932..000000000 --- a/src/libCom/osi/devLib.h +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLib.h */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - */ -#ifndef EPICSDEVLIB_H -#define EPICSDEVLIB_H - -/* - * Support macros - */ - -/* - * Normalize a digital value and convert it to type TYPE - * - * Ex: - * float f; - * int d; - * f = devNormalizeDigital(d,12) - * - */ -#define devCreateMask(NBITS) ((1<<(NBITS))-1) -#define devDigToNml(DIGITAL,NBITS) \ - (((double)(DIGITAL))/devCreateMask(NBITS)) -#define devNmlToDig(NORMAL,NBITS) \ - (((long)(NORMAL)) * devCreateMask(NBITS)) - -/* - * - * Alignment mask - * (for use when testing to see if the proper number of least - * significant bits are zero) - * - */ -#define devCreateAlignmentMask(CTYPE)\ -(sizeof(CTYPE)>sizeof(double)?sizeof(double)-1:sizeof(CTYPE)-1) - -/* - * pointer aligned test - * (returns true if the pointer is on the worst case alignemnt - * boundary for its type) - */ -#define devPtrAlignTest(PTR) (!(devCreateAlignmentMask(*PTR)&(long)(PTR))) - -/* - * error codes (and messages) associated with devLib.c - */ -#define S_dev_success 0 -#define S_dev_vectorInUse (M_devLib| 1) /*interrupt vector in use*/ -#define S_dev_vecInstlFail (M_devLib| 2) /*interrupt vector install failed*/ -#define S_dev_uknIntType (M_devLib| 3) /*Unrecognized interrupt type*/ -#define S_dev_vectorNotInUse (M_devLib| 4) /*Interrupt vector not in use by caller*/ -#define S_dev_badA16 (M_devLib| 5) /*Invalid VME A16 address*/ -#define S_dev_badA24 (M_devLib| 6) /*Invalid VME A24 address*/ -#define S_dev_badA32 (M_devLib| 7) /*Invalid VME A32 address*/ -#define S_dev_uknAddrType (M_devLib| 8) /*Unrecognized address space type*/ -#define S_dev_addressOverlap (M_devLib| 9) /*Specified device address overlaps another device*/ -#define S_dev_identifyOverlap (M_devLib| 10) /*This device already owns the address range*/ -#define S_dev_addrMapFail (M_devLib| 11) /*unable to map address*/ -#define S_dev_intDisconnect (M_devLib| 12) /*Interrupt at vector disconnected from an EPICS device*/ -#define S_dev_internal (M_devLib| 13) /*Internal failure*/ -#define S_dev_intEnFail (M_devLib| 14) /*unable to enable interrupt level*/ -#define S_dev_intDissFail (M_devLib| 15) /*unable to disable interrupt level*/ -#define S_dev_noMemory (M_devLib| 16) /*Memory allocation failed*/ -#define S_dev_addressNotFound (M_devLib| 17) /*Specified device address unregistered*/ -#define S_dev_noDevice (M_devLib| 18) /*No device at specified address*/ -#define S_dev_wrongDevice (M_devLib| 19) /*Wrong device type found at specified address*/ -#define S_dev_badSignalNumber (M_devLib| 20) /*Signal number (offset) to large*/ -#define S_dev_badSignalCount (M_devLib| 21) /*Signal count to large*/ -#define S_dev_badRequest (M_devLib| 22) /*Device does not support requested operation*/ -#define S_dev_highValue (M_devLib| 23) /*Parameter to high*/ -#define S_dev_lowValue (M_devLib| 24) /*Parameter to low*/ -#define S_dev_multDevice (M_devLib| 25) /*Specified address is ambiguous (more than one device responds)*/ -#define S_dev_badSelfTest (M_devLib| 26) /*Device self test failed*/ -#define S_dev_badInit (M_devLib| 27) /*Device failed during initialization*/ -#define S_dev_hdwLimit (M_devLib| 28) /*Input exceeds Hardware Limit*/ -#define S_dev_deviceDoesNotFit (M_devLib| 29) /*Unable to locate address space for device*/ -#define S_dev_deviceTMO (M_devLib| 30) /*device timed out*/ -#define S_dev_badFunction (M_devLib| 31) /*bad function pointer*/ -#define S_dev_badVector (M_devLib| 32) /*bad interrupt vector*/ -#define S_dev_badArgument (M_devLib| 33) /*bad function argument*/ -#define S_dev_badISA (M_devLib| 34) /*Invalid ISA address*/ -#define S_dev_badCRCSR (M_devLib| 35) /*Invalid VME CR/CSR address*/ -#define S_dev_vxWorksIntEnFail S_dev_intEnFail - - -#endif /* EPICSDEVLIB_H */ - -/* - * Retain compatibility by including VME by default - */ -#ifndef NO_DEVLIB_COMPAT -# include "devLibVME.h" -#endif diff --git a/src/libCom/osi/devLibVME.c b/src/libCom/osi/devLibVME.c deleted file mode 100644 index 6c7d93f99..000000000 --- a/src/libCom/osi/devLibVME.c +++ /dev/null @@ -1,1156 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLib.c - support for allocation of common device resources */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - * - * NOTES: - * .01 06-14-93 joh needs devAllocInterruptVector() routine - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "ellLib.h" - -#define NO_DEVLIB_COMPAT -#include "devLibVME.h" -#include "devLibVMEImpl.h" - -static ELLLIST addrAlloc[atLast]; -static ELLLIST addrFree[atLast]; - -static size_t addrLast[atLast] = { - 0xffff, - 0xffffff, - 0xffffffff, - 0xffffff, - 0xffffff, - }; - -static unsigned addrHexDig[atLast] = { - 4, - 6, - 8, - 6, - 6 - }; - -static long addrFail[atLast] = { - S_dev_badA16, - S_dev_badA24, - S_dev_badA32, - S_dev_badISA, - S_dev_badCRCSR - }; - -static epicsMutexId addrListLock; -static char devLibInitFlag; - -const char *epicsAddressTypeName[] - = { - "VME A16", - "VME A24", - "VME A32", - "ISA", - "VME CR/CSR" - }; - -typedef struct{ - ELLNODE node; - const char *pOwnerName; - volatile void *pPhysical; - /* - * first, last is used here instead of base, size - * so that we can store a block that is the maximum size - * available in type size_t - */ - size_t begin; - size_t end; -}rangeItem; - -/* - * These routines are not exported - */ - -static long devLibInit(void); - -static long addrVerify( - epicsAddressType addrType, - size_t base, - size_t size); - -static long blockFind ( - epicsAddressType addrType, - const rangeItem *pRange, - /* size needed */ - size_t requestSize, - /* n ls bits zero in base addr */ - unsigned alignment, - /* base address found */ - size_t *pFirst); - -static void report_conflict( - epicsAddressType addrType, - size_t base, - size_t size, - const char *pOwnerName); - -static void report_conflict_device( - epicsAddressType addrType, - const rangeItem *pRange); - -static void devInsertAddress( - ELLLIST *pRangeList, - rangeItem *pNewRange); - -static long devListAddressMap( - ELLLIST *pRangeList); - -static long devCombineAdjacentBlocks( - ELLLIST *pRangeList, - rangeItem *pRange); - -static long devInstallAddr( - rangeItem *pRange, /* item on the free list to be split */ - const char *pOwnerName, - epicsAddressType addrType, - size_t base, - size_t size, - volatile void **ppPhysicalAddress); - -#define SUCCESS 0 - -/* - * devBusToLocalAddr() - */ -long devBusToLocalAddr( - epicsAddressType addrType, - size_t busAddr, - volatile void **ppLocalAddress) -{ - long status; - volatile void *localAddress; - - /* - * Make sure that devLib has been intialized - */ - if (!devLibInitFlag) { - status = devLibInit(); - if(status){ - return status; - } - } - - /* - * Make sure we have a valid bus address - */ - status = addrVerify (addrType, busAddr, 4); - if (status) { - return status; - } - - /* - * Call the virtual os routine to map the bus address to a CPU address - */ - status = (*pdevLibVME->pDevMapAddr) (addrType, 0, busAddr, 4, &localAddress); - if (status) { - errPrintf (status, __FILE__, __LINE__, "%s bus address =0X%X\n", - epicsAddressTypeName[addrType], (unsigned int)busAddr); - return status; - } - - /* - * Return the local CPU address if the pointer is supplied - */ - if (ppLocalAddress) { - *ppLocalAddress = localAddress; - } - - return SUCCESS; - -}/*end devBusToLocalAddr()*/ - - -/* - * devRegisterAddress() - */ -long devRegisterAddress( - const char *pOwnerName, - epicsAddressType addrType, - size_t base, - size_t size, - volatile void **ppPhysicalAddress) -{ - rangeItem *pRange; - long s; - - if (!devLibInitFlag) { - s = devLibInit(); - if(s){ - return s; - } - } - - s = addrVerify (addrType, base, size); - if (s) { - return s; - } - - if (size == 0) { - return S_dev_lowValue; - } - -#ifdef DEBUG - printf ("Req Addr 0X%X Size 0X%X\n", base, size); -#endif - - epicsMutexMustLock(addrListLock); - pRange = (rangeItem *) ellFirst(&addrFree[addrType]); - while (TRUE) { - if (pRange->begin > base) { - pRange = NULL; -# ifdef DEBUG - printf ("Unable to locate a free block\n"); - devListAddressMap (&addrFree[addrType]); -# endif - break; - } - else if (base + (size - 1) <= pRange->end) { -# ifdef DEBUG - printf ("Found free block Begin 0X%X End 0X%X\n", - pRange->begin, pRange->end); -# endif - break; - } - - pRange = (rangeItem *) ellNext (&pRange->node); - } - epicsMutexUnlock(addrListLock); - - if (pRange==NULL) { - report_conflict (addrType, base, size, pOwnerName); - return S_dev_addressOverlap; - } - - s = devInstallAddr( - pRange, /* item on the free list to be split */ - pOwnerName, - addrType, - base, - size, - ppPhysicalAddress); - - return s; -} - -/* - * devReadProbe() - * - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -long devReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevReadProbe) (wordSize, ptr, pValue); -} - -/* - * devWriteProbe - * - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -long devWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevWriteProbe) (wordSize, ptr, pValue); -} - -/* - * devInstallAddr() - */ -static long devInstallAddr ( - rangeItem *pRange, /* item on the free list to be split */ - const char *pOwnerName, - epicsAddressType addrType, - size_t base, - size_t size, - volatile void **ppPhysicalAddress) -{ - volatile void *pPhysicalAddress; - rangeItem *pNewRange; - size_t reqEnd = base + (size-1); - long status; - - /* - * does it start below the specified block - */ - if (base < pRange->begin) { - return S_dev_badArgument; - } - - /* - * does it end above the specified block - */ - if (reqEnd > pRange->end) { - return S_dev_badArgument; - } - - /* - * always map through the virtual os in case the memory - * management is set up there - */ - status = (*pdevLibVME->pDevMapAddr) (addrType, 0, base, - size, &pPhysicalAddress); - if (status) { - errPrintf (status, __FILE__, __LINE__, "%s base=0X%X size = 0X%X", - epicsAddressTypeName[addrType], (unsigned int)base, (unsigned int)size); - return status; - } - - /* - * set the callers variable if the pointer is supplied - */ - if (ppPhysicalAddress) { - *ppPhysicalAddress = pPhysicalAddress; - } - - /* - * does it start at the beginning of the block - */ - if (pRange->begin == base) { - if (pRange->end == reqEnd) { - epicsMutexMustLock(addrListLock); - ellDelete(&addrFree[addrType], &pRange->node); - epicsMutexUnlock(addrListLock); - free ((void *)pRange); - } - else { - pRange->begin = base + size; - } - } - /* - * does it end at the end of the block - */ - else if (pRange->end == reqEnd) { - pRange->end = base-1; - } - /* - * otherwise split the item on the free list - */ - else { - - pNewRange = (rangeItem *) calloc (1, sizeof(*pRange)); - if(!pNewRange){ - return S_dev_noMemory; - } - - pNewRange->begin = base + size; - pNewRange->end = pRange->end; - pNewRange->pOwnerName = ""; - pNewRange->pPhysical = NULL; - pRange->end = base - 1; - - /* - * add the node after the old item on the free list - * (blocks end up ordered by address) - */ - epicsMutexMustLock(addrListLock); - ellInsert(&addrFree[addrType], &pRange->node, &pNewRange->node); - epicsMutexUnlock(addrListLock); - } - - /* - * allocate a new address range entry and add it to - * the list - */ - pNewRange = (rangeItem *)calloc (1, sizeof(*pRange)); - if (!pNewRange) { - return S_dev_noMemory; - } - - pNewRange->begin = base; - pNewRange->end = reqEnd; - pNewRange->pOwnerName = pOwnerName; - pNewRange->pPhysical = pPhysicalAddress; - - devInsertAddress (&addrAlloc[addrType], pNewRange); - - return SUCCESS; -} - -/* - * report_conflict() - */ -static void report_conflict ( - epicsAddressType addrType, - size_t base, - size_t size, - const char *pOwnerName -) -{ - const rangeItem *pRange; - - errPrintf ( - S_dev_addressOverlap, - __FILE__, - __LINE__, - "%10s 0X%08X - OX%08X Requested by %s", - epicsAddressTypeName[addrType], - (unsigned int)base, - (unsigned int)(base+size-1), - pOwnerName); - - pRange = (rangeItem *) ellFirst(&addrAlloc[addrType]); - while (pRange) { - - if (pRange->begin <= base + (size-1) && pRange->end >= base) { - report_conflict_device (addrType, pRange); - } - - pRange = (rangeItem *) pRange->node.next; - } -} - -/* - * report_conflict_device() - */ -static void report_conflict_device(epicsAddressType addrType, const rangeItem *pRange) -{ - errPrintf ( - S_dev_identifyOverlap, - __FILE__, - __LINE__, - "%10s 0X%08X - 0X%08X Owned by %s", - epicsAddressTypeName[addrType], - (unsigned int)pRange->begin, - (unsigned int)pRange->end, - pRange->pOwnerName); -} - -/* - * devUnregisterAddress() - */ -long devUnregisterAddress( - epicsAddressType addrType, - size_t baseAddress, - const char *pOwnerName) -{ - rangeItem *pRange; - int s; - - if (!devLibInitFlag) { - s = devLibInit(); - if(s) { - return s; - } - } - - s = addrVerify (addrType, baseAddress, 1); - if (s != SUCCESS) { - return s; - } - - epicsMutexMustLock(addrListLock); - pRange = (rangeItem *) ellFirst(&addrAlloc[addrType]); - while (pRange) { - if (pRange->begin == baseAddress) { - break; - } - if (pRange->begin > baseAddress) { - pRange = NULL; - break; - } - pRange = (rangeItem *) ellNext(&pRange->node); - } - epicsMutexUnlock(addrListLock); - - if (!pRange) { - return S_dev_addressNotFound; - } - - if (strcmp(pOwnerName,pRange->pOwnerName)) { - s = S_dev_addressOverlap; - errPrintf ( - s, - __FILE__, - __LINE__, - "unregister address for %s at 0X%X failed because %s owns it", - pOwnerName, - (unsigned int)baseAddress, - pRange->pOwnerName); - return s; - } - - epicsMutexMustLock(addrListLock); - ellDelete (&addrAlloc[addrType], &pRange->node); - epicsMutexUnlock(addrListLock); - - pRange->pOwnerName = ""; - devInsertAddress (&addrFree[addrType], pRange); - s = devCombineAdjacentBlocks (&addrFree[addrType], pRange); - if(s){ - errMessage (s, "devCombineAdjacentBlocks error"); - return s; - } - - return SUCCESS; -} - -/* - * devCombineAdjacentBlocks() - */ -static long devCombineAdjacentBlocks( - ELLLIST *pRangeList, - rangeItem *pRange) -{ - rangeItem *pBefore; - rangeItem *pAfter; - - pBefore = (rangeItem *) ellPrevious (&pRange->node); - pAfter = (rangeItem *) ellNext (&pRange->node); - - /* - * combine adjacent blocks - */ - if (pBefore) { - if (pBefore->end == pRange->begin-1) { - epicsMutexMustLock(addrListLock); - pRange->begin = pBefore->begin; - ellDelete (pRangeList, &pBefore->node); - epicsMutexUnlock(addrListLock); - free ((void *)pBefore); - } - } - - if (pAfter) { - if (pAfter->begin == pRange->end+1) { - epicsMutexMustLock(addrListLock); - pRange->end = pAfter->end; - ellDelete (pRangeList, &pAfter->node); - epicsMutexUnlock(addrListLock); - free((void *)pAfter); - } - } - - return SUCCESS; -} - -/* - * devInsertAddress() - */ -static void devInsertAddress( -ELLLIST *pRangeList, -rangeItem *pNewRange) -{ - rangeItem *pBefore; - rangeItem *pAfter; - - epicsMutexMustLock(addrListLock); - pAfter = (rangeItem *) ellFirst (pRangeList); - while (pAfter) { - if (pNewRange->end < pAfter->begin) { - break; - } - pAfter = (rangeItem *) ellNext (&pAfter->node); - } - - if (pAfter) { - pBefore = (rangeItem *) ellPrevious (&pAfter->node); - ellInsert (pRangeList, &pBefore->node, &pNewRange->node); - } - else { - ellAdd (pRangeList, &pNewRange->node); - } - epicsMutexUnlock(addrListLock); -} - -/* - * devAllocAddress() - */ -long devAllocAddress( - const char *pOwnerName, - epicsAddressType addrType, - size_t size, - unsigned alignment, /* n ls bits zero in base addr*/ - volatile void ** pLocalAddress ) -{ - int s; - rangeItem *pRange; - size_t base = 0; - - if (!devLibInitFlag) { - s = devLibInit(); - if(s){ - return s; - } - } - - s = addrVerify (addrType, 0, size); - if(s){ - return s; - } - - if (size == 0) { - return S_dev_lowValue; - } - - epicsMutexMustLock(addrListLock); - pRange = (rangeItem *) ellFirst (&addrFree[addrType]); - while (pRange) { - if ((pRange->end - pRange->begin) + 1 >= size){ - s = blockFind ( - addrType, - pRange, - size, - alignment, - &base); - if (s==SUCCESS) { - break; - } - } - pRange = (rangeItem *) pRange->node.next; - } - epicsMutexUnlock(addrListLock); - - if(!pRange){ - s = S_dev_deviceDoesNotFit; - errMessage(s, epicsAddressTypeName[addrType]); - return s; - } - - s = devInstallAddr (pRange, pOwnerName, addrType, base, - size, pLocalAddress); - - return s; -} - -/* - * addrVerify() - * - * care has been taken here not to overflow type size_t - */ -static long addrVerify(epicsAddressType addrType, size_t base, size_t size) -{ - if (addrType>=atLast) { - return S_dev_uknAddrType; - } - - if (size == 0) { - return addrFail[addrType]; - } - - if (size-1 > addrLast[addrType]) { - return addrFail[addrType]; - } - - if (base > addrLast[addrType]) { - return addrFail[addrType]; - } - - if (size - 1 > addrLast[addrType] - base) { - return addrFail[addrType]; - } - - return SUCCESS; -} - -/* - * devLibInit() - */ -static long devLibInit (void) -{ - rangeItem *pRange; - int i; - - - if(devLibInitFlag) return(SUCCESS); - if(!pdevLibVME) { - epicsPrintf ("pdevLibVME is NULL\n"); - return S_dev_internal; - } - - if (NELEMENTS(addrAlloc) != NELEMENTS(addrFree)) { - return S_dev_internal; - } - - addrListLock = epicsMutexMustCreate(); - - epicsMutexMustLock(addrListLock); - for (i=0; ipOwnerName = ""; - pRange->pPhysical = NULL; - pRange->begin = 0; - pRange->end = addrLast[i]; - ellAdd (&addrFree[i], &pRange->node); - } - epicsMutexUnlock(addrListLock); - devLibInitFlag = TRUE; - return pdevLibVME->pDevInit(); -} - -/* - * devAddressMap() - */ -long devAddressMap(void) -{ - return devListAddressMap(addrAlloc); -} - -/* - * devListAddressMap() - */ -static long devListAddressMap(ELLLIST *pRangeList) -{ - rangeItem *pri; - int i; - long s; - - if (!devLibInitFlag) { - s = devLibInit (); - if (s) { - return s; - } - } - - epicsMutexMustLock(addrListLock); - for (i=0; ibegin, - addrHexDig[i], - (unsigned long) pri->end, - pri->pPhysical, - pri->pOwnerName); - pri = (rangeItem *) ellNext (&pri->node); - } - } - epicsMutexUnlock(addrListLock); - - return SUCCESS; -} - - -/* - * - * blockFind() - * - * Find unoccupied block in a large block - * - */ -static long blockFind ( - epicsAddressType addrType, - const rangeItem *pRange, - /* size needed */ - size_t requestSize, - /* n ls bits zero in base addr */ - unsigned alignment, - /* base address found */ - size_t *pBase) -{ - int s = SUCCESS; - size_t bb; - size_t mask; - size_t newBase; - size_t newSize; - - /* - * align the block base - */ - mask = devCreateMask (alignment); - newBase = pRange->begin; - if ( mask & newBase ) { - newBase |= mask; - newBase++; - } - - if ( requestSize == 0) { - return S_dev_badRequest; - } - - /* - * align size of block - */ - newSize = requestSize; - if (mask & newSize) { - newSize |= mask; - newSize++; - } - - if (pRange->end - pRange->begin + 1 < newSize) { - return S_dev_badRequest; - } - - bb = pRange->begin; - while (bb <= (pRange->end + 1) - newSize) { - s = devNoResponseProbe (addrType, bb, newSize); - if (s==SUCCESS) { - *pBase = bb; - return SUCCESS; - } - bb += newSize; - } - - return s; -} - -/* - * devNoResponseProbe() - */ -long devNoResponseProbe (epicsAddressType addrType, - size_t base, size_t size) -{ - volatile void *pPhysical; - size_t probe; - size_t byteNo; - unsigned wordSize; - union { - char charWord; - short shortWord; - int intWord; - long longWord; - }allWordSizes; - long s; - - if (!devLibInitFlag) { - s = devLibInit(); - if (s) { - return s; - } - } - - byteNo = 0; - while (byteNo < size) { - - probe = base + byteNo; - - /* - * for all word sizes - */ - for (wordSize=1; wordSize<=sizeof(allWordSizes); wordSize <<= 1) { - /* - * only check naturally aligned words - */ - if ( (probe&(wordSize-1)) != 0 ) { - break; - } - - if (byteNo+wordSize>size) { - break; - } - - /* - * every byte in the block must - * map to a physical address - */ - s = (*pdevLibVME->pDevMapAddr) (addrType, 0, probe, wordSize, &pPhysical); - if (s!=SUCCESS) { - return s; - } - - /* - * verify that no device is present - */ - s = (*pdevLibVME->pDevReadProbe)(wordSize, pPhysical, &allWordSizes); - if (s==SUCCESS) { - return S_dev_addressOverlap; - } - } - byteNo++; - } - return SUCCESS; -} - -long devConnectInterruptVME( -unsigned vectorNumber, -void (*pFunction)(void *), -void *parameter ) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber, - pFunction, parameter); -} - -long devDisconnectInterruptVME( -unsigned vectorNumber, -void (*pFunction)(void *) ) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber, pFunction); -} - -int devInterruptInUseVME (unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevInterruptInUseVME) (level); -} - -long devEnableInterruptLevelVME (unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevEnableInterruptLevelVME) (level); -} - -long devDisableInterruptLevelVME (unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - return (*pdevLibVME->pDevDisableInterruptLevelVME) (level); -} - -/* - * devConnectInterrupt () - * - * !! DEPRECATED !! - */ -long devConnectInterrupt( -epicsInterruptType intType, -unsigned vectorNumber, -void (*pFunction)(void *), -void *parameter) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - switch(intType){ - case intVME: - case intVXI: - return (*pdevLibVME->pDevConnectInterruptVME) (vectorNumber, - pFunction, parameter); - default: - return S_dev_uknIntType; - } -} - -/* - * - * devDisconnectInterrupt() - * - * !! DEPRECATED !! - */ -long devDisconnectInterrupt( -epicsInterruptType intType, -unsigned vectorNumber, -void (*pFunction)(void *) -) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - switch(intType){ - case intVME: - case intVXI: - return (*pdevLibVME->pDevDisconnectInterruptVME) (vectorNumber, - pFunction); - default: - return S_dev_uknIntType; - } -} - -/* - * devEnableInterruptLevel() - * - * !! DEPRECATED !! - */ -long devEnableInterruptLevel( -epicsInterruptType intType, -unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - switch(intType){ - case intVME: - case intVXI: - return (*pdevLibVME->pDevEnableInterruptLevelVME) (level); - default: - return S_dev_uknIntType; - } -} - -/* - * devDisableInterruptLevel() - * - * !! DEPRECATED !! - */ -long devDisableInterruptLevel ( -epicsInterruptType intType, -unsigned level) -{ - long status; - - if (!devLibInitFlag) { - status = devLibInit(); - if (status) { - return status; - } - } - - switch(intType){ - case intVME: - case intVXI: - return (*pdevLibVME->pDevDisableInterruptLevelVME) (level); - default: - return S_dev_uknIntType; - } -} - -/* - * locationProbe - * - * !! DEPRECATED !! - */ -long locationProbe (epicsAddressType addrType, char *pLocation) -{ - return devNoResponseProbe (addrType, (size_t) pLocation, sizeof(long)); -} - -/****************************************************************************** - * - * The follwing may, or may not be present in the BSP for the CPU in use. - * - */ -/****************************************************************************** - * - * Routines to use to allocate and free memory present in the A24 region. - * - ******************************************************************************/ - -int devLibA24Debug = 0; /* Debugging flag */ - -void *devLibA24Calloc(size_t size) -{ - void *ret; - - ret = devLibA24Malloc(size); - - if (ret == NULL) - return (NULL); - - memset(ret, 0x00, size); - return(ret); -} - -void *devLibA24Malloc(size_t size) -{ - void *ret; - - if (devLibA24Debug) - epicsPrintf ("devLibA24Malloc(%u) entered\n", (unsigned int)size); - - ret = pdevLibVME->pDevA24Malloc(size); - return(ret); -} - -void devLibA24Free(void *pBlock) -{ - if (devLibA24Debug) - epicsPrintf("devLibA24Free(%p) entered\n", pBlock); - - pdevLibVME->pDevA24Free(pBlock); -} diff --git a/src/libCom/osi/devLibVME.h b/src/libCom/osi/devLibVME.h deleted file mode 100644 index 4fb17f0c2..000000000 --- a/src/libCom/osi/devLibVME.h +++ /dev/null @@ -1,306 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLib.h */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - */ - -#ifndef INCdevLibh -#define INCdevLibh 1 - -#include "dbDefs.h" -#include "osdVME.h" -#include "errMdef.h" -#include "shareLib.h" -#include "devLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epdevAddressType & EPICStovxWorksAddrType - * devLib.c must change in unison - */ -typedef enum { - atVMEA16, - atVMEA24, - atVMEA32, - atISA, /* memory mapped ISA access (until now only on PC) */ - atVMECSR, /* VME-64 CR/CSR address space */ - atLast /* atLast must be the last enum in this list */ - } epicsAddressType; - -/* - * pointer to an array of strings for each of - * the above address types - */ -epicsShareExtern const char *epicsAddressTypeName[]; - -#ifdef __cplusplus -} -#endif - -/* - * To retain compatibility include everything by default - */ -#ifndef NO_DEVLIB_COMPAT -# include "devLibVMEImpl.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * General API - * - * This section applies to all bus types - */ - -epicsShareFunc long devAddressMap(void); /* print an address map */ - -/* - * devBusToLocalAddr() - * - * OSI routine to translate bus addresses their local CPU address mapping - */ -epicsShareFunc long devBusToLocalAddr ( - epicsAddressType addrType, - size_t busAddr, - volatile void **ppLocalAddr); -/* - * devReadProbe() - * - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -epicsShareFunc long devReadProbe ( - unsigned wordSize, volatile const void *ptr, void *pValueRead); - -/* - * devNoResponseProbe() - * - * Verifies that no devices respond at naturally aligned words - * within the specified address range. Return success if no devices - * respond. Returns an error if a device does respond or if - * a physical address for a naturally aligned word cant be mapped. - * Checks all naturally aligned word sizes between char and long for - * the entire specified range of bytes. - */ -epicsShareFunc long devNoResponseProbe( - epicsAddressType addrType, - size_t base, - size_t size -); - -/* - * devWriteProbe - * - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -epicsShareFunc long devWriteProbe ( - unsigned wordSize, volatile void *ptr, const void *pValueWritten); - -epicsShareFunc long devRegisterAddress( - const char *pOwnerName, - epicsAddressType addrType, - size_t logicalBaseAddress, - size_t size, /* bytes */ - volatile void **pPhysicalAddress); - -epicsShareFunc long devUnregisterAddress( - epicsAddressType addrType, - size_t logicalBaseAddress, - const char *pOwnerName); - -/* - * allocate and register an unoccupied address block - */ -epicsShareFunc long devAllocAddress( - const char *pOwnerName, - epicsAddressType addrType, - size_t size, - unsigned alignment, /*n ls bits zero in addr*/ - volatile void **pLocalAddress); - -/* - * VME API - * - * Functions in this section apply only to the VME bus type - */ - -/* - * connect ISR to a VME interrupt vector - */ -epicsShareFunc long devConnectInterruptVME( - unsigned vectorNumber, - void (*pFunction)(void *), - void *parameter); - -/* - * disconnect ISR from a VME interrupt vector - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from inadvertently - * removing an interrupt handler that it didn't install - */ -epicsShareFunc long devDisconnectInterruptVME( - unsigned vectorNumber, - void (*pFunction)(void *)); - -/* - * determine if a VME interrupt vector is in use - * - * returns boolean - */ -epicsShareFunc int devInterruptInUseVME (unsigned vectorNumber); - -/* - * enable VME interrupt level - */ -epicsShareFunc long devEnableInterruptLevelVME (unsigned level); - -/* - * disable VME interrupt level - */ -epicsShareFunc long devDisableInterruptLevelVME (unsigned level); - -/* - * Routines to allocate and free memory in the A24 memory region. - * - */ -epicsShareFunc void *devLibA24Malloc(size_t); -epicsShareFunc void *devLibA24Calloc(size_t); -epicsShareFunc void devLibA24Free(void *pBlock); - -/* - * ISA API - * - * Functions in this section apply only to the ISA bus type - */ - -/* - * connect ISR to an ISA interrupt level - * (not implemented) - * (API should be reviewed) - */ -epicsShareFunc long devConnectInterruptISA( - unsigned interruptLevel, - void (*pFunction)(void *), - void *parameter); - -/* - * disconnect ISR from an ISA interrupt level - * (not implemented) - * (API should be reviewed) - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from inadvertently - * removing an interrupt handler that it didn't install - */ -epicsShareFunc long devDisconnectInterruptISA( - unsigned interruptLevel, - void (*pFunction)(void *)); - -/* - * determine if an ISA interrupt level is in use - * (not implemented) - * - * returns boolean - */ -epicsShareFunc int devInterruptLevelInUseISA (unsigned interruptLevel); - -/* - * enable ISA interrupt level - */ -epicsShareFunc long devEnableInterruptLevelISA (unsigned level); - -/* - * disable ISA interrupt level - */ -epicsShareFunc long devDisableInterruptLevelISA (unsigned level); - -/* - * Deprecated interface - */ - -#ifndef NO_DEVLIB_OLD_INTERFACE - -typedef enum {intVME, intVXI, intISA} epicsInterruptType; - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use one of devConnectInterruptVME, devConnectInterruptPCI, - * devConnectInterruptISA etc. devConnectInterrupt will be removed - * in a future release. - */ -epicsShareFunc long devConnectInterrupt( - epicsInterruptType intType, - unsigned vectorNumber, - void (*pFunction)(void *), - void *parameter); - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use one of devDisconnectInterruptVME, devDisconnectInterruptPCI, - * devDisconnectInterruptISA etc. devDisconnectInterrupt will be removed - * in a future release. - */ -epicsShareFunc long devDisconnectInterrupt( - epicsInterruptType intType, - unsigned vectorNumber, - void (*pFunction)(void *)); - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use one of devEnableInterruptLevelVME, devEnableInterruptLevelPCI, - * devEnableInterruptLevelISA etc. devEnableInterruptLevel will be removed - * in a future release. - */ -epicsShareFunc long devEnableInterruptLevel( - epicsInterruptType intType, unsigned level); - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use one of devDisableInterruptLevelVME, devDisableInterruptLevelISA, - * devDisableInterruptLevelPCI etc. devDisableInterruptLevel will be removed - * in a future release. - */ -epicsShareFunc long devDisableInterruptLevel ( - epicsInterruptType intType, unsigned level); - -/* - * NOTE: this routine has been deprecated. It exists - * for backwards compatibility purposes only. - * - * Please use devNoResponseProbe(). locationProbe() will be removed - * in a future release. - */ -epicsShareFunc long locationProbe (epicsAddressType addrType, char *pLocation); - -#endif /* NO_DEVLIB_OLD_INTERFACE */ - -#ifdef __cplusplus -} -#endif - -#endif /* INCdevLibh.h*/ diff --git a/src/libCom/osi/devLibVMEImpl.h b/src/libCom/osi/devLibVMEImpl.h deleted file mode 100644 index e479d869c..000000000 --- a/src/libCom/osi/devLibVMEImpl.h +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLibImpl.h */ - -/* - * Original Author: Marty Kraimer - * Author: Jeff Hill - * Date: 03-10-93 - */ - -#ifndef INCdevLibImplh -#define INCdevLibImplh 1 - -#include "dbDefs.h" -#include "shareLib.h" -#include "devLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * virtual OS layer for devLib.c - * - * The global virtual OS table pdevLibVME controls - * the behaviour of the functions defined in devLib.h. - * All of which call into the functions found in this table - * to perform system specific tasks. - */ -typedef struct devLibVME { - /* - * maps logical address to physical address, but does not detect - * two device drivers that are using the same address range - */ - long (*pDevMapAddr) (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress); - - /* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ - long (*pDevReadProbe) (unsigned wordSize, volatile const void *ptr, void *pValueRead); - - /* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ - long (*pDevWriteProbe) (unsigned wordSize, volatile void *ptr, const void *pValueWritten); - - /* - * connect ISR to a VME interrupt vector - * (required for backwards compatibility) - */ - long (*pDevConnectInterruptVME) (unsigned vectorNumber, - void (*pFunction)(void *), void *parameter); - - /* - * disconnect ISR from a VME interrupt vector - * (required for backwards compatibility) - */ - long (*pDevDisconnectInterruptVME) (unsigned vectorNumber, - void (*pFunction)(void *)); - - /* - * enable VME interrupt level - */ - long (*pDevEnableInterruptLevelVME) (unsigned level); - - /* - * disable VME interrupt level - */ - long (*pDevDisableInterruptLevelVME) (unsigned level); - /* malloc/free A24 address space */ - void *(*pDevA24Malloc)(size_t nbytes); - void (*pDevA24Free)(void *pBlock); - long (*pDevInit)(void); - - /* - * test if VME interrupt has an ISR connected - */ - int (*pDevInterruptInUseVME) (unsigned vectorNumber); -}devLibVME; - -epicsShareExtern devLibVME *pdevLibVME; - -#ifndef NO_DEVLIB_COMPAT -# define pdevLibVirtualOS pdevLibVME -typedef devLibVME devLibVirtualOS; -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /* INCdevLibImplh */ diff --git a/src/libCom/osi/epicsAssert.h b/src/libCom/osi/epicsAssert.h deleted file mode 100644 index 6f83d3a82..000000000 --- a/src/libCom/osi/epicsAssert.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * EPICS assert - * - * Author: Jeffrey O. Hill - * Date: 022795 - */ - -#ifndef INC_epicsAssert_H -#define INC_epicsAssert_H - -#include "shareLib.h" -#include "compilerDependencies.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifndef epicsAssertAuthor -# define epicsAssertAuthor 0 -#endif - -#undef assert - -#ifdef NDEBUG -# define assert(ignore) ((void) 0) -#else /* NDEBUG */ - -epicsShareFunc void epicsAssert (const char *pFile, const unsigned line, - const char *pExp, const char *pAuthorName); - -# define assert(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -#endif /* NDEBUG */ - - -/* Compile-time checks */ -#if __cplusplus>=201103L -#define STATIC_ASSERT(expr) static_assert(expr, #expr) -#else -#define STATIC_JOIN(x, y) STATIC_JOIN2(x, y) -#define STATIC_JOIN2(x, y) x ## y -#define STATIC_ASSERT(expr) \ - typedef int STATIC_JOIN(static_assert_failed_at_line_, __LINE__) \ - [ (expr) ? 1 : -1 ] EPICS_UNUSED -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsAssert_H */ diff --git a/src/libCom/osi/epicsAtomic.h b/src/libCom/osi/epicsAtomic.h deleted file mode 100644 index b3aad5c9c..000000000 --- a/src/libCom/osi/epicsAtomic.h +++ /dev/null @@ -1,217 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomic_h -#define epicsAtomic_h - -#include /* define size_t */ - -#include "compilerSpecific.h" - -#define EPICS_ATOMIC_INLINE static EPICS_ALWAYS_INLINE - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void * EpicsAtomicPtrT; - -/* load target into cache */ -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void); - -/* push cache version of target into target */ -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void); - -/* - * lock out other smp processors from accessing the target, - * load target into cache, add one to target, flush cache - * to target, allow other smp processors to access the target, - * return new value of target as modified by this operation - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ); -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ); - -/* - * lock out other smp processors from accessing the target, - * load target into cache, subtract one from target, flush cache - * to target, allow out other smp processors to access the target, - * return new value of target as modified by this operation - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ); -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ); - -/* - * lock out other smp processors from accessing the target, - * load target into cache, add/sub delta to/from target, flush cache - * to target, allow other smp processors to access the target, - * return new value of target as modified by this operation - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ); -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ); -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ); - -/* - * set cache version of target, flush cache to target - */ -EPICS_ATOMIC_INLINE void epicsAtomicSetSizeT ( size_t * pTarget, size_t newValue ); -EPICS_ATOMIC_INLINE void epicsAtomicSetIntT ( int * pTarget, int newValue ); -EPICS_ATOMIC_INLINE void epicsAtomicSetPtrT ( EpicsAtomicPtrT * pTarget, EpicsAtomicPtrT newValue ); - -/* - * fetch target into cache, return new value of target - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget ); -EPICS_ATOMIC_INLINE int epicsAtomicGetIntT ( const int * pTarget ); -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicGetPtrT ( const EpicsAtomicPtrT * pTarget ); - -/* - * lock out other smp processors from accessing the target, - * load target into cache, if target is equal to oldVal set target - * to newVal, flush cache to target, allow other smp processors - * to access the target, return the original value stored in the - * target - */ -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldVal, size_t newVal ); -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ); -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, - EpicsAtomicPtrT newVal ); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -/* - * options for in-line compiler intrinsic or OS specific - * implementations of the above function prototypes - * - * for some of the compilers we must define the - * in-line functions before they get used in the c++ - * in-line functions below - */ -#include "epicsAtomicCD.h" - -#ifdef __cplusplus - -namespace epics { -namespace atomic { - -/* - * overloaded c++ interface - */ - -/************* incr ***************/ -EPICS_ATOMIC_INLINE size_t increment ( size_t & v ) -{ - return epicsAtomicIncrSizeT ( & v ); -} - -EPICS_ATOMIC_INLINE int increment ( int & v ) -{ - return epicsAtomicIncrIntT ( & v ); -} - -/************* decr ***************/ -EPICS_ATOMIC_INLINE size_t decrement ( size_t & v ) -{ - return epicsAtomicDecrSizeT ( & v ); -} - -EPICS_ATOMIC_INLINE int decrement ( int & v ) -{ - return epicsAtomicDecrIntT ( & v ); -} - -/************* add ***************/ -EPICS_ATOMIC_INLINE size_t add ( size_t & v, size_t delta ) -{ - return epicsAtomicAddSizeT ( & v, delta ); -} - -EPICS_ATOMIC_INLINE int add ( int & v, int delta ) -{ - return epicsAtomicAddIntT ( & v, delta ); -} - -/************* sub ***************/ -EPICS_ATOMIC_INLINE size_t subtract ( size_t & v, size_t delta ) -{ - return epicsAtomicSubSizeT ( & v, delta ); -} - -EPICS_ATOMIC_INLINE int subtract ( int & v, int delta ) -{ - return epicsAtomicAddIntT ( & v, -delta ); -} - -/************* set ***************/ -EPICS_ATOMIC_INLINE void set ( size_t & v , size_t newValue ) -{ - epicsAtomicSetSizeT ( & v, newValue ); -} - -EPICS_ATOMIC_INLINE void set ( int & v, int newValue ) -{ - epicsAtomicSetIntT ( & v, newValue ); -} - -EPICS_ATOMIC_INLINE void set ( EpicsAtomicPtrT & v, EpicsAtomicPtrT newValue ) -{ - epicsAtomicSetPtrT ( & v, newValue ); -} - -/************* get ***************/ -EPICS_ATOMIC_INLINE size_t get ( const size_t & v ) -{ - return epicsAtomicGetSizeT ( & v ); -} - -EPICS_ATOMIC_INLINE int get ( const int & v ) -{ - return epicsAtomicGetIntT ( & v ); -} - -EPICS_ATOMIC_INLINE EpicsAtomicPtrT get ( const EpicsAtomicPtrT & v ) -{ - return epicsAtomicGetPtrT ( & v ); -} - -/************* cas ***************/ -EPICS_ATOMIC_INLINE size_t compareAndSwap ( size_t & v, - size_t oldVal, size_t newVal ) -{ - return epicsAtomicCmpAndSwapSizeT ( & v, oldVal, newVal ); -} - -EPICS_ATOMIC_INLINE int compareAndSwap ( int & v, int oldVal, int newVal ) -{ - return epicsAtomicCmpAndSwapIntT ( & v, oldVal, newVal ); -} - -EPICS_ATOMIC_INLINE EpicsAtomicPtrT compareAndSwap ( EpicsAtomicPtrT & v, - EpicsAtomicPtrT oldVal, - EpicsAtomicPtrT newVal ) -{ - return epicsAtomicCmpAndSwapPtrT ( & v, oldVal, newVal ); -} - -} /* end of name space atomic */ -} /* end of name space epics */ - -#endif /* ifdef __cplusplus */ - -#endif /* epicsAtomic_h */ diff --git a/src/libCom/osi/epicsAtomicDefault.h b/src/libCom/osi/epicsAtomicDefault.h deleted file mode 100644 index 26115ce63..000000000 --- a/src/libCom/osi/epicsAtomicDefault.h +++ /dev/null @@ -1,247 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicDefault_h -#define epicsAtomicDefault_h - -#ifdef __cpluplus -extern "C" { -#endif - -/* - * struct EpicsAtomicLockKey; - * epicsShareFunc void epicsAtomicReadMemoryBarrier (); - * epicsShareFunc void epicsAtomicWriteMemoryBarrier (); - * epicsShareFunc void epicsAtomicLock ( struct EpicsAtomicLockKey * ); - * epicsShareFunc void epicsAtomicUnock ( struct EpicsAtomicLockKey * ); - */ - -/* - * incr - */ -#ifndef EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - EpicsAtomicLockKey key; - int result; - - epicsAtomicLock ( & key ); - result = ++(*pTarget); - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -#ifndef EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - EpicsAtomicLockKey key; - size_t result; - - epicsAtomicLock ( & key ); - result = ++(*pTarget); - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -/* - * decr - */ -#ifndef EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - EpicsAtomicLockKey key; - int result; - - epicsAtomicLock ( & key ); - result = --(*pTarget); - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - EpicsAtomicLockKey key; - size_t result; - - epicsAtomicLock ( & key ); - result = --(*pTarget); - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -/* - * add/sub - */ -#ifndef EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - EpicsAtomicLockKey key; - int result; - - epicsAtomicLock ( & key ); - result = *pTarget += delta; - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ) -{ - EpicsAtomicLockKey key; - size_t result; - - epicsAtomicLock ( & key ); - result = *pTarget += delta; - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - EpicsAtomicLockKey key; - size_t result; - - epicsAtomicLock ( & key ); - result = *pTarget -= delta; - epicsAtomicUnlock ( & key ); - return result; -} -#endif - -/* - * set - */ -#ifndef EPICS_ATOMIC_SET_INTT -EPICS_ATOMIC_INLINE void epicsAtomicSetIntT ( int * pTarget, int newVal ) -{ - *pTarget = newVal; - epicsAtomicWriteMemoryBarrier (); -} -#endif - -#ifndef EPICS_ATOMIC_SET_SIZET -EPICS_ATOMIC_INLINE void epicsAtomicSetSizeT ( size_t * pTarget, size_t newVal ) -{ - *pTarget = newVal; - epicsAtomicWriteMemoryBarrier (); -} -#endif - -#ifndef EPICS_ATOMIC_SET_PTRT -EPICS_ATOMIC_INLINE void epicsAtomicSetPtrT ( EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT newVal ) -{ - *pTarget = newVal; - epicsAtomicWriteMemoryBarrier (); -} -#endif - -/* - * get - */ -#ifndef EPICS_ATOMIC_GET_INTT -EPICS_ATOMIC_INLINE int epicsAtomicGetIntT ( const int * pTarget ) -{ - epicsAtomicReadMemoryBarrier (); - return *pTarget; -} -#endif - -#ifndef EPICS_ATOMIC_GET_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget ) -{ - epicsAtomicReadMemoryBarrier (); - return *pTarget; -} -#endif - -#ifndef EPICS_ATOMIC_GET_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT - epicsAtomicGetPtrT ( const EpicsAtomicPtrT * pTarget ) -{ - epicsAtomicReadMemoryBarrier (); - return *pTarget; -} -#endif - -/* - * cmp and swap - */ -#ifndef EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, int oldval, int newval ) -{ - EpicsAtomicLockKey key; - int cur; - - epicsAtomicLock ( & key ); - cur = *pTarget; - if ( cur == oldval ) { - *pTarget = newval; - } - epicsAtomicUnlock ( & key ); - return cur; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldval, size_t newval ) -{ - EpicsAtomicLockKey key; - size_t cur; - - epicsAtomicLock ( & key ); - cur = *pTarget; - if ( cur == oldval ) { - *pTarget = newval; - } - epicsAtomicUnlock ( & key ); - return cur; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldval, EpicsAtomicPtrT newval ) -{ - EpicsAtomicLockKey key; - EpicsAtomicPtrT cur; - - epicsAtomicLock ( & key ); - cur = *pTarget; - if ( cur == oldval ) { - *pTarget = newval; - } - epicsAtomicUnlock ( & key ); - return cur; -} -#endif - -#ifdef __cpluplus -} /* end of extern "C" */ -#endif - -#endif /* epicsAtomicDefault_h */ - - diff --git a/src/libCom/osi/epicsEndian.h b/src/libCom/osi/epicsEndian.h deleted file mode 100644 index fd662822f..000000000 --- a/src/libCom/osi/epicsEndian.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_epicsEndian_H -#define INC_epicsEndian_H - -/* This file must be usable from both C and C++ */ - -#define EPICS_ENDIAN_LITTLE 1234 -#define EPICS_ENDIAN_BIG 4321 - - -/* The following OS Dependent file defines the macros - * EPICS_BYTE_ORDER and EPICS_FLOAT_WORD_ORDER to be - * one of the above EPICS_ENDIAN_ values. - */ - -#include "osdWireConfig.h" - -#ifndef EPICS_BYTE_ORDER -#error osdWireConfig.h didnt define EPICS_BYTE_ORDER -#endif - -#ifndef EPICS_FLOAT_WORD_ORDER -#error osdWireConfig.h didnt define EPICS_FLOAT_WORD_ORDER -#endif - -#endif /* INC_epicsEndian_H */ diff --git a/src/libCom/osi/epicsEvent.cpp b/src/libCom/osi/epicsEvent.cpp deleted file mode 100644 index 237f7d268..000000000 --- a/src/libCom/osi/epicsEvent.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsMutex.c */ -/* Author: Jeff Hill */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsEvent.h" -#include "epicsStdio.h" -#include "cantProceed.h" - -// vxWorks 5.4 gcc fails during compile when I use std::exception -using namespace std; - -// exception payload -class epicsEvent::invalidSemaphore : public exception -{ - const char * what () const throw (); -}; - -const char * epicsEvent::invalidSemaphore::what () const throw () -{ - return "epicsEvent::invalidSemaphore()"; -} - -// -// Its probably preferable to not make these inline because they are in -// the sharable library interface. The use of inline or not here is probably -// not an issue because all of this ends up in the operating system in system -// calls -// - -epicsEvent::epicsEvent ( epicsEventInitialState initial ) : - id ( epicsEventCreate ( initial ) ) -{ - if ( this->id == 0 ) { - throw std::bad_alloc (); - } -} - -epicsEvent::~epicsEvent () -{ - epicsEventDestroy ( this->id ); -} - -void epicsEvent::trigger () -{ - epicsEventStatus status = epicsEventTrigger (this->id); - - if (status != epicsEventOK) { - throw invalidSemaphore (); - } -} - -void epicsEvent::wait () -{ - epicsEventStatus status = epicsEventWait (this->id); - - if (status != epicsEventOK) { - throw invalidSemaphore (); - } -} - -bool epicsEvent::wait (double timeOut) -{ - epicsEventStatus status = epicsEventWaitWithTimeout (this->id, timeOut); - - if (status == epicsEventOK) { - return true; - } else if (status == epicsEventWaitTimeout) { - return false; - } - throw invalidSemaphore (); -} - -bool epicsEvent::tryWait () -{ - epicsEventStatus status = epicsEventTryWait (this->id); - - if (status == epicsEventOK) { - return true; - } else if (status == epicsEventWaitTimeout) { - return false; - } - throw invalidSemaphore (); -} - -void epicsEvent::show ( unsigned level ) const -{ - epicsEventShow ( this->id, level ); -} - - -// epicsEventMust... convenience routines for C code - -extern "C" { - -epicsShareFunc epicsEventId epicsEventMustCreate ( - epicsEventInitialState initialState) -{ - epicsEventId id = epicsEventCreate (initialState); - - if (!id) - cantProceed ("epicsEventMustCreate"); - return id; -} - -epicsShareFunc void epicsEventMustTrigger (epicsEventId id) { - epicsEventStatus status = epicsEventTrigger (id); - - if (status != epicsEventOK) - cantProceed ("epicsEventMustTrigger"); -} - -epicsShareFunc void epicsEventMustWait (epicsEventId id) { - epicsEventStatus status = epicsEventWait (id); - - if (status != epicsEventOK) - cantProceed ("epicsEventMustWait"); -} - -} // extern "C" - diff --git a/src/libCom/osi/epicsEvent.h b/src/libCom/osi/epicsEvent.h deleted file mode 100644 index e77d9a5ce..000000000 --- a/src/libCom/osi/epicsEvent.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsEventh -#define epicsEventh - -#include "shareLib.h" - -typedef struct epicsEventOSD *epicsEventId; - -typedef enum { - epicsEventOK = 0, - epicsEventWaitTimeout, - epicsEventError -} epicsEventStatus; - -/* Backwards compatibility */ -#define epicsEventWaitStatus epicsEventStatus -#define epicsEventWaitOK epicsEventOK -#define epicsEventWaitError epicsEventError - -typedef enum { - epicsEventEmpty, - epicsEventFull -} epicsEventInitialState; - -#ifdef __cplusplus - -class epicsShareClass epicsEvent { -public: - epicsEvent ( epicsEventInitialState initial = epicsEventEmpty ); - ~epicsEvent (); - void trigger (); - void signal () { this->trigger(); } - void wait (); /* blocks until full */ - bool wait ( double timeOut ); /* false if still empty at time out */ - bool tryWait (); /* false if empty */ - void show ( unsigned level ) const; - - class invalidSemaphore; /* exception payload */ -private: - epicsEvent ( const epicsEvent & ); - epicsEvent & operator = ( const epicsEvent & ); - epicsEventId id; -}; - -extern "C" { -#endif /*__cplusplus */ - -epicsShareFunc epicsEventId epicsEventCreate( - epicsEventInitialState initialState); -epicsShareFunc epicsEventId epicsEventMustCreate ( - epicsEventInitialState initialState); -epicsShareFunc void epicsEventDestroy(epicsEventId id); -epicsShareFunc epicsEventStatus epicsEventTrigger( - epicsEventId id); -epicsShareFunc void epicsEventMustTrigger(epicsEventId id); -#define epicsEventSignal(ID) epicsEventMustTrigger(ID) -epicsShareFunc epicsEventStatus epicsEventWait( - epicsEventId id); -epicsShareFunc void epicsEventMustWait(epicsEventId id); -epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout( - epicsEventId id, double timeOut); -epicsShareFunc epicsEventStatus epicsEventTryWait( - epicsEventId id); -epicsShareFunc void epicsEventShow( - epicsEventId id, unsigned int level); - -#ifdef __cplusplus -} -#endif /*__cplusplus */ - -#include "osdEvent.h" - -#endif /* epicsEventh */ diff --git a/src/libCom/osi/epicsFindSymbol.h b/src/libCom/osi/epicsFindSymbol.h deleted file mode 100644 index 9935834da..000000000 --- a/src/libCom/osi/epicsFindSymbol.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsFindSymbolh -#define epicsFindSymbolh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -epicsShareFunc void * epicsLoadLibrary(const char *name); -epicsShareFunc const char *epicsLoadError(void); -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /* epicsFindSymbolh */ diff --git a/src/libCom/osi/epicsGeneralTime.c b/src/libCom/osi/epicsGeneralTime.c deleted file mode 100644 index ca3317ee3..000000000 --- a/src/libCom/osi/epicsGeneralTime.c +++ /dev/null @@ -1,635 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2008 Diamond Light Source Ltd -* Copyright (c) 2004 Oak Ridge National Laboratory -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Original Authors: David H. Thompson & Sheng Peng (ORNL) */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsTypes.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsMessageQueue.h" -#include "epicsString.h" -#include "epicsStdioRedirect.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "epicsTimer.h" -#include "epicsInterrupt.h" -#include "osiSock.h" -#include "ellLib.h" -#include "errlog.h" -#include "cantProceed.h" -#include "envDefs.h" -#include "generalTimeSup.h" -#include "epicsGeneralTime.h" - -/* Change 'undef' to 'define' to turn on debug statements: */ -#undef DEBUG_GENERAL_TIME - -#ifdef DEBUG_GENERAL_TIME - int generalTimeDebug = 10; -# define IFDEBUG(n) \ - if (generalTimeDebug >= n) /* block or statement */ -#else -# define IFDEBUG(n) \ - if(0) /* Compiler will elide the block or statement */ -#endif - -/* Declarations */ - -typedef struct { - ELLNODE node; - char *name; - int priority; - union { - TIMECURRENTFUN Time; - TIMEEVENTFUN Event; - } get; - union { - TIMECURRENTFUN Time; - TIMEEVENTFUN Event; - } getInt; -} gtProvider; - -static struct { - epicsMutexId timeListLock; - ELLLIST timeProviders; - gtProvider *lastTimeProvider; - epicsTimeStamp lastProvidedTime; - - epicsMutexId eventListLock; - ELLLIST eventProviders; - gtProvider *lastEventProvider; - epicsTimeStamp eventTime[NUM_TIME_EVENTS]; - epicsTimeStamp lastProvidedBestTime; - - int ErrorCounts; -} gtPvt; - -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - -static const char * const tsfmt = "%Y-%m-%d %H:%M:%S.%09f"; - -/* Implementation */ - -static void generalTime_InitOnce(void *dummy) -{ - ellInit(>Pvt.timeProviders); - gtPvt.timeListLock = epicsMutexMustCreate(); - - ellInit(>Pvt.eventProviders); - gtPvt.eventListLock = epicsMutexMustCreate(); - - IFDEBUG(1) - printf("General Time Initialized\n"); -} - -void generalTime_Init(void) -{ - epicsThreadOnce(&onceId, generalTime_InitOnce, NULL); -} - - -int generalTimeGetExceptPriority(epicsTimeStamp *pDest, int *pPrio, int ignore) -{ - gtProvider *ptp; - int status = S_time_noProvider; - - generalTime_Init(); - - IFDEBUG(2) - printf("generalTimeGetExceptPriority(ignore=%d)\n", ignore); - - epicsMutexMustLock(gtPvt.timeListLock); - for (ptp = (gtProvider *)ellFirst(>Pvt.timeProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - if ((ignore > 0 && ptp->priority == ignore) || - (ignore < 0 && ptp->priority != -ignore)) - continue; - - status = ptp->get.Time(pDest); - if (status == epicsTimeOK) { - /* No ratchet, time from this routine may go backwards */ - if (pPrio) - *pPrio = ptp->priority; - break; - } - else IFDEBUG(2) - printf("gTGExP provider '%s' returned error\n", ptp->name); - } - epicsMutexUnlock(gtPvt.timeListLock); - - IFDEBUG(2) { - if (ptp && status == epicsTimeOK) { - char buff[40]; - - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, pDest); - printf("gTGExP returning %s from provider '%s'\n", - buff, ptp->name); - } - else - printf("gTGExP returning error\n"); - } - - return status; -} - -int epicsShareAPI epicsTimeGetCurrent(epicsTimeStamp *pDest) -{ - gtProvider *ptp; - int status = S_time_noProvider; - epicsTimeStamp ts; - - generalTime_Init(); - - IFDEBUG(20) - printf("epicsTimeGetCurrent()\n"); - - epicsMutexMustLock(gtPvt.timeListLock); - for (ptp = (gtProvider *)ellFirst(>Pvt.timeProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - - status = ptp->get.Time(&ts); - if (status == epicsTimeOK) { - /* check time is monotonic */ - if (epicsTimeGreaterThanEqual(&ts, >Pvt.lastProvidedTime)) { - *pDest = ts; - gtPvt.lastProvidedTime = ts; - gtPvt.lastTimeProvider = ptp; - } else { - int key; - - *pDest = gtPvt.lastProvidedTime; - key = epicsInterruptLock(); - gtPvt.ErrorCounts++; - epicsInterruptUnlock(key); - - IFDEBUG(10) { - char last[40], buff[40]; - - epicsTimeToStrftime(last, sizeof(last), tsfmt, - >Pvt.lastProvidedTime); - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("eTGC provider '%s' returned older time\n" - " %s, using %s instead\n", ptp->name, buff, last); - } - } - break; - } - } - if (status) - gtPvt.lastTimeProvider = NULL; - epicsMutexUnlock(gtPvt.timeListLock); - - IFDEBUG(20) { - if (ptp && status == epicsTimeOK) { - char buff[40]; - - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("eTGC returning %s from provider '%s'\n", - buff, ptp->name); - } - else - printf("eTGC returning error\n"); - } - - return status; -} - -int epicsTimeGetCurrentInt(epicsTimeStamp *pDest) -{ - gtProvider *ptp = gtPvt.lastTimeProvider; - - if (ptp == NULL || - ptp->getInt.Time == NULL) { - IFDEBUG(20) - epicsInterruptContextMessage("eTGCInt: No support\n"); - return S_time_noProvider; - } - - return ptp->getInt.Time(pDest); -} - - -static int generalTimeGetEventPriority(epicsTimeStamp *pDest, int eventNumber, - int *pPrio) -{ - gtProvider *ptp; - int status = S_time_noProvider; - epicsTimeStamp ts; - - generalTime_Init(); - - IFDEBUG(2) - printf("generalTimeGetEventPriority(eventNum=%d)\n", eventNumber); - - if ((eventNumber < 0 || eventNumber >= NUM_TIME_EVENTS) && - (eventNumber != epicsTimeEventBestTime)) - return S_time_badEvent; - - epicsMutexMustLock(gtPvt.eventListLock); - for (ptp = (gtProvider *)ellFirst(>Pvt.eventProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - - status = ptp->get.Event(&ts, eventNumber); - if (status == epicsTimeOK) { - gtPvt.lastEventProvider = ptp; - if (pPrio) - *pPrio = ptp->priority; - - if (eventNumber == epicsTimeEventBestTime) { - if (epicsTimeGreaterThanEqual(&ts, - >Pvt.lastProvidedBestTime)) { - *pDest = ts; - gtPvt.lastProvidedBestTime = ts; - } else { - int key; - - *pDest = gtPvt.lastProvidedBestTime; - key = epicsInterruptLock(); - gtPvt.ErrorCounts++; - epicsInterruptUnlock(key); - - IFDEBUG(10) { - char last[40], buff[40]; - - epicsTimeToStrftime(last, sizeof(last), tsfmt, - >Pvt.lastProvidedBestTime); - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("gTGEvP provider '%s' returned older time\n" - " %s, using %s instead\n", - ptp->name, buff, last); - } - } - } else { - if (epicsTimeGreaterThanEqual(pDest, - >Pvt.eventTime[eventNumber])) { - *pDest = ts; - gtPvt.eventTime[eventNumber] = ts; - } else { - int key; - - *pDest = gtPvt.eventTime[eventNumber]; - key = epicsInterruptLock(); - gtPvt.ErrorCounts++; - epicsInterruptUnlock(key); - } - - IFDEBUG(10) { - char last[40], buff[40]; - - epicsTimeToStrftime(last, sizeof(last), tsfmt, - >Pvt.lastProvidedBestTime); - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("gTGEvP provider '%s' returned older time\n" - " %s, using %s instead\n", - ptp->name, buff, last); - } - } - break; - } - else IFDEBUG(2) - printf("gTGEvP provider '%s' returned error\n", ptp->name); - } - if (status) - gtPvt.lastEventProvider = NULL; - epicsMutexUnlock(gtPvt.eventListLock); - - IFDEBUG(10) { - if (ptp && status == epicsTimeOK) { - char buff[40]; - - epicsTimeToStrftime(buff, sizeof(buff), tsfmt, &ts); - printf("gTGEvP returning %s from provider '%s'\n", - buff, ptp->name); - } - else - printf("gTGEvP returning error\n"); - } - - return status; -} - -int epicsShareAPI epicsTimeGetEvent(epicsTimeStamp *pDest, int eventNumber) -{ - if (eventNumber == epicsTimeEventCurrentTime) { - return epicsTimeGetCurrent(pDest); - } else { - return generalTimeGetEventPriority(pDest, eventNumber, NULL); - } -} - -int epicsTimeGetEventInt(epicsTimeStamp *pDest, int eventNumber) -{ - if (eventNumber == epicsTimeEventCurrentTime) { - return epicsTimeGetCurrentInt(pDest); - } else { - gtProvider *ptp = gtPvt.lastEventProvider; - - if (ptp == NULL || - ptp->getInt.Event == NULL) { - IFDEBUG(20) - epicsInterruptContextMessage("eTGEvInt: No support\n"); - return S_time_noProvider; - } - - return ptp->getInt.Event(pDest, eventNumber); - } -} - - -/* Provider Registration */ - -static void insertProvider(gtProvider *ptp, ELLLIST *plist, epicsMutexId lock) -{ - gtProvider *ptpref; - - epicsMutexMustLock(lock); - - for (ptpref = (gtProvider *)ellFirst(plist); - ptpref; ptpref = (gtProvider *)ellNext(&ptpref->node)) { - if (ptpref->priority > ptp->priority) - break; - } - - if (ptpref) { - /* Found a provider below the new one */ - ptpref = (gtProvider *)ellPrevious(&ptpref->node); - ellInsert(plist, &ptpref->node, &ptp->node); - } else { - ellAdd(plist, &ptp->node); - } - - epicsMutexUnlock(lock); -} - -static gtProvider * findProvider(ELLLIST *plist, epicsMutexId lock, - const char *name, int priority) -{ - gtProvider *ptp; - - epicsMutexMustLock(lock); - - for (ptp = (gtProvider *)ellFirst(plist); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - if (ptp->priority == priority && - !strcmp(ptp->name, name)) - break; - } - - epicsMutexUnlock(lock); - return ptp; -} - -int generalTimeRegisterEventProvider(const char *name, int priority, - TIMEEVENTFUN getEvent) -{ - gtProvider *ptp; - - generalTime_Init(); - - if (name == NULL || getEvent == NULL) - return S_time_badArgs; - - ptp = (gtProvider *)malloc(sizeof(gtProvider)); - if (ptp == NULL) - return S_time_noMemory; - - ptp->name = epicsStrDup(name); - ptp->priority = priority; - ptp->get.Event = getEvent; - ptp->getInt.Event = NULL; - - insertProvider(ptp, >Pvt.eventProviders, gtPvt.eventListLock); - - IFDEBUG(1) - printf("Registered event provider '%s' at %d\n", name, priority); - - return epicsTimeOK; -} - -int generalTimeAddIntEventProvider(const char *name, int priority, - TIMEEVENTFUN getEvent) -{ - gtProvider *ptp = findProvider(>Pvt.eventProviders, gtPvt.eventListLock, - name, priority); - if (ptp == NULL) - return S_time_noProvider; - - ptp->getInt.Event = getEvent; - - IFDEBUG(1) - printf("Event provider '%s' is interrupt-callable\n", name); - - return epicsTimeOK; -} - -int generalTimeRegisterCurrentProvider(const char *name, int priority, - TIMECURRENTFUN getTime) -{ - gtProvider *ptp; - - generalTime_Init(); - - if (name == NULL || getTime == NULL) - return S_time_badArgs; - - ptp = (gtProvider *)malloc(sizeof(gtProvider)); - if (ptp == NULL) - return S_time_noMemory; - - ptp->name = epicsStrDup(name); - ptp->priority = priority; - ptp->get.Time = getTime; - ptp->getInt.Time = NULL; - - insertProvider(ptp, >Pvt.timeProviders, gtPvt.timeListLock); - - IFDEBUG(1) - printf("Registered time provider '%s' at %d\n", name, priority); - - return epicsTimeOK; -} - -int generalTimeAddIntCurrentProvider(const char *name, int priority, - TIMECURRENTFUN getTime) -{ - gtProvider *ptp = findProvider(>Pvt.timeProviders, gtPvt.timeListLock, - name, priority); - if (ptp == NULL) - return S_time_noProvider; - - ptp->getInt.Time = getTime; - - IFDEBUG(1) - printf("Time provider '%s' is interrupt-callable\n", name); - - return epicsTimeOK; -} - -/* - * Provide an optional "last resort" provider for Event Time. - * - * This is deliberately optional, as it represents site policy. - * It is intended to be installed as an EventTime provider at the lowest - * priority, to return the current time for an event if there is no - * better time provider for event times. - * - * Typically, this will only be used during startup, or a time-provider - * resynchronisation, where events are being generated by the event system - * but the time provided by the system is not yet valid. - */ -static int lastResortGetEvent(epicsTimeStamp *timeStamp, int eventNumber) -{ - return epicsTimeGetCurrent(timeStamp); -} - -int installLastResortEventProvider(void) -{ - return generalTimeEventTpRegister("Last Resort Event", - LAST_RESORT_PRIORITY, lastResortGetEvent); -} - - -/* Status Report */ - -long generalTimeReport(int level) -{ - int items; - - if (onceId == EPICS_THREAD_ONCE_INIT) { - printf("General time framework not yet initialized.\n"); - return epicsTimeOK; - } - - printf("Backwards time errors prevented %u times.\n\n", - generalTimeGetErrorCounts()); - - /* Use an output buffer to avoid holding mutexes during printing */ - - printf("Current Time Providers:\n"); - epicsMutexMustLock(gtPvt.timeListLock); - if ((items = ellCount(>Pvt.timeProviders))) { - gtProvider *ptp; - char *message; /* Temporary output buffer */ - char *pout; - - message = calloc(items, 80 * 2); /* Each provider needs 2 lines */ - if (!message) { - epicsMutexUnlock(gtPvt.timeListLock); - printf("Out of memory\n"); - return S_time_noMemory; - } - - pout = message; - - for (ptp = (gtProvider *)ellFirst(>Pvt.timeProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - pout += sprintf(pout, " \"%s\", priority = %d\n", - ptp->name, ptp->priority); - if (level) { - epicsTimeStamp tempTS; - if (ptp->get.Time(&tempTS) == epicsTimeOK) { - char tempTSText[40]; - epicsTimeToStrftime(tempTSText, sizeof(tempTSText), - "%Y-%m-%d %H:%M:%S.%06f", &tempTS); - pout += sprintf(pout, "\tCurrent Time is %s.\n", - tempTSText); - } else { - pout += sprintf(pout, "\tCurrent Time not available\n"); - } - } - } - epicsMutexUnlock(gtPvt.timeListLock); - puts(message); - free(message); - } else { - epicsMutexUnlock(gtPvt.timeListLock); - printf("\tNo Providers registered.\n"); - } - - printf("Event Time Providers:\n"); - epicsMutexMustLock(gtPvt.eventListLock); - if ((items = ellCount(>Pvt.eventProviders))) - { - gtProvider *ptp; - char *message; /* Temporary output buffer */ - char *pout; - - message = calloc(items, 80); /* Each provider needs 1 line, */ - if (!message) { - epicsMutexUnlock(gtPvt.eventListLock); - printf("Out of memory\n"); - return S_time_noMemory; - } - - pout = message; - - for (ptp = (gtProvider *)ellFirst(>Pvt.eventProviders); - ptp; ptp = (gtProvider *)ellNext(&ptp->node)) { - pout += sprintf(pout, " \"%s\", priority = %d\n", - ptp->name, ptp->priority); - } - epicsMutexUnlock(gtPvt.eventListLock); - puts(message); - free(message); - } - else - { - epicsMutexUnlock(gtPvt.eventListLock); - printf("\tNo Providers registered.\n"); - } - - return epicsTimeOK; -} - -/* - * Access to internal status values. - */ - -void generalTimeResetErrorCounts(void) -{ - int key = epicsInterruptLock(); - gtPvt.ErrorCounts = 0; - epicsInterruptUnlock(key); -} - -int generalTimeGetErrorCounts(void) -{ - int key = epicsInterruptLock(); - int errors = gtPvt.ErrorCounts; - epicsInterruptUnlock(key); - return errors; -} - -const char * generalTimeCurrentProviderName(void) -{ - if (gtPvt.lastTimeProvider) - return gtPvt.lastTimeProvider->name; - return NULL; -} - -const char * generalTimeEventProviderName(void) -{ - if (gtPvt.lastEventProvider) - return gtPvt.lastEventProvider->name; - return NULL; -} - -const char * generalTimeHighestCurrentName(void) -{ - gtProvider *ptp; - - epicsMutexMustLock(gtPvt.timeListLock); - ptp = (gtProvider *)ellFirst(>Pvt.timeProviders); - epicsMutexUnlock(gtPvt.timeListLock); - return ptp ? ptp->name : NULL; -} diff --git a/src/libCom/osi/epicsGeneralTime.h b/src/libCom/osi/epicsGeneralTime.h deleted file mode 100644 index 3adc23705..000000000 --- a/src/libCom/osi/epicsGeneralTime.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2008 Diamond Light Source Ltd -* Copyright (c) 2004 Oak Ridge National Laboratory -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_epicsGeneralTime_H -#define INC_epicsGeneralTime_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define NUM_TIME_EVENTS 256 -/* Time Events are numbered 0 through (NUM_TIME_EVENTS-1) */ - -epicsShareFunc void generalTime_Init(void); - -epicsShareFunc int installLastResortEventProvider(void); - -epicsShareFunc void generalTimeResetErrorCounts(void); -epicsShareFunc int generalTimeGetErrorCounts(void); - -epicsShareFunc const char * generalTimeCurrentProviderName(void); -epicsShareFunc const char * generalTimeEventProviderName(void); -epicsShareFunc const char * generalTimeHighestCurrentName(void); - -/* Original names, for compatibility */ -#define generalTimeCurrentTpName generalTimeCurrentProviderName -#define generalTimeEventTpName generalTimeEventProviderName - -epicsShareFunc long generalTimeReport(int interest); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsGeneralTime_H */ diff --git a/src/libCom/osi/epicsInterrupt.h b/src/libCom/osi/epicsInterrupt.h deleted file mode 100644 index 93b443810..000000000 --- a/src/libCom/osi/epicsInterrupt.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsInterrupth -#define epicsInterrupth - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -epicsShareFunc int epicsInterruptLock(void); -epicsShareFunc void epicsInterruptUnlock(int key); -epicsShareFunc int epicsInterruptIsInterruptContext(void); -epicsShareFunc void epicsInterruptContextMessage(const char *message); - -#ifdef __cplusplus -} -#endif - -#include "osdInterrupt.h" - -#endif /* epicsInterrupth */ diff --git a/src/libCom/osi/epicsMath.cpp b/src/libCom/osi/epicsMath.cpp deleted file mode 100644 index 1388e658a..000000000 --- a/src/libCom/osi/epicsMath.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonna LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMath.cpp */ - -#define epicsExportSharedSymbols -#include - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4723) -#endif - -#ifndef NAN -static float makeNAN ( void ) -{ - float a = 0, b = 0; - return a / b; -} -#define NAN makeNAN() -#endif - -#ifndef INFINITY -static float makeINF ( void ) -{ - float a = 1, b = 0; - return a / b; -} -#define INFINITY makeINF() -#endif - -extern "C" { -epicsShareDef float epicsNAN = NAN; -epicsShareDef float epicsINF = INFINITY; -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - diff --git a/src/libCom/osi/epicsMessageQueue.cpp b/src/libCom/osi/epicsMessageQueue.cpp deleted file mode 100644 index 1527b3d3a..000000000 --- a/src/libCom/osi/epicsMessageQueue.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsMessageQueue.h" -#include "epicsStdio.h" - -epicsMessageQueue::epicsMessageQueue(unsigned int aCapacity, - unsigned int aMaxMessageSize) - : id ( epicsMessageQueueCreate(aCapacity, aMaxMessageSize) ) -{ - if (id == NULL) - throw std::bad_alloc (); -} - -epicsMessageQueue::~epicsMessageQueue() -{ - epicsMessageQueueDestroy(id); -} - -int -epicsMessageQueue::trySend(void *message, unsigned int size) -{ - return epicsMessageQueueTrySend(id, message, size); -} - -int -epicsMessageQueue::send(void *message, unsigned int size) -{ - return epicsMessageQueueSend(id, message, size); -} - -int -epicsMessageQueue::send(void *message, unsigned int size, double timeout) -{ - return epicsMessageQueueSendWithTimeout(id, message, size, timeout); -} - -int -epicsMessageQueue::tryReceive(void *message, unsigned int size ) -{ - return epicsMessageQueueTryReceive(id, message, size); -} - -int -epicsMessageQueue::receive(void *message, unsigned int size ) -{ - return epicsMessageQueueReceive(id, message, size); -} - -int -epicsMessageQueue::receive(void *message, unsigned int size, double timeout) -{ - return epicsMessageQueueReceiveWithTimeout(id, message, size, timeout); -} - -unsigned int -epicsMessageQueue::pending() -{ - return epicsMessageQueuePending(id); -} - -void -epicsMessageQueue::show(unsigned int level) -{ - epicsMessageQueueShow(id, level); -} diff --git a/src/libCom/osi/epicsMessageQueue.h b/src/libCom/osi/epicsMessageQueue.h deleted file mode 100644 index c6a98fd47..000000000 --- a/src/libCom/osi/epicsMessageQueue.h +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -/* - * Interthread message passing - */ -#ifndef epicsMessageQueueh -#define epicsMessageQueueh - -#include "epicsAssert.h" -#include "shareLib.h" - -typedef struct epicsMessageQueueOSD *epicsMessageQueueId; - -#ifdef __cplusplus - -class epicsShareClass epicsMessageQueue { -public: - epicsMessageQueue ( unsigned int capacity, - unsigned int maximumMessageSize ); - ~epicsMessageQueue (); - int trySend ( void *message, unsigned int messageSize ); - int send ( void *message, unsigned int messageSize); - int send ( void *message, unsigned int messageSize, double timeout ); - int tryReceive ( void *message, unsigned int size ); - int receive ( void *message, unsigned int size ); - int receive ( void *message, unsigned int size, double timeout ); - void show ( unsigned int level = 0 ); - unsigned int pending (); - -private: /* Prevent compiler-generated member functions */ - /* default constructor, copy constructor, assignment operator */ - epicsMessageQueue(); - epicsMessageQueue(const epicsMessageQueue &); - epicsMessageQueue& operator=(const epicsMessageQueue &); - - epicsMessageQueueId id; -}; - -extern "C" { -#endif /*__cplusplus */ - -epicsShareFunc epicsMessageQueueId epicsShareAPI epicsMessageQueueCreate( - unsigned int capacity, - unsigned int maximumMessageSize); -epicsShareFunc void epicsShareAPI epicsMessageQueueDestroy( - epicsMessageQueueId id); -epicsShareFunc int epicsShareAPI epicsMessageQueueTrySend( - epicsMessageQueueId id, - void *message, - unsigned int messageSize); -epicsShareFunc int epicsShareAPI epicsMessageQueueSend( - epicsMessageQueueId id, - void *message, - unsigned int messageSize); -epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int messageSize, - double timeout); -epicsShareFunc int epicsShareAPI epicsMessageQueueTryReceive( - epicsMessageQueueId id, - void *message, - unsigned int size); -epicsShareFunc int epicsShareAPI epicsMessageQueueReceive( - epicsMessageQueueId id, - void *message, - unsigned int size); -epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int size, - double timeout); -epicsShareFunc int epicsShareAPI epicsMessageQueuePending( - epicsMessageQueueId id); -epicsShareFunc void epicsShareAPI epicsMessageQueueShow( - epicsMessageQueueId id, - int level); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#include "osdMessageQueue.h" - -#endif /* epicsMessageQueueh */ diff --git a/src/libCom/osi/epicsMutex.cpp b/src/libCom/osi/epicsMutex.cpp deleted file mode 100644 index 7c8d05056..000000000 --- a/src/libCom/osi/epicsMutex.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMutex.cpp */ -/* Author: Marty Kraimer and Jeff Hill Date: 03APR01 */ - -/* - * NOTES: - * 1) LOG_LAST_OWNER feature is normally commented out because - * it slows down the system at run time, anfd because its not - * currently safe to convert a thread id to a thread name because - * the thread may have exited making the thread id invalid. - */ - -#include - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "epicsThread.h" -#include "valgrind/valgrind.h" -#include "ellLib.h" -#include "errlog.h" -#include "epicsMutex.h" -#include "epicsThread.h" - -static epicsThreadOnceId epicsMutexOsiOnce = EPICS_THREAD_ONCE_INIT; -static ELLLIST mutexList; -static ELLLIST freeList; - -struct epicsMutexParm { - ELLNODE node; - epicsMutexOSD * id; -# ifdef LOG_LAST_OWNER - epicsThreadId lastOwner; -# endif - const char *pFileName; - int lineno; -}; - -static epicsMutexOSD * epicsMutexGlobalLock; - - -// vxWorks 5.4 gcc fails during compile when I use std::exception -using namespace std; - -// exception payload -class epicsMutex::mutexCreateFailed : public exception -{ - const char * what () const throw (); -}; - -const char * epicsMutex::mutexCreateFailed::what () const throw () -{ - return "epicsMutex::mutexCreateFailed()"; -} - -// exception payload -class epicsMutex::invalidMutex : public exception -{ - const char * what () const throw (); -}; - -const char * epicsMutex::invalidMutex::what () const throw () -{ - return "epicsMutex::invalidMutex()"; -} - -static void epicsMutexOsiInit(void *) { - ellInit(&mutexList); - ellInit(&freeList); - VALGRIND_CREATE_MEMPOOL(&freeList, 0, 0); - epicsMutexGlobalLock = epicsMutexOsdCreate(); -} - -epicsMutexId epicsShareAPI epicsMutexOsiCreate( - const char *pFileName,int lineno) -{ - epicsMutexOSD * id; - - epicsThreadOnce(&epicsMutexOsiOnce, epicsMutexOsiInit, NULL); - - id = epicsMutexOsdCreate(); - if(!id) { - return 0; - } - epicsMutexLockStatus lockStat = - epicsMutexOsdLock(epicsMutexGlobalLock); - assert ( lockStat == epicsMutexLockOK ); - epicsMutexParm *pmutexNode = - reinterpret_cast < epicsMutexParm * > ( ellFirst(&freeList) ); - if(pmutexNode) { - ellDelete(&freeList,&pmutexNode->node); - VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode); - } else { - pmutexNode = static_cast < epicsMutexParm * > ( calloc(1,sizeof(epicsMutexParm)) ); - } - VALGRIND_MEMPOOL_ALLOC(&freeList, pmutexNode, sizeof(epicsMutexParm)); - pmutexNode->id = id; -# ifdef LOG_LAST_OWNER - pmutexNode->lastOwner = 0; -# endif - pmutexNode->pFileName = pFileName; - pmutexNode->lineno = lineno; - ellAdd(&mutexList,&pmutexNode->node); - epicsMutexOsdUnlock(epicsMutexGlobalLock); - return(pmutexNode); -} - -epicsMutexId epicsShareAPI epicsMutexOsiMustCreate( - const char *pFileName,int lineno) -{ - epicsMutexId id = epicsMutexOsiCreate(pFileName,lineno); - assert(id); - return(id ); -} - -void epicsShareAPI epicsMutexDestroy(epicsMutexId pmutexNode) -{ - epicsMutexLockStatus lockStat = - epicsMutexOsdLock(epicsMutexGlobalLock); - assert ( lockStat == epicsMutexLockOK ); - ellDelete(&mutexList,&pmutexNode->node); - epicsMutexOsdDestroy(pmutexNode->id); - VALGRIND_MEMPOOL_FREE(&freeList, pmutexNode); - VALGRIND_MEMPOOL_ALLOC(&freeList, &pmutexNode->node, sizeof(pmutexNode->node)); - ellAdd(&freeList,&pmutexNode->node); - epicsMutexOsdUnlock(epicsMutexGlobalLock); -} - -void epicsShareAPI epicsMutexUnlock(epicsMutexId pmutexNode) -{ - epicsMutexOsdUnlock(pmutexNode->id); -} - -epicsMutexLockStatus epicsShareAPI epicsMutexLock( - epicsMutexId pmutexNode) -{ - epicsMutexLockStatus status = - epicsMutexOsdLock(pmutexNode->id); -# ifdef LOG_LAST_OWNER - if ( status == epicsMutexLockOK ) { - pmutexNode->lastOwner = epicsThreadGetIdSelf(); - } -# endif - return status; -} - -epicsMutexLockStatus epicsShareAPI epicsMutexTryLock( - epicsMutexId pmutexNode) -{ - epicsMutexLockStatus status = - epicsMutexOsdTryLock(pmutexNode->id); -# ifdef LOG_LAST_OWNER - if ( status == epicsMutexLockOK ) { - pmutexNode->lastOwner = epicsThreadGetIdSelf(); - } -# endif - return status; -} - -/* Empty the freeList. - * Called from epicsExit.c, but not via epicsAtExit() - * to avoid the possibility of a circular reference. - */ -extern "C" -void epicsMutexCleanup(void) -{ - ELLNODE *cur; - epicsMutexLockStatus lockStat = - epicsMutexOsdLock(epicsMutexGlobalLock); - assert ( lockStat == epicsMutexLockOK ); - - while((cur=ellGet(&freeList))!=NULL) { - VALGRIND_MEMPOOL_FREE(&freeList, cur); - free(cur); - } - - epicsMutexOsdUnlock(epicsMutexGlobalLock); -} - -void epicsShareAPI epicsMutexShow( - epicsMutexId pmutexNode, unsigned int level) -{ -# ifdef LOG_LAST_OWNER - char threadName [255]; - if ( pmutexNode->lastOwner ) { -# error currently not safe to fetch name for stale thread - epicsThreadGetName ( pmutexNode->lastOwner, - threadName, sizeof ( threadName ) ); - } - else { - strcpy ( threadName, "" ); - } - printf("epicsMutexId %p last owner \"%s\" source %s line %d\n", - (void *)pmutexNode, threadName, - pmutexNode->pFileName, pmutexNode->lineno); -# else - printf("epicsMutexId %p source %s line %d\n", - (void *)pmutexNode, pmutexNode->pFileName, - pmutexNode->lineno); -# endif - if ( level > 0 ) { - epicsMutexOsdShow(pmutexNode->id,level-1); - } -} - -void epicsShareAPI epicsMutexShowAll(int onlyLocked,unsigned int level) -{ - epicsMutexParm *pmutexNode; - - if (epicsMutexOsiOnce == EPICS_THREAD_ONCE_INIT) - return; - - printf("ellCount(&mutexList) %d ellCount(&freeList) %d\n", - ellCount(&mutexList),ellCount(&freeList)); - epicsMutexLockStatus lockStat = - epicsMutexOsdLock(epicsMutexGlobalLock); - assert ( lockStat == epicsMutexLockOK ); - pmutexNode = reinterpret_cast < epicsMutexParm * > ( ellFirst(&mutexList) ); - while(pmutexNode) { - if(onlyLocked) { - epicsMutexLockStatus status; - status = epicsMutexOsdTryLock(pmutexNode->id); - if(status==epicsMutexLockOK) { - epicsMutexOsdUnlock(pmutexNode->id); - pmutexNode = - reinterpret_cast < epicsMutexParm * > - ( ellNext(&pmutexNode->node) ); - continue; - } - } - epicsMutexShow(pmutexNode, level); - pmutexNode = - reinterpret_cast < epicsMutexParm * > ( ellNext(&pmutexNode->node) ); - } - epicsMutexOsdUnlock(epicsMutexGlobalLock); -} - -epicsMutex :: epicsMutex () : - id ( epicsMutexCreate () ) -{ - if ( this->id == 0 ) { - throw mutexCreateFailed (); - } -} - -epicsMutex :: epicsMutex ( const char *pFileName, int lineno ) : - id ( epicsMutexOsiCreate (pFileName, lineno) ) -{ - if ( this->id == 0 ) { - throw mutexCreateFailed (); - } -} - -epicsMutex ::~epicsMutex () -{ - epicsMutexDestroy ( this->id ); -} - -void epicsMutex::lock () -{ - epicsMutexLockStatus status = epicsMutexLock ( this->id ); - if ( status != epicsMutexLockOK ) { - throw invalidMutex (); - } -} - -bool epicsMutex::tryLock () -{ - epicsMutexLockStatus status = epicsMutexTryLock ( this->id ); - if ( status == epicsMutexLockOK ) { - return true; - } - else if ( status != epicsMutexLockTimeout ) { - throw invalidMutex (); - } - return false; -} - -void epicsMutex::unlock () -{ - epicsMutexUnlock ( this->id ); -} - -void epicsMutex :: show ( unsigned level ) const -{ - epicsMutexShow ( this->id, level ); -} - -static epicsThreadPrivate < epicsDeadlockDetectMutex > - * pCurrentMutexLevel = 0; - -static epicsThreadOnceId epicsDeadlockDetectMutexInit = EPICS_THREAD_ONCE_INIT; - -extern "C" -void epicsDeadlockDetectMutexInitFunc ( void * ) -{ - pCurrentMutexLevel = new epicsThreadPrivate < epicsDeadlockDetectMutex > (); -} - -epicsDeadlockDetectMutex:: - epicsDeadlockDetectMutex ( hierarchyLevel_t level ) : - hierarchyLevel ( level ), pPreviousLevel ( 0 ) -{ - epicsThreadOnce ( & epicsDeadlockDetectMutexInit, - epicsDeadlockDetectMutexInitFunc, 0 ); -} - -epicsDeadlockDetectMutex::~epicsDeadlockDetectMutex () -{ -} - -void epicsDeadlockDetectMutex::show ( unsigned level ) const -{ - this->mutex.show ( level ); -} - -void epicsDeadlockDetectMutex::lock () -{ - epicsDeadlockDetectMutex * pPrev = pCurrentMutexLevel->get(); - if ( pPrev && pPrev != this ) { - if ( pPrev->hierarchyLevel >= this->hierarchyLevel ) { - errlogPrintf ( "!!!! Deadlock Vulnerability Detected !!!! " - "at level %u and moving to level %u\n", - pPrev->hierarchyLevel, - this->hierarchyLevel ); - } - } - this->mutex.lock (); - if ( pPrev && pPrev != this ) { - pCurrentMutexLevel->set ( this ); - this->pPreviousLevel = pPrev; - } -} - -void epicsDeadlockDetectMutex::unlock () -{ - pCurrentMutexLevel->set ( this->pPreviousLevel ); - this->mutex.unlock (); -} - -bool epicsDeadlockDetectMutex::tryLock () -{ - bool success = this->mutex.tryLock (); - if ( success ) { - this->pPreviousLevel = pCurrentMutexLevel->get(); - pCurrentMutexLevel->set ( this ); - } - return success; -} - - diff --git a/src/libCom/osi/epicsMutex.h b/src/libCom/osi/epicsMutex.h deleted file mode 100644 index 6d74f9599..000000000 --- a/src/libCom/osi/epicsMutex.h +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsMutexh -#define epicsMutexh - -#include "epicsAssert.h" - -#include "shareLib.h" - -typedef struct epicsMutexParm *epicsMutexId; -typedef enum { - epicsMutexLockOK,epicsMutexLockTimeout,epicsMutexLockError -} epicsMutexLockStatus; - -#ifdef __cplusplus - -#include "compilerDependencies.h" -#include "epicsGuard.h" - -#define newEpicsMutex new epicsMutex(__FILE__,__LINE__) - -class epicsShareClass epicsMutex { -public: - typedef epicsGuard guard_t; - typedef epicsGuard release_t; - class mutexCreateFailed; /* exception payload */ - class invalidMutex; /* exception payload */ - epicsMutex (); - epicsMutex ( const char *pFileName, int lineno ); - ~epicsMutex (); - void show ( unsigned level ) const; - void lock (); /* blocks until success */ - void unlock (); - bool tryLock (); /* true if successful */ -private: - epicsMutexId id; - epicsMutex ( const epicsMutex & ); - epicsMutex & operator = ( const epicsMutex & ); -}; - -class epicsShareClass epicsDeadlockDetectMutex { -public: - typedef epicsGuard guard_t; - typedef epicsGuard release_t; - typedef unsigned hierarchyLevel_t; - epicsDeadlockDetectMutex ( unsigned hierarchyLevel_t ); - ~epicsDeadlockDetectMutex (); - void show ( unsigned level ) const; - void lock (); /* blocks until success */ - void unlock (); - bool tryLock (); /* true if successful */ -private: - epicsMutex mutex; - const hierarchyLevel_t hierarchyLevel; - class epicsDeadlockDetectMutex * pPreviousLevel; - epicsDeadlockDetectMutex ( const epicsDeadlockDetectMutex & ); - epicsDeadlockDetectMutex & operator = ( const epicsDeadlockDetectMutex & ); -}; - -#endif /*__cplusplus*/ - -#ifdef __cplusplus -extern "C" { -#endif /*__cplusplus*/ - -#define epicsMutexCreate() epicsMutexOsiCreate(__FILE__,__LINE__) -epicsShareFunc epicsMutexId epicsShareAPI epicsMutexOsiCreate( - const char *pFileName,int lineno); -#define epicsMutexMustCreate() epicsMutexOsiMustCreate(__FILE__,__LINE__) -epicsShareFunc epicsMutexId epicsShareAPI epicsMutexOsiMustCreate( - const char *pFileName,int lineno); -epicsShareFunc void epicsShareAPI epicsMutexDestroy(epicsMutexId id); -epicsShareFunc void epicsShareAPI epicsMutexUnlock(epicsMutexId id); -epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexLock( - epicsMutexId id); -#define epicsMutexMustLock(ID) { \ - epicsMutexLockStatus status = epicsMutexLock(ID); \ - assert(status == epicsMutexLockOK); \ -} -epicsShareFunc epicsMutexLockStatus epicsShareAPI epicsMutexTryLock( - epicsMutexId id); -epicsShareFunc void epicsShareAPI epicsMutexShow( - epicsMutexId id,unsigned int level); -epicsShareFunc void epicsShareAPI epicsMutexShowAll( - int onlyLocked,unsigned int level); - -/*NOTES: - epicsMutex MUST implement recursive locking - epicsMutex should implement priority inheritance and deletion safe -*/ - -/* - * The following is the interface to the OS dependent - * implementation and should NOT be called directly by - * user code - */ -struct epicsMutexOSD * epicsMutexOsdCreate(void); -void epicsMutexOsdDestroy(struct epicsMutexOSD *); -void epicsMutexOsdUnlock(struct epicsMutexOSD *); -epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD *); -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD *); -void epicsMutexOsdShow(struct epicsMutexOSD *,unsigned int level); - -#ifdef __cplusplus -} -#endif - -#include "osdMutex.h" - -#endif /* epicsMutexh */ diff --git a/src/libCom/osi/epicsReadline.c b/src/libCom/osi/epicsReadline.c deleted file mode 100644 index 936cbce99..000000000 --- a/src/libCom/osi/epicsReadline.c +++ /dev/null @@ -1,148 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "envDefs.h" -#include "epicsReadline.h" - -#define EPICS_COMMANDLINE_LIBRARY_EPICS 0 -#define EPICS_COMMANDLINE_LIBRARY_LIBTECLA 1 -#define EPICS_COMMANDLINE_LIBRARY_READLINE 2 -#define EPICS_COMMANDLINE_LIBRARY_READLINE_CURSES 2 -#define EPICS_COMMANDLINE_LIBRARY_READLINE_NCURSES 2 - -#ifndef EPICS_COMMANDLINE_LIBRARY -# define EPICS_COMMANDLINE_LIBRARY EPICS_COMMANDLINE_LIBRARY_EPICS -#endif - -struct osdContext; -struct readlineContext { - FILE *in; - char *line; - struct osdContext *osd; -}; - -static void osdReadlineBegin(struct readlineContext *); -static char * osdReadline(const char *prompt, struct readlineContext *); -static void osdReadlineEnd(struct readlineContext *); - -#if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_EPICS - -static void osdReadlineBegin(struct readlineContext * c) {} -static char * osdReadline(const char *prompt, struct readlineContext * c) { return NULL; } -static void osdReadlineEnd(struct readlineContext * c) {} - -#else - -# if EPICS_COMMANDLINE_LIBRARY == EPICS_COMMANDLINE_LIBRARY_READLINE -# include "gnuReadline.c" -# else -# include "osdReadline.c" -# endif - -#endif - -/* - * Create a command-line context - */ -void * epicsShareAPI -epicsReadlineBegin(FILE *in) -{ - struct readlineContext *readlineContext = calloc(1, sizeof(*readlineContext)); - - if (readlineContext) { - readlineContext->in = in; - readlineContext->line = NULL; - if (!envGetConfigParamPtr(&IOCSH_HISTEDIT_DISABLE)) - osdReadlineBegin(readlineContext); - } - return readlineContext; -} - -/* - * Read a line of input - */ -char * epicsShareAPI -epicsReadline (const char *prompt, void *context) -{ - struct readlineContext *readlineContext = context; - FILE *in; - char *line; - int c; /* char is unsigned on some archs, EOF is -ve */ - int linelen = 0; - int linesize = 50; - - if (readlineContext->osd) - return osdReadline(prompt, readlineContext); - - free(readlineContext->line); - readlineContext->line = NULL; - if ((in = readlineContext->in) == NULL) { - in = stdin; - if (prompt) { - fputs(prompt, stdout); - fflush(stdout); - } - } - line = (char *)malloc(linesize); - if (line == NULL) { - printf("Out of memory!\n"); - return NULL; - } - while ((c = getc(in)) != '\n') { - if (c == EOF) { - if (ferror(in)) { - if ((errno == EINTR) || (errno == EPIPE)) { - clearerr(in); - continue; - } - } - free (line); - return NULL; - } - if ((linelen + 1) >= linesize) { - char *cp; - - linesize += 50; - cp = (char *)realloc(line, linesize); - if (cp == NULL) { - printf("Out of memory!\n"); - free(line); - return NULL; - } - line = cp; - } - line[linelen++] = c; - } - line[linelen] = '\0'; - readlineContext->line = line; - return line; -} - -/* - * Destroy a command-line context - */ -void epicsShareAPI -epicsReadlineEnd (void *context) -{ - if (context) { - struct readlineContext *readlineContext = context; - - if (readlineContext->osd) - osdReadlineEnd(readlineContext); - else - free(readlineContext->line); - free(readlineContext); - } -} - diff --git a/src/libCom/osi/epicsReadline.h b/src/libCom/osi/epicsReadline.h deleted file mode 100644 index 1d0e8b761..000000000 --- a/src/libCom/osi/epicsReadline.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INC_epicsReadline_H -#define INC_epicsReadline_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -epicsShareFunc void * epicsShareAPI epicsReadlineBegin (FILE *in); -epicsShareFunc char * epicsShareAPI epicsReadline (const char *prompt, void *context); -epicsShareFunc void epicsShareAPI epicsReadlineEnd (void *context); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsReadline_H */ diff --git a/src/libCom/osi/epicsSignal.h b/src/libCom/osi/epicsSignal.h deleted file mode 100644 index 79adf71d1..000000000 --- a/src/libCom/osi/epicsSignal.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_epicsSignal_H -#define INC_epicsSignal_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -/* - * The requests in this interface are typically ignored on OS that do not implement - * POSIX signals. - */ - -struct epicsThreadOSD; - -/* - * Required to avoid problems with soft IOCs getting SIGHUPs when a - * Channel Access client disconnects - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ); - -/* - * Required to avoid terminating a process which is blocking in a - * socket send() call when the SIGPIPE signal is generated by the OS. - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ); - -/* - * required only if shutdown() and close() do not interrupt a thread blocking in - * a socket system call - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ); -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * ); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsSignal_H */ diff --git a/src/libCom/osi/epicsSpin.h b/src/libCom/osi/epicsSpin.h deleted file mode 100644 index 22ce8ec8f..000000000 --- a/src/libCom/osi/epicsSpin.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsSpinh -#define epicsSpinh - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct epicsSpin *epicsSpinId; - -epicsShareFunc epicsSpinId epicsSpinCreate(void); -epicsShareFunc epicsSpinId epicsSpinMustCreate(void); -epicsShareFunc void epicsSpinDestroy(epicsSpinId); - -epicsShareFunc void epicsSpinLock(epicsSpinId); -epicsShareFunc int epicsSpinTryLock(epicsSpinId); -epicsShareFunc void epicsSpinUnlock(epicsSpinId); - -#ifdef __cplusplus -} -#endif - -#endif /* epicsSpinh */ diff --git a/src/libCom/osi/epicsStackTrace.c b/src/libCom/osi/epicsStackTrace.c deleted file mode 100644 index 0fe6928c4..000000000 --- a/src/libCom/osi/epicsStackTrace.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsThread.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "epicsStackTracePvt.h" -#include "epicsStackTrace.h" - -/* How many stack frames to capture */ -#define MAXDEPTH 100 - -static epicsThreadOnceId stackTraceInitId = EPICS_THREAD_ONCE_INIT; -static epicsMutexId stackTraceMtx; - -static void stackTraceInit(void *unused) -{ - stackTraceMtx = epicsMutexMustCreate(); -} - -static void stackTraceLock(void) -{ - epicsThreadOnce( &stackTraceInitId, stackTraceInit, 0 ); - epicsMutexLock( stackTraceMtx ); -} - -static void stackTraceUnlock(void) -{ - epicsMutexUnlock( stackTraceMtx ); -} - -static int -dumpInfo(void *addr, epicsSymbol *sym_p) -{ -int rval = 0; - - rval += errlogPrintf("[%*p]", (int)(sizeof(addr)*2 + 2), addr); - if ( sym_p ) { - if ( sym_p->f_nam ) { - rval += errlogPrintf(": %s", sym_p->f_nam); - } - if ( sym_p->s_nam ) { - rval += errlogPrintf("(%s+0x%lx)", sym_p->s_nam, (unsigned long)((char*)addr - (char*)sym_p->s_val)); - } else { - rval += errlogPrintf("()"); - } - } - rval += errlogPrintf("\n"); - errlogFlush(); - - return rval; -} - -void epicsStackTrace(void) -{ -void **buf; -int i,n; -epicsSymbol sym; - - if ( 0 == epicsStackTraceGetFeatures() ) { - /* unsupported on this platform */ - return; - } - - if ( ! (buf = malloc(sizeof(*buf) * MAXDEPTH))) { - free(buf); - errlogPrintf("epicsStackTrace(): not enough memory for backtrace\n"); - return; - } - - n = epicsBackTrace(buf, MAXDEPTH); - - if ( n > 0 ) { - - stackTraceLock(); - - errlogPrintf("Dumping a stack trace of thread '%s':\n", epicsThreadGetNameSelf()); - - errlogFlush(); - - for ( i=0; i, 2011, 2014 - */ - -#ifndef INC_epicsStackTrace_H -#define INC_epicsStackTrace_H - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Dump a stack trace to the errlog */ -epicsShareFunc void epicsStackTrace(void); - -/* Inquire about functionality implemented on your system */ - -/* StackTrace provides numerical addresses */ -#define EPICS_STACKTRACE_ADDRESSES (1<<0) - -/* StackTrace is able to lookup dynamic symbols */ -#define EPICS_STACKTRACE_DYN_SYMBOLS (1<<1) - -/* StackTrace is able to lookup global symbols */ -#define EPICS_STACKTRACE_GBL_SYMBOLS (1<<2) - -/* StackTrace is able to lookup local symbols */ -#define EPICS_STACKTRACE_LCL_SYMBOLS (1<<3) - -/* returns ORed bitset of supported features */ -epicsShareFunc int epicsStackTraceGetFeatures(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/epicsStackTracePvt.h b/src/libCom/osi/epicsStackTracePvt.h deleted file mode 100644 index de26044fa..000000000 --- a/src/libCom/osi/epicsStackTracePvt.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#ifndef INC_epicsStackTracePvt_H -#define INC_epicsStackTracePvt_H - -#include "shareLib.h" - -typedef struct epicsSymbol { - const char *f_nam; /* file where the symbol is defined */ - const char *s_nam; /* symbol name */ - void *s_val; /* symbol value */ -} epicsSymbol; - -#ifdef __cplusplus -extern "C" { -#endif - -/* Take a snapshot of the stack into 'buf' (limited to buf_sz entries) - * RETURNS: actual number of entries in 'buf' - */ -epicsShareFunc int epicsBackTrace(void **buf, int buf_sz); - -/* Find symbol closest to 'addr'. - * - * If successful the routine fills in the members of *sym_p but - * note that 'f_nam' and/or 's_nam' may be NULL if the address - * cannot be resolved. - * - * RETURNS: 0 on success, nonzero on failure (not finding an address - * is not considered an error). - */ -epicsShareFunc int epicsFindAddr(void *addr, epicsSymbol *sym_p); - -/* report supported features (as reported by epicsStackTraceGetFeatures) */ -epicsShareFunc int epicsFindAddrGetFeatures(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/epicsStdio.c b/src/libCom/osi/epicsStdio.c deleted file mode 100644 index 52b65bbe4..000000000 --- a/src/libCom/osi/epicsStdio.c +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsStdio.c */ - -/* Author: Marty Kraimer */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#define epicsStdioStdStreams -#include "shareLib.h" -#include "epicsThread.h" -#include "epicsStdio.h" - -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; -static epicsThreadPrivateId stdinThreadPrivateId; -static epicsThreadPrivateId stdoutThreadPrivateId; -static epicsThreadPrivateId stderrThreadPrivateId = 0; - -static void once(void *junk) -{ - stdinThreadPrivateId = epicsThreadPrivateCreate(); - stdoutThreadPrivateId = epicsThreadPrivateCreate(); - stderrThreadPrivateId = epicsThreadPrivateCreate(); -} - -FILE * epicsShareAPI epicsGetStdin(void) -{ - FILE *fp = epicsGetThreadStdin(); - - if (!fp) - fp = stdin; - return fp; -} - -FILE * epicsShareAPI epicsGetStdout(void) -{ - FILE *fp = epicsGetThreadStdout(); - - if (!fp) - fp = stdout; - return fp; -} - -FILE * epicsShareAPI epicsGetStderr(void) -{ - FILE *fp = epicsGetThreadStderr(); - - if (!fp) - fp = stderr; - return fp; -} - -FILE * epicsShareAPI epicsGetThreadStdin(void) -{ - epicsThreadOnce(&onceId,once,0); - return epicsThreadPrivateGet(stdinThreadPrivateId); -} - -FILE * epicsShareAPI epicsGetThreadStdout(void) -{ - epicsThreadOnce(&onceId,once,0); - return epicsThreadPrivateGet(stdoutThreadPrivateId); -} - -FILE * epicsShareAPI epicsGetThreadStderr(void) -{ - /* Deliberately don't do the epicsThreadOnce() here; epicsThreadInit() - * is allowed to use stderr inside its once() routine, in which case we - * must return the OS's stderr instead. There may be a tiny chance of a - * race happening here during initialization for some architectures, so - * we only use it for stderr to reduce the chance of that happening. - */ - if (!stderrThreadPrivateId) - return NULL; - return epicsThreadPrivateGet(stderrThreadPrivateId); -} - -void epicsShareAPI epicsSetThreadStdin(FILE *fp) -{ - epicsThreadOnce(&onceId,once,0); - epicsThreadPrivateSet(stdinThreadPrivateId,fp); -} - -void epicsShareAPI epicsSetThreadStdout(FILE *fp) -{ - epicsThreadOnce(&onceId,once,0); - epicsThreadPrivateSet(stdoutThreadPrivateId,fp); -} - -void epicsShareAPI epicsSetThreadStderr(FILE *fp) -{ - epicsThreadOnce(&onceId,once,0); - epicsThreadPrivateSet(stderrThreadPrivateId,fp); -} - -int epicsShareAPI epicsStdoutPrintf(const char *pFormat, ...) -{ - va_list pvar; - int nchar; - FILE *stream = epicsGetStdout(); - - va_start(pvar, pFormat); - nchar = vfprintf(stream, pFormat, pvar); - va_end(pvar); - return nchar; -} - -int epicsShareAPI epicsStdoutPuts(const char *str) -{ - return fprintf(epicsGetStdout(), "%s\n", str); -} - -int epicsShareAPI epicsStdoutPutchar(int c) -{ - return putc(c, epicsGetStdout()); -} diff --git a/src/libCom/osi/epicsStdio.h b/src/libCom/osi/epicsStdio.h deleted file mode 100644 index 172d5cf87..000000000 --- a/src/libCom/osi/epicsStdio.h +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsStdio.h */ - -#ifndef epicsStdioh -#define epicsStdioh - -#include -#include - -#include "shareLib.h" -#include "compilerDependencies.h" -#include "epicsTempFile.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef epicsStdioStdStreams -# undef stdin -# define stdin epicsGetStdin() -# undef stdout -# define stdout epicsGetStdout() -# undef stderr -# define stderr epicsGetStderr() -#endif - -/* Make printf, puts and putchar use *our* version of stdout */ - -#ifdef printf -# undef printf -#endif /* printf */ -#define printf epicsStdoutPrintf - -#ifdef puts -# undef puts -#endif /* puts */ -#define puts epicsStdoutPuts - -#ifdef putchar -# undef putchar -#endif /* putchar */ -#define putchar epicsStdoutPutchar - -epicsShareFunc int epicsShareAPI epicsSnprintf( - char *str, size_t size, const char *format, ...) EPICS_PRINTF_STYLE(3,4); -epicsShareFunc int epicsShareAPI epicsVsnprintf( - char *str, size_t size, const char *format, va_list ap); - -/* - * truncate to specified size (we dont use truncate() - * because it is not portable) - * - * pFileName - name (and optionally path) of file - * size - the new file size (if file is curretly larger) - * - * returns TF_OK if the file is less than size bytes - * or if it was successfully truncated. Returns - * TF_ERROR if the file could not be truncated. - */ -enum TF_RETURN {TF_OK=0, TF_ERROR=1}; -epicsShareFunc enum TF_RETURN truncateFile ( const char *pFileName, unsigned long size ); - -/* The following are for redirecting stdin,stdout,stderr */ -epicsShareFunc FILE * epicsShareAPI epicsGetStdin(void); -epicsShareFunc FILE * epicsShareAPI epicsGetStdout(void); -epicsShareFunc FILE * epicsShareAPI epicsGetStderr(void); -/* These are intended for iocsh only */ -epicsShareFunc FILE * epicsShareAPI epicsGetThreadStdin(void); -epicsShareFunc FILE * epicsShareAPI epicsGetThreadStdout(void); -epicsShareFunc FILE * epicsShareAPI epicsGetThreadStderr(void); -epicsShareFunc void epicsShareAPI epicsSetThreadStdin(FILE *); -epicsShareFunc void epicsShareAPI epicsSetThreadStdout(FILE *); -epicsShareFunc void epicsShareAPI epicsSetThreadStderr(FILE *); - -epicsShareFunc int epicsShareAPI epicsStdoutPrintf( - const char *pformat, ...) EPICS_PRINTF_STYLE(1,2); -epicsShareFunc int epicsShareAPI epicsStdoutPuts(const char *str); -epicsShareFunc int epicsShareAPI epicsStdoutPutchar(int c); - -#ifdef __cplusplus -} -#endif - -#endif /* epicsStdioh */ diff --git a/src/libCom/osi/epicsStdioRedirect.h b/src/libCom/osi/epicsStdioRedirect.h deleted file mode 100644 index 6f99cc9a5..000000000 --- a/src/libCom/osi/epicsStdioRedirect.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsStdioRedirect.h */ - -/* This file is now obselete, and is likely to be - * deleted in a future release of EPICS Base. - * - * Use the epicsStdio.h header file instead. - */ - -#ifndef epicsStdioRedirecth -#define epicsStdioRedirecth - -#include - -#endif /* epicsStdioRedirecth */ diff --git a/src/libCom/osi/epicsTempFile.h b/src/libCom/osi/epicsTempFile.h deleted file mode 100644 index c48e336ec..000000000 --- a/src/libCom/osi/epicsTempFile.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsTempFile.h */ - -#ifndef INC_epicsTempFile_H -#define INC_epicsTempFile_H - -#include - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc void epicsShareAPI epicsTempName(char *pbuf, size_t bufLen); -epicsShareFunc FILE * epicsShareAPI epicsTempFile(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsTempFile_H */ diff --git a/src/libCom/osi/epicsThread.cpp b/src/libCom/osi/epicsThread.cpp deleted file mode 100644 index 892d73de0..000000000 --- a/src/libCom/osi/epicsThread.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// Author: Jeff Hill -// - -#include -#include - -#include -#include -#include -#include - -// The following is required for Solaris builds -#undef __EXTENSIONS__ - -#define epicsExportSharedSymbols -#include "epicsAlgorithm.h" -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsAssert.h" -#include "epicsGuard.h" -#include "errlog.h" - -using namespace std; - -epicsThreadRunable::~epicsThreadRunable () {} -void epicsThreadRunable::run () {} -void epicsThreadRunable::show ( unsigned int ) const {} - -class epicsThread :: unableToCreateThread : - public std :: exception { -public: - const char * what () const throw (); -}; - -const char * epicsThread :: - unableToCreateThread :: what () const throw () -{ - return "unable to create thread"; -} - -void epicsThread :: printLastChanceExceptionMessage ( - const char * pExceptionTypeName, - const char * pExceptionContext ) -{ - char date[64]; - try { - epicsTime cur = epicsTime :: getCurrent (); - cur.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f"); - } - catch ( ... ) { - strcpy ( date, "" ); - } - char name [128]; - epicsThreadGetName ( this->id, name, sizeof ( name ) ); - errlogPrintf ( - "epicsThread: Unexpected C++ exception \"%s\" " - "with type \"%s\" in thread \"%s\" at %s\n", - pExceptionContext, pExceptionTypeName, name, date ); - errlogFlush (); - // This behavior matches the C++ implementation when an exception - // isn't handled by the thread code. Users can install their own - // application-specific unexpected handler if preferred. - std::unexpected (); -} - -extern "C" void epicsThreadCallEntryPoint ( void * pPvt ) -{ - epicsThread * pThread = - static_cast ( pPvt ); - bool threadDestroyed = false; - try { - pThread->pThreadDestroyed = & threadDestroyed; - if ( pThread->beginWait () ) { - pThread->runable.run (); - // The run() routine may have destroyed the epicsThread - // object by now; pThread can only be used below here - // when the threadDestroyed flag is false. - } - } - catch ( const epicsThread::exitException & ) { - } - catch ( std :: exception & except ) { - if ( ! threadDestroyed ) { - pThread->printLastChanceExceptionMessage ( - typeid ( except ).name (), except.what () ); - } - } - catch ( ... ) { - if ( ! threadDestroyed ) { - pThread->printLastChanceExceptionMessage ( - "catch ( ... )", "Non-standard C++ exception" ); - } - } - if ( ! threadDestroyed ) { - epicsGuard < epicsMutex > guard ( pThread->mutex ); - pThread->pThreadDestroyed = NULL; - pThread->terminated = true; - pThread->exitEvent.signal (); - // After the terminated flag is set and guard's destructor - // releases the lock, pThread must never be used again. - } -} - -bool epicsThread::beginWait () throw () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - while ( ! this->begin && ! this->cancel ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->event.wait (); - } - return this->begin && ! this->cancel; -} - -void epicsThread::exit () -{ - throw exitException (); -} - -void epicsThread::exitWait () throw () -{ - bool success = this->exitWait ( DBL_MAX ); - assert ( success ); -} - -bool epicsThread::exitWait ( const double delay ) throw () -{ - try { - // When called (usually by a destructor) in the context of - // the managed thread we can't wait for the thread to exit. - // Set the threadDestroyed flag and return success. - if ( this->isCurrentThread() ) { - if ( this->pThreadDestroyed ) { - *this->pThreadDestroyed = true; - } - return true; - } - epicsTime exitWaitBegin = epicsTime::getCurrent (); - double exitWaitElapsed = 0.0; - epicsGuard < epicsMutex > guard ( this->mutex ); - this->cancel = true; - while ( ! this->terminated && exitWaitElapsed < delay ) { - epicsGuardRelease < epicsMutex > unguard ( guard ); - this->event.signal (); - this->exitEvent.wait ( delay - exitWaitElapsed ); - epicsTime current = epicsTime::getCurrent (); - exitWaitElapsed = current - exitWaitBegin; - } - } - catch ( std :: exception & except ) { - errlogPrintf ( - "epicsThread::exitWait(): Unexpected exception " - " \"%s\"\n", - except.what () ); - epicsThreadSleep ( epicsMin ( delay, 5.0 ) ); - } - catch ( ... ) { - errlogPrintf ( - "Non-standard unexpected exception in " - "epicsThread::exitWait()\n" ); - epicsThreadSleep ( epicsMin ( delay, 5.0 ) ); - } - // the event mechanism is used for other purposes - this->event.signal (); - return this->terminated; -} - -epicsThread::epicsThread ( - epicsThreadRunable & runableIn, const char * pName, - unsigned stackSize, unsigned priority ) : - runable ( runableIn ), id ( 0 ), pThreadDestroyed ( 0 ), - begin ( false ), cancel ( false ), terminated ( false ) -{ - this->id = epicsThreadCreate ( - pName, priority, stackSize, epicsThreadCallEntryPoint, - static_cast < void * > ( this ) ); - if ( ! this->id ) { - throw unableToCreateThread (); - } -} - -epicsThread::~epicsThread () throw () -{ - while ( ! this->exitWait ( 10.0 ) ) { - char nameBuf [256]; - this->getName ( nameBuf, sizeof ( nameBuf ) ); - fprintf ( stderr, - "epicsThread::~epicsThread(): " - "blocking for thread \"%s\" to exit\n", - nameBuf ); - fprintf ( stderr, - "was epicsThread object destroyed before thread exit ?\n"); - } -} - -void epicsThread::start () throw () -{ - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->begin = true; - } - this->event.signal (); -} - -bool epicsThread::isCurrentThread () const throw () -{ - return ( epicsThreadGetIdSelf () == this->id ); -} - -void epicsThread::resume () throw () -{ - epicsThreadResume ( this->id ); -} - -void epicsThread::getName ( char *name, size_t size ) const throw () -{ - epicsThreadGetName ( this->id, name, size ); -} - -epicsThreadId epicsThread::getId () const throw () -{ - return this->id; -} - -unsigned int epicsThread::getPriority () const throw () -{ - return epicsThreadGetPriority (this->id); -} - -void epicsThread::setPriority (unsigned int priority) throw () -{ - epicsThreadSetPriority (this->id, priority); -} - -bool epicsThread::priorityIsEqual (const epicsThread &otherThread) const throw () -{ - if ( epicsThreadIsEqual (this->id, otherThread.id) ) { - return true; - } - return false; -} - -bool epicsThread::isSuspended () const throw () -{ - if ( epicsThreadIsSuspended (this->id) ) { - return true; - } - return false; -} - -bool epicsThread::operator == (const epicsThread &rhs) const throw () -{ - return (this->id == rhs.id); -} - -void epicsThread::suspendSelf () throw () -{ - epicsThreadSuspendSelf (); -} - -void epicsThread::sleep (double seconds) throw () -{ - epicsThreadSleep (seconds); -} - -const char *epicsThread::getNameSelf () throw () -{ - return epicsThreadGetNameSelf (); -} - -bool epicsThread::isOkToBlock () throw () -{ - return epicsThreadIsOkToBlock() != 0; -} - -void epicsThread::setOkToBlock(bool isOkToBlock) throw () -{ - epicsThreadSetOkToBlock(static_cast(isOkToBlock)); -} - -void epicsThreadPrivateBase::throwUnableToCreateThreadPrivate () -{ - throw epicsThreadPrivateBase::unableToCreateThreadPrivate (); -} - -void epicsThread :: show ( unsigned level ) const throw () -{ - ::printf ( "epicsThread at %p\n", this->id ); - if ( level > 0u ) { - epicsThreadShow ( this->id, level - 1 ); - if ( level > 1u ) { - ::printf ( "pThreadDestroyed = %p\n", this->pThreadDestroyed ); - ::printf ( "begin = %c, cancel = %c, terminated = %c\n", - this->begin ? 'T' : 'F', - this->cancel ? 'T' : 'F', - this->terminated ? 'T' : 'F' ); - this->runable.show ( level - 2u ); - this->mutex.show ( level - 2u ); - ::printf ( "general purpose event\n" ); - this->event.show ( level - 2u ); - ::printf ( "exit event\n" ); - this->exitEvent.show ( level - 2u ); - } - } -} - -extern "C" { - static epicsThreadOnceId okToBlockOnce = EPICS_THREAD_ONCE_INIT; - epicsThreadPrivateId okToBlockPrivate; - static const int okToBlockNo = 0; - static const int okToBlockYes = 1; - - static void epicsThreadOnceIdInit(void *) - { - okToBlockPrivate = epicsThreadPrivateCreate(); - } - - int epicsShareAPI epicsThreadIsOkToBlock(void) - { - const int *pokToBlock; - epicsThreadOnce(&okToBlockOnce, epicsThreadOnceIdInit, NULL); - pokToBlock = (int *) epicsThreadPrivateGet(okToBlockPrivate); - return (pokToBlock ? *pokToBlock : 0); - } - - void epicsShareAPI epicsThreadSetOkToBlock(int isOkToBlock) - { - const int *pokToBlock; - epicsThreadOnce(&okToBlockOnce, epicsThreadOnceIdInit, NULL); - pokToBlock = (isOkToBlock) ? &okToBlockYes : &okToBlockNo; - epicsThreadPrivateSet(okToBlockPrivate, (void *)pokToBlock); - } - - epicsThreadId epicsShareAPI epicsThreadMustCreate ( - const char *name, unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) - { - epicsThreadId id = epicsThreadCreate ( - name, priority, stackSize, funptr, parm ); - assert ( id ); - return id; - } -} // extern "C" - -// Ensure the main thread gets a unique ID -epicsThreadId epicsThreadMainId = epicsThreadGetIdSelf(); diff --git a/src/libCom/osi/epicsThread.h b/src/libCom/osi/epicsThread.h deleted file mode 100644 index 84b2c4788..000000000 --- a/src/libCom/osi/epicsThread.h +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef epicsThreadh -#define epicsThreadh - -#include - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*EPICSTHREADFUNC)(void *parm); - -#define epicsThreadPriorityMax 99 -#define epicsThreadPriorityMin 0 - -/* some generic values */ -#define epicsThreadPriorityLow 10 -#define epicsThreadPriorityMedium 50 -#define epicsThreadPriorityHigh 90 - -/* some iocCore specific values */ -#define epicsThreadPriorityCAServerLow 20 -#define epicsThreadPriorityCAServerHigh 40 -#define epicsThreadPriorityScanLow 60 -#define epicsThreadPriorityScanHigh 70 -#define epicsThreadPriorityIocsh 91 -#define epicsThreadPriorityBaseMax 91 - -/* stack sizes for each stackSizeClass are implementation and CPU dependent */ -typedef enum { - epicsThreadStackSmall, epicsThreadStackMedium, epicsThreadStackBig -} epicsThreadStackSizeClass; - -typedef enum { - epicsThreadBooleanStatusFail, epicsThreadBooleanStatusSuccess -} epicsThreadBooleanStatus; - -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize( - epicsThreadStackSizeClass size); - -/* (epicsThreadId)0 is guaranteed to be an invalid thread id */ -typedef struct epicsThreadOSD *epicsThreadId; - -typedef epicsThreadId epicsThreadOnceId; -#define EPICS_THREAD_ONCE_INIT 0 - -epicsShareFunc void epicsShareAPI epicsThreadOnce( - epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg); - -/* When real-time scheduling is active, attempt any post-init operations - * that preserve real-time performance. For POSIX targets this locks the - * process into RAM, preventing swap-related VM faults. - */ -epicsShareFunc void epicsThreadRealtimeLock(void); - -epicsShareFunc void epicsShareAPI epicsThreadExitMain(void); - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate ( - const char * name, unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void * parm ); -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadMustCreate ( - const char * name, unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void * parm ); -epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void); -epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadId id); -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPriority( - epicsThreadId id); -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPrioritySelf(void); -epicsShareFunc void epicsShareAPI epicsThreadSetPriority( - epicsThreadId id,unsigned int priority); -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI - epicsThreadHighestPriorityLevelBelow ( - unsigned int priority, unsigned *pPriorityJustBelow); -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI - epicsThreadLowestPriorityLevelAbove ( - unsigned int priority, unsigned *pPriorityJustAbove); -epicsShareFunc int epicsShareAPI epicsThreadIsEqual( - epicsThreadId id1, epicsThreadId id2); -epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId id); -epicsShareFunc void epicsShareAPI epicsThreadSleep(double seconds); -epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum(void); -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void); -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId(const char *name); -epicsShareFunc int epicsThreadGetCPUs(void); - -epicsShareFunc const char * epicsShareAPI epicsThreadGetNameSelf(void); - -/* For epicsThreadGetName name is guaranteed to be null terminated */ -/* size is size of buffer to hold name (including terminator) */ -/* Failure results in an empty string stored in name */ -epicsShareFunc void epicsShareAPI epicsThreadGetName( - epicsThreadId id, char *name, size_t size); - -epicsShareFunc int epicsShareAPI epicsThreadIsOkToBlock(void); -epicsShareFunc void epicsShareAPI epicsThreadSetOkToBlock(int isOkToBlock); - -epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level); -epicsShareFunc void epicsShareAPI epicsThreadShow( - epicsThreadId id,unsigned int level); - -/* Hooks called when a thread starts, map function called once for every thread */ -typedef void (*EPICS_THREAD_HOOK_ROUTINE)(epicsThreadId id); -epicsShareFunc int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook); -epicsShareFunc int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook); -epicsShareFunc void epicsThreadHooksShow(void); -epicsShareFunc void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func); - -typedef struct epicsThreadPrivateOSD * epicsThreadPrivateId; -epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void); -epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete(epicsThreadPrivateId id); -epicsShareFunc void epicsShareAPI epicsThreadPrivateSet(epicsThreadPrivateId,void *); -epicsShareFunc void * epicsShareAPI epicsThreadPrivateGet(epicsThreadPrivateId); - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus - -#include "epicsEvent.h" -#include "epicsMutex.h" - -class epicsShareClass epicsThreadRunable { -public: - virtual ~epicsThreadRunable () = 0; - virtual void run () = 0; - virtual void show ( unsigned int level ) const; -}; - -extern "C" void epicsThreadCallEntryPoint ( void * ); - -class epicsShareClass epicsThread { -public: - epicsThread ( epicsThreadRunable &,const char *name, unsigned int stackSize, - unsigned int priority=epicsThreadPriorityLow ); - ~epicsThread () throw (); - void start () throw (); - void exitWait () throw (); - bool exitWait ( const double delay ) throw (); - static void exit (); - void resume () throw (); - void getName ( char * name, size_t size ) const throw (); - epicsThreadId getId () const throw (); - unsigned int getPriority () const throw (); - void setPriority ( unsigned int ) throw (); - bool priorityIsEqual ( const epicsThread & ) const throw (); - bool isSuspended () const throw (); - bool isCurrentThread () const throw (); - bool operator == ( const epicsThread & ) const throw (); - void show ( unsigned level ) const throw (); - - /* these operate on the current thread */ - static void suspendSelf () throw (); - static void sleep (double seconds) throw (); - static const char * getNameSelf () throw (); - static bool isOkToBlock () throw (); - static void setOkToBlock ( bool isOkToBlock ) throw (); - - /* exceptions */ - class unableToCreateThread; -private: - epicsThreadRunable & runable; - epicsThreadId id; - epicsMutex mutex; - epicsEvent event; - epicsEvent exitEvent; - bool * pThreadDestroyed; - bool begin; - bool cancel; - bool terminated; - - bool beginWait () throw (); - epicsThread ( const epicsThread & ); - epicsThread & operator = ( const epicsThread & ); - friend void epicsThreadCallEntryPoint ( void * ); - void printLastChanceExceptionMessage ( - const char * pExceptionTypeName, - const char * pExceptionContext ); - /* exceptions */ - class exitException {}; -}; - -class epicsShareClass epicsThreadPrivateBase { -public: - class unableToCreateThreadPrivate {}; /* exception */ -protected: - static void throwUnableToCreateThreadPrivate (); -}; - -template < class T > -class epicsThreadPrivate : - private epicsThreadPrivateBase { -public: - epicsThreadPrivate (); - ~epicsThreadPrivate () throw (); - T * get () const throw (); - void set (T *) throw (); -private: - epicsThreadPrivateId id; -}; - -#endif /* __cplusplus */ - -#include "osdThread.h" - -#ifdef __cplusplus - -template -inline epicsThreadPrivate::epicsThreadPrivate () -{ - this->id = epicsThreadPrivateCreate (); - if ( this->id == 0 ) { - epicsThreadPrivateBase::throwUnableToCreateThreadPrivate (); - } -} - -template -inline epicsThreadPrivate::~epicsThreadPrivate () throw () -{ - epicsThreadPrivateDelete ( this->id ); -} - -template -inline T *epicsThreadPrivate::get () const throw () -{ - return static_cast ( epicsThreadPrivateGet (this->id) ); -} - -template -inline void epicsThreadPrivate::set (T *pIn) throw () -{ - epicsThreadPrivateSet ( this->id, static_cast (pIn) ); -} - -#endif /* ifdef __cplusplus */ - -#endif /* epicsThreadh */ diff --git a/src/libCom/osi/epicsTime.cpp b/src/libCom/osi/epicsTime.cpp deleted file mode 100644 index 6dd1d3f97..000000000 --- a/src/libCom/osi/epicsTime.cpp +++ /dev/null @@ -1,1133 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsTime.cpp */ -/* Author Jeffrey O. Hill */ - -// Notes: -// 1) The epicsTime::nSec field is not public and so it could be -// changed to work more like the fractional seconds field in the NTP time -// stamp. That would significantly improve the precision of epicsTime on -// 64 bit architectures. -// - -#include - -#include -#include -#include -#include -#include -#include -#include // vxWorks 6.0 requires this include - -#define epicsExportSharedSymbols -#include "locationException.h" -#include "epicsAssert.h" -#include "epicsVersion.h" -#include "envDefs.h" -#include "epicsTime.h" -#include "osiSock.h" /* pull in struct timeval */ -#include "epicsStdio.h" - -static const char pEpicsTimeVersion[] = - "@(#) " EPICS_VERSION_STRING ", Common Utilities Library " __DATE__; - -// -// useful public constants -// -static const unsigned mSecPerSec = 1000u; -static const unsigned uSecPerMSec = 1000u; -static const unsigned uSecPerSec = uSecPerMSec * mSecPerSec; -static const unsigned nSecPerUSec = 1000u; -static const unsigned nSecPerSec = nSecPerUSec * uSecPerSec; -static const unsigned nSecFracDigits = 9u; - - -// Timescale conversion data - -static const unsigned long NTP_TIME_AT_POSIX_EPOCH = 2208988800ul; -static const unsigned long NTP_TIME_AT_EPICS_EPOCH = - NTP_TIME_AT_POSIX_EPOCH + POSIX_TIME_AT_EPICS_EPOCH; - -// -// epicsTime (const unsigned long secIn, const unsigned long nSecIn) -// -inline epicsTime::epicsTime (const unsigned long secIn, const unsigned long nSecIn) : - secPastEpoch ( secIn ), nSec ( nSecIn ) -{ - if (nSecIn >= nSecPerSec) { - this->secPastEpoch += nSecIn / nSecPerSec; - this->nSec = nSecIn % nSecPerSec; - } -} - -// -// epicsTimeLoadTimeInit -// -class epicsTimeLoadTimeInit { -public: - epicsTimeLoadTimeInit (); - double epicsEpochOffset; // seconds - double time_tSecPerTick; // seconds (both NTP and EPICS use int sec) - unsigned long epicsEpochOffsetAsAnUnsignedLong; - bool useDiffTimeOptimization; -}; - -// -// epicsTimeLoadTimeInit () -// -epicsTimeLoadTimeInit::epicsTimeLoadTimeInit () -{ - // All we know about time_t is that it is an arithmetic type. - time_t t_zero = static_cast (0); - time_t t_one = static_cast (1); - this->time_tSecPerTick = difftime (t_one, t_zero); - - /* The EPICS epoch (1/1/1990 00:00:00UTC) was 631152000 seconds after - * the ANSI epoch (1/1/1970 00:00:00UTC) - * Convert this offset into time_t units, however this must not be - * calculated using local time (i.e. using mktime() or similar), since - * in the UK the ANSI Epoch had daylight saving time in effect, and - * the value calculated would be 3600 seconds wrong.*/ - this->epicsEpochOffset = - (double) POSIX_TIME_AT_EPICS_EPOCH / this->time_tSecPerTick; - - if (this->time_tSecPerTick == 1.0 && - this->epicsEpochOffset <= ULONG_MAX && - this->epicsEpochOffset >= 0) { - // We can use simpler code on Posix-compliant systems - this->useDiffTimeOptimization = true; - this->epicsEpochOffsetAsAnUnsignedLong = - static_cast(this->epicsEpochOffset); - } else { - // Forced to use the slower but correct code - this->useDiffTimeOptimization = false; - this->epicsEpochOffsetAsAnUnsignedLong = 0; - } -} - -// -// private epicsTime::addNanoSec () -// -// Most formats keep the nSec value as an unsigned long, so are +ve. -// struct timeval's tv_usec may be -1, but I think that means error, -// so this private method never needs to handle -ve offsets. -// -void epicsTime :: addNanoSec ( long nSecAdj ) -{ - if (nSecAdj <= 0) - return; - - if (static_cast(nSecAdj) >= nSecPerSec) { - this->secPastEpoch += nSecAdj / nSecPerSec; - nSecAdj %= nSecPerSec; - } - - this->nSec += nSecAdj; // Can't overflow - if (this->nSec >= nSecPerSec) { - this->secPastEpoch++; - this->nSec -= nSecPerSec; - } -} - -// -// epicsTime (const time_t_wrapper &tv) -// -epicsTime::epicsTime ( const time_t_wrapper & ansiTimeTicks ) -{ - // avoid c++ static initialization order issues - static epicsTimeLoadTimeInit & lti = * new epicsTimeLoadTimeInit (); - - // - // try to directly map time_t into an unsigned long integer because this is - // faster on systems w/o hardware floating point and a simple integer type time_t. - // - if ( lti.useDiffTimeOptimization ) { - // LONG_MAX is used here and not ULONG_MAX because some systems (linux) - // still store time_t as a long. - if ( ansiTimeTicks.ts > 0 && ansiTimeTicks.ts <= LONG_MAX ) { - unsigned long ticks = static_cast < unsigned long > ( ansiTimeTicks.ts ); - if ( ticks >= lti.epicsEpochOffsetAsAnUnsignedLong ) { - this->secPastEpoch = ticks - lti.epicsEpochOffsetAsAnUnsignedLong; - } - else { - this->secPastEpoch = ( ULONG_MAX - lti.epicsEpochOffsetAsAnUnsignedLong ) + ticks; - } - this->nSec = 0; - return; - } - } - - // - // otherwise map time_t, which ANSI C and POSIX define as any arithmetic type, - // into type double - // - double sec = ansiTimeTicks.ts * lti.time_tSecPerTick - lti.epicsEpochOffset; - - // - // map into the the EPICS time stamp range (which allows rollover) - // - static double uLongMax = static_cast (ULONG_MAX); - if ( sec < 0.0 ) { - if ( sec < -uLongMax ) { - sec = sec + static_cast ( -sec / uLongMax ) * uLongMax; - } - sec += uLongMax; - } - else if ( sec > uLongMax ) { - sec = sec - static_cast ( sec / uLongMax ) * uLongMax; - } - - this->secPastEpoch = static_cast ( sec ); - this->nSec = static_cast ( ( sec-this->secPastEpoch ) * nSecPerSec ); -} - -epicsTime::epicsTime (const epicsTimeStamp &ts) -{ - if ( ts.nsec < nSecPerSec ) { - this->secPastEpoch = ts.secPastEpoch; - this->nSec = ts.nsec; - } - else { - throw std::logic_error ( - "epicsTimeStamp has overflow in nano-seconds field" ); - } -} - -epicsTime::epicsTime () : - secPastEpoch(0u), nSec(0u) {} - -epicsTime::epicsTime (const epicsTime &t) : - secPastEpoch (t.secPastEpoch), nSec (t.nSec) {} - -epicsTime epicsTime::getCurrent () -{ - epicsTimeStamp current; - int status = epicsTimeGetCurrent (¤t); - if (status) { - throwWithLocation ( unableToFetchCurrentTime () ); - } - return epicsTime ( current ); -} - -epicsTime epicsTime::getEvent (const epicsTimeEvent &event) -{ - epicsTimeStamp current; - int status = epicsTimeGetEvent (¤t, event); - if (status) { - throwWithLocation ( unableToFetchCurrentTime () ); - } - return epicsTime ( current ); -} - -// -// operator time_t_wrapper () -// -epicsTime::operator time_t_wrapper () const -{ - // avoid c++ static initialization order issues - static epicsTimeLoadTimeInit & lti = * new epicsTimeLoadTimeInit (); - time_t_wrapper wrap; - - if ( lti.useDiffTimeOptimization ) { - if ( this->secPastEpoch < ULONG_MAX - lti.epicsEpochOffsetAsAnUnsignedLong ) { - wrap.ts = static_cast ( this->secPastEpoch + lti.epicsEpochOffsetAsAnUnsignedLong ); - return wrap; - } - } - - // - // map type double into time_t which ansi C defines as some arithmetic type - // - double tmp = (this->secPastEpoch + lti.epicsEpochOffset) / lti.time_tSecPerTick; - tmp += (this->nSec / lti.time_tSecPerTick) / nSecPerSec; - - wrap.ts = static_cast ( tmp ); - - return wrap; -} - -// -// convert to ANSI C struct tm (with nano seconds) adjusted for the local time zone -// -epicsTime::operator local_tm_nano_sec () const -{ - time_t_wrapper ansiTimeTicks = *this; - - local_tm_nano_sec tm; - - int status = epicsTime_localtime ( &ansiTimeTicks.ts, &tm.ansi_tm ); - if ( status ) { - throw std::logic_error ( "epicsTime_localtime failed" ); - } - - tm.nSec = this->nSec; - - return tm; -} - -// -// convert to ANSI C struct tm (with nano seconds) adjusted for UTC -// -epicsTime::operator gm_tm_nano_sec () const -{ - time_t_wrapper ansiTimeTicks = *this; - - gm_tm_nano_sec tm; - - int status = epicsTime_gmtime ( &ansiTimeTicks.ts, &tm.ansi_tm ); - if ( status ) { - throw std::logic_error ( "epicsTime_gmtime failed" ); - } - - tm.nSec = this->nSec; - - return tm; -} - -// -// epicsTime (const local_tm_nano_sec &tm) -// -epicsTime::epicsTime (const local_tm_nano_sec &tm) -{ - struct tm tmp = tm.ansi_tm; - time_t_wrapper ansiTimeTicks = { mktime (&tmp) }; - - static const time_t mktimeError = static_cast (-1); - if (ansiTimeTicks.ts == mktimeError) { - throwWithLocation ( formatProblemWithStructTM () ); - } - - *this = epicsTime(ansiTimeTicks); - this->addNanoSec(tm.nSec); -} - -// -// epicsTime (const gm_tm_nano_sec &tm) -// - -// do conversion avoiding the timezone mechanism -static inline int is_leap(int year) -{ - if (year % 400 == 0) - return 1; - if (year % 100 == 0) - return 0; - if (year % 4 == 0) - return 1; - return 0; -} - -static inline int days_from_0(int year) -{ - year--; - return 365 * year + (year / 400) - (year / 100) + (year / 4); -} - -static inline int days_from_1970(int year) -{ - static const int days_from_0_to_1970 = days_from_0(1970); - return days_from_0(year) - days_from_0_to_1970; -} - -static inline int days_from_1jan(int year, int month, int day) -{ - static const int days[2][12] = - { - { 0,31,59,90,120,151,181,212,243,273,304,334}, - { 0,31,60,91,121,152,182,213,244,274,305,335} - }; - return days[is_leap(year)][month-1] + day - 1; -} - -epicsTime::epicsTime (const gm_tm_nano_sec &tm) -{ - int year = tm.ansi_tm.tm_year + 1900; - int month = tm.ansi_tm.tm_mon; - if (month > 11) { - year += month / 12; - month %= 12; - } else if (month < 0) { - int years_diff = (-month + 11) / 12; - year -= years_diff; - month += 12 * years_diff; - } - month++; - - int day = tm.ansi_tm.tm_mday; - int day_of_year = days_from_1jan(year, month, day); - int days_since_epoch = days_from_1970(year) + day_of_year; - - time_t_wrapper ansiTimeTicks; - ansiTimeTicks.ts = ((days_since_epoch - * 24 + tm.ansi_tm.tm_hour) - * 60 + tm.ansi_tm.tm_min) - * 60 + tm.ansi_tm.tm_sec; - - *this = epicsTime(ansiTimeTicks); - this->addNanoSec(tm.nSec); -} - -// -// operator struct timespec () -// -epicsTime::operator struct timespec () const -{ - struct timespec ts; - time_t_wrapper ansiTimeTicks; - - ansiTimeTicks = *this; - ts.tv_sec = ansiTimeTicks.ts; - ts.tv_nsec = static_cast (this->nSec); - return ts; -} - -// -// epicsTime (const struct timespec &ts) -// -epicsTime::epicsTime (const struct timespec &ts) -{ - time_t_wrapper ansiTimeTicks; - - ansiTimeTicks.ts = ts.tv_sec; - *this = epicsTime (ansiTimeTicks); - this->addNanoSec (ts.tv_nsec); -} - -// -// operator struct timeval () -// -epicsTime::operator struct timeval () const -{ - struct timeval ts; - time_t_wrapper ansiTimeTicks; - - ansiTimeTicks = *this; - // On Posix systems timeval :: tv_sec is a time_t so this can be - // a direct assignment. On other systems I dont know that we can - // guarantee that time_t and timeval :: tv_sec will have the - // same epoch or have the same scaling factor to discrete seconds. - // For example, on windows time_t changed recently to a 64 bit - // quantity but timeval is still a long. That can cause problems - // on 32 bit systems. So technically, we should have an os - // dependent conversion between time_t and timeval :: tv_sec? - ts.tv_sec = ansiTimeTicks.ts; - ts.tv_usec = static_cast < long > ( this->nSec / nSecPerUSec ); - return ts; -} - -// -// epicsTime (const struct timeval &ts) -// -epicsTime::epicsTime (const struct timeval &ts) -{ - time_t_wrapper ansiTimeTicks; - // On Posix systems timeval :: tv_sec is a time_t so this can be - // a direct assignment. On other systems I dont know that we can - // guarantee that time_t and timeval :: tv_sec will have the - // same epoch or have the same scaling factor to discrete seconds. - // For example, on windows time_t changed recently to a 64 bit - // quantity but timeval is still a long. That can cause problems - // on 32 bit systems. So technically, we should have an os - // dependent conversion between time_t and timeval :: tv_sec? - ansiTimeTicks.ts = ts.tv_sec; - *this = epicsTime (ansiTimeTicks); - this->addNanoSec (ts.tv_usec * nSecPerUSec); -} - - -static const double NTP_FRACTION_DENOMINATOR = 1.0 + 0xffffffff; - -struct l_fp { /* NTP time stamp */ - epicsUInt32 l_ui; /* sec past NTP epoch */ - epicsUInt32 l_uf; /* fractional seconds */ -}; - -// -// epicsTime::l_fp () -// -epicsTime::operator l_fp () const -{ - l_fp ts; - ts.l_ui = this->secPastEpoch + NTP_TIME_AT_EPICS_EPOCH; - ts.l_uf = static_cast < unsigned long > - ( ( this->nSec * NTP_FRACTION_DENOMINATOR ) / nSecPerSec ); - return ts; -} - -// -// epicsTime::epicsTime ( const l_fp & ts ) -// -epicsTime::epicsTime ( const l_fp & ts ) -{ - this->secPastEpoch = ts.l_ui - NTP_TIME_AT_EPICS_EPOCH; - this->nSec = static_cast < unsigned long > - ( ( ts.l_uf / NTP_FRACTION_DENOMINATOR ) * nSecPerSec ); -} - -epicsTime::operator epicsTimeStamp () const -{ - if ( this->nSec >= nSecPerSec ) { - throw std::logic_error ( - "epicsTimeStamp has overflow in nano-seconds field?" ); - } - epicsTimeStamp ts; - // - // truncation by design - // ------------------- - // epicsTime::secPastEpoch is based on ulong and has much greater range - // on 64 bit hosts than the original epicsTimeStamp::secPastEpoch. The - // epicsTimeStamp::secPastEpoch is based on epicsUInt32 so that it will - // match the original network protocol. Of course one can anticipate - // that eventually, a epicsUInt64 based network time stamp will be - // introduced when 64 bit architectures are more ubiquitous. - // - // Truncation usually works fine here because the routines in this code - // that compute time stamp differences and compare time stamps produce - // good results when the operands are on either side of a time stamp - // rollover as long as the difference between the operands does not exceed - // 1/2 of full range. - // - ts.secPastEpoch = static_cast < epicsUInt32 > ( this->secPastEpoch ); - ts.nsec = static_cast < epicsUInt32 > ( this->nSec ); - return ts; -} - -// Break up a format string into "%0f" -// (where in an unsigned integer) -// Result: -// A) Copies a prefix which is valid for ANSI strftime into the supplied -// buffer setting the buffer to an empty string if no prefix is present. -// B) Indicates whether a valid "%0f]" is present or not and if so -// specifying its nnnn -// C) returning a pointer to the postfix (which might be passed again -// to fracFormatFind. -static const char * fracFormatFind ( - const char * const pFormat, - char * const pPrefixBuf, - const size_t prefixBufLen, - bool & fracFmtFound, - unsigned long & fracFmtWidth ) -{ - assert ( prefixBufLen > 1 ); - unsigned long width = ULONG_MAX; - bool fracFound = false; - const char * pAfter = pFormat; - const char * pFmt = pFormat; - while ( *pFmt != '\0' ) { - if ( *pFmt == '%' ) { - if ( pFmt[1] == '%' ) { - pFmt++; - } - else if ( pFmt[1] == 'f' ) { - fracFound = true; - pAfter = & pFmt[2]; - break; - } - else { - errno = 0; - char * pAfterTmp; - unsigned long result = strtoul ( pFmt + 1, & pAfterTmp, 10 ); - if ( errno == 0 && *pAfterTmp == 'f' && result > 0 ) { - width = result; - fracFound = true; - pAfter = pAfterTmp + 1; - break; - } - } - } - pFmt++; - pAfter = pFmt; - } - size_t len = pFmt - pFormat; - if ( len < prefixBufLen ) { - strncpy ( pPrefixBuf, pFormat, len ); - pPrefixBuf [ len ] = '\0'; - if ( fracFound ) { - fracFmtFound = true; - fracFmtWidth = width; - } - else { - fracFmtFound = false; - } - } - else { - strncpy ( pPrefixBuf, "", prefixBufLen - 1 ); - pPrefixBuf [ prefixBufLen - 1 ] = '\0'; - fracFmtFound = false; - pAfter = ""; - } - - return pAfter; -} - -// -// size_t epicsTime::strftime () -// -size_t epicsTime::strftime ( - char * pBuff, size_t bufLength, const char * pFormat ) const -{ - if ( bufLength == 0u ) { - return 0u; - } - - // presume that EPOCH date is an uninitialized time stamp - if ( this->secPastEpoch == 0 && this->nSec == 0u ) { - strncpy ( pBuff, "", bufLength ); - pBuff[bufLength-1] = '\0'; - return strlen ( pBuff ); - } - - char * pBufCur = pBuff; - const char * pFmt = pFormat; - size_t bufLenLeft = bufLength; - while ( *pFmt != '\0' && bufLenLeft > 1 ) { - // look for "%0f" at the end (used for fractional second formatting) - char strftimePrefixBuf [256]; - bool fracFmtFound; - unsigned long fracWid = 0; - pFmt = fracFormatFind ( - pFmt, - strftimePrefixBuf, sizeof ( strftimePrefixBuf ), - fracFmtFound, fracWid ); - - // nothing more in the string, then quit - if ( ! ( strftimePrefixBuf[0] != '\0' || fracFmtFound ) ) { - break; - } - // all but fractional seconds use strftime formatting - if ( strftimePrefixBuf[0] != '\0' ) { - local_tm_nano_sec tmns = *this; - size_t strftimeNumChar = :: strftime ( - pBufCur, bufLenLeft, strftimePrefixBuf, & tmns.ansi_tm ); - pBufCur [ strftimeNumChar ] = '\0'; - pBufCur += strftimeNumChar; - bufLenLeft -= strftimeNumChar; - } - - // fractional seconds formating - if ( fracFmtFound && bufLenLeft > 1 ) { - if ( fracWid > nSecFracDigits ) { - fracWid = nSecFracDigits; - } - // verify that there are enough chars left for the fractional seconds - if ( fracWid < bufLenLeft ) - { - local_tm_nano_sec tmns = *this; - if ( tmns.nSec < nSecPerSec ) { - // divisors for fraction (see below) - static const unsigned long div[] = { - static_cast < unsigned long > ( 1e9 ), - static_cast < unsigned long > ( 1e8 ), - static_cast < unsigned long > ( 1e7 ), - static_cast < unsigned long > ( 1e6 ), - static_cast < unsigned long > ( 1e5 ), - static_cast < unsigned long > ( 1e4 ), - static_cast < unsigned long > ( 1e3 ), - static_cast < unsigned long > ( 1e2 ), - static_cast < unsigned long > ( 1e1 ), - static_cast < unsigned long > ( 1e0 ) - }; - // round without overflowing into whole seconds - unsigned long frac = tmns.nSec + div[fracWid] / 2; - if (frac >= nSecPerSec) - frac = nSecPerSec - 1; - // convert nanosecs to integer of correct range - frac /= div[fracWid]; - char fracFormat[32]; - sprintf ( fracFormat, "%%0%lulu", fracWid ); - int status = epicsSnprintf ( pBufCur, bufLenLeft, fracFormat, frac ); - if ( status > 0 ) { - unsigned long nChar = static_cast < unsigned long > ( status ); - if ( nChar >= bufLenLeft ) { - nChar = bufLenLeft - 1; - } - pBufCur[nChar] = '\0'; - pBufCur += nChar; - bufLenLeft -= nChar; - } - } - else { - static const char pOVF [] = "OVF"; - size_t tmpLen = sizeof ( pOVF ) - 1; - if ( tmpLen >= bufLenLeft ) { - tmpLen = bufLenLeft - 1; - } - strncpy ( pBufCur, pOVF, tmpLen ); - pBufCur[tmpLen] = '\0'; - pBufCur += tmpLen; - bufLenLeft -= tmpLen; - } - } - else { - static const char pDoesntFit [] = "************"; - size_t tmpLen = sizeof ( pDoesntFit ) - 1; - if ( tmpLen >= bufLenLeft ) { - tmpLen = bufLenLeft - 1; - } - strncpy ( pBufCur, pDoesntFit, tmpLen ); - pBufCur[tmpLen] = '\0'; - pBufCur += tmpLen; - bufLenLeft -= tmpLen; - break; - } - } - } - return pBufCur - pBuff; -} - -// -// epicsTime::show (unsigned) -// -void epicsTime::show ( unsigned level ) const -{ - char bigBuffer[256]; - - size_t numChar = this->strftime ( bigBuffer, sizeof ( bigBuffer ), - "%a %b %d %Y %H:%M:%S.%09f" ); - if ( numChar > 0 ) { - printf ( "epicsTime: %s\n", bigBuffer ); - } - - if ( level > 1 ) { - // this also suppresses the "defined, but not used" - // warning message - printf ( "epicsTime: revision \"%s\"\n", - pEpicsTimeVersion ); - } - -} - -// -// epicsTime::operator + (const double &rhs) -// -// rhs has units seconds -// -epicsTime epicsTime::operator + (const double &rhs) const -{ - unsigned long newSec, newNSec, secOffset, nSecOffset; - double fnsec; - - if (rhs >= 0) { - secOffset = static_cast (rhs); - fnsec = rhs - secOffset; - nSecOffset = static_cast ( (fnsec * nSecPerSec) + 0.5 ); - - newSec = this->secPastEpoch + secOffset; // overflow expected - newNSec = this->nSec + nSecOffset; - if (newNSec >= nSecPerSec) { - newSec++; // overflow expected - newNSec -= nSecPerSec; - } - } - else { - secOffset = static_cast (-rhs); - fnsec = rhs + secOffset; - nSecOffset = static_cast ( (-fnsec * nSecPerSec) + 0.5 ); - - newSec = this->secPastEpoch - secOffset; // underflow expected - if (this->nSec>=nSecOffset) { - newNSec = this->nSec - nSecOffset; - } - else { - // borrow - newSec--; // underflow expected - newNSec = this->nSec + (nSecPerSec - nSecOffset); - } - } - return epicsTime (newSec, newNSec); -} - -// -// operator - -// -// To make this code robust during timestamp rollover events -// time stamp differences greater than one half full scale are -// interpreted as rollover situations: -// -// when RHS is greater than THIS: -// RHS-THIS > one half full scale => return THIS + (ULONG_MAX-RHS) -// RHS-THIS <= one half full scale => return -(RHS-THIS) -// -// when THIS is greater than or equal to RHS -// THIS-RHS > one half full scale => return -(RHS + (ULONG_MAX-THIS)) -// THIS-RHS <= one half full scale => return THIS-RHS -// -double epicsTime::operator - (const epicsTime &rhs) const -{ - double nSecRes, secRes; - - // - // first compute the difference between the nano-seconds members - // - // nano sec member is not allowed to be greater that 1/2 full scale - // so the unsigned to signed conversion is ok - // - if (this->nSec>=rhs.nSec) { - nSecRes = this->nSec - rhs.nSec; - } - else { - nSecRes = rhs.nSec - this->nSec; - nSecRes = -nSecRes; - } - - // - // next compute the difference between the seconds members - // and invert the sign of the nano seconds result if there - // is a range violation - // - if (this->secPastEpochsecPastEpoch; - if (secRes > ULONG_MAX/2) { - // - // In this situation where the difference is more than - // 68 years assume that the seconds counter has rolled - // over and compute the "wrap around" difference - // - secRes = 1 + (ULONG_MAX-secRes); - nSecRes = -nSecRes; - } - else { - secRes = -secRes; - } - } - else { - secRes = this->secPastEpoch - rhs.secPastEpoch; - if (secRes > ULONG_MAX/2) { - // - // In this situation where the difference is more than - // 68 years assume that the seconds counter has rolled - // over and compute the "wrap around" difference - // - secRes = 1 + (ULONG_MAX-secRes); - secRes = -secRes; - nSecRes = -nSecRes; - } - } - - return secRes + nSecRes/nSecPerSec; -} - -// -// operator <= -// -bool epicsTime::operator <= (const epicsTime &rhs) const -{ - bool rc; - - if (this->secPastEpochsecPastEpoch < ULONG_MAX/2) { - // - // In this situation where the difference is less than - // 69 years compute the expected result - // - rc = true; - } - else { - // - // In this situation where the difference is more than - // 69 years assume that the seconds counter has rolled - // over and compute the "wrap around" result - // - rc = false; - } - } - else if (this->secPastEpoch>rhs.secPastEpoch) { - if (this->secPastEpoch-rhs.secPastEpoch < ULONG_MAX/2) { - // - // In this situation where the difference is less than - // 69 years compute the expected result - // - rc = false; - } - else { - // - // In this situation where the difference is more than - // 69 years assume that the seconds counter has rolled - // over and compute the "wrap around" result - // - rc = true; - } - } - else { - if (this->nSec<=rhs.nSec) { - rc = true; - } - else { - rc = false; - } - } - return rc; -} - -// -// operator < -// -bool epicsTime::operator < (const epicsTime &rhs) const -{ - bool rc; - - if (this->secPastEpochsecPastEpoch < ULONG_MAX/2) { - // - // In this situation where the difference is less than - // 69 years compute the expected result - // - rc = true; - } - else { - // - // In this situation where the difference is more than - // 69 years assume that the seconds counter has rolled - // over and compute the "wrap around" result - // - rc = false; - } - } - else if (this->secPastEpoch>rhs.secPastEpoch) { - if (this->secPastEpoch-rhs.secPastEpoch < ULONG_MAX/2) { - // - // In this situation where the difference is less than - // 69 years compute the expected result - // - rc = false; - } - else { - // - // In this situation where the difference is more than - // 69 years assume that the seconds counter has rolled - // over and compute the "wrap around" result - // - rc = true; - } - } - else { - if (this->nSec epicsTime (*pRight); - } - catch ( ... ) { - return 0; - } - } - epicsShareFunc int epicsShareAPI epicsTimeGreaterThanEqual (const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight) - { - try { - return epicsTime (*pLeft) >= epicsTime (*pRight); - } - catch ( ... ) { - return 0; - } - } - epicsShareFunc size_t epicsShareAPI epicsTimeToStrftime (char *pBuff, size_t bufLength, const char *pFormat, const epicsTimeStamp *pTS) - { - try { - return epicsTime(*pTS).strftime (pBuff, bufLength, pFormat); - } - catch ( ... ) { - return 0; - } - } - epicsShareFunc void epicsShareAPI epicsTimeShow (const epicsTimeStamp *pTS, unsigned interestLevel) - { - try { - epicsTime(*pTS).show (interestLevel); - } - catch ( ... ) { - printf ( "Invalid epicsTimeStamp\n" ); - } - } -} diff --git a/src/libCom/osi/epicsTime.h b/src/libCom/osi/epicsTime.h deleted file mode 100644 index 149f6f2d3..000000000 --- a/src/libCom/osi/epicsTime.h +++ /dev/null @@ -1,357 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsTime.h */ -/* Author Jeffrey O. Hill */ - -#ifndef epicsTimehInclude -#define epicsTimehInclude - -#include - -#include "shareLib.h" -#include "epicsTypes.h" -#include "osdTime.h" -#include "errMdef.h" - -/* The EPICS Epoch is 00:00:00 Jan 1, 1990 UTC */ -#define POSIX_TIME_AT_EPICS_EPOCH 631152000u - -/* epics time stamp for C interface*/ -typedef struct epicsTimeStamp { - epicsUInt32 secPastEpoch; /* seconds since 0000 Jan 1, 1990 */ - epicsUInt32 nsec; /* nanoseconds within second */ -} epicsTimeStamp; - -/*TS_STAMP is deprecated */ -#define TS_STAMP epicsTimeStamp - - -struct timespec; /* POSIX real time */ -struct timeval; /* BSD */ -struct l_fp; /* NTP timestamp */ - -#ifdef __cplusplus - -/* - * extend ANSI C RTL "struct tm" to include nano seconds within a second - * and a struct tm that is adjusted for the local timezone - */ -struct local_tm_nano_sec { - struct tm ansi_tm; /* ANSI C time details */ - unsigned long nSec; /* nano seconds extension */ -}; - -/* - * extend ANSI C RTL "struct tm" to includes nano seconds within a second - * and a struct tm that is adjusted for GMT (UTC) - */ -struct gm_tm_nano_sec { - struct tm ansi_tm; /* ANSI C time details */ - unsigned long nSec; /* nano seconds extension */ -}; - -/* - * wrapping this in a struct allows conversion to and - * from ANSI time_t but does not allow unexpected - * conversions to occur - */ -struct time_t_wrapper { - time_t ts; -}; - -class epicsShareClass epicsTimeEvent -{ -public: - epicsTimeEvent (const int &number); - operator int () const; -private: - int eventNumber; -}; - -class epicsShareClass epicsTime -{ -public: - /* exceptions */ - class unableToFetchCurrentTime {}; - class formatProblemWithStructTM {}; - - epicsTime (); - epicsTime ( const epicsTime & t ); - - static epicsTime getEvent ( const epicsTimeEvent & ); - static epicsTime getCurrent (); - - /* convert to and from EPICS epicsTimeStamp format */ - operator epicsTimeStamp () const; - epicsTime ( const epicsTimeStamp & ts ); - epicsTime & operator = ( const epicsTimeStamp & ); - - /* convert to and from ANSI time_t */ - operator time_t_wrapper () const; - epicsTime ( const time_t_wrapper & ); - epicsTime & operator = ( const time_t_wrapper & ); - - /* - * convert to and from ANSI Cs "struct tm" (with nano seconds) - * adjusted for the local time zone - */ - operator local_tm_nano_sec () const; - epicsTime ( const local_tm_nano_sec & ); - epicsTime & operator = ( const local_tm_nano_sec & ); - - /* - * convert to and from ANSI Cs "struct tm" (with nano seconds) - * adjusted for GM time (UTC) - */ - operator gm_tm_nano_sec () const; - epicsTime ( const gm_tm_nano_sec & ); - epicsTime & operator = ( const gm_tm_nano_sec & ); - - /* convert to and from POSIX RTs "struct timespec" */ - operator struct timespec () const; - epicsTime ( const struct timespec & ); - epicsTime & operator = ( const struct timespec & ); - - /* convert to and from BSDs "struct timeval" */ - operator struct timeval () const; - epicsTime ( const struct timeval & ); - epicsTime & operator = ( const struct timeval & ); - - /* convert to and from NTP timestamp format */ - operator l_fp () const; - epicsTime ( const l_fp & ); - epicsTime & operator = ( const l_fp & ); - - /* convert to and from WIN32s FILETIME (implemented only on WIN32) */ - operator struct _FILETIME () const; - epicsTime ( const struct _FILETIME & ); - epicsTime & operator = ( const struct _FILETIME & ); - - /* arithmetic operators */ - double operator- ( const epicsTime & ) const; /* returns seconds */ - epicsTime operator+ ( const double & ) const; /* add rhs seconds */ - epicsTime operator- ( const double & ) const; /* subtract rhs seconds */ - epicsTime operator+= ( const double & ); /* add rhs seconds */ - epicsTime operator-= ( const double & ); /* subtract rhs seconds */ - - /* comparison operators */ - bool operator == ( const epicsTime & ) const; - bool operator != ( const epicsTime & ) const; - bool operator <= ( const epicsTime & ) const; - bool operator < ( const epicsTime & ) const; - bool operator >= ( const epicsTime & ) const; - bool operator > ( const epicsTime & ) const; - - /* convert current state to user-specified string */ - size_t strftime ( char * pBuff, size_t bufLength, const char * pFormat ) const; - - /* dump current state to standard out */ - void show ( unsigned interestLevel ) const; - -private: - /* - * private because: - * a) application does not break when EPICS epoch is changed - * b) no assumptions about internal storage or internal precision - * in the application - * c) it would be easy to forget which argument is nanoseconds - * and which argument is seconds (no help from compiler) - */ - epicsTime ( const unsigned long secPastEpoch, const unsigned long nSec ); - void addNanoSec ( long nanoSecAdjust ); - - unsigned long secPastEpoch; /* seconds since O000 Jan 1, 1990 */ - unsigned long nSec; /* nanoseconds within second */ -}; - -extern "C" { -#endif /* __cplusplus */ - -/* epicsTime routines return S_time_ error status values */ -#define epicsTimeOK 0 -#define S_time_noProvider (M_time| 1) /*No time provider*/ -#define S_time_badEvent (M_time| 2) /*Bad event number*/ -#define S_time_badArgs (M_time| 3) /*Invalid arguments*/ -#define S_time_noMemory (M_time| 4) /*Out of memory*/ -#define S_time_unsynchronized (M_time| 5) /*Provider not synchronized*/ -#define S_time_timezone (M_time| 6) /*Invalid timeone*/ -#define S_time_conversion (M_time| 7) /*Time conversion error*/ - -/*Some special values for eventNumber*/ -#define epicsTimeEventCurrentTime 0 -#define epicsTimeEventBestTime -1 -#define epicsTimeEventDeviceTime -2 - -/* These are implemented in the "generalTime" framework */ -epicsShareFunc int epicsShareAPI epicsTimeGetCurrent ( epicsTimeStamp * pDest ); -epicsShareFunc int epicsShareAPI epicsTimeGetEvent ( - epicsTimeStamp *pDest, int eventNumber); - -/* These are callable from an Interrupt Service Routine */ -epicsShareFunc int epicsTimeGetCurrentInt(epicsTimeStamp *pDest); -epicsShareFunc int epicsTimeGetEventInt(epicsTimeStamp *pDest, int eventNumber); - -/* convert to and from ANSI C's "time_t" */ -epicsShareFunc int epicsShareAPI epicsTimeToTime_t ( - time_t * pDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromTime_t ( - epicsTimeStamp * pDest, time_t src ); - -/* convert to and from ANSI C's "struct tm" with nano seconds */ -epicsShareFunc int epicsShareAPI epicsTimeToTM ( - struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeToGMTM ( - struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromTM ( - epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromGMTM ( - epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc ); - -/* convert to and from POSIX RT's "struct timespec" */ -epicsShareFunc int epicsShareAPI epicsTimeToTimespec ( - struct timespec * pDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromTimespec ( - epicsTimeStamp * pDest, const struct timespec * pSrc ); - -/* convert to and from BSD's "struct timeval" */ -epicsShareFunc int epicsShareAPI epicsTimeToTimeval ( - struct timeval * pDest, const epicsTimeStamp * pSrc ); -epicsShareFunc int epicsShareAPI epicsTimeFromTimeval ( - epicsTimeStamp * pDest, const struct timeval * pSrc ); - -/*arithmetic operations */ -epicsShareFunc double epicsShareAPI epicsTimeDiffInSeconds ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight );/* left - right */ -epicsShareFunc void epicsShareAPI epicsTimeAddSeconds ( - epicsTimeStamp * pDest, double secondsToAdd ); /* adds seconds to *pDest */ - -/*comparison operations: returns (0,1) if (false,true) */ -epicsShareFunc int epicsShareAPI epicsTimeEqual ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); -epicsShareFunc int epicsShareAPI epicsTimeNotEqual ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); -epicsShareFunc int epicsShareAPI epicsTimeLessThan ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left < right */ -epicsShareFunc int epicsShareAPI epicsTimeLessThanEqual ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left <= right) */ -epicsShareFunc int epicsShareAPI epicsTimeGreaterThan ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left > right */ -epicsShareFunc int epicsShareAPI epicsTimeGreaterThanEqual ( - const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left >= right */ - -/*convert to ASCII string */ -epicsShareFunc size_t epicsShareAPI epicsTimeToStrftime ( - char * pBuff, size_t bufLength, const char * pFormat, const epicsTimeStamp * pTS ); - -/* dump current state to standard out */ -epicsShareFunc void epicsShareAPI epicsTimeShow ( - const epicsTimeStamp *, unsigned interestLevel ); - -/* OS dependent reentrant versions of the ANSI C interface because */ -/* vxWorks gmtime_r interface does not match POSIX standards */ -epicsShareFunc int epicsShareAPI epicsTime_localtime ( const time_t * clock, struct tm * result ); -epicsShareFunc int epicsShareAPI epicsTime_gmtime ( const time_t * clock, struct tm * result ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -/* inline member functions ,*/ -#ifdef __cplusplus - -/* epicsTimeEvent */ - -inline epicsTimeEvent::epicsTimeEvent (const int &number) : - eventNumber(number) {} - -inline epicsTimeEvent::operator int () const -{ - return this->eventNumber; -} - - -/* epicsTime */ - -inline epicsTime epicsTime::operator - ( const double & rhs ) const -{ - return epicsTime::operator + ( -rhs ); -} - -inline epicsTime epicsTime::operator += ( const double & rhs ) -{ - *this = epicsTime::operator + ( rhs ); - return *this; -} - -inline epicsTime epicsTime::operator -= ( const double & rhs ) -{ - *this = epicsTime::operator + ( -rhs ); - return *this; -} - -inline bool epicsTime::operator == ( const epicsTime & rhs ) const -{ - if ( this->secPastEpoch == rhs.secPastEpoch && this->nSec == rhs.nSec ) { - return true; - } - return false; -} - -inline bool epicsTime::operator != ( const epicsTime & rhs ) const -{ - return !epicsTime::operator == ( rhs ); -} - -inline bool epicsTime::operator >= ( const epicsTime & rhs ) const -{ - return ! ( *this < rhs ); -} - -inline bool epicsTime::operator > ( const epicsTime & rhs ) const -{ - return ! ( *this <= rhs ); -} - -inline epicsTime & epicsTime::operator = ( const local_tm_nano_sec & rhs ) -{ - return *this = epicsTime ( rhs ); -} - -inline epicsTime & epicsTime::operator = ( const gm_tm_nano_sec & rhs ) -{ - return *this = epicsTime ( rhs ); -} - -inline epicsTime & epicsTime::operator = ( const struct timespec & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} - -inline epicsTime & epicsTime::operator = ( const epicsTimeStamp & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} - -inline epicsTime & epicsTime::operator = ( const l_fp & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} - -inline epicsTime & epicsTime::operator = ( const time_t_wrapper & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} -#endif /* __cplusplus */ - -#endif /* epicsTimehInclude */ - diff --git a/src/libCom/osi/generalTimeSup.h b/src/libCom/osi/generalTimeSup.h deleted file mode 100644 index bd6627ef6..000000000 --- a/src/libCom/osi/generalTimeSup.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2008 Diamond Light Source Ltd -* Copyright (c) 2004 Oak Ridge National Laboratory -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_generalTimeSup_H -#define INC_generalTimeSup_H - -#include "epicsTime.h" -#include "epicsTimer.h" -#include "shareLib.h" - -#define LAST_RESORT_PRIORITY 999 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int (*TIMECURRENTFUN)(epicsTimeStamp *pDest); -typedef int (*TIMEEVENTFUN)(epicsTimeStamp *pDest, int event); - -epicsShareFunc int generalTimeRegisterCurrentProvider(const char *name, - int priority, TIMECURRENTFUN getTime); -epicsShareFunc int generalTimeRegisterEventProvider(const char *name, - int priority, TIMEEVENTFUN getEvent); - -/* Original names, for compatibility */ -#define generalTimeCurrentTpRegister generalTimeRegisterCurrentProvider -#define generalTimeEventTpRegister generalTimeRegisterEventProvider - -epicsShareFunc int generalTimeAddIntCurrentProvider(const char *name, - int priority, TIMECURRENTFUN getTime); -epicsShareFunc int generalTimeAddIntEventProvider(const char *name, - int priority, TIMEEVENTFUN getEvent); - -epicsShareFunc int generalTimeGetExceptPriority(epicsTimeStamp *pDest, - int *pPrio, int ignorePrio); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_generalTimeSup_H */ diff --git a/src/libCom/osi/os/Darwin/epicsMath.h b/src/libCom/osi/os/Darwin/epicsMath.h deleted file mode 100644 index d540ba5d3..000000000 --- a/src/libCom/osi/os/Darwin/epicsMath.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include - -#define finite(x) isfinite(x) - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/Darwin/osdBackTrace.cpp b/src/libCom/osi/os/Darwin/osdBackTrace.cpp deleted file mode 100644 index 4595fee3a..000000000 --- a/src/libCom/osi/os/Darwin/osdBackTrace.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include "osdExecinfoBackTrace.cpp" diff --git a/src/libCom/osi/os/Darwin/osdEnv.c b/src/libCom/osi/os/Darwin/osdEnv.c deleted file mode 100644 index ab3f93644..000000000 --- a/src/libCom/osi/os/Darwin/osdEnv.c +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEnv.c */ -/* - * Author: Eric Norum - * Date: May 7, 2001 - * - * Routines to modify/display environment variables and EPICS parameters - * - */ - -#include -#include -#include -#include -#include - -/* - * Starting in Mac OS X 10.5 (Leopard) shared libraries and - * bundles don't have direct access to environ (man environ). - */ -#include -#define environ (*_NSGetEnviron()) - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "envDefs.h" -#include "iocsh.h" - -/* - * Set the value of an environment variable - */ -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value) -{ - iocshEnvClear(name); - setenv(name, value, 1); -} - -/* - * Show the value of the specified, or all, environment variables - */ -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name) -{ - if (name == NULL) { - extern char **environ; - char **sp; - - for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) - printf ("%s\n", *sp); - } - else { - const char *cp = getenv (name); - if (cp == NULL) - printf ("%s is not an environment variable.\n", name); - else - printf ("%s=%s\n", name, cp); - } -} diff --git a/src/libCom/osi/os/Darwin/osdFindAddr.c b/src/libCom/osi/os/Darwin/osdFindAddr.c deleted file mode 100644 index b92770a54..000000000 --- a/src/libCom/osi/os/Darwin/osdFindAddr.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -/* Make sure dladdr() is visible */ -#define _DARWIN_C_SOURCE - -#include - -#define epicsExportSharedSymbols -#include "epicsStackTrace.h" -#include "epicsStackTracePvt.h" - -/* Darwin's finds local symbols, too :-) */ - -int epicsFindAddr(void *addr, epicsSymbol *sym_p) -{ - Dl_info inf; - - if ( ! dladdr(addr, &inf) ) { - sym_p->f_nam = 0; - sym_p->s_nam = 0; - sym_p->s_val = 0; - } else { - sym_p->f_nam = inf.dli_fname; - sym_p->s_nam = inf.dli_sname; - sym_p->s_val = inf.dli_saddr; - } - - return 0; -} - -int epicsFindAddrGetFeatures(void) -{ - return EPICS_STACKTRACE_LCL_SYMBOLS - | EPICS_STACKTRACE_GBL_SYMBOLS - | EPICS_STACKTRACE_DYN_SYMBOLS; -} diff --git a/src/libCom/osi/os/Darwin/osdSock.h b/src/libCom/osi/os/Darwin/osdSock.h deleted file mode 100644 index 1d4556eee..000000000 --- a/src/libCom/osi/os/Darwin/osdSock.h +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Eric Norum - */ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)ifr_addr.sa_len + sizeof((pifreq)->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/Darwin/osdSockAddrReuse.cpp b/src/libCom/osi/os/Darwin/osdSockAddrReuse.cpp deleted file mode 100644 index 869514160..000000000 --- a/src/libCom/osi/os/Darwin/osdSockAddrReuse.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} - -/* - * SO_REUSEPORT is not in POSIX - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEPORT, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEPORT?\n"); - } -} diff --git a/src/libCom/osi/os/Darwin/osdTime.cpp b/src/libCom/osi/os/Darwin/osdTime.cpp deleted file mode 100644 index 72b3dc874..000000000 --- a/src/libCom/osi/os/Darwin/osdTime.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#include "osiSock.h" - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsTime.h" -#include "generalTimeSup.h" - -static clock_serv_t host_clock; - -extern "C" { -static int osdTimeGetCurrent (epicsTimeStamp *pDest) -{ - mach_timespec_t mts; - struct timespec ts; - - clock_get_time(host_clock, &mts); - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; - *pDest = epicsTime(ts); - return epicsTimeOK; -} -} // extern "C" - - -static int timeRegister(void) -{ - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &host_clock); - - generalTimeCurrentTpRegister("MachTime", \ - LAST_RESORT_PRIORITY, osdTimeGetCurrent); - return 1; -} -static int done = timeRegister(); - - -int epicsTime_gmtime(const time_t *pAnsiTime, struct tm *pTM) -{ - return gmtime_r(pAnsiTime, pTM) ? - epicsTimeOK : errno; -} - -int epicsTime_localtime(const time_t *clock, struct tm *result) -{ - return localtime_r(clock, result) ? - epicsTimeOK : errno; -} - -extern "C" epicsShareFunc void -convertDoubleToWakeTime(double timeout, struct timespec *wakeTime) -{ - mach_timespec_t now; - struct timespec wait; - - if (timeout < 0.0) - timeout = 0.0; - else if (timeout > 60 * 60 * 24 * 3652.5) - timeout = 60 * 60 * 24 * 3652.5; /* 10 years */ - - clock_get_time(host_clock, &now); - - wait.tv_sec = static_cast< time_t >(timeout); - wait.tv_nsec = static_cast< long >((timeout - (double)wait.tv_sec) * 1e9); - - wakeTime->tv_sec = now.tv_sec + wait.tv_sec; - wakeTime->tv_nsec = now.tv_nsec + wait.tv_nsec; - if (wakeTime->tv_nsec >= 1000000000L) { - wakeTime->tv_nsec -= 1000000000L; - ++wakeTime->tv_sec; - } -} diff --git a/src/libCom/osi/os/Darwin/osdTime.h b/src/libCom/osi/os/Darwin/osdTime.h deleted file mode 100644 index d0c361404..000000000 --- a/src/libCom/osi/os/Darwin/osdTime.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Eric Norum - */ - -#ifndef osdTimeh -#define osdTimeh - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void convertDoubleToWakeTime(double timeout, - struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/Darwin/osiFileName.h b/src/libCom/osi/os/Darwin/osiFileName.h deleted file mode 100644 index a78118679..000000000 --- a/src/libCom/osi/os/Darwin/osiFileName.h +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Eric Norum - */ - -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/Linux/osdBackTrace.cpp b/src/libCom/osi/os/Linux/osdBackTrace.cpp deleted file mode 100644 index 4595fee3a..000000000 --- a/src/libCom/osi/os/Linux/osdBackTrace.cpp +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include "osdExecinfoBackTrace.cpp" diff --git a/src/libCom/osi/os/Linux/osdFindAddr.c b/src/libCom/osi/os/Linux/osdFindAddr.c deleted file mode 100644 index 84d17d96f..000000000 --- a/src/libCom/osi/os/Linux/osdFindAddr.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include "osdElfFindAddr.c" diff --git a/src/libCom/osi/os/Linux/osdSock.h b/src/libCom/osi/os/Linux/osdSock.h deleted file mode 100644 index 614f3f98d..000000000 --- a/src/libCom/osi/os/Linux/osdSock.h +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Linux specific socket include - */ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/Linux/osdThread.h b/src/libCom/osi/os/Linux/osdThread.h deleted file mode 100644 index 7d2a4868d..000000000 --- a/src/libCom/osi/os/Linux/osdThread.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef INC_osdThread_H -#define INC_osdThread_H - -#include -#include - -#include "shareLib.h" -#include "ellLib.h" -#include "epicsEvent.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct epicsThreadOSD { - ELLNODE node; - pthread_t tid; - pid_t lwpId; - pthread_attr_t attr; - struct sched_param schedParam; - int schedPolicy; - EPICSTHREADFUNC createFunc; - void *createArg; - epicsEventId suspendEvent; - int isSuspended; - int isEpicsThread; - int isRealTimeScheduled; - int isOnThreadList; - unsigned int osiPriority; - char name[1]; /* actually larger */ -} epicsThreadOSD; - -epicsShareFunc pthread_t epicsThreadGetPosixThreadId(epicsThreadId id); -epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId id); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_osdThread_H */ diff --git a/src/libCom/osi/os/Linux/osdThreadExtra.c b/src/libCom/osi/os/Linux/osdThreadExtra.c deleted file mode 100644 index 6423004c5..000000000 --- a/src/libCom/osi/os/Linux/osdThreadExtra.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 18JAN2000 */ - -/* This differs from the posix implementation of epicsThread by: - * - printing the Linux LWP ID instead of the POSIX thread ID in the show routines - * - installing a default thread start hook, that sets the Linux thread name to the - * EPICS thread name to make it visible on OS level, and discovers the LWP ID */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsThread.h" - -void epicsThreadShowInfo(epicsThreadId pthreadInfo, unsigned int level) -{ - if (!pthreadInfo) { - fprintf(epicsGetStdout(), " NAME EPICS ID " - "LWP ID OSIPRI OSSPRI STATE\n"); - } else { - struct sched_param param; - int priority = 0; - - if (pthreadInfo->tid) { - int policy; - int status = pthread_getschedparam(pthreadInfo->tid, &policy, - ¶m); - - if (!status) - priority = param.sched_priority; - } - fprintf(epicsGetStdout(),"%16.16s %14p %8lu %3d%8d %8.8s\n", - pthreadInfo->name,(void *) - pthreadInfo,(unsigned long)pthreadInfo->lwpId, - pthreadInfo->osiPriority,priority, - pthreadInfo->isSuspended ? "SUSPEND" : "OK"); - } -} - -static void thread_hook(epicsThreadId pthreadInfo) -{ - /* Set the name of the thread's process. Limited to 16 characters. */ - char comm[16]; - - if (strcmp(pthreadInfo->name, "_main_")) { - snprintf(comm, sizeof(comm), "%s", pthreadInfo->name); - prctl(PR_SET_NAME, comm, 0l, 0l, 0l); - } - pthreadInfo->lwpId = syscall(SYS_gettid); -} - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault = thread_hook; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain = thread_hook; diff --git a/src/libCom/osi/os/Linux/osdTime.h b/src/libCom/osi/os/Linux/osdTime.h deleted file mode 100644 index 988f8747f..000000000 --- a/src/libCom/osi/os/Linux/osdTime.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osdTimeh -#define osdTimeh - -/* - * Linux needs this include file since the POSIX version - * causes `struct timespec' to be defined in more than one place. - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsShareAPI - convertDoubleToWakeTime(double timeout,struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/Linux/osiFileName.h b/src/libCom/osi/os/Linux/osiFileName.h deleted file mode 100644 index 3a6448d54..000000000 --- a/src/libCom/osi/os/Linux/osiFileName.h +++ /dev/null @@ -1,19 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/Linux/osiUnistd.h b/src/libCom/osi/os/Linux/osiUnistd.h deleted file mode 100644 index 336a9a802..000000000 --- a/src/libCom/osi/os/Linux/osiUnistd.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -/* - * Some systems fail to provide prototypes of these functions. - * Others provide different prototypes. - * There seems to be no way to handle this automatically, so - * if you get compile errors, just make the appropriate changes here. - */ diff --git a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c b/src/libCom/osi/os/RTEMS/devLibVMEOSD.c deleted file mode 100644 index 0a96bad1a..000000000 --- a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c +++ /dev/null @@ -1,365 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* RTEMS port by Till Straumann, - * 3/2002 - * - */ - -#include -#include -#include -#include -#include "devLibVME.h" -#include - -#if defined(__PPC__) || defined(__mcf528x__) - -#if defined(__PPC__) -#include -#include -#endif - - -typedef void myISR (void *pParam); - -static myISR *isrFetch(unsigned vectorNumber, void **parg); - -/* - * this routine needs to be in the symbol table - * for this code to work correctly - */ -static void unsolicitedHandlerEPICS(int vectorNumber); - -static myISR *defaultHandlerAddr[]={ - (myISR*)unsolicitedHandlerEPICS, -}; - -/* - * Make sure that the CR/CSR addressing mode is defined. - * (it may not be in some BSPs). - */ -#ifndef VME_AM_CSR -# define VME_AM_CSR (0x2f) -#endif - -/* - * we use a translation between an EPICS encoding - * and a vxWorks encoding here - * to reduce dependency of drivers on vxWorks - * - * we assume that the BSP are configured to use these - * address modes by default - */ -#define EPICSAddrTypeNoConvert -1 -int EPICStovxWorksAddrType[] - = { - VME_AM_SUP_SHORT_IO, - VME_AM_STD_SUP_DATA, - VME_AM_EXT_SUP_DATA, - EPICSAddrTypeNoConvert, - VME_AM_CSR - }; - -/* - * maps logical address to physical address, but does not detect - * two device drivers that are using the same address range - */ -static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress); - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue); - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); - -static long rtemsDevConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter); - -static long rtemsDevDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -); - -static long rtemsDevEnableInterruptLevelVME (unsigned level); - -static long rtemsDevDisableInterruptLevelVME (unsigned level); - -static int rtemsDevInterruptInUseVME (unsigned vectorNumber); - -/* RTEMS specific init */ - -/*devA24Malloc and devA24Free are not implemented*/ -static void *devA24Malloc(size_t size) { return 0;} -static void devA24Free(void *pBlock) {}; -static long rtemsDevInit(void); - -/* - * used by bind in devLib.c - */ -static devLibVME rtemsVirtualOS = { - rtemsDevMapAddr, rtemsDevReadProbe, rtemsDevWriteProbe, - rtemsDevConnectInterruptVME, rtemsDevDisconnectInterruptVME, - rtemsDevEnableInterruptLevelVME, rtemsDevDisableInterruptLevelVME, - devA24Malloc,devA24Free,rtemsDevInit,rtemsDevInterruptInUseVME -}; -devLibVME *pdevLibVME = &rtemsVirtualOS; - -/* RTEMS specific initialization */ -static long -rtemsDevInit(void) -{ - /* assume the vme bridge has been initialized by bsp */ - /* init BSP extensions [memProbe etc.] */ - return bspExtInit(); -} - -/* - * devConnectInterruptVME - * - * wrapper to minimize driver dependency on OS - */ -static long rtemsDevConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter) -{ - int status; - - - if (devInterruptInUseVME(vectorNumber)) { - return S_dev_vectorInUse; - } - status = BSP_installVME_isr( - vectorNumber, - pFunction, - parameter); - if (status) { - return S_dev_vecInstlFail; - } - - return 0; -} - -/* - * - * devDisconnectInterruptVME() - * - * wrapper to minimize driver dependency on OS - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from removing - * an interrupt handler that was installed by another driver - * - */ -static long rtemsDevDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -) -{ - void (*psub)(); - void *arg; - int status; - - /* - * If pFunction not connected to this vector - * then they are probably disconnecting from the wrong vector - */ - psub = isrFetch(vectorNumber, &arg); - if(psub != pFunction){ - return S_dev_vectorNotInUse; - } - - status = BSP_removeVME_isr( - vectorNumber, - psub, - arg) || - BSP_installVME_isr( - vectorNumber, - (BSP_VME_ISR_t)unsolicitedHandlerEPICS, - (void*)vectorNumber); - if(status){ - return S_dev_vecInstlFail; - } - - return 0; -} - -/* - * enable VME interrupt level - */ -static long rtemsDevEnableInterruptLevelVME (unsigned level) -{ - return BSP_enableVME_int_lvl(level); -} - -/* - * disable VME interrupt level - */ -static long rtemsDevDisableInterruptLevelVME (unsigned level) -{ - return BSP_disableVME_int_lvl(level); -} - -/* - * rtemsDevMapAddr () - */ -static long rtemsDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress) -{ - long status; - - if (ppPhysicalAddress==NULL) { - return S_dev_badArgument; - } - - if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert) - { - *ppPhysicalAddress = (void *) logicalAddress; - } - else - { - status = BSP_vme2local_adrs(EPICStovxWorksAddrType[addrType], - logicalAddress, (unsigned long *)ppPhysicalAddress); - if (status) { - return S_dev_addrMapFail; - } - } - - return 0; -} - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -rtems_status_code bspExtMemProbe(void *addr, int write, int size, void *pval); -static long rtemsDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) -{ - long status; - - /* - * this global variable exists in the nivxi library - */ - status = bspExtMemProbe ((void*)ptr, 0/*read*/, wordSize, pValue); - if (status!=RTEMS_SUCCESSFUL) { - return S_dev_noDevice; - } - - return 0; -} - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long rtemsDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) -{ - long status; - - /* - * this global variable exists in the nivxi library - */ - status = bspExtMemProbe ((void*)ptr, 1/*write*/, wordSize, (void*)pValue); - if (status!=RTEMS_SUCCESSFUL) { - return S_dev_noDevice; - } - - return 0; -} - -/* - * isrFetch() - */ -static myISR *isrFetch(unsigned vectorNumber, void **parg) -{ - /* - * fetch the handler or C stub attached at this vector - */ - return (myISR *) BSP_getVME_isr(vectorNumber,parg); -} - -/* - * determine if a VME interrupt vector is in use - */ -static int rtemsDevInterruptInUseVME (unsigned vectorNumber) -{ - int i; - myISR *psub; - void *arg; - - psub = isrFetch (vectorNumber,&arg); - - if (!psub) - return FALSE; - - /* - * its a C routine. Does it match a default handler? - */ - for (i=0; i -#include "epicsMMIO.h" -#include "compilerSpecific.h" -#include "epicsInterrupt.h" - -#define EPICS_ATOMIC_OS_NAME "RTEMS" - -typedef struct EpicsAtomicLockKey { - int key; -} EpicsAtomicLockKey; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - epicsAtomicMemoryBarrierFallback(); -} -#endif - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - rwbarr(); -} -#endif - -EPICS_ATOMIC_INLINE void epicsAtomicLock ( struct EpicsAtomicLockKey * pkey ) -{ - pkey->key = epicsInterruptLock(); -} - -EPICS_ATOMIC_INLINE void epicsAtomicUnlock ( struct EpicsAtomicLockKey * pkey ) -{ - epicsInterruptUnlock(pkey->key); -} - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/RTEMS/epicsMMIO.h b/src/libCom/osi/os/RTEMS/epicsMMIO.h deleted file mode 100644 index 293886b78..000000000 --- a/src/libCom/osi/os/RTEMS/epicsMMIO.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Michael Davidsaver - */ - -#ifndef EPICSMMIO_H -#define EPICSMMIO_H - -#include -#include -#include - -#if defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) -# include - -/*NOTE: All READ/WRITE operations have an implicit read or write barrier */ - -# define ioread8(A) in_8((volatile epicsUInt8*)(A)) -# define iowrite8(A,D) out_8((volatile epicsUInt8*)(A), D) -# define le_ioread16(A) in_le16((volatile epicsUInt16*)(A)) -# define le_ioread32(A) in_le32((volatile epicsUInt32*)(A)) -# define le_iowrite16(A,D) out_le16((volatile epicsUInt16*)(A), D) -# define le_iowrite32(A,D) out_le32((volatile epicsUInt32*)(A), D) -# define be_ioread16(A) in_be16((volatile epicsUInt16*)(A)) -# define be_ioread32(A) in_be32((volatile epicsUInt32*)(A)) -# define be_iowrite16(A,D) out_be16((volatile epicsUInt16*)(A), D) -# define be_iowrite32(A,D) out_be32((volatile epicsUInt32*)(A), D) - -# define rbarr() iobarrier_r() -# define wbarr() iobarrier_w() -# define rwbarr() iobarrier_rw() - -/* Define native operations */ -# define nat_ioread16 be_ioread16 -# define nat_ioread32 be_ioread32 -# define nat_iowrite16 be_iowrite16 -# define nat_iowrite32 be_iowrite32 - -static EPICS_ALWAYS_INLINE -epicsUInt16 -bswap16(epicsUInt16 value) -{ - return (((epicsUInt16)(value) & 0x00ff) << 8) | - (((epicsUInt16)(value) & 0xff00) >> 8); -} - -static EPICS_ALWAYS_INLINE -epicsUInt32 -bswap32(epicsUInt32 value) -{ - return (((epicsUInt32)(value) & 0x000000ff) << 24) | - (((epicsUInt32)(value) & 0x0000ff00) << 8) | - (((epicsUInt32)(value) & 0x00ff0000) >> 8) | - (((epicsUInt32)(value) & 0xff000000) >> 24); -} - -#elif defined(i386) || defined(__i386__) || defined(__i386) || defined(__m68k__) - -/* X86 does not need special handling for read/write width. - * - * TODO: Memory barriers? - */ - -#include "epicsMMIODef.h" - -#else -# warning I/O operations not defined for this RTEMS architecture - -#include "epicsMMIODef.h" - -#endif /* if defined PPC */ - -#endif /* EPICSMMIO_H */ diff --git a/src/libCom/osi/os/RTEMS/epicsMath.h b/src/libCom/osi/os/RTEMS/epicsMath.h deleted file mode 100644 index 83115f06e..000000000 --- a/src/libCom/osi/os/RTEMS/epicsMath.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/RTEMS/osdEvent.c b/src/libCom/osi/os/RTEMS/osdEvent.c deleted file mode 100644 index 455413870..000000000 --- a/src/libCom/osi/os/RTEMS/osdEvent.c +++ /dev/null @@ -1,200 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdEvent.c - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -/* - * We want to access information which is - * normally hidden from application programs. - */ -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#include -#include -#include - -#include "epicsEvent.h" -#include "epicsThread.h" -#include "errlog.h" - -/* #define EPICS_RTEMS_SEMAPHORE_STATS */ -/* - * Some performance tuning instrumentation - */ -#ifdef EPICS_RTEMS_SEMAPHORE_STATS -unsigned long semEstat[4]; -#define SEMSTAT(i) semEstat[i]++; -#else -#define SEMSTAT(i) -#endif - -/* - * Create a simple binary semaphore - */ -epicsEventId -epicsEventCreate(epicsEventInitialState initialState) -{ - rtems_status_code sc; - rtems_id sid; - rtems_interrupt_level level; - static char c1 = 'a'; - static char c2 = 'a'; - static char c3 = 'a'; - - sc = rtems_semaphore_create (rtems_build_name ('B', c3, c2, c1), - initialState, - RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | - RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, - 0, - &sid); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't create binary semaphore: %s\n", rtems_status_text (sc)); - return NULL; - } - rtems_interrupt_disable (level); - if (c1 == 'z') { - if (c2 == 'z') { - if (c3 == 'z') { - c3 = 'a'; - } - else { - c3++; - } - c2 = 'a'; - } - else { - c2++; - } - c1 = 'a'; - } - else { - c1++; - } - rtems_interrupt_enable (level); - return (epicsEventId)sid; -} - -void -epicsEventDestroy(epicsEventId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - sc = rtems_semaphore_delete (sid); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf ("Can't destroy semaphore: %s\n", rtems_status_text (sc)); -} - -epicsEventStatus -epicsEventTrigger(epicsEventId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - sc = rtems_semaphore_release (sid); - if (sc == RTEMS_SUCCESSFUL) - return epicsEventOK; - errlogPrintf ("Can't release semaphore: %s\n", rtems_status_text (sc)); - return epicsEventError; -} - -epicsEventStatus -epicsEventWait(epicsEventId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - SEMSTAT(0) - sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - return epicsEventError; - return epicsEventOK; -} - -epicsEventStatus -epicsEventWaitWithTimeout(epicsEventId id, double timeOut) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - rtems_interval delay; - extern double rtemsTicksPerSecond_double; - - if (timeOut <= 0.0) - return epicsEventTryWait(id); - SEMSTAT(1) - delay = timeOut * rtemsTicksPerSecond_double; - if (delay == 0) - delay++; - sc = rtems_semaphore_obtain (sid, RTEMS_WAIT, delay); - if (sc == RTEMS_SUCCESSFUL) - return epicsEventOK; - else if (sc == RTEMS_TIMEOUT) - return epicsEventWaitTimeout; - else - return epicsEventError; -} - -epicsEventStatus -epicsEventTryWait(epicsEventId id) -{ - rtems_id sid = (rtems_id)id; - rtems_status_code sc; - - SEMSTAT(2) - sc = rtems_semaphore_obtain (sid, RTEMS_NO_WAIT, RTEMS_NO_TIMEOUT); - if (sc == RTEMS_SUCCESSFUL) - return epicsEventOK; - else if (sc == RTEMS_UNSATISFIED) - return epicsEventWaitTimeout; - else - return epicsEventError; -} - -void -epicsEventShow(epicsEventId id, unsigned int level) -{ -#if __RTEMS_VIOLATE_KERNEL_VISIBILITY__ - rtems_id sid = (rtems_id)id; - Semaphore_Control *the_semaphore; - Semaphore_Control semaphore; - Objects_Locations location; - - the_semaphore = _Semaphore_Get (sid, &location); - if (location != OBJECTS_LOCAL) - return; - /* - * Yes, there's a race condition here since an interrupt might - * change things while the copy is in progress, but the information - * is only for display, so it's not that critical. - */ - semaphore = *the_semaphore; - _Thread_Enable_dispatch(); - printf (" %8.8x ", (int)sid); - if (_Attributes_Is_counting_semaphore (semaphore.attribute_set)) { - printf ("Count: %d", (int)semaphore.Core_control.semaphore.count); - } - else { - if (_CORE_mutex_Is_locked(&semaphore.Core_control.mutex)) { - char name[30]; - epicsThreadGetName ((epicsThreadId)semaphore.Core_control.mutex.holder_id, name, sizeof name); - printf ("Held by:%8.8x (%s) Nest count:%d", - (unsigned int)semaphore.Core_control.mutex.holder_id, - name, - (int)semaphore.Core_control.mutex.nest_count); - } - else { - printf ("Not Held"); - } - } - printf ("\n"); -#endif -} diff --git a/src/libCom/osi/os/RTEMS/osdEvent.h b/src/libCom/osi/os/RTEMS/osdEvent.h deleted file mode 100644 index 6c53aada7..000000000 --- a/src/libCom/osi/os/RTEMS/osdEvent.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdEvent.h - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -/* osdEvent.h not needed */ diff --git a/src/libCom/osi/os/RTEMS/osdFindSymbol.c b/src/libCom/osi/os/RTEMS/osdFindSymbol.c deleted file mode 100644 index 9e947f95c..000000000 --- a/src/libCom/osi/os/RTEMS/osdFindSymbol.c +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/RTEMS/osdFindSymbol.c */ - -/* GESYS could support this, but must use compile-time detection - * as the code must build for non-GESYS systems as well. - */ - -#define epicsExportSharedSymbols -#include "epicsFindSymbol.h" - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - return 0; -} - -epicsShareFunc const char *epicsLoadError(void) -{ - return "epicsLoadLibrary not implemented"; -} - -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name) -{ - return 0; -} diff --git a/src/libCom/osi/os/RTEMS/osdInterrupt.c b/src/libCom/osi/os/RTEMS/osdInterrupt.c deleted file mode 100644 index 88ce664e5..000000000 --- a/src/libCom/osi/os/RTEMS/osdInterrupt.c +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdInterrupt.c - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -#include -#include -#include -#include "errlog.h" -#include "epicsInterrupt.h" -#include "epicsThread.h" - -#define INTERRUPT_CONTEXT_MESSAGE_QUEUE_COUNT 100 - -static rtems_id interruptContextMessageQueue; - -int -epicsInterruptLock (void) -{ - rtems_interrupt_level level; - - rtems_interrupt_disable (level); - return level; -} - -void -epicsInterruptUnlock (int key) -{ - rtems_interrupt_level level = key; - - rtems_interrupt_enable (level); -} - -int -epicsInterruptIsInterruptContext (void) -{ - return rtems_interrupt_is_in_progress (); -} - -/* - * Pass a message from an interrupt context. - * Note that this passes a pointer to the message, not the message itself. - * This implies that the message must remain valid after the - * interrupt context is no longer active. - */ -void -epicsInterruptContextMessage (const char *message) -{ - rtems_message_queue_send (interruptContextMessageQueue, &message, sizeof message); -} - -/* - * Daemon to process interrupt context messages - */ -void -InterruptContextMessageDaemon (void *unused) -{ - const char *message; - size_t size; - rtems_status_code sc; - - sc = rtems_message_queue_create (rtems_build_name ('I', 'C', 'M', 'Q'), - INTERRUPT_CONTEXT_MESSAGE_QUEUE_COUNT, - sizeof message, - RTEMS_FIFO | RTEMS_LOCAL, - &interruptContextMessageQueue); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't create interrupt context message queue: %s\n", rtems_status_text (sc)); - epicsThreadSuspendSelf (); - } - for (;;) { - sc = rtems_message_queue_receive (interruptContextMessageQueue, - &message, - &size, - RTEMS_WAIT, - RTEMS_NO_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't receive message from interrupt context: %s\n", rtems_status_text (sc)); - epicsThreadSuspendSelf (); - } - if (size == sizeof message) - syslog (LOG_ERR, "%s", message); - else - errlogPrintf ("Received %u-byte message from interrupt context", (unsigned int)size); - } -} diff --git a/src/libCom/osi/os/RTEMS/osdInterrupt.h b/src/libCom/osi/os/RTEMS/osdInterrupt.h deleted file mode 100644 index 2f3a2c596..000000000 --- a/src/libCom/osi/os/RTEMS/osdInterrupt.h +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Daemon to soak up and report messages from interrupt contexts - */ -extern void InterruptContextMessageDaemon (void *); diff --git a/src/libCom/osi/os/RTEMS/osdMessageQueue.c b/src/libCom/osi/os/RTEMS/osdMessageQueue.c deleted file mode 100644 index a566de6f6..000000000 --- a/src/libCom/osi/os/RTEMS/osdMessageQueue.c +++ /dev/null @@ -1,251 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -/* - * We want to access information which is - * normally hidden from application programs. - */ -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#define epicsExportSharedSymbols -#include -#include -#include -#include -#include -#include -#include "epicsMessageQueue.h" -#include "errlog.h" - -epicsShareFunc epicsMessageQueueId epicsShareAPI -epicsMessageQueueCreate(unsigned int capacity, unsigned int maximumMessageSize) -{ - rtems_status_code sc; - epicsMessageQueueId id = calloc(1, sizeof(*id)); - rtems_interrupt_level level; - static char c1 = 'a'; - static char c2 = 'a'; - static char c3 = 'a'; - - if(!id) - return NULL; - - sc = rtems_message_queue_create (rtems_build_name ('Q', c3, c2, c1), - capacity, - maximumMessageSize, - RTEMS_FIFO|RTEMS_LOCAL, - &id->id); - if (sc != RTEMS_SUCCESSFUL) { - free(id); - errlogPrintf ("Can't create message queue: %s\n", rtems_status_text (sc)); - return NULL; - } - id->maxSize = maximumMessageSize; - id->localBuf = NULL; - rtems_interrupt_disable (level); - if (c1 == 'z') { - if (c2 == 'z') { - if (c3 == 'z') { - c3 = 'a'; - } - else { - c3++; - } - c2 = 'a'; - } - else { - c2++; - } - c1 = 'a'; - } - else { - c1++; - } - rtems_interrupt_enable (level); - return id; -} - -static rtems_status_code rtems_message_queue_send_timeout( - rtems_id id, - void *buffer, - uint32_t size, - rtems_interval timeout) -{ - Message_queue_Control *the_message_queue; - Objects_Locations location; - CORE_message_queue_Status msg_status; - - the_message_queue = _Message_queue_Get( id, &location ); - switch ( location ) - { - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - msg_status = _CORE_message_queue_Send( - &the_message_queue->message_queue, - buffer, - size, - id, - NULL, - 1, - timeout - ); - - _Thread_Enable_dispatch(); - - /* - * If we had to block, then this is where the task returns - * after it wakes up. The returned status is correct for - * non-blocking operations but if we blocked, then we need - * to look at the status in our TCB. - */ - - if ( msg_status == CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_WAIT ) - msg_status = _Thread_Executing->Wait.return_code; - return _Message_queue_Translate_core_message_queue_return_code( msg_status ); - } - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueSend( - epicsMessageQueueId id, - void *message, - unsigned int messageSize) -{ - if (rtems_message_queue_send_timeout(id->id, message, messageSize, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL) - return 0; - else - return -1; -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int messageSize, - double timeout) -{ - rtems_interval delay; - extern double rtemsTicksPerSecond_double; - - /* - * Convert time to ticks - */ - if (timeout <= 0.0) - return epicsMessageQueueTrySend(id, message, messageSize); - delay = (int)(timeout * rtemsTicksPerSecond_double); - if (delay == 0) - delay++; - if (rtems_message_queue_send_timeout(id->id, message, messageSize, delay) == RTEMS_SUCCESSFUL) - return 0; - else - return -1; -} - -static int receiveMessage( - epicsMessageQueueId id, - void *buffer, - uint32_t size, - uint32_t wait, - rtems_interval delay) -{ - size_t rsize; - rtems_status_code sc; - - if (size < id->maxSize) { - if (id->localBuf == NULL) { - id->localBuf = malloc(id->maxSize); - if (id->localBuf == NULL) - return -1; - } - rsize = receiveMessage(id, id->localBuf, id->maxSize, wait, delay); - if (rsize > size) - return -1; - memcpy(buffer, id->localBuf, rsize); - } - else { - sc = rtems_message_queue_receive(id->id, buffer, &rsize, wait, delay); - if (sc != RTEMS_SUCCESSFUL) - return -1; - } - return rsize; -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueTryReceive( - epicsMessageQueueId id, - void *message, - unsigned int size) -{ - return receiveMessage(id, message, size, RTEMS_NO_WAIT, 0); -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueReceive( - epicsMessageQueueId id, - void *message, - unsigned int size) -{ - return receiveMessage(id, message, size, RTEMS_WAIT, RTEMS_NO_TIMEOUT); -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int size, - double timeout) -{ - rtems_interval delay; - uint32_t wait; - extern double rtemsTicksPerSecond_double; - - /* - * Convert time to ticks - */ - if (timeout <= 0.0) { - wait = RTEMS_NO_WAIT; - delay = 0; - } - else { - wait = RTEMS_WAIT; - delay = (int)(timeout * rtemsTicksPerSecond_double); - if (delay == 0) - delay++; - } - return receiveMessage(id, message, size, wait, delay); -} - -epicsShareFunc int epicsShareAPI epicsMessageQueuePending( - epicsMessageQueueId id) -{ - uint32_t count; - rtems_status_code sc; - - sc = rtems_message_queue_get_number_pending(id->id, &count); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf("Message queue %x get number pending failed: %s\n", - (unsigned int)id, - rtems_status_text(sc)); - return -1; - } - return count; -} - -epicsShareFunc void epicsShareAPI epicsMessageQueueShow( - epicsMessageQueueId id, - int level) -{ - int pending = epicsMessageQueuePending(id); - if (pending >= 0) - printf ("Message queue %lx -- Pending: %d\n", (unsigned long)id, pending); -} diff --git a/src/libCom/osi/os/RTEMS/osdMessageQueue.h b/src/libCom/osi/os/RTEMS/osdMessageQueue.h deleted file mode 100644 index 0244a1f0b..000000000 --- a/src/libCom/osi/os/RTEMS/osdMessageQueue.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -/* - * Very thin shims around RTEMS routines - */ -#include - -struct epicsMessageQueueOSD { - rtems_id id; - unsigned int maxSize; - void *localBuf; - -}; -#define epicsMessageQueueDestroy(q) (rtems_message_queue_delete((q)->id)) - -#define epicsMessageQueueTrySend(q,m,l) (rtems_message_queue_send((q)->id, (m), (l)) == RTEMS_SUCCESSFUL ? 0 : -1) diff --git a/src/libCom/osi/os/RTEMS/osdMutex.c b/src/libCom/osi/os/RTEMS/osdMutex.c deleted file mode 100644 index 96fde6ea0..000000000 --- a/src/libCom/osi/os/RTEMS/osdMutex.c +++ /dev/null @@ -1,195 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdMutex.c - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -/* - * We want to access information which is - * normally hidden from application programs. - */ -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#include -#include -#include -#include - -#include "epicsStdio.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "errlog.h" - -#define RTEMS_FAST_MUTEX -/* #define EPICS_RTEMS_SEMAPHORE_STATS */ -/* - * Some performance tuning instrumentation - */ -#ifdef EPICS_RTEMS_SEMAPHORE_STATS -unsigned long semMstat[4]; -#define SEMSTAT(i) semMstat[i]++; -#else -#define SEMSTAT(i) -#endif - -struct epicsMutexOSD * -epicsMutexOsdCreate(void) -{ - rtems_status_code sc; - rtems_id sid; - rtems_interrupt_level level; - static char c1 = 'a'; - static char c2 = 'a'; - static char c3 = 'a'; - - sc = rtems_semaphore_create (rtems_build_name ('M', c3, c2, c1), - 1, - RTEMS_PRIORITY|RTEMS_BINARY_SEMAPHORE|RTEMS_INHERIT_PRIORITY|RTEMS_NO_PRIORITY_CEILING|RTEMS_LOCAL, - 0, - &sid); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("Can't create mutex semaphore: %s\n", rtems_status_text (sc)); - return NULL; - } - rtems_interrupt_disable (level); - if (c1 == 'z') { - if (c2 == 'z') { - if (c3 == 'z') { - c3 = 'a'; - } - else { - c3++; - } - c2 = 'a'; - } - else { - c2++; - } - c1 = 'a'; - } - else { - c1++; - } - rtems_interrupt_enable (level); -#ifdef RTEMS_FAST_MUTEX - { - Semaphore_Control *the_semaphore; - Objects_Locations location; - - the_semaphore = _Semaphore_Get( sid, &location ); - _Thread_Enable_dispatch(); - - return (struct epicsMutexOSD *)the_semaphore; - } -#endif - return (struct epicsMutexOSD *)sid; -} - -void epicsMutexOsdDestroy(struct epicsMutexOSD * id) -{ - rtems_status_code sc; - rtems_id sid; -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - sid = the_semaphore->Object.id; -#else - sid = (rtems_id)id; -#endif - sc = rtems_semaphore_delete (sid); - if (sc == RTEMS_RESOURCE_IN_USE) { - rtems_semaphore_release (sid); - sc = rtems_semaphore_delete (sid); - } - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf ("Can't destroy semaphore %p (%lx): %s\n", id, (unsigned long)sid, rtems_status_text (sc)); -} - -void epicsMutexOsdUnlock(struct epicsMutexOSD * id) -{ -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - _Thread_Disable_dispatch(); - _CORE_mutex_Surrender ( - &the_semaphore->Core_control.mutex, - the_semaphore->Object.id, - NULL - ); - _Thread_Enable_dispatch(); -#else - epicsEventSignal (id); -#endif - -} - -epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * id) -{ -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - ISR_Level level; - SEMSTAT(0) - _ISR_Disable( level ); - _CORE_mutex_Seize( - &the_semaphore->Core_control.mutex, - the_semaphore->Object.id, - 1, /* TRUE or FALSE */ - 0, /* same as passed to obtain -- ticks */ - level - ); - if (_Thread_Executing->Wait.return_code == 0) - return epicsMutexLockOK; - else - return epicsMutexLockError; -#else - SEMSTAT(0) - return((epicsEventWait (id) == epicsEventWaitOK) - ?epicsMutexLockOK : epicsMutexLockError); -#endif -} - -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id) -{ -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - ISR_Level level; - SEMSTAT(2) - _ISR_Disable( level ); - _CORE_mutex_Seize( - &the_semaphore->Core_control.mutex, - the_semaphore->Object.id, - 0, /* TRUE or FALSE */ - 0, /* same as passed to obtain -- ticks */ - level - ); - if (_Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_SUCCESSFUL) - return epicsMutexLockOK; - else if (_Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT) - return epicsMutexLockTimeout; - else - return epicsMutexLockError; -#else - epicsEventWaitStatus status; - SEMSTAT(2) - status = epicsEventTryWait(id); - return((status==epicsEventWaitOK - ? epicsMutexLockOK - : (status==epicsEventWaitTimeout) - ? epicsMutexLockTimeout - : epicsMutexLockError)); -#endif -} - -epicsShareFunc void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level) -{ -#ifdef RTEMS_FAST_MUTEX - Semaphore_Control *the_semaphore = (Semaphore_Control *)id; - id = (struct epicsMutexOSD *)the_semaphore->Object.id; -#endif - epicsEventShow ((epicsEventId)id,level); -} diff --git a/src/libCom/osi/os/RTEMS/osdMutex.h b/src/libCom/osi/os/RTEMS/osdMutex.h deleted file mode 100644 index 7e2ecc77d..000000000 --- a/src/libCom/osi/os/RTEMS/osdMutex.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdMutex.h - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ - -/* osdSem.h not needed */ diff --git a/src/libCom/osi/os/RTEMS/osdPoolStatus.c b/src/libCom/osi/os/RTEMS/osdPoolStatus.c deleted file mode 100644 index b2f401190..000000000 --- a/src/libCom/osi/os/RTEMS/osdPoolStatus.c +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include - -#define epicsExportSharedSymbols -#include "osiPoolStatus.h" - -/* - * osiSufficentSpaceInPool () - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) -{ - rtems_malloc_statistics_t s; - unsigned long n; - - malloc_get_statistics(&s); - n = s.space_available - (unsigned long)(s.lifetime_allocated - s.lifetime_freed); - return (n > (50000 + contiguousBlockSize)); -} diff --git a/src/libCom/osi/os/RTEMS/osdProcess.c b/src/libCom/osi/os/RTEMS/osdProcess.c deleted file mode 100644 index 2768dbb0d..000000000 --- a/src/libCom/osi/os/RTEMS/osdProcess.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Operating System Dependent Implementation of osiProcess.h - * - * Author: Jeff Hill - * - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "osiProcess.h" - -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSizeIn) -{ - const char *pName = "rtems"; - unsigned uiLength; - size_t len; - - len = strlen (pName); - - if ( len>UINT_MAX || len<=0 ) { - return osiGetUserNameFail; - } - uiLength = (unsigned) len; - - if ( uiLength + 1 >= bufSizeIn ) { - return osiGetUserNameFail; - } - - strncpy ( pBuf, pName, (size_t) bufSizeIn ); - - return osiGetUserNameSuccess; -} - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - (const char *pProcessName, const char *pBaseExecutableName) -{ - return osiSpawnDetachedProcessNoSupport; -} diff --git a/src/libCom/osi/os/RTEMS/osdReadline.c b/src/libCom/osi/os/RTEMS/osdReadline.c deleted file mode 100644 index 877db53f6..000000000 --- a/src/libCom/osi/os/RTEMS/osdReadline.c +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ - -/* - * This file is included by epicsReadline.c which has already included the - * headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h - */ - -#include -#include - -struct osdContext {}; - -/* - * Create a command-line context - */ -static void -osdReadlineBegin (struct readlineContext *context) -{ - GetLine *gl; - long i = 50; - - envGetLongConfigParam(&IOCSH_HISTSIZE, &i); - if (i < 0) - i = 0; - - gl = new_GetLine(200, i * 40); - if (gl) { - context->osd = (struct osdContext *) gl; - if (context->in) - gl_change_terminal(gl, context->in, stdout, NULL); - } -} - -/* - * Read a line of input - */ -static char * -osdReadline (const char *prompt, struct readlineContext *context) -{ - GetLine *gl = (GetLine *) context->osd; - char *line; - - line = gl_get_line(gl, prompt ? prompt : "", NULL, -1); - if (line) { - char *nl = strchr(line, '\n'); - - if (nl) - *nl = '\0'; - } - return line; -} - -/* - * Destroy a command-line context - */ -static void -osdReadlineEnd(struct readlineContext *context) -{ - GetLine *gl = (GetLine *) context->osd; - - del_GetLine(gl); -} - diff --git a/src/libCom/osi/os/RTEMS/osdSignal.cpp b/src/libCom/osi/os/RTEMS/osdSignal.cpp deleted file mode 100644 index 08dfa023c..000000000 --- a/src/libCom/osi/os/RTEMS/osdSignal.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -/* - * All NOOPs if the os isnt POSIX - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * /* threadId */ ) {} - diff --git a/src/libCom/osi/os/RTEMS/osdSock.h b/src/libCom/osi/os/RTEMS/osdSock.h deleted file mode 100644 index 930ed0e72..000000000 --- a/src/libCom/osi/os/RTEMS/osdSock.h +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdSock.h - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD) -#include -#include - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK (u_long)0x7F000001 -#endif - -#ifndef INADDR_NONE -# define INADDR_NONE (0xffffffff) -#endif - -/* - * For shutdown() - */ -#ifndef SHUT_RD -# define SHUT_RD 0 -#endif - -#ifndef SHUT_WR -# define SHUT_WR 1 -#endif - -#ifndef SHUT_RDWR -# define SHUT_RDWR 2 -#endif - -/* - * Ensure that we get the right network code in default/osdNetIntf.c. - */ -#define ifreq_size(pifreq) (pifreq->ifr_addr.sa_len + sizeof(pifreq->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/RTEMS/osdSpin.c b/src/libCom/osi/os/RTEMS/osdSpin.c deleted file mode 100644 index 7a4546812..000000000 --- a/src/libCom/osi/os/RTEMS/osdSpin.c +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2013 Brookhaven Science Assoc. as Operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Authors: Ralph Lange - * Andrew Johnson - * Michael Davidsaver - * - * Inspired by Linux UP spinlocks implemention - * include/linux/spinlock_api_up.h - */ - -/* - * RTEMS (single CPU): LOCK INTERRUPT and DISABLE PREEMPTION - * - * CAVEAT: - * This implementation is intended for UP architectures only. - */ - -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#include -#include - -#include "cantProceed.h" -#include "epicsSpin.h" - -typedef struct epicsSpin { - rtems_interrupt_level level; - unsigned int locked; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - return calloc(1, sizeof(epicsSpin)); -} - -epicsSpinId epicsSpinMustCreate(void) -{ - epicsSpinId ret = epicsSpinCreate(); - if (!ret) - cantProceed("epicsSpinMustCreate: epicsSpinCreate failed."); - return ret; -} - -void epicsSpinDestroy(epicsSpinId spin) { - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - _Thread_Disable_dispatch(); - if (spin->locked) { - rtems_interrupt_enable(level); - _Thread_Enable_dispatch(); - if (!rtems_interrupt_is_in_progress()) { - printk("epicsSpinLock(%p): Deadlock.\n", spin); - cantProceed("Recursive lock, missed unlock or block when locked."); - } - else { - printk("epicsSpinLock(%p): Deadlock in ISR.\n" - "Recursive lock, missed unlock or block when locked.\n", - spin); - } - return; - } - spin->level = level; - spin->locked = 1; -} - -int epicsSpinTryLock(epicsSpinId spin) { - rtems_interrupt_level level; - - rtems_interrupt_disable(level); - _Thread_Disable_dispatch(); - if (spin->locked) { - rtems_interrupt_enable(level); - _Thread_Enable_dispatch(); - return 1; - } - spin->level = level; - spin->locked = 1; - return 0; -} - -void epicsSpinUnlock(epicsSpinId spin) { - rtems_interrupt_level level = spin->level; - - if (!spin->locked) { - printk("epicsSpinUnlock(%p): not locked\n", spin); - return; - } - spin->level = spin->locked = 0; - rtems_interrupt_enable (level); - _Thread_Enable_dispatch(); -} diff --git a/src/libCom/osi/os/RTEMS/osdStrtod.h b/src/libCom/osi/os/RTEMS/osdStrtod.h deleted file mode 100644 index 39fda698d..000000000 --- a/src/libCom/osi/os/RTEMS/osdStrtod.h +++ /dev/null @@ -1,11 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * epicsStrtod() for systems with working strtod() routine - */ -#define epicsStrtod strtod diff --git a/src/libCom/osi/os/RTEMS/osdThread.c b/src/libCom/osi/os/RTEMS/osdThread.c deleted file mode 100644 index 769e95820..000000000 --- a/src/libCom/osi/os/RTEMS/osdThread.c +++ /dev/null @@ -1,748 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osdThread.c - * Author: W. Eric Norum - */ - -/* - * We want to print out some task information which is - * normally hidden from application programs. - */ -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ 1 - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "epicsStdio.h" -#include "errlog.h" -#include "epicsMutex.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "osiUnistd.h" -#include "osdInterrupt.h" -#include "epicsExit.h" - -epicsShareFunc void osdThreadHooksRun(epicsThreadId id); -epicsShareFunc void osdThreadHooksRunMain(epicsThreadId id); - -/* - * Per-task variables - */ -struct taskVar { - struct taskVar *forw; - struct taskVar *back; - char *name; - rtems_id id; - EPICSTHREADFUNC funptr; - void *parm; - unsigned int threadVariableCapacity; - void **threadVariables; -}; -static struct epicsMutexOSD *taskVarMutex; -static struct taskVar *taskVarHead; -#define RTEMS_NOTEPAD_TASKVAR 11 - -/* - * Support for `once-only' execution - */ -static volatile int initialized = 0; /* strictly speaking 'volatile' is not enough here, but it shouldn't hurt */ -static struct epicsMutexOSD *onceMutex; - -static -void epicsMutexOsdMustLock(struct epicsMutexOSD * L) -{ - while(epicsMutexOsdLock(L)!=epicsMutexLockOK) { - cantProceed("epicsThreadOnce() mutex error"); - } -} - -/* - * Just map osi 0 to 99 into RTEMS 199 to 100 - * For RTEMS lower number means higher priority - * RTEMS = 100 + (99 - osi) - * = 199 - osi - * osi = 199 - RTEMS - */ -int epicsThreadGetOsiPriorityValue(int ossPriority) -{ - if (ossPriority < 100) { - return epicsThreadPriorityMax; - } - else if (ossPriority > 199) { - return epicsThreadPriorityMin; - } - else { - return (199u - (unsigned int)ossPriority); - } -} - -int epicsThreadGetOssPriorityValue(unsigned int osiPriority) -{ - if (osiPriority > 99) { - return 100; - } - else { - return (199 - (signed int)osiPriority); - } -} - -/* - * epicsThreadLowestPriorityLevelAbove () - */ -epicsShareFunc epicsThreadBooleanStatus epicsThreadLowestPriorityLevelAbove - (unsigned int priority, unsigned *pPriorityJustAbove) -{ - unsigned newPriority = priority + 1; - - newPriority = priority + 1; - if (newPriority <= 99) { - *pPriorityJustAbove = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -/* - * epicsThreadHighestPriorityLevelBelow () - */ -epicsShareFunc epicsThreadBooleanStatus epicsThreadHighestPriorityLevelBelow - (unsigned int priority, unsigned *pPriorityJustBelow) -{ - unsigned newPriority = priority - 1; - - if (newPriority <= 99) { - *pPriorityJustBelow = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -unsigned int -epicsThreadGetStackSize (epicsThreadStackSizeClass size) -{ - unsigned int stackSize = 11000; - switch(size) { - case epicsThreadStackSmall: stackSize = 5000; break; - case epicsThreadStackMedium: stackSize = 8000; break; - case epicsThreadStackBig: break; - default: - errlogPrintf("epicsThreadGetStackSize illegal argument"); - break; - } - if (stackSize < RTEMS_MINIMUM_STACK_SIZE) - stackSize = RTEMS_MINIMUM_STACK_SIZE; - return stackSize; -} - -/* - * Ensure integrity of task variable list - */ -static void -taskVarLock (void) -{ - epicsMutexOsdMustLock (taskVarMutex); -} - -static void -taskVarUnlock (void) -{ - epicsMutexOsdUnlock (taskVarMutex); -} - -/* - * EPICS threads destroy themselves by returning from the thread entry function. - * This simple wrapper provides the same semantics on RTEMS. - */ -static rtems_task -threadWrapper (rtems_task_argument arg) -{ - struct taskVar *v = (struct taskVar *)arg; - - osdThreadHooksRun((epicsThreadId)v->id); - (*v->funptr)(v->parm); - epicsExitCallAtThreadExits (); - taskVarLock (); - if (v->back) - v->back->forw = v->forw; - else - taskVarHead = v->forw; - if (v->forw) - v->forw->back = v->back; - taskVarUnlock (); - free (v->threadVariables); - free (v->name); - free (v); - rtems_task_delete (RTEMS_SELF); -} - -/* - * The task wrapper takes care of cleanup - */ -void epicsThreadExitMain (void) -{ -} - -static void -setThreadInfo(rtems_id tid, const char *name, EPICSTHREADFUNC funptr, - void *parm) -{ - struct taskVar *v; - uint32_t note; - rtems_status_code sc; - - v = mallocMustSucceed (sizeof *v, "epicsThreadCreate_vars"); - v->name = epicsStrDup(name); - v->id = tid; - v->funptr = funptr; - v->parm = parm; - v->threadVariableCapacity = 0; - v->threadVariables = NULL; - note = (uint32_t)v; - rtems_task_set_note (tid, RTEMS_NOTEPAD_TASKVAR, note); - taskVarLock (); - v->forw = taskVarHead; - v->back = NULL; - if (v->forw) - v->forw->back = v; - taskVarHead = v; - taskVarUnlock (); - if (funptr) { - sc = rtems_task_start (tid, threadWrapper, (rtems_task_argument)v); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf ("setThreadInfo: Can't start %s: %s\n", - name, rtems_status_text(sc)); - } -} - -/* - * OS-dependent initialization - * No need to worry about making this thread-safe since - * it must be called before epicsThreadCreate creates - * any new threads. - */ -static void -epicsThreadInit (void) -{ - if (!initialized) { - rtems_id tid; - rtems_task_priority old; - - rtems_task_set_priority (RTEMS_SELF, epicsThreadGetOssPriorityValue(99), &old); - onceMutex = epicsMutexOsdCreate(); - taskVarMutex = epicsMutexOsdCreate(); - if (!onceMutex || !taskVarMutex) - cantProceed("epicsThreadInit() can't create global mutexes\n"); - rtems_task_ident (RTEMS_SELF, 0, &tid); - setThreadInfo (tid, "_main_", NULL, NULL); - osdThreadHooksRunMain((epicsThreadId)tid); - initialized = 1; - epicsThreadCreate ("ImsgDaemon", 99, - epicsThreadGetStackSize (epicsThreadStackSmall), - InterruptContextMessageDaemon, NULL); - } -} - -void epicsThreadRealtimeLock(void) -{} - -/* - * Create and start a new thread - */ -epicsThreadId -epicsThreadCreate (const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - rtems_id tid; - rtems_status_code sc; - char c[4]; - - if (!initialized) epicsThreadInit(); - if (stackSize < RTEMS_MINIMUM_STACK_SIZE) { - errlogPrintf ("Warning: epicsThreadCreate %s illegal stackSize %d\n", - name, stackSize); - stackSize = RTEMS_MINIMUM_STACK_SIZE; - } - strncpy (c, name, sizeof c); - sc = rtems_task_create (rtems_build_name (c[0], c[1], c[2], c[3]), - epicsThreadGetOssPriorityValue (priority), - stackSize, - RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), - RTEMS_FLOATING_POINT|RTEMS_LOCAL, - &tid); - if (sc != RTEMS_SUCCESSFUL) { - errlogPrintf ("epicsThreadCreate create failure for %s: %s\n", - name, rtems_status_text(sc)); - return 0; - } - setThreadInfo (tid, name, funptr,parm); - return (epicsThreadId)tid; -} - -epicsThreadId -threadMustCreate (const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - epicsThreadId tid = epicsThreadCreate(name, priority, stackSize, funptr, parm); - - if (tid == NULL) - cantProceed(0); - return tid; -} - -void -epicsThreadSuspendSelf (void) -{ - rtems_status_code sc; - - sc = rtems_task_suspend (RTEMS_SELF); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadSuspendSelf failed: %s\n", - rtems_status_text(sc)); -} - -void epicsThreadResume(epicsThreadId id) -{ - rtems_id tid = (rtems_id)id; - rtems_status_code sc; - - sc = rtems_task_resume (tid); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadResume failed: %s\n", - rtems_status_text (sc)); -} - -unsigned int epicsThreadGetPriority(epicsThreadId id) -{ - rtems_id tid = (rtems_id)id; - rtems_status_code sc; - rtems_task_priority pri; - - sc = rtems_task_set_priority (tid, RTEMS_CURRENT_PRIORITY, &pri); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadGetPriority failed: %s\n", - rtems_status_text(sc)); - return epicsThreadGetOsiPriorityValue(pri); -} - -unsigned int epicsThreadGetPrioritySelf(void) -{ - return epicsThreadGetPriority((epicsThreadId)RTEMS_SELF); -} - -void -epicsThreadSetPriority (epicsThreadId id,unsigned int osip) -{ - rtems_id tid = (rtems_id)id; - rtems_status_code sc; - rtems_task_priority pri = epicsThreadGetOssPriorityValue(osip); - - sc = rtems_task_set_priority (tid, pri, &pri); - if (sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadSetPriority failed: %s\n", - rtems_status_text(sc)); -} - -int -epicsThreadIsEqual (epicsThreadId id1, epicsThreadId id2) -{ - return (id1 == id2); -} - -int -epicsThreadIsSuspended (epicsThreadId id) -{ - rtems_id tid = (rtems_id)id; - rtems_status_code sc; - - switch (sc = rtems_task_is_suspended (tid)) { - case RTEMS_SUCCESSFUL: - return 0; - - case RTEMS_ALREADY_SUSPENDED: - return 1; - - default: - return 1; - } -} - -void -epicsThreadSleep (double seconds) -{ - rtems_status_code sc; - rtems_interval delay; - extern double rtemsTicksPerSecond_double; - - if (seconds > 0.0) { - seconds *= rtemsTicksPerSecond_double; - seconds += 0.99999999; /* 8 9s here is optimal */ - delay = (seconds >= INT_MAX) ? INT_MAX : (int) seconds; - } - else { /* seconds <= 0 or NAN */ - delay = 0; - } - sc = rtems_task_wake_after (delay); - if(sc != RTEMS_SUCCESSFUL) - errlogPrintf("epicsThreadSleep: %s\n", rtems_status_text(sc)); -} - -epicsThreadId -epicsThreadGetIdSelf (void) -{ - rtems_id tid; - - rtems_task_ident (RTEMS_SELF, 0, &tid); - return (epicsThreadId)tid; -} - -const char *epicsThreadGetNameSelf(void) -{ - uint32_t note; - struct taskVar *v; - - rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, ¬e); - v = (void *)note; - return v->name; -} - -void epicsThreadGetName (epicsThreadId id, char *name, size_t size) -{ - rtems_id tid = (rtems_id)id; - struct taskVar *v; - int haveName = 0; - - taskVarLock (); - for (v=taskVarHead ; v != NULL ; v=v->forw) { - if (v->id == tid) { - strncpy(name, v->name, size); - haveName = 1; - break; - } - } - taskVarUnlock (); - if (!haveName) { -#if (__RTEMS_MAJOR__>4 || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__>8) || \ - (__RTEMS_MAJOR__==4 && __RTEMS_MINOR__==8 && __RTEMS_REVISION__>=99)) - if (_Objects_Get_name_as_string((rtems_id)id, size, name) != NULL) - haveName = 1; -#else - /* - * Try to get the RTEMS task name - */ - Thread_Control *thr; - Objects_Locations l; - if ((thr=_Thread_Get(tid, &l)) != NULL) { - if (OBJECTS_LOCAL == l) { - int length; - Objects_Information *oi = _Objects_Get_information(tid); - if (oi->name_length >= size) - length = size - 1; - else - length = oi->name_length; - if (oi->is_string) - strncpy(name, thr->Object.name, length); - else - _Objects_Copy_name_raw( &thr->Object.name, name, length); - name[length] = '\0'; - haveName = 1; - } - _Thread_Enable_dispatch(); - } -#endif - } - if (!haveName) - snprintf(name, size, "0x%lx", (long)tid); - name[size-1] = '\0'; -} - -epicsThreadId epicsThreadGetId (const char *name) -{ - struct taskVar *v; - rtems_id tid = 0; - - /* - * Linear search is good enough since this routine - * is invoked only by command-line calls. - */ - taskVarLock (); - for (v = taskVarHead ; v != NULL ; v = v->forw) { - if (strcmp (name, v->name) == 0) { - tid = v->id; - break; - } - } - taskVarUnlock (); - return (epicsThreadId)tid; -} - -/* - * Ensure func() is run only once. - */ -void epicsThreadOnce(epicsThreadOnceId *id, void(*func)(void *), void *arg) -{ - #define EPICS_THREAD_ONCE_DONE (epicsThreadId) 1 - - if (!initialized) epicsThreadInit(); - epicsMutexOsdMustLock(onceMutex); - if (*id != EPICS_THREAD_ONCE_DONE) { - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - epicsMutexOsdUnlock(onceMutex); - func(arg); - epicsMutexOsdMustLock(onceMutex); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - epicsMutexOsdUnlock(onceMutex); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ - epicsMutexOsdUnlock(onceMutex); - epicsThreadSleep(epicsThreadSleepQuantum()); - epicsMutexOsdMustLock(onceMutex); - } - } - epicsMutexOsdUnlock(onceMutex); -} - -/* - * Thread private storage implementation based on the vxWorks - * implementation by Andrew Johnson APS/ASD. - */ -epicsThreadPrivateId epicsThreadPrivateCreate () -{ - unsigned int taskVarIndex; - static volatile unsigned int threadVariableCount = 0; - - if (!initialized) epicsThreadInit (); - taskVarLock (); - taskVarIndex = ++threadVariableCount; - taskVarUnlock (); - return (epicsThreadPrivateId)taskVarIndex; -} - -void epicsThreadPrivateDelete (epicsThreadPrivateId id) -{ - /* empty */ -} - -void epicsThreadPrivateSet (epicsThreadPrivateId id, void *pvt) -{ - unsigned int varIndex = (unsigned int)id; - uint32_t note; - struct taskVar *v; - int i; - - rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, ¬e); - v = (struct taskVar *)note; - if (varIndex >= v->threadVariableCapacity) { - v->threadVariables = realloc (v->threadVariables, - (varIndex + 1) * sizeof(void *)); - if (v->threadVariables == NULL) - cantProceed("epicsThreadPrivateSet realloc failed\n"); - for (i = v->threadVariableCapacity ; i < varIndex ; i++) - v->threadVariables[i] = NULL; - v->threadVariableCapacity = varIndex + 1; - } - v->threadVariables[varIndex] = pvt; -} - -void * epicsThreadPrivateGet (epicsThreadPrivateId id) -{ - unsigned int varIndex = (unsigned int)id; - uint32_t note; - struct taskVar *v; - - rtems_task_get_note (RTEMS_SELF, RTEMS_NOTEPAD_TASKVAR, ¬e); - v = (struct taskVar *)note; - if (varIndex >= v->threadVariableCapacity) - return NULL; - return v->threadVariables[varIndex]; -} - -/* - * Show task info - */ -struct bitmap { - char *msg; - unsigned long mask; - unsigned long state; -}; - -static void -showBitmap (char *cbuf, unsigned long bits, const struct bitmap *bp) -{ - for ( ; bp->msg != NULL ; bp++) { - if ((bp->mask & bits) == bp->state) { - strcpy (cbuf, bp->msg); - cbuf += strlen (bp->msg); - } - } -} - -static void -showInternalTaskInfo (rtems_id tid) -{ -#ifdef __RTEMS_VIOLATE_KERNEL_VISIBILITY__ - int epicsPri; - Thread_Control *the_thread; - Objects_Locations location; - static Thread_Control thread; - static char bitbuf[120]; - static const struct bitmap taskState[] = { - { "RUN", STATES_ALL_SET, STATES_READY }, - { "DORM", STATES_DORMANT, STATES_DORMANT }, - { "SUSP", STATES_SUSPENDED, STATES_SUSPENDED }, - { "TRANS", STATES_TRANSIENT, STATES_TRANSIENT }, - { "Delay", STATES_DELAYING, STATES_DELAYING }, - { "Wtime", STATES_WAITING_FOR_TIME, STATES_WAITING_FOR_TIME }, - { "Wbuf", STATES_WAITING_FOR_BUFFER, STATES_WAITING_FOR_BUFFER }, - { "Wseg", STATES_WAITING_FOR_SEGMENT, STATES_WAITING_FOR_SEGMENT }, - { "Wmsg" , STATES_WAITING_FOR_MESSAGE, STATES_WAITING_FOR_MESSAGE }, - { "Wevnt", STATES_WAITING_FOR_EVENT, STATES_WAITING_FOR_EVENT }, - { "Wsem", STATES_WAITING_FOR_SEMAPHORE,STATES_WAITING_FOR_SEMAPHORE }, - { "Wmtx", STATES_WAITING_FOR_MUTEX, STATES_WAITING_FOR_MUTEX }, - { "Wjoin", STATES_WAITING_FOR_JOIN_AT_EXIT,STATES_WAITING_FOR_JOIN_AT_EXIT }, - { "Wrpc", STATES_WAITING_FOR_RPC_REPLY,STATES_WAITING_FOR_RPC_REPLY }, - { "Wrate", STATES_WAITING_FOR_PERIOD, STATES_WAITING_FOR_PERIOD }, - { "Wsig", STATES_WAITING_FOR_SIGNAL, STATES_WAITING_FOR_SIGNAL }, - { NULL, 0, 0 }, - }; - - the_thread = _Thread_Get (tid, &location); - if (location != OBJECTS_LOCAL) { - fprintf(epicsGetStdout(),"%-30s", " *** RTEMS task gone! ***"); - return; - } - thread = *the_thread; - _Thread_Enable_dispatch(); - /* - * Show both real and current priorities if they differ. - * Note that the epicsThreadGetOsiPriorityValue routine is not used here. - * If a thread has a priority outside the normal EPICS range then - * that priority should be displayed, not the value truncated to - * the EPICS range. - */ - epicsPri = 199-thread.real_priority; - if (epicsPri < 0) - fprintf(epicsGetStdout()," <0"); - else if (epicsPri > 99) - fprintf(epicsGetStdout()," >99"); - else - fprintf(epicsGetStdout()," %4d", epicsPri); - if (thread.current_priority == thread.real_priority) - fprintf(epicsGetStdout(),"%4d ", (int)thread.current_priority); - else - fprintf(epicsGetStdout(),"%4d/%-3d", (int)thread.real_priority, (int)thread.current_priority); - showBitmap (bitbuf, thread.current_state, taskState); - fprintf(epicsGetStdout(),"%8.8s", bitbuf); - if (thread.current_state & (STATES_WAITING_FOR_SEMAPHORE | - STATES_WAITING_FOR_MUTEX | - STATES_WAITING_FOR_MESSAGE)) - fprintf(epicsGetStdout()," %8.8x", (int)thread.Wait.id); - else - fprintf(epicsGetStdout()," %8.8s", ""); -#endif -} - -static void -epicsThreadShowInfo (struct taskVar *v, unsigned int level) -{ - if (!v) { - fprintf(epicsGetStdout()," PRIORITY\n"); - fprintf(epicsGetStdout()," ID EPICS RTEMS STATE WAIT NAME\n"); - fprintf(epicsGetStdout(),"+--------+-----------+--------+--------+---------------------+\n"); - } else { - fprintf(epicsGetStdout(),"%9.8x", (int)v->id); - showInternalTaskInfo (v->id); - fprintf(epicsGetStdout()," %s\n", v->name); - } -} - -void epicsThreadShow (epicsThreadId id, unsigned int level) -{ - struct taskVar *v; - - if (!id) { - epicsThreadShowInfo (NULL, level); - return; - } - taskVarLock (); - for (v = taskVarHead ; v != NULL ; v = v->forw) { - if ((rtems_id)id == v->id) { - epicsThreadShowInfo (v, level); - taskVarUnlock (); - return; - } - } - taskVarUnlock (); - fprintf(epicsGetStdout(),"*** Thread %x does not exist.\n", (unsigned int)id); -} - -void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func) -{ - struct taskVar *v; - - taskVarLock (); - /* - * Map tasks in the order of creation (backwards through list) - */ - for (v = taskVarHead ; v != NULL && v->forw != NULL ; v = v->forw) - continue; - while (v) { - func ((epicsThreadId)v->id); - v = v->back; - } - taskVarUnlock (); -} - -void epicsThreadShowAll (unsigned int level) -{ - struct taskVar *v; - - epicsThreadShowInfo (NULL, level); - taskVarLock (); - /* - * Show tasks in the order of creation (backwards through list) - */ - for (v = taskVarHead ; v != NULL && v->forw != NULL ; v = v->forw) - continue; - while (v) { - epicsThreadShowInfo (v, level); - v = v->back; - } - taskVarUnlock (); -} - -double epicsThreadSleepQuantum ( void ) -{ - extern double rtemsTicksPerSecond_double; - - return 1.0 / rtemsTicksPerSecond_double; -} - -epicsShareFunc int epicsThreadGetCPUs(void) -{ -#if defined(RTEMS_SMP) - return rtems_smp_get_number_of_processors(); -#else - return 1; -#endif -} diff --git a/src/libCom/osi/os/RTEMS/osdThread.h b/src/libCom/osi/os/RTEMS/osdThread.h deleted file mode 100644 index 4451f845a..000000000 --- a/src/libCom/osi/os/RTEMS/osdThread.h +++ /dev/null @@ -1,12 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -int epicsThreadGetOssPriorityValue(unsigned int osiPriority); - diff --git a/src/libCom/osi/os/RTEMS/osdThreadExtra.c b/src/libCom/osi/os/RTEMS/osdThreadExtra.c deleted file mode 100644 index 0a7c7ae95..000000000 --- a/src/libCom/osi/os/RTEMS/osdThreadExtra.c +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Ralph Lange Date: 26 Jun 2012 */ - -/* Null default thread hooks for all platforms that do not do anything special */ - -#define epicsExportSharedSymbols -#include "epicsThread.h" - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; diff --git a/src/libCom/osi/os/RTEMS/osdTime.cpp b/src/libCom/osi/os/RTEMS/osdTime.cpp deleted file mode 100644 index 4947c568e..000000000 --- a/src/libCom/osi/os/RTEMS/osdTime.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: W. Eric Norum - */ -#define __BSD_VISIBLE 1 -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include "epicsTime.h" -#include "osdTime.h" -#include "osiNTPTime.h" -#include "osiClockTime.h" -#include "generalTimeSup.h" - -extern "C" { - -extern rtems_interval rtemsTicksPerSecond; -int rtems_bsdnet_get_ntp(int, int(*)(), struct timespec *); -static int ntpSocket = -1; - -void osdTimeRegister(void) -{ - /* Init NTP first so it can be used to sync ClockTime */ - NTPTime_Init(100); - ClockTime_Init(CLOCKTIME_SYNC); -} - -int osdNTPGet(struct timespec *ts) -{ - static unsigned bequiet; - ssize_t ret; - - if (ntpSocket < 0) - return -1; - - /* rtems_bsdnet_get_ntp() will send an NTP request, then - * call recvfrom() exactly once to process the expected reply. - * Any leftovers in the socket buffer (ie. duplicates of - * previous replies) will cause problems. - * So flush out the socket buffer first. - */ - do { - char junk[16]; - - ret = recvfrom(ntpSocket, junk, sizeof(junk), MSG_DONTWAIT, NULL, NULL); - if (ret == -1 && errno == EAGAIN) { - break; - } - else if (ret == -1) { - if (!bequiet) { - printf("osdNTPGet cleaner error: %s\n", strerror(errno)); - bequiet = 1; - } - break; - } - else { - bequiet = 0; - } - } while (ret > 0); - - return rtems_bsdnet_get_ntp(ntpSocket, NULL, ts); -} - -void osdNTPInit(void) -{ - struct sockaddr_in myAddr; - - ntpSocket = socket (AF_INET, SOCK_DGRAM, 0); - if (ntpSocket < 0) { - printf("osdNTPInit() Can't create socket: %s\n", strerror (errno)); - return; - } - memset (&myAddr, 0, sizeof myAddr); - myAddr.sin_family = AF_INET; - myAddr.sin_port = htons (0); - myAddr.sin_addr.s_addr = htonl (INADDR_ANY); - if (bind (ntpSocket, (struct sockaddr *)&myAddr, sizeof myAddr) < 0) { - printf("osdNTPInit() Can't bind socket: %s\n", strerror (errno)); - close (ntpSocket); - ntpSocket = -1; - } -} - -void osdNTPReport(void) -{ -} - -int osdTickGet(void) -{ - rtems_interval t; - rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &t); - return t; -} - -int osdTickRateGet(void) -{ - return rtemsTicksPerSecond; -} - -/* - * Use reentrant versions of time access - */ -int epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM ) -{ - struct tm * pRet = gmtime_r ( pAnsiTime, pTM ); - if ( pRet ) { - return epicsTimeOK; - } - else { - return errno; - } -} - -int epicsTime_localtime ( const time_t *clock, struct tm *result ) -{ - struct tm * pRet = localtime_r ( clock, result ); - if ( pRet ) { - return epicsTimeOK; - } - else { - return errno; - } -} - -rtems_interval rtemsTicksPerSecond; -double rtemsTicksPerSecond_double, rtemsTicksPerTwoSeconds_double; - -} // extern "C" - -/* - * Static constructors are run too early in a standalone binary - * to be able to initialize the NTP time provider (the network - * is not available yet), so the RTEMS standalone startup code - * explicitly calls osdTimeRegister() at the appropriate time. - * However if we are loaded dynamically we *do* register our - * standard time providers at static constructor time; in this - * case the network is available already. - */ -static int staticTimeRegister(void) -{ - rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &rtemsTicksPerSecond); - rtemsTicksPerSecond_double = rtemsTicksPerSecond; - rtemsTicksPerTwoSeconds_double = rtemsTicksPerSecond_double * 2.0; - - /* If networking is already up at the time static constructors - * are executed then we are probably run-time loaded and it's - * OK to osdTimeRegister() at this point. - */ - if (rtems_bsdnet_ticks_per_second != 0) - osdTimeRegister(); - - return 1; -} -static int done = staticTimeRegister(); diff --git a/src/libCom/osi/os/RTEMS/osdTime.h b/src/libCom/osi/os/RTEMS/osdTime.h deleted file mode 100644 index 55e3bc2b0..000000000 --- a/src/libCom/osi/os/RTEMS/osdTime.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osdTime_H -#define INC_osdTime_H - -#ifdef __cplusplus -extern "C" { -#endif - -void osdTimeRegister(void); - -void osdNTPInit(void); -int osdNTPGet(struct timespec *); -void osdNTPReport(void); - -int osdTickRateGet(void); -int osdTickGet(void); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_osdTime_H */ diff --git a/src/libCom/osi/os/RTEMS/osdVME.h b/src/libCom/osi/os/RTEMS/osdVME.h deleted file mode 100644 index 65548abcb..000000000 --- a/src/libCom/osi/os/RTEMS/osdVME.h +++ /dev/null @@ -1,22 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * OS-dependent VME support - */ -#ifndef __i386__ -#ifndef __mc68000 -#ifndef __arm__ -#include -#endif -#endif -#endif - -void bcopyLongs(char *source, char *destination, int nlongs); diff --git a/src/libCom/osi/os/RTEMS/osiFileName.h b/src/libCom/osi/os/RTEMS/osiFileName.h deleted file mode 100644 index 8c9226898..000000000 --- a/src/libCom/osi/os/RTEMS/osiFileName.h +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * RTEMS osiFileName.h - * Author: W. Eric Norum - * eric@cls.usask.ca - * (306) 966-6055 - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/RTEMS/osiUnistd.h b/src/libCom/osi/os/RTEMS/osiUnistd.h deleted file mode 100644 index c0a6e222d..000000000 --- a/src/libCom/osi/os/RTEMS/osiUnistd.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -/* - * Some systems fail to provide prototypes of these functions. - * Others provide different prototypes. - * There seems to be no way to handle this automatically, so - * if you get compile errors, just make the appropriate changes here. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -int putenv (char *); -char *strdup (const char *); -char *strtok_r(char*, const char*, char**); - -int snprintf(char *str, size_t size, const char *format, ...); -#include -int vsnprintf(char *str, size_t size, const char *format, va_list ap); - - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/WIN32/epicsAtomicMS.h b/src/libCom/osi/os/WIN32/epicsAtomicMS.h deleted file mode 100644 index 14d2c9bac..000000000 --- a/src/libCom/osi/os/WIN32/epicsAtomicMS.h +++ /dev/null @@ -1,222 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicMS_h -#define epicsAtomicMS_h - -#include "epicsAssert.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_INCR_INTT -#define EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) ); - MS_LONG * const pTarg = ( MS_LONG * ) pTarget; - return MS_InterlockedIncrement ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_INTT -#define EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) ); - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return MS_InterlockedDecrement ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_INTT -#define EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) ); - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - /* we dont use InterlockedAdd because only latest windows is supported */ - return delta + ( int ) MS_InterlockedExchangeAdd ( pTarg, - ( MS_LONG ) delta ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_INTT -#define EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ) -{ - STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) ); - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return (int) MS_InterlockedCompareExchange ( pTarg, - (MS_LONG) newVal, (MS_LONG) oldVal ); -} -#endif - -#if ! defined ( MS_ATOMIC_64 ) - -/* - * necessary for next three functions - * - * looking at the MS documentation it appears that they will - * keep type long the same size as an int on 64 bit builds - */ -STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( size_t ) ); - -#ifndef EPICS_ATOMIC_INCR_SIZET -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) pTarget; - return MS_InterlockedIncrement ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return MS_InterlockedDecrement ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, - size_t delta ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - /* we dont use InterlockedAdd because only latest windows is supported */ - return delta + ( size_t ) MS_InterlockedExchangeAdd ( pTarg, - ( MS_LONG ) delta ); -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - MS_LONG ldelta = (MS_LONG) delta; - /* we dont use InterlockedAdd because only latest windows is supported */ - return ( ( size_t ) MS_InterlockedExchangeAdd ( pTarg, -ldelta ) ) - delta; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( - size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return (size_t) MS_InterlockedCompareExchange ( pTarg, - (MS_LONG) newVal, (MS_LONG) oldVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal ) -{ - MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget ); - return (EpicsAtomicPtrT) MS_InterlockedCompareExchange ( pTarg, - (MS_LONG) newVal, (MS_LONG) oldVal ); -} -#endif - -#else /* ! MS_ATOMIC_64 */ - -/* - * necessary for next three functions - */ -STATIC_ASSERT ( sizeof ( MS_LONGLONG ) == sizeof ( size_t ) ); - -#ifndef EPICS_ATOMIC_INCR_SIZET -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) pTarget; - return ( size_t ) MS_InterlockedIncrement64 ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - return ( size_t ) MS_InterlockedDecrement64 ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - /* we dont use InterlockedAdd64 because only latest windows is supported */ - return delta + ( size_t ) MS_InterlockedExchangeAdd64 ( pTarg, - ( MS_LONGLONG ) delta ); -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - MS_LONGLONG ldelta = (MS_LONGLONG) delta; - /* we dont use InterlockedAdd64 because only latest windows is supported */ - return (( size_t ) MS_InterlockedExchangeAdd64 ( pTarg, -ldelta )) - delta; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - return (size_t) MS_InterlockedCompareExchange64 ( pTarg, - (MS_LONGLONG) newVal, - (MS_LONGLONG) oldVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal ) -{ - MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget ); - return (EpicsAtomicPtrT) MS_InterlockedCompareExchange64 ( pTarg, - (MS_LONGLONG) newVal, (MS_LONGLONG) oldVal ); -} -#endif - -#endif /* ! MS_ATOMIC_64 */ - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#endif /* ifdef epicsAtomicMS_h */ - diff --git a/src/libCom/osi/os/WIN32/epicsAtomicOSD.h b/src/libCom/osi/os/WIN32/epicsAtomicOSD.h deleted file mode 100644 index 2170fceff..000000000 --- a/src/libCom/osi/os/WIN32/epicsAtomicOSD.h +++ /dev/null @@ -1,67 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicOSD_h -#define epicsAtomicOSD_h - -#define EPICS_ATOMIC_OS_NAME "WIN32" - -#ifdef VC_EXTRALEAN -# define VC_EXTRALEAN_DETECTED_epicsAtomicOSD_h -#else -# define VC_EXTRALEAN -#endif - -#ifdef STRICT -# define STRICT_DETECTED_epicsAtomicOSD_h -#else -# define STRICT -#endif - -#include "windows.h" - -#ifndef VC_EXTRALEAN_DETECTED_epicsAtomicOSD_h -# undef VC_EXTRALEAN -#endif - -#ifndef STRICT_DETECTED_epicsAtomicOSD_h -# undef STRICT -#endif - -#if defined ( _WIN64 ) -# define MS_ATOMIC_64 -#endif - -#define MS_LONG LONG -#define MS_InterlockedExchange InterlockedExchange -#define MS_InterlockedCompareExchange InterlockedCompareExchange -#define MS_InterlockedIncrement InterlockedIncrement -#define MS_InterlockedDecrement InterlockedDecrement -#define MS_InterlockedExchange InterlockedExchange -#define MS_InterlockedExchangeAdd InterlockedExchangeAdd -#if defined ( MS_ATOMIC_64 ) -# define MS_LONGLONG LONGLONG -# define MS_InterlockedIncrement64 InterlockedIncrement64 -# define MS_InterlockedDecrement64 InterlockedDecrement64 -# define MS_InterlockedExchange64 InterlockedExchange64 -# define MS_InterlockedExchangeAdd64 InterlockedExchangeAdd64 -# define MS_InterlockedCompareExchange64 InterlockedCompareExchange64 -#endif - -#include "epicsAtomicMS.h" -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/WIN32/epicsGetopt.c b/src/libCom/osi/os/WIN32/epicsGetopt.c deleted file mode 100644 index 1ea064ea2..000000000 --- a/src/libCom/osi/os/WIN32/epicsGetopt.c +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef _MINGW - -/* - * Copyright (c) 1987, 1993, 1994 - * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include - -#define _getprogname() nargv[0] - -epicsShareDef -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt; /* character checked for validity */ -int optreset; /* reset getopt */ - -epicsShareDef -char *optarg; /* argument associated with option */ - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int getopt(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; -{ - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return (-1); - } - if (place[1] && *++place == '-') { /* found "--" */ - ++optind; - place = EMSG; - return (-1); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, optopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means -1. - */ - if (optopt == (int)'-') - return (-1); - if (!*place) - ++optind; - if (opterr && *ostr != ':' && optopt != BADCH) - (void)fprintf(stderr, "%s: illegal option -- %c\n", - _getprogname(), optopt); - return (BADCH); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } - else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (opterr) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - _getprogname(), optopt); - return (BADCH); - } - else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return (optopt); /* dump back option letter */ -} - -#endif /* !_MINGW */ diff --git a/src/libCom/osi/os/WIN32/epicsGetopt.h b/src/libCom/osi/os/WIN32/epicsGetopt.h deleted file mode 100644 index f92041085..000000000 --- a/src/libCom/osi/os/WIN32/epicsGetopt.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef _EPICS_GETOPT_H -#define _EPICS_GETOPT_H - -#ifdef _MINGW - -#include - -#else /* _MINGW */ - -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareFunc int getopt(int argc, char * const argv[], const char *optstring); - -epicsShareExtern char *optarg; - -epicsShareExtern int optind, opterr, optopt; - -#ifdef __cplusplus -} -#endif - -#endif /* _MINGW */ - -#endif /* _EPICS_GETOPT_H */ diff --git a/src/libCom/osi/os/WIN32/epicsMath.h b/src/libCom/osi/os/WIN32/epicsMath.h deleted file mode 100644 index 33eb9dddd..000000000 --- a/src/libCom/osi/os/WIN32/epicsMath.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include -#include - -#ifndef finite -#define finite(D) _finite(D) -#endif - -#ifndef isnan -#define isnan(D) _isnan(D) -#endif - -#ifndef isinf -#define isinf(D) ( !_finite(D) && !_isnan(D) ) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp b/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp deleted file mode 100644 index 3db87ac84..000000000 --- a/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "epicsStdio.h" - -/* - * epicsSocketConvertErrorToString () - */ -void epicsSocketConvertErrorToString ( - char * pBuf, unsigned bufSize, int theSockError ) -{ - if ( bufSize ) { - /* - * this does not work on systems prior to W2K - */ - DWORD success = FormatMessage ( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, - NULL, theSockError, - MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ), /* Default language */ - pBuf, bufSize, NULL ); - if ( ! success ) { - int status = epicsSnprintf ( - pBuf, bufSize, "WINSOCK Error %d", theSockError ); - if ( status <= 0 ) { - strncpy ( pBuf, "WINSOCK Error", bufSize ); - pBuf [bufSize - 0] = '\0'; - } - } - } -} - -/* - * epicsSocketConvertErrnoToString () - */ -void epicsSocketConvertErrnoToString ( - char * pBuf, unsigned bufSize ) -{ - epicsSocketConvertErrorToString ( pBuf, bufSize, SOCKERRNO ); -} diff --git a/src/libCom/osi/os/WIN32/epicsTempFile.cpp b/src/libCom/osi/os/WIN32/epicsTempFile.cpp deleted file mode 100644 index 11b835134..000000000 --- a/src/libCom/osi/os/WIN32/epicsTempFile.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsTempFile.h" - -// -// epicsTempName -// -// allow the teporary file directory to be set with the -// TMP environment varianble -// -extern "C" -epicsShareFunc void epicsShareAPI epicsTempName ( - char * pNameBuf, size_t nameBufLength ) -{ - if ( nameBufLength ) { - pNameBuf[0] = '\0'; - char * pName = _tempnam ( "c:\\tmp", "epics" ); - if ( pName ) { - if ( nameBufLength > strlen ( pName ) ) { - strncpy ( pNameBuf, pName, nameBufLength ); - } - free ( pName ); - } - } -} - -// -// epicsTmpFile -// -// allow the teporary file directory to be set with the -// TMP environment varianble -// -extern "C" -epicsShareFunc FILE * epicsShareAPI epicsTempFile () -{ - char * pName = _tempnam ( "c:\\tmp", "epics" ); - if( ! pName ) { - return 0; - } - // We use open followed by fdopen so that the _O_EXCL - // flag can be used. This causes detection of a race - // condition where two programs end up receiving the - // same temporary file name. - // - // _O_CREAT create if non-existant - // _O_EXCL file must not exist - // _O_RDWR read and write the file - // _O_TEMPORARY delete file on close - // _O_BINARY no translation - // _O_SHORT_LIVED avoid flush to disk - // - const int openFlag = _O_CREAT | _O_EXCL | _O_RDWR | - _O_SHORT_LIVED | _O_BINARY | _O_TEMPORARY; - int fd = open ( pName, openFlag, _S_IWRITE ); - FILE * pNewFile = 0; - if ( fd >=0 ) { - pNewFile = _fdopen ( fd, "w+b" ); - } - else { - printf ( - "Temporary file \"%s\" open failed because " - "\"%s\"\n", pName, strerror ( errno ) ); - } - free ( pName ); - return pNewFile; -} - diff --git a/src/libCom/osi/os/WIN32/forceBadAllocException.cpp b/src/libCom/osi/os/WIN32/forceBadAllocException.cpp deleted file mode 100644 index 985ec988e..000000000 --- a/src/libCom/osi/os/WIN32/forceBadAllocException.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// On older version of ms visual c++ operator new -// does not throw a bad_alloc exception -// when it fails. It simply returns a null pointer. -// This behavior is not in conformance with the -// ANSI / ISO C++. -// -#if _MSC_VER > 1000 && _MSC_VER < 1400 - -#include -#include - -// instruct loader to call this gllobal object -// constructor before user global object constructors -#pragma warning (disable: 4073) -#pragma init_seg(lib) -#pragma warning (default: 4073) - -static int my_new_handler (size_t size) -{ - throw std::bad_alloc(); - return 0; -} - -class my_new_handler_obj -{ -public: - my_new_handler_obj() - { - //_old_new_mode = _set_new_mode(1); // cause malloc to throw like new - _old_new_handler = _set_new_handler(my_new_handler); - } - - ~my_new_handler_obj() - { - _set_new_handler(_old_new_handler); - //_set_new_mode(_old_new_mode); - } - -private: - _PNH _old_new_handler; - //int _old_new_mode; -}; - -static my_new_handler_obj _g_new_handler_obj; - -#endif diff --git a/src/libCom/osi/os/WIN32/osdBackTrace.cpp b/src/libCom/osi/os/WIN32/osdBackTrace.cpp deleted file mode 100644 index 8f5896a37..000000000 --- a/src/libCom/osi/os/WIN32/osdBackTrace.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2014 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" - -int epicsBackTrace(void **buf, int buf_sz) -{ -#ifdef CaptureStackBackTrace - /* Docs say that (for some windows versions) the sum of - * skipped + captured frames must be less than 63 - */ - if ( buf_sz >= 63 ) - buf_sz = 62; - return CaptureStackBackTrace(0, buf_sz, buf, 0); -#else - /* Older versions of MinGW */ - return -1; -#endif -} diff --git a/src/libCom/osi/os/WIN32/osdEvent.c b/src/libCom/osi/os/WIN32/osdEvent.c deleted file mode 100644 index 314138b27..000000000 --- a/src/libCom/osi/os/WIN32/osdEvent.c +++ /dev/null @@ -1,145 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEvent.c */ -/* - * WIN32 version - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - */ - -#include - -#define VC_EXTRALEAN -#define STRICT -#include - -#define epicsExportSharedSymbols -#include "shareLib.h" -#include "epicsEvent.h" - -typedef struct epicsEventOSD { - HANDLE handle; -} epicsEventOSD; - -/* - * epicsEventCreate () - */ -epicsShareFunc epicsEventId epicsEventCreate ( - epicsEventInitialState initialState ) -{ - epicsEventOSD *pSem; - - pSem = malloc ( sizeof ( *pSem ) ); - if ( pSem ) { - pSem->handle = CreateEvent ( NULL, FALSE, initialState?TRUE:FALSE, NULL ); - if ( pSem->handle == 0 ) { - free ( pSem ); - pSem = 0; - } - } - - return pSem; -} - -/* - * epicsEventDestroy () - */ -epicsShareFunc void epicsEventDestroy ( epicsEventId pSem ) -{ - CloseHandle ( pSem->handle ); - free ( pSem ); -} - -/* - * epicsEventTrigger () - */ -epicsShareFunc epicsEventStatus epicsEventTrigger ( epicsEventId pSem ) -{ - BOOL status; - status = SetEvent ( pSem->handle ); - return status ? epicsEventOK : epicsEventError; -} - -/* - * epicsEventWait () - */ -epicsShareFunc epicsEventStatus epicsEventWait ( epicsEventId pSem ) -{ - DWORD status; - status = WaitForSingleObject (pSem->handle, INFINITE); - if ( status == WAIT_OBJECT_0 ) { - return epicsEventOK; - } - else { - return epicsEventError; - } -} - -/* - * epicsEventWaitWithTimeout () - */ -epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout ( - epicsEventId pSem, double timeOut ) -{ - static const unsigned mSecPerSec = 1000; - DWORD status; - DWORD tmo; - - if ( timeOut <= 0.0 ) { - tmo = 0u; - } - else if ( timeOut >= INFINITE / mSecPerSec ) { - tmo = INFINITE - 1; - } - else { - tmo = ( DWORD ) ( ( timeOut * mSecPerSec ) + 0.5 ); - if ( tmo == 0 ) { - tmo = 1; - } - } - status = WaitForSingleObject ( pSem->handle, tmo ); - if ( status == WAIT_OBJECT_0 ) { - return epicsEventOK; - } - else if ( status == WAIT_TIMEOUT ) { - return epicsEventWaitTimeout; - } - else { - return epicsEventError; - } -} - -/* - * epicsEventTryWait () - */ -epicsShareFunc epicsEventStatus epicsEventTryWait ( epicsEventId pSem ) -{ - DWORD status; - - status = WaitForSingleObject ( pSem->handle, 0 ); - if ( status == WAIT_OBJECT_0 ) { - return epicsEventOK; - } - else if ( status == WAIT_TIMEOUT ) { - return epicsEventWaitTimeout; - } - else { - return epicsEventError; - } -} - -/* - * epicsEventShow () - */ -epicsShareFunc void epicsEventShow ( epicsEventId id, unsigned level ) -{ -} diff --git a/src/libCom/osi/os/WIN32/osdEvent.h b/src/libCom/osi/os/WIN32/osdEvent.h deleted file mode 100644 index f57f2cc49..000000000 --- a/src/libCom/osi/os/WIN32/osdEvent.h +++ /dev/null @@ -1,19 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEvent.c */ -/* - * WIN32 version - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -/* osdEvent.h not needed */ diff --git a/src/libCom/osi/os/WIN32/osdFindSymbol.c b/src/libCom/osi/os/WIN32/osdFindSymbol.c deleted file mode 100644 index 6de3c428e..000000000 --- a/src/libCom/osi/os/WIN32/osdFindSymbol.c +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 Dirk Zimoch, PSI -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/WIN32/osdFindSymbol.c */ - - -#include - -#define epicsExportSharedSymbols -#include "epicsFindSymbol.h" - -static int epicsLoadErrorCode = 0; - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - HMODULE lib; - - epicsLoadErrorCode = 0; - lib = LoadLibrary(name); - if (lib == NULL) - { - epicsLoadErrorCode = GetLastError(); - } - return lib; -} - -epicsShareFunc const char *epicsLoadError(void) -{ - static char buffer[100]; - - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - epicsLoadErrorCode, - 0, - buffer, - sizeof(buffer)-1, NULL ); - return buffer; -} - -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name) -{ - return GetProcAddress(0, name); -} diff --git a/src/libCom/osi/os/WIN32/osdMutex.c b/src/libCom/osi/os/WIN32/osdMutex.c deleted file mode 100644 index 63a51efd5..000000000 --- a/src/libCom/osi/os/WIN32/osdMutex.c +++ /dev/null @@ -1,179 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdMutex.c */ -/* - * WIN32 version - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - * - */ - -#include -#include - -#define VC_EXTRALEAN -#define STRICT -/* - * Defining this allows the *much* faster critical - * section mutex primitive to be used. Unfortunately, - * using certain of these functions drops support for W95\W98\WME - * unless we specify "delay loading" when we link with the - * DLL so that DLL entry points are not resolved until they - * are used. The code does have run time switches so - * that the more advanced calls are not called unless - * they are available in the windows OS, but this feature - * isnt going to be very useful unless we specify "delay - * loading" when we link with the DLL. - * - * It appears that the only entry point used here that causes - * portability problems with W95\W98\WME is TryEnterCriticalSection. - */ -#ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -#endif -#include - -#define epicsExportSharedSymbols -#include "shareLib.h" -#include "epicsMutex.h" -#include "epicsAssert.h" -#include "epicsStdio.h" - -typedef struct epicsMutexOSD { - union { - HANDLE mutex; - CRITICAL_SECTION criticalSection; - } os; -} epicsMutexOSD; - -static BOOL thisIsNT = FALSE; -static LONG weHaveInitialized = 0; - -/* - * epicsMutexCreate () - */ -epicsMutexOSD * epicsMutexOsdCreate ( void ) -{ - epicsMutexOSD * pSem; - - if ( ! weHaveInitialized ) { - BOOL status; - OSVERSIONINFO osInfo; - osInfo.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO ); - status = GetVersionEx ( & osInfo ); - thisIsNT = status && ( osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ); - weHaveInitialized = 1; - } - - pSem = malloc ( sizeof (*pSem) ); - if ( pSem ) { - if ( thisIsNT ) { - InitializeCriticalSection ( &pSem->os.criticalSection ); - } - else { - pSem->os.mutex = CreateMutex ( NULL, FALSE, NULL ); - if ( pSem->os.mutex == 0 ) { - free ( pSem ); - pSem = 0; - } - } - } - return pSem; -} - -/* - * epicsMutexOsdDestroy () - */ -void epicsMutexOsdDestroy ( epicsMutexOSD * pSem ) -{ - if ( thisIsNT ) { - DeleteCriticalSection ( &pSem->os.criticalSection ); - } - else { - CloseHandle ( pSem->os.mutex ); - } - free ( pSem ); -} - -/* - * epicsMutexOsdUnlock () - */ -void epicsMutexOsdUnlock ( epicsMutexOSD * pSem ) -{ - if ( thisIsNT ) { - LeaveCriticalSection ( &pSem->os.criticalSection ); - } - else { - BOOL success = ReleaseMutex ( pSem->os.mutex ); - assert ( success ); - } -} - -/* - * epicsMutexOsdLock () - */ -epicsMutexLockStatus epicsMutexOsdLock ( epicsMutexOSD * pSem ) -{ - if ( thisIsNT ) { - EnterCriticalSection ( &pSem->os.criticalSection ); - } - else { - DWORD status = WaitForSingleObject ( pSem->os.mutex, INFINITE ); - if ( status != WAIT_OBJECT_0 ) { - return epicsMutexLockError; - } - } - return epicsMutexLockOK; -} - -/* - * epicsMutexOsdTryLock () - */ -epicsMutexLockStatus epicsMutexOsdTryLock ( epicsMutexOSD * pSem ) -{ - if ( thisIsNT ) { - if ( TryEnterCriticalSection ( &pSem->os.criticalSection ) ) { - return epicsMutexLockOK; - } - else { - return epicsMutexLockTimeout; - } - } - else { - DWORD status = WaitForSingleObject ( pSem->os.mutex, 0 ); - if ( status != WAIT_OBJECT_0 ) { - if (status == WAIT_TIMEOUT) { - return epicsMutexLockTimeout; - } - else { - return epicsMutexLockError; - } - } - } - return epicsMutexLockOK; -} - -/* - * epicsMutexOsdShow () - */ -void epicsMutexOsdShow ( epicsMutexOSD * pSem, unsigned level ) -{ - if ( thisIsNT ) { - printf ("epicsMutex: win32 critical section at %p\n", - (void * ) & pSem->os.criticalSection ); - } - else { - printf ( "epicsMutex: win32 mutex at %p\n", - ( void * ) pSem->os.mutex ); - } -} - diff --git a/src/libCom/osi/os/WIN32/osdMutex.h b/src/libCom/osi/os/WIN32/osdMutex.h deleted file mode 100644 index d8f3f78bd..000000000 --- a/src/libCom/osi/os/WIN32/osdMutex.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* osdMutex.h */ -/* - * WIN32 version - * - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef osdMutexh -#define osdMutexh - -#endif /* osdMutexh */ diff --git a/src/libCom/osi/os/WIN32/osdNetIntf.c b/src/libCom/osi/os/WIN32/osdNetIntf.c deleted file mode 100644 index db445d494..000000000 --- a/src/libCom/osi/os/WIN32/osdNetIntf.c +++ /dev/null @@ -1,253 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * WIN32 specific initialisation for bsd sockets, - * based on Chris Timossi's base/src/ca/windows_depend.c, - * and also further additions by Kay Kasemir when this was in - * dllmain.cc - * - * 7-1-97 -joh- - * - */ - -/* - * ANSI C - */ -#include -#include - -/* - * WIN32 specific - */ -#define VC_EXTRALEAN -#define STRICT -#include -#include - -/* - * EPICS - */ -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" -#include "epicsThread.h" -#include "epicsVersion.h" - -static osiSockAddr osiLocalAddrResult; -static epicsThreadOnceId osiLocalAddrId = EPICS_THREAD_ONCE_INIT; - -/* - * osiLocalAddr () - */ -static void osiLocalAddrOnce ( void *raw ) -{ - SOCKET *psocket = raw; - osiSockAddr addr; - int status; - INTERFACE_INFO *pIfinfo; - INTERFACE_INFO *pIfinfoList = NULL; - unsigned nelem; - DWORD numifs; - DWORD cbBytesReturned; - - memset ( (void *) &addr, '\0', sizeof ( addr ) ); - addr.sa.sa_family = AF_UNSPEC; - - /* only valid for winsock 2 and above */ - if ( wsaMajorVersion() < 2 ) { - goto fail; - } - - nelem = 100; - pIfinfoList = (INTERFACE_INFO *) calloc ( nelem, sizeof (INTERFACE_INFO) ); - if (!pIfinfoList) { - errlogPrintf ("calloc failed\n"); - goto fail; - } - - status = WSAIoctl (*psocket, SIO_GET_INTERFACE_LIST, NULL, 0, - (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO), - &cbBytesReturned, NULL, NULL); - - if (status != 0 || cbBytesReturned == 0) { - errlogPrintf ("WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError()); - goto fail; - } - - numifs = cbBytesReturned / sizeof(INTERFACE_INFO); - for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){ - - /* - * dont use interfaces that have been disabled - */ - if (!(pIfinfo->iiFlags & IFF_UP)) { - continue; - } - - /* - * dont use the loop back interface - */ - if (pIfinfo->iiFlags & IFF_LOOPBACK) { - continue; - } - - addr.sa = pIfinfo->iiAddress.Address; - - /* Work around MS Winsock2 bugs */ - if (addr.sa.sa_family == 0) { - addr.sa.sa_family = AF_INET; - } - - osiLocalAddrResult = addr; - free ( pIfinfoList ); - return; - } - - errlogPrintf ( - "osiLocalAddr(): only loopback found\n"); -fail: - /* fallback to loopback */ - memset ( (void *) &addr, '\0', sizeof ( addr ) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - osiLocalAddrResult = addr; - - free ( pIfinfoList ); -} - -epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket) -{ - epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, (void*)&socket); - return osiLocalAddrResult; -} - -/* - * osiSockDiscoverBroadcastAddresses () - */ -epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses - (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr) -{ - int status; - INTERFACE_INFO *pIfinfo; - INTERFACE_INFO *pIfinfoList; - unsigned nelem; - int numifs; - DWORD cbBytesReturned; - osiSockAddrNode *pNewNode; - - if ( pMatchAddr->sa.sa_family == AF_INET ) { - if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) { - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); - if ( pNewNode == NULL ) { - return; - } - pNewNode->addr.ia.sin_family = AF_INET; - pNewNode->addr.ia.sin_port = htons ( 0 ); - pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - ellAdd ( pList, &pNewNode->node ); - return; - } - } - - /* only valid for winsock 2 and above */ - if (wsaMajorVersion() < 2 ) { - fprintf(stderr, "Need to set EPICS_CA_AUTO_ADDR_LIST=NO for winsock 1\n"); - return; - } - - nelem = 100; - pIfinfoList = (INTERFACE_INFO *) calloc(nelem, sizeof(INTERFACE_INFO)); - if(!pIfinfoList){ - return; - } - - status = WSAIoctl (socket, SIO_GET_INTERFACE_LIST, - NULL, 0, - (LPVOID)pIfinfoList, nelem*sizeof(INTERFACE_INFO), - &cbBytesReturned, NULL, NULL); - - if (status != 0 || cbBytesReturned == 0) { - fprintf(stderr, "WSAIoctl SIO_GET_INTERFACE_LIST failed %d\n",WSAGetLastError()); - free(pIfinfoList); - return; - } - - numifs = cbBytesReturned/sizeof(INTERFACE_INFO); - for (pIfinfo = pIfinfoList; pIfinfo < (pIfinfoList+numifs); pIfinfo++){ - - /* - * dont bother with interfaces that have been disabled - */ - if (!(pIfinfo->iiFlags & IFF_UP)) { - continue; - } - - if (pIfinfo->iiFlags & IFF_LOOPBACK) { - continue; - } - - /* - * work around WS2 bug - */ - if (pIfinfo->iiAddress.Address.sa_family != AF_INET) { - if (pIfinfo->iiAddress.Address.sa_family == 0) { - pIfinfo->iiAddress.Address.sa_family = AF_INET; - } - } - - /* - * if it isnt a wildcarded interface then look for - * an exact match - */ - if (pMatchAddr->sa.sa_family != AF_UNSPEC) { - if (pIfinfo->iiAddress.Address.sa_family != pMatchAddr->sa.sa_family) { - continue; - } - if (pIfinfo->iiAddress.Address.sa_family != AF_INET) { - continue; - } - if (pMatchAddr->sa.sa_family != AF_INET) { - continue; - } - if (pMatchAddr->ia.sin_addr.s_addr != htonl(INADDR_ANY)) { - if (pIfinfo->iiAddress.AddressIn.sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr) { - continue; - } - } - } - - pNewNode = (osiSockAddrNode *) calloc (1, sizeof(*pNewNode)); - if (pNewNode==NULL) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n"); - return; - } - - if (pIfinfo->iiAddress.Address.sa_family == AF_INET && - pIfinfo->iiFlags & IFF_BROADCAST) { - const unsigned mask = pIfinfo->iiNetmask.AddressIn.sin_addr.s_addr; - const unsigned bcast = pIfinfo->iiBroadcastAddress.AddressIn.sin_addr.s_addr; - const unsigned addr = pIfinfo->iiAddress.AddressIn.sin_addr.s_addr; - unsigned result = (addr & mask) | (bcast &~mask); - pNewNode->addr.ia.sin_family = AF_INET; - pNewNode->addr.ia.sin_addr.s_addr = result; - pNewNode->addr.ia.sin_port = htons ( 0 ); - } - else { - pNewNode->addr.sa = pIfinfo->iiBroadcastAddress.Address; - } - - /* - * LOCK applied externally - */ - ellAdd (pList, &pNewNode->node); - } - - free (pIfinfoList); -} diff --git a/src/libCom/osi/os/WIN32/osdPoolStatus.c b/src/libCom/osi/os/WIN32/osdPoolStatus.c deleted file mode 100644 index bb764b2ad..000000000 --- a/src/libCom/osi/os/WIN32/osdPoolStatus.c +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "osiPoolStatus.h" - -/* - * osiSufficentSpaceInPool () - * - * @@@@@ not implemented @@@@@ - * - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) -{ - return 1; -} diff --git a/src/libCom/osi/os/WIN32/osdPoolStatus.h b/src/libCom/osi/os/WIN32/osdPoolStatus.h deleted file mode 100644 index 178434b11..000000000 --- a/src/libCom/osi/os/WIN32/osdPoolStatus.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifdef osdPoolStatush -#define osdPoolStatush - -#endif /* osdPoolStatush */ diff --git a/src/libCom/osi/os/WIN32/osdProcess.c b/src/libCom/osi/os/WIN32/osdProcess.c deleted file mode 100644 index 6e69c0485..000000000 --- a/src/libCom/osi/os/WIN32/osdProcess.c +++ /dev/null @@ -1,137 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Operating System Dependent Implementation of osiProcess.h - * - * Author: Jeff Hill - * - */ - -#ifndef _WIN32 -#error This source is specific to WIN32 -#endif - -#include - -#define STRICT -#include - -#define epicsExportSharedSymbols -#include "osiProcess.h" -#include "errlog.h" - -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSizeIn) -{ - DWORD bufsize; - - if ( bufSizeIn > 0xffffffff ) { - return osiGetUserNameFail; - } - - bufsize = (DWORD) bufSizeIn; - - if ( ! GetUserName (pBuf, &bufsize) ) { - return osiGetUserNameFail; - } - - if ( *pBuf == '\0' ) { - return osiGetUserNameFail; - } - - return osiGetUserNameSuccess; -} - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - ( const char *pProcessName, const char *pBaseExecutableName ) -{ - BOOL status; - STARTUPINFO startupInfo; - PROCESS_INFORMATION processInfo; - - GetStartupInfo ( &startupInfo ); - startupInfo.lpReserved = NULL; - startupInfo.lpTitle = (char *) pProcessName; - startupInfo.dwFlags = STARTF_USESHOWWINDOW; - startupInfo.wShowWindow = SW_SHOWMINNOACTIVE; - - status = CreateProcess ( - NULL, /* pointer to name of executable module (not required if command line is specified) */ - (char *) pBaseExecutableName, /* pointer to command line string */ - NULL, /* pointer to process security attributes */ - NULL, /* pointer to thread security attributes */ - FALSE, /* handle inheritance flag */ - CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, /* creation flags */ - NULL, /* pointer to new environment block (defaults to caller's environement) */ - NULL, /* pointer to current directory name (defaults to caller's current directory) */ - &startupInfo, /* pointer to STARTUPINFO */ - &processInfo /* pointer to PROCESS_INFORMATION */ - ); - if ( status == 0 ) { - DWORD W32status; - LPVOID errStrMsgBuf; - LPVOID complteMsgBuf; - - W32status = FormatMessage ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError (), - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &errStrMsgBuf, - 0, - NULL - ); - - if ( W32status ) { - char *pFmtArgs[6]; - pFmtArgs[0] = "Failed to start executable -"; - pFmtArgs[1] = (char *) pBaseExecutableName; - pFmtArgs[2] = errStrMsgBuf; - pFmtArgs[3] = "Changes may be required in your \"path\" environment variable."; - pFmtArgs[4] = "PATH = "; - pFmtArgs[5] = getenv ("path"); - if ( pFmtArgs[5] == NULL ) { - pFmtArgs[5] = ""; - } - - W32status = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | - FORMAT_MESSAGE_ARGUMENT_ARRAY | 80, - "%1 \"%2\". %3 %4 %5 \"%6\"", - 0, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &complteMsgBuf, - 0, - pFmtArgs - ); - if (W32status) { - /* Display the string. */ - MessageBox (NULL, complteMsgBuf, "Configuration Problem", - MB_OK | MB_ICONINFORMATION); - LocalFree (complteMsgBuf); - } - else { - /* Display the string. */ - MessageBox (NULL, errStrMsgBuf, "Failed to start executable", - MB_OK | MB_ICONINFORMATION); - } - - /* Free the buffer. */ - LocalFree (errStrMsgBuf); - } - else { - errlogPrintf ("!!WARNING!!\n"); - errlogPrintf ("Unable to locate executable \"%s\".\n", pBaseExecutableName); - errlogPrintf ("You may need to modify your \"path\" environment variable.\n"); - } - return osiSpawnDetachedProcessFail; - } - - return osiSpawnDetachedProcessSuccess; -} diff --git a/src/libCom/osi/os/WIN32/osdSignal.cpp b/src/libCom/osi/os/WIN32/osdSignal.cpp deleted file mode 100644 index 5f799273a..000000000 --- a/src/libCom/osi/os/WIN32/osdSignal.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -/* - * NOOP - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * /* threadid */ ) {} - diff --git a/src/libCom/osi/os/WIN32/osdSock.c b/src/libCom/osi/os/WIN32/osdSock.c deleted file mode 100644 index b8c8363fb..000000000 --- a/src/libCom/osi/os/WIN32/osdSock.c +++ /dev/null @@ -1,190 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * WIN32 specific initialisation for bsd sockets, - * based on Chris Timossi's base/src/ca/windows_depend.c, - * and also further additions by Kay Kasemir when this was in - * dllmain.cc - * - * 7-1-97 -joh- - * - */ - -/* - * ANSI C - */ -#include -#include - -/* - * WIN32 specific - */ -#define VC_EXTRALEAN -#define STRICT -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" -#include "epicsVersion.h" - -static unsigned nAttached = 0; -static WSADATA WsaData; /* version of winsock */ - -epicsShareFunc unsigned epicsShareAPI wsaMajorVersion () -{ - return (unsigned) LOBYTE( WsaData.wVersion ); -} - -/* - * osiSockAttach() - */ -epicsShareFunc int epicsShareAPI osiSockAttach() -{ - int status; - - if (nAttached) { - nAttached++; - return TRUE; - } - -#if _DEBUG - /* for gui applications, setup console for error messages */ - if (AllocConsole()) - { - char title[256]; - DWORD titleLength = GetConsoleTitle(title, sizeof(title)); - if (titleLength) { - titleLength = strlen (title); - strncat (title, " " EPICS_VERSION_STRING, sizeof(title)); - } - else { - strncpy(title, EPICS_VERSION_STRING, sizeof(title)); - } - title[sizeof(title)-1]= '\0'; - SetConsoleTitle(title); - freopen( "CONOUT$", "a", stderr ); - } -#endif - - /* - * attach to win sock - */ - status = WSAStartup(MAKEWORD(/*major*/2,/*minor*/2), &WsaData); - if (status != 0) { - fprintf(stderr, - "Unable to attach to windows sockets version 2. error=%d\n", status); - fprintf(stderr, - "A Windows Sockets II update for windows 95 is available at\n"); - fprintf(stderr, - "http://www.microsoft.com/windows95/info/ws2.htm"); - return FALSE; - } - -# if defined ( _DEBUG ) && 0 - fprintf(stderr, "EPICS attached to winsock version %s\n", WsaData.szDescription); -# endif - - nAttached = 1u; - - return TRUE; -} - -/* - * osiSockRelease() - */ -epicsShareFunc void epicsShareAPI osiSockRelease() -{ - if (nAttached) { - if (--nAttached==0u) { - WSACleanup(); -# if defined ( _DEBUG ) && 0 - fprintf(stderr, "EPICS released winsock version %s\n", WsaData.szDescription); -# endif - memset (&WsaData, '\0', sizeof(WsaData)); - } - } -} - -epicsShareFunc SOCKET epicsShareAPI epicsSocketCreate ( - int domain, int type, int protocol ) -{ - return socket ( domain, type, protocol ); -} - -epicsShareFunc int epicsShareAPI epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) -{ - return accept ( sock, pAddr, addrlen ); -} - -epicsShareFunc void epicsShareAPI epicsSocketDestroy ( SOCKET s ) -{ - int status = closesocket ( s ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketDestroy: failed to " - "close a socket because \"%s\"\n", buf ); - } -} - -/* - * ipAddrToHostName - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName - (const struct in_addr *pAddr, char *pBuf, unsigned bufSize) -{ - struct hostent *ent; - - if (bufSize<1) { - return 0; - } - - ent = gethostbyaddr((char *) pAddr, sizeof (*pAddr), AF_INET); - if (ent) { - strncpy (pBuf, ent->h_name, bufSize); - pBuf[bufSize-1] = '\0'; - return strlen (pBuf); - } - return 0; -} - -/* - * hostToIPAddr () - */ -epicsShareFunc int epicsShareAPI hostToIPAddr - (const char *pHostName, struct in_addr *pIPA) -{ - struct hostent *phe; - - phe = gethostbyname (pHostName); - if (phe && phe->h_addr_list[0]) { - if (phe->h_addrtype==AF_INET && phe->h_length<=sizeof(struct in_addr)) { - struct in_addr *pInAddrIn = (struct in_addr *) phe->h_addr_list[0]; - - *pIPA = *pInAddrIn; - - /* - * success - */ - return 0; - } - } - - /* - * return indicating an error - */ - return -1; -} - - diff --git a/src/libCom/osi/os/WIN32/osdSock.h b/src/libCom/osi/os/WIN32/osdSock.h deleted file mode 100644 index d92e18755..000000000 --- a/src/libCom/osi/os/WIN32/osdSock.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef osdSockH -#define osdSockH - -#include -#include - -/* - * winsock2.h changes the structure alignment to 4 if - * WIN32 isnt set which can be a source of confusion - */ -#ifndef WIN32 -# define WIN32 -#endif -#include -#include - -#define SOCKERRNO WSAGetLastError() - -#define socket_ioctl(A,B,C) ioctlsocket(A,B,C) -typedef u_long FAR osiSockIoctl_t; -typedef int osiSocklen_t; - -#ifndef SHUT_RD -# define SHUT_RD SD_RECEIVE -#endif - -#ifndef SHUT_WR -# define SHUT_WR SD_SEND -#endif - -#ifndef SHUT_RDWR -# define SHUT_RDWR SD_BOTH -#endif - -#define MAXHOSTNAMELEN 75 -#define IPPORT_USERRESERVED 5000U - -#define SOCK_EWOULDBLOCK WSAEWOULDBLOCK -#define SOCK_ENOBUFS WSAENOBUFS -#define SOCK_ECONNRESET WSAECONNRESET -#define SOCK_ETIMEDOUT WSAETIMEDOUT -#define SOCK_EACCES WSAEACCES -#define SOCK_EADDRINUSE WSAEADDRINUSE -#define SOCK_EADDRNOTAVAIL WSAEADDRNOTAVAIL -#define SOCK_ECONNREFUSED WSAECONNREFUSED -#define SOCK_ECONNABORTED WSAECONNABORTED -#define SOCK_EINPROGRESS WSAEINPROGRESS -#define SOCK_EISCONN WSAEISCONN -#define SOCK_EALREADY WSAEALREADY -#define SOCK_EINVAL WSAEINVAL -#define SOCK_EINTR WSAEINTR -#define SOCK_EPIPE EPIPE -#define SOCK_EMFILE WSAEMFILE -#define SOCK_SHUTDOWN WSAESHUTDOWN -#define SOCK_ENOTSOCK WSAENOTSOCK -#define SOCK_EBADF WSAENOTSOCK - -/* - * Under WIN32, FD_SETSIZE is the max. number of sockets, - * not the max. fd value that you use in select(). - * - * Therefore, it is difficult to detemine if any given - * fd can be used with FD_SET(), FD_CLR(), and FD_ISSET(). - */ -#define FD_IN_FDSET(FD) (1) - -epicsShareFunc unsigned epicsShareAPI wsaMajorVersion (); - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/WIN32/osdSockAddrReuse.cpp b/src/libCom/osi/os/WIN32/osdSockAddrReuse.cpp deleted file mode 100644 index d441d7511..000000000 --- a/src/libCom/osi/os/WIN32/osdSockAddrReuse.cpp +++ /dev/null @@ -1,44 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -/* - * Note: WINSOCK appears to assign a different functionality for - * SO_REUSEADDR compared to other OS. With WINSOCK SO_REUSEADDR indicates - * that simultaneously servers can bind to the same TCP port on the same host! - * Also, servers are always enabled to reuse a port immediately after - * they exit ( even if SO_REUSEADDR isnt set ). - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ -} - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} diff --git a/src/libCom/osi/os/WIN32/osdStdio.c b/src/libCom/osi/os/WIN32/osdStdio.c deleted file mode 100644 index 8a2d58ea9..000000000 --- a/src/libCom/osi/os/WIN32/osdStdio.c +++ /dev/null @@ -1,45 +0,0 @@ -/* osdStdio.c */ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#ifndef _MSC_VER -/* Older versions of MinGW omitted this prototype from stdio.h */ -_CRTIMP int __cdecl __MINGW_NOTHROW _vscprintf (const char*, va_list); -#endif - -#define epicsExportSharedSymbols -#include "epicsStdio.h" - -int epicsShareAPI epicsVsnprintf(char *str, size_t len, - const char *fmt, va_list ap) -{ - int retval = _vsnprintf(str, len, fmt, ap); - int needed = _vscprintf(fmt, ap); - - if ((int) len < needed + 1) { - str[len - 1] = 0; - return needed; - } - - return retval; -} - -int epicsShareAPI epicsSnprintf (char *str, size_t len, const char *fmt, ...) -{ - int rtn; - va_list pvar; - - va_start (pvar, fmt); - rtn = epicsVsnprintf (str, len, fmt, pvar); - va_end (pvar); - return (rtn); -} diff --git a/src/libCom/osi/os/WIN32/osdStrtod.h b/src/libCom/osi/os/WIN32/osdStrtod.h deleted file mode 100644 index 4edb444ee..000000000 --- a/src/libCom/osi/os/WIN32/osdStrtod.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header fragment is intended to be included as part of epicsString.h - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epicsStrtod() for systems with broken strtod() routine - */ -epicsShareFunc double epicsStrtod(const char *str, char **endp); - -/* - * Microsoft apparently added strto[u]ll() in VS2013 - * Older compilers have these equivalents though - */ - -#if !defined(_MINGW) && (_MSC_VER < 1800) -# define strtoll _strtoi64 -# define strtoull _strtoui64 -#endif - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/libCom/osi/os/WIN32/osdThread.c deleted file mode 100644 index 8cdb4a3f4..000000000 --- a/src/libCom/osi/os/WIN32/osdThread.c +++ /dev/null @@ -1,1125 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#include -#include -#include -#include - -#define VC_EXTRALEAN -#define STRICT -#ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x400 /* No support for W95 */ -#endif -#include -#include /* for _endthread() etc */ - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "shareLib.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsAssert.h" -#include "ellLib.h" -#include "epicsExit.h" - -epicsShareFunc void osdThreadHooksRun(epicsThreadId id); - -void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ); -static void threadCleanupWIN32 ( void ); - -typedef struct win32ThreadGlobal { - CRITICAL_SECTION mutex; - ELLLIST threadList; - DWORD tlsIndexThreadLibraryEPICS; -} win32ThreadGlobal; - -typedef struct epicsThreadOSD { - ELLNODE node; - HANDLE handle; - EPICSTHREADFUNC funptr; - void * parm; - char * pName; - DWORD id; - unsigned epicsPriority; - char isSuspended; -} win32ThreadParam; - -typedef struct epicsThreadPrivateOSD { - DWORD key; -} epicsThreadPrivateOSD; - -#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION -# define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 -#endif - -#define osdOrdinaryPriorityStateCount 5u -static const int osdOrdinaryPriorityList [osdOrdinaryPriorityStateCount] = -{ - THREAD_PRIORITY_LOWEST, /* -2 on >= W2K ??? on W95 */ - THREAD_PRIORITY_BELOW_NORMAL, /* -1 on >= W2K ??? on W95 */ - THREAD_PRIORITY_NORMAL, /* 0 on >= W2K ??? on W95 */ - THREAD_PRIORITY_ABOVE_NORMAL, /* 1 on >= W2K ??? on W95 */ - THREAD_PRIORITY_HIGHEST /* 2 on >= W2K ??? on W95 */ -}; - -# define osdRealtimePriorityStateCount 14u -static const int osdRealtimePriorityList [osdRealtimePriorityStateCount] = -{ - -7, /* allowed on >= W2k, but no #define supplied */ - -6, /* allowed on >= W2k, but no #define supplied */ - -5, /* allowed on >= W2k, but no #define supplied */ - -4, /* allowed on >= W2k, but no #define supplied */ - -3, /* allowed on >= W2k, but no #define supplied */ - THREAD_PRIORITY_LOWEST, /* -2 on >= W2K ??? on W95 */ - THREAD_PRIORITY_BELOW_NORMAL, /* -1 on >= W2K ??? on W95 */ - THREAD_PRIORITY_NORMAL, /* 0 on >= W2K ??? on W95 */ - THREAD_PRIORITY_ABOVE_NORMAL, /* 1 on >= W2K ??? on W95 */ - THREAD_PRIORITY_HIGHEST, /* 2 on >= W2K ??? on W95 */ - 3, /* allowed on >= W2k, but no #define supplied */ - 4, /* allowed on >= W2k, but no #define supplied */ - 5, /* allowed on >= W2k, but no #define supplied */ - 6 /* allowed on >= W2k, but no #define supplied */ -}; - -#if defined(EPICS_BUILD_DLL) -BOOL WINAPI DllMain ( - HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved ) -{ - static DWORD dllHandleIndex; - HMODULE dllHandle = 0; - BOOL success = TRUE; - - switch ( dwReason ) - { - case DLL_PROCESS_ATTACH: - dllHandleIndex = TlsAlloc (); - if ( dllHandleIndex == TLS_OUT_OF_INDEXES ) { - success = FALSE; - } - break; - - case DLL_PROCESS_DETACH: - success = TlsFree ( dllHandleIndex ); - break; - - case DLL_THREAD_ATTACH: - /* - * Dont allow user's explicitly calling FreeLibrary for Com.dll to yank - * the carpet out from under EPICS threads that are still using Com.dll - */ -#if _WIN32_WINNT >= 0x0501 - /* - * Only in WXP - * Thats a shame because this is probably much faster - */ - success = GetModuleHandleEx ( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - ( LPCTSTR ) DllMain, & dllHandle ); -#else - { - char name[256]; - DWORD nChar = GetModuleFileName ( - hModule, name, sizeof ( name ) ); - if ( nChar && nChar < sizeof ( name ) ) { - dllHandle = LoadLibrary ( name ); - if ( ! dllHandle ) { - success = FALSE; - } - } - else { - success = FALSE; - } - } -#endif - if ( success ) { - success = TlsSetValue ( dllHandleIndex, dllHandle ); - } - break; - case DLL_THREAD_DETACH: - /* - * Thread is exiting, release Com.dll. I am assuming that windows is - * smart enough to postpone the unload until this function returns. - */ - dllHandle = TlsGetValue ( dllHandleIndex ); - if ( dllHandle ) { - success = FreeLibrary ( dllHandle ); - } - break; - } - - return success; -} -#endif - -/* - * fetchWin32ThreadGlobal () - * Search for "Synchronization and Multiprocessor Issues" in ms doc - * to understand why this is necessary and why this works on smp systems. - */ -static win32ThreadGlobal * fetchWin32ThreadGlobal ( void ) -{ - static win32ThreadGlobal * pWin32ThreadGlobal = 0; - static LONG initStarted = 0; - static LONG initCompleted = 0; - int crtlStatus; - LONG started; - LONG done; - - done = InterlockedCompareExchange ( & initCompleted, 0, 0 ); - if ( done ) { - return pWin32ThreadGlobal; - } - - started = InterlockedCompareExchange ( & initStarted, 0, 1 ); - if ( started ) { - unsigned tries = 0u; - while ( ! InterlockedCompareExchange ( & initCompleted, 0, 0 ) ) { - /* - * I am not fond of busy loops, but since this will - * collide very infrequently and this is the lowest - * level init then perhaps this is ok - */ - Sleep ( 1 ); - if ( tries++ > 1000 ) { - return 0; - } - } - return pWin32ThreadGlobal; - } - - pWin32ThreadGlobal = ( win32ThreadGlobal * ) - calloc ( 1, sizeof ( * pWin32ThreadGlobal ) ); - if ( ! pWin32ThreadGlobal ) { - InterlockedExchange ( & initStarted, 0 ); - return 0; - } - - InitializeCriticalSection ( & pWin32ThreadGlobal->mutex ); - ellInit ( & pWin32ThreadGlobal->threadList ); - pWin32ThreadGlobal->tlsIndexThreadLibraryEPICS = TlsAlloc(); - if ( pWin32ThreadGlobal->tlsIndexThreadLibraryEPICS == 0xFFFFFFFF ) { - DeleteCriticalSection ( & pWin32ThreadGlobal->mutex ); - free ( pWin32ThreadGlobal ); - pWin32ThreadGlobal = 0; - return 0; - } - - crtlStatus = atexit ( threadCleanupWIN32 ); - if ( crtlStatus ) { - TlsFree ( pWin32ThreadGlobal->tlsIndexThreadLibraryEPICS ); - DeleteCriticalSection ( & pWin32ThreadGlobal->mutex ); - free ( pWin32ThreadGlobal ); - pWin32ThreadGlobal = 0; - return 0; - } - - InterlockedExchange ( & initCompleted, 1 ); - - return pWin32ThreadGlobal; -} - -static void epicsParmCleanupWIN32 ( win32ThreadParam * pParm ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - if ( ! pGbl ) { - fprintf ( stderr, "epicsParmCleanupWIN32: unable to find ctx\n" ); - return; - } - - if ( pParm ) { - /* fprintf ( stderr, "thread %s is exiting\n", pParm->pName ); */ - EnterCriticalSection ( & pGbl->mutex ); - ellDelete ( & pGbl->threadList, & pParm->node ); - LeaveCriticalSection ( & pGbl->mutex ); - - CloseHandle ( pParm->handle ); - free ( pParm ); - TlsSetValue ( pGbl->tlsIndexThreadLibraryEPICS, 0 ); - } -} - -/* - * threadCleanupWIN32 () - */ -static void threadCleanupWIN32 ( void ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - fprintf ( stderr, "threadCleanupWIN32: unable to find ctx\n" ); - return; - } - - while ( ( pParm = ( win32ThreadParam * ) - ellFirst ( & pGbl->threadList ) ) ) { - epicsParmCleanupWIN32 ( pParm ); - } -} - -/* - * epicsThreadExitMain () - */ -epicsShareFunc void epicsShareAPI epicsThreadExitMain ( void ) -{ - _endthread (); -} - -/* - * osdPriorityMagFromPriorityOSI () - */ -static unsigned osdPriorityMagFromPriorityOSI ( unsigned osiPriority, unsigned priorityStateCount ) -{ - unsigned magnitude; - - /* optimizer will remove this one if epicsThreadPriorityMin is zero */ - /* and osiPriority is unsigned */ - if ( osiPriority < epicsThreadPriorityMin ) { - osiPriority = epicsThreadPriorityMin; - } - - if ( osiPriority > epicsThreadPriorityMax ) { - osiPriority = epicsThreadPriorityMax; - } - - magnitude = osiPriority * priorityStateCount; - magnitude /= ( epicsThreadPriorityMax - epicsThreadPriorityMin ) + 1; - - return magnitude; -} - -epicsShareFunc -void epicsThreadRealtimeLock(void) -{} - -/* - * epicsThreadGetOsdPriorityValue () - */ -static int epicsThreadGetOsdPriorityValue ( unsigned osiPriority ) -{ - const DWORD priorityClass = GetPriorityClass ( GetCurrentProcess () ); - const int * pStateList; - unsigned stateCount; - unsigned magnitude; - - if ( priorityClass == REALTIME_PRIORITY_CLASS ) { - stateCount = osdRealtimePriorityStateCount; - pStateList = osdRealtimePriorityList; - } - else { - stateCount = osdOrdinaryPriorityStateCount; - pStateList = osdOrdinaryPriorityList; - } - - magnitude = osdPriorityMagFromPriorityOSI ( osiPriority, stateCount ); - return pStateList[magnitude]; -} - -/* - * osiPriorityMagFromMagnitueOSD () - */ -static unsigned osiPriorityMagFromMagnitueOSD ( unsigned magnitude, unsigned osdPriorityStateCount ) -{ - unsigned osiPriority; - - osiPriority = magnitude * ( epicsThreadPriorityMax - epicsThreadPriorityMin ); - osiPriority /= osdPriorityStateCount - 1u; - osiPriority += epicsThreadPriorityMin; - - return osiPriority; -} - - -/* - * epicsThreadGetOsiPriorityValue () - */ -static unsigned epicsThreadGetOsiPriorityValue ( int osdPriority ) -{ - const DWORD priorityClass = GetPriorityClass ( GetCurrentProcess () ); - const int * pStateList; - unsigned stateCount; - unsigned magnitude; - - if ( priorityClass == REALTIME_PRIORITY_CLASS ) { - stateCount = osdRealtimePriorityStateCount; - pStateList = osdRealtimePriorityList; - } - else { - stateCount = osdOrdinaryPriorityStateCount; - pStateList = osdOrdinaryPriorityList; - } - - for ( magnitude = 0u; magnitude < stateCount; magnitude++ ) { - if ( osdPriority == pStateList[magnitude] ) { - break; - } - } - - if ( magnitude >= stateCount ) { - fprintf ( stderr, - "Unrecognized WIN32 thread priority level %d.\n", - osdPriority ); - fprintf ( stderr, - "Mapping to EPICS thread priority level epicsThreadPriorityMin.\n" ); - return epicsThreadPriorityMin; - } - - return osiPriorityMagFromMagnitueOSD ( magnitude, stateCount ); -} - -/* - * epicsThreadLowestPriorityLevelAbove () - */ -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadLowestPriorityLevelAbove - ( unsigned int priority, unsigned * pPriorityJustAbove ) -{ - const DWORD priorityClass = GetPriorityClass ( GetCurrentProcess () ); - epicsThreadBooleanStatus status; - unsigned stateCount; - unsigned magnitude; - - if ( priorityClass == REALTIME_PRIORITY_CLASS ) { - stateCount = osdRealtimePriorityStateCount; - } - else { - stateCount = osdOrdinaryPriorityStateCount; - } - - magnitude = osdPriorityMagFromPriorityOSI ( priority, stateCount ); - - if ( magnitude < ( stateCount - 1 ) ) { - *pPriorityJustAbove = osiPriorityMagFromMagnitueOSD ( magnitude + 1u, stateCount ); - status = epicsThreadBooleanStatusSuccess; - } - else { - status = epicsThreadBooleanStatusFail; - } - return status; -} - -/* - * epicsThreadHighestPriorityLevelBelow () - */ -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadHighestPriorityLevelBelow - ( unsigned int priority, unsigned * pPriorityJustBelow ) -{ - const DWORD priorityClass = GetPriorityClass ( GetCurrentProcess () ); - epicsThreadBooleanStatus status; - unsigned stateCount; - unsigned magnitude; - - if ( priorityClass == REALTIME_PRIORITY_CLASS ) { - stateCount = osdRealtimePriorityStateCount; - } - else { - stateCount = osdOrdinaryPriorityStateCount; - } - - magnitude = osdPriorityMagFromPriorityOSI ( priority, stateCount ); - - if ( magnitude > 0u ) { - *pPriorityJustBelow = osiPriorityMagFromMagnitueOSD ( magnitude - 1u, stateCount ); - status = epicsThreadBooleanStatusSuccess; - } - else { - status = epicsThreadBooleanStatusFail; - } - return status; -} - -/* - * epicsThreadGetStackSize () - */ -epicsShareFunc unsigned int epicsShareAPI - epicsThreadGetStackSize ( epicsThreadStackSizeClass stackSizeClass ) -{ - #define STACK_SIZE(f) (f * 0x10000 * sizeof(void *)) - static const unsigned stackSizeTable[epicsThreadStackBig+1] = { - STACK_SIZE(1), STACK_SIZE(2), STACK_SIZE(4) - }; - - if (stackSizeClassepicsThreadStackBig) { - fprintf ( stderr, - "epicsThreadGetStackSize illegal argument (too large)"); - return stackSizeTable[epicsThreadStackBig]; - } - - return stackSizeTable[stackSizeClass]; -} - -void epicsThreadCleanupWIN32 () -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - fprintf ( stderr, "epicsThreadCleanupWIN32: unable to find ctx\n" ); - return; - } - - pParm = ( win32ThreadParam * ) - TlsGetValue ( pGbl->tlsIndexThreadLibraryEPICS ); - epicsParmCleanupWIN32 ( pParm ); -} - -/* - * epicsWin32ThreadEntry() - */ -static unsigned WINAPI epicsWin32ThreadEntry ( LPVOID lpParameter ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm = ( win32ThreadParam * ) lpParameter; - unsigned retStat = 0u; - BOOL success; - - if ( pGbl ) { - setThreadName ( pParm->id, pParm->pName ); - - success = TlsSetValue ( pGbl->tlsIndexThreadLibraryEPICS, pParm ); - if ( success ) { - osdThreadHooksRun ( ( epicsThreadId ) pParm ); - /* printf ( "starting thread %d\n", pParm->id ); */ - ( *pParm->funptr ) ( pParm->parm ); - /* printf ( "terminating thread %d\n", pParm->id ); */ - retStat = 1; - } - else { - fprintf ( stderr, "epicsWin32ThreadEntry: unable to set private\n" ); - } - } - else { - fprintf ( stderr, "epicsWin32ThreadEntry: unable to find ctx\n" ); - } - - epicsExitCallAtThreadExits (); - /* - * CAUTION: !!!! the thread id might continue to be used after this thread exits !!!! - */ - epicsParmCleanupWIN32 ( pParm ); - - return retStat; /* this indirectly closes the thread handle */ -} - -static win32ThreadParam * epicsThreadParmCreate ( const char *pName ) -{ - win32ThreadParam *pParmWIN32; - - pParmWIN32 = calloc ( 1, sizeof ( *pParmWIN32 ) + strlen ( pName ) + 1 ); - if ( pParmWIN32 ) { - pParmWIN32->pName = (char *) ( pParmWIN32 + 1 ); - strcpy ( pParmWIN32->pName, pName ); - pParmWIN32->isSuspended = 0; - } - return pParmWIN32; -} - -static win32ThreadParam * epicsThreadImplicitCreate ( void ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - DWORD id = GetCurrentThreadId (); - win32ThreadParam * pParm; - char name[64]; - HANDLE handle; - BOOL success; - - if ( ! pGbl ) { - fprintf ( stderr, "epicsThreadImplicitCreate: unable to find ctx\n" ); - return 0; - } - - success = DuplicateHandle ( GetCurrentProcess (), GetCurrentThread (), - GetCurrentProcess (), & handle, 0, FALSE, DUPLICATE_SAME_ACCESS ); - if ( ! success ) { - return 0; - } - { - unsigned long idForFormat = id; - sprintf ( name, "win%lx", idForFormat ); - } - pParm = epicsThreadParmCreate ( name ); - if ( pParm ) { - int win32ThreadPriority; - - pParm->handle = handle; - pParm->id = id; - win32ThreadPriority = GetThreadPriority ( pParm->handle ); - assert ( win32ThreadPriority != THREAD_PRIORITY_ERROR_RETURN ); - pParm->epicsPriority = epicsThreadGetOsiPriorityValue ( win32ThreadPriority ); - success = TlsSetValue ( pGbl->tlsIndexThreadLibraryEPICS, pParm ); - if ( ! success ) { - epicsParmCleanupWIN32 ( pParm ); - pParm = 0; - } - else { - EnterCriticalSection ( & pGbl->mutex ); - ellAdd ( & pGbl->threadList, & pParm->node ); - LeaveCriticalSection ( & pGbl->mutex ); - } - } - return pParm; -} - -/* - * epicsThreadCreate () - */ -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate (const char *pName, - unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC pFunc,void *pParm) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParmWIN32; - int osdPriority; - DWORD wstat; - BOOL bstat; - - if ( ! pGbl ) { - return NULL; - } - - pParmWIN32 = epicsThreadParmCreate ( pName ); - if ( pParmWIN32 == 0 ) { - return ( epicsThreadId ) pParmWIN32; - } - pParmWIN32->funptr = pFunc; - pParmWIN32->parm = pParm; - pParmWIN32->epicsPriority = priority; - - { - unsigned threadId; - pParmWIN32->handle = (HANDLE) _beginthreadex ( - 0, stackSize, epicsWin32ThreadEntry, - pParmWIN32, - CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, - & threadId ); - if ( pParmWIN32->handle == 0 ) { - free ( pParmWIN32 ); - return NULL; - } - /* weird win32 interface threadId parameter inconsistency */ - pParmWIN32->id = ( DWORD ) threadId ; - } - - osdPriority = epicsThreadGetOsdPriorityValue (priority); - bstat = SetThreadPriority ( pParmWIN32->handle, osdPriority ); - if (!bstat) { - CloseHandle ( pParmWIN32->handle ); - free ( pParmWIN32 ); - return NULL; - } - - EnterCriticalSection ( & pGbl->mutex ); - ellAdd ( & pGbl->threadList, & pParmWIN32->node ); - LeaveCriticalSection ( & pGbl->mutex ); - - wstat = ResumeThread ( pParmWIN32->handle ); - if (wstat==0xFFFFFFFF) { - EnterCriticalSection ( & pGbl->mutex ); - ellDelete ( & pGbl->threadList, & pParmWIN32->node ); - LeaveCriticalSection ( & pGbl->mutex ); - CloseHandle ( pParmWIN32->handle ); - free ( pParmWIN32 ); - return NULL; - } - - return ( epicsThreadId ) pParmWIN32; -} - -/* - * epicsThreadSuspendSelf () - */ -epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf () -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - DWORD stat; - - assert ( pGbl ); - - pParm = ( win32ThreadParam * ) - TlsGetValue ( pGbl->tlsIndexThreadLibraryEPICS ); - if ( ! pParm ) { - pParm = epicsThreadImplicitCreate (); - } - if ( pParm ) { - EnterCriticalSection ( & pGbl->mutex ); - pParm->isSuspended = 1; - LeaveCriticalSection ( & pGbl->mutex ); - } - stat = SuspendThread ( GetCurrentThread () ); - assert ( stat != 0xFFFFFFFF ); -} - -/* - * epicsThreadResume () - */ -epicsShareFunc void epicsShareAPI epicsThreadResume ( epicsThreadId id ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - DWORD stat; - - assert ( pGbl ); - - EnterCriticalSection ( & pGbl->mutex ); - - stat = ResumeThread ( pParm->handle ); - pParm->isSuspended = 0; - - LeaveCriticalSection ( & pGbl->mutex ); - - assert ( stat != 0xFFFFFFFF ); -} - -/* - * epicsThreadGetPriority () - */ -epicsShareFunc unsigned epicsShareAPI epicsThreadGetPriority (epicsThreadId id) -{ - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - return pParm->epicsPriority; -} - -/* - * epicsThreadGetPrioritySelf () - */ -epicsShareFunc unsigned epicsShareAPI epicsThreadGetPrioritySelf () -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - assert ( pGbl ); - - pParm = ( win32ThreadParam * ) - TlsGetValue ( pGbl->tlsIndexThreadLibraryEPICS ); - if ( ! pParm ) { - pParm = epicsThreadImplicitCreate (); - } - if ( pParm ) { - return pParm->epicsPriority; - } - else { - int win32ThreadPriority = - GetThreadPriority ( GetCurrentThread () ); - assert ( win32ThreadPriority != THREAD_PRIORITY_ERROR_RETURN ); - return epicsThreadGetOsiPriorityValue ( win32ThreadPriority ); - } -} - -/* - * epicsThreadSetPriority () - */ -epicsShareFunc void epicsShareAPI epicsThreadSetPriority ( epicsThreadId id, unsigned priority ) -{ - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - BOOL stat = SetThreadPriority ( pParm->handle, epicsThreadGetOsdPriorityValue (priority) ); - assert (stat); -} - -/* - * epicsThreadIsEqual () - */ -epicsShareFunc int epicsShareAPI epicsThreadIsEqual ( epicsThreadId id1, epicsThreadId id2 ) -{ - win32ThreadParam * pParm1 = ( win32ThreadParam * ) id1; - win32ThreadParam * pParm2 = ( win32ThreadParam * ) id2; - return ( id1 == id2 && pParm1->id == pParm2->id ); -} - -/* - * epicsThreadIsSuspended () - */ -epicsShareFunc int epicsShareAPI epicsThreadIsSuspended ( epicsThreadId id ) -{ - win32ThreadParam *pParm = ( win32ThreadParam * ) id; - DWORD exitCode; - BOOL stat; - - stat = GetExitCodeThread ( pParm->handle, & exitCode ); - if ( stat ) { - if ( exitCode != STILL_ACTIVE ) { - return 1; - } - else { - return pParm->isSuspended; - } - } - else { - return 1; - } -} - -/* - * epicsThreadSleep () - */ -epicsShareFunc void epicsShareAPI epicsThreadSleep ( double seconds ) -{ - static const unsigned mSecPerSec = 1000; - DWORD milliSecDelay; - - if ( seconds > 0.0 ) { - seconds *= mSecPerSec; - seconds += 0.99999999; /* 8 9s here is optimal */ - milliSecDelay = ( seconds >= INFINITE ) ? - INFINITE - 1 : ( DWORD ) seconds; - } - else { /* seconds <= 0 or NAN */ - milliSecDelay = 0u; - } - Sleep ( milliSecDelay ); -} - -/* - * epicsThreadSleepQuantum () - */ -double epicsShareAPI epicsThreadSleepQuantum () -{ - /* - * Its worth noting here that the sleep quantum on windows can - * mysteriously get better. I eventually tracked this down to - * codes that call timeBeginPeriod(1). Calling timeBeginPeriod() - * specifying a better timer resolution also increases the interrupt - * load. This appears to be related to java applet activity. - * The function timeGetDevCaps can tell us the range of periods - * that can be specified to timeBeginPeriod, but alas there - * appears to be no way to find out what the value of the global - * minimum of all timeBeginPeriod calls for all processes is. - */ - static const double secPerTick = 100e-9; - DWORD adjustment; - DWORD delay; - BOOL disabled; - BOOL success; - - success = GetSystemTimeAdjustment ( - & adjustment, & delay, & disabled ); - if ( success ) { - return delay * secPerTick; - } - else { - return 0.0; - } -} - -/* - * epicsThreadGetIdSelf () - */ -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf (void) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - assert ( pGbl ); - - pParm = ( win32ThreadParam * ) TlsGetValue ( - pGbl->tlsIndexThreadLibraryEPICS ); - if ( ! pParm ) { - pParm = epicsThreadImplicitCreate (); - assert ( pParm ); /* very dangerous to allow non-unique thread id into use */ - } - return ( epicsThreadId ) pParm; -} - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId ( const char * pName ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - return 0; - } - - EnterCriticalSection ( & pGbl->mutex ); - - for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList ); - pParm; pParm = ( win32ThreadParam * ) ellNext ( & pParm->node ) ) { - if ( pParm->pName ) { - if ( strcmp ( pParm->pName, pName ) == 0 ) { - break; - } - } - } - - LeaveCriticalSection ( & pGbl->mutex ); - - /* !!!! warning - the thread parm could vanish at any time !!!! */ - - return ( epicsThreadId ) pParm; -} - - -/* - * epicsThreadGetNameSelf () - */ -epicsShareFunc const char * epicsShareAPI epicsThreadGetNameSelf (void) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - return "thread library not initialized"; - } - - pParm = ( win32ThreadParam * ) - TlsGetValue ( pGbl->tlsIndexThreadLibraryEPICS ); - if ( ! pParm ) { - pParm = epicsThreadImplicitCreate (); - } - - if ( pParm ) { - if ( pParm->pName ) { - return pParm->pName; - } - } - return "anonymous"; -} - -/* - * epicsThreadGetName () - */ -epicsShareFunc void epicsShareAPI epicsThreadGetName ( - epicsThreadId id, char * pName, size_t size ) -{ - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - - if ( size ) { - size_t sizeMinusOne = size-1; - strncpy ( pName, pParm->pName, sizeMinusOne ); - pName [sizeMinusOne] = '\0'; - } -} - -/* - * epics_GetThreadPriorityAsString () - */ -static const char * epics_GetThreadPriorityAsString ( HANDLE thr ) -{ - const char * pPriName = "?????"; - switch ( GetThreadPriority ( thr ) ) { - case THREAD_PRIORITY_TIME_CRITICAL: - pPriName = "tm-crit"; - break; - case THREAD_PRIORITY_HIGHEST: - pPriName = "high"; - break; - case THREAD_PRIORITY_ABOVE_NORMAL: - pPriName = "normal+"; - break; - case THREAD_PRIORITY_NORMAL: - pPriName = "normal"; - break; - case THREAD_PRIORITY_BELOW_NORMAL: - pPriName = "normal-"; - break; - case THREAD_PRIORITY_LOWEST: - pPriName = "low"; - break; - case THREAD_PRIORITY_IDLE: - pPriName = "idle"; - break; - } - return pPriName; -} - -/* - * epicsThreadShowInfo () - */ -static void epicsThreadShowInfo ( epicsThreadId id, unsigned level ) -{ - win32ThreadParam * pParm = ( win32ThreadParam * ) id; - - if ( pParm ) { - unsigned long idForFormat = pParm->id; - fprintf ( epicsGetStdout(), "%-15s %-8p %-8lx %-9u %-9s %-7s", pParm->pName, - (void *) pParm, idForFormat, pParm->epicsPriority, - epics_GetThreadPriorityAsString ( pParm->handle ), - epicsThreadIsSuspended ( id ) ? "suspend" : "ok" ); - if ( level ) { - fprintf (epicsGetStdout(), " %-8p %-8p ", - (void *) pParm->handle, (void *) pParm->parm ); - } - } - else { - fprintf (epicsGetStdout(), - "NAME EPICS-ID WIN32-ID EPICS-PRI WIN32-PRI STATE " ); - if ( level ) { - fprintf (epicsGetStdout(), " HANDLE FUNCTION PARAMETER" ); - } - } - fprintf (epicsGetStdout(),"\n" ); -} - -/* - * epicsThreadMap () - */ -epicsShareFunc void epicsThreadMap ( EPICS_THREAD_HOOK_ROUTINE func ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - return; - } - - EnterCriticalSection ( & pGbl->mutex ); - - for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList ); - pParm; pParm = ( win32ThreadParam * ) ellNext ( & pParm->node ) ) { - func ( ( epicsThreadId ) pParm ); - } - - LeaveCriticalSection ( & pGbl->mutex ); -} - -/* - * epicsThreadShowAll () - */ -epicsShareFunc void epicsShareAPI epicsThreadShowAll ( unsigned level ) -{ - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - win32ThreadParam * pParm; - - if ( ! pGbl ) { - return; - } - - EnterCriticalSection ( & pGbl->mutex ); - - epicsThreadShowInfo ( 0, level ); - for ( pParm = ( win32ThreadParam * ) ellFirst ( & pGbl->threadList ); - pParm; pParm = ( win32ThreadParam * ) ellNext ( & pParm->node ) ) { - epicsThreadShowInfo ( ( epicsThreadId ) pParm, level ); - } - - LeaveCriticalSection ( & pGbl->mutex ); -} - -/* - * epicsThreadShow () - */ -epicsShareFunc void epicsShareAPI epicsThreadShow ( epicsThreadId id, unsigned level ) -{ - epicsThreadShowInfo ( 0, level ); - epicsThreadShowInfo ( id, level ); -} - -/* - * epicsThreadOnce () - */ -epicsShareFunc void epicsShareAPI epicsThreadOnce ( - epicsThreadOnceId *id, void (*func)(void *), void *arg ) -{ - static struct epicsThreadOSD threadOnceComplete; - #define EPICS_THREAD_ONCE_DONE & threadOnceComplete - win32ThreadGlobal * pGbl = fetchWin32ThreadGlobal (); - - assert ( pGbl ); - - EnterCriticalSection ( & pGbl->mutex ); - - if ( *id != EPICS_THREAD_ONCE_DONE ) { - if ( *id == EPICS_THREAD_ONCE_INIT ) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - LeaveCriticalSection ( & pGbl->mutex ); - func ( arg ); - EnterCriticalSection ( & pGbl->mutex ); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if ( *id == epicsThreadGetIdSelf() ) { - LeaveCriticalSection ( & pGbl->mutex ); - cantProceed( "Recursive epicsThreadOnce() initialization\n" ); - } else - while ( *id != EPICS_THREAD_ONCE_DONE ) { - /* Another thread is in the above func(arg) call. */ - LeaveCriticalSection ( & pGbl->mutex ); - epicsThreadSleep ( epicsThreadSleepQuantum() ); - EnterCriticalSection ( & pGbl->mutex ); - } - } - LeaveCriticalSection ( & pGbl->mutex ); -} - -/* - * epicsThreadPrivateCreate () - */ -epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate () -{ - epicsThreadPrivateOSD *p = ( epicsThreadPrivateOSD * ) malloc ( sizeof ( *p ) ); - if ( p ) { - p->key = TlsAlloc (); - if ( p->key == 0xFFFFFFFF ) { - free ( p ); - p = 0; - } - } - return p; -} - -/* - * epicsThreadPrivateDelete () - */ -epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete ( epicsThreadPrivateId p ) -{ - BOOL stat = TlsFree ( p->key ); - assert ( stat ); - free ( p ); -} - -/* - * epicsThreadPrivateSet () - */ -epicsShareFunc void epicsShareAPI epicsThreadPrivateSet ( epicsThreadPrivateId pPvt, void *pVal ) -{ - BOOL stat = TlsSetValue ( pPvt->key, (void *) pVal ); - assert (stat); -} - -/* - * epicsThreadPrivateGet () - */ -epicsShareFunc void * epicsShareAPI epicsThreadPrivateGet ( epicsThreadPrivateId pPvt ) -{ - return ( void * ) TlsGetValue ( pPvt->key ); -} - -/* - * epicsThreadGetCPUs () - */ -epicsShareFunc int epicsThreadGetCPUs ( void ) -{ - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - if (sysinfo.dwNumberOfProcessors > 0) - return sysinfo.dwNumberOfProcessors; - return 1; -} - -#ifdef TEST_CODES -void testPriorityMapping () -{ - unsigned i; - - for (i=epicsThreadPriorityMin; i -#include -#include -#include - -// -// WIN32 -// -#define VC_EXTRALEAN -#define STRICT -#include -#include - -// -// EPICS -// -#define epicsExportSharedSymbols -#include "epicsTime.h" -#include "generalTimeSup.h" -#include "epicsTimer.h" -#include "errlog.h" -#include "epicsAssert.h" -#include "epicsThread.h" - -#if defined ( DEBUG ) -# define debugPrintf(argsInParen) ::printf argsInParen -#else -# define debugPrintf(argsInParen) -#endif - -extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ); - -static int osdTimeGetCurrent ( epicsTimeStamp *pDest ); - -// for mingw -#if !defined ( MAXLONGLONG ) -# define MAXLONGLONG 0x7fffffffffffffffLL -#endif -#if !defined ( MINLONGLONG ) -# define MINLONGLONG ~0x7fffffffffffffffLL -#endif -#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION -# define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 -#endif - -static const LONGLONG epicsEpochInFileTime = 0x01b41e2a18d64000LL; - -static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ); - -class currentTime { -public: - currentTime (); - ~currentTime (); - void getCurrentTime ( epicsTimeStamp & dest ); - void startPLL (); -private: - CRITICAL_SECTION mutex; - LONGLONG lastPerfCounter; - LONGLONG perfCounterFreq; - LONGLONG epicsTimeLast; // nano-sec since the EPICS epoch - LONGLONG perfCounterFreqPLL; - LONGLONG lastPerfCounterPLL; - LONGLONG lastFileTimePLL; - HANDLE threadHandle; - unsigned threadId; - bool perfCtrPresent; - bool threadShutdownCmd; - bool threadHasExited; - void updatePLL (); - static const int pllDelay; /* integer seconds */ - // cant be static because of diff btw __stdcall and __cdecl - friend unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ); -}; - -const int currentTime :: pllDelay = 5; - -static currentTime * pCurrentTime = 0; -static const LONGLONG FILE_TIME_TICKS_PER_SEC = 10000000; -static const LONGLONG EPICS_TIME_TICKS_PER_SEC = 1000000000; -static const LONGLONG ET_TICKS_PER_FT_TICK = - EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC; - -// -// Start and register time provider -// -static int timeRegister(void) -{ - pCurrentTime = new currentTime (); - - generalTimeCurrentTpRegister("PerfCounter", 150, osdTimeGetCurrent); - - pCurrentTime->startPLL (); - return 1; -} -static int done = timeRegister(); - -// -// osdTimeGetCurrent () -// -static int osdTimeGetCurrent ( epicsTimeStamp *pDest ) -{ - assert ( pCurrentTime ); - - pCurrentTime->getCurrentTime ( *pDest ); - return epicsTimeOK; -} - -// synthesize a reentrant gmtime on WIN32 -int epicsShareAPI epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM ) -{ - struct tm * pRet = gmtime ( pAnsiTime ); - if ( pRet ) { - *pTM = *pRet; - return epicsTimeOK; - } - else { - return errno; - } -} - -// synthesize a reentrant localtime on WIN32 -int epicsShareAPI epicsTime_localtime ( - const time_t * pAnsiTime, struct tm * pTM ) -{ - struct tm * pRet = localtime ( pAnsiTime ); - if ( pRet ) { - *pTM = *pRet; - return epicsTimeOK; - } - else { - return errno; - } -} - -currentTime::currentTime () : - lastPerfCounter ( 0 ), - perfCounterFreq ( 0 ), - epicsTimeLast ( 0 ), - perfCounterFreqPLL ( 0 ), - lastPerfCounterPLL ( 0 ), - lastFileTimePLL ( 0 ), - threadHandle ( 0 ), - threadId ( 0 ), - perfCtrPresent ( false ), - threadShutdownCmd ( false ), - threadHasExited ( false ) -{ - InitializeCriticalSection ( & this->mutex ); - - // avoid interruptions by briefly becoming a time critical thread - int originalPriority = GetThreadPriority ( GetCurrentThread () ); - SetThreadPriority ( GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL ); - - FILETIME ft; - GetSystemTimeAsFileTime ( & ft ); - LARGE_INTEGER tmp; - QueryPerformanceCounter ( & tmp ); - this->lastPerfCounter = tmp.QuadPart; - // if no high resolution counters then default to low res file time - if ( QueryPerformanceFrequency ( & tmp ) ) { - this->perfCounterFreq = tmp.QuadPart; - this->perfCtrPresent = true; - } - SetThreadPriority ( GetCurrentThread (), originalPriority ); - - LARGE_INTEGER liFileTime; - liFileTime.LowPart = ft.dwLowDateTime; - liFileTime.HighPart = ft.dwHighDateTime; - - if ( liFileTime.QuadPart >= epicsEpochInFileTime ) { - // the windows file time has a maximum resolution of 100 nS - // and a nominal resolution of 10 mS - 16 mS - this->epicsTimeLast = - ( liFileTime.QuadPart - epicsEpochInFileTime ) * - ET_TICKS_PER_FT_TICK; - } - else { - errlogPrintf ( - "win32 osdTime.cpp init detected questionable " - "system date prior to EPICS epoch, epics time will not advance\n" ); - this->epicsTimeLast = 0; - } - - this->perfCounterFreqPLL = this->perfCounterFreq; - this->lastPerfCounterPLL = this->lastPerfCounter; - this->lastFileTimePLL = liFileTime.QuadPart; -} - -void currentTime :: startPLL () -{ - // create frequency estimation thread when needed - if ( this->perfCtrPresent && ! this->threadHandle ) { - this->threadHandle = (HANDLE) - _beginthreadex ( 0, 4096, _pllThreadEntry, this, - CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, - & this->threadId ); - assert ( this->threadHandle ); - BOOL bstat = SetThreadPriority ( - this->threadHandle, THREAD_PRIORITY_HIGHEST ); - assert ( bstat ); - DWORD wstat = ResumeThread ( this->threadHandle ); - assert ( wstat != 0xFFFFFFFF ); - } -} - -currentTime::~currentTime () -{ - EnterCriticalSection ( & this->mutex ); - this->threadShutdownCmd = true; - while ( ! this->threadHasExited ) { - LeaveCriticalSection ( & this->mutex ); - Sleep ( 250 /* mS */ ); - EnterCriticalSection ( & this->mutex ); - } - LeaveCriticalSection ( & this->mutex ); - DeleteCriticalSection ( & this->mutex ); -} - -void currentTime::getCurrentTime ( epicsTimeStamp & dest ) -{ - if ( this->perfCtrPresent ) { - EnterCriticalSection ( & this->mutex ); - - LARGE_INTEGER curPerfCounter; - QueryPerformanceCounter ( & curPerfCounter ); - - LONGLONG offset; - if ( curPerfCounter.QuadPart >= this->lastPerfCounter ) { - offset = curPerfCounter.QuadPart - this->lastPerfCounter; - } - else { - // - // must have been a timer roll-over event - // - // It takes 9.223372036855e+18/perf_freq sec to roll over this - // counter. This is currently about 245118 years using the perf - // counter freq value on my system (1193182). Nevertheless, I - // have code for this situation because the performance - // counter resolution will more than likely improve over time. - // - offset = ( MAXLONGLONG - this->lastPerfCounter ) - + ( curPerfCounter.QuadPart - MINLONGLONG ) + 1; - } - if ( offset < MAXLONGLONG / EPICS_TIME_TICKS_PER_SEC ) { - offset *= EPICS_TIME_TICKS_PER_SEC; - offset /= this->perfCounterFreq; - } - else { - double fpOffset = static_cast < double > ( offset ); - fpOffset *= EPICS_TIME_TICKS_PER_SEC; - fpOffset /= static_cast < double > ( this->perfCounterFreq ); - offset = static_cast < LONGLONG > ( fpOffset ); - } - LONGLONG epicsTimeCurrent = this->epicsTimeLast + offset; - if ( this->epicsTimeLast > epicsTimeCurrent ) { - double diff = static_cast < double > - ( this->epicsTimeLast - epicsTimeCurrent ) / EPICS_TIME_TICKS_PER_SEC; - errlogPrintf ( - "currentTime::getCurrentTime(): %f sec " - "time discontinuity detected\n", - diff ); - } - this->epicsTimeLast = epicsTimeCurrent; - this->lastPerfCounter = curPerfCounter.QuadPart; - - LeaveCriticalSection ( & this->mutex ); - - dest.secPastEpoch = static_cast < epicsUInt32 > - ( epicsTimeCurrent / EPICS_TIME_TICKS_PER_SEC ); - dest.nsec = static_cast < epicsUInt32 > - ( epicsTimeCurrent % EPICS_TIME_TICKS_PER_SEC ); - } - else { - // if high resolution performance counters are not supported then - // fall back to low res file time - FILETIME ft; - GetSystemTimeAsFileTime ( & ft ); - dest = epicsTime ( ft ); - } -} - -// -// Maintain corrected version of the performance counter's frequency using -// a phase locked loop. This approach is similar to NTP's. -// -void currentTime :: updatePLL () -{ - EnterCriticalSection ( & this->mutex ); - - // avoid interruptions by briefly becoming a time critical thread - LARGE_INTEGER curFileTime; - LARGE_INTEGER curPerfCounter; - { - int originalPriority = GetThreadPriority ( GetCurrentThread () ); - SetThreadPriority ( GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL ); - FILETIME ft; - GetSystemTimeAsFileTime ( & ft ); - QueryPerformanceCounter ( & curPerfCounter ); - SetThreadPriority ( GetCurrentThread (), originalPriority ); - - curFileTime.LowPart = ft.dwLowDateTime; - curFileTime.HighPart = ft.dwHighDateTime; - } - - LONGLONG perfCounterDiff; - if ( curPerfCounter.QuadPart >= this->lastPerfCounterPLL ) { - perfCounterDiff = curPerfCounter.QuadPart - this->lastPerfCounterPLL; - } - else { - // - // must have been a timer roll-over event - // - // It takes 9.223372036855e+18/perf_freq sec to roll over this - // counter. This is currently about 245118 years using the perf - // counter freq value on my system (1193182). Nevertheless, I - // have code for this situation because the performance - // counter resolution will more than likely improve over time. - // - perfCounterDiff = ( MAXLONGLONG - this->lastPerfCounterPLL ) - + ( curPerfCounter.QuadPart - MINLONGLONG ) + 1; - } - this->lastPerfCounterPLL = curPerfCounter.QuadPart; - - LONGLONG fileTimeDiff = curFileTime.QuadPart - this->lastFileTimePLL; - this->lastFileTimePLL = curFileTime.QuadPart; - - // discard glitches - if ( fileTimeDiff <= 0 ) { - LeaveCriticalSection( & this->mutex ); - debugPrintf ( ( "currentTime: file time difference in PLL was less than zero\n" ) ); - return; - } - - LONGLONG freq = ( FILE_TIME_TICKS_PER_SEC * perfCounterDiff ) / fileTimeDiff; - LONGLONG delta = freq - this->perfCounterFreqPLL; - - // discard glitches - LONGLONG bound = this->perfCounterFreqPLL >> 10; - if ( delta < -bound || delta > bound ) { - LeaveCriticalSection( & this->mutex ); - debugPrintf ( ( "freq est out of bounds l=%d e=%d h=%d\n", - static_cast < int > ( -bound ), - static_cast < int > ( delta ), - static_cast < int > ( bound ) ) ); - return; - } - - // update feedback loop estimating the performance counter's frequency - LONGLONG feedback = delta >> 8; - this->perfCounterFreqPLL += feedback; - - LONGLONG perfCounterDiffSinceLastFetch; - if ( curPerfCounter.QuadPart >= this->lastPerfCounter ) { - perfCounterDiffSinceLastFetch = - curPerfCounter.QuadPart - this->lastPerfCounter; - } - else { - // - // must have been a timer roll-over event - // - // It takes 9.223372036855e+18/perf_freq sec to roll over this - // counter. This is currently about 245118 years using the perf - // counter freq value on my system (1193182). Nevertheless, I - // have code for this situation because the performance - // counter resolution will more than likely improve over time. - // - perfCounterDiffSinceLastFetch = - ( MAXLONGLONG - this->lastPerfCounter ) - + ( curPerfCounter.QuadPart - MINLONGLONG ) + 1; - } - - // discard performance counter delay measurement glitches - { - const LONGLONG expectedDly = this->perfCounterFreq * pllDelay; - const LONGLONG bnd = expectedDly / 4; - if ( perfCounterDiffSinceLastFetch <= 0 || - perfCounterDiffSinceLastFetch >= expectedDly + bnd ) { - LeaveCriticalSection( & this->mutex ); - debugPrintf ( ( "perf ctr measured delay out of bounds m=%d max=%d\n", - static_cast < int > ( perfCounterDiffSinceLastFetch ), - static_cast < int > ( expectedDly + bnd ) ) ); - return; - } - } - - // Update the current estimated time. - this->epicsTimeLast += - ( perfCounterDiffSinceLastFetch * EPICS_TIME_TICKS_PER_SEC ) - / this->perfCounterFreq; - this->lastPerfCounter = curPerfCounter.QuadPart; - - LONGLONG epicsTimeFromCurrentFileTime; - - { - static bool firstMessageWasSent = false; - if ( curFileTime.QuadPart >= epicsEpochInFileTime ) { - epicsTimeFromCurrentFileTime = - ( curFileTime.QuadPart - epicsEpochInFileTime ) * - ET_TICKS_PER_FT_TICK; - firstMessageWasSent = false; - } - else { - /* - * if the system time jumps to before the EPICS epoch - * then latch to the EPICS epoch printing only one - * warning message the first time that the issue is - * detected - */ - if ( ! firstMessageWasSent ) { - errlogPrintf ( - "win32 osdTime.cpp time PLL update detected questionable " - "system date prior to EPICS epoch, epics time will not advance\n" ); - firstMessageWasSent = true; - } - epicsTimeFromCurrentFileTime = 0; - } - } - - delta = epicsTimeFromCurrentFileTime - this->epicsTimeLast; - if ( delta > EPICS_TIME_TICKS_PER_SEC || delta < -EPICS_TIME_TICKS_PER_SEC ) { - // When there is an abrupt shift in the current computed time vs - // the time derived from the current file time then someone has - // probably adjusted the real time clock and the best reaction - // is to just assume the new time base - this->epicsTimeLast = epicsTimeFromCurrentFileTime; - this->perfCounterFreq = this->perfCounterFreqPLL; - debugPrintf ( ( "currentTime: did someone adjust the date?\n" ) ); - } - else { - // update the effective performance counter frequency that will bring - // our calculated time base in syncy with file time one second from now. - this->perfCounterFreq = - ( EPICS_TIME_TICKS_PER_SEC * this->perfCounterFreqPLL ) - / ( delta + EPICS_TIME_TICKS_PER_SEC ); - - // limit effective performance counter frequency rate of change - LONGLONG lowLimit = this->perfCounterFreqPLL - bound; - if ( this->perfCounterFreq < lowLimit ) { - debugPrintf ( ( "currentTime: out of bounds low freq excursion %d\n", - static_cast ( lowLimit - this->perfCounterFreq ) ) ); - this->perfCounterFreq = lowLimit; - } - else { - LONGLONG highLimit = this->perfCounterFreqPLL + bound; - if ( this->perfCounterFreq > highLimit ) { - debugPrintf ( ( "currentTime: out of bounds high freq excursion %d\n", - static_cast ( this->perfCounterFreq - highLimit ) ) ); - this->perfCounterFreq = highLimit; - } - } - -# if defined ( DEBUG ) - LARGE_INTEGER sysFreq; - QueryPerformanceFrequency ( & sysFreq ); - double freqDiff = static_cast - ( this->perfCounterFreq - sysFreq.QuadPart ); - freqDiff /= sysFreq.QuadPart; - freqDiff *= 100.0; - double freqEstDiff = static_cast - ( this->perfCounterFreqPLL - sysFreq.QuadPart ); - freqEstDiff /= sysFreq.QuadPart; - freqEstDiff *= 100.0; - debugPrintf ( ( "currentTime: freq delta %f %% freq est " - "delta %f %% time delta %f sec\n", - freqDiff, - freqEstDiff, - static_cast < double > ( delta ) / - EPICS_TIME_TICKS_PER_SEC ) ); -# endif - } - - LeaveCriticalSection ( & this->mutex ); -} - -static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ) -{ - currentTime * pCT = - reinterpret_cast < currentTime * > ( pCurrentTimeIn ); - setThreadName ( pCT->threadId, "EPICS Time PLL" ); - while ( ! pCT->threadShutdownCmd ) { - Sleep ( currentTime :: pllDelay * 1000 /* mS */ ); - pCT->updatePLL (); - } - EnterCriticalSection ( & pCT->mutex ); - pCT->threadHasExited = true; - LeaveCriticalSection ( & pCT->mutex ); - return 1; -} - -epicsTime::operator FILETIME () const -{ - LARGE_INTEGER ftTicks; - ftTicks.QuadPart = ( this->secPastEpoch * FILE_TIME_TICKS_PER_SEC ) + - ( this->nSec / ET_TICKS_PER_FT_TICK ); - ftTicks.QuadPart += epicsEpochInFileTime; - FILETIME ts; - ts.dwLowDateTime = ftTicks.LowPart; - ts.dwHighDateTime = ftTicks.HighPart; - return ts; -} - -epicsTime::epicsTime ( const FILETIME & ts ) -{ - LARGE_INTEGER lift; - lift.LowPart = ts.dwLowDateTime; - lift.HighPart = ts.dwHighDateTime; - if ( lift.QuadPart > epicsEpochInFileTime ) { - LONGLONG fileTimeTicksSinceEpochEPICS = - lift.QuadPart - epicsEpochInFileTime; - this->secPastEpoch = static_cast < epicsUInt32 > - ( fileTimeTicksSinceEpochEPICS / FILE_TIME_TICKS_PER_SEC ); - this->nSec = static_cast < epicsUInt32 > - ( ( fileTimeTicksSinceEpochEPICS % FILE_TIME_TICKS_PER_SEC ) * - ET_TICKS_PER_FT_TICK ); - } - else { - this->secPastEpoch = 0; - this->nSec = 0; - } -} - -epicsTime & epicsTime::operator = ( const FILETIME & rhs ) -{ - *this = epicsTime ( rhs ); - return *this; -} diff --git a/src/libCom/osi/os/WIN32/osdTime.h b/src/libCom/osi/os/WIN32/osdTime.h deleted file mode 100644 index 35848f6dc..000000000 --- a/src/libCom/osi/os/WIN32/osdTime.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#ifndef INC_osdTime_H -#define INC_osdTime_H - -/* MinGW only has a snippet time.h not protected against multiple inclusion */ -#if defined(__struct_timespec_defined) -#define _TIMESPEC_DEFINED 1 -#endif - -#if ! defined(_MINGW) || ! defined(_TIMESPEC_DEFINED) -# if _MSC_VER >= 1900 -# include -# else - -#define __struct_timespec_defined 1 -#define _TIMESPEC_DEFINED 1 -struct timespec { - time_t tv_sec; /* seconds since some epoch */ - long tv_nsec; /* nanoseconds within the second */ -}; - -# endif /* _MSC_VER */ -#endif /* ! defined(_MINGW) || ! defined(_TIMESPEC_DEFINED) */ - -#endif /* ifndef INC_osdTime_H */ - diff --git a/src/libCom/osi/os/WIN32/osdWireConfig.h b/src/libCom/osi/os/WIN32/osdWireConfig.h deleted file mode 100644 index 1715786e0..000000000 --- a/src/libCom/osi/os/WIN32/osdWireConfig.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * WIN32 version of - * osdWireConfig.h - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireConfig_h -#define osdWireConfig_h - -/* for now, assume that win32 runs only on generic little endian */ -#define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -#define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER - -#endif /* ifdef osdWireConfig_h */ diff --git a/src/libCom/osi/os/WIN32/osiFileName.h b/src/libCom/osi/os/WIN32/osiFileName.h deleted file mode 100644 index 6ff0308b2..000000000 --- a/src/libCom/osi/os/WIN32/osiFileName.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#define OSI_PATH_LIST_SEPARATOR ";" -#define OSI_PATH_SEPARATOR "\\" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/WIN32/osiUnistd.h b/src/libCom/osi/os/WIN32/osiUnistd.h deleted file mode 100644 index 3f34e74cc..000000000 --- a/src/libCom/osi/os/WIN32/osiUnistd.h +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include diff --git a/src/libCom/osi/os/WIN32/setThreadName.cpp b/src/libCom/osi/os/WIN32/setThreadName.cpp deleted file mode 100644 index 49663c8af..000000000 --- a/src/libCom/osi/os/WIN32/setThreadName.cpp +++ /dev/null @@ -1,51 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define VC_EXTRALEAN -#define STRICT -#if _WIN64 -# define _WIN32_WINNT 0x400 /* defining this drops support for W95 */ -#endif -#include - -/* - * this was copied directly from an example in visual c++ 7 documentation, - * It uses visual C++ specific keywords for exception handling, but is - * probably only useful when using the visual c++ or later debugger. - * - * Usage: setThreadName (-1, "MainThread"); - */ -extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ) -{ -#if _MSC_VER >= 1300 && defined ( _DEBUG ) - typedef struct tagTHREADNAME_INFO - { - DWORD dwType; // must be 0x1000 - LPCSTR szName; // pointer to name (in user addr space) - DWORD dwThreadID; // thread ID (-1=caller thread) - DWORD dwFlags; // reserved for future use, must be zero - } THREADNAME_INFO; - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = szThreadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; - - __try - { - RaiseException( 0x406D1388, 0, - sizeof(info)/sizeof(DWORD), (const ULONG_PTR*)&info ); - } - __except(EXCEPTION_CONTINUE_EXECUTION) - { - } -#endif -} diff --git a/src/libCom/osi/os/WIN32/systemCallIntMech.cpp b/src/libCom/osi/os/WIN32/systemCallIntMech.cpp deleted file mode 100644 index 5e13299c0..000000000 --- a/src/libCom/osi/os/WIN32/systemCallIntMech.cpp +++ /dev/null @@ -1,22 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" - -enum epicsSocketSystemCallInterruptMechanismQueryInfo - epicsSocketSystemCallInterruptMechanismQuery () -{ - return esscimqi_socketCloseRequired; -} diff --git a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c b/src/libCom/osi/os/cygwin32/devLibVMEOSD.c deleted file mode 100644 index 53cbd58cd..000000000 --- a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "devLibVME.h" - -epicsShareDef devLibVME *pdevLibVME = NULL; diff --git a/src/libCom/osi/os/cygwin32/osdSock.h b/src/libCom/osi/os/cygwin32/osdSock.h deleted file mode 100644 index d642cad44..000000000 --- a/src/libCom/osi/os/cygwin32/osdSock.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * cygwin32 specific include - */ - - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef int osiSocklen_t; -#define FD_IN_FDSET(FD) ((FD)=0) -#ifndef SHUT_RD -#define SHUT_RD 0 -#endif -#ifndef SHUT_WR -#define SHUT_WR 1 -#endif -#ifndef SHUT_RDWR -# define SHUT_RDWR 2 -#endif - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EACCES EACCES -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE -#define SOCK_EMFILE EMFILE -#define SOCK_SHUTDOWN ESHUTDOWN -#define SOCK_ENOTSOCK ENOTSOCK -#define SOCK_EBADF EBADF - -#define ifreq_size(pifreq) (sizeof(pifreq->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp b/src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp deleted file mode 100644 index d441d7511..000000000 --- a/src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp +++ /dev/null @@ -1,44 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -/* - * Note: WINSOCK appears to assign a different functionality for - * SO_REUSEADDR compared to other OS. With WINSOCK SO_REUSEADDR indicates - * that simultaneously servers can bind to the same TCP port on the same host! - * Also, servers are always enabled to reuse a port immediately after - * they exit ( even if SO_REUSEADDR isnt set ). - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ -} - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} diff --git a/src/libCom/osi/os/cygwin32/osdStrtod.h b/src/libCom/osi/os/cygwin32/osdStrtod.h deleted file mode 100644 index b5fda31c3..000000000 --- a/src/libCom/osi/os/cygwin32/osdStrtod.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header fragment is intended to be included as part of epicsString.h - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epicsStrtod() for systems with broken strtod() routine - */ -epicsShareFunc double epicsStrtod(const char *str, char **endp); - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/cygwin32/osiFileName.h b/src/libCom/osi/os/cygwin32/osiFileName.h deleted file mode 100644 index 6d7fd6eb9..000000000 --- a/src/libCom/osi/os/cygwin32/osiFileName.h +++ /dev/null @@ -1,20 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - */ -#ifndef osiFileNameH -#define osiFileNameH - -#define OSI_PATH_LIST_SEPARATOR ";" -#define OSI_PATH_SEPARATOR "\\" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp b/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp deleted file mode 100644 index 9c0df3293..000000000 --- a/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - */ - -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" - -enum epicsSocketSystemCallInterruptMechanismQueryInfo - epicsSocketSystemCallInterruptMechanismQuery () -{ -#if (CYGWIN_VERSION_DLL_MAJOR == 1007) && (CYGWIN_VERSION_DLL_MINOR < 15) - // Behaviour changed in early Cygwin 1.7 releases, reverted later. - return esscimqi_socketCloseRequired; -#else - return esscimqi_socketBothShutdownRequired; -#endif -} diff --git a/src/libCom/osi/os/default/devLibVMEOSD.c b/src/libCom/osi/os/default/devLibVMEOSD.c deleted file mode 100644 index b8b1d5047..000000000 --- a/src/libCom/osi/os/default/devLibVMEOSD.c +++ /dev/null @@ -1,15 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "devLibVME.h" - -/* This file must contain no definitions other than the following: */ - -epicsShareDef devLibVME *pdevLibVME; diff --git a/src/libCom/osi/os/default/epicsAtomicOSD.cpp b/src/libCom/osi/os/default/epicsAtomicOSD.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/libCom/osi/os/default/epicsGetopt.h b/src/libCom/osi/os/default/epicsGetopt.h deleted file mode 100644 index 4bcc962cb..000000000 --- a/src/libCom/osi/os/default/epicsGetopt.h +++ /dev/null @@ -1,17 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Berliner Elektronenspeicherringgesellschaft fuer -* Synchrotronstrahlung. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef _EPICS_GETOPT_H -#define _EPICS_GETOPT_H - -#include - -#endif /* _EPICS_GETOPT_H */ diff --git a/src/libCom/osi/os/default/epicsMMIO.h b/src/libCom/osi/os/default/epicsMMIO.h deleted file mode 100644 index 79040932a..000000000 --- a/src/libCom/osi/os/default/epicsMMIO.h +++ /dev/null @@ -1,2 +0,0 @@ - -#include "epicsMMIODef.h" diff --git a/src/libCom/osi/os/default/epicsMMIODef.h b/src/libCom/osi/os/default/epicsMMIODef.h deleted file mode 100644 index dc4bb4cb7..000000000 --- a/src/libCom/osi/os/default/epicsMMIODef.h +++ /dev/null @@ -1,274 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Michael Davidsaver - */ - -#ifndef EPICSMMIODEF_H -#define EPICSMMIODEF_H - -#include -#include -#include -#include - -#ifdef __cplusplus -# ifndef INLINE -# define INLINE inline -# endif -#endif - -/** @ingroup mmio - *@{ - */ - -/** @brief Read a single byte. - */ -static EPICS_ALWAYS_INLINE -epicsUInt8 -ioread8(volatile void* addr) -{ - return *(volatile epicsUInt8*)(addr); -} - -/** @brief Write a single byte. - */ -static EPICS_ALWAYS_INLINE -void -iowrite8(volatile void* addr, epicsUInt8 val) -{ - *(volatile epicsUInt8*)(addr) = val; -} - -/** @brief Read two bytes in host order. - * Not byte swapping - */ -static EPICS_ALWAYS_INLINE -epicsUInt16 -nat_ioread16(volatile void* addr) -{ - return *(volatile epicsUInt16*)(addr); -} - -/** @brief Write two byte in host order. - * Not byte swapping - */ -static EPICS_ALWAYS_INLINE -void -nat_iowrite16(volatile void* addr, epicsUInt16 val) -{ - *(volatile epicsUInt16*)(addr) = val; -} - -/** @brief Read four bytes in host order. - * Not byte swapping - */ -static EPICS_ALWAYS_INLINE -epicsUInt32 -nat_ioread32(volatile void* addr) -{ - return *(volatile epicsUInt32*)(addr); -} - -/** @brief Write four byte in host order. - * Not byte swapping - */ -static EPICS_ALWAYS_INLINE -void -nat_iowrite32(volatile void* addr, epicsUInt32 val) -{ - *(volatile epicsUInt32*)(addr) = val; -} - -#if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - -/** @ingroup mmio - *@{ - */ - -static EPICS_ALWAYS_INLINE -epicsUInt16 -bswap16(epicsUInt16 value) -{ - return (((epicsUInt16)(value) & 0x00ff) << 8) | - (((epicsUInt16)(value) & 0xff00) >> 8); -} - -static EPICS_ALWAYS_INLINE -epicsUInt32 -bswap32(epicsUInt32 value) -{ - return (((epicsUInt32)(value) & 0x000000ff) << 24) | - (((epicsUInt32)(value) & 0x0000ff00) << 8) | - (((epicsUInt32)(value) & 0x00ff0000) >> 8) | - (((epicsUInt32)(value) & 0xff000000) >> 24); -} - -# define be_ioread16(A) nat_ioread16(A) -# define be_ioread32(A) nat_ioread32(A) -# define be_iowrite16(A,D) nat_iowrite16(A,D) -# define be_iowrite32(A,D) nat_iowrite32(A,D) - -# define le_ioread16(A) bswap16(nat_ioread16(A)) -# define le_ioread32(A) bswap32(nat_ioread32(A)) -# define le_iowrite16(A,D) nat_iowrite16(A,bswap16(D)) -# define le_iowrite32(A,D) nat_iowrite32(A,bswap32(D)) - -/** @} */ - -#elif EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - -/* Get hton[sl] declarations: */ -#include - -/** @ingroup mmio - *@{ - */ - -/* hton* is optimized or a builtin for most compilers - * so use it if possible - */ -#define bswap16(v) htons(v) -#define bswap32(v) htonl(v) - -# define be_ioread16(A) bswap16(nat_ioread16(A)) -# define be_ioread32(A) bswap32(nat_ioread32(A)) -# define be_iowrite16(A,D) nat_iowrite16(A,bswap16(D)) -# define be_iowrite32(A,D) nat_iowrite32(A,bswap32(D)) - -# define le_ioread16(A) nat_ioread16(A) -# define le_ioread32(A) nat_ioread32(A) -# define le_iowrite16(A,D) nat_iowrite16(A,D) -# define le_iowrite32(A,D) nat_iowrite32(A,D) - -/** @} */ - -#else -# error Unable to determine native byte order -#endif - -/** @def bswap16 - * @brief Unconditional two byte swap - */ -/** @def bswap32 - * @brief Unconditional four byte swap - */ -/** @def be_ioread16 - * @brief Read two byte in big endian order. - */ -/** @def be_iowrite16 - * @brief Write two byte in big endian order. - */ -/** @def be_ioread32 - * @brief Read four byte in big endian order. - */ -/** @def be_iowrite32 - * @brief Write four byte in big endian order. - */ -/** @def le_ioread16 - * @brief Read two byte in little endian order. - */ -/** @def le_iowrite16 - * @brief Write two byte in little endian order. - */ -/** @def le_ioread32 - * @brief Read four byte in little endian order. - */ -/** @def le_iowrite32 - * @brief Write four byte in little endian order. - */ - -/** @ingroup mmio - *@{ - */ - -/** @brief Explicit read memory barrier - * Prevents reordering of reads around it. - */ -#define rbarr() do{}while(0) -/** @brief Explicit write memory barrier - * Prevents reordering of writes around it. - */ -#define wbarr() do{}while(0) -/** @brief Explicit read/write memory barrier - * Prevents reordering of reads or writes around it. - */ -#define rwbarr() do{}while(0) - -/** @} */ - -/** @defgroup mmio Memory Mapped I/O - * - * Safe operations on I/O memory. - * - *This files defines a set of macros for access to Memory Mapped I/O - * - *They are named T_ioread# and T_iowrite# where # can be 8, 16, or 32. - *'T' can either be 'le', 'be', or 'nat' (except ioread8 and - *iowrite8). - * - *The macros defined use OS specific extensions (when available) - *to ensure the following. - * - *@li Width. A 16 bit operation will not be broken into two 8 bit operations, - * or one half of a 32 bit operation. - * - *@li Order. Writes to two different registers will not be reordered. - * This only applies to MMIO operations, not between MMIO and - * normal memory operations. - * - *PCI access should use either 'le_' or 'be_' as determined by the - *device byte order. - * - *VME access should always use 'nat_'. If the device byte order is - *little endian then an explicit swap is required. - * - *@section mmioex Examples: - * - *@subsection mmioexbe Big endian device: - * - *@b PCI - * - @code - be_iowrite16(base+off, 14); - var = be_ioread16(base+off); - @endcode - * - *@b VME - * - @code - nat_iowrite16(base+off, 14); - var = nat_ioread16(base+off); - @endcode - * - *@subsection mmioexle Little endian device - * - *@b PCI - @code - le_iowrite16(base+off, 14); - var = le_ioread16(base+off); - @endcode - *@b VME - @code - nat_iowrite16(base+off, bswap16(14)); - var = bswap16(nat_iowrite16(base+off)); - @endcode - *This difference arises because VME bridges implement hardware byte - *swapping on little endian systems, while PCI bridges do not. - *Software accessing PCI devices must know if byte swapping is required. - *This conditional swap is implemented by the 'be_' and 'le_' macros. - * - *This is a fundamental difference between PCI and VME. - * - *Software accessing PCI @b must do conditional swapping. - * - *Software accessing VME must @b not do conditional swapping. - * - *@note All read and write operations have an implicit read or write barrier. - */ - -#endif /* EPICSMMIODEF_H */ diff --git a/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp b/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp deleted file mode 100644 index 3cbfce60d..000000000 --- a/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdSock.c */ -/* - * Author: Jeff Hill - * Date: 04-05-94 - * - */ - -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" - -/* - * epicsSocketConvertErrorToString() - */ -void epicsSocketConvertErrorToString ( - char * pBuf, unsigned bufSize, int theSockError ) -{ - if ( bufSize ) { - strncpy ( pBuf, strerror ( theSockError ), bufSize ); - pBuf[bufSize-1] = '\0'; - } -} - -/* - * epicsSocketConvertErrnoToString() - */ -void epicsSocketConvertErrnoToString ( - char * pBuf, unsigned bufSize ) -{ - epicsSocketConvertErrorToString ( pBuf, bufSize, SOCKERRNO ); -} diff --git a/src/libCom/osi/os/default/gnuReadline.c b/src/libCom/osi/os/default/gnuReadline.c deleted file mode 100644 index ae646a53e..000000000 --- a/src/libCom/osi/os/default/gnuReadline.c +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ - -/* - * This file is included by epicsReadline.c which has already included the - * headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h - */ - -#include -#include - -#include "epicsExit.h" - -static struct osdContext { - char dummy; /* Required for older compilers */ -} present; - -static enum {rlNone, rlIdle, rlBusy} rlState = rlNone; - -static void rlExit(void *dummy) { - if (rlState == rlBusy) - rl_cleanup_after_signal(); -} - - -/* - * Create a command-line context - */ -static void -osdReadlineBegin(struct readlineContext *context) -{ - if (rlState == rlNone) { - epicsAtExit(rlExit, NULL); - rlState = rlIdle; - } - - context->osd = &present; - if (context->in == NULL) { - long i = 50; - - envGetLongConfigParam(&IOCSH_HISTSIZE, &i); - if (i < 0) - i = 0; - stifle_history(i); - rl_bind_key('\t', rl_insert); - } -} - -/* - * Read a line of input - */ -static char * -osdReadline (const char *prompt, struct readlineContext *context) -{ - char *line; - - free(context->line); - context->line = NULL; - if (context->in == NULL) { - rlState = rlBusy; - line = readline (prompt); - rlState = rlIdle; - } - else { - int c; /* char is unsigned on some archs; EOF is -ve */ - int linelen = 0; - int linesize = 50; - - line = malloc(linesize); - if (line == NULL) { - printf("Out of memory!\n"); - return NULL; - } - if (prompt) { - fputs(prompt, stdout); - fflush(stdout); - } - while ((c = getc(context->in)) != '\n') { - if (c == EOF) { - free(line); - line = NULL; - break; - } - if ((linelen + 1) >= linesize) { - char *cp; - - linesize += 50; - cp = (char *)realloc(line, linesize); - if (cp == NULL) { - printf ("Out of memory!\n"); - free(line); - line = NULL; - break; - } - line = cp; - } - line[linelen++] = c; - } - if (line) - line[linelen] = '\0'; - } - context->line = line; - if (line && *line) - add_history(line); - return line; -} - -/* - * Destroy a command-line context - */ -static void -osdReadlineEnd (struct readlineContext *context) -{ - if (context->osd) { - free(context->line); - } -} - diff --git a/src/libCom/osi/os/default/osdAssert.c b/src/libCom/osi/os/default/osdAssert.c deleted file mode 100644 index 14d548c3d..000000000 --- a/src/libCom/osi/os/default/osdAssert.c +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeffrey Hill - * Date: 02-27-95 - */ - -#define epicsExportSharedSymbols -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsVersion.h" -#include "epicsAssert.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "cantProceed.h" -#include "epicsStackTrace.h" - - -void epicsAssert (const char *pFile, const unsigned line, - const char *pExp, const char *pAuthorName) -{ - epicsTimeStamp current; - - errlogPrintf("\n\n\n" - "A call to 'assert(%s)'\n" - " by thread '%s' failed in %s line %u.\n", - pExp, epicsThreadGetNameSelf(), pFile, line); - - epicsStackTrace(); - - errlogPrintf("EPICS Release %s.\n", epicsReleaseVersion); - - if (epicsTimeGetCurrent(¤t) == 0) { - char date[64]; - - epicsTimeToStrftime(date, sizeof(date), - "%Y-%m-%d %H:%M:%S.%f %Z", ¤t); - errlogPrintf("Local time is %s\n", date); - } - - if (!pAuthorName) { - pAuthorName = "the author"; - } - errlogPrintf("Please E-mail this message to %s or to tech-talk@aps.anl.gov\n", - pAuthorName); - - errlogPrintf("Calling epicsThreadSuspendSelf()\n"); - epicsThreadSuspendSelf (); -} diff --git a/src/libCom/osi/os/default/osdBackTrace.cpp b/src/libCom/osi/os/default/osdBackTrace.cpp deleted file mode 100644 index e1f96c033..000000000 --- a/src/libCom/osi/os/default/osdBackTrace.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" - -int epicsBackTrace(void **buf, int buf_sz) -{ - return -1; -} diff --git a/src/libCom/osi/os/default/osdEnv.c b/src/libCom/osi/os/default/osdEnv.c deleted file mode 100644 index 682bcc934..000000000 --- a/src/libCom/osi/os/default/osdEnv.c +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEnv.c */ -/* - * Author: Eric Norum - * Date: May 7, 2001 - * - * Routines to modify/display environment variables and EPICS parameters - * - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "errlog.h" -#include "cantProceed.h" -#include "envDefs.h" -#include "osiUnistd.h" -#include "epicsFindSymbol.h" -#include "iocsh.h" - -/* - * Set the value of an environment variable - * Leaks memory, but the assumption is that this routine won't be - * called often enough for the leak to be a problem. - */ -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value) -{ - char *cp; - - iocshEnvClear(name); - - cp = mallocMustSucceed (strlen (name) + strlen (value) + 2, "epicsEnvSet"); - strcpy (cp, name); - strcat (cp, "="); - strcat (cp, value); - if (putenv (cp) < 0) { - errPrintf( - -1L, - __FILE__, - __LINE__, - "Failed to set environment parameter \"%s\" to \"%s\": %s\n", - name, - value, - strerror (errno)); - free (cp); - } -} - -/* - * Show the value of the specified, or all, environment variables - */ -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name) -{ - if (name == NULL) { - extern char **environ; - char **sp; - - for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) - printf ("%s\n", *sp); - } - else { - const char *cp = getenv (name); - if (cp == NULL) - printf ("%s is not an environment variable.\n", name); - else - printf ("%s=%s\n", name, cp); - } -} diff --git a/src/libCom/osi/os/default/osdFindAddr.c b/src/libCom/osi/os/default/osdFindAddr.c deleted file mode 100644 index 582dd5442..000000000 --- a/src/libCom/osi/os/default/osdFindAddr.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" -#include "epicsStackTrace.h" - -int epicsFindAddr(void *addr, epicsSymbol *sym_p) -{ - sym_p->f_nam = 0; - sym_p->s_nam = 0; - sym_p->s_val = 0; - return -1; -} - -int epicsFindAddrGetFeatures(void) -{ - return 0; -} diff --git a/src/libCom/osi/os/default/osdFindSymbol.c b/src/libCom/osi/os/default/osdFindSymbol.c deleted file mode 100644 index 9d9a8878c..000000000 --- a/src/libCom/osi/os/default/osdFindSymbol.c +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/default/osdFindSymbol.c */ - -#define epicsExportSharedSymbols -#include "epicsFindSymbol.h" - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - return 0; -} - -epicsShareFunc const char *epicsLoadError(void) -{ - return "epicsLoadLibrary not implemented"; -} - -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name) -{ - return 0; -} diff --git a/src/libCom/osi/os/default/osdInterrupt.c b/src/libCom/osi/os/default/osdInterrupt.c deleted file mode 100644 index 91c5c5681..000000000 --- a/src/libCom/osi/os/default/osdInterrupt.c +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/default/osdInterrupt.c */ - -/* Author: Marty Kraimer Date: 15JUL99 */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "errlog.h" -#include "epicsInterrupt.h" - - -static epicsMutexId globalLock = NULL; -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - -static void initOnce(void *junk) -{ - globalLock = epicsMutexMustCreate(); -} - -epicsShareFunc int epicsInterruptLock() -{ - epicsThreadOnce(&onceId, initOnce, NULL); - epicsMutexMustLock(globalLock); - return 0; -} - -epicsShareFunc void epicsInterruptUnlock(int key) -{ - if (!globalLock) - cantProceed("epicsInterruptUnlock called before epicsInterruptLock\n"); - epicsMutexUnlock(globalLock); -} - -epicsShareFunc int epicsInterruptIsInterruptContext() -{ - return 0; -} - -epicsShareFunc void epicsInterruptContextMessage(const char *message) -{ - errlogPrintf("%s", message); -} - diff --git a/src/libCom/osi/os/default/osdInterrupt.h b/src/libCom/osi/os/default/osdInterrupt.h deleted file mode 100644 index 5559d6280..000000000 --- a/src/libCom/osi/os/default/osdInterrupt.h +++ /dev/null @@ -1,15 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef osdInterrupth -#define osdInterrupth - -#endif /* osdInterrupth */ - diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/libCom/osi/os/default/osdMessageQueue.cpp deleted file mode 100644 index c86d8cc2b..000000000 --- a/src/libCom/osi/os/default/osdMessageQueue.cpp +++ /dev/null @@ -1,408 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -#include -#include - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMessageQueue.h" -#include -#include -#include -#include - -/* - * Event cache - */ -struct eventNode { - ELLNODE link; - epicsEventId event; -}; - -/* - * List of threads waiting to send or receive a message - */ -struct threadNode { - ELLNODE link; - struct eventNode *evp; - void *buf; - unsigned int size; - volatile bool eventSent; -}; - -/* - * Message info - */ -struct epicsMessageQueueOSD { - ELLLIST sendQueue; - ELLLIST receiveQueue; - ELLLIST eventFreeList; - int numberOfSendersWaiting; - - epicsMutexId mutex; - unsigned long capacity; - unsigned long maxMessageSize; - - unsigned long *buf; - char *firstMessageSlot; - char *lastMessageSlot; - volatile char *inPtr; - volatile char *outPtr; - unsigned long slotSize; - - bool full; -}; - -epicsShareFunc epicsMessageQueueId epicsShareAPI epicsMessageQueueCreate( - unsigned int capacity, - unsigned int maxMessageSize) -{ - epicsMessageQueueId pmsg; - unsigned int slotBytes, slotLongs; - - if(capacity == 0) - return NULL; - - pmsg = (epicsMessageQueueId)calloc(1, sizeof(*pmsg)); - if(!pmsg) - return NULL; - - pmsg->capacity = capacity; - pmsg->maxMessageSize = maxMessageSize; - slotLongs = 1 + ((maxMessageSize + sizeof(unsigned long) - 1) / sizeof(unsigned long)); - slotBytes = slotLongs * sizeof(unsigned long); - - pmsg->mutex = epicsMutexCreate(); - pmsg->buf = (unsigned long*)calloc(pmsg->capacity, slotBytes); - if(!pmsg->buf || !pmsg->mutex) { - if(pmsg->mutex) - epicsMutexDestroy(pmsg->mutex); - free(pmsg->buf); - free(pmsg); - return NULL; - } - - pmsg->inPtr = pmsg->outPtr = pmsg->firstMessageSlot = (char *)&pmsg->buf[0]; - pmsg->lastMessageSlot = (char *)&pmsg->buf[(capacity - 1) * slotLongs]; - pmsg->full = false; - pmsg->slotSize = slotBytes; - - ellInit(&pmsg->sendQueue); - ellInit(&pmsg->receiveQueue); - ellInit(&pmsg->eventFreeList); - return pmsg; -} - -static void -freeEventNode(struct eventNode *enode) -{ - epicsEventDestroy(enode->event); - free(enode); -} - -epicsShareFunc void epicsShareAPI -epicsMessageQueueDestroy(epicsMessageQueueId pmsg) -{ - struct eventNode *evp; - - while ((evp = reinterpret_cast < struct eventNode * > - ( ellGet(&pmsg->eventFreeList) ) ) != NULL) { - freeEventNode(evp); - } - epicsMutexDestroy(pmsg->mutex); - free(pmsg->buf); - free(pmsg); -} - -static struct eventNode * -getEventNode(epicsMessageQueueId pmsg) -{ - struct eventNode *evp; - - evp = reinterpret_cast < struct eventNode * > ( ellGet(&pmsg->eventFreeList) ); - if (evp == NULL) { - evp = (struct eventNode *) calloc(1, sizeof(*evp)); - if (evp) { - evp->event = epicsEventCreate(epicsEventEmpty); - if (evp->event == NULL) { - free(evp); - return NULL; - } - } - } - return evp; -} - -static int -mySend(epicsMessageQueueId pmsg, void *message, unsigned int size, - double timeout) -{ - char *myInPtr, *nextPtr; - struct threadNode *pthr; - - if(size > pmsg->maxMessageSize) - return -1; - - /* - * See if message can be sent - */ - epicsMutexMustLock(pmsg->mutex); - - if ((pmsg->numberOfSendersWaiting > 0) - || (pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL))) { - /* - * Return if not allowed to wait - */ - if (timeout == 0) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - - /* - * Wait - */ - struct threadNode threadNode; - threadNode.evp = getEventNode(pmsg); - threadNode.eventSent = false; - if (!threadNode.evp) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - - ellAdd(&pmsg->sendQueue, &threadNode.link); - pmsg->numberOfSendersWaiting++; - - epicsMutexUnlock(pmsg->mutex); - - epicsEventStatus status; - if (timeout > 0) - status = epicsEventWaitWithTimeout(threadNode.evp->event, timeout); - else - status = epicsEventWait(threadNode.evp->event); - - epicsMutexMustLock(pmsg->mutex); - - if(!threadNode.eventSent) - ellDelete(&pmsg->sendQueue, &threadNode.link); - pmsg->numberOfSendersWaiting--; - - ellAdd(&pmsg->eventFreeList, &threadNode.evp->link); - - if ((pmsg->full && (ellFirst(&pmsg->receiveQueue) == NULL)) || - status != epicsEventOK) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - } - - /* - * Copy message to waiting receiver - */ - if ((pthr = reinterpret_cast < struct threadNode * > - ( ellGet(&pmsg->receiveQueue) ) ) != NULL) { - if(size <= pthr->size) - memcpy(pthr->buf, message, size); - pthr->size = size; - pthr->eventSent = true; - epicsEventSignal(pthr->evp->event); - epicsMutexUnlock(pmsg->mutex); - return 0; - } - - /* - * Copy to queue - */ - myInPtr = (char *)pmsg->inPtr; - if (myInPtr == pmsg->lastMessageSlot) - nextPtr = pmsg->firstMessageSlot; - else - nextPtr = myInPtr + pmsg->slotSize; - if (nextPtr == (char *)pmsg->outPtr) - pmsg->full = true; - *(volatile unsigned long *)myInPtr = size; - memcpy((unsigned long *)myInPtr + 1, message, size); - pmsg->inPtr = nextPtr; - epicsMutexUnlock(pmsg->mutex); - return 0; -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueTrySend(epicsMessageQueueId pmsg, void *message, - unsigned int size) -{ - return mySend(pmsg, message, size, 0); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueSend(epicsMessageQueueId pmsg, void *message, - unsigned int size) -{ - return mySend(pmsg, message, size, -1); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueSendWithTimeout(epicsMessageQueueId pmsg, void *message, - unsigned int size, double timeout) -{ - return mySend(pmsg, message, size, timeout); -} - -static int -myReceive(epicsMessageQueueId pmsg, void *message, unsigned int size, - double timeout) -{ - char *myOutPtr; - unsigned long l; - struct threadNode *pthr; - - /* - * If there's a message on the queue, copy it - */ - epicsMutexMustLock(pmsg->mutex); - - myOutPtr = (char *)pmsg->outPtr; - if ((myOutPtr != pmsg->inPtr) || pmsg->full) { - int ret; - l = *(unsigned long *)myOutPtr; - if (l <= size) { - memcpy(message, (unsigned long *)myOutPtr + 1, l); - ret = l; - } - else { - ret = -1; - } - if (myOutPtr == pmsg->lastMessageSlot) - pmsg->outPtr = pmsg->firstMessageSlot; - else - pmsg->outPtr += pmsg->slotSize; - pmsg->full = false; - - /* - * Wake up the oldest task waiting to send - */ - if ((pthr = reinterpret_cast < struct threadNode * > - ( ellGet(&pmsg->sendQueue) ) ) != NULL) { - pthr->eventSent = true; - epicsEventSignal(pthr->evp->event); - } - epicsMutexUnlock(pmsg->mutex); - return ret; - } - - /* - * Return if not allowed to wait - */ - if (timeout == 0) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - - /* - * Wake up the oldest task waiting to send - */ - if ((pthr = reinterpret_cast < struct threadNode * > - ( ellGet(&pmsg->sendQueue) ) ) != NULL) { - pthr->eventSent = true; - epicsEventSignal(pthr->evp->event); - } - - /* - * Wait for message to arrive - */ - struct threadNode threadNode; - threadNode.evp = getEventNode(pmsg); - threadNode.buf = message; - threadNode.size = size; - threadNode.eventSent = false; - - if (!threadNode.evp) { - epicsMutexUnlock(pmsg->mutex); - return -1; - } - - ellAdd(&pmsg->receiveQueue, &threadNode.link); - epicsMutexUnlock(pmsg->mutex); - - epicsEventStatus status; - if (timeout > 0) - status = epicsEventWaitWithTimeout(threadNode.evp->event, timeout); - else - status = epicsEventWait(threadNode.evp->event); - - epicsMutexMustLock(pmsg->mutex); - - if (!threadNode.eventSent) - ellDelete(&pmsg->receiveQueue, &threadNode.link); - ellAdd(&pmsg->eventFreeList, &threadNode.evp->link); - - epicsMutexUnlock(pmsg->mutex); - - if (threadNode.eventSent && (threadNode.size <= size) && - status == epicsEventOK) - return threadNode.size; - return -1; -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueTryReceive(epicsMessageQueueId pmsg, void *message, - unsigned int size) -{ - return myReceive(pmsg, message, size, 0); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueReceive(epicsMessageQueueId pmsg, void *message, - unsigned int size) -{ - return myReceive(pmsg, message, size, -1); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueueReceiveWithTimeout(epicsMessageQueueId pmsg, void *message, - unsigned int size, double timeout) -{ - return myReceive(pmsg, message, size, timeout); -} - -epicsShareFunc int epicsShareAPI -epicsMessageQueuePending(epicsMessageQueueId pmsg) -{ - char *myInPtr, *myOutPtr; - int nmsg; - - epicsMutexMustLock(pmsg->mutex); - myInPtr = (char *)pmsg->inPtr; - myOutPtr = (char *)pmsg->outPtr; - if (pmsg->full) - nmsg = pmsg->capacity; - else if (myInPtr >= myOutPtr) - nmsg = (myInPtr - myOutPtr) / pmsg->slotSize; - else - nmsg = pmsg->capacity - (myOutPtr - myInPtr) / pmsg->slotSize; - epicsMutexUnlock(pmsg->mutex); - return nmsg; -} - -epicsShareFunc void epicsShareAPI -epicsMessageQueueShow(epicsMessageQueueId pmsg, int level) -{ - printf("Message Queue Used:%d Slots:%lu", epicsMessageQueuePending(pmsg), pmsg->capacity); - if (level >= 1) - printf(" Maximum size:%lu", pmsg->maxMessageSize); - printf("\n"); -} diff --git a/src/libCom/osi/os/default/osdMessageQueue.h b/src/libCom/osi/os/default/osdMessageQueue.h deleted file mode 100644 index dabf6a71e..000000000 --- a/src/libCom/osi/os/default/osdMessageQueue.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * Nothing needed for default implementation - */ diff --git a/src/libCom/osi/os/default/osdNetIntf.c b/src/libCom/osi/os/default/osdNetIntf.c deleted file mode 100644 index 62247bc5d..000000000 --- a/src/libCom/osi/os/default/osdNetIntf.c +++ /dev/null @@ -1,352 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - * Date: 04-05-94 - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "epicsAssert.h" -#include "errlog.h" -#include "epicsThread.h" - -#ifdef DEBUG -# define ifDepenDebugPrintf(argsInParen) printf argsInParen -#else -# define ifDepenDebugPrintf(argsInParen) -#endif - -static osiSockAddr osiLocalAddrResult; -static epicsThreadOnceId osiLocalAddrId = EPICS_THREAD_ONCE_INIT; - -/* - * Determine the size of an ifreq structure - * Made difficult by the fact that addresses larger than the structure - * size may be returned from the kernel. - */ -static size_t ifreqSize ( struct ifreq *pifreq ) -{ - size_t size; - - size = ifreq_size ( pifreq ); - if ( size < sizeof ( *pifreq ) ) { - size = sizeof ( *pifreq ); - } - return size; -} - -/* - * Move to the next ifreq structure - */ -static struct ifreq * ifreqNext ( struct ifreq *pifreq ) -{ - struct ifreq *ifr; - - ifr = ( struct ifreq * )( ifreqSize (pifreq) + ( char * ) pifreq ); - ifDepenDebugPrintf( ("ifreqNext() pifreq %p, size 0x%x, ifr 0x%p\n", pifreq, (unsigned)ifreqSize (pifreq), ifr) ); - return ifr; -} - - -/* - * osiSockDiscoverBroadcastAddresses () - */ -epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses - (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr) -{ - static const unsigned nelem = 100; - int status; - struct ifconf ifconf; - struct ifreq *pIfreqList; - struct ifreq *pIfreqListEnd; - struct ifreq *pifreq; - struct ifreq *pnextifreq; - osiSockAddrNode *pNewNode; - - if ( pMatchAddr->sa.sa_family == AF_INET ) { - if ( pMatchAddr->ia.sin_addr.s_addr == htonl (INADDR_LOOPBACK) ) { - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); - if ( pNewNode == NULL ) { - errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" ); - return; - } - pNewNode->addr.ia.sin_family = AF_INET; - pNewNode->addr.ia.sin_port = htons ( 0 ); - pNewNode->addr.ia.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - ellAdd ( pList, &pNewNode->node ); - return; - } - } - - /* - * use pool so that we avoid using too much stack space - * - * nelem is set to the maximum interfaces - * on one machine here - */ - pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pifreq) ); - if (!pIfreqList) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): no memory to complete request\n"); - return; - } - - ifconf.ifc_len = nelem * sizeof(*pifreq); - ifconf.ifc_req = pIfreqList; - status = socket_ioctl (socket, SIOCGIFCONF, &ifconf); - if (status < 0 || ifconf.ifc_len == 0) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): unable to fetch network interface configuration (%d)\n", status); - free (pIfreqList); - return; - } - - pIfreqListEnd = (struct ifreq *) (ifconf.ifc_len + (char *) pIfreqList); - pIfreqListEnd--; - - for ( pifreq = pIfreqList; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) { - uint32_t current_ifreqsize; - - /* - * find the next ifreq - */ - pnextifreq = ifreqNext (pifreq); - - /* determine ifreq size */ - current_ifreqsize = ifreqSize ( pifreq ); - /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */ - memmove(pIfreqList, pifreq, current_ifreqsize); - - ifDepenDebugPrintf (("osiSockDiscoverBroadcastAddresses(): found IFACE: %s len: 0x%x current_ifreqsize: 0x%x \n", - pIfreqList->ifr_name, - (unsigned)ifreq_size(pifreq), - (unsigned)current_ifreqsize)); - - /* - * If its not an internet interface then dont use it - */ - if ( pIfreqList->ifr_addr.sa_family != AF_INET ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): interface \"%s\" was not AF_INET\n", pIfreqList->ifr_name) ); - continue; - } - - /* - * if it isnt a wildcarded interface then look for - * an exact match - */ - if ( pMatchAddr->sa.sa_family != AF_UNSPEC ) { - if ( pMatchAddr->sa.sa_family != AF_INET ) { - continue; - } - if ( pMatchAddr->ia.sin_addr.s_addr != htonl (INADDR_ANY) ) { - struct sockaddr_in *pInetAddr = (struct sockaddr_in *) &pIfreqList->ifr_addr; - if ( pInetAddr->sin_addr.s_addr != pMatchAddr->ia.sin_addr.s_addr ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" didnt match\n", pIfreqList->ifr_name) ); - continue; - } - } - } - - status = socket_ioctl ( socket, SIOCGIFFLAGS, pIfreqList ); - if ( status ) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf flags fetch for \"%s\" failed\n", pIfreqList->ifr_name); - continue; - } - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" flags: %x\n", pIfreqList->ifr_name, pIfreqList->ifr_flags) ); - - /* - * dont bother with interfaces that have been disabled - */ - if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" was down\n", pIfreqList->ifr_name) ); - continue; - } - - /* - * dont use the loop back interface - */ - if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): ignoring loopback interface: \"%s\"\n", pIfreqList->ifr_name) ); - continue; - } - - pNewNode = (osiSockAddrNode *) calloc (1, sizeof (*pNewNode) ); - if ( pNewNode == NULL ) { - errlogPrintf ( "osiSockDiscoverBroadcastAddresses(): no memory available for configuration\n" ); - free ( pIfreqList ); - return; - } - - /* - * If this is an interface that supports - * broadcast fetch the broadcast address. - * - * Otherwise if this is a point to point - * interface then use the destination address. - * - * Otherwise CA will not query through the - * interface. - */ - if ( pIfreqList->ifr_flags & IFF_BROADCAST ) { - osiSockAddr baddr; - status = socket_ioctl (socket, SIOCGIFBRDADDR, pIfreqList); - if ( status ) { - errlogPrintf ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": bcast addr fetch fail\n", pIfreqList->ifr_name); - free ( pNewNode ); - continue; - } - baddr.sa = pIfreqList->ifr_broadaddr; - if (baddr.ia.sin_family==AF_INET && baddr.ia.sin_addr.s_addr != INADDR_ANY) { - pNewNode->addr.sa = pIfreqList->ifr_broadaddr; - ifDepenDebugPrintf ( ( "found broadcast addr = %x\n", ntohl ( baddr.ia.sin_addr.s_addr ) ) ); - } else { - ifDepenDebugPrintf ( ( "Ignoring broadcast addr = \n", ntohl ( baddr.ia.sin_addr.s_addr ) ) ); - free ( pNewNode ); - continue; - } - } -#if defined (IFF_POINTOPOINT) - else if ( pIfreqList->ifr_flags & IFF_POINTOPOINT ) { - status = socket_ioctl ( socket, SIOCGIFDSTADDR, pIfreqList); - if ( status ) { - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\": pt to pt addr fetch fail\n", pIfreqList->ifr_name) ); - free ( pNewNode ); - continue; - } - pNewNode->addr.sa = pIfreqList->ifr_dstaddr; - } -#endif - else { - ifDepenDebugPrintf ( ( "osiSockDiscoverBroadcastAddresses(): net intf \"%s\": not point to point or bcast?\n", pIfreqList->ifr_name ) ); - free ( pNewNode ); - continue; - } - - ifDepenDebugPrintf ( ("osiSockDiscoverBroadcastAddresses(): net intf \"%s\" found\n", pIfreqList->ifr_name) ); - - /* - * LOCK applied externally - */ - ellAdd ( pList, &pNewNode->node ); - } - - free ( pIfreqList ); -} - -/* - * osiLocalAddr () - */ -static void osiLocalAddrOnce (void *raw) -{ - SOCKET *psocket = raw; - const unsigned nelem = 100; - osiSockAddr addr; - int status; - struct ifconf ifconf; - struct ifreq *pIfreqList; - struct ifreq *pifreq; - struct ifreq *pIfreqListEnd; - struct ifreq *pnextifreq; - - memset ( (void *) &addr, '\0', sizeof ( addr ) ); - addr.sa.sa_family = AF_UNSPEC; - - pIfreqList = (struct ifreq *) calloc ( nelem, sizeof(*pIfreqList) ); - if ( ! pIfreqList ) { - errlogPrintf ( "osiLocalAddr(): no memory to complete request\n" ); - goto fail; - } - - ifconf.ifc_len = nelem * sizeof ( *pIfreqList ); - ifconf.ifc_req = pIfreqList; - status = socket_ioctl ( *psocket, SIOCGIFCONF, &ifconf ); - if ( status < 0 || ifconf.ifc_len == 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( - "osiLocalAddr(): SIOCGIFCONF ioctl failed because \"%s\"\n", - sockErrBuf ); - goto fail; - } - - pIfreqListEnd = (struct ifreq *) ( ifconf.ifc_len + (char *) ifconf.ifc_req ); - pIfreqListEnd--; - - for ( pifreq = ifconf.ifc_req; pifreq <= pIfreqListEnd; pifreq = pnextifreq ) { - osiSockAddr addrCpy; - uint32_t current_ifreqsize; - - /* - * find the next if req - */ - pnextifreq = ifreqNext ( pifreq ); - - /* determine ifreq size */ - current_ifreqsize = ifreqSize ( pifreq ); - /* copy current ifreq to aligned bufferspace (to start of pIfreqList buffer) */ - memmove(pIfreqList, pifreq, current_ifreqsize); - - if ( pIfreqList->ifr_addr.sa_family != AF_INET ) { - ifDepenDebugPrintf ( ("osiLocalAddr(): interface %s was not AF_INET\n", pIfreqList->ifr_name) ); - continue; - } - - addrCpy.sa = pIfreqList->ifr_addr; - - status = socket_ioctl ( *psocket, SIOCGIFFLAGS, pIfreqList ); - if ( status < 0 ) { - errlogPrintf ( "osiLocalAddr(): net intf flags fetch for %s failed\n", pIfreqList->ifr_name ); - continue; - } - - if ( ! ( pIfreqList->ifr_flags & IFF_UP ) ) { - ifDepenDebugPrintf ( ("osiLocalAddr(): net intf %s was down\n", pIfreqList->ifr_name) ); - continue; - } - - /* - * dont use the loop back interface - */ - if ( pIfreqList->ifr_flags & IFF_LOOPBACK ) { - ifDepenDebugPrintf ( ("osiLocalAddr(): ignoring loopback interface: %s\n", pIfreqList->ifr_name) ); - continue; - } - - ifDepenDebugPrintf ( ("osiLocalAddr(): net intf %s found\n", pIfreqList->ifr_name) ); - - osiLocalAddrResult = addrCpy; - free ( pIfreqList ); - return; - } - - errlogPrintf ( - "osiLocalAddr(): only loopback found\n"); -fail: - /* fallback to loopback */ - memset ( (void *) &addr, '\0', sizeof ( addr ) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - osiLocalAddrResult = addr; - - free ( pIfreqList ); -} - - -epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket) -{ - epicsThreadOnce(&osiLocalAddrId, osiLocalAddrOnce, &socket); - return osiLocalAddrResult; -} diff --git a/src/libCom/osi/os/default/osdPoolStatus.c b/src/libCom/osi/os/default/osdPoolStatus.c deleted file mode 100644 index bb764b2ad..000000000 --- a/src/libCom/osi/os/default/osdPoolStatus.c +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "osiPoolStatus.h" - -/* - * osiSufficentSpaceInPool () - * - * @@@@@ not implemented @@@@@ - * - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) -{ - return 1; -} diff --git a/src/libCom/osi/os/default/osdPoolStatus.h b/src/libCom/osi/os/default/osdPoolStatus.h deleted file mode 100644 index efb2cfab8..000000000 --- a/src/libCom/osi/os/default/osdPoolStatus.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef osdPoolStatush -#define osdPoolStatush - -#endif /* osdPoolStatush */ diff --git a/src/libCom/osi/os/default/osdSignal.cpp b/src/libCom/osi/os/default/osdSignal.cpp deleted file mode 100644 index 08dfa023c..000000000 --- a/src/libCom/osi/os/default/osdSignal.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -/* - * All NOOPs if the os isnt POSIX - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * /* threadId */ ) {} - diff --git a/src/libCom/osi/os/default/osdSpin.c b/src/libCom/osi/os/default/osdSpin.c deleted file mode 100644 index 6e9acb158..000000000 --- a/src/libCom/osi/os/default/osdSpin.c +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "errlog.h" -#include "epicsMutex.h" -#include "epicsSpin.h" - -/* - * Default: EPICS MUTEX IMPLEMENTATION - */ - -typedef struct epicsSpin { - epicsMutexId lock; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - epicsSpin *spin; - - spin = calloc(1, sizeof(*spin)); - if (!spin) - goto fail; - - spin->lock = epicsMutexCreate(); - if (!spin->lock) - goto fail; - - return spin; - -fail: - free(spin); - return NULL; -} - -epicsSpinId epicsSpinMustCreate(void) -{ - epicsSpinId ret = epicsSpinCreate(); - if(!ret) - cantProceed("epicsSpinMustCreate: epicsSpinCreate failed."); - return ret; -} - -void epicsSpinDestroy(epicsSpinId spin) { - epicsMutexDestroy(spin->lock); - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - epicsMutexLockStatus status; - - status = epicsMutexLock(spin->lock); - if (status != epicsMutexLockOK) { - errlogPrintf("epicsSpinLock(%p): epicsMutexLock returned %s\n", spin, - status == epicsMutexLockTimeout ? - "epicsMutexLockTimeout" : "epicsMutexLockError"); - } -} - -int epicsSpinTryLock(epicsSpinId spin) { - epicsMutexLockStatus status; - - status = epicsMutexTryLock(spin->lock); - if (status == epicsMutexLockOK) return 0; - if (status == epicsMutexLockTimeout) return 1; - - errlogPrintf("epicsSpinTryLock(%p): epicsMutexTryLock returned epicsMutexLockError\n", spin); - return 2; -} - -void epicsSpinUnlock(epicsSpinId spin) { - epicsMutexUnlock(spin->lock); -} diff --git a/src/libCom/osi/os/default/osdThreadExtra.c b/src/libCom/osi/os/default/osdThreadExtra.c deleted file mode 100644 index 0a7c7ae95..000000000 --- a/src/libCom/osi/os/default/osdThreadExtra.c +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Ralph Lange Date: 26 Jun 2012 */ - -/* Null default thread hooks for all platforms that do not do anything special */ - -#define epicsExportSharedSymbols -#include "epicsThread.h" - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; diff --git a/src/libCom/osi/os/default/osdThreadHooks.c b/src/libCom/osi/os/default/osdThreadHooks.c deleted file mode 100644 index cbe28a4ff..000000000 --- a/src/libCom/osi/os/default/osdThreadHooks.c +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Authors: Ralph Lange & Andrew Johnson */ - -/* Secure hooks for epicsThread */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "ellLib.h" -#include "epicsMutex.h" -#include "epicsThread.h" - -epicsShareExtern EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareExtern EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; - -typedef struct epicsThreadHook { - ELLNODE node; - EPICS_THREAD_HOOK_ROUTINE func; -} epicsThreadHook; - -static ELLLIST hookList = ELLLIST_INIT; -static epicsMutexId hookLock; - - -static void threadHookOnce(void *arg) -{ - hookLock = epicsMutexMustCreate(); - - if (epicsThreadHookDefault) { - static epicsThreadHook defHook = {ELLNODE_INIT, NULL}; - - defHook.func = epicsThreadHookDefault; - ellAdd(&hookList, &defHook.node); - } -} - -static void threadHookInit(void) -{ - static epicsThreadOnceId flag = EPICS_THREAD_ONCE_INIT; - - epicsThreadOnce(&flag, threadHookOnce, NULL); -} - -epicsShareFunc int epicsThreadHookAdd(EPICS_THREAD_HOOK_ROUTINE hook) -{ - epicsThreadHook *pHook; - - if (!hook) return 0; - threadHookInit(); - - pHook = calloc(1, sizeof(epicsThreadHook)); - if (!pHook) { - fprintf(stderr, "epicsThreadHookAdd: calloc failed\n"); - return -1; - } - pHook->func = hook; - - if (epicsMutexLock(hookLock) == epicsMutexLockOK) { - ellAdd(&hookList, &pHook->node); - epicsMutexUnlock(hookLock); - return 0; - } - fprintf(stderr, "epicsThreadHookAdd: Locking problem\n"); - return -1; -} - -epicsShareFunc int epicsThreadHookDelete(EPICS_THREAD_HOOK_ROUTINE hook) -{ - if (!hook) return 0; - threadHookInit(); - - if (epicsMutexLock(hookLock) == epicsMutexLockOK) { - epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList); - - while (pHook) { - if (hook == pHook->func) { - ellDelete(&hookList, &pHook->node); - break; - } - pHook = (epicsThreadHook *) ellNext(&pHook->node); - } - epicsMutexUnlock(hookLock); - return 0; - } - fprintf(stderr, "epicsThreadHookAdd: Locking problem\n"); - return -1; -} - -epicsShareFunc void osdThreadHooksRunMain(epicsThreadId id) -{ - if (epicsThreadHookMain) - epicsThreadHookMain(id); -} - -epicsShareFunc void osdThreadHooksRun(epicsThreadId id) -{ - threadHookInit(); - - if (epicsMutexLock(hookLock) == epicsMutexLockOK) { - epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList); - - while (pHook) { - pHook->func(id); - pHook = (epicsThreadHook *) ellNext(&pHook->node); - } - epicsMutexUnlock(hookLock); - } - else { - fprintf(stderr, "osdThreadHooksRun: Locking problem\n"); - } -} - -epicsShareFunc void epicsThreadHooksShow(void) -{ - threadHookInit(); - - if (epicsMutexLock(hookLock) == epicsMutexLockOK) { - epicsThreadHook *pHook = (epicsThreadHook *) ellFirst(&hookList); - - while (pHook) { - printf(" %p\n", pHook->func); - pHook = (epicsThreadHook *) ellNext(&pHook->node); - } - epicsMutexUnlock(hookLock); - } - else { - fprintf(stderr, "epicsThreadHooksShow: Locking problem\n"); - } -} diff --git a/src/libCom/osi/os/default/osdVME.h b/src/libCom/osi/os/default/osdVME.h deleted file mode 100644 index 1b65b3184..000000000 --- a/src/libCom/osi/os/default/osdVME.h +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * OS-dependent VME support - */ diff --git a/src/libCom/osi/os/default/osdWireConfig.h b/src/libCom/osi/os/default/osdWireConfig.h deleted file mode 100644 index e8def865e..000000000 --- a/src/libCom/osi/os/default/osdWireConfig.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Default version of osdWireConfig.h that might - * work on UNIX like systems that define - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireConfig_h -#define osdWireConfig_h - -/* This file must be usable from both C and C++ */ - -/* if compilation fails because this wasnt found then you may need to define an OS - specific osdWireConfig.h */ -#include - -#ifdef __BYTE_ORDER -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -# elif __BYTE_ORDER == __BIG_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_BIG -# else -# error EPICS hasnt been ported to run on the specified __BYTE_ORDER -# endif -#else -# ifdef BYTE_ORDER -# if BYTE_ORDER == LITTLE_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -# elif BYTE_ORDER == BIG_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_BIG -# else -# error EPICS hasnt been ported to run on the specified BYTE_ORDER -# endif -# else -# error doesnt specify __BYTE_ORDER or BYTE_ORDER - is an OS specific osdWireConfig.h needed? -# endif -#endif - -#ifdef __FLOAT_WORD_ORDER -# if __FLOAT_WORD_ORDER == __LITTLE_ENDIAN -# define EPICS_FLOAT_WORD_ORDER EPICS_ENDIAN_LITTLE -# elif __FLOAT_WORD_ORDER == __BIG_ENDIAN -# define EPICS_FLOAT_WORD_ORDER EPICS_ENDIAN_BIG -# else -# error EPICS hasnt been ported to specified __FLOAT_WORD_ORDER -# endif -#else -# ifdef FLOAT_WORD_ORDER -# if FLOAT_WORD_ORDER == LITTLE_ENDIAN -# define EPICS_FLOAT_WORD_ORDER EPICS_ENDIAN_LITTLE -# elif FLOAT_WORD_ORDER == BIG_ENDIAN -# define EPICS_FLOAT_WORD_ORDER EPICS_ENDIAN_BIG -# else -# error EPICS hasnt been ported to specified FLOAT_WORD_ORDER -# endif -# else - /* assume that if neither __FLOAT_WORD_ORDER nor FLOAT_WORD_ORDER are - defined then weird fp ordered archs like arm nwfp aren't supported */ -# define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER -# endif -#endif - -#endif /* ifdef osdWireConfig_h */ diff --git a/src/libCom/osi/os/default/osdWireFormat.h b/src/libCom/osi/os/default/osdWireFormat.h deleted file mode 100644 index 385c9bd69..000000000 --- a/src/libCom/osi/os/default/osdWireFormat.h +++ /dev/null @@ -1,240 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireFormat -#define osdWireFormat - -#ifdef __SUNPRO_CC -# include -#else -# include -#endif - -#include "epicsEndian.h" - -// -// The default assumption is that the local floating point format is -// IEEE and that these routines only need to perform byte swapping -// as a side effect of copying an aligned operand into an unaligned -// network byte stream. OS specific code can provide a alternative -// for this file if that assumption is wrong. -// - -// -// EPICS_CONVERSION_REQUIRED is set if either the byte order -// or the floating point word order are not exactly big endian. -// This can be set by hand above for a specific architecture -// should there be an architecture that is a weird middle endian -// ieee floating point format that is also big endian integer. -// -#if EPICS_BYTE_ORDER != EPICS_ENDIAN_BIG || EPICS_FLOAT_WORD_ORDER != EPICS_BYTE_ORDER -# if ! defined ( EPICS_CONVERSION_REQUIRED ) -# define EPICS_CONVERSION_REQUIRED -# endif -#endif - -// -// We still use a big endian wire format for CA consistent with the internet, -// but inconsistent with the vast majority of CPUs -// - -template <> -inline void WireGet < epicsFloat64 > ( - const epicsUInt8 * pWireSrc, epicsFloat64 & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - union { - epicsFloat64 _f; - epicsUInt32 _u[2]; - } tmp; -# if EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE - WireGet ( pWireSrc, tmp._u[1] ); - WireGet ( pWireSrc + 4, tmp._u[0] ); -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG - WireGet ( pWireSrc, tmp._u[0] ); - WireGet ( pWireSrc + 4, tmp._u[1] ); -# else -# error unsupported floating point word order -# endif - dst = tmp._f; -} - -#if defined ( __GNUC__ ) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 0 ) -template <> -inline void WireGet < epicsOldString > ( - const epicsUInt8 * pWireSrc, epicsOldString & dst ) -{ - memcpy ( dst, pWireSrc, sizeof ( dst ) ); -} -#else -inline void WireGet ( - const epicsUInt8 * pWireSrc, epicsOldString & dst ) -{ - memcpy ( dst, pWireSrc, sizeof ( dst ) ); -} -#endif - -template <> -inline void WireSet < epicsFloat64 > ( - const epicsFloat64 & src, epicsUInt8 * pWireDst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - union { - epicsFloat64 _f; - epicsUInt32 _u[2]; - } tmp; - tmp._f = src; -# if EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE - WireSet ( tmp._u[1], pWireDst ); - WireSet ( tmp._u[0], pWireDst + 4 ); -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG - WireSet ( tmp._u[0], pWireDst ); - WireSet ( tmp._u[1], pWireDst + 4 ); -# else -# error unsupported floating point word order -# endif -} - -#if defined ( __GNUC__ ) && ( __GNUC__ == 4 && __GNUC_MINOR__ <= 0 ) -template <> -inline void WireSet < epicsOldString > ( - const epicsOldString & src, epicsUInt8 * pWireDst ) -{ - memcpy ( pWireDst, src, sizeof ( src ) ); -} -#else -inline void WireSet ( - const epicsOldString & src, epicsUInt8 * pWireDst ) -{ - memcpy ( pWireDst, src, sizeof ( src ) ); -} -#endif - -template <> -inline void AlignedWireGet < epicsUInt16 > ( - const epicsUInt16 & src, epicsUInt16 & dst ) -{ -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - dst = byteSwap ( src ); -# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - dst = src; -# else -# error unsupported endian type -# endif -} - -template <> -inline void AlignedWireGet < epicsUInt32 > ( - const epicsUInt32 & src, epicsUInt32 & dst ) -{ -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - dst = byteSwap ( src ); -# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - dst = src; -# else -# error unsupported endian type -# endif -} - -template <> -inline void AlignedWireGet < epicsFloat64 > ( - const epicsFloat64 & src, epicsFloat64 & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - union Swapper { - epicsUInt32 _u[2]; - epicsFloat64 _f; - }; -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG && EPICS_FLOAT_WORD_ORDER == EPICS_BYTE_ORDER - dst = src; -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG - Swapper tmp; - tmp._f = src; - AlignedWireGet ( tmp._u[0], tmp._u[0] ); - AlignedWireGet ( tmp._u[1], tmp._u[1] ); - dst = tmp._f; -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE - Swapper srcu, dstu; - srcu._f = src; - AlignedWireGet ( srcu._u[1], dstu._u[0] ); - AlignedWireGet ( srcu._u[0], dstu._u[1] ); - dst = dstu._f; -# else -# error unsupported floating point word order -# endif -} - -template <> -inline void AlignedWireSet < epicsUInt16 > - ( const epicsUInt16 & src, epicsUInt16 & dst ) -{ -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - dst = byteSwap ( src ); -# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - dst = src; -# else -# error undefined endian type -# endif -} - -template <> -inline void AlignedWireSet < epicsUInt32 > ( - const epicsUInt32 & src, epicsUInt32 & dst ) -{ -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE - dst = byteSwap ( src ); -# elif EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG - dst = src; -# else -# error undefined endian type -# endif -} - -template <> -inline void AlignedWireSet < epicsFloat64 > ( - const epicsFloat64 & src, epicsFloat64 & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - union Swapper { - epicsUInt32 _u[2]; - epicsFloat64 _f; - }; -# if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG && EPICS_FLOAT_WORD_ORDER == EPICS_BYTE_ORDER - dst = src; -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_BIG - Swapper tmp; - tmp._f = src; - AlignedWireSet ( tmp._u[0], tmp._u[0] ); - AlignedWireSet ( tmp._u[1], tmp._u[1] ); - dst = tmp._f; -# elif EPICS_FLOAT_WORD_ORDER == EPICS_ENDIAN_LITTLE - Swapper srcu, dstu; - srcu._f = src; - AlignedWireSet ( srcu._u[1], dstu._u[0] ); - AlignedWireSet ( srcu._u[0], dstu._u[1] ); - dst = dstu._f; -# else -# error unsupported floating point word order -# endif -} - -#endif // osdWireFormat diff --git a/src/libCom/osi/os/freebsd/osdSock.h b/src/libCom/osi/os/freebsd/osdSock.h deleted file mode 100644 index fe28d4cd5..000000000 --- a/src/libCom/osi/os/freebsd/osdSock.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -#ifndef IPPORT_USERRESERVED -#define IPPORT_USERRESERVED 5000 -#endif - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)ifr_addr.sa_len + sizeof(pifreq->ifr_name)) -#else -# define ifreq_size(pifreq) sizeof(*pifreq) -#endif - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/freebsd/osdTime.h b/src/libCom/osi/os/freebsd/osdTime.h deleted file mode 100644 index 941426c72..000000000 --- a/src/libCom/osi/os/freebsd/osdTime.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osdTimeh -#define osdTimeh - -/* - * We need this include file since the POSIX version - * causes `struct timespec' to be defined in more than one place. - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsShareAPI - convertDoubleToWakeTime(double timeout,struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/freebsd/osiFileName.h b/src/libCom/osi/os/freebsd/osiFileName.h deleted file mode 100644 index 83204c70f..000000000 --- a/src/libCom/osi/os/freebsd/osiFileName.h +++ /dev/null @@ -1,18 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/freebsd/osiUnistd.h b/src/libCom/osi/os/freebsd/osiUnistd.h deleted file mode 100644 index c64e57a6c..000000000 --- a/src/libCom/osi/os/freebsd/osiUnistd.h +++ /dev/null @@ -1,22 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -/* - * Some systems fail to provide prototypes of these functions. - * Others provide different prototypes. - * There seems to be no way to handle this automatically, so - * if you get compile errors, just make the appropriate changes here. - */ diff --git a/src/libCom/osi/os/iOS/epicsMath.h b/src/libCom/osi/os/iOS/epicsMath.h deleted file mode 100644 index 493583f70..000000000 --- a/src/libCom/osi/os/iOS/epicsMath.h +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include - -#define finite(x) isfinite(x) - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/iOS/osdEnv.c b/src/libCom/osi/os/iOS/osdEnv.c deleted file mode 100644 index a32cce5ef..000000000 --- a/src/libCom/osi/os/iOS/osdEnv.c +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* osdEnv.c */ -/* - * Author: Eric Norum - * Date: May 7, 2001 - * - * Routines to modify/display environment variables and EPICS parameters - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include -#include -#include -#include -#include "epicsFindSymbol.h" -#include - -/* - * Set the value of an environment variable - */ -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value) -{ - iocshEnvClear(name); - setenv(name, value, 1); -} - -/* - * Show the value of the specified, or all, environment variables - */ -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name) -{ - if (name == NULL) { - extern char **environ; - char **sp; - - for (sp = environ ; (sp != NULL) && (*sp != NULL) ; sp++) - printf ("%s\n", *sp); - } - else { - const char *cp = getenv (name); - if (cp == NULL) - printf ("%s is not an environment variable.\n", name); - else - printf ("%s=%s\n", name, cp); - } -} diff --git a/src/libCom/osi/os/iOS/osdSock.h b/src/libCom/osi/os/iOS/osdSock.h deleted file mode 100644 index 0b3b3f6c1..000000000 --- a/src/libCom/osi/os/iOS/osdSock.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; -typedef socklen_t osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)ifr_addr.sa_len + sizeof((pifreq)->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/iOS/osdSockAddrReuse.cpp b/src/libCom/osi/os/iOS/osdSockAddrReuse.cpp deleted file mode 100644 index 9f64e331a..000000000 --- a/src/libCom/osi/os/iOS/osdSockAddrReuse.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} - -/* - * SO_REUSEPORT is not in POSIX - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEPORT, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEPORT?\n"); - } -} diff --git a/src/libCom/osi/os/iOS/osdTime.h b/src/libCom/osi/os/iOS/osdTime.h deleted file mode 100644 index 953ec31b8..000000000 --- a/src/libCom/osi/os/iOS/osdTime.h +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osdTimeh -#define osdTimeh - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void convertDoubleToWakeTime(double timeout, - struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/iOS/osiFileName.h b/src/libCom/osi/os/iOS/osiFileName.h deleted file mode 100644 index f7dd62878..000000000 --- a/src/libCom/osi/os/iOS/osiFileName.h +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Eric Norum - */ - -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/posix/README b/src/libCom/osi/os/posix/README deleted file mode 100644 index 59f3d9524..000000000 --- a/src/libCom/osi/os/posix/README +++ /dev/null @@ -1,13 +0,0 @@ -A knowledge of pthreads is necessary to understand osdThread.c and osdSem.c. - -The following are good references - -Programming with POSIX Threads, David R. Butenhof, Addison-weslet, 1997 - -Multithreaded Programming with Pthreads, Bil Lewis & Daniel J. Berg, -Sun Microsystems, 1998 - -Pthreads Programming, Bradford Nichols etc, O'Reilly & Associates, 1996 - -The implementation of semMutex is based on the example code by Bil Leeis -that os available via the WWW. diff --git a/src/libCom/osi/os/posix/epicsAtomicOSD.cpp b/src/libCom/osi/os/posix/epicsAtomicOSD.cpp deleted file mode 100644 index 1cc227fcd..000000000 --- a/src/libCom/osi/os/posix/epicsAtomicOSD.cpp +++ /dev/null @@ -1,74 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeffrey O. Hill - * johill@lanl.gov - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "epicsAtomic.h" - -/* - * Slow, but probably correct on all systems. - * Useful only if something more efficient isn`t - * provided based on knowledge of the compiler - * or OS - * - * A statically initialized pthread mutex doesn`t - * need to be destroyed - * - * !!!!! - * !!!!! WARNING - * !!!!! - * !!!!! Do not use this implementation on systems where - * !!!!! code runs at interrupt context. If so, then - * !!!!! an implementation must be provided that is based - * !!!!! on a compiler intrinsic or an interrupt lock and or - * !!!!! a spin lock primitive - * !!!!! - */ -static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - -void epicsAtomicLock ( EpicsAtomicLockKey * ) -{ - unsigned countDown = 1000u; - int status; - while ( true ) { - status = pthread_mutex_lock ( & mutex ); - if ( status == 0 ) return; - assert ( status == EINTR ); - static const useconds_t retryDelayUSec = 100000; - usleep ( retryDelayUSec ); - countDown--; - assert ( countDown ); - } -} - -void epicsAtomicUnlock ( EpicsAtomicLockKey * ) -{ - const int status = pthread_mutex_unlock ( & mutex ); - assert ( status == 0 ); -} - - -// Slow, but probably correct on all systems. -// Useful only if something more efficient isn`t -// provided based on knowledge of the compiler -// or OS -void epicsAtomicMemoryBarrierFallback (void) -{ - EpicsAtomicLockKey key; - epicsAtomicLock ( & key ); - epicsAtomicUnlock ( & key ); -} diff --git a/src/libCom/osi/os/posix/epicsAtomicOSD.h b/src/libCom/osi/os/posix/epicsAtomicOSD.h deleted file mode 100644 index 892d2dcb5..000000000 --- a/src/libCom/osi/os/posix/epicsAtomicOSD.h +++ /dev/null @@ -1,54 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef epicsAtomicOSD_h -#define epicsAtomicOSD_h - -#include - -#define EPICS_ATOMIC_OS_NAME "POSIX" - -typedef struct EpicsAtomicLockKey {} EpicsAtomicLockKey; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsAtomicLock ( struct EpicsAtomicLockKey * ); -epicsShareFunc void epicsAtomicUnlock ( struct EpicsAtomicLockKey * ); -epicsShareFunc void epicsAtomicMemoryBarrierFallback ( void ); - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - epicsAtomicMemoryBarrierFallback(); -} -#endif - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - epicsAtomicMemoryBarrierFallback(); -} -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/posix/epicsMath.h b/src/libCom/osi/os/posix/epicsMath.h deleted file mode 100644 index 4e558676c..000000000 --- a/src/libCom/osi/os/posix/epicsMath.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef isfinite -# undef finite -# define finite(x) isfinite((double)(x)) -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/posix/epicsTempFile.cpp b/src/libCom/osi/os/posix/epicsTempFile.cpp deleted file mode 100644 index 19b5fb4bc..000000000 --- a/src/libCom/osi/os/posix/epicsTempFile.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#define epicsExportSharedSymbols -#include "epicsTempFile.h" - -extern "C" -epicsShareFunc void epicsShareAPI epicsTempName ( - char * pNameBuf, size_t nameBufLength ) -{ - if ( nameBufLength ) { - pNameBuf[0] = '\0'; - char nameBuf[L_tmpnam]; - if ( tmpnam ( nameBuf ) ) { - if ( nameBufLength > strlen ( nameBuf ) ) { - strncpy ( pNameBuf, nameBuf, nameBufLength ); - } - } - } -} - - -extern "C" -epicsShareFunc FILE * epicsShareAPI epicsTempFile ( void ) -{ - return tmpfile (); -} - diff --git a/src/libCom/osi/os/posix/osdElfFindAddr.c b/src/libCom/osi/os/posix/osdElfFindAddr.c deleted file mode 100644 index bc67ae9ea..000000000 --- a/src/libCom/osi/os/posix/osdElfFindAddr.c +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _POSIX_MAPPED_FILES -#include -#endif - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "epicsStackTrace.h" -#include "epicsStackTracePvt.h" - -/* This routine is provided by osiClockTime.c */ -epicsShareExtern void ClockTime_GetProgramStart(epicsTimeStamp *pDest); - -#define FIND_ADDR_DEBUG 0 - -/* - * On some systems (linux, solaris) dladdr doesn't find local symbols - * or symbols in the main executable. - * Hence, we want to use dladdr() to find the file name - * where a symbol is defined and if not more information is available - * then proceed to lookup symbols in the ELF symbol tables. - */ - -/* Macros to handle elf32 vs. elf64 access to unions etc. */ - -#define FLD(c,s,f) (ELFCLASS32==c ? s.e32.f : s.e64.f ) -#define ARR(c,s,i,f) (ELFCLASS32==c ? s.e32[i].f : s.e64[i].f) - -/* Elf header */ -typedef union Ehdr_ { - Elf32_Ehdr e32; - Elf64_Ehdr e64; -} Ehdr; - -/* Section header */ -typedef union Shdr_ { - Elf32_Shdr e32; - Elf64_Shdr e64; -} Shdr; - -/* Elf symbol */ -typedef union Sym_ { - void *raw; - Elf32_Sym *e32; - Elf64_Sym *e64; -} Sym; - -/* Memory mapped portion of a file; we must - * keep additional information because the - * map's starting address + length must be - * page-aligned (man mmap). - */ -typedef struct MMap_ { - void *addr; - off_t off; /* offset into the map where 'real' data start */ - size_t len; - size_t max; /* max offset: legal data from addr+off .. addr+off+max-1 */ - void (*freeMap)(struct MMap_*); /* 'method' to destroy the mapping */ -} *MMap; - -/* Structure describing symbol information - * contained in a file. - * We keep these around (so that the file - * doesn't have to be opened + parsed every - * time we do a lookup). - */ -typedef struct ESyms_ { - struct ESyms_ *next; /* linked list; one struct per executable */ - const char *fname; /* file name */ - int fd; /* file descriptor */ - uintptr_t addr; /* address where file is loaded */ - MMap symMap; - MMap strMap; - size_t nsyms; - uint8_t eclss; -} *ESyms; - -/* LOCKING NOTE: if the ELF symbol facility is ever expanded to be truly used - * in a multithreaded way then proper multiple-readers, single-writer locking - * should be implemented. - */ - -/* Linked list where we keep all our ESyms */ -static ESyms elfs = 0; - -static epicsMutexId listMtx; -static epicsThreadOnceId listMtxInitId = EPICS_THREAD_ONCE_INIT; - -static void listMtxInit(void *unused) -{ - listMtx = epicsMutexMustCreate(); -} - -static void -elfsLockWrite() -{ - epicsThreadOnce(&listMtxInitId, listMtxInit, 0); - epicsMutexMustLock(listMtx); -} - -static void -elfsUnlockWrite() -{ - epicsMutexUnlock(listMtx); -} - -static void -freeMap(MMap m) -{ - if ( m ) { - m->freeMap(m); - free(m); - } -} - -/* Helper to read exactly 'sz' bytes into 'buf' - * RETURNS: # chars read or negative value on error. - */ -static ssize_t -do_read(int fd, void *buf, ssize_t sz) -{ - ssize_t got; - char *ptr=(char*)buf; - - while ( sz > 0 ) { - if ( (got=read(fd,ptr,sz)) <= 0 ) { - return got; - } - ptr+=got; - sz -=got; - } - return ptr-(char*)buf; -} - -/* Elf file access -- can either be with mmap or by sequential read */ - -#ifdef _POSIX_MAPPED_FILES -/* Destructor for data that is mmap()ed */ -static void -freeMapMmap(MMap m) -{ - if ( MAP_FAILED != m->addr ) - munmap( m->addr, m->len ); -} - -/* Obtain section data with mmap() */ -static MMap -getscn_mmap(int fd, uint8_t c, Shdr *shdr_p) -{ - off_t n; - MMap rval = 0; - size_t pgsz = sysconf(_SC_PAGESIZE); - - if ( 0 == (n = (off_t)FLD(c,(*shdr_p),sh_size)) ) { - errlogPrintf("elfRead - getscn() -- no section data\n"); - goto bail; - } - - if ( ! (rval = (MMap) malloc(sizeof(*rval))) ) { - errlogPrintf("elfRead - getscn() -- no memory for section map\n"); - goto bail; - } - - rval->freeMap = freeMapMmap; - - rval->off = (off_t) (FLD(c,(*shdr_p),sh_offset) & (pgsz-1)); - rval->len = (n + rval->off + (pgsz - 1)) & ~(pgsz - 1); - rval->max = rval->len - rval->off; - - if ( MAP_FAILED == (rval->addr = mmap(0, rval->len, PROT_READ, MAP_SHARED, fd, (off_t) (FLD(c,(*shdr_p),sh_offset) & ~(pgsz-1)))) ) { - errlogPrintf("elfRead - getscn() -- mapping section contents: %s\n", strerror(errno)); - goto bail; - } - - return rval; - -bail: - freeMap(rval); - return 0; -} -#else -static MMap getscn_mmap(int fd, uint8_t c, Shrd *shdr_p) -{ - return 0; -} -#endif - -/* Destructor for data that is read into a malloc()ed buffer */ -static void -freeMapMalloc(MMap m) -{ - free(m->addr); -} - -/* Read section data into a malloc()ed buffer */ -static MMap -getscn_read(int fd, uint8_t c, Shdr *shdr_p) -{ - ssize_t n; - MMap rval = 0; - - if ( 0 == (n = (ssize_t) FLD(c,(*shdr_p),sh_size)) ) { - errlogPrintf("elfRead - getscn() -- no section data\n"); - goto bail; - } - - if ( ! (rval = (MMap) malloc(sizeof(*rval))) ) { - errlogPrintf("elfRead - getscn() -- no memory for section map\n"); - goto bail; - } - - rval->freeMap = freeMapMalloc; - - if ( ! (rval->addr = malloc(n)) ) { - errlogPrintf("elfRead - getscn() -- no memory for section data\n"); - goto bail; - } - - rval->off = 0; - rval->len = n; - rval->max = rval->len - rval->off; - - /* seek to symbol table contents */ - if ( (off_t)-1 == lseek(fd, (off_t) FLD(c,(*shdr_p),sh_offset), SEEK_SET) ) { - errlogPrintf("elfRead - getscn() -- seeking to sh_offset: %s\n", strerror(errno)); - goto bail; - } - - if ( n != do_read(fd, rval->addr, n) ) { - errlogPrintf("elfRead - getscn() -- reading section contents: %s\n", strerror(errno)); - goto bail; - } - - return rval; - -bail: - freeMap(rval); - return 0; -} - -static MMap -getscn(int fd, uint8_t c, Shdr *shdr_p) -{ - MMap rval = getscn_mmap(fd, c, shdr_p); - - if ( ! rval ) - rval = getscn_read(fd, c, shdr_p); - - return rval; -} - -/* Release resources but keep filename so that - * a file w/o symbol table is not read over and over again. - */ -static void -elfSymsRelease(ESyms es) -{ - if ( es ) { - freeMap(es->symMap); - es->symMap = 0; - freeMap(es->strMap); - es->strMap = 0; - if ( es->fd >= 0 ) - close(es->fd); - es->fd = -1; - es->nsyms = 0; - } -} - -static ESyms -elfRead(const char *fname, uintptr_t fbase) -{ - int i; - Ehdr ehdr; - Shdr shdr; - uint8_t c; - ESyms es; - ssize_t idx,n; - const char *cp; - struct stat stat_b; - - if ( !(es = (ESyms) malloc(sizeof(*es))) ) { - /* no memory -- give up */ - return 0; - } - - memset(es, 0, sizeof(*es)); - es->fd = -1; - es->fname = fname; - - if ( (es->fd = open(fname, O_RDONLY)) < 0 ) { - errlogPrintf("elfRead() -- unable to open file: %s\n", strerror(errno)); - goto bail; - } - - if ( EI_NIDENT != do_read(es->fd, &ehdr, EI_NIDENT) ) { - errlogPrintf("elfRead() -- unable to read ELF e_ident: %s\n", strerror(errno)); - goto bail; - } - - if ( ELFMAG0 != ehdr.e32.e_ident[EI_MAG0] - || ELFMAG1 != ehdr.e32.e_ident[EI_MAG1] - || ELFMAG2 != ehdr.e32.e_ident[EI_MAG2] - || ELFMAG3 != ehdr.e32.e_ident[EI_MAG3] ) { - errlogPrintf("bad ELF magic number\n"); - goto bail; - } - - if ( EV_CURRENT != ehdr.e32.e_ident[EI_VERSION] ) { - errlogPrintf("bad ELF version\n"); - goto bail; - } - - switch ( (es->eclss = c = ehdr.e32.e_ident[EI_CLASS]) ) { - default: - errlogPrintf("bad ELF class\n"); - goto bail; - - case ELFCLASS32: - n = sizeof(Elf32_Ehdr); - break; - case ELFCLASS64: - n = sizeof(Elf64_Ehdr); - break; - } - n -= EI_NIDENT; - - if ( 0 == fstat(es->fd, &stat_b) ) { - epicsTimeStamp progStartStamp; - time_t progStartTime; - - ClockTime_GetProgramStart(&progStartStamp); - epicsTimeToTime_t(&progStartTime, &progStartStamp); - if ( stat_b.st_mtime >= progStartTime ) { - errlogPrintf("elfRead() -- WARNING: '%s' was modified after program start -- symbol information may be inaccurate or invalid\n", fname); - } - } - - /* read rest */ - if ( n != do_read(es->fd, ehdr.e32.e_ident + EI_NIDENT, n) ) { - errlogPrintf("elfRead() -- unable to read ELF ehdr: %s\n", strerror(errno)); - goto bail; - } - - /* seek to section header table */ - if ( (off_t)-1 == lseek(es->fd, (off_t) FLD(c,ehdr,e_shoff), SEEK_SET) ) { - errlogPrintf("elfRead() -- unable to seek to shoff: %s\n", strerror(errno)); - goto bail; - } - - n = ELFCLASS32 == c ? sizeof(shdr.e32) : sizeof(shdr.e64); - - for ( i = 0; ifd, &shdr, n) ) { - errlogPrintf("elfRead() -- unable to read section header: %s\n", strerror(errno)); - goto bail; - } - if ( SHT_SYMTAB == FLD(c,shdr,sh_type) ) - break; - } - - if ( i>=FLD(c,ehdr,e_shnum) ) { - /* no SYMTAB -- try dynamic symbols */ - - if ( (off_t)-1 == lseek(es->fd, (off_t) FLD(c,ehdr,e_shoff), SEEK_SET) ) { - errlogPrintf("elfRead() -- unable to seek to shoff: %s\n", strerror(errno)); - goto bail; - } - - for ( i = 0; ifd, &shdr, n) ) { - errlogPrintf("elfRead() -- unable to read section header: %s\n", strerror(errno)); - goto bail; - } - if ( SHT_DYNSYM == FLD(c,shdr,sh_type) ) - break; - } - } - - if ( i>=FLD(c,ehdr,e_shnum) ) { - errlogPrintf("elfRead() -- no symbol table found\n"); - goto bail; - } - - if ( 0 == (n = (ssize_t) FLD(c,shdr,sh_size)) ) { - errlogPrintf("elfRead() -- no symbol table data\n"); - goto bail; - } - - if ( !(es->symMap = getscn(es->fd, c, &shdr)) ) { - errlogPrintf("elfRead() -- unable to read ELF symtab\n"); - goto bail; - } - - es->nsyms = n / (ELFCLASS32==c ? sizeof(Elf32_Sym) : sizeof(Elf64_Sym)); - - /* find and read string table */ - - n = ELFCLASS32 == c ? sizeof(shdr.e32) : sizeof(shdr.e64); - - /* seek to section header table */ - if ( (off_t)-1 == lseek(es->fd, (off_t) (FLD(c,ehdr,e_shoff) + n * FLD(c,shdr,sh_link)), SEEK_SET) ) { - errlogPrintf("elfRead() -- unable to lseek to ELF e_shoff: %s\n", strerror(errno)); - goto bail; - } - - if ( n != do_read(es->fd, &shdr, n) ) { - errlogPrintf("elfRead() -- unable to read ELF strtab section header: %s\n", strerror(errno)); - goto bail; - } - - if ( !(es->strMap = getscn(es->fd,c,&shdr)) ) { - errlogPrintf("elfRead() -- unable to read ELF strtab\n"); - goto bail; - } - - /* Make sure there is a terminating NUL - unfortunately, memrchr is not portable */ - cp = (char*)es->strMap->addr + es->strMap->off; - for ( idx = es->strMap->max - 1; i >= 0; i-- ) { - if ( !cp[i] ) - break; - } - es->strMap->max = idx + 1; - - switch ( FLD(c,ehdr,e_type) ) { - case ET_EXEC: - /* Symbols in an executable already has absolute addresses */ - es->addr = 0; - break; - case ET_DYN: - /* Symbols in an shared library are relative to base address */ - es->addr = fbase; - break; - default: - errlogPrintf("dlLookupAddr(): Unexpected ELF object file type %u\n", FLD(c,ehdr,e_type)); - goto bail; - } - - return es; - -bail: - elfSymsRelease(es); - return es; -} - -/* Destroy a cached ELF symbol table */ -static void -elfSymsDestroy(ESyms es) -{ - if ( es ) { - elfSymsRelease(es); - free(es); - } -} - -/* Destroy all cached ELF symbol tables - * - * However - w/o proper locking for read access - * this must not be used. Otherwise, readers - * will hold stale pointers... - * - * We leave the commented code here to show - * how the tables can be torn down. - -void -elfSymTblFlush() -{ -ESyms es; - - elfsLockWrite(); - while ( (es = elfs) ) { - elfs = es->next; - es->next = 0; - elfsUnlockWrite(); - elfSymsDestroy(es); - elfsLockWrite(); - } - elfsUnlockWrite(); -} - -*/ - - -/* This routine must be called with the write-lock held */ -static ESyms -elfSymsFind(const char *fname) -{ - ESyms es; - - for ( es=elfs; es && strcmp(fname, es->fname); es = es->next ) - /* nothing else to do */; - return es; -} - -int -epicsFindAddr(void *addr, epicsSymbol *sym_p) -{ - Dl_info inf; - ESyms es,nes = 0; - uintptr_t minoff,off; - size_t i; - Sym sym; - Sym nearest; - const char *strtab; - uint8_t c; - size_t idx; - - if ( ! dladdr(addr, &inf) || (!inf.dli_fname && !inf.dli_sname) ) { - sym_p->f_nam = 0; - sym_p->s_nam = 0; - /* unable to lookup */ - return 0; - } - - sym_p->f_nam = inf.dli_fname; - - /* If the symbol is in the main executable then solaris' dladdr returns bogus info */ -#ifndef __sun - if ( (sym_p->s_nam = inf.dli_sname) ) { - sym_p->s_val = inf.dli_saddr; - /* Have a symbol name - just use it and be done */ - return 0; - } -#endif - - /* No symbol info; try to access ELF file and ready symbol table from there */ - - elfsLockWrite(); - - /* See if we have loaded this file already */ - es = elfSymsFind(inf.dli_fname); - - if ( !es ) { - - elfsUnlockWrite(); - - if ( ! (nes = elfRead(inf.dli_fname, (uintptr_t)inf.dli_fbase)) ) { - /* this path can only be taken if there is no memory for '*nes' */ - return 0; - } - - elfsLockWrite(); - - /* Has someone else intervened and already added this file while we were reading ? */ - es = elfSymsFind(inf.dli_fname); - - if ( es ) { - /* will undo our work in the unlikely event... */ - } else { - nes->next = elfs; - es = elfs = nes; - nes = 0; - } - } - - elfsUnlockWrite(); - - /* Undo our work in the unlikely event that it was redundant */ - if ( nes ) - elfSymsDestroy( nes ); - - nearest.raw = 0; - minoff = (uintptr_t)-1LL; - - if ( es->nsyms ) { - c = es->eclss; - sym.raw = (char*)es->symMap->addr + es->symMap->off; - strtab = (char*)es->strMap->addr + es->strMap->off; - - /* Do a brute-force search through the symbol table; if this is executed - * very often then it would be worthwhile constructing a sorted list of - * symbol addresses but for the stack trace we don't care... - */ -#if (FIND_ADDR_DEBUG & 1) - printf("Looking for %p\n", addr); -#endif - - if ( ELFCLASS32 == c ) { - for ( i=0; insyms; i++ ) { - if ( STT_FUNC != ELF32_ST_TYPE(sym.e32[i].st_info) ) - continue; - /* don't bother about undefined symbols */ - if ( 0 == sym.e32[i].st_shndx ) - continue; -#if (FIND_ADDR_DEBUG & 1) - printf("Trying: %s (0x%lx)\n", strtab + sym.e32[i].st_name, (unsigned long)(sym.e32[i].st_value + es->addr)); -#endif - if ( (uintptr_t)addr >= (uintptr_t)sym.e32[i].st_value + es->addr ) { - off = (uintptr_t)addr - ((uintptr_t)sym.e32[i].st_value + es->addr); - if ( off < minoff ) { - minoff = off; - nearest.e32 = &sym.e32[i]; - } - } - } - } else { - for ( i=0; insyms; i++ ) { - if ( STT_FUNC != ELF64_ST_TYPE(sym.e64[i].st_info) ) - continue; - /* don't bother about undefined symbols */ - if ( 0 == sym.e64[i].st_shndx ) - continue; -#if (FIND_ADDR_DEBUG & 1) - printf("Trying: %s (0x%llx)\n", strtab + sym.e64[i].st_name, (unsigned long long)(sym.e64[i].st_value + es->addr)); -#endif - if ( (uintptr_t)addr >= (uintptr_t)sym.e64[i].st_value + es->addr ) { - off = (uintptr_t)addr - ((uintptr_t)sym.e64[i].st_value + es->addr); - if ( off < minoff ) { - minoff = off; - nearest.e64 = &sym.e64[i]; - } - } - } - } - } - - if ( nearest.raw && ( (idx = ARR(c,nearest,0,st_name)) < es->strMap->max ) ) { - sym_p->s_nam = strtab + idx; - sym_p->s_val = (char*) ARR(c, nearest, 0, st_value) + es->addr; - } - - return 0; -} - -int epicsFindAddrGetFeatures(void) -{ - /* The static information given here may not be correct; - * it also depends on - * - compilation (frame pointer optimization) - * - linkage (static vs. dynamic) - * - stripping - */ - return EPICS_STACKTRACE_LCL_SYMBOLS - | EPICS_STACKTRACE_GBL_SYMBOLS - | EPICS_STACKTRACE_DYN_SYMBOLS; -} diff --git a/src/libCom/osi/os/posix/osdEvent.c b/src/libCom/osi/os/posix/osdEvent.c deleted file mode 100644 index f133ed028..000000000 --- a/src/libCom/osi/os/posix/osdEvent.c +++ /dev/null @@ -1,158 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/posix/osdEvent.c */ - -/* Author: Marty Kraimer Date: 13AUG1999 */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsEvent.h" -#include "epicsTime.h" -#include "errlog.h" - -struct epicsEventOSD { - pthread_mutex_t mutex; - pthread_cond_t cond; - int isFull; -}; - -#define printStatus(status, routine, func) \ - errlogPrintf("%s: %s failed: %s\n", (func), (routine), strerror(status)) - -#define checkStatus(status, routine, func) \ - if (status) { \ - printStatus(status, routine, func); \ - } - -#define checkStatusReturn(status, routine, func) \ - if (status) { \ - printStatus(status, routine, func); \ - return epicsEventError; \ - } - - -epicsShareFunc epicsEventId epicsEventCreate(epicsEventInitialState init) -{ - epicsEventId pevent = malloc(sizeof(*pevent)); - - if (pevent) { - int status = pthread_mutex_init(&pevent->mutex, 0); - - pevent->isFull = (init == epicsEventFull); - if (status) { - printStatus(status, "pthread_mutex_init", "epicsEventCreate"); - } else { - status = pthread_cond_init(&pevent->cond, 0); - if (!status) - return pevent; - printStatus(status, "pthread_cond_init", "epicsEventCreate"); - status = pthread_mutex_destroy(&pevent->mutex); - checkStatus(status, "pthread_mutex_destroy", "epicsEventCreate"); - } - free(pevent); - } - return NULL; -} - -epicsShareFunc void epicsEventDestroy(epicsEventId pevent) -{ - int status = pthread_mutex_destroy(&pevent->mutex); - - checkStatus(status, "pthread_mutex_destroy", "epicsEventDestroy"); - status = pthread_cond_destroy(&pevent->cond); - checkStatus(status, "pthread_cond_destroy", "epicsEventDestroy"); - free(pevent); -} - -epicsShareFunc epicsEventStatus epicsEventTrigger(epicsEventId pevent) -{ - int status = pthread_mutex_lock(&pevent->mutex); - - checkStatusReturn(status, "pthread_mutex_lock", "epicsEventTrigger"); - if (!pevent->isFull) { - pevent->isFull = 1; - status = pthread_cond_signal(&pevent->cond); - checkStatus(status, "pthread_cond_signal", "epicsEventTrigger"); - } - status = pthread_mutex_unlock(&pevent->mutex); - checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventTrigger"); - return epicsEventOK; -} - -epicsShareFunc epicsEventStatus epicsEventWait(epicsEventId pevent) -{ - epicsEventStatus result = epicsEventOK; - int status = pthread_mutex_lock(&pevent->mutex); - - checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWait"); - while (!pevent->isFull) { - status = pthread_cond_wait(&pevent->cond, &pevent->mutex); - if (status) { - printStatus(status, "pthread_cond_wait", "epicsEventWait"); - result = epicsEventError; - goto release; - } - } - pevent->isFull = 0; - result = epicsEventOK; -release: - status = pthread_mutex_unlock(&pevent->mutex); - checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWait"); - return result; -} - -epicsShareFunc epicsEventStatus epicsEventWaitWithTimeout(epicsEventId pevent, - double timeout) -{ - epicsEventStatus result = epicsEventOK; - int status = pthread_mutex_lock(&pevent->mutex); - - checkStatusReturn(status, "pthread_mutex_lock", "epicsEventWaitWithTimeout"); - if (!pevent->isFull) { - struct timespec wakeTime; - - convertDoubleToWakeTime(timeout, &wakeTime); - while (!status && !pevent->isFull) { - status = pthread_cond_timedwait(&pevent->cond, &pevent->mutex, - &wakeTime); - } - if (status) { - result = (status == ETIMEDOUT) ? - epicsEventWaitTimeout : epicsEventError; - goto release; - } - } - pevent->isFull = 0; -release: - status = pthread_mutex_unlock(&pevent->mutex); - checkStatusReturn(status, "pthread_mutex_unlock", "epicsEventWaitWithTimeout"); - return result; -} - -epicsShareFunc epicsEventStatus epicsEventTryWait(epicsEventId id) -{ - return epicsEventWaitWithTimeout(id, 0.0); -} - -epicsShareFunc void epicsEventShow(epicsEventId pevent, unsigned int level) -{ - printf("epicsEvent %p: %s\n", pevent, - pevent->isFull ? "full" : "empty"); - if (level > 0) - printf(" pthread_mutex = %p, pthread_cond = %p\n", - &pevent->mutex, &pevent->cond); -} diff --git a/src/libCom/osi/os/posix/osdEvent.h b/src/libCom/osi/os/posix/osdEvent.h deleted file mode 100644 index e2f8b9af9..000000000 --- a/src/libCom/osi/os/posix/osdEvent.h +++ /dev/null @@ -1,10 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* for a pure posix implementation no osdEvent.h definitions are needed*/ diff --git a/src/libCom/osi/os/posix/osdExecinfoBackTrace.cpp b/src/libCom/osi/os/posix/osdExecinfoBackTrace.cpp deleted file mode 100644 index ae13d28fc..000000000 --- a/src/libCom/osi/os/posix/osdExecinfoBackTrace.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" - -int epicsBackTrace(void **buf, int buf_sz) -{ - return backtrace(buf, buf_sz); -} diff --git a/src/libCom/osi/os/posix/osdFindSymbol.c b/src/libCom/osi/os/posix/osdFindSymbol.c deleted file mode 100644 index acfc405e5..000000000 --- a/src/libCom/osi/os/posix/osdFindSymbol.c +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/posix/osdFindSymbol.c */ - -#include - -#define epicsExportSharedSymbols -#include "epicsFindSymbol.h" - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - return dlopen(name, RTLD_LAZY | RTLD_GLOBAL); -} - -epicsShareFunc const char *epicsLoadError(void) -{ - return dlerror(); -} - -epicsShareFunc void * epicsShareAPI epicsFindSymbol(const char *name) -{ - return dlsym(0, name); -} diff --git a/src/libCom/osi/os/posix/osdMutex.c b/src/libCom/osi/os/posix/osdMutex.c deleted file mode 100644 index f569916a5..000000000 --- a/src/libCom/osi/os/posix/osdMutex.c +++ /dev/null @@ -1,331 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/posix/osdMutex.c */ - -/* Author: Marty Kraimer Date: 13AUG1999 */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMutex.h" -#include "cantProceed.h" -#include "epicsTime.h" -#include "errlog.h" -#include "epicsAssert.h" - -#define checkStatus(status,message) \ - if((status)) { \ - errlogPrintf("epicsMutex %s failed: error %s\n", \ - (message), strerror((status))); \ - } -#define checkStatusQuit(status,message,method) \ - if(status) { \ - errlogPrintf("epicsMutex %s failed: error %s\n", \ - (message), strerror((status))); \ - cantProceed((method)); \ - } - -static int mutexLock(pthread_mutex_t *id) -{ - int status; - - while ((status = pthread_mutex_lock(id)) == EINTR) { - errlogPrintf("pthread_mutex_lock returned EINTR. Violates SUSv3\n"); - } - return status; -} - -/* Until these can be demonstrated to work leave them undefined*/ -/* On solaris 8 _POSIX_THREAD_PRIO_INHERIT fails*/ -#undef _POSIX_THREAD_PROCESS_SHARED -#undef _POSIX_THREAD_PRIO_INHERIT - -/* Two completely different implementations are provided below - * If support is available for PTHREAD_MUTEX_RECURSIVE then - * only pthread_mutex is used. - * If support is not available for PTHREAD_MUTEX_RECURSIVE then - * a much more complicated solution is required - */ - - -#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 -typedef struct epicsMutexOSD { - pthread_mutex_t lock; - pthread_mutexattr_t mutexAttr; -} epicsMutexOSD; - -epicsMutexOSD * epicsMutexOsdCreate(void) { - epicsMutexOSD *pmutex; - int status; - - pmutex = calloc(1, sizeof(*pmutex)); - if(!pmutex) - goto fail; - - status = pthread_mutexattr_init(&pmutex->mutexAttr); - if (status) - goto fail; - -#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 - status = pthread_mutexattr_setprotocol(&pmutex->mutexAttr, - PTHREAD_PRIO_INHERIT); - if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocal"); -#endif /*_POSIX_THREAD_PRIO_INHERIT*/ - - status = pthread_mutexattr_settype(&pmutex->mutexAttr, - PTHREAD_MUTEX_RECURSIVE); - checkStatus(status, "pthread_mutexattr_settype"); - if (status) - goto fail; - - status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr); - if (status) - goto dattr; - return pmutex; - -dattr: - pthread_mutexattr_destroy(&pmutex->mutexAttr); -fail: - free(pmutex); - return NULL; -} - -void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex) -{ - int status; - - status = pthread_mutex_destroy(&pmutex->lock); - checkStatus(status, "pthread_mutex_destroy"); - status = pthread_mutexattr_destroy(&pmutex->mutexAttr); - checkStatus(status, "pthread_mutexattr_destroy"); - free(pmutex); -} - -void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex) -{ - int status; - - status = pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock"); -} - -epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex) -{ - int status; - - status = mutexLock(&pmutex->lock); - if (status == EINVAL) return epicsMutexLockError; - if(status) { - errlogMessage("epicsMutex pthread_mutex_lock failed: error epicsMutexOsdLock\n"); - return epicsMutexLockError; - } - return epicsMutexLockOK; -} - -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex) -{ - int status; - - if (!pmutex) return epicsMutexLockError; - status = pthread_mutex_trylock(&pmutex->lock); - if (status == EINVAL) return epicsMutexLockError; - if (status == EBUSY) return epicsMutexLockTimeout; - if(status) { - errlogMessage("epicsMutex pthread_mutex_trylock failed: error epicsMutexOsdTryLock"); - return epicsMutexLockError; - } - return epicsMutexLockOK; -} - -void epicsMutexOsdShow(struct epicsMutexOSD * pmutex, unsigned int level) -{ -} - -#else /*defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 */ - -typedef struct epicsMutexOSD { - pthread_mutex_t lock; - pthread_mutexattr_t mutexAttr; - pthread_cond_t waitToBeOwner; -#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 - pthread_condattr_t condAttr; -#endif /*_POSIX_THREAD_PROCESS_SHARED*/ - int count; - int owned; /* TRUE | FALSE */ - pthread_t ownerTid; -} epicsMutexOSD; - -epicsMutexOSD * epicsMutexOsdCreate(void) { - epicsMutexOSD *pmutex; - int status; - - pmutex = calloc(1, sizeof(*pmutex)); - if(!pmutex) - return NULL; - - status = pthread_mutexattr_init(&pmutex->mutexAttr); - if(status) - goto fail; - -#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0 - status = pthread_mutexattr_setprotocol( - &pmutex->mutexAttr,PTHREAD_PRIO_INHERIT); - if (errVerbose) checkStatus(status, "pthread_mutexattr_setprotocal"); -#endif /*_POSIX_THREAD_PRIO_INHERIT*/ - - status = pthread_mutex_init(&pmutex->lock, &pmutex->mutexAttr); - if(status) - goto dattr; - -#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 - status = pthread_condattr_init(&pmutex->condAttr); - checkStatus(status, "pthread_condattr_init"); - status = pthread_condattr_setpshared(&pmutex->condAttr, - PTHREAD_PROCESS_PRIVATE); - checkStatus(status, "pthread_condattr_setpshared"); - status = pthread_cond_init(&pmutex->waitToBeOwner, &pmutex->condAttr); -#else - status = pthread_cond_init(&pmutex->waitToBeOwner, 0); -#endif /*_POSIX_THREAD_PROCESS_SHARED*/ - if(status) - goto dmutex; - - return pmutex; - -dmutex: - pthread_mutex_destroy(&pmutex->lock); -dattr: - pthread_mutexattr_destroy(&pmutex->mutexAttr); -fail: - free(pmutex); - return NULL; -} - -void epicsMutexOsdDestroy(struct epicsMutexOSD * pmutex) -{ - int status; - - status = pthread_cond_destroy(&pmutex->waitToBeOwner); - checkStatus(status, "pthread_cond_destroy"); -#if defined(_POSIX_THREAD_PROCESS_SHARED) && _POSIX_THREAD_PROCESS_SHARED > 0 - status = pthread_condattr_destroy(&pmutex->condAttr); -#endif /*_POSIX_THREAD_PROCESS_SHARED*/ - status = pthread_mutex_destroy(&pmutex->lock); - checkStatus(status, "pthread_mutex_destroy"); - status = pthread_mutexattr_destroy(&pmutex->mutexAttr); - checkStatus(status, "pthread_mutexattr_destroy"); - free(pmutex); -} - -void epicsMutexOsdUnlock(struct epicsMutexOSD * pmutex) -{ - int status; - - status = mutexLock(&pmutex->lock); - checkStatus(status, "pthread_mutex_lock epicsMutexOsdUnlock"); - if(status) - return; - - if ((pmutex->count <= 0) || (pmutex->ownerTid != pthread_self())) { - pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock"); - errlogPrintf("epicsMutexOsdUnlock but caller is not owner\n"); - cantProceed("epicsMutexOsdUnlock but caller is not owner"); - return; - } - - pmutex->count--; - if (pmutex->count == 0) { - pmutex->owned = 0; - pmutex->ownerTid = 0; - status = pthread_cond_signal(&pmutex->waitToBeOwner); - checkStatusQuit(status, "pthread_cond_signal epicsMutexOsdUnlock", "epicsMutexOsdUnlock"); - } - - status = pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdUnlock"); -} - -static int condWait(pthread_cond_t *condId, pthread_mutex_t *mutexId) -{ - int status; - - while ((status = pthread_cond_wait(condId, mutexId)) == EINTR) { - errlogPrintf("pthread_cond_wait returned EINTR. Violates SUSv3\n"); - } - return status; -} - -epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD * pmutex) -{ - pthread_t tid = pthread_self(); - int status; - - if (!pmutex || !tid) return epicsMutexLockError; - status = mutexLock(&pmutex->lock); - if (status == EINVAL) return epicsMutexLockError; - checkStatus(status, "pthread_mutex_lock epicsMutexOsdLock"); - if(status) - return epicsMutexLockError; - - while (pmutex->owned && !pthread_equal(pmutex->ownerTid, tid)) - condWait(&pmutex->waitToBeOwner, &pmutex->lock); - pmutex->ownerTid = tid; - pmutex->owned = 1; - pmutex->count++; - - status = pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdLock"); - if(status) - return epicsMutexLockError; - return epicsMutexLockOK; -} - -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * pmutex) -{ - pthread_t tid = pthread_self(); - epicsMutexLockStatus result; - int status; - - status = mutexLock(&pmutex->lock); - if (status == EINVAL) return epicsMutexLockError; - checkStatus(status, "pthread_mutex_lock epicsMutexOsdTryLock"); - if(status) - return epicsMutexLockError; - - if (!pmutex->owned || pthread_equal(pmutex->ownerTid, tid)) { - pmutex->ownerTid = tid; - pmutex->owned = 1; - pmutex->count++; - result = epicsMutexLockOK; - } else { - result = epicsMutexLockTimeout; - } - - status = pthread_mutex_unlock(&pmutex->lock); - checkStatus(status, "pthread_mutex_unlock epicsMutexOsdTryLock"); - if(status) - return epicsMutexLockError; - return result; -} - -void epicsMutexOsdShow(struct epicsMutexOSD *pmutex,unsigned int level) -{ - printf("ownerTid %p count %d owned %d\n", - (void *)pmutex->ownerTid, pmutex->count, pmutex->owned); -} -#endif /*defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE)>=500 */ diff --git a/src/libCom/osi/os/posix/osdMutex.h b/src/libCom/osi/os/posix/osdMutex.h deleted file mode 100644 index cc416384a..000000000 --- a/src/libCom/osi/os/posix/osdMutex.h +++ /dev/null @@ -1,10 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* for a pure posix implementation no osdMutex.h definitions are needed*/ diff --git a/src/libCom/osi/os/posix/osdProcess.c b/src/libCom/osi/os/posix/osdProcess.c deleted file mode 100644 index a08871465..000000000 --- a/src/libCom/osi/os/posix/osdProcess.c +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Operating System Dependent Implementation of osiProcess.h - * - * Author: Jeff Hill - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "osiProcess.h" -#include "errlog.h" -#include "epicsAssert.h" - -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSizeIn) -{ - struct passwd *p; - - p = getpwuid ( getuid () ); - if ( p && p->pw_name ) { - size_t len = strlen ( p->pw_name ); - unsigned uiLength; - - if ( len > UINT_MAX || len <= 0 ) { - return osiGetUserNameFail; - } - uiLength = (unsigned) len; - - if ( uiLength + 1 >= bufSizeIn ) { - return osiGetUserNameFail; - } - - strncpy ( pBuf, p->pw_name, (size_t) bufSizeIn ); - - return osiGetUserNameSuccess; - } - else { - return osiGetUserNameFail; - } -} - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - (const char *pProcessName, const char *pBaseExecutableName) -{ - int status; - - /* - * create a duplicate process - */ - status = fork (); - if (status < 0) { - return osiSpawnDetachedProcessFail; - } - - /* - * return to the caller - * in the initiating (parent) process - */ - if (status) { - return osiSpawnDetachedProcessSuccess; - } - - /* - * This is executed only by the new child process. - * Close all open files except for STDIO, so they will not - * be inherited by the new program. - */ - { - int fd, maxfd = sysconf ( _SC_OPEN_MAX ); - for ( fd = 0; fd <= maxfd; fd++ ) { - if (fd==STDIN_FILENO) continue; - if (fd==STDOUT_FILENO) continue; - if (fd==STDERR_FILENO) continue; - close (fd); - } - } - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - /* - * Drop real-time SCHED_FIFO priority - */ - { - struct sched_param p; - - p.sched_priority = 0; - status = sched_setscheduler(0, SCHED_OTHER, &p); - } -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - /* - * Run the specified executable - */ - status = execlp (pBaseExecutableName, pBaseExecutableName, (char *)NULL); - if ( status < 0 ) { - fprintf ( stderr, "**** The executable \"%s\" couldn't be located\n", pBaseExecutableName ); - fprintf ( stderr, "**** because of errno = \"%s\".\n", strerror (errno) ); - fprintf ( stderr, "**** You may need to modify your PATH environment variable.\n" ); - fprintf ( stderr, "**** Unable to start \"%s\" process.\n", pProcessName); - } - /* Don't run our parent's atexit() handlers */ - _exit ( -1 ); -} diff --git a/src/libCom/osi/os/posix/osdSignal.cpp b/src/libCom/osi/os/posix/osdSignal.cpp deleted file mode 100644 index 3f8deb4fb..000000000 --- a/src/libCom/osi/os/posix/osdSignal.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Authors: J. Hill, A. Johnson - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -static void ignoreIfDefault(int signum, const char *name) -{ - struct sigaction curAction; - int status = sigaction(signum, NULL, &curAction); - - if (status >= 0 && - curAction.sa_handler == SIG_DFL) { - curAction.sa_handler = SIG_IGN; - status = sigaction(signum, &curAction, NULL); - } - if (status < 0) { - fprintf(stderr, "%s: sigaction failed for %s, %s\n", - __FILE__, name, strerror(errno)); - } -} - -/* - * epicsSignalInstallSigHupIgnore () - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore (void) -{ - ignoreIfDefault(SIGHUP, "SIGHUP"); -} - -/* - * epicsSignalInstallSigPipeIgnore () - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore (void) -{ - ignoreIfDefault(SIGPIPE, "SIGPIPE"); -} - -/* Disabled */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm - ( struct epicsThreadOSD * /* threadId */ ) {} diff --git a/src/libCom/osi/os/posix/osdSock.c b/src/libCom/osi/os/posix/osdSock.c deleted file mode 100644 index 9f8146142..000000000 --- a/src/libCom/osi/os/posix/osdSock.c +++ /dev/null @@ -1,183 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdSock.c */ -/* - * Author: Jeff Hill - * Date: 04-05-94 - * - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "osiSock.h" -#include "epicsAssert.h" -#include "errlog.h" - -/* - * Protect some routines which are not thread-safe - */ -static epicsMutexId infoMutex; -static void createInfoMutex (void *unused) -{ - infoMutex = epicsMutexMustCreate (); -} -static void lockInfo (void) -{ - static epicsThreadOnceId infoMutexOnceFlag = EPICS_THREAD_ONCE_INIT; - - epicsThreadOnce (&infoMutexOnceFlag, createInfoMutex, NULL); - epicsMutexMustLock (infoMutex); -} -static void unlockInfo (void) -{ - epicsMutexUnlock (infoMutex); -} - -/* - * NOOP - */ -int osiSockAttach() -{ - return 1; -} - -/* - * NOOP - */ -void osiSockRelease() -{ -} - -/* - * this version sets the file control flags so that - * the socket will be closed if the user uses exec() - * as is the case with third party tools such as TCL/TK - */ -epicsShareFunc SOCKET epicsShareAPI epicsSocketCreate ( - int domain, int type, int protocol ) -{ - SOCKET sock = socket ( domain, type, protocol ); - if ( sock < 0 ) { - sock = INVALID_SOCKET; - } - else { - int status = fcntl ( sock, F_SETFD, FD_CLOEXEC ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketCreate: failed to " - "fcntl FD_CLOEXEC because \"%s\"\n", - buf ); - close ( sock ); - sock = INVALID_SOCKET; - } - } - return sock; -} - -epicsShareFunc int epicsShareAPI epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) -{ - int newSock = accept ( sock, pAddr, addrlen ); - if ( newSock < 0 ) { - newSock = INVALID_SOCKET; - } - else { - int status = fcntl ( newSock, F_SETFD, FD_CLOEXEC ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketCreate: failed to " - "fcntl FD_CLOEXEC because \"%s\"\n", - buf ); - close ( newSock ); - newSock = INVALID_SOCKET; - } - } - return newSock; -} - -epicsShareFunc void epicsShareAPI epicsSocketDestroy ( SOCKET s ) -{ - int status = close ( s ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketDestroy: failed to " - "close a socket because \"%s\"\n", - buf ); - } -} - -/* - * ipAddrToHostName - * On many systems, gethostbyaddr must be protected by a - * mutex since the routine is not thread-safe. - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName - (const struct in_addr *pAddr, char *pBuf, unsigned bufSize) -{ - struct hostent *ent; - int ret = 0; - - if (bufSize<1) { - return 0; - } - - lockInfo (); - ent = gethostbyaddr((const char *) pAddr, sizeof (*pAddr), AF_INET); - if (ent) { - strncpy (pBuf, ent->h_name, bufSize); - pBuf[bufSize-1] = '\0'; - ret = strlen (pBuf); - } - unlockInfo (); - return ret; -} - -/* - * hostToIPAddr () - * On many systems, gethostbyname must be protected by a - * mutex since the routine is not thread-safe. - */ -epicsShareFunc int epicsShareAPI hostToIPAddr - (const char *pHostName, struct in_addr *pIPA) -{ - struct hostent *phe; - int ret = -1; - - lockInfo (); - phe = gethostbyname (pHostName); - if (phe && phe->h_addr_list[0]) { - if (phe->h_addrtype==AF_INET && phe->h_length<=sizeof(struct in_addr)) { - struct in_addr *pInAddrIn = (struct in_addr *) phe->h_addr_list[0]; - - *pIPA = *pInAddrIn; - ret = 0; - } - } - unlockInfo (); - return ret; -} - - - diff --git a/src/libCom/osi/os/posix/osdSockAddrReuse.cpp b/src/libCom/osi/os/posix/osdSockAddrReuse.cpp deleted file mode 100644 index 3a3f78ebd..000000000 --- a/src/libCom/osi/os/posix/osdSockAddrReuse.cpp +++ /dev/null @@ -1,49 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" -#include "errlog.h" - -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnableAddressReuseDuringTimeWaitState: " - "unable to set SO_REUSEADDR?\n"); - } -} - -/* - * SO_REUSEPORT is not in POSIX - */ -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ) -{ - int yes = true; - int status; - status = setsockopt ( s, SOL_SOCKET, SO_REUSEADDR, - (char *) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - errlogPrintf ( - "epicsSocketEnablePortUseForDatagramFanout: " - "unable to set SO_REUSEADDR?\n"); - } -} diff --git a/src/libCom/osi/os/posix/osdSpin.c b/src/libCom/osi/os/posix/osdSpin.c deleted file mode 100644 index aa61a6c90..000000000 --- a/src/libCom/osi/os/posix/osdSpin.c +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "errlog.h" -#include "cantProceed.h" -#include "epicsSpin.h" - -/* POSIX spinlocks may be subject to priority inversion - * and so can't be guaranteed safe in situations where - * threads have different priorities, and thread - * preemption can't be disabled. - */ -#if defined(DONT_USE_POSIX_THREAD_PRIORITY_SCHEDULING) -#if defined(_POSIX_SPIN_LOCKS) && (_POSIX_SPIN_LOCKS > 0) -# define USE_PSPIN -#endif -#endif - -#define checkStatus(status,message) \ - if ((status)) { \ - errlogPrintf("epicsSpin %s failed: error %s\n", \ - (message), strerror((status))); \ - } - -#ifdef USE_PSPIN - -/* - * POSIX SPIN LOCKS IMPLEMENTATION - */ - -typedef struct epicsSpin { - pthread_spinlock_t lock; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - epicsSpin *spin; - int status; - - spin = calloc(1, sizeof(*spin)); - if (!spin) - goto fail; - - status = pthread_spin_init(&spin->lock, PTHREAD_PROCESS_PRIVATE); - checkStatus(status, "pthread_spin_init"); - if (status) - goto fail; - - return spin; - -fail: - free(spin); - return NULL; -} - -void epicsSpinDestroy(epicsSpinId spin) { - int status; - - status = pthread_spin_destroy(&spin->lock); - checkStatus(status, "pthread_spin_destroy"); - - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - int status; - - status = pthread_spin_lock(&spin->lock); - checkStatus(status, "pthread_spin_lock"); - if (status) - cantProceed(NULL); -} - -int epicsSpinTryLock(epicsSpinId spin) { - int status; - - status = pthread_spin_trylock(&spin->lock); - if (status == EBUSY) - return 1; - checkStatus(status, "pthread_spin_trylock"); - return status; -} - -void epicsSpinUnlock(epicsSpinId spin) { - int status; - - status = pthread_spin_unlock(&spin->lock); - checkStatus(status, "pthread_spin_unlock"); -} - -#else /* USE_PSPIN */ - -/* - * POSIX MUTEX IMPLEMENTATION - */ - -typedef struct epicsSpin { - pthread_mutex_t lock; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - epicsSpin *spin; - int status; - - spin = calloc(1, sizeof(*spin)); - if (!spin) - goto fail; - - status = pthread_mutex_init(&spin->lock, NULL); - checkStatus(status, "pthread_mutex_init"); - if (status) - goto fail; - - return spin; - -fail: - free(spin); - return NULL; -} - -void epicsSpinDestroy(epicsSpinId spin) { - int status; - - status = pthread_mutex_destroy(&spin->lock); - checkStatus(status, "pthread_mutex_destroy"); - - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - int status; - - status = pthread_mutex_lock(&spin->lock); - checkStatus(status, "pthread_mutex_lock"); - if (status) - cantProceed(NULL); -} - -int epicsSpinTryLock(epicsSpinId spin) { - int status; - - status = pthread_mutex_trylock(&spin->lock); - if (status == EBUSY) - return 1; - checkStatus(status, "pthread_mutex_trylock"); - return status; -} - -void epicsSpinUnlock(epicsSpinId spin) { - int status; - - status = pthread_mutex_unlock(&spin->lock); - checkStatus(status, "pthread_mutex_unlock"); -} - -#endif /* USE_PSPIN */ - - -epicsSpinId epicsSpinMustCreate(void) -{ - epicsSpinId ret = epicsSpinCreate(); - if(!ret) - cantProceed("epicsSpinMustCreate: epicsSpinCreate failed."); - return ret; -} diff --git a/src/libCom/osi/os/posix/osdStdio.c b/src/libCom/osi/os/posix/osdStdio.c deleted file mode 100644 index 2a23cee71..000000000 --- a/src/libCom/osi/os/posix/osdStdio.c +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#define epicsExportSharedSymbols -#include - -epicsShareFunc int epicsShareAPI epicsSnprintf( - char *str, size_t size, const char *format, ...) -{ - int nchars; - va_list pvar; - - va_start(pvar,format); - nchars = epicsVsnprintf(str,size,format,pvar); - va_end (pvar); - return(nchars); -} - -epicsShareFunc int epicsShareAPI epicsVsnprintf( - char *str, size_t size, const char *format, va_list ap) -{ - return vsnprintf ( str, size, format, ap ); -} diff --git a/src/libCom/osi/os/posix/osdStrtod.h b/src/libCom/osi/os/posix/osdStrtod.h deleted file mode 100644 index 502889a9d..000000000 --- a/src/libCom/osi/os/posix/osdStrtod.h +++ /dev/null @@ -1,15 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header fragment is intended to be included as part of epicsString.h - */ - -/* - * epicsStrtod() for systems with working strtod() routine - */ -#define epicsStrtod strtod diff --git a/src/libCom/osi/os/posix/osdThread.c b/src/libCom/osi/os/posix/osdThread.c deleted file mode 100644 index 755390eed..000000000 --- a/src/libCom/osi/os/posix/osdThread.c +++ /dev/null @@ -1,914 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 18JAN2000 */ - -/* This is a posix implementation of epicsThread */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0 -#include -#endif - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsString.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "errlog.h" -#include "epicsAssert.h" -#include "epicsExit.h" - -epicsShareFunc void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level); -epicsShareFunc void osdThreadHooksRun(epicsThreadId id); -epicsShareFunc void osdThreadHooksRunMain(epicsThreadId id); - -static int mutexLock(pthread_mutex_t *id) -{ - int status; - - while(1) { - status = pthread_mutex_lock(id); - if(status!=EINTR) return status; - fprintf(stderr,"pthread_mutex_lock returned EINTR. Violates SUSv3\n"); - } -} - -#if defined DONT_USE_POSIX_THREAD_PRIORITY_SCHEDULING -#undef _POSIX_THREAD_PRIORITY_SCHEDULING -#endif - -typedef struct commonAttr{ - pthread_attr_t attr; - struct sched_param schedParam; - int maxPriority; - int minPriority; - int schedPolicy; - int usePolicy; -} commonAttr; - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 -typedef struct { - int min_pri, max_pri; - int policy; - int ok; -} priAvailable; -#endif - -static pthread_key_t getpthreadInfo; -static pthread_mutex_t onceLock; -static pthread_mutex_t listLock; -static ELLLIST pthreadList = ELLLIST_INIT; -static commonAttr *pcommonAttr = 0; -static int epicsThreadOnceCalled = 0; - -static epicsThreadOSD *createImplicit(void); - -#define checkStatus(status,message) \ -if((status)) {\ - errlogPrintf("%s error %s\n",(message),strerror((status))); \ -} - -#define checkStatusQuit(status,message,method) \ -if(status) { \ - errlogPrintf("%s error %s\n",(message),strerror((status))); \ - cantProceed((method)); \ -} - -/* The following are for use by once, which is only invoked from epicsThreadInit*/ -/* Until epicsThreadInit completes errlogInit will not work */ -/* It must also be used by init_threadInfo otherwise errlogInit could get */ -/* called recursively */ -#define checkStatusOnce(status,message) \ -if((status)) {\ - fprintf(stderr,"%s error %s\n",(message),strerror((status))); } - -#define checkStatusOnceQuit(status,message,method) \ -if(status) { \ - fprintf(stderr,"%s error %s",(message),strerror((status))); \ - fprintf(stderr," %s\n",method); \ - fprintf(stderr,"epicsThreadInit cant proceed. Program exiting\n"); \ - exit(-1);\ -} - - -epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId pthreadInfo) -{ -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - double maxPriority,minPriority,slope,oss; - - if(pcommonAttr->maxPriority==pcommonAttr->minPriority) - return(pcommonAttr->maxPriority); - maxPriority = (double)pcommonAttr->maxPriority; - minPriority = (double)pcommonAttr->minPriority; - slope = (maxPriority - minPriority)/100.0; - oss = (double)pthreadInfo->osiPriority * slope + minPriority; - return((int)oss); -#else - return 0; -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ -} - -static void setSchedulingPolicy(epicsThreadOSD *pthreadInfo,int policy) -{ -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - int status; - - if(!pcommonAttr->usePolicy) return; - - status = pthread_attr_getschedparam( - &pthreadInfo->attr,&pthreadInfo->schedParam); - checkStatusOnce(status,"pthread_attr_getschedparam"); - pthreadInfo->schedParam.sched_priority = epicsThreadGetPosixPriority(pthreadInfo); - pthreadInfo->schedPolicy = policy; - status = pthread_attr_setschedpolicy( - &pthreadInfo->attr,policy); - checkStatusOnce(status,"pthread_attr_setschedpolicy"); - status = pthread_attr_setschedparam( - &pthreadInfo->attr,&pthreadInfo->schedParam); - checkStatusOnce(status,"pthread_attr_setschedparam"); - status = pthread_attr_setinheritsched( - &pthreadInfo->attr,PTHREAD_EXPLICIT_SCHED); - checkStatusOnce(status,"pthread_attr_setinheritsched"); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ -} - -static epicsThreadOSD * create_threadInfo(const char *name) -{ - epicsThreadOSD *pthreadInfo; - - /* sizeof(epicsThreadOSD) includes one byte for the '\0' */ - pthreadInfo = calloc(1,sizeof(*pthreadInfo) + strlen(name)); - if(!pthreadInfo) - return NULL; - pthreadInfo->suspendEvent = epicsEventCreate(epicsEventEmpty); - if(!pthreadInfo->suspendEvent){ - free(pthreadInfo); - return NULL; - } - strcpy(pthreadInfo->name, name); - return pthreadInfo; -} - -static epicsThreadOSD * init_threadInfo(const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - epicsThreadOSD *pthreadInfo; - int status; - - pthreadInfo = create_threadInfo(name); - if(!pthreadInfo) - return NULL; - pthreadInfo->createFunc = funptr; - pthreadInfo->createArg = parm; - status = pthread_attr_init(&pthreadInfo->attr); - checkStatusOnce(status,"pthread_attr_init"); - if(status) return 0; - status = pthread_attr_setdetachstate( - &pthreadInfo->attr, PTHREAD_CREATE_DETACHED); - checkStatusOnce(status,"pthread_attr_setdetachstate"); -#if defined (_POSIX_THREAD_ATTR_STACKSIZE) -#if ! defined (OSITHREAD_USE_DEFAULT_STACK) - status = pthread_attr_setstacksize( &pthreadInfo->attr,(size_t)stackSize); - checkStatusOnce(status,"pthread_attr_setstacksize"); -#endif /*OSITHREAD_USE_DEFAULT_STACK*/ -#endif /*_POSIX_THREAD_ATTR_STACKSIZE*/ - status = pthread_attr_setscope(&pthreadInfo->attr,PTHREAD_SCOPE_PROCESS); - if(errVerbose) checkStatusOnce(status,"pthread_attr_setscope"); - pthreadInfo->osiPriority = priority; - return(pthreadInfo); -} - -static void free_threadInfo(epicsThreadOSD *pthreadInfo) -{ - int status; - - status = mutexLock(&listLock); - checkStatusQuit(status,"pthread_mutex_lock","free_threadInfo"); - if(pthreadInfo->isOnThreadList) ellDelete(&pthreadList,&pthreadInfo->node); - status = pthread_mutex_unlock(&listLock); - checkStatusQuit(status,"pthread_mutex_unlock","free_threadInfo"); - epicsEventDestroy(pthreadInfo->suspendEvent); - status = pthread_attr_destroy(&pthreadInfo->attr); - checkStatusQuit(status,"pthread_attr_destroy","free_threadInfo"); - free(pthreadInfo); -} - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 -/* - * The actually available range priority range (at least under linux) - * may be restricted by resource limitations (but that is ignored - * by sched_get_priority_max()). See bug #835138 which is fixed by - * this code. - */ - -static int try_pri(int pri, int policy) -{ -struct sched_param schedp; - - schedp.sched_priority = pri; - return pthread_setschedparam(pthread_self(), policy, &schedp); -} - -static void* -find_pri_range(void *arg) -{ -priAvailable *prm = arg; -int min = sched_get_priority_min(prm->policy); -int max = sched_get_priority_max(prm->policy); -int low, try; - - if ( -1 == min || -1 == max ) { - /* something is very wrong; maintain old behavior - * (warning message if sched_get_priority_xxx() fails - * and use default policy's sched_priority [even if - * that is likely to cause epicsThreadCreate to fail - * because that priority is not suitable for SCHED_FIFO]). - */ - prm->min_pri = prm->max_pri = -1; - return 0; - } - - - if ( try_pri(min, prm->policy) ) { - /* cannot create thread at minimum priority; - * probably no permission to use SCHED_FIFO - * at all. However, we still must return - * a priority range accepted by the SCHED_FIFO - * policy. Otherwise, epicsThreadCreate() cannot - * detect the unsufficient permission (EPERM) - * and fall back to a non-RT thread (because - * pthread_attr_setschedparam would fail with - * EINVAL due to the bad priority). - */ - prm->min_pri = prm->max_pri = min; - return 0; - } - - - /* Binary search through available priorities. - * The actually available range may be restricted - * by resource limitations (but that is ignored - * by sched_get_priority_max() [linux]). - */ - low = min; - - while ( low < max ) { - try = (max+low)/2; - if ( try_pri(try, prm->policy) ) { - max = try; - } else { - low = try + 1; - } - } - - prm->min_pri = min; - prm->max_pri = try_pri(max, prm->policy) ? max-1 : max; - prm->ok = 1; - - return 0; -} - -static void findPriorityRange(commonAttr *a_p) -{ -priAvailable arg; -pthread_t id; -void *dummy; -int status; - - arg.policy = a_p->schedPolicy; - arg.ok = 0; - - status = pthread_create(&id, 0, find_pri_range, &arg); - checkStatusQuit(status, "pthread_create","epicsThreadInit"); - - status = pthread_join(id, &dummy); - checkStatusQuit(status, "pthread_join","epicsThreadInit"); - - a_p->minPriority = arg.min_pri; - a_p->maxPriority = arg.max_pri; - a_p->usePolicy = arg.ok; -} -#endif - - -static void once(void) -{ - epicsThreadOSD *pthreadInfo; - int status; - - pthread_key_create(&getpthreadInfo,0); - status = pthread_mutex_init(&onceLock,0); - checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit"); - status = pthread_mutex_init(&listLock,0); - checkStatusQuit(status,"pthread_mutex_init","epicsThreadInit"); - pcommonAttr = calloc(1,sizeof(commonAttr)); - if(!pcommonAttr) checkStatusOnceQuit(errno,"calloc","epicsThreadInit"); - status = pthread_attr_init(&pcommonAttr->attr); - checkStatusOnceQuit(status,"pthread_attr_init","epicsThreadInit"); - status = pthread_attr_setdetachstate( - &pcommonAttr->attr, PTHREAD_CREATE_DETACHED); - checkStatusOnce(status,"pthread_attr_setdetachstate"); - status = pthread_attr_setscope(&pcommonAttr->attr,PTHREAD_SCOPE_PROCESS); - if(errVerbose) checkStatusOnce(status,"pthread_attr_setscope"); - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - status = pthread_attr_setschedpolicy( - &pcommonAttr->attr,SCHED_FIFO); - checkStatusOnce(status,"pthread_attr_setschedpolicy"); - status = pthread_attr_getschedpolicy( - &pcommonAttr->attr,&pcommonAttr->schedPolicy); - checkStatusOnce(status,"pthread_attr_getschedpolicy"); - status = pthread_attr_getschedparam( - &pcommonAttr->attr,&pcommonAttr->schedParam); - checkStatusOnce(status,"pthread_attr_getschedparam"); - - findPriorityRange(pcommonAttr); - - if(pcommonAttr->maxPriority == -1) { - pcommonAttr->maxPriority = pcommonAttr->schedParam.sched_priority; - fprintf(stderr,"sched_get_priority_max failed set to %d\n", - pcommonAttr->maxPriority); - } - if(pcommonAttr->minPriority == -1) { - pcommonAttr->minPriority = pcommonAttr->schedParam.sched_priority; - fprintf(stderr,"sched_get_priority_min failed set to %d\n", - pcommonAttr->maxPriority); - } - - if (errVerbose) { - fprintf(stderr, "LRT: min priority: %d max priority %d\n", - pcommonAttr->minPriority, pcommonAttr->maxPriority); - } - -#else - if(errVerbose) fprintf(stderr,"task priorities are not implemented\n"); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - pthreadInfo = init_threadInfo("_main_",0,epicsThreadGetStackSize(epicsThreadStackSmall),0,0); - assert(pthreadInfo!=NULL); - status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo); - checkStatusOnceQuit(status,"pthread_setspecific","epicsThreadInit"); - status = mutexLock(&listLock); - checkStatusQuit(status,"pthread_mutex_lock","epicsThreadInit"); - ellAdd(&pthreadList,&pthreadInfo->node); - pthreadInfo->isOnThreadList = 1; - status = pthread_mutex_unlock(&listLock); - checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadInit"); - status = atexit(epicsExitCallAtExits); - checkStatusOnce(status,"atexit"); - osdThreadHooksRunMain(pthreadInfo); - epicsThreadOnceCalled = 1; -} - -static void * start_routine(void *arg) -{ - epicsThreadOSD *pthreadInfo = (epicsThreadOSD *)arg; - int status; - sigset_t blockAllSig; - - sigfillset(&blockAllSig); - pthread_sigmask(SIG_SETMASK,&blockAllSig,NULL); - status = pthread_setspecific(getpthreadInfo,arg); - checkStatusQuit(status,"pthread_setspecific","start_routine"); - status = mutexLock(&listLock); - checkStatusQuit(status,"pthread_mutex_lock","start_routine"); - ellAdd(&pthreadList,&pthreadInfo->node); - pthreadInfo->isOnThreadList = 1; - status = pthread_mutex_unlock(&listLock); - checkStatusQuit(status,"pthread_mutex_unlock","start_routine"); - osdThreadHooksRun(pthreadInfo); - - (*pthreadInfo->createFunc)(pthreadInfo->createArg); - - epicsExitCallAtThreadExits (); - free_threadInfo(pthreadInfo); - return(0); -} - -static void epicsThreadInit(void) -{ - static pthread_once_t once_control = PTHREAD_ONCE_INIT; - int status = pthread_once(&once_control,once); - checkStatusQuit(status,"pthread_once","epicsThreadInit"); -} - -epicsShareFunc -void epicsThreadRealtimeLock(void) -{ -#if defined(_POSIX_MEMLOCK) && _POSIX_MEMLOCK > 0 - if (pcommonAttr->maxPriority > pcommonAttr->minPriority) { - int status = mlockall(MCL_CURRENT | MCL_FUTURE); - - if (status) { - fprintf(stderr, "epicsThreadRealtimeLock " - "Warning: Unable to lock the virtual address space.\n" - "VM page faults may harm real-time performance.\n"); - } - } -#endif -} - -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass) -{ -#if defined (OSITHREAD_USE_DEFAULT_STACK) - return 0; -#elif defined(_POSIX_THREAD_ATTR_STACKSIZE) && _POSIX_THREAD_ATTR_STACKSIZE > 0 - #define STACK_SIZE(f) (f * 0x10000 * sizeof(void *)) - static const unsigned stackSizeTable[epicsThreadStackBig+1] = { - STACK_SIZE(1), STACK_SIZE(2), STACK_SIZE(4) - }; - if (stackSizeClassepicsThreadStackBig) { - errlogPrintf("epicsThreadGetStackSize illegal argument (too large)"); - return stackSizeTable[epicsThreadStackBig]; - } - - return stackSizeTable[stackSizeClass]; -#else - return 0; -#endif /*_POSIX_THREAD_ATTR_STACKSIZE*/ -} - -epicsShareFunc void epicsShareAPI epicsThreadOnce(epicsThreadOnceId *id, void (*func)(void *), void *arg) -{ - static struct epicsThreadOSD threadOnceComplete; - #define EPICS_THREAD_ONCE_DONE &threadOnceComplete - int status; - - epicsThreadInit(); - status = mutexLock(&onceLock); - if(status) { - fprintf(stderr,"epicsThreadOnce: pthread_mutex_lock returned %s.\n", - strerror(status)); - exit(-1); - } - - if (*id != EPICS_THREAD_ONCE_DONE) { - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - func(arg); - status = mutexLock(&onceLock); - checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock", "epicsThreadOnce"); - epicsThreadSleep(epicsThreadSleepQuantum()); - status = mutexLock(&onceLock); - checkStatusQuit(status,"pthread_mutex_lock", "epicsThreadOnce"); - } - } - status = pthread_mutex_unlock(&onceLock); - checkStatusQuit(status,"pthread_mutex_unlock","epicsThreadOnce"); -} - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadCreate(const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - epicsThreadOSD *pthreadInfo; - int status; - sigset_t blockAllSig, oldSig; - - epicsThreadInit(); - assert(pcommonAttr); - sigfillset(&blockAllSig); - pthread_sigmask(SIG_SETMASK,&blockAllSig,&oldSig); - pthreadInfo = init_threadInfo(name,priority,stackSize,funptr,parm); - if(pthreadInfo==0) return 0; - pthreadInfo->isEpicsThread = 1; - setSchedulingPolicy(pthreadInfo,SCHED_FIFO); - pthreadInfo->isRealTimeScheduled = 1; - status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, - start_routine,pthreadInfo); - if(status==EPERM){ - /* Try again without SCHED_FIFO*/ - free_threadInfo(pthreadInfo); - pthreadInfo = init_threadInfo(name,priority,stackSize,funptr,parm); - if(pthreadInfo==0) return 0; - pthreadInfo->isEpicsThread = 1; - status = pthread_create(&pthreadInfo->tid,&pthreadInfo->attr, - start_routine,pthreadInfo); - } - checkStatusOnce(status,"pthread_create"); - if(status) { - free_threadInfo(pthreadInfo); - return 0; - } - status = pthread_sigmask(SIG_SETMASK,&oldSig,NULL); - checkStatusOnce(status,"pthread_sigmask"); - return(pthreadInfo); -} - -/* - * Create dummy context for threads not created by epicsThreadCreate(). - */ -static epicsThreadOSD *createImplicit(void) -{ - epicsThreadOSD *pthreadInfo; - char name[64]; - pthread_t tid; - int status; - - tid = pthread_self(); - sprintf(name, "non-EPICS_%ld", (long)tid); - pthreadInfo = create_threadInfo(name); - assert(pthreadInfo); - pthreadInfo->tid = tid; - pthreadInfo->osiPriority = 0; - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - { - struct sched_param param; - int policy; - if(pthread_getschedparam(tid,&policy,¶m) == 0) - pthreadInfo->osiPriority = - (param.sched_priority - pcommonAttr->minPriority) * 100.0 / - (pcommonAttr->maxPriority - pcommonAttr->minPriority + 1); - } -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - status = pthread_setspecific(getpthreadInfo,(void *)pthreadInfo); - checkStatus(status,"pthread_setspecific createImplicit"); - if(status){ - free_threadInfo(pthreadInfo); - return NULL; - } - return pthreadInfo; -} - -epicsShareFunc void epicsShareAPI epicsThreadSuspendSelf(void) -{ - epicsThreadOSD *pthreadInfo; - - epicsThreadInit(); - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); - if(pthreadInfo==NULL) - pthreadInfo = createImplicit(); - pthreadInfo->isSuspended = 1; - epicsEventWait(pthreadInfo->suspendEvent); -} - -epicsShareFunc void epicsShareAPI epicsThreadResume(epicsThreadOSD *pthreadInfo) -{ - assert(epicsThreadOnceCalled); - pthreadInfo->isSuspended = 0; - epicsEventSignal(pthreadInfo->suspendEvent); -} - -epicsShareFunc void epicsShareAPI epicsThreadExitMain(void) -{ - epicsThreadOSD *pthreadInfo; - - epicsThreadInit(); - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); - if(pthreadInfo==NULL) - pthreadInfo = createImplicit(); - if(pthreadInfo->createFunc) { - errlogPrintf("called from non-main thread\n"); - cantProceed("epicsThreadExitMain"); - } - else { - free_threadInfo(pthreadInfo); - pthread_exit(0); - } -} - -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPriority(epicsThreadId pthreadInfo) -{ - assert(epicsThreadOnceCalled); - return(pthreadInfo->osiPriority); -} - -epicsShareFunc unsigned int epicsShareAPI epicsThreadGetPrioritySelf(void) -{ - epicsThreadInit(); - return(epicsThreadGetPriority(epicsThreadGetIdSelf())); -} - -epicsShareFunc void epicsShareAPI epicsThreadSetPriority(epicsThreadId pthreadInfo,unsigned int priority) -{ -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - int status; -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - assert(epicsThreadOnceCalled); - assert(pthreadInfo); - if(!pthreadInfo->isEpicsThread) { - fprintf(stderr,"epicsThreadSetPriority called by non epics thread\n"); - return; - } - pthreadInfo->osiPriority = priority; - if(!pthreadInfo->isRealTimeScheduled) return; - -#if defined (_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - if(!pcommonAttr->usePolicy) return; - pthreadInfo->schedParam.sched_priority = epicsThreadGetPosixPriority(pthreadInfo); - status = pthread_attr_setschedparam( - &pthreadInfo->attr,&pthreadInfo->schedParam); - if(errVerbose) checkStatus(status,"pthread_attr_setschedparam"); - status = pthread_setschedparam( - pthreadInfo->tid, pthreadInfo->schedPolicy, &pthreadInfo->schedParam); - if(errVerbose) checkStatus(status,"pthread_setschedparam"); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ -} - -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadHighestPriorityLevelBelow( - unsigned int priority, unsigned *pPriorityJustBelow) -{ - unsigned newPriority = priority - 1; -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - int diff; - diff = pcommonAttr->maxPriority - pcommonAttr->minPriority; - if(diff<0) diff = -diff; - if(diff>1 && diff <100) newPriority -= 100/(diff+1); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - if (newPriority <= 99) { - *pPriorityJustBelow = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -epicsShareFunc epicsThreadBooleanStatus epicsShareAPI epicsThreadLowestPriorityLevelAbove( - unsigned int priority, unsigned *pPriorityJustAbove) -{ - unsigned newPriority = priority + 1; - -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && _POSIX_THREAD_PRIORITY_SCHEDULING > 0 - int diff; - diff = pcommonAttr->maxPriority - pcommonAttr->minPriority; - if(diff<0) diff = -diff; - if(diff>1 && diff <100) newPriority += 100/(diff+1); -#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */ - - if (newPriority <= 99) { - *pPriorityJustAbove = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -epicsShareFunc int epicsShareAPI epicsThreadIsEqual(epicsThreadId p1, epicsThreadId p2) -{ - assert(epicsThreadOnceCalled); - assert(p1); - assert(p2); - return(pthread_equal(p1->tid,p2->tid)); -} - -epicsShareFunc int epicsShareAPI epicsThreadIsSuspended(epicsThreadId pthreadInfo) { - assert(epicsThreadOnceCalled); - assert(pthreadInfo); - return(pthreadInfo->isSuspended ? 1 : 0); -} - -epicsShareFunc void epicsShareAPI epicsThreadSleep(double seconds) -{ - struct timespec delayTime; - struct timespec remainingTime; - double nanoseconds; - - if (seconds > 0) { - delayTime.tv_sec = seconds; - nanoseconds = (seconds - delayTime.tv_sec) *1e9; - delayTime.tv_nsec = nanoseconds; - } - else { - delayTime.tv_sec = 0; - delayTime.tv_nsec = 0; - } - while (nanosleep(&delayTime, &remainingTime) == -1 && - errno == EINTR) - delayTime = remainingTime; -} - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetIdSelf(void) { - epicsThreadOSD *pthreadInfo; - - epicsThreadInit(); - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); - if(pthreadInfo==NULL) - pthreadInfo = createImplicit(); - assert ( pthreadInfo ); - return(pthreadInfo); -} - -epicsShareFunc pthread_t epicsThreadGetPosixThreadId ( epicsThreadId threadId ) -{ - return threadId->tid; -} - -epicsShareFunc epicsThreadId epicsShareAPI epicsThreadGetId(const char *name) { - epicsThreadOSD *pthreadInfo; - int status; - - assert(epicsThreadOnceCalled); - status = mutexLock(&listLock); - checkStatus(status,"pthread_mutex_lock epicsThreadGetId"); - if(status) - return NULL; - pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); - while(pthreadInfo) { - if(strcmp(name,pthreadInfo->name) == 0) break; - pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); - } - status = pthread_mutex_unlock(&listLock); - checkStatus(status,"pthread_mutex_unlock epicsThreadGetId"); - - return(pthreadInfo); -} - -epicsShareFunc const char epicsShareAPI *epicsThreadGetNameSelf() -{ - epicsThreadOSD *pthreadInfo; - - epicsThreadInit(); - pthreadInfo = (epicsThreadOSD *)pthread_getspecific(getpthreadInfo); - if(pthreadInfo==NULL) - pthreadInfo = createImplicit(); - return(pthreadInfo->name); -} - -epicsShareFunc void epicsShareAPI epicsThreadGetName(epicsThreadId pthreadInfo, char *name, size_t size) -{ - assert(epicsThreadOnceCalled); - strncpy(name, pthreadInfo->name, size-1); - name[size-1] = '\0'; -} - -epicsShareFunc void epicsThreadMap(EPICS_THREAD_HOOK_ROUTINE func) -{ - epicsThreadOSD *pthreadInfo; - int status; - - epicsThreadInit(); - status = mutexLock(&listLock); - checkStatus(status, "pthread_mutex_lock epicsThreadMap"); - if (status) - return; - pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); - while (pthreadInfo) { - func(pthreadInfo); - pthreadInfo = (epicsThreadOSD *)ellNext(&pthreadInfo->node); - } - status = pthread_mutex_unlock(&listLock); - checkStatus(status, "pthread_mutex_unlock epicsThreadMap"); -} - -epicsShareFunc void epicsShareAPI epicsThreadShowAll(unsigned int level) -{ - epicsThreadOSD *pthreadInfo; - int status; - - epicsThreadInit(); - epicsThreadShow(0,level); - status = mutexLock(&listLock); - checkStatus(status,"pthread_mutex_lock epicsThreadShowAll"); - if(status) - return; - pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); - while(pthreadInfo) { - epicsThreadShowInfo(pthreadInfo,level); - pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); - } - status = pthread_mutex_unlock(&listLock); - checkStatus(status,"pthread_mutex_unlock epicsThreadShowAll"); -} - -epicsShareFunc void epicsShareAPI epicsThreadShow(epicsThreadId showThread, unsigned int level) -{ - epicsThreadOSD *pthreadInfo; - int status; - int found = 0; - - epicsThreadInit(); - if(!showThread) { - epicsThreadShowInfo(0,level); - return; - } - status = mutexLock(&listLock); - checkStatus(status,"pthread_mutex_lock epicsThreadShowAll"); - if(status) - return; - pthreadInfo=(epicsThreadOSD *)ellFirst(&pthreadList); - while(pthreadInfo) { - if (((epicsThreadId)pthreadInfo == showThread) - || ((epicsThreadId)pthreadInfo->tid == showThread)) { - found = 1; - epicsThreadShowInfo(pthreadInfo,level); - } - pthreadInfo=(epicsThreadOSD *)ellNext(&pthreadInfo->node); - } - status = pthread_mutex_unlock(&listLock); - checkStatus(status,"pthread_mutex_unlock epicsThreadShowAll"); - if(status) return; - if (!found) - printf("Thread %#lx (%lu) not found.\n", (unsigned long)showThread, (unsigned long)showThread); -} - -epicsShareFunc epicsThreadPrivateId epicsShareAPI epicsThreadPrivateCreate(void) -{ - pthread_key_t *key; - int status; - - epicsThreadInit(); - key = calloc(1,sizeof(pthread_key_t)); - if(!key) - return NULL; - status = pthread_key_create(key,0); - checkStatus(status,"pthread_key_create epicsThreadPrivateCreate"); - if(status) - return NULL; - return((epicsThreadPrivateId)key); -} - -epicsShareFunc void epicsShareAPI epicsThreadPrivateDelete(epicsThreadPrivateId id) -{ - pthread_key_t *key = (pthread_key_t *)id; - int status; - - assert(epicsThreadOnceCalled); - status = pthread_key_delete(*key); - checkStatusQuit(status,"pthread_key_delete","epicsThreadPrivateDelete"); - free((void *)key); -} - -epicsShareFunc void epicsShareAPI epicsThreadPrivateSet (epicsThreadPrivateId id, void *value) -{ - pthread_key_t *key = (pthread_key_t *)id; - int status; - - assert(epicsThreadOnceCalled); - if(errVerbose && !value) - errlogPrintf("epicsThreadPrivateSet: setting value of 0\n"); - status = pthread_setspecific(*key,value); - checkStatusQuit(status,"pthread_setspecific","epicsThreadPrivateSet"); -} - -epicsShareFunc void epicsShareAPI *epicsThreadPrivateGet(epicsThreadPrivateId id) -{ - pthread_key_t *key = (pthread_key_t *)id; - - assert(epicsThreadOnceCalled); - return pthread_getspecific(*key); -} - -epicsShareFunc double epicsShareAPI epicsThreadSleepQuantum () -{ - double hz; - hz = sysconf ( _SC_CLK_TCK ); - if(hz<0) - return 0.0; - return 1.0 / hz; -} - -epicsShareFunc int epicsThreadGetCPUs(void) -{ - long ret; -#ifdef _SC_NPROCESSORS_ONLN - ret = sysconf(_SC_NPROCESSORS_ONLN); - if (ret > 0) - return ret; -#endif -#ifdef _SC_NPROCESSORS_CONF - ret = sysconf(_SC_NPROCESSORS_CONF); - if (ret > 0) - return ret; -#endif - return 1; -} diff --git a/src/libCom/osi/os/posix/osdThread.h b/src/libCom/osi/os/posix/osdThread.h deleted file mode 100644 index 3a80b537c..000000000 --- a/src/libCom/osi/os/posix/osdThread.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef osdThreadh -#define osdThreadh - -#include - -#include "shareLib.h" -#include "ellLib.h" -#include "epicsEvent.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct epicsThreadOSD { - ELLNODE node; - pthread_t tid; - pthread_attr_t attr; - struct sched_param schedParam; - int schedPolicy; - EPICSTHREADFUNC createFunc; - void *createArg; - epicsEventId suspendEvent; - int isSuspended; - int isEpicsThread; - int isRealTimeScheduled; - int isOnThreadList; - unsigned int osiPriority; - char name[1]; /* actually larger */ -} epicsThreadOSD; - -epicsShareFunc pthread_t epicsThreadGetPosixThreadId(epicsThreadId id); -epicsShareFunc int epicsThreadGetPosixPriority(epicsThreadId id); - -#ifdef __cplusplus -} -#endif - -#endif /* osdThreadh */ diff --git a/src/libCom/osi/os/posix/osdThreadExtra.c b/src/libCom/osi/os/posix/osdThreadExtra.c deleted file mode 100644 index af622dc08..000000000 --- a/src/libCom/osi/os/posix/osdThreadExtra.c +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Marty Kraimer Date: 18JAN2000 */ - -/* This is part of the posix implementation of epicsThread */ - -#define epicsExportSharedSymbols -#include "epicsStdio.h" -#include "ellLib.h" -#include "epicsEvent.h" -#include "epicsThread.h" - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; - -void epicsThreadShowInfo(epicsThreadOSD *pthreadInfo, unsigned int level) -{ - if(!pthreadInfo) { - fprintf(epicsGetStdout()," NAME EPICS ID " - "PTHREAD ID OSIPRI OSSPRI STATE\n"); - } else { - struct sched_param param; - int policy; - int priority = 0; - - if(pthreadInfo->tid) { - int status; - status = pthread_getschedparam(pthreadInfo->tid,&policy,¶m); - if(!status) priority = param.sched_priority; - } - fprintf(epicsGetStdout(),"%16.16s %14p %12lu %3d%8d %8.8s\n", - pthreadInfo->name,(void *) - pthreadInfo,(unsigned long)pthreadInfo->tid, - pthreadInfo->osiPriority,priority, - pthreadInfo->isSuspended?"SUSPEND":"OK"); - } -} - diff --git a/src/libCom/osi/os/posix/osdTime.cpp b/src/libCom/osi/os/posix/osdTime.cpp deleted file mode 100644 index d5fb05a1c..000000000 --- a/src/libCom/osi/os/posix/osdTime.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include -#include - -#include "osiSock.h" - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsTime.h" -#include "generalTimeSup.h" - -#ifdef CLOCK_REALTIME - #include "osiClockTime.h" - - #define TIME_INIT ClockTime_Init(CLOCKTIME_NOSYNC) -#else - /* Some posix systems may not have CLOCK_REALTIME */ - - #define TIME_INIT generalTimeCurrentTpRegister("GetTimeOfDay", \ - LAST_RESORT_PRIORITY, osdTimeGetCurrent) - - extern "C" { - static int osdTimeGetCurrent (epicsTimeStamp *pDest) - { - struct timeval tv; - struct timezone tz; - - if (gettimeofday (&tv, &tz)) - return errno; - - *pDest = epicsTime(tv); - return epicsTimeOK; - } - } // extern "C" -#endif - -#ifdef __CYGWIN__ -int clock_settime(clockid_t clock, const timespec *tp) -{ - return -EFAULT; -} -#endif - - -static int timeRegister(void) -{ - TIME_INIT; - return 1; -} -static int done = timeRegister(); - - -int epicsTime_gmtime ( const time_t *pAnsiTime, - struct tm *pTM ) -{ - struct tm * pRet = gmtime_r ( pAnsiTime, pTM ); - if ( pRet ) { - return epicsTimeOK; - } - else { - return errno; - } -} - -int epicsTime_localtime ( const time_t *clock, - struct tm *result ) -{ - struct tm * pRet = localtime_r ( clock, result ); - if ( pRet ) { - return epicsTimeOK; - } - else { - return errno; - } -} - -extern "C" epicsShareFunc void - convertDoubleToWakeTime(double timeout,struct timespec *wakeTime) -{ - struct timespec now, wait; - int status; - - if (timeout < 0.0) - timeout = 0.0; - else if (timeout > 60 * 60 * 24 * 3652.5) - timeout = 60 * 60 * 24 * 3652.5; /* 10 years */ - -#ifdef CLOCK_REALTIME - status = clock_gettime(CLOCK_REALTIME, &now); -#else - { - struct timeval tv; - struct timezone tz; - status = gettimeofday(&tv, &tz); - now.tv_sec = tv.tv_sec; - now.tv_nsec = tv.tv_usec * 1000; - } -#endif - if (status) { - perror("convertDoubleToWakeTime"); - cantProceed("convertDoubleToWakeTime"); - } - - wait.tv_sec = static_cast< time_t >(timeout); - wait.tv_nsec = static_cast< long >((timeout - (double)wait.tv_sec) * 1e9); - - wakeTime->tv_sec = now.tv_sec + wait.tv_sec; - wakeTime->tv_nsec = now.tv_nsec + wait.tv_nsec; - if (wakeTime->tv_nsec >= 1000000000L) { - wakeTime->tv_nsec -= 1000000000L; - ++wakeTime->tv_sec; - } -} diff --git a/src/libCom/osi/os/posix/osdTime.h b/src/libCom/osi/os/posix/osdTime.h deleted file mode 100644 index d1da77696..000000000 --- a/src/libCom/osi/os/posix/osdTime.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - */ - -#ifndef osdTimeh -#define osdTimeh - -#include - -#if !defined(_POSIX_TIMERS) || _POSIX_TIMERS < 0 - struct timespec { - time_t tv_sec; /* seconds since some epoch */ - long tv_nsec; /* nanoseconds within the second */ - }; -#endif /* !_POSIX_TIMERS */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsShareAPI - convertDoubleToWakeTime(double timeout,struct timespec *wakeTime); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ifndef osdTimeh */ - diff --git a/src/libCom/osi/os/posix/osiUnistd.h b/src/libCom/osi/os/posix/osiUnistd.h deleted file mode 100644 index 5121261b6..000000000 --- a/src/libCom/osi/os/posix/osiUnistd.h +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include diff --git a/src/libCom/osi/os/posix/systemCallIntMech.cpp b/src/libCom/osi/os/posix/systemCallIntMech.cpp deleted file mode 100644 index cdac1d0cb..000000000 --- a/src/libCom/osi/os/posix/systemCallIntMech.cpp +++ /dev/null @@ -1,22 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Jeff Hill - */ - -#define epicsExportSharedSymbols -#include "osiSock.h" - -enum epicsSocketSystemCallInterruptMechanismQueryInfo - epicsSocketSystemCallInterruptMechanismQuery () -{ - return esscimqi_socketBothShutdownRequired; -} diff --git a/src/libCom/osi/os/solaris/epicsAtomicOSD.h b/src/libCom/osi/os/solaris/epicsAtomicOSD.h deleted file mode 100644 index 1fa23bd88..000000000 --- a/src/libCom/osi/os/solaris/epicsAtomicOSD.h +++ /dev/null @@ -1,185 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2011 LANS LLC, as Operator of -* Los Alamos National Laboratory. -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#include "shareLib.h" - -#ifndef epicsAtomicOSD_h -#define epicsAtomicOSD_h - -#define EPICS_ATOMIC_OS_NAME "Solaris" - -#if defined ( __SunOS_5_10 ) - -/* - * atomic.h exists only in Solaris 10 or higher - */ -#include - -#include "epicsAssert.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - membar_consumer (); -} -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - membar_producer (); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_INTT -#define EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ) -{ - STATIC_ASSERT ( sizeof ( int ) == sizeof ( unsigned ) ); - unsigned * const pTarg = ( unsigned * ) pTarget; - return ( int ) atomic_cas_uint ( pTarg, ( unsigned ) oldVal, - ( unsigned ) newVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( - size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - return ( size_t ) atomic_cas_ulong ( pTarg, oldVal, newVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( - EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, - EpicsAtomicPtrT newVal ) -{ - return atomic_cas_ptr ( pTarget, oldVal, newVal ); -} -#endif - -#ifndef EPICS_ATOMIC_INCR_INTT -#define EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - STATIC_ASSERT ( sizeof ( unsigned ) == sizeof ( int ) ); - unsigned * const pTarg = ( unsigned * ) ( pTarget ); - return ( int ) atomic_inc_uint_nv ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_INCR_SIZET -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - return ( size_t ) atomic_inc_ulong_nv ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_INTT -#define EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - STATIC_ASSERT ( sizeof ( unsigned ) == sizeof ( int ) ); - unsigned * const pTarg = ( unsigned * ) ( pTarget ); - return ( int ) atomic_dec_uint_nv ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - return ( size_t ) atomic_dec_ulong_nv ( pTarg ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_INTT -#define EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - STATIC_ASSERT ( sizeof ( unsigned ) == sizeof ( int ) ); - unsigned * const pTarg = ( unsigned * ) ( pTarget ); - return ( int ) atomic_add_int_nv ( pTarg, delta ); -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, - size_t delta ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - return ( size_t ) atomic_add_long_nv ( pTarg, ( long ) delta ); -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, - size_t delta ) -{ - STATIC_ASSERT ( sizeof ( ulong_t ) == sizeof ( size_t ) ); - ulong_t * const pTarg = ( ulong_t * ) pTarget; - long sdelta = ( long ) delta; - return ( size_t ) atomic_add_long_nv ( pTarg, -sdelta ); -} -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#endif /* ifdef __SunOS_5_10 */ - -typedef struct EpicsAtomicLockKey { - char dummy; -} EpicsAtomicLockKey; - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -epicsShareFunc void epicsAtomicLock ( struct EpicsAtomicLockKey * ); -epicsShareFunc void epicsAtomicUnlock ( struct EpicsAtomicLockKey * ); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/solaris/epicsMath.h b/src/libCom/osi/os/solaris/epicsMath.h deleted file mode 100644 index 87d4986a7..000000000 --- a/src/libCom/osi/os/solaris/epicsMath.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne, LLC as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_epicsMath_H -#define INC_epicsMath_H - -#include -#include -#include - -#ifndef isinf -# define isinf(x) (((x)==(x)) && !finite((x))) -/* same as (!isnan(x) && !finite(x)) */ -#endif - -#ifndef isnan -# define isnan(x) ((x) != (x)) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* INC_epicsMath_H */ diff --git a/src/libCom/osi/os/solaris/osdBackTrace.cpp b/src/libCom/osi/os/solaris/osdBackTrace.cpp deleted file mode 100644 index 55d5e3648..000000000 --- a/src/libCom/osi/os/solaris/osdBackTrace.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2014 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsStackTracePvt.h" - -struct wlk { - void **buf; - int max; - int cur; -}; - - -extern "C" { - -static int -walker(uintptr_t addr, int sig, void *arg) -{ -struct wlk *w_p = (struct wlk *)arg; - if ( w_p->cur < w_p->max ) - w_p->buf[w_p->cur++] = (void*)addr; - return 0; -} - -} - -int epicsBackTrace(void **buf, int buf_sz) -{ -ucontext_t u; -struct wlk d; - d.buf = buf; - d.max = buf_sz; - d.cur = 0; - if ( getcontext(&u) ) - return -1; - walkcontext( &u, walker, &d ); - return d.cur; -} diff --git a/src/libCom/osi/os/solaris/osdFindAddr.c b/src/libCom/osi/os/solaris/osdFindAddr.c deleted file mode 100644 index 84d17d96f..000000000 --- a/src/libCom/osi/os/solaris/osdFindAddr.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2011, 2014 - */ - -#include "osdElfFindAddr.c" diff --git a/src/libCom/osi/os/solaris/osdSock.h b/src/libCom/osi/os/solaris/osdSock.h deleted file mode 100644 index a39c6c3d3..000000000 --- a/src/libCom/osi/os/solaris/osdSock.h +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Solaris specific socket include - */ - -#ifndef osdSockH -#define osdSockH - -#include - -#include -#include /* for MAXHOSTNAMELEN */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* close() and others */ - - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#define socket_ioctl(A,B,C) ioctl(A,B,C) -typedef int osiSockIoctl_t; - -#if SOLARIS > 6 || defined ( _SOCKLEN_T ) - typedef uint32_t osiSocklen_t; -#else - typedef int osiSocklen_t; -#endif - -#define DOES_NOT_ACCEPT_ZERO_LENGTH_UDP - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EACCES EACCES -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE -#define SOCK_EMFILE EMFILE -#define SOCK_SHUTDOWN ESHUTDOWN -#define SOCK_ENOTSOCK ENOTSOCK -#define SOCK_EBADF EBADF - -#ifndef SHUT_RD -# define SHUT_RD 0 -#endif - -#ifndef SHUT_WR -# define SHUT_WR 1 -#endif - -#ifndef SHUT_RDWR -# define SHUT_RDWR 2 -#endif - -#ifndef INADDR_NONE -# define INADDR_NONE (0xffffffff) -#endif - -#define ifreq_size(pifreq) (sizeof(pifreq->ifr_name)) - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/solaris/osdStrtod.h b/src/libCom/osi/os/solaris/osdStrtod.h deleted file mode 100644 index b5fda31c3..000000000 --- a/src/libCom/osi/os/solaris/osdStrtod.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header fragment is intended to be included as part of epicsString.h - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epicsStrtod() for systems with broken strtod() routine - */ -epicsShareFunc double epicsStrtod(const char *str, char **endp); - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/solaris/osdWireConfig.h b/src/libCom/osi/os/solaris/osdWireConfig.h deleted file mode 100644 index 277fe395e..000000000 --- a/src/libCom/osi/os/solaris/osdWireConfig.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Solaris version of - * osdWireConfig.h - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireConfig_h -#define osdWireConfig_h - -#include - -#if defined ( _LITTLE_ENDIAN ) -# define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -#elif defined ( _BIG_ENDIAN ) -# define EPICS_BYTE_ORDER EPICS_ENDIAN_BIG -#else -# error EPICS hasnt been ported to byte order specified by on Solaris -#endif - -/* for now, assume that Solaris doesnt run on weird arch like ARM NWFP */ -#define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER - -#endif /* ifdef osdWireConfig_h */ - diff --git a/src/libCom/osi/os/solaris/osiFileName.h b/src/libCom/osi/os/solaris/osiFileName.h deleted file mode 100644 index b79203992..000000000 --- a/src/libCom/osi/os/solaris/osiFileName.h +++ /dev/null @@ -1,21 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - * - * - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/vxWorks/atReboot.cpp b/src/libCom/osi/os/vxWorks/atReboot.cpp deleted file mode 100644 index 2f755c581..000000000 --- a/src/libCom/osi/os/vxWorks/atReboot.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* atReboot.cpp */ - -/* Author: Marty Kraimer Date: 30AUG2003 */ - -#include - -#include "epicsFindSymbol.h" -#include "epicsExit.h" - -extern "C" { - -typedef int (*sysAtReboot_t)(void(func)(void)); - -void atRebootRegister(void) -{ - sysAtReboot_t sysAtReboot = (sysAtReboot_t) epicsFindSymbol("_sysAtReboot"); - - if (sysAtReboot) { - STATUS status = sysAtReboot(epicsExitCallAtExits); - - if (status) { - printf("atReboot: sysAtReboot returned error %d\n", status); - } - } else { - printf("BSP routine sysAtReboot() not found, epicsExit() will not be\n" - "called by reboot. For reduced functionality, call\n" - " rebootHookAdd(epicsExitCallAtExits)\n"); - } -} - -} diff --git a/src/libCom/osi/os/vxWorks/camacLib.h b/src/libCom/osi/os/vxWorks/camacLib.h deleted file mode 100644 index a30ab5659..000000000 --- a/src/libCom/osi/os/vxWorks/camacLib.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* camacLib.h -- Prototypes for camacLib.o - * - * Marty Wise - * 10/11/93 - * - */ - -/********************************/ -/* GLOBAL DATA */ -/********************************/ -extern int debug_hook; - -extern struct glob_dat { - int total; - int read_error[5]; - int write_error[5]; - int cmd_error[5]; - int total_err; - int lam_count[12]; -} debug_dat; - - -/********************************/ -/* FUNCTION PROTOTYPES */ -/********************************/ - -void cdreg(int *ext, int b, int c, int n, int a); -void cfsa(int f, int ext, int *dat, int *q); -void cssa(int f, int ext, short *dat, int *q); -void ccci(int ext, int l); -void cccz(int ext); -void cccc(int ext); -void ccinit(int b); -void ctci(int ext, int *l); -void cgreg(int ext, int *b, int *c, int *n, int *a); -void cfmad(int f, int extb[2], int *intc, int cb[4]); -void cfubc(int f, int ext, int *intc, int cb[4]); -void cfubc(int f, int ext, int *intc, int cb[4]); -void csmad(int f, int extb[2], short *intc, int cb[4]); -void ctcd(int ext, int *l); -void cccd(int ext, int l); -void csga(int fa[], int exta[], unsigned short intc[], int qa[], int cb[4]); -void cfga(int fa[], int exta[], int intc[], int qa[], int cb[4]); -void cfubr(int f, int ext, int intc[], int cb[4]); -void csubc(int f, int ext, unsigned short *intc, int cb[4]); -void csubr(int f, int ext, int intc[], int cb[4]); -void print_reg(int ext); - diff --git a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c b/src/libCom/osi/os/vxWorks/devLibVMEOSD.c deleted file mode 100644 index 82bec603d..000000000 --- a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c +++ /dev/null @@ -1,502 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Archictecture dependent support for common device driver resources - * - * Author: Jeff Hill - * Date: 10-30-98 - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsFindSymbol.h" -#include "devLibVME.h" -#include "errlog.h" - -typedef void myISR (void *pParam); - -#if CPU_FAMILY != PPC -/* - * A list of the names of the unexpected interrupt handlers - * ( some of these are provided by wrs ) - */ -static char *defaultHandlerNames[] = { - "excStub", - "excIntStub", - "unsolicitedHandlerEPICS"}; - -static myISR *defaultHandlerAddr[NELEMENTS(defaultHandlerNames)]; -#endif - -static myISR *isrFetch(unsigned vectorNumber); - -/* - * this routine needs to be in the symbol table - * (i.e. not static) for this code to work correctly - */ -void unsolicitedHandlerEPICS(int vectorNumber); - -/* - * this is in veclist.c - */ -int cISRTest(void (*)(), void (**)(), void **); - -/* - * Make sure that the CR/CSR addressing mode is defined. - * (it may not be in older versions of vxWorks) - */ -#ifndef VME_AM_CSR -# define VME_AM_CSR (0x2f) -#endif - -/* - * we use a translation between an EPICS encoding - * and a vxWorks encoding here - * to reduce dependency of drivers on vxWorks - * - * we assume that the BSP are configured to use these - * address modes by default - */ - -#define EPICSAddrTypeNoConvert -1 - -int EPICStovxWorksAddrType[] - = { - VME_AM_SUP_SHORT_IO, - VME_AM_STD_SUP_DATA, - VME_AM_EXT_SUP_DATA, - EPICSAddrTypeNoConvert, - VME_AM_CSR - }; - -#if CPU_FAMILY != PPC -static void initHandlerAddrList(void); -#endif - -/* - * maps logical address to physical address, but does not detect - * two device drivers that are using the same address range - */ -static long vxDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress); - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue); - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isnt present - */ -static long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue); - -static void *devA24Malloc(size_t size); -static void devA24Free(void *pBlock); -static long devInit(void) { return 0;} - -static long vxDevConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter); - -static long vxDevDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -); - -static long vxDevEnableInterruptLevelVME (unsigned level); - -static long vxDevDisableInterruptLevelVME (unsigned level); - -static int vxDevInterruptInUseVME (unsigned vectorNumber); - -/* - * used by dynamic bind in devLib.c - */ -static devLibVME vxVirtualOS = { - vxDevMapAddr, vxDevReadProbe, vxDevWriteProbe, - vxDevConnectInterruptVME, vxDevDisconnectInterruptVME, - vxDevEnableInterruptLevelVME, vxDevDisableInterruptLevelVME, - devA24Malloc,devA24Free,devInit,vxDevInterruptInUseVME -}; -devLibVME *pdevLibVME = &vxVirtualOS; - -/* - * devConnectInterruptVME - * - * wrapper to minimize driver dependency on vxWorks - */ -static long vxDevConnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)(), - void *parameter) -{ - int status; - - - if (devInterruptInUseVME(vectorNumber)) { - return S_dev_vectorInUse; - } - status = intConnect( - (void *)INUM_TO_IVEC(vectorNumber), - pFunction, - (int) parameter); - if (status<0) { - return S_dev_vecInstlFail; - } - - return 0; -} - -/* - * - * vxDevDisconnectInterruptVME() - * - * wrapper to minimize driver dependency on vxWorks - * - * The parameter pFunction should be set to the C function pointer that - * was connected. It is used as a key to prevent a driver from removing - * an interrupt handler that was installed by another driver - * - */ -static long vxDevDisconnectInterruptVME ( - unsigned vectorNumber, - void (*pFunction)() -) -{ - void (*psub)(); - int status; - -# if CPU_FAMILY == PPC - return S_dev_vecInstlFail; -# endif - - /* - * If pFunction not connected to this vector - * then they are probably disconnecting from the wrong vector - */ - psub = isrFetch(vectorNumber); - if(psub != pFunction){ - return S_dev_vectorNotInUse; - } - - status = intConnect( - (void *)INUM_TO_IVEC(vectorNumber), - unsolicitedHandlerEPICS, - (int) vectorNumber); - if(status<0){ - return S_dev_vecInstlFail; - } - - return 0; -} - -/* - * enable VME interrupt level - */ -static long vxDevEnableInterruptLevelVME (unsigned level) -{ -# if CPU_FAMILY != I80X86 - int s; - s = sysIntEnable (level); - if (s!=OK) { - return S_dev_intEnFail; - } - return 0; -# else - return S_dev_intEnFail; -# endif -} - -/* - * enable ISA interrupt level - */ -long devEnableInterruptLevelISA (unsigned level) -{ -# if CPU_FAMILY == I80X86 - int s; - s = sysIntEnablePIC (level); - if (s!=OK) { - return S_dev_intEnFail; - } - return 0; -# else - return S_dev_intEnFail; -# endif -} - -/* - * disable ISA interrupt level - */ -long devDisableInterruptLevelISA (unsigned level) -{ -# if CPU_FAMILY == I80X86 - int s; - s = sysIntDisablePIC (level); - if (s!=OK) { - return S_dev_intEnFail; - } -# else - return S_dev_intEnFail; -# endif - - return 0; -} - -/* - * disable VME interrupt level - */ -static long vxDevDisableInterruptLevelVME (unsigned level) -{ -# if CPU_FAMILY != I80X86 - int s; - s = sysIntDisable (level); - if (s!=OK) { - return S_dev_intDissFail; - } - return 0; -# else - return S_dev_intEnFail; -# endif -} - -/* - * vxDevMapAddr () - */ -static long vxDevMapAddr (epicsAddressType addrType, unsigned options, - size_t logicalAddress, size_t size, volatile void **ppPhysicalAddress) -{ - long status; - - if (ppPhysicalAddress==NULL) { - return S_dev_badArgument; - } - - if (EPICStovxWorksAddrType[addrType] == EPICSAddrTypeNoConvert) - { - *ppPhysicalAddress = (void *) logicalAddress; - } - else - { - status = sysBusToLocalAdrs (EPICStovxWorksAddrType[addrType], - (char *) logicalAddress, (char **)ppPhysicalAddress); - if (status) { - return S_dev_addrMapFail; - } - } - - return 0; -} - -/* - * a bus error safe "wordSize" read at the specified address which returns - * unsuccessful status if the device isn't present - */ -static long vxDevReadProbe (unsigned wordSize, volatile const void *ptr, void *pValue) -{ - long status; - - status = vxMemProbe ((char *)ptr, VX_READ, wordSize, (char *) pValue); - if (status!=OK) { - return S_dev_noDevice; - } - - return 0; -} - -/* - * a bus error safe "wordSize" write at the specified address which returns - * unsuccessful status if the device isn't present - */ -static long vxDevWriteProbe (unsigned wordSize, volatile void *ptr, const void *pValue) -{ - long status; - - status = vxMemProbe ((char *)ptr, VX_WRITE, wordSize, (char *) pValue); - if (status!=OK) { - return S_dev_noDevice; - } - - return 0; -} - -/* - * isrFetch() - */ -static myISR *isrFetch(unsigned vectorNumber) -{ - myISR *psub; - myISR *pCISR; - void *pParam; - int s; - - /* - * fetch the handler or C stub attached at this vector - */ - psub = (myISR *) intVecGet((FUNCPTR *)INUM_TO_IVEC(vectorNumber)); - - if ( psub ) { - /* - * from libvxWorks/veclist.c - * - * checks to see if it is a C ISR - * and if so finds the function pointer and - * the parameter passed - */ - s = cISRTest(psub, &pCISR, &pParam); - if(!s){ - psub = pCISR; - } - } - - return psub; -} - -/* - * determine if a VME interrupt vector is in use - */ -static int vxDevInterruptInUseVME (unsigned vectorNumber) -{ -#if CPU_FAMILY == PPC - return FALSE; -#else - { - static int init; - int i; - myISR *psub; - - if (!init) { - initHandlerAddrList(); - init = TRUE; - } - - psub = isrFetch (vectorNumber); - - /* - * its a C routine. Does it match a default handler? - */ - for (i=0; i -#endif - -#include "vxWorks.h" /* obtain the version of vxWorks */ -#include "epicsAssert.h" - -/* - * With vxWorks 6.6 and later we need to use vxAtomicLib - * to implement this functionality correctly on SMP systems - */ -#if _WRS_VXWORKS_MAJOR * 100 + _WRS_VXWORKS_MINOR >= 606 - -#include -#include - -#define EPICS_ATOMIC_OS_NAME "VX-ATOMICLIB" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) -{ - VX_MEM_BARRIER_R (); -} -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) -{ - VX_MEM_BARRIER_W (); -} -#endif - -/* - * we make the probably correct guess that if ULONG_MAX - * is the same as UINT_MAX then sizeof ( atomic_t ) - * will be the same as sizeof ( size_t ) - * - * if ULONG_MAX != UINT_MAX then its 64 bit vxWorks and - * WRS doesnt not supply at this time the atomic interface - * for 8 byte integers that is needed - so that architecture - * receives the lock synchronized version - */ -#if ULONG_MAX == UINT_MAX - -STATIC_ASSERT ( sizeof ( atomic_t ) == sizeof ( size_t ) ); -STATIC_ASSERT ( sizeof ( atomic_t ) == sizeof ( EpicsAtomicPtrT ) ); - - -#ifndef EPICS_ATOMIC_INCR_SIZET -#define EPICS_ATOMIC_INCR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicInc ( pTarg ); - return 1 + ( size_t ) ( oldVal ); -} -#endif - -#ifndef EPICS_ATOMIC_DECR_SIZET -#define EPICS_ATOMIC_DECR_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicDec ( pTarg ); - return ( ( size_t ) oldVal ) - 1u; -} -#endif - -#ifndef EPICS_ATOMIC_ADD_SIZET -#define EPICS_ATOMIC_ADD_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta ) -{ - /* - * vxAtomicLib doc indicates that vxAtomicAdd is - * implemented using signed arithmetic, but it - * does not change the end result because twos - * complement addition is used in either case - */ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicAdd ( pTarg, (atomic_t) delta ); - return delta + ( size_t ) oldVal; -} -#endif - -#ifndef EPICS_ATOMIC_SUB_SIZET -#define EPICS_ATOMIC_SUB_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta ) -{ - /* - * vxAtomicLib doc indicates that vxAtomicSub is - * implemented using signed arithmetic, but it - * does not change the end result because twos - * complement subtraction is used in either case - */ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicSub ( pTarg, (atomic_t) delta ); - return ( ( size_t ) oldVal ) - delta; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_SIZET -#define EPICS_ATOMIC_CAS_SIZET -EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget, - size_t oldVal, size_t newVal ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - return ( size_t ) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal ); -} -#endif - -#ifndef EPICS_ATOMIC_CAS_PTRT -#define EPICS_ATOMIC_CAS_PTRT -EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT ( EpicsAtomicPtrT * pTarget, - EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - return (EpicsAtomicPtrT) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal ); -} -#endif - -#else /* ULONG_MAX == UINT_MAX */ - -/* - * if its 64 bit SMP vxWorks and the compiler doesnt - * have an intrinsic then maybe there isnt any way to - * implement these without using a global lock because - * size_t is maybe bigger than atomic_t - * - * I dont yet have access to vxWorks manuals for - * 64 bit systems so this is still undecided, but is - * defaulting now to a global lock - */ - -#endif /* ULONG_MAX == UINT_MAX */ - -STATIC_ASSERT ( sizeof ( atomic_t ) == sizeof ( int ) ); - -#ifndef EPICS_ATOMIC_INCR_INTT -#define EPICS_ATOMIC_INCR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicInc ( pTarg ); - return 1 + ( int ) oldVal; -} -#endif - -#ifndef EPICS_ATOMIC_DECR_INTT -#define EPICS_ATOMIC_DECR_INTT -EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicDec ( pTarg ); - return ( ( int ) oldVal ) - 1; -} -#endif - -#ifndef EPICS_ATOMIC_ADD_INTT -#define EPICS_ATOMIC_ADD_INTT -EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - const atomic_t oldVal = vxAtomicAdd ( pTarg, (atomic_t) delta ); - return delta + ( int ) oldVal; -} -#endif - -#ifndef EPICS_ATOMIC_CAS_INTT -#define EPICS_ATOMIC_CAS_INTT -EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget, - int oldVal, int newVal ) -{ - atomic_t * const pTarg = ( atomic_t * ) ( pTarget ); - return ( int ) vxCas ( pTarg, (atomic_t) oldVal, (atomic_t) newVal ); -} -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#else /* _WRS_VXWORKS_MAJOR * 100 + _WRS_VXWORKS_MINOR >= 606 */ - -#include "vxLib.h" -#include "intLib.h" - -#define EPICS_ATOMIC_OS_NAME "VX-INTLIB" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef EPICS_ATOMIC_LOCK -#define EPICS_ATOMIC_LOCK - -typedef struct EpicsAtomicLockKey { int m_key; } EpicsAtomicLockKey; - -EPICS_ATOMIC_INLINE void epicsAtomicLock ( EpicsAtomicLockKey * pKey ) -{ - pKey->m_key = intLock (); -} - -EPICS_ATOMIC_INLINE void epicsAtomicUnlock ( EpicsAtomicLockKey * pKey ) -{ - intUnlock ( pKey->m_key ); -} -#endif - -#ifndef EPICS_ATOMIC_READ_MEMORY_BARRIER -#define EPICS_ATOMIC_READ_MEMORY_BARRIER -/* - * no need for memory barrior since prior to vxWorks 6.6 it is a single cpu system - * (we are not protecting against multiple access to memory mapped IO) - */ -EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void) {} -#endif - -#ifndef EPICS_ATOMIC_WRITE_MEMORY_BARRIER -#define EPICS_ATOMIC_WRITE_MEMORY_BARRIER -/* - * no need for memory barrior since prior to vxWorks 6.6 it is a single cpu system - * (we are not protecting against multiple access to memory mapped IO) - */ -EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void) {} -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif /* __cplusplus */ - -#endif /* _WRS_VXWORKS_MAJOR * 100 + _WRS_VXWORKS_MINOR >= 606 */ - -#include "epicsAtomicDefault.h" - -#endif /* epicsAtomicOSD_h */ - diff --git a/src/libCom/osi/os/vxWorks/epicsDynLink.c b/src/libCom/osi/os/vxWorks/epicsDynLink.c deleted file mode 100644 index df954782a..000000000 --- a/src/libCom/osi/os/vxWorks/epicsDynLink.c +++ /dev/null @@ -1,94 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * On 68K targets, all symbols have an underscore prepended to their name. - * This code permits both standards to work, as long as you're not looking - * for a symbol name that actually begins with an underscore. - */ - -#include - -#include "epicsDynLink.h" - -#if _WRS_VXWORKS_MAJOR < 6 || _WRS_VXWORKS_MINOR < 9 - -static int symNoUnderscore(SYMTAB_ID symTblId) -{ - static int init = 0; - static int noUnderscore = 0; - - if (!init) { - char name[] = "symFindByNameEPICS"; - char *pSymValue; - SYM_TYPE type; - - if (symFindByName(symTblId, name, &pSymValue, &type) == OK) - noUnderscore = 1; - init = 1; - } - return noUnderscore; -} - -STATUS symFindByNameEPICS(SYMTAB_ID symTblId, char *name, char **ppvalue, - SYM_TYPE *pType) -{ - if (name[0] == '_' && symNoUnderscore(symTblId)) - name++; - - return symFindByName(symTblId, name, ppvalue, pType); -} - -STATUS symFindByNameAndTypeEPICS(SYMTAB_ID symTblId, char *name, - char **ppvalue, SYM_TYPE *pType, SYM_TYPE sType, SYM_TYPE mask) -{ - if (name[0] == '_' && symNoUnderscore(symTblId)) - name++; - - return symFindByNameAndType(symTblId, name, ppvalue, pType, sType, mask); -} - -#else /* VxWorks 6.9 deprecated the symFindBy routines */ - -STATUS symFindByNameEPICS(SYMTAB_ID symTblId, char *name, char **ppvalue, - SYM_TYPE *pType) -{ - SYMBOL_DESC symDesc; - STATUS status; - - memset(&symDesc, 0, sizeof(SYMBOL_DESC)); - symDesc.mask = SYM_FIND_BY_NAME; - symDesc.name = name + (name[0] == '_'); - status = symFind(sysSymTbl, &symDesc); - if (!status) { - *ppvalue = symDesc.value; - *pType = symDesc.type; - } - return status; -} - -STATUS symFindByNameAndTypeEPICS(SYMTAB_ID symTblId, char *name, - char **ppvalue, SYM_TYPE *pType, SYM_TYPE sType, SYM_TYPE mask) -{ - SYMBOL_DESC symDesc; - STATUS status; - - memset(&symDesc, 0, sizeof(SYMBOL_DESC)); - symDesc.mask = SYM_FIND_BY_NAME | SYM_FIND_BY_TYPE; - symDesc.name = name + (name[0] == '_'); - symDesc.type = sType; - symDesc.typeMask = mask; - status = symFind(sysSymTbl, &symDesc); - if (!status) { - *ppvalue = symDesc.value; - *pType = symDesc.type; - } - return status; -} - -#endif diff --git a/src/libCom/osi/os/vxWorks/epicsDynLink.h b/src/libCom/osi/os/vxWorks/epicsDynLink.h deleted file mode 100644 index 581260a49..000000000 --- a/src/libCom/osi/os/vxWorks/epicsDynLink.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * These routines will eventually need to be made OS independent - * (currently this is vxWorks specific) - */ - -#ifndef epicsDynLinkh -#define epicsDynLinkh - -#include "vxWorks.h" -#include "symLib.h" -#include "sysSymTbl.h" -#include "compilerDependencies.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Use epicsFindSymbol() instead of these */ - -STATUS symFindByNameEPICS(SYMTAB_ID symTblId, char *name, char **pvalue, - SYM_TYPE *pType) EPICS_DEPRECATED; - -STATUS symFindByNameAndTypeEPICS(SYMTAB_ID symTblId, char *name, char **pvalue, - SYM_TYPE *pType, SYM_TYPE sType, SYM_TYPE mask) EPICS_DEPRECATED; - -#ifdef __cplusplus -} -#endif - -#endif /* ifdef epicsDynLinkh */ - diff --git a/src/libCom/osi/os/vxWorks/epicsMMIO.h b/src/libCom/osi/os/vxWorks/epicsMMIO.h deleted file mode 100644 index b12c71ad9..000000000 --- a/src/libCom/osi/os/vxWorks/epicsMMIO.h +++ /dev/null @@ -1,174 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2006 The Regents of the University of California, -* as Operator of Los Alamos National Laboratory. -* Copyright (c) 2006 The Board of Trustees of the Leland Stanford Junior -* University, as Operator of the Stanford Linear Accelerator Center. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Original Author: Eric Bjorklund (was called mrfSyncIO.h) - * Author: Michael Davidsaver - */ - -#ifndef EPICSMMIO_H -#define EPICSMMIO_H - -#if (CPU_FAMILY != PPC) && (CPU_FAMILY != I80X86) -# include "epicsMMIODef.h" -#else - -/**************************************************************************************************/ -/* Required Header Files */ -/**************************************************************************************************/ - -/* This is needed on vxWorks 6.8 */ -#ifndef _VSB_CONFIG_FILE -# define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> -#endif - -#include /* vxWorks common definitions */ -#include /* vxWorks System Library Definitions */ -#include /* vxWorks Version Definitions */ - -#include /* EPICS Common Type Definitions */ -#include /* EPICS Byte Order Definitions */ -#include - -/*===================== - * vxAtomicLib.h (which defines the memory barrier macros) - * is available on vxWorks 6.6 and above. - */ - -#if _WRS_VXWORKS_MAJOR > 6 -# include -#elif _WRS_VXWORKS_MAJOR == 6 && _WRS_VXWORKS_MINOR >= 6 -# include -#endif - -static EPICS_ALWAYS_INLINE -epicsUInt16 -bswap16(epicsUInt16 value) -{ - return (((epicsUInt16)(value) & 0x00ff) << 8) | - (((epicsUInt16)(value) & 0xff00) >> 8); -} - -static EPICS_ALWAYS_INLINE -epicsUInt32 -bswap32(epicsUInt32 value) -{ - return (((epicsUInt32)(value) & 0x000000ff) << 24) | - (((epicsUInt32)(value) & 0x0000ff00) << 8) | - (((epicsUInt32)(value) & 0x00ff0000) >> 8) | - (((epicsUInt32)(value) & 0xff000000) >> 24); -} - -#if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG -# define be16_to_cpu(X) (epicsUInt16)(X) -# define be32_to_cpu(X) (epicsUInt32)(X) -# define le16_to_cpu(X) bswap16(X) -# define le32_to_cpu(X) bswap32(X) - -#elif EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE -# define be16_to_cpu(X) bswap16(X) -# define be32_to_cpu(X) bswap32(X) -# define le16_to_cpu(X) (epicsUInt16)(X) -# define le32_to_cpu(X) (epicsUInt32)(X) - -#else -# error Unable to determine native byte order -#endif - -#if CPU_FAMILY == PPC - -/* All PowerPC BSPs that I have studied implement these functions - * with the same definition, byte-swapping the data and adding a - * sync and/or eieio instruction as necessary on that CPU board. - * They do *not* all implement the sys{In/Out}{Byte/Word/Long} - * functions to do the same thing though, so we can't use them. - */ -#ifdef __cplusplus -extern "C" { -#endif -UINT8 sysPciInByte(UINT8 *addr); -void sysPciOutByte(UINT8 *addr, UINT8 data); -UINT16 sysPciInWord(UINT16 *addr); -void sysPciOutWord(UINT16 *addr, UINT16 data); -UINT32 sysPciInLong (UINT32 *addr); -void sysPciOutLong (UINT32 *addr, UINT32 data); -#ifdef __cplusplus -} -#endif - -#define ioread8(address) sysPciInByte((UINT8 *)(address)) -#define iowrite8(address,data) sysPciOutByte((UINT8 *)(address), (epicsUInt8)(data)) - -#define nat_ioread16(address) bswap16(sysPciInWord((UINT16 *)(address))) -#define nat_ioread32(address) bswap32(sysPciInLong((UINT32 *)(address))) - -#define nat_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), bswap16(data)) -#define nat_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), bswap32(data)) - -#define be_ioread16(address) bswap16(sysPciInWord((UINT16 *)(address))) -#define be_ioread32(address) bswap32(sysPciInLong((UINT32 *)(address))) - -#define be_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), bswap16(data)) -#define be_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), bswap32(data)) - -#define le_ioread16(address) sysPciInWord((UINT16 *)(address)) -#define le_ioread32(address) sysPciInLong((UINT32 *)(address)) - -#define le_iowrite16(address,data) sysPciOutWord((UINT16 *)(address), (data)) -#define le_iowrite32(address,data) sysPciOutLong((UINT32 *)(address), (data)) - -#else /* CPU_FAMILY == I80X86 */ - -/* All Intel BSPs should implement the sys{In/Out}{Byte/Word/Long} - * functions, which are declared in the sysLib.h header. - */ - -#define ioread8(address) sysInByte ((epicsUInt32)(address)) -#define iowrite8(address,data) sysOutByte ((epicsUInt32)(address), (epicsUInt8)(data)) - -#define nat_ioread16(address) sysInWord ((epicsUInt32)(address)) -#define nat_ioread32(address) sysInLong ((epicsUInt32)(address)) - -#define nat_iowrite16(address,data) sysOutWord((epicsUInt32)(address),(data)) -#define nat_iowrite32(address,data) sysOutLong((epicsUInt32)(address),(data)) - -#define be_ioread16(address) be16_to_cpu (sysInWord ((epicsUInt32)(address))) -#define be_ioread32(address) be32_to_cpu (sysInLong ((epicsUInt32)(address))) - -#define be_iowrite16(address,data) sysOutWord ((epicsUInt32)(address), be16_to_cpu((epicsUInt16)(data))) -#define be_iowrite32(address,data) sysOutLong ((epicsUInt32)(address), be32_to_cpu((epicsUInt32)(data))) - -#define le_ioread16(address) le16_to_cpu (sysInWord ((epicsUInt32)(address))) -#define le_ioread32(address) le32_to_cpu (sysInLong ((epicsUInt32)(address))) - -#define le_iowrite16(address,data) sysOutWord ((epicsUInt32)(address), le16_to_cpu((epicsUInt16)(data))) -#define le_iowrite32(address,data) sysOutLong ((epicsUInt32)(address), le32_to_cpu((epicsUInt32)(data))) - -#endif /* I80X86 */ - - -#ifndef VX_MEM_BARRIER_R -# define VX_MEM_BARRIER_R() do{}while(0) -#endif -#ifndef VX_MEM_BARRIER_W -# define VX_MEM_BARRIER_W() do{}while(0) -#endif -#ifndef VX_MEM_BARRIER_RW -# define VX_MEM_BARRIER_RW() do{}while(0) -#endif - -#define rbarr() VX_MEM_BARRIER_R() -#define wbarr() VX_MEM_BARRIER_W() -#define rwbarr() VX_MEM_BARRIER_RW() - -#endif /* CPU_FAMILY */ -#endif /* EPICSMMIO_H */ diff --git a/src/libCom/osi/os/vxWorks/epicsMath.h b/src/libCom/osi/os/vxWorks/epicsMath.h deleted file mode 100644 index e973d2d9c..000000000 --- a/src/libCom/osi/os/vxWorks/epicsMath.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef epicsMathh -#define epicsMathh - -#include -#include -#include - -/* private/mathP.h defines NAN as 4, and uses its value in the - * isNan() macro. We need mathP.h for isInf(), but can create - * our own isnan() test. epicsMath.cpp requires that NAN either - * be undef or yield the NaN value, so this solves the issue. - */ -#undef NAN - -#define isnan(D) (!(D == D)) -#define isinf(D) isInf(D) -#define finite(D) (!isnan(D) && !isInf(D)) - -#ifdef __cplusplus -extern "C" { -#endif - -epicsShareExtern float epicsNAN; -epicsShareExtern float epicsINF; - -#ifdef __cplusplus -} -#endif - -#endif /* epicsMathh */ diff --git a/src/libCom/osi/os/vxWorks/logMsgToErrlog.cpp b/src/libCom/osi/os/vxWorks/logMsgToErrlog.cpp deleted file mode 100644 index b44881cd0..000000000 --- a/src/libCom/osi/os/vxWorks/logMsgToErrlog.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * route vxWorks logMsg messages into the EPICS logging system - * - * Author: Jeff Hill - * - */ - -#include -#include - -#include -#include -#include - -#include "errlog.h" - -// vxCommonLibrary calls logMsgToErrlog so that logMsgToErrlog gets loaded -extern "C" { - int logMsgToErrlog(); -} - -int logMsgToErrlog() { return 0;} - -static class errlogDevTimeInit -{ -public: - errlogDevTimeInit (); -} errlogDevInstance; - -static int errlogOpen ( DEV_HDR *, const char *, int ) -{ - return OK; -} - -static int errlogWrite ( DEV_HDR *, const char * pInBuf, int nbytes ) -{ - errlogPrintfNoConsole ( "%.*s", nbytes, pInBuf ); - return nbytes; -} - -errlogDevTimeInit::errlogDevTimeInit () -{ - int errlogNo = iosDrvInstall ( - 0, // create not supported - 0, // remove not supported - reinterpret_cast < FUNCPTR > ( errlogOpen ), - 0, // close is a noop - 0, // read not supported - reinterpret_cast < FUNCPTR > ( errlogWrite ), - 0 // ioctl not supported - ); - if ( errlogNo == ERROR ) { - errlogPrintf ( - "Unable to install driver routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - return; - } - DEV_HDR * pDev = static_cast < DEV_HDR * > ( calloc ( 1, sizeof ( *pDev ) ) ); - if ( ! pDev ) { - errlogPrintf ( - "Unable to create driver data structure for routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - return; - } - int status = iosDevAdd ( pDev, "/errlog/", errlogNo ); - if ( status < 0 ) { - errlogPrintf ( - "Unable to install device routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - free ( pDev ); - return; - } - int fd = open ( "/errlog/any", O_WRONLY, 0 ); - if ( fd < 0 ) { - errlogPrintf ( - "Unable to open fd routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - return; - } - status = logFdAdd ( fd ); - if ( status != OK) { - errlogPrintf ( - "Unable to install fd routing the vxWorks " - "logging system to the EPICS logging system because \"%s\"\n", - strerror ( errno ) ); - close ( fd ); - return; - } -} - diff --git a/src/libCom/osi/os/vxWorks/module_types.h b/src/libCom/osi/os/vxWorks/module_types.h deleted file mode 100644 index 07372c37a..000000000 --- a/src/libCom/osi/os/vxWorks/module_types.h +++ /dev/null @@ -1,494 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* module_types.h */ -/* - * Author: Bob Dalesio - * Date: 12-07-88 - */ - -#ifndef INCLmodule_typesh -#define INCLmodule_typesh - -/* Device module types */ -/* - * all devices have corresponding entries in ~operator/db/src/menus.c - * changes must be made in both areas to keep the database and drivers in sync - */ -/* & in comment indicates tested with card 0 */ -/* % in comment indicates tested with card other than card 0 */ -/* # in comment indicates that the Nth card has been tested */ -/* !! never been tested */ - -/* - * @# If any changes are made to this file, check the procedures - * ab_card, and vme_card in signallist.c, and get_address in sigmenu.c. - */ - -#ifdef MODULE_TYPES_INIT -#define MODULE_TYPES_DEF(MT_DEF_PARM) MT_DEF_PARM -#else -#define MODULE_TYPES_DEF(MT_DEF_PARM) extern MT_DEF_PARM; -#endif - -/* Number of columns used in io_report. */ -#define IOR_MAX_COLS 4 - -/* I/O types */ -#define IO_AI 0 -#define IO_AO 1 -#define IO_BI 2 -#define IO_BO 3 -#define IO_SM 4 -#define IO_WF 5 -#define IO_TIMER 6 -#define MAX_IO_TYPE IO_TIMER - -/* bus types */ -/* must correspond to the values in link types */ -/* these defines are in ~gta/dbcon/h/link.h */ - - -/* equates for the Allen-Bradley cards. */ -#define AB_BASE_ADDR 0xc00000 /* base addr of first AB6008SV */ -#define AB_MAX_LINKS 2 /* number of serial links from VME */ -#define AB_MAX_ADAPTERS 8 /* number of physical adapters on a link */ -#define AB_MAX_CARDS 16 /* max number of IO cards per adapter */ -#define AB_CARD_ADAPTER 16 /* cards per logical adapter */ -#define AB_CHAN_CARD 16 /* max channels per card */ - -/* analog inputs */ -#define AB1771IL 0 /* &% Allen-Bradley low level analog input */ -#define AB1771IFE 1 /* &% Allen-Bradley low level analog input */ -#define AB1771IXE 2 /* &% Allen-Bradley millivolt input */ -#define XY566SE 3 /* & Xycom 12-bit Single Ended Scanned*/ -#define XY566DI 4 /* &% Xycom 12-bit Differential Scanned */ -#define XY566DIL 5 /* &% Xycom 12-bit Differential Latched */ -#define VXI_AT5_AI 6 /* % AT-5 VXI module's Analog Inputs */ -#define AB1771IFE_SE 7 /* % A-B IFE in 16 single-ended input mode */ -#define AB1771IFE_4to20MA 8 /* % A-B IFE in 8 double-ended 4to20Ma */ -#define DVX2502 9 /* &% DVX_2502 128 chan 16 bit differential */ -#define AB1771IFE_0to5V 10 /* % A-B IFE in 8 double-ended 4to20Ma */ -#define KSCV215 11 /* % KSC V215 VXI 16 bit differential */ -#define AB1771IrPlatinum 12 /* % A-B RTD Platinum */ -#define AB1771IrCopper 13 /* % A-B RTD Copper */ -#define MAX_AI_TYPES AB1771IrCopper -MODULE_TYPES_DEF(short ai_num_cards[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={12,12,12, 4, 4, 6,32,12,12, 1, 12, 32, 12,12}; -#endif -MODULE_TYPES_DEF(short ai_num_channels[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 8, 8, 8,32,16,16, 8,16, 8, 127, 8, 32,6,6}; -#endif -MODULE_TYPES_DEF(short ai_interruptable[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,0,0}; -#endif -MODULE_TYPES_DEF(short ai_bus[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 4, 2, 2, 2, 2, 4, 4, 2, 4, 2,4,4}; -#endif -MODULE_TYPES_DEF(unsigned short ai_addrs[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0,0x6000,0x7000,0xe000, 0xc014,0,0, 0xff00, 0, 0,0,0}; -#endif -MODULE_TYPES_DEF(long ai_memaddrs[MAX_AI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0,0,0,0x000000,0x040000,0x0c0000, 0,0,0, 0x100000, 0, 0,0,0}; -#endif - -/* analog outputs */ -#define AB1771OFE 0 /* &% Allen-Bradley 12 bit Analog Output */ -#define VMI4100 1 /* & VMIC VMIVME 4100 */ -#define ZIO085 2 /* & Ziomek 085 */ -#define VXI_AT5_AO 3 /* !! AT-5 VXI modules analog outputs */ -#define MAX_AO_TYPES VXI_AT5_AO -MODULE_TYPES_DEF(short ao_num_cards[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = {12, 4, 1, 32}; -#endif -MODULE_TYPES_DEF(short ao_num_channels[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = { 4, 16, 32, 16}; -#endif -MODULE_TYPES_DEF(short ao_interruptable[MAX_AO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 0, 0, 0, 1}; -#endif -MODULE_TYPES_DEF(short ao_bus[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 2, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short ao_addrs[MAX_AO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0x4100,0x0800, 0xc000}; -#endif - -/* binary inputs */ -#define ABBI_08_BIT 0 /* &% Allen-Bradley generic Binary In 8 bit */ -#define ABBI_16_BIT 1 /* &% Allen-Bradley generic Binary In 16 bit */ -#define BB910 2 /* & BURR BROWN MPV 910 (relay) */ -#define XY210 3 /* &% XYcom 32 bit binary in */ -#define VXI_AT5_BI 4 /* !! AT-5 VXI modules binary inputs */ -#define HPE1368A_BI 5 /* !! HP E1368A video switch */ -#define AT8_FP10S_BI 6 /* !! AT8 FP10 slave fast protect */ -#define XY240_BI 7 /* !! Xycom 32 bit binary in / 32 bit binary out */ -#define MAX_BI_TYPES XY240_BI -MODULE_TYPES_DEF(short bi_num_cards[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 12, 12, 4, 4, 32, 32, 8, 2}; -#endif -MODULE_TYPES_DEF(short bi_num_channels[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 16, 32, 32, 32, 16, 32, 32}; -#endif -MODULE_TYPES_DEF(short bi_interruptable[MAX_BI_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 1, 1, 0, 0, 1, 1, 1, 1}; -#endif -MODULE_TYPES_DEF(short bi_bus[MAX_BI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 2, 2, 2, 2, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short bi_addrs[MAX_BI_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0xb800,0xa000, 0xc000, 0xc000, 0x0e00, 0xd000}; -#endif - -/* binary outputs */ -#define ABBO_08_BIT 0 /* &% Allen-Bradley 8 bit binary out */ -#define ABBO_16_BIT 1 /* &% Allen-Bradley 16 bit binary out */ -#define BB902 2 /* &% BURR BROWN MPV 902 (relay) */ -#define XY220 3 /* &% XYcom 32 bit binary out */ -#define VXI_AT5_BO 4 /* !! AT-5 VXI modules binary outputs */ -#define HPE1368A_BO 5 /* !! HP E1368A video switch */ -#define AT8_FP10M_BO 6 /* !! AT8 FP10 master fast protect */ -#define XY240_BO 7 /* !! Xycom 32 bit binary in / 32 bit binary out */ -#define MAX_BO_TYPES XY240_BO -MODULE_TYPES_DEF(short bo_num_cards[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={12, 12, 4, 1, 32, 32, 2, 2}; -#endif -MODULE_TYPES_DEF(short bo_num_channels[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 16, 32, 32, 32, 16, 32, 32}; -#endif -MODULE_TYPES_DEF(short bo_interruptable[MAX_BO_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 0, 0, 0, 0, 1, 0, 0, 1 }; -#endif -MODULE_TYPES_DEF(short bo_bus[MAX_BO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 4, 4, 2, 2, 2, 2, 2, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short bo_addrs[MAX_BO_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0,0,0xd800,0xc800, 0xc000, 0xc000, 0x0c00, 0xd000}; -#endif - -/* stepper motor drivers */ -#define CM57_83E 0 /* & Compumotor 57-83E motor controller */ -#define OMS_6AXIS 1 /* & OMS six axis motor controller */ -#define MAX_SM_TYPES OMS_6AXIS -MODULE_TYPES_DEF(short sm_num_cards[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 8, 8 }; -#endif -MODULE_TYPES_DEF(short sm_num_channels[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 1, 8}; -#endif -MODULE_TYPES_DEF(short sm_interruptable[MAX_SM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 0, 0 }; -#endif -MODULE_TYPES_DEF(short sm_bus[MAX_SM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 2, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short sm_addrs[MAX_SM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 0x8000, 0xfc00 }; -#endif - -/* waveforms */ -#define XY566WF 0 /* & Xycom 566 as a waveform */ -#define CAMAC_THING 1 /* !! CAMAC waveform digitizer */ -#define JGVTR1 2 /* & Joerger transient recorder */ -#define COMET 3 /* !! COMET transient recorder */ -#define MAX_WF_TYPES COMET -MODULE_TYPES_DEF(short wf_num_cards[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={4, 4, 8, 4}; -#endif -MODULE_TYPES_DEF(short wf_num_channels[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={1, 1, 1, 4}; -#endif -MODULE_TYPES_DEF(short wf_interruptable[MAX_WF_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = {0, 0, 0, 0}; -#endif -MODULE_TYPES_DEF(short wf_bus[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={2, 3, 2, 2}; -#endif -MODULE_TYPES_DEF(unsigned short wf_addrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0x9000, 0, 0xB000, 0xbc00}; -#endif -MODULE_TYPES_DEF(unsigned short wf_armaddrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - = {0x5400, 0, 0, 0}; -#endif -MODULE_TYPES_DEF(long wf_memaddrs[MAX_WF_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0x080000, 0, 0xb80000, 0xe0000000}; -#endif - - -/* timing cards */ -#define MZ8310 0 /* &% Mizar Timing Module */ -#define DG535 1 /* !! GPIB timing instrument */ -#define VXI_AT5_TIME 2 /* !! AT-5 VXI modules timing channels */ -#define MAX_TM_TYPES VXI_AT5_TIME -MODULE_TYPES_DEF(short tm_num_cards[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={ 4, 1, 32 }; -#endif -MODULE_TYPES_DEF(short tm_num_channels[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - ={10, 1, 10}; -#endif -MODULE_TYPES_DEF(short tm_interruptable[MAX_TM_TYPES+1] ) -#ifdef MODULE_TYPES_INIT - = { 1, 0, 1 }; -#endif -MODULE_TYPES_DEF(short tm_bus[MAX_TM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={ 2, 5, 2 }; -#endif -MODULE_TYPES_DEF(unsigned short tm_addrs[MAX_TM_TYPES+1]) -#ifdef MODULE_TYPES_INIT - ={0xf800, 0, 0xc000 }; -#endif - -/* AT830X clock cards */ -MODULE_TYPES_DEF(long AT830X_1_addrs ) -#ifdef MODULE_TYPES_INIT - = 0x0400; -#endif -MODULE_TYPES_DEF(short AT830X_1_num_cards ) -#ifdef MODULE_TYPES_INIT - = 2; -#endif -MODULE_TYPES_DEF(long AT830X_addrs ) -#ifdef MODULE_TYPES_INIT - = 0xaa0000; -#endif -MODULE_TYPES_DEF(short AT830X_num_cards ) -#ifdef MODULE_TYPES_INIT - = 2; -#endif - -/* - * system controller cards. - * (driver looks for only one card) - */ -MODULE_TYPES_DEF(long xy010ScA16Base) -#ifdef MODULE_TYPES_INIT - = 0x0000; -#endif -/* - * limit the size of the VXI logical address space - * - * = + 0xc000 - * - * LA VME address - * 0 - * EPICS_VXI_LA_COUNT + (EPICS_VXI_LA_COUNT-1)*64 - */ -MODULE_TYPES_DEF(unsigned char EPICS_VXI_LA_COUNT) -#ifdef MODULE_TYPES_INIT - = 32; -#endif - -/* - * - * address ranges for VXI A24 and A32 devices - * - */ -MODULE_TYPES_DEF(char *EPICS_VXI_A24_BASE) -#ifdef MODULE_TYPES_INIT - = (char *) 0x900000; -#endif -MODULE_TYPES_DEF(unsigned long EPICS_VXI_A24_SIZE) -#ifdef MODULE_TYPES_INIT - = 0x100000; -#endif -MODULE_TYPES_DEF(char *EPICS_VXI_A32_BASE) -#ifdef MODULE_TYPES_INIT - = (char *) 0x90000000; -#endif -MODULE_TYPES_DEF(unsigned long EPICS_VXI_A32_SIZE) -#ifdef MODULE_TYPES_INIT - = 0x10000000; -#endif - - -/****************************************************************************** - * - * Interrupt vector locations used by the MV167 CPU board. - * These are defined in mv167.h - * - * PCC2_INT_VEC_BASE 0x40 PCC interrupt vector base number - * any multiple of 0x10 - * UTIL_INT_VEC_BASE0 0x50 VMEchip2 utility interrupt - * vector base number - * any multiple of 0x10 - * UTIL_INT_VEC_BASE1 0x60 VMEchip2 utility interrupt - * vector base number - * any multiple of 0x10 - * - * INT_VEC_CD2400_A 0x90 int vec for channel A - * INT_VEC_CD2400_B 0x94 int vec for channel B - * INT_VEC_CD2400_C 0x98 int vec for channel C - * INT_VEC_CD2400_D 0x9c int vec for channel D - * - * LANC_IRQ_LEVEL 3 LNANC IRQ level - * MPCC_IRQ_LEVEL 4 serial comm IRQ level - * SYS_CLK_LEVEL 6 interrupt level for sysClk - * AUX_CLK_LEVEL 5 interrupt level for auxClk - * SCSI_IRQ_LEVEL 2 scsi interrupt level - * - ******************************************************************************/ - -/* interrupt vector allocation - one for each XY566 DIL card */ -MODULE_TYPES_DEF(int AI566_VNUM) -#ifdef MODULE_TYPES_INIT - =0xf8; /* Xycom 566 Differential Latched */ -#endif - -/* interrupt vector allocation - one for each DVX card */ -MODULE_TYPES_DEF(int DVX_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd0; -#endif - -/* stepper motor interrupt vector - one for each motor */ -MODULE_TYPES_DEF(int MD_INT_BASE) -#ifdef MODULE_TYPES_INIT - =0xf0; /* base of the motor int vector */ -#endif - -/* I reserve from here up to num_cards * 4 interrupting chans/card - joh */ -MODULE_TYPES_DEF(int MZ8310_INT_VEC_BASE) -#ifdef MODULE_TYPES_INIT - =0xe8; -#endif - -/* Allen-Bradley Serial Driver - MAX_AB_LINKS number of vectors */ -MODULE_TYPES_DEF(int AB_VEC_BASE) -#ifdef MODULE_TYPES_INIT - =0x60; -#endif - -/* only one interrupt vector allocated for all Joerger VTR1 boards joh */ -MODULE_TYPES_DEF(int JGVTR1_INT_VEC) -#ifdef MODULE_TYPES_INIT - =0xe0; -#endif - -/* AT830X_1 cards have 1 intr vector for each AT830X_1_num_cards (presently 2) */ -MODULE_TYPES_DEF(int AT830X_1_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd4; -#endif - -/* AT830X cards have 1 intr vector for each AT830X_num_cards (presently 2) */ -MODULE_TYPES_DEF(int AT830X_IVEC0) -#ifdef MODULE_TYPES_INIT - =0xd6; -#endif - -/* AT8 fast protect interrupt vector base */ -MODULE_TYPES_DEF(int AT8FP_IVEC_BASE) -#ifdef MODULE_TYPES_INIT - =0xa2; -#endif - - -MODULE_TYPES_DEF(int AT8FPM_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - =0xaa; -#endif - - -/****************************************************************************** - * - * Addresses and IRQ information used by the XVME402 bitbus cards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short BB_SHORT_OFF ) -#ifdef MODULE_TYPES_INIT - = 0x1800; /* the first address of link 0's region */ -#endif -#define BB_NUM_LINKS 4 /* max number of BB ports allowed */ -MODULE_TYPES_DEF(int BB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 0xa0; /* vectored interrupts (2 used for each link) */ -#endif -MODULE_TYPES_DEF(int BB_IRQ_LEVEL ) -#ifdef MODULE_TYPES_INIT - = 5; /* IRQ level */ -#endif - -/****************************************************************************** - * - * Information for the PEP modular Bitbus boards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short PEP_BB_SHORT_OFF ) -#ifdef MODULE_TYPES_INIT - = 0x1c00; -#endif -MODULE_TYPES_DEF(int PEP_BB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 0xe8; -#endif - -/****************************************************************************** - * - * Addresses and IRQ information used by the NI1014 and NI1014D bitbus cards. - * - ******************************************************************************/ -MODULE_TYPES_DEF(unsigned short NIGPIB_SHORT_OFF) -#ifdef MODULE_TYPES_INIT - = 0x5000;/* First address of link 0's region */ -#endif - /* Each link uses 0x0200 bytes */ -#define NIGPIB_NUM_LINKS 4 /* Max number of NI GPIB ports allowed */ -MODULE_TYPES_DEF(int NIGPIB_IVEC_BASE ) -#ifdef MODULE_TYPES_INIT - = 100; /* Vectored interrupts (2 used for each link) */ -#endif -MODULE_TYPES_DEF(int NIGPIB_IRQ_LEVEL ) -#ifdef MODULE_TYPES_INIT - =5; /* IRQ level */ -#endif - -#if 0 /* JRW */ -#define NI1014_LINK_NUM_BASE 0 -#endif - -/* - * nothing after this endif - */ -#endif /*INCLmodule_typesh*/ diff --git a/src/libCom/osi/os/vxWorks/osdEnv.c b/src/libCom/osi/os/vxWorks/osdEnv.c deleted file mode 100644 index c81f49316..000000000 --- a/src/libCom/osi/os/vxWorks/osdEnv.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osdEnv.c */ -/* - * Author: Eric Norum - * Date: May 7, 2001 - * - * Routines to modify/display environment variables and EPICS parameters - * - */ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "epicsFindSymbol.h" -#include "epicsStdio.h" -#include "errlog.h" -#include "iocsh.h" - -/* - * Set the value of an environment variable - * Leaks memory, but the assumption is that this routine won't be - * called often enough for the leak to be a problem. - */ -epicsShareFunc void epicsShareAPI epicsEnvSet (const char *name, const char *value) -{ - char *cp; - - iocshEnvClear(name); - - cp = mallocMustSucceed (strlen (name) + strlen (value) + 2, "epicsEnvSet"); - strcpy (cp, name); - strcat (cp, "="); - strcat (cp, value); - if (putenv (cp) < 0) { - errPrintf(-1L, __FILE__, __LINE__, - "Failed to set environment parameter \"%s\" to \"%s\": %s\n", - name, value, strerror (errno)); - free (cp); - } -} - -/* - * Show the value of the specified, or all, environment variables - */ -epicsShareFunc void epicsShareAPI epicsEnvShow (const char *name) -{ - if (name == NULL) { - envShow (0); - } - else { - const char *cp = getenv (name); - if (cp == NULL) - printf ("%s is not an environment variable.\n", name); - else - printf ("%s=%s\n", name, cp); - } -} diff --git a/src/libCom/osi/os/vxWorks/osdEvent.c b/src/libCom/osi/os/vxWorks/osdEvent.c deleted file mode 100644 index 875d4e6f6..000000000 --- a/src/libCom/osi/os/vxWorks/osdEvent.c +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* os/vxWorks/osdEvent.c */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -#include -#include -#include -#include -#include -#include - -#include "epicsEvent.h" - -/* The following not defined in any vxWorks header */ -int sysClkRateGet(void); - -epicsEventId epicsEventCreate(epicsEventInitialState initialState) -{ - return (epicsEventId) semBCreate(SEM_Q_FIFO, - (initialState == epicsEventEmpty) ? SEM_EMPTY : SEM_FULL); -} - -void epicsEventDestroy(epicsEventId id) -{ - semDelete((SEM_ID)id); -} - -epicsEventStatus epicsEventWaitWithTimeout(epicsEventId id, double timeOut) -{ - int rate = sysClkRateGet(); - int status; - int ticks; - - if (timeOut <= 0.0) { - ticks = 0; - } else if (timeOut >= (double) INT_MAX / rate) { - ticks = WAIT_FOREVER; - } else { - ticks = timeOut * rate; - if (ticks <= 0) - ticks = 1; - } - status = semTake((SEM_ID)id, ticks); - if (status == OK) - return epicsEventOK; - if (errno == S_objLib_OBJ_TIMEOUT || - (errno == S_objLib_OBJ_UNAVAILABLE && ticks == 0)) - return epicsEventWaitTimeout; - return epicsEventError; -} - -epicsEventStatus epicsEventTryWait(epicsEventId id) -{ - int status = semTake((SEM_ID)id, NO_WAIT); - - if (status == OK) - return epicsEventOK; - if (errno == S_objLib_OBJ_UNAVAILABLE) - return epicsEventWaitTimeout; - return epicsEventError; -} - -void epicsEventShow(epicsEventId id, unsigned int level) -{ - semShow((SEM_ID)id,level); -} diff --git a/src/libCom/osi/os/vxWorks/osdEvent.h b/src/libCom/osi/os/vxWorks/osdEvent.h deleted file mode 100644 index b08b4d98f..000000000 --- a/src/libCom/osi/os/vxWorks/osdEvent.h +++ /dev/null @@ -1,20 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* os/vxWorks/osdEvent.h */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -#include -#include - -#define epicsEventTrigger(ID) \ - (semGive((SEM_ID)(ID)) == OK ? epicsEventOK : epicsEventError) - -#define epicsEventWait(ID) \ - (semTake((SEM_ID)(ID), WAIT_FOREVER) == OK ? epicsEventOK : epicsEventError) diff --git a/src/libCom/osi/os/vxWorks/osdFindSymbol.c b/src/libCom/osi/os/vxWorks/osdFindSymbol.c deleted file mode 100644 index da17c5bf3..000000000 --- a/src/libCom/osi/os/vxWorks/osdFindSymbol.c +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/vxWorks/osdFindSymbol */ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dbmf.h" -#include "epicsString.h" -#include "epicsFindSymbol.h" - -static char *errmsg = NULL; -static char *oldmsg = NULL; - -epicsShareFunc void * epicsLoadLibrary(const char *name) -{ - MODULE_ID m = 0; - int fd; - - if (oldmsg) { - free(oldmsg); - oldmsg = NULL; - } - if (errmsg) { - free(errmsg); - errmsg = NULL; - } - - fd = open(name, O_RDONLY, 0); - if (fd != ERROR) { - m = loadModule(fd, GLOBAL_SYMBOLS); - close(fd); - } - - if (!m) { - errmsg = epicsStrDup(strerror(errno)); - } - return m; -} - -epicsShareFunc const char *epicsLoadError(void) -{ - if (oldmsg) - free(oldmsg); - - oldmsg = errmsg; - errmsg = NULL; - return oldmsg; -} - -void *epicsFindSymbol(const char *name) -{ - STATUS status; - -#if _WRS_VXWORKS_MAJOR < 6 || _WRS_VXWORKS_MINOR < 9 - char *pvalue; - SYM_TYPE type; - - status = symFindByName(sysSymTbl, (char *)name, &pvalue, &type); - if (!status) - return pvalue; - - if (name[0] == '_' ) { - status = symFindByName(sysSymTbl, (char *)(name+1), &pvalue, &type); - } -#if CPU_FAMILY == MC680X0 - else { - char *pname = dbmfMalloc(strlen(name) + 2); - - pname[0] = '_'; - strcpy(pname + 1, name); - status = symFindByName(sysSymTbl, pname, &pvalue, &type); - dbmfFree(pname); - } -#endif - if (!status) - return pvalue; - -#else - - SYMBOL_DESC symDesc; - - memset(&symDesc, 0, sizeof(SYMBOL_DESC)); - symDesc.mask = SYM_FIND_BY_NAME; - symDesc.name = (char *) name; - status = symFind(sysSymTbl, &symDesc); - if (!status) - return symDesc.value; - - if (name[0] == '_') { - symDesc.name++; - status = symFind(sysSymTbl, &symDesc); - if (!status) - return symDesc.value; - } - /* No need to prepend an '_'; 68K-only, no longer supported */ -#endif - return 0; -} diff --git a/src/libCom/osi/os/vxWorks/osdInterrupt.c b/src/libCom/osi/os/vxWorks/osdInterrupt.c deleted file mode 100644 index 3ac9e9e83..000000000 --- a/src/libCom/osi/os/vxWorks/osdInterrupt.c +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/vxWorks/osdInterrupt.c */ - -/* Author: Marty Kraimer Date: 28JAN2000 */ - -#include -#include -#include - -#include "epicsInterrupt.h" - -int epicsInterruptLock() {return(intLock());} - -void epicsInterruptUnlock(int key) {intUnlock(key);} - -int epicsInterruptIsInterruptContext() {return(intContext());} - -void epicsInterruptContextMessage(const char *message) -{ - logMsg((char *)message,0,0,0,0,0,0); -} diff --git a/src/libCom/osi/os/vxWorks/osdInterrupt.h b/src/libCom/osi/os/vxWorks/osdInterrupt.h deleted file mode 100644 index ad99926de..000000000 --- a/src/libCom/osi/os/vxWorks/osdInterrupt.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/vxWorks/osdInterrupt.h */ - -/* Author: Marty Kraimer Date: 28JAN2000 */ - -/*osdInterrupt.h not needed */ diff --git a/src/libCom/osi/os/vxWorks/osdMessageQueue.cpp b/src/libCom/osi/os/vxWorks/osdMessageQueue.cpp deleted file mode 100644 index 89c2745ed..000000000 --- a/src/libCom/osi/os/vxWorks/osdMessageQueue.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -#define epicsExportSharedSymbols -#include -#include "epicsMessageQueue.h" - -extern "C" int sysClkRateGet(void); - -epicsShareFunc int epicsShareAPI epicsMessageQueueSendWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int messageSize, - double timeout) -{ - int ticks; - - if (timeout<=0.0) { - ticks = 0; - } else { - ticks = (int)(timeout*sysClkRateGet()); - if(ticks<=0) ticks = 1; - } - return msgQSend((MSG_Q_ID)id, (char *)message, messageSize, ticks, MSG_PRI_NORMAL); -} - -epicsShareFunc int epicsShareAPI epicsMessageQueueReceiveWithTimeout( - epicsMessageQueueId id, - void *message, - unsigned int size, - double timeout) -{ - int ticks; - - if (timeout<=0.0) { - ticks = 0; - } else { - ticks = (int)(timeout*sysClkRateGet()); - if(ticks<=0) ticks = 1; - } - return msgQReceive((MSG_Q_ID)id, (char *)message, size, ticks); -} diff --git a/src/libCom/osi/os/vxWorks/osdMessageQueue.h b/src/libCom/osi/os/vxWorks/osdMessageQueue.h deleted file mode 100644 index 87b35bd38..000000000 --- a/src/libCom/osi/os/vxWorks/osdMessageQueue.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - * norume@aps.anl.gov - * 630 252 4793 - */ - -/* - * Very thin shims around vxWorks routines - */ -#include -#include - -#define epicsMessageQueueCreate(c,s) ((epicsMessageQueueId)msgQCreate((c),(s),MSG_Q_FIFO)) -#define epicsMessageQueueDestroy(q) (msgQDelete((MSG_Q_ID)(q))) - -#define epicsMessageQueueTrySend(q,m,l) (msgQSend((MSG_Q_ID)(q), (char*)(m), (l), NO_WAIT, MSG_PRI_NORMAL)) -#define epicsMessageQueueSend(q,m,l) (msgQSend((MSG_Q_ID)(q), (char*)(m), (l), WAIT_FOREVER, MSG_PRI_NORMAL)) - -#define epicsMessageQueueTryReceive(q,m,s) (msgQReceive((MSG_Q_ID)(q), (char*)(m), (s), NO_WAIT)) -#define epicsMessageQueueReceive(q,m,s) (msgQReceive((MSG_Q_ID)(q), (char*)(m), (s), WAIT_FOREVER)) - -#define epicsMessageQueuePending(q) (msgQNumMsgs((MSG_Q_ID)(q))) -#define epicsMessageQueueShow(q,l) (msgQShow((MSG_Q_ID)(q),(l))) diff --git a/src/libCom/osi/os/vxWorks/osdMutex.c b/src/libCom/osi/os/vxWorks/osdMutex.c deleted file mode 100644 index 38db2ab83..000000000 --- a/src/libCom/osi/os/vxWorks/osdMutex.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* os/vxWorks/osdMutex.c */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -#include -#include -#include -#include -#include - -/* The following not defined in an vxWorks header */ -int sysClkRateGet(void); - - -#include "epicsMutex.h" - -struct epicsMutexOSD * epicsMutexOsdCreate(void) -{ - return((struct epicsMutexOSD *) - semMCreate(SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY)); -} - -void epicsMutexOsdDestroy(struct epicsMutexOSD * id) -{ - semDelete((SEM_ID)id); -} - -epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD * id) -{ - int status; - status = semTake((SEM_ID)id,NO_WAIT); - if(status==OK) return(epicsMutexLockOK); - if(errno==S_objLib_OBJ_UNAVAILABLE) return(epicsMutexLockTimeout); - return(epicsMutexLockError); -} - -void epicsMutexOsdShow(struct epicsMutexOSD * id,unsigned int level) -{ - semShow((SEM_ID)id,level); -} diff --git a/src/libCom/osi/os/vxWorks/osdMutex.h b/src/libCom/osi/os/vxWorks/osdMutex.h deleted file mode 100644 index 3ea951a8f..000000000 --- a/src/libCom/osi/os/vxWorks/osdMutex.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* os/vxWorks/osdMutex.h */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -#include -#include - -/* If the macro is replaced by inline it is necessary to say - static __inline__ - but then a warning message appears everywhere osdMutex.h is included -*/ - -#define epicsMutexOsdUnlock(ID) semGive((SEM_ID)(ID)) - -#define epicsMutexOsdLock(ID) \ -(semTake((SEM_ID)(ID),WAIT_FOREVER)==OK ? epicsMutexLockOK : epicsMutexLockError) diff --git a/src/libCom/osi/os/vxWorks/osdPoolStatus.c b/src/libCom/osi/os/vxWorks/osdPoolStatus.c deleted file mode 100644 index 06447c1f7..000000000 --- a/src/libCom/osi/os/vxWorks/osdPoolStatus.c +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsThread.h" -#include "osiPoolStatus.h" - -/* - * It turns out that memPartInfoGet() and memFindMax() are very CPU intensive on vxWorks - * so we must spawn off a thread that periodically polls. Although this isnt 100% safe, I - * dont see what else to do. - * - * It takes about 30 uS to call memPartInfoGet() on a pcPentium I vxWorks system. - * - * joh - */ - -static epicsThreadOnceId osdMaxBlockOnceler = EPICS_THREAD_ONCE_INIT; - -static size_t osdMaxBlockSize = 0; - -static void osdSufficentSpaceInPoolQuery () -{ - osdMaxBlockSize = (size_t) memFindMax (); -} - -static void osdSufficentSpaceInPoolPoll ( void *pArgIn ) -{ - while ( 1 ) { - epicsThreadSleep ( 1.0 ); - osdSufficentSpaceInPoolQuery (); - } -} - -static void osdSufficentSpaceInPoolInit ( void *pArgIn ) -{ - epicsThreadId id; - - osdSufficentSpaceInPoolQuery (); - - id = epicsThreadCreate ( "poolPoll", epicsThreadPriorityMedium, - epicsThreadGetStackSize ( epicsThreadStackSmall ), - osdSufficentSpaceInPoolPoll, 0 ); -} - -/* - * osiSufficentSpaceInPool () - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ) -{ - epicsThreadOnce ( &osdMaxBlockOnceler, osdSufficentSpaceInPoolInit, 0 ); - - if ( UINT_MAX - 100000u >= contiguousBlockSize ) { - return ( osdMaxBlockSize > 100000 + contiguousBlockSize ); - } - else { - return 0; - } -} diff --git a/src/libCom/osi/os/vxWorks/osdProcess.c b/src/libCom/osi/os/vxWorks/osdProcess.c deleted file mode 100644 index 2347a407c..000000000 --- a/src/libCom/osi/os/vxWorks/osdProcess.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Operating System Dependent Implementation of osiProcess.h - * - * Author: Jeff Hill - * - */ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include - -#include - -#define epicsExportSharedSymbols -#include "osiProcess.h" -#include "errlog.h" - -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSizeIn) -{ - char pName[MAX_IDENTITY_LEN]; - unsigned uiLength; - size_t len; - - remCurIdGet ( pName, NULL ); - len = strlen ( pName ); - - if (len>UINT_MAX || len<=0) { - return osiGetUserNameFail; - } - uiLength = (unsigned) len; - - if ( uiLength + 1 >= bufSizeIn ) { - return osiGetUserNameFail; - } - - strncpy ( pBuf, pName, (size_t) bufSizeIn ); - - return osiGetUserNameSuccess; -} - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - (const char *pProcessName, const char *pBaseExecutableName) -{ - return osiSpawnDetachedProcessNoSupport; -} diff --git a/src/libCom/osi/os/vxWorks/osdReadline.c b/src/libCom/osi/os/vxWorks/osdReadline.c deleted file mode 100644 index 9195b6b72..000000000 --- a/src/libCom/osi/os/vxWorks/osdReadline.c +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Author: Eric Norum Date: 12DEC2001 */ - -/* - * This file is included by epicsReadline.c which has already included the - * headers stdio.h, stdlib.h, errno.h, envDefs.h and epicsReadline.h - */ - -#include -#include - -/* FIXME: Remove line-lenth limitation */ -#define LEDLIB_LINESIZE 1000 - -#ifndef _WRS_VXWORKS_MAJOR -typedef int LED_ID; -#endif - -struct osdContext { - LED_ID ledId; - char line[LEDLIB_LINESIZE]; -}; - -/* - * Create a command-line context - */ -static void -osdReadlineBegin(struct readlineContext *context) -{ - struct osdContext osd = malloc(sizeof *osd); - - if (osd != NULL) { - osd->ledId = (LED_ID) ERROR; - if (context->in == NULL) { - long i = 50; - - envGetLongConfigParam(&IOCSH_HISTSIZE, &i); - if (i < 1) - i = 1; - - osd->ledId = ledOpen(fileno(stdin), fileno(stdout), i); - if (osd->ledId == (LED_ID) ERROR) { - context->in = stdin; - printf("Warning -- Unabled to allocate space for command-line history.\n"); - printf("Warning -- Command-line editting disabled.\n"); - } - } - context->osd = osd; - } -} - -/* - * Read a line of input - */ -static char * -osdReadline (const char *prompt, struct readlineContext *context) -{ - struct osdContext *osd = context->osd; - int i; - - if (prompt) { - fputs(prompt, stdout); - fflush(stdout); - } - if (osd->ledId != (LED_ID) ERROR) { - i = ledRead(osd->ledId, osd->line, LEDLIB_LINESIZE-1); - if (i < 0) - return NULL; - } - else { - if (fgets(osd->line, LEDLIB_LINESIZE, context->in) == NULL) - return NULL; - i = strlen(osd->line); - } - if ((i >= 1) && (osd->line[i-1] == '\n')) - osd->line[i-1] = '\0'; - else - osd->line[i] = '\0'; - return osd->line; -} - -/* - * Destroy a command-line context - */ -static void -osdReadlineEnd (struct readlineContext *context) -{ - LED_ID ledId = context->osd->ledId; - - if (ledId != (LED_ID) ERROR) - ledClose(ledId); - free(context->osd); -} - diff --git a/src/libCom/osi/os/vxWorks/osdSignal.cpp b/src/libCom/osi/os/vxWorks/osdSignal.cpp deleted file mode 100644 index 1157854aa..000000000 --- a/src/libCom/osi/os/vxWorks/osdSignal.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/*************************************************************************\ - * Copyright (c) 2002 The University of Chicago, as Operator of Argonne - * National Laboratory. - * Copyright (c) 2002 The Regents of the University of California, as - * Operator of Los Alamos National Laboratory. - * EPICS BASE Versions 3.13.7 - * and higher are distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "epicsSignal.h" - -/* - * NOOP - */ -epicsShareFunc void epicsShareAPI epicsSignalInstallSigHupIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigPipeIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalInstallSigAlarmIgnore ( void ) {} -epicsShareFunc void epicsShareAPI epicsSignalRaiseSigAlarm ( struct epicsThreadOSD * /* threadId */ ) {} diff --git a/src/libCom/osi/os/vxWorks/osdSock.c b/src/libCom/osi/os/vxWorks/osdSock.c deleted file mode 100644 index a0f5e8ec5..000000000 --- a/src/libCom/osi/os/vxWorks/osdSock.c +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include - -#ifndef vxWorks -#error this is a vxWorks specific source code -#endif - -#include -#include - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "osiSock.h" - -int osiSockAttach() -{ - return 1; -} - -void osiSockRelease() -{ -} - -epicsShareFunc SOCKET epicsShareAPI epicsSocketCreate ( - int domain, int type, int protocol ) -{ - SOCKET sock = socket ( domain, type, protocol ); - if ( sock < 0 ) { - sock = INVALID_SOCKET; - } - return sock; -} - -epicsShareFunc int epicsShareAPI epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ) -{ - int newSock = accept ( sock, pAddr, addrlen ); - if ( newSock < 0 ) { - newSock = INVALID_SOCKET; - } - return newSock; -} - -epicsShareFunc void epicsShareAPI epicsSocketDestroy ( SOCKET s ) -{ - int status = close ( s ); - if ( status < 0 ) { - char buf [ 64 ]; - epicsSocketConvertErrnoToString ( buf, sizeof ( buf ) ); - errlogPrintf ( - "epicsSocketDestroy: failed to " - "close a socket because \"%s\"\n", - buf ); - } -} - -/* - * ipAddrToHostName - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName - (const struct in_addr *pAddr, char *pBuf, unsigned bufSize) -{ - int status; - int errnoCopy = errno; - unsigned len; - - if (bufSize<1) { - return 0; - } - - if (bufSize>MAXHOSTNAMELEN) { - status = hostGetByAddr ((int)pAddr->s_addr, pBuf); - if (status==OK) { - pBuf[MAXHOSTNAMELEN] = '\0'; - len = strlen (pBuf); - } - else { - len = 0; - } - } - else { - char name[MAXHOSTNAMELEN+1]; - status = hostGetByAddr (pAddr->s_addr, name); - if (status==OK) { - strncpy (pBuf, name, bufSize); - pBuf[bufSize-1] = '\0'; - len = strlen (pBuf); - } - else { - len = 0; - } - } - - errno = errnoCopy; - - return len; -} - -/* - * hostToIPAddr () - */ -epicsShareFunc int epicsShareAPI -hostToIPAddr(const char *pHostName, struct in_addr *pIPA) -{ - int addr = hostGetByName ( (char *) pHostName ); - if ( addr == ERROR ) { - return -1; - } - pIPA->s_addr = (unsigned long) addr; - - /* - * success - */ - return 0; -} - diff --git a/src/libCom/osi/os/vxWorks/osdSock.h b/src/libCom/osi/os/vxWorks/osdSock.h deleted file mode 100644 index 80464ef87..000000000 --- a/src/libCom/osi/os/vxWorks/osdSock.h +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * vxWorks specific socket include - */ - -#ifndef osdSockH -#define osdSockH - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#ifndef _VSB_CONFIG_FILE -# define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*This following is not defined in any vxWorks header files*/ -int sysClkRateGet(void); - -#ifdef __cplusplus -} -#endif - -typedef int SOCKET; -#define INVALID_SOCKET (-1) -#define SOCKERRNO errno -#ifndef SHUT_RD -# define SHUT_RD 0 -#endif -#ifndef SHUT_WR -# define SHUT_WR 1 -#endif -#ifndef SHUT_RDWR -# define SHUT_RDWR 2 -#endif - -/* - * it is quite lame on WRS's part to assume that - * a ptr is always the same as an int - */ -#define socket_ioctl(A,B,C) ioctl(A,B,(int)C) -typedef int osiSockIoctl_t; -typedef int osiSocklen_t; - -#define FD_IN_FDSET(FD) ((FD)=0) - -#define SOCK_EWOULDBLOCK EWOULDBLOCK -#define SOCK_ENOBUFS ENOBUFS -#define SOCK_ECONNRESET ECONNRESET -#define SOCK_ETIMEDOUT ETIMEDOUT -#define SOCK_EACCES EACCES -#define SOCK_EADDRINUSE EADDRINUSE -#define SOCK_EADDRNOTAVAIL EADDRNOTAVAIL -#define SOCK_ECONNREFUSED ECONNREFUSED -#define SOCK_ECONNABORTED ECONNABORTED -#define SOCK_EINPROGRESS EINPROGRESS -#define SOCK_EISCONN EISCONN -#define SOCK_EALREADY EALREADY -#define SOCK_EINVAL EINVAL -#define SOCK_EINTR EINTR -#define SOCK_EPIPE EPIPE -#define SOCK_EMFILE EMFILE -#define SOCK_SHUTDOWN ESHUTDOWN -#define SOCK_ENOTSOCK ENOTSOCK -#define SOCK_EBADF EBADF - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7F000001 -#endif - -#ifndef INADDR_NONE -# define INADDR_NONE (0xffffffff) -#endif - -#if defined(_SIZEOF_ADDR_IFREQ) -# define ifreq_size(pifreq) _SIZEOF_ADDR_IFREQ(*pifreq) -#elif ( defined (BSD) && ( BSD >= 44 ) ) -# define ifreq_size(pifreq) (pifreq->ifr_addr.sa_len + sizeof(pifreq->ifr_name)) -#else -# define ifreq_size(pifreq) sizeof(*pifreq) -#endif - -#endif /*osdSockH*/ diff --git a/src/libCom/osi/os/vxWorks/osdSpin.c b/src/libCom/osi/os/vxWorks/osdSpin.c deleted file mode 100644 index a68cdd374..000000000 --- a/src/libCom/osi/os/vxWorks/osdSpin.c +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2013 Brookhaven Science Assoc. as Operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Authors: Ralph Lange - * Andrew Johnson - * Michael Davidsaver - * - * Inspired by Linux UP spinlocks implemention - * include/linux/spinlock_api_up.h - */ - -/* - * vxWorks (single CPU): LOCK INTERRUPT and DISABLE PREEMPTION - * - * CAVEAT: - * This implementation will not compile on vxWorks SMP architectures. - * These architectures provide spinlocks, which must be used instead. - * - */ - -/* This is needed for vxWorks 6.x to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include - -#include "cantProceed.h" -#include "epicsSpin.h" - -typedef struct epicsSpin { - int key; - unsigned int locked; -} epicsSpin; - -epicsSpinId epicsSpinCreate(void) { - return calloc(1, sizeof(epicsSpin)); -} - -epicsSpinId epicsSpinMustCreate(void) -{ - epicsSpinId ret = epicsSpinCreate(); - if (!ret) - cantProceed("epicsSpinMustCreate: epicsSpinCreate failed."); - return ret; -} - -void epicsSpinDestroy(epicsSpinId spin) { - free(spin); -} - -void epicsSpinLock(epicsSpinId spin) { - int key = intLock(); - - if (!intContext()) - taskLock(); - if (spin->locked) { - intUnlock(key); - if (!intContext()) { - taskUnlock(); - logMsg("epicsSpinLock(%p): Deadlock.\n", - (int) spin, 0, 0, 0, 0, 0); - cantProceed("Recursive lock, missed unlock or block when locked."); - } - else { - logMsg("epicsSpinLock(%p): Deadlock in ISR.\n" - "Recursive lock, missed unlock or block when locked.\n", - (int) spin, 0, 0, 0, 0, 0); - } - return; - } - spin->key = key; - spin->locked = 1; -} - -int epicsSpinTryLock(epicsSpinId spin) { - int key = intLock(); - - if (!intContext()) - taskLock(); - if (spin->locked) { - intUnlock(key); - if (!intContext()) - taskUnlock(); - return 1; - } - spin->key = key; - spin->locked = 1; - return 0; -} - -void epicsSpinUnlock(epicsSpinId spin) { - int key = spin->key; - - if (!spin->locked) { - logMsg("epicsSpinUnlock(%p): not locked\n", - (int) spin, 0, 0, 0, 0, 0); - return; - } - spin->key = spin->locked = 0; - intUnlock(key); - if (!intContext()) - taskUnlock(); -} diff --git a/src/libCom/osi/os/vxWorks/osdStdio.c b/src/libCom/osi/os/vxWorks/osdStdio.c deleted file mode 100644 index 20664a1a4..000000000 --- a/src/libCom/osi/os/vxWorks/osdStdio.c +++ /dev/null @@ -1,57 +0,0 @@ -/* osdStdio.c */ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include "epicsStdio.h" -#include "dbDefs.h" - -struct outStr_s { - char *str; - size_t free; -}; - -static STATUS outRoutine(char *buffer, size_t nchars, int outarg) { - struct outStr_s *poutStr = (struct outStr_s *) outarg; - size_t free = poutStr->free; - size_t len; - - if (free < 1) { /*let fioFormatV continue to count length*/ - return OK; - } else if (free > 1) { - len = min(free-1, nchars); - strncpy(poutStr->str, buffer, len); - poutStr->str += len; - poutStr->free -= len; - } - /*make sure final string is null terminated*/ - *poutStr->str = 0; - return OK; -} - -int epicsVsnprintf(char *str, size_t size, const char *format, va_list ap) { - struct outStr_s outStr; - - outStr.str = str; - outStr.free = size; - return fioFormatV(format, ap, outRoutine, (int) &outStr); -} - -int epicsSnprintf(char *str, size_t size, const char *format, ...) -{ - size_t nchars; - va_list pvar; - - va_start(pvar,format); - nchars = epicsVsnprintf(str,size,format,pvar); - va_end (pvar); - return(nchars); -} diff --git a/src/libCom/osi/os/vxWorks/osdStrtod.h b/src/libCom/osi/os/vxWorks/osdStrtod.h deleted file mode 100644 index 91c47d70e..000000000 --- a/src/libCom/osi/os/vxWorks/osdStrtod.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Saskatchewan -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * This header is included by epicsString.h and epicsStdlib.h - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * epicsStrtod() for systems with broken strtod() routine - */ -double epicsStrtod(const char *str, char **endp); - -/* - * VxWorks doesn't provide these routines, so for now we do - */ - -long long int strtoll(const char *nptr, char **endptr, int base); -unsigned long long int strtoull(const char *nptr, char **endptr, int base); - -#ifdef __cplusplus -} -#endif diff --git a/src/libCom/osi/os/vxWorks/osdThread.c b/src/libCom/osi/os/vxWorks/osdThread.c deleted file mode 100644 index ce01ea609..000000000 --- a/src/libCom/osi/os/vxWorks/osdThread.c +++ /dev/null @@ -1,457 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* osi/os/vxWorks/epicsThread.c */ - -/* Author: Marty Kraimer Date: 25AUG99 */ - -/* This is needed for vxWorks 6.8 to prevent an obnoxious compiler warning */ -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "errlog.h" -#include "ellLib.h" -#include "epicsThread.h" -#include "cantProceed.h" -#include "epicsAssert.h" -#include "vxLib.h" -#include "epicsExit.h" - -epicsShareFunc void osdThreadHooksRun(epicsThreadId id); - -#if CPU_FAMILY == MC680X0 -#define ARCH_STACK_FACTOR 1 -#elif CPU_FAMILY == SPARC -#define ARCH_STACK_FACTOR 2 -#else -#define ARCH_STACK_FACTOR 2 -#endif -static const unsigned stackSizeTable[epicsThreadStackBig+1] = - {4000*ARCH_STACK_FACTOR, 6000*ARCH_STACK_FACTOR, 11000*ARCH_STACK_FACTOR}; - -/* Table and lock for epicsThreadMap() */ -#define ID_LIST_CHUNK 512 -static int *taskIdList = 0; -int taskIdListSize = 0; -static SEM_ID epicsThreadListMutex = 0; - -/* This routine is found in atReboot.cpp */ -extern void atRebootRegister(void); - -/* definitions for implementation of epicsThreadPrivate */ -static void **papTSD = 0; -static int nepicsThreadPrivate = 0; - -static SEM_ID epicsThreadOnceMutex = 0; - -/* Just map osi 0 to 99 into vx 100 to 199 */ -/* remember that for vxWorks lower number means higher priority */ -/* vx = 100 + (99 -osi) = 199 - osi*/ -/* osi = 199 - vx */ - -static unsigned int getOsiPriorityValue(int ossPriority) -{ - if ( ossPriority < 100 ) { - return epicsThreadPriorityMax; - } - else if ( ossPriority > 199 ) { - return epicsThreadPriorityMin; - } - else { - return ( 199u - (unsigned int) ossPriority ); - } -} - -static int getOssPriorityValue(unsigned int osiPriority) -{ - if ( osiPriority > 99 ) { - return 100; - } - else { - return ( 199 - (signed int) osiPriority ); - } -} - -#define THREAD_SEM_FLAGS (SEM_DELETE_SAFE|SEM_INVERSION_SAFE|SEM_Q_PRIORITY) -static void epicsThreadInit(void) -{ - static int lock = 0; - static int done = 0; - - if (done) return; - - while(!vxTas(&lock)) - taskDelay(1); - - if (!done) { - epicsThreadOnceMutex = semMCreate(THREAD_SEM_FLAGS); - assert(epicsThreadOnceMutex); - epicsThreadListMutex = semMCreate(THREAD_SEM_FLAGS); - assert(epicsThreadListMutex); - taskIdList = calloc(ID_LIST_CHUNK, sizeof(int)); - assert(taskIdList); - taskIdListSize = ID_LIST_CHUNK; - atRebootRegister(); - done = 1; - } - lock = 0; -} - -void epicsThreadRealtimeLock(void) -{} - -unsigned int epicsThreadGetStackSize (epicsThreadStackSizeClass stackSizeClass) -{ - - if (stackSizeClassepicsThreadStackBig) { - errlogPrintf("epicsThreadGetStackSize illegal argument (too large)"); - return stackSizeTable[epicsThreadStackBig]; - } - - return stackSizeTable[stackSizeClass]; -} - -struct epicsThreadOSD {}; - /* Strictly speaking this should be a WIND_TCB, but we only need it to - * be able to create an epicsThreadId that is guaranteed never to be - * the same as any current TID, and since TIDs are pointers this works. - */ - -void epicsThreadOnce(epicsThreadOnceId *id, void (*func)(void *), void *arg) -{ - static struct epicsThreadOSD threadOnceComplete; - #define EPICS_THREAD_ONCE_DONE &threadOnceComplete - int result; - - epicsThreadInit(); - result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); - assert(result == OK); - if (*id != EPICS_THREAD_ONCE_DONE) { - if (*id == EPICS_THREAD_ONCE_INIT) { /* first call */ - *id = epicsThreadGetIdSelf(); /* mark active */ - semGive(epicsThreadOnceMutex); - func(arg); - result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); - assert(result == OK); - *id = EPICS_THREAD_ONCE_DONE; /* mark done */ - } else if (*id == epicsThreadGetIdSelf()) { - semGive(epicsThreadOnceMutex); - cantProceed("Recursive epicsThreadOnce() initialization\n"); - } else - while (*id != EPICS_THREAD_ONCE_DONE) { - /* Another thread is in the above func(arg) call. */ - semGive(epicsThreadOnceMutex); - epicsThreadSleep(epicsThreadSleepQuantum()); - result = semTake(epicsThreadOnceMutex, WAIT_FOREVER); - assert(result == OK); - } - } - semGive(epicsThreadOnceMutex); -} - -static void createFunction(EPICSTHREADFUNC func, void *parm) -{ - int tid = taskIdSelf(); - - taskVarAdd(tid,(int *)(char *)&papTSD); - /*Make sure that papTSD is still 0 after that call to taskVarAdd*/ - papTSD = 0; - osdThreadHooksRun((epicsThreadId)tid); - (*func)(parm); - epicsExitCallAtThreadExits (); - free(papTSD); - taskVarDelete(tid,(int *)(char *)&papTSD); -} - -#ifdef ALTIVEC - #define TASK_FLAGS (VX_FP_TASK | VX_ALTIVEC_TASK) -#else - #define TASK_FLAGS (VX_FP_TASK) -#endif -epicsThreadId epicsThreadCreate(const char *name, - unsigned int priority, unsigned int stackSize, - EPICSTHREADFUNC funptr,void *parm) -{ - int tid; - - epicsThreadInit(); - if(stackSize<100) { - errlogPrintf("epicsThreadCreate %s illegal stackSize %d\n",name,stackSize); - return(0); - } - tid = taskSpawn((char *)name,getOssPriorityValue(priority), - TASK_FLAGS, stackSize, - (FUNCPTR)createFunction,(int)funptr,(int)parm, - 0,0,0,0,0,0,0,0); - if(tid==ERROR) { - errlogPrintf("epicsThreadCreate %s failure %s\n", - name,strerror(errno)); - return(0); - } - return((epicsThreadId)tid); -} - -void epicsThreadSuspendSelf() -{ - STATUS status; - - status = taskSuspend(taskIdSelf()); - if(status) errlogPrintf("epicsThreadSuspendSelf failed\n"); -} - -void epicsThreadResume(epicsThreadId id) -{ - int tid = (int)id; - STATUS status; - - status = taskResume(tid); - if(status) errlogPrintf("epicsThreadResume failed\n"); -} - -void epicsThreadExitMain(void) -{ - errlogPrintf("epicsThreadExitMain was called for vxWorks. Why?\n"); -} - -unsigned int epicsThreadGetPriority(epicsThreadId id) -{ - int tid = (int)id; - STATUS status; - int priority = 0; - - status = taskPriorityGet(tid,&priority); - if(status) errlogPrintf("epicsThreadGetPriority failed\n"); - return(getOsiPriorityValue(priority)); -} - -unsigned int epicsThreadGetPrioritySelf(void) -{ - return(epicsThreadGetPriority(epicsThreadGetIdSelf())); -} - -void epicsThreadSetPriority(epicsThreadId id,unsigned int osip) -{ - int tid = (int)id; - STATUS status; - int priority = 0; - - priority = getOssPriorityValue(osip); - status = taskPrioritySet(tid,priority); - if(status) errlogPrintf("epicsThreadSetPriority failed\n"); -} - -epicsThreadBooleanStatus epicsThreadHighestPriorityLevelBelow( - unsigned int priority, unsigned *pPriorityJustBelow) -{ - unsigned newPriority = priority - 1; - if (newPriority <= 99) { - *pPriorityJustBelow = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -epicsThreadBooleanStatus epicsThreadLowestPriorityLevelAbove( - unsigned int priority, unsigned *pPriorityJustAbove) -{ - unsigned newPriority = priority + 1; - - newPriority = priority + 1; - if (newPriority <= 99) { - *pPriorityJustAbove = newPriority; - return epicsThreadBooleanStatusSuccess; - } - return epicsThreadBooleanStatusFail; -} - -int epicsThreadIsEqual(epicsThreadId id1, epicsThreadId id2) -{ - return((id1==id2) ? 1 : 0); -} - -int epicsThreadIsSuspended(epicsThreadId id) -{ - int tid = (int)id; - return((int)taskIsSuspended(tid)); -} - -void epicsThreadSleep(double seconds) -{ - STATUS status; - int ticks; - - if (seconds > 0.0) { - seconds *= sysClkRateGet(); - seconds += 0.99999999; /* 8 9s here is optimal */ - ticks = (seconds >= INT_MAX) ? INT_MAX : (int) seconds; - } - else { /* seconds <= 0 or NAN */ - ticks = 0; - } - status = taskDelay(ticks); - if(status) errlogPrintf("epicsThreadSleep\n"); -} - -epicsThreadId epicsThreadGetIdSelf(void) -{ - return((epicsThreadId)taskIdSelf()); -} - -epicsThreadId epicsThreadGetId(const char *name) -{ - int tid = taskNameToId((char *)name); - return((epicsThreadId)(tid==ERROR?0:tid)); -} - -const char *epicsThreadGetNameSelf(void) -{ - return taskName(taskIdSelf()); -} - -void epicsThreadGetName (epicsThreadId id, char *name, size_t size) -{ - int tid = (int)id; - strncpy(name,taskName(tid),size-1); - name[size-1] = '\0'; -} - -epicsShareFunc void epicsThreadMap ( EPICS_THREAD_HOOK_ROUTINE func ) -{ - int noTasks = 0; - int i; - int result; - - result = semTake(epicsThreadListMutex, WAIT_FOREVER); - assert(result == OK); - while (noTasks == 0) { - noTasks = taskIdListGet(taskIdList, taskIdListSize); - if (noTasks == taskIdListSize) { - taskIdList = realloc(taskIdList, (taskIdListSize+ID_LIST_CHUNK)*sizeof(int)); - assert(taskIdList); - taskIdListSize += ID_LIST_CHUNK; - noTasks = 0; - } - } - for (i = 0; i < noTasks; i++) { - func ((epicsThreadId)taskIdList[i]); - } - semGive(epicsThreadListMutex); -} - -void epicsThreadShowAll(unsigned int level) -{ - taskShow(0,2); -} - -void epicsThreadShow(epicsThreadId id, unsigned int level) -{ - int tid = (int)id; - - if (level > 1) level = 1; - if (tid) - taskShow(tid, level); -} - -/* The following algorithm was thought of by Andrew Johnson APS/ASD . - * The basic idea is to use a single vxWorks task variable. - * The task variable is papTSD, which is an array of pointers to the TSD - * The array size is equal to the number of epicsThreadPrivateIds created + 1 - * when epicsThreadPrivateSet is called. - * Until the first call to epicsThreadPrivateCreate by a application papTSD=0 - * After first call papTSD[0] is value of nepicsThreadPrivate when - * epicsThreadPrivateSet was last called by the thread. This is also - * the value of epicsThreadPrivateId. - * The algorithm allows for epicsThreadPrivateCreate being called after - * the first call to epicsThreadPrivateSet. - */ -epicsThreadPrivateId epicsThreadPrivateCreate() -{ - static int lock = 0; - epicsThreadPrivateId id; - - epicsThreadInit(); - /*lock is necessary because ++nepicsThreadPrivate may not be indivisible*/ - while(!vxTas(&lock)) taskDelay(1); - id = (epicsThreadPrivateId)++nepicsThreadPrivate; - lock = 0; - return(id); -} - -void epicsThreadPrivateDelete(epicsThreadPrivateId id) -{ - /*nothing to delete */ - return; -} - -/* - * No mutex is necessary here because by definition - * thread variables are local to a single thread. - */ -void epicsThreadPrivateSet (epicsThreadPrivateId id, void *pvt) -{ - int int_id = (int)id; - int nepicsThreadPrivateOld = 0; - - if (papTSD) nepicsThreadPrivateOld = (int)papTSD[0]; - - if (!papTSD || nepicsThreadPrivateOld < int_id) { - void **papTSDold = papTSD; - int i; - - papTSD = callocMustSucceed(int_id + 1,sizeof(void *), - "epicsThreadPrivateSet"); - papTSD[0] = (void *)(int_id); - for (i = 1; i <= nepicsThreadPrivateOld; i++) { - papTSD[i] = papTSDold[i]; - } - free (papTSDold); - } - papTSD[int_id] = pvt; -} - -void *epicsThreadPrivateGet(epicsThreadPrivateId id) -{ - int int_id = (int)id; - - /* - * If epicsThreadPrivateGet() is called before epicsThreadPrivateSet() - * for any particular thread, the value returned is always NULL. - */ - if ( papTSD && int_id <= (int) papTSD[0] ) { - return papTSD[int_id]; - } - return NULL; -} - -double epicsThreadSleepQuantum () -{ - double HZ = sysClkRateGet (); - return 1.0 / HZ; -} - -epicsShareFunc int epicsThreadGetCPUs(void) -{ - return 1; -} diff --git a/src/libCom/osi/os/vxWorks/osdThread.h b/src/libCom/osi/os/vxWorks/osdThread.h deleted file mode 100644 index 2ee9f2d46..000000000 --- a/src/libCom/osi/os/vxWorks/osdThread.h +++ /dev/null @@ -1,13 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#ifndef osdThreadh -#define osdThreadh - -#endif /* osdThreadh */ diff --git a/src/libCom/osi/os/vxWorks/osdThreadExtra.c b/src/libCom/osi/os/vxWorks/osdThreadExtra.c deleted file mode 100644 index 0a7c7ae95..000000000 --- a/src/libCom/osi/os/vxWorks/osdThreadExtra.c +++ /dev/null @@ -1,16 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Ralph Lange Date: 26 Jun 2012 */ - -/* Null default thread hooks for all platforms that do not do anything special */ - -#define epicsExportSharedSymbols -#include "epicsThread.h" - -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookDefault; -epicsShareDef EPICS_THREAD_HOOK_ROUTINE epicsThreadHookMain; diff --git a/src/libCom/osi/os/vxWorks/osdTime.cpp b/src/libCom/osi/os/vxWorks/osdTime.cpp deleted file mode 100644 index 4db375fbb..000000000 --- a/src/libCom/osi/os/vxWorks/osdTime.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#define _VSB_CONFIG_FILE <../lib/h/config/vsbConfig.h> - -#include -#include -#include -#include -#include -#include - -#include "epicsTime.h" -#include "osiNTPTime.h" -#include "osiClockTime.h" -#include "generalTimeSup.h" -#include "envDefs.h" - -#define NTP_REQUEST_TIMEOUT 4 /* seconds */ - -static char sntp_sync_task[] = "ipsntps"; -static char ntp_daemon[] = "ipntpd"; - -static const char *pserverAddr = NULL; -extern char* sysBootLine; - -static int timeRegister(void) -{ - /* If TIMEZONE not defined, set it from EPICS_TIMEZONE */ - if (getenv("TIMEZONE") == NULL) { - const char *timezone = envGetConfigParamPtr(&EPICS_TIMEZONE); - if (timezone == NULL) { - printf("timeRegister: No Time Zone Information\n"); - } else { - epicsEnvSet("TIMEZONE", timezone); - } - } - - // Define EPICS_TS_FORCE_NTPTIME to force use of NTPTime provider - bool useNTP = getenv("EPICS_TS_FORCE_NTPTIME") != NULL; - - if (!useNTP && - (taskNameToId(sntp_sync_task) != ERROR || - taskNameToId(ntp_daemon) != ERROR)) { - // A VxWorks 6 SNTP/NTP sync task is running - struct timespec clockNow; - - useNTP = clock_gettime(CLOCK_REALTIME, &clockNow) != OK || - clockNow.tv_sec < BUILD_TIME; - // Assumes VxWorks and the host OS have the same epoch - } - - if (useNTP) { - // Start NTP first so it can be used to sync SysTime - NTPTime_Init(100); - ClockTime_Init(CLOCKTIME_SYNC); - } else { - ClockTime_Init(CLOCKTIME_NOSYNC); - } - return 1; -} -static int done = timeRegister(); - - -// Routines for NTPTime provider - -int osdNTPGet(struct timespec *ts) -{ - return sntpcTimeGet(const_cast(pserverAddr), - NTP_REQUEST_TIMEOUT * sysClkRateGet(), ts); -} - -void osdNTPInit(void) -{ - pserverAddr = envGetConfigParamPtr(&EPICS_TS_NTP_INET); - if (!pserverAddr) { /* use the boot host */ - BOOT_PARAMS bootParms; - static char host_addr[BOOT_ADDR_LEN]; - - bootStringToStruct(sysBootLine, &bootParms); - /* bootParms.had = host IP address */ - strncpy(host_addr, bootParms.had, BOOT_ADDR_LEN); - pserverAddr = host_addr; - } -} - -void osdNTPReport(void) -{ - if (pserverAddr) - printf("NTP Server = %s\n", pserverAddr); -} - - -// Other Time Routines - -// vxWorks localtime_r returns different things in different versions. -// It can't fail though, so we just ignore the return value. -int epicsTime_localtime(const time_t *clock, struct tm *result) -{ - localtime_r(clock, result); - return epicsTimeOK; -} - -// vxWorks gmtime_r returns different things in different versions. -// It can't fail though, so we just ignore the return value. -int epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM ) -{ - gmtime_r(pAnsiTime, pTM); - return epicsTimeOK; -} diff --git a/src/libCom/osi/os/vxWorks/osdTime.h b/src/libCom/osi/os/vxWorks/osdTime.h deleted file mode 100644 index a816c7ae3..000000000 --- a/src/libCom/osi/os/vxWorks/osdTime.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* Following needed for struct timeval */ -#include - -#ifndef osdTimeh -#define osdTimeh - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void osdNTPInit(void); -int osdNTPGet(struct timespec *); -void osdNTPReport(void); - -#define osdTickRateGet sysClkRateGet -#define osdTickGet tickGet - -#ifdef __cplusplus -} -#endif -#endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/vxWorks/osdVME.h b/src/libCom/osi/os/vxWorks/osdVME.h deleted file mode 100644 index b9d031a04..000000000 --- a/src/libCom/osi/os/vxWorks/osdVME.h +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * OS-dependent VME support - */ -#include diff --git a/src/libCom/osi/os/vxWorks/osdWireConfig.h b/src/libCom/osi/os/vxWorks/osdWireConfig.h deleted file mode 100644 index 408ec6758..000000000 --- a/src/libCom/osi/os/vxWorks/osdWireConfig.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * vxWorks version of - * osdWireConfig.h - * - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osdWireConfig_h -#define osdWireConfig_h - -#include -#include - -#if _BYTE_ORDER == _LITTLE_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_LITTLE -#elif _BYTE_ORDER == _BIG_ENDIAN -# define EPICS_BYTE_ORDER EPICS_ENDIAN_BIG -#else -# error EPICS hasnt been ported to _BYTE_ORDER specified by vxWorks -#endif - -/* for now, assume that vxWorks doesnt run on weird arch like ARM NWFP */ -#define EPICS_FLOAT_WORD_ORDER EPICS_BYTE_ORDER - -#endif /* ifdef osdWireConfig_h */ diff --git a/src/libCom/osi/os/vxWorks/osiFileName.h b/src/libCom/osi/os/vxWorks/osiFileName.h deleted file mode 100644 index 3a6448d54..000000000 --- a/src/libCom/osi/os/vxWorks/osiFileName.h +++ /dev/null @@ -1,19 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * osiFileName.h - * Author: Jeff Hill - */ -#ifndef osiFileNameH -#define osiFileNameH - -#include "unixFileName.h" - -#endif /* osiFileNameH */ diff --git a/src/libCom/osi/os/vxWorks/strtoll.c b/src/libCom/osi/os/vxWorks/strtoll.c deleted file mode 100644 index 54e0a9522..000000000 --- a/src/libCom/osi/os/vxWorks/strtoll.c +++ /dev/null @@ -1,139 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. 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. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 - -#ifndef LLONG_MAX -#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL -#define LLONG_MIN (-0x7FFFFFFFFFFFFFFFLL - 1) -#endif - -/* - * Convert a string to a long long integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long long -strtoll(const char * __restrict nptr, char ** __restrict endptr, int base) -{ - const char *s; - unsigned long long acc; - char c; - unsigned long long cutoff; - int neg, any, cutlim; - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = *s++; - } while (isspace((unsigned char)c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X') && - ((s[1] >= '0' && s[1] <= '9') || - (s[1] >= 'A' && s[1] <= 'F') || - (s[1] >= 'a' && s[1] <= 'f'))) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for quads is - * [-9223372036854775808..9223372036854775807] and the input base - * is 10, cutoff will be set to 922337203685477580 and cutlim to - * either 7 (neg==0) or 8 (neg==1), meaning that if we have - * accumulated a value > 922337203685477580, or equal but the - * next digit is > 7 (or 8), the number is too big, and we will - * return a range error. - * - * Set 'any' if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX - : LLONG_MAX; - cutlim = cutoff % base; - cutoff /= base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = neg ? LLONG_MIN : LLONG_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} diff --git a/src/libCom/osi/os/vxWorks/strtoull.c b/src/libCom/osi/os/vxWorks/strtoull.c deleted file mode 100644 index 197a45bcf..000000000 --- a/src/libCom/osi/os/vxWorks/strtoull.c +++ /dev/null @@ -1,116 +0,0 @@ -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. 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. - * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 - -#ifndef ULLONG_MAX -#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL -#endif - -/* - * Convert a string to an unsigned long long integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long long -strtoull(const char * __restrict nptr, char ** __restrict endptr, int base) -{ - const char *s; - unsigned long long acc; - char c; - unsigned long long cutoff; - int neg, any, cutlim; - - /* - * See strtoq for comments as to the logic used. - */ - s = nptr; - do { - c = *s++; - } while (isspace((unsigned char)c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X') && - ((s[1] >= '0' && s[1] <= '9') || - (s[1] >= 'A' && s[1] <= 'F') || - (s[1] >= 'a' && s[1] <= 'f'))) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; - - cutoff = ULLONG_MAX / base; - cutlim = ULLONG_MAX % base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = ULLONG_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} diff --git a/src/libCom/osi/os/vxWorks/task_params.h b/src/libCom/osi/os/vxWorks/task_params.h deleted file mode 100644 index 7b2055157..000000000 --- a/src/libCom/osi/os/vxWorks/task_params.h +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Parameters for tasks on IOC */ -/* - * Authors: Andy Kozubal, Jeff Hill, and Bob Dalesio - * Date: 2-24-89 - */ - -#ifndef INCtaskLibh -#include -#endif - -#define VXTASKIDSELF 0 - -/* Task Names */ -#define EVENTSCAN_NAME "scanEvent" -#define SCANONCE_NAME "scanOnce" -#define SMCMD_NAME "smCommand" -#define SMRESP_NAME "smResponse" -#define ABDONE_NAME "abDone" -#define ABSCAN_NAME "abScan" -#define ABCOS_NAME "abBiCosScanner" -#define MOMENTARY_NAME "momentary" -#define WFDONE_NAME "wfDone" -#define SEQUENCER_NAME "sequencer" -#define BKPT_CONT_NAME "bkptCont" -#define SCANNER_NAME "scanner" -#define REQ_SRVR_NAME "CA_TCP" -#define CA_CLIENT_NAME "CA_client" -#define CA_EVENT_NAME "CA_event" -#define CAST_SRVR_NAME "CA_UDP" -#define CA_REPEATER_NAME "CA_repeater" -#define CA_ONLINE_NAME "CA_online" -#define TASKWD_NAME "taskwd" -#define SMIOTEST_NAME "smInout" -#define SMROTTEST_NAME "smRotate" -#define EVENT_PEND_NAME "event_task" -#define XY240_NAME "xy_240_scan" -#define GPIBLINK_NAME "gpibLink" -#define BBLINK_NAME "bbLinkTask" -#define BBTXLINK_NAME "bbTx" -#define BBRXLINK_NAME "bbRx" -#define BBWDTASK_NAME "bbwd" -#define ERRLOG_NAME "errlog" -#define LOG_RESTART_NAME "logRestart" - -/* Task priorities */ -#define SCANONCE_PRI 129 /* scan one time */ -/*DO NOT RUN ANY RECORD PROCESSING TASKS AT HIGHER PRIORITY THAN _netTask=50*/ -#define CALLBACK_PRI_LOW 140 /* callback task - generall callback task */ -#define CALLBACK_PRI_MEDIUM 135 /* callback task - generall callback task */ -#define CALLBACK_PRI_HIGH 128 /* callback task - generall callback task */ -#define EVENTSCAN_PRI 129 /* Event Scanner - Runs on a global event */ -#define SMCMD_PRI 120 /* Stepper Motor Command Task - Waits for cmds */ -#define SMRESP_PRI 121 /* Stepper Motor Resp Task - Waits for resps */ -#define ABCOS_PRI 121 /* Allen-Bradley Binary Input COS io_event wakeup */ -#define ABDONE_PRI 122 /* Allen-Bradley Resp Task - Interrupt Driven */ -#define ABSCAN_PRI 123 /* Allen-Bradley Scan Task - Base Rate .1 secs */ -#define BBLINK_PRI 124 -#define BBWDTASK_PRI 123 /* BitBus watchdog task */ -#define BBRXLINK_PRI 124 /* BitBus link task */ -#define BBTXLINK_PRI 125 /* BitBus link task */ -#define GPIBLINK_PRI 125 /* GPIB link task */ -#define MOMENTARY_PRI 126 /* Momentary output - posted from watchdog */ -#define WFDONE_PRI 127 /* Waveform Task - Base Rate of .1 second */ -#define PERIODSCAN_PRI 139 /* Periodic Scanners - Slowest rate */ -#define DB_CA_PRI 149 /*database to channel access*/ -#define SEQUENCER_PRI 151 -#define XY240_PRI 160 /* xy 240 dio scanner */ -#define SCANNER_PRI 170 -#define REQ_SRVR_PRI 181 /* Channel Access TCP request server*/ -#define CA_CLIENT_PRI 180 /* Channel Access clients */ -#define CA_REPEATER_PRI 181 /* Channel Access repeater */ -#define ERRLOG_PRI CA_REPEATER_PRI /*error logger task*/ -#define CAST_SRVR_PRI 182 /* Channel Access broadcast server */ -#define CA_ONLINE_PRI 183 /* Channel Access server online notify */ -#define TASKWD_PRI 200 /* Watchdog Scan Task - runs every 6 seconds */ -#define SMIOTEST_PRI 205 /* Stepper Mtr in/out test - runs every .1 sec */ -#define SMROTTEST_PRI 205 /* Stepper Mtr rotate test - runs every .1 sec */ -#define LOG_RESTART_PRI 200 /* Log server connection watch dog */ - -/* Task delay times (seconds) */ -#define TASKWD_DELAY 6 - -/* Task delay times (tics) */ -#define ABSCAN_RATE (sysClkRateGet()/6) -#define SEQUENCER_DELAY (sysClkRateGet()/5) -#define SCANNER_DELAY (sysClkRateGet()/5) -#define CA_ONLINE_DELAY (sysClkRateGet()*15) -#define LOG_RESTART_DELAY (sysClkRateGet()*30) - -/* Task creation options */ -#define ERRLOG_OPT VX_FP_TASK -#define EVENTSCAN_OPT VX_FP_TASK -#define SCANONCE_OPT VX_FP_TASK -#define CALLBACK_OPT VX_FP_TASK -#define SMCMD_OPT VX_FP_TASK -#define SMRESP_OPT VX_FP_TASK -#define ABDONE_OPT VX_FP_TASK -#define ABCOS_OPT VX_FP_TASK -#define ABSCAN_OPT VX_FP_TASK -#define MOMENTARY_OPT VX_FP_TASK -#define PERIODSCAN_OPT VX_FP_TASK -#define WFDONE_OPT VX_FP_TASK -#define SEQUENCER_OPT VX_FP_TASK | VX_STDIO -#define BKPT_CONT_OPT VX_FP_TASK -#define SCANNER_OPT VX_FP_TASK -#define REQ_SRVR_OPT VX_FP_TASK -#define CAST_SRVR_OPT VX_FP_TASK -#define CA_CLIENT_OPT VX_FP_TASK -#define CA_REPEATER_OPT VX_FP_TASK -#define CA_ONLINE_OPT VX_FP_TASK -#define TASKWD_OPT VX_FP_TASK -#define SMIOTEST_OPT VX_FP_TASK -#define SMROTTEST_OPT VX_FP_TASK -#define EVENT_PEND_OPT VX_FP_TASK -#define GPIBLINK_OPT VX_FP_TASK|VX_STDIO -#define BBLINK_OPT VX_FP_TASK|VX_STDIO -#define BBTXLINK_OPT VX_FP_TASK|VX_STDIO -#define BBRXLINK_OPT VX_FP_TASK|VX_STDIO -#define BBWDTASK_OPT VX_FP_TASK|VX_STDIO -#define DB_CA_OPT (VX_FP_TASK | VX_STDIO) -#define XY_240_OPT (0) /* none */ -#define LOG_RESTART_OPT (VX_FP_TASK) - - -/* - * Task stack sizes - * - * (original stack sizes are appropriate for the 68k) - * ARCH_STACK_FACTOR allows scaling the stacks on particular - * processor architectures - */ -#if CPU_FAMILY == MC680X0 -#define ARCH_STACK_FACTOR 1 -#elif CPU_FAMILY == SPARC -#define ARCH_STACK_FACTOR 2 -#else -#define ARCH_STACK_FACTOR 2 -#endif - -#define ERRLOG_STACK (4000*ARCH_STACK_FACTOR) -#define EVENTSCAN_STACK (11000*ARCH_STACK_FACTOR) -#define SCANONCE_STACK (11000*ARCH_STACK_FACTOR) -#define CALLBACK_STACK (11000*ARCH_STACK_FACTOR) -#define SMCMD_STACK (3000*ARCH_STACK_FACTOR) -#define SMRESP_STACK (3000*ARCH_STACK_FACTOR) -#define ABCOS_STACK (3000*ARCH_STACK_FACTOR) -#define ABDONE_STACK (3000*ARCH_STACK_FACTOR) -#define ABSCAN_STACK (3000*ARCH_STACK_FACTOR) -#define MOMENTARY_STACK (2000*ARCH_STACK_FACTOR) -#define PERIODSCAN_STACK (11000*ARCH_STACK_FACTOR) -#define WFDONE_STACK (9000*ARCH_STACK_FACTOR) -#define SEQUENCER_STACK (5500*ARCH_STACK_FACTOR) -#define BKPT_CONT_STACK (11000*ARCH_STACK_FACTOR) -#define SCANNER_STACK (3048*ARCH_STACK_FACTOR) -#define RSP_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define REQ_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define CAST_SRVR_STACK (5096*ARCH_STACK_FACTOR) -#define CA_CLIENT_STACK (11000*ARCH_STACK_FACTOR) -#define CA_REPEATER_STACK (5096*ARCH_STACK_FACTOR) -#define CA_ONLINE_STACK (3048*ARCH_STACK_FACTOR) -#define TASKWD_STACK (2000*ARCH_STACK_FACTOR) -#define SMIOTEST_STACK (2000*ARCH_STACK_FACTOR) -#define SMROTTEST_STACK (2000*ARCH_STACK_FACTOR) -#define EVENT_PEND_STACK (5096*ARCH_STACK_FACTOR) -#define TIMESTAMP_STACK (4000*ARCH_STACK_FACTOR) -#define GPIBLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBRXLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBTXLINK_STACK (5000*ARCH_STACK_FACTOR) -#define BBWDTASK_STACK (5000*ARCH_STACK_FACTOR) -#define DB_CA_STACK (11000*ARCH_STACK_FACTOR) -#define XY_240_STACK (4096*ARCH_STACK_FACTOR) -#define LOG_RESTART_STACK (0x1000*ARCH_STACK_FACTOR) - diff --git a/src/libCom/osi/os/vxWorks/veclist.c b/src/libCom/osi/os/vxWorks/veclist.c deleted file mode 100644 index 2a4e617ef..000000000 --- a/src/libCom/osi/os/vxWorks/veclist.c +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * list fuctions attached to the interrupt vector table - * - * Created 28Mar89 Jeffrey O. Hill - * johill@lanl.gov - * (505) 665 1831 - * - */ - -#include "vxWorks.h" -#include "stdio.h" -#include "string.h" -#include "intLib.h" -#include "vxLib.h" -#include "iv.h" -#include "ctype.h" -#include "sysSymTbl.h" - -/* - * - * VME bus dependent - * - */ -#define NVEC 0x100 - -static char *ignore_list[] = {"_excStub","_excIntStub"}; - -int veclist(int); -int cISRTest(FUNCPTR proutine, FUNCPTR *ppisr, void **pparam); -static void *fetch_pointer(unsigned char *); - - -/* - * - * veclist() - * - */ -int veclist(int all) -{ - int vec; - int value; - SYM_TYPE type; - char name[MAX_SYS_SYM_LEN]; - char function_type[10]; - FUNCPTR proutine; - FUNCPTR pCISR; - int cRoutine; - void *pparam; - int status; - unsigned i; - - for(vec=0; vec -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsMutex.h" -#include "epicsThread.h" -#include "errlog.h" -#include "epicsGeneralTime.h" -#include "generalTimeSup.h" -#include "iocsh.h" -#include "osiClockTime.h" -#include "taskwd.h" - -#define NSEC_PER_SEC 1000000000 -#define ClockTimeSyncInterval_value 60.0 - - -static struct { - int synchronize; - int synchronized; - epicsEventId loopEvent; - epicsTimeStamp startTime; - epicsTimeStamp syncTime; - double ClockTimeSyncInterval; - int syncFromPriority; - epicsMutexId lock; -} ClockTimePvt; - -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - - -#if defined(CLOCK_REALTIME) && !defined(_WIN32) -/* This code is not used on systems without Posix CLOCK_REALTIME such - * as Darwin, but the only way to detect that is from the OS headers, - * so the Makefile can't exclude building this file on those systems. - */ - -/* Forward references */ - -static int ClockTimeGetCurrent(epicsTimeStamp *pDest); -static void ClockTimeSync(void *dummy); - - -/* ClockTime_Report iocsh command */ -static const iocshArg ReportArg0 = { "interest_level", iocshArgArgv}; -static const iocshArg * const ReportArgs[1] = { &ReportArg0 }; -static const iocshFuncDef ReportFuncDef = {"ClockTime_Report", 1, ReportArgs}; -static void ReportCallFunc(const iocshArgBuf *args) -{ - ClockTime_Report(args[0].ival); -} - -/* ClockTime_Shutdown iocsh command */ -static const iocshFuncDef ShutdownFuncDef = {"ClockTime_Shutdown", 0, NULL}; -static void ShutdownCallFunc(const iocshArgBuf *args) -{ - ClockTime_Shutdown(NULL); -} - - -/* Initialization */ - -static void ClockTime_InitOnce(void *pfirst) -{ - *(int *) pfirst = 1; - - ClockTimePvt.loopEvent = epicsEventMustCreate(epicsEventEmpty); - ClockTimePvt.lock = epicsMutexCreate(); - ClockTimePvt.ClockTimeSyncInterval = 1.0; /* First sync */ - - epicsAtExit(ClockTime_Shutdown, NULL); - - /* Register the iocsh commands */ - iocshRegister(&ReportFuncDef, ReportCallFunc); - iocshRegister(&ShutdownFuncDef, ShutdownCallFunc); - - /* Register as a time provider */ - generalTimeRegisterCurrentProvider("OS Clock", LAST_RESORT_PRIORITY, - ClockTimeGetCurrent); -} - -void ClockTime_Init(int synchronize) -{ - int firstTime = 0; - - epicsThreadOnce(&onceId, ClockTime_InitOnce, &firstTime); - - if (synchronize == CLOCKTIME_SYNC) { - if (ClockTimePvt.synchronize == CLOCKTIME_NOSYNC) { - /* Start synchronizing */ - ClockTimePvt.synchronize = synchronize; - - epicsThreadCreate("ClockTimeSync", epicsThreadPriorityHigh, - epicsThreadGetStackSize(epicsThreadStackSmall), - ClockTimeSync, NULL); - } - else { - /* No change, sync thread should already be running */ - } - } - else { - if (ClockTimePvt.synchronize == CLOCKTIME_SYNC) { - /* Turn off synchronization thread */ - ClockTime_Shutdown(NULL); - } - else { - /* No synchronization thread */ - if (firstTime) - ClockTimeGetCurrent(&ClockTimePvt.startTime); - } - } -} - - -/* Shutdown */ - -void ClockTime_Shutdown(void *dummy) -{ - ClockTimePvt.synchronize = CLOCKTIME_NOSYNC; - epicsEventSignal(ClockTimePvt.loopEvent); -} - -void ClockTime_GetProgramStart(epicsTimeStamp *pDest) -{ - *pDest = ClockTimePvt.startTime; -} - - -/* Synchronization thread */ - -static void ClockTimeSync(void *dummy) -{ - taskwdInsert(0, NULL, NULL); - - for (epicsEventWaitWithTimeout(ClockTimePvt.loopEvent, - ClockTimePvt.ClockTimeSyncInterval); - ClockTimePvt.synchronize == CLOCKTIME_SYNC; - epicsEventWaitWithTimeout(ClockTimePvt.loopEvent, - ClockTimePvt.ClockTimeSyncInterval)) { - epicsTimeStamp timeNow; - int priority; - - if (generalTimeGetExceptPriority(&timeNow, &priority, - LAST_RESORT_PRIORITY) == epicsTimeOK) { - struct timespec clockNow; - - epicsTimeToTimespec(&clockNow, &timeNow); - if (clock_settime(CLOCK_REALTIME, &clockNow)) { - errlogPrintf("ClockTimeSync: clock_settime failed\n"); - continue; - } - - epicsMutexMustLock(ClockTimePvt.lock); - if (!ClockTimePvt.synchronized) { - ClockTimePvt.startTime = timeNow; - ClockTimePvt.synchronized = 1; - } - ClockTimePvt.syncFromPriority = priority; - ClockTimePvt.syncTime = timeNow; - epicsMutexUnlock(ClockTimePvt.lock); - - ClockTimePvt.ClockTimeSyncInterval = ClockTimeSyncInterval_value; - } - } - - ClockTimePvt.synchronized = 0; - taskwdRemove(0); -} - - -/* Time Provider Routine */ - -static int ClockTimeGetCurrent(epicsTimeStamp *pDest) -{ - struct timespec clockNow; - - /* If a Hi-Res clock is available and works, use it */ - #ifdef CLOCK_REALTIME_HR - clock_gettime(CLOCK_REALTIME_HR, &clockNow) && - #endif - clock_gettime(CLOCK_REALTIME, &clockNow); - - if (!ClockTimePvt.synchronized && - clockNow.tv_sec < POSIX_TIME_AT_EPICS_EPOCH) { - clockNow.tv_sec = POSIX_TIME_AT_EPICS_EPOCH + 86400; - clockNow.tv_nsec = 0; - clock_settime(CLOCK_REALTIME, &clockNow); - errlogPrintf("WARNING: OS Clock time was read before being set.\n" - "Using 1990-01-02 00:00:00.000000 UTC\n"); - } - - epicsTimeFromTimespec(pDest, &clockNow); - return 0; -} - -#endif /* CLOCK_REALTIME */ - -/* Allow the following report routine to be compiled anyway - * to avoid getting a build warning from ranlib. - */ - -/* Status Report */ - -int ClockTime_Report(int level) -{ - char timebuf[32]; - - if (onceId == EPICS_THREAD_ONCE_INIT) { - printf("OS Clock driver not %s.\n", -#ifdef CLOCK_REALTIME - "initialized" -#else - "available" -#endif /* CLOCK_REALTIME */ - ); - } - else if (ClockTimePvt.synchronize == CLOCKTIME_SYNC) { - int synchronized, syncFromPriority; - epicsTimeStamp startTime, syncTime; - - epicsMutexMustLock(ClockTimePvt.lock); - synchronized = ClockTimePvt.synchronized; - syncFromPriority = ClockTimePvt.syncFromPriority; - startTime = ClockTimePvt.startTime; - syncTime = ClockTimePvt.syncTime; - epicsMutexUnlock(ClockTimePvt.lock); - - if (synchronized) { - printf("OS Clock driver is synchronized to a priority=%d provider\n", - syncFromPriority); - if (level) { - epicsTimeToStrftime(timebuf, sizeof(timebuf), - "%Y-%m-%d %H:%M:%S.%06f", &startTime); - printf("Initial sync was at %s\n", timebuf); - epicsTimeToStrftime(timebuf, sizeof(timebuf), - "%Y-%m-%d %H:%M:%S.%06f", &syncTime); - printf("Last successful sync was at %s\n", timebuf); - } - printf("Syncronization interval = %.0f seconds\n", - ClockTimePvt.ClockTimeSyncInterval); - } - else - printf("OS Clock driver is *not* synchronized\n"); - } - else { - epicsTimeToStrftime(timebuf, sizeof(timebuf), - "%Y-%m-%d %H:%M:%S.%06f", &ClockTimePvt.startTime); - printf("Program started at %s\n", timebuf); - printf("OS Clock synchronization thread not running.\n"); - } - return 0; -} diff --git a/src/libCom/osi/osiClockTime.h b/src/libCom/osi/osiClockTime.h deleted file mode 100644 index 17eacab3e..000000000 --- a/src/libCom/osi/osiClockTime.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osiClockTime_H -#define INC_osiClockTime_H - -#define CLOCKTIME_NOSYNC 0 -#define CLOCKTIME_SYNC 1 - -#ifdef __cplusplus -extern "C" { -#endif - -void ClockTime_Init(int synchronize); -void ClockTime_Shutdown(void *dummy); -int ClockTime_Report(int level); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/osiNTPTime.c b/src/libCom/osi/osiNTPTime.c deleted file mode 100644 index d22df861b..000000000 --- a/src/libCom/osi/osiNTPTime.c +++ /dev/null @@ -1,284 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Original Author: Marty Kraimer - * Date: 16JUN2000 - */ - -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsTypes.h" -#include "cantProceed.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "epicsGeneralTime.h" -#include "generalTimeSup.h" -#include "iocsh.h" -#include "osdTime.h" -#include "osiNTPTime.h" -#include "taskwd.h" - -#define NSEC_PER_SEC 1000000000 -#define NTPTimeSyncInterval 60.0 -#define NTPTimeSyncRetries 4 - - -static struct { - int synchronize; - int synchronized; - epicsEventId loopEvent; - int syncsFailed; - epicsMutexId lock; - epicsTimeStamp syncTime; - epicsUInt32 syncTick; - epicsTimeStamp clockTime; - epicsUInt32 clockTick; - epicsUInt32 ticksToSkip; - double tickRate; -} NTPTimePvt; - -static epicsThreadOnceId onceId = EPICS_THREAD_ONCE_INIT; - - -/* Forward references */ - -static int NTPTimeGetCurrent(epicsTimeStamp *pDest); -static void NTPTimeSync(void *dummy); - - -/* NTPTime_Report iocsh command */ -static const iocshArg ReportArg0 = { "interest_level", iocshArgArgv}; -static const iocshArg * const ReportArgs[1] = { &ReportArg0 }; -static const iocshFuncDef ReportFuncDef = {"NTPTime_Report", 1, ReportArgs}; -static void ReportCallFunc(const iocshArgBuf *args) -{ - NTPTime_Report(args[0].ival); -} - -/* NTPTime_Shutdown iocsh command */ -static const iocshFuncDef ShutdownFuncDef = {"NTPTime_Shutdown", 0, NULL}; -static void ShutdownCallFunc(const iocshArgBuf *args) -{ - NTPTime_Shutdown(NULL); -} - - -/* Initialization */ - -static void NTPTime_InitOnce(void *pprio) -{ - struct timespec timespecNow; - - NTPTimePvt.synchronize = 1; - NTPTimePvt.synchronized = 0; - NTPTimePvt.loopEvent = epicsEventMustCreate(epicsEventEmpty); - NTPTimePvt.syncsFailed = 0; - NTPTimePvt.lock = epicsMutexCreate(); - - /* Initialize OS-dependent code */ - osdNTPInit(); - - /* Try to sync with NTP server */ - if (!osdNTPGet(×pecNow)) { - NTPTimePvt.syncTick = osdTickGet(); - if (timespecNow.tv_sec > POSIX_TIME_AT_EPICS_EPOCH && epicsTimeOK == - epicsTimeFromTimespec(&NTPTimePvt.syncTime, ×pecNow)) { - NTPTimePvt.clockTick = NTPTimePvt.syncTick; - NTPTimePvt.clockTime = NTPTimePvt.syncTime; - NTPTimePvt.synchronized = 1; - } - } - - /* Start the sync thread */ - epicsThreadCreate("NTPTimeSync", epicsThreadPriorityHigh, - epicsThreadGetStackSize(epicsThreadStackSmall), - NTPTimeSync, NULL); - - epicsAtExit(NTPTime_Shutdown, NULL); - - /* Register the iocsh commands */ - iocshRegister(&ReportFuncDef, ReportCallFunc); - iocshRegister(&ShutdownFuncDef, ShutdownCallFunc); - - /* Finally register as a time provider */ - generalTimeRegisterCurrentProvider("NTP", *(int *)pprio, NTPTimeGetCurrent); -} - -void NTPTime_Init(int priority) -{ - epicsThreadOnce(&onceId, NTPTime_InitOnce, &priority); -} - - -/* Shutdown */ - -void NTPTime_Shutdown(void *dummy) -{ - NTPTimePvt.synchronize = 0; - epicsEventSignal(NTPTimePvt.loopEvent); -} - - -/* Synchronization thread */ - -static void NTPTimeSync(void *dummy) -{ - taskwdInsert(0, NULL, NULL); - - for (epicsEventWaitWithTimeout(NTPTimePvt.loopEvent, NTPTimeSyncInterval); - NTPTimePvt.synchronize; - epicsEventWaitWithTimeout(NTPTimePvt.loopEvent, NTPTimeSyncInterval)) { - int status; - struct timespec timespecNow; - epicsTimeStamp timeNow; - epicsUInt32 tickNow; - double diff; - double ntpDelta; - - status = osdNTPGet(×pecNow); - tickNow = osdTickGet(); - - if (status) { - if (++NTPTimePvt.syncsFailed > NTPTimeSyncRetries && - NTPTimePvt.synchronized) { - errlogPrintf("NTPTimeSync: NTP requests failing - %s\n", - strerror(errno)); - NTPTimePvt.synchronized = 0; - } - continue; - } - - if (timespecNow.tv_sec <= POSIX_TIME_AT_EPICS_EPOCH || - epicsTimeFromTimespec(&timeNow, ×pecNow) != epicsTimeOK) { - errlogPrintf("NTPTimeSync: Bad time received from NTP server\n"); - NTPTimePvt.synchronized = 0; - continue; - } - - ntpDelta = epicsTimeDiffInSeconds(&timeNow, &NTPTimePvt.syncTime); - if (ntpDelta <= 0.0 && NTPTimePvt.synchronized) { - errlogPrintf("NTPTimeSync: NTP time not increasing, delta = %g\n", - ntpDelta); - NTPTimePvt.synchronized = 0; - continue; - } - - NTPTimePvt.syncsFailed = 0; - if (!NTPTimePvt.synchronized) { - errlogPrintf("NTPTimeSync: Sync recovered.\n"); - } - - epicsMutexMustLock(NTPTimePvt.lock); - diff = epicsTimeDiffInSeconds(&timeNow, &NTPTimePvt.clockTime); - if (diff >= 0.0) { - NTPTimePvt.ticksToSkip = 0; - } else { /* dont go back in time */ - NTPTimePvt.ticksToSkip = -diff * osdTickRateGet(); - } - NTPTimePvt.clockTick = tickNow; - NTPTimePvt.clockTime = timeNow; - NTPTimePvt.synchronized = 1; - epicsMutexUnlock(NTPTimePvt.lock); - - NTPTimePvt.tickRate = (tickNow - NTPTimePvt.syncTick) / ntpDelta; - NTPTimePvt.syncTick = tickNow; - NTPTimePvt.syncTime = timeNow; - } - - NTPTimePvt.synchronized = 0; - taskwdRemove(0); -} - - -/* Time Provider Routine */ - -static int NTPTimeGetCurrent(epicsTimeStamp *pDest) -{ - epicsUInt32 tickNow; - epicsUInt32 ticksSince; - - if (!NTPTimePvt.synchronized) - return S_time_unsynchronized; - - epicsMutexMustLock(NTPTimePvt.lock); - - tickNow = osdTickGet(); - ticksSince = tickNow - NTPTimePvt.clockTick; - - if (NTPTimePvt.ticksToSkip <= ticksSince) { - if (NTPTimePvt.ticksToSkip) { - ticksSince -= NTPTimePvt.ticksToSkip; - NTPTimePvt.ticksToSkip = 0; - } - - if (ticksSince) { - epicsUInt32 ticksPerSecond = osdTickRateGet(); - epicsUInt32 nsecsPerTick = NSEC_PER_SEC / ticksPerSecond; - epicsUInt32 secsSince = ticksSince / ticksPerSecond; - - ticksSince -= secsSince * ticksPerSecond; - NTPTimePvt.clockTime.nsec += ticksSince * nsecsPerTick; - if (NTPTimePvt.clockTime.nsec >= NSEC_PER_SEC) { - secsSince++; - NTPTimePvt.clockTime.nsec -= NSEC_PER_SEC; - } - NTPTimePvt.clockTime.secPastEpoch += secsSince; - NTPTimePvt.clockTick = tickNow; - } - } - - *pDest = NTPTimePvt.clockTime; - - epicsMutexUnlock(NTPTimePvt.lock); - return 0; -} - - -/* Status Report */ - -int NTPTime_Report(int level) -{ - if (onceId == EPICS_THREAD_ONCE_INIT) { - printf("NTP driver not initialized\n"); - } else if (NTPTimePvt.synchronize) { - printf("NTP driver %s synchronized with server\n", - NTPTimePvt.synchronized ? "is" : "is *not*"); - if (NTPTimePvt.syncsFailed) { - printf("Last successful sync was %.1f minutes ago\n", - NTPTimePvt.syncsFailed * NTPTimeSyncInterval / 60.0); - } - if (level) { - char lastSync[32]; - - epicsTimeToStrftime(lastSync, sizeof(lastSync), - "%Y-%m-%d %H:%M:%S.%06f", &NTPTimePvt.syncTime); - printf("Syncronization interval = %.1f seconds\n", - NTPTimeSyncInterval); - printf("Last synchronized at %s\n", - lastSync); - printf("Current OS tick rate = %u Hz\n", - osdTickRateGet()); - printf("Measured tick rate = %.3f Hz\n", - NTPTimePvt.tickRate); - osdNTPReport(); - } - } else { - printf("NTP synchronization thread not running.\n"); - } - return 0; -} diff --git a/src/libCom/osi/osiNTPTime.h b/src/libCom/osi/osiNTPTime.h deleted file mode 100644 index 21b29d118..000000000 --- a/src/libCom/osi/osiNTPTime.h +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osiNTPTime_H -#define INC_osiNTPTime_H - -#ifdef __cplusplus -extern "C" { -#endif - -void NTPTime_Init(int priority); -void NTPTime_Shutdown(void *dummy); -int NTPTime_Report(int level); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/osi/osiPoolStatus.h b/src/libCom/osi/osiPoolStatus.h deleted file mode 100644 index b0207f185..000000000 --- a/src/libCom/osi/osiPoolStatus.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osiPoolStatus_H -#define INC_osiPoolStatus_H - -/* - * Author: Jeff Hill - * - * Functions which interrogate the state of the system wide pool - * - */ - -#include -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * tests to see if there is sufficent space for a block of the requested size - * along with whatever additional free space is necessary to keep the system running - * reliably - * - * this routine is called quite frequently so an efficent implementation is important - */ -epicsShareFunc int epicsShareAPI osiSufficentSpaceInPool ( size_t contiguousBlockSize ); - -#ifdef __cplusplus -} -#endif - -#include "osdPoolStatus.h" - -#endif /* INC_osiPoolStatus_H */ diff --git a/src/libCom/osi/osiProcess.h b/src/libCom/osi/osiProcess.h deleted file mode 100644 index eabff1e72..000000000 --- a/src/libCom/osi/osiProcess.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef INC_osiProcess_H -#define INC_osiProcess_H - -/* - * Operating System Independent Interface to Process Environment - * - * Author: Jeff Hill - * - */ -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum osiGetUserNameReturn { - osiGetUserNameFail, - osiGetUserNameSuccess} osiGetUserNameReturn; -epicsShareFunc osiGetUserNameReturn epicsShareAPI osiGetUserName (char *pBuf, unsigned bufSize); - -/* - * Spawn detached process with named executable, but return - * osiSpawnDetachedProcessNoSupport if the local OS does not - * support heavy weight processes. - */ -typedef enum osiSpawnDetachedProcessReturn { - osiSpawnDetachedProcessFail, - osiSpawnDetachedProcessSuccess, - osiSpawnDetachedProcessNoSupport} osiSpawnDetachedProcessReturn; - -epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProcess - (const char *pProcessName, const char *pBaseExecutableName); - -#ifdef __cplusplus -} -#endif - -#endif /* INC_osiProcess_H */ diff --git a/src/libCom/osi/osiSock.c b/src/libCom/osi/osiSock.c deleted file mode 100644 index 8b4634caf..000000000 --- a/src/libCom/osi/osiSock.c +++ /dev/null @@ -1,189 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * socket support library generic code - * - * 7-1-97 -joh- - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsAssert.h" -#include "epicsSignal.h" -#include "epicsStdio.h" -#include "osiSock.h" - -#define nDigitsDottedIP 4u -#define chunkSize 8u - -#define makeMask(NBITS) ( ( 1u << ( (unsigned) NBITS) ) - 1u ) - -/* - * sockAddrAreIdentical() - * (returns true if addresses are identical) - */ -int epicsShareAPI sockAddrAreIdentical - ( const osiSockAddr *plhs, const osiSockAddr *prhs ) -{ - int match; - - if ( plhs->sa.sa_family != prhs->sa.sa_family ) { - match = 0; - } - else if ( plhs->sa.sa_family != AF_INET ) { - match = 0; - } - else if ( plhs->ia.sin_addr.s_addr != prhs->ia.sin_addr.s_addr ) { - match = 0; - } - else if ( plhs->ia.sin_port != prhs->ia.sin_port ) { - match = 0; - } - else { - match = 1; - } - return match; -} - -/* - * sockAddrToA() - * (convert socket address to ASCII host name) - */ -unsigned epicsShareAPI sockAddrToA ( - const struct sockaddr * paddr, char * pBuf, unsigned bufSize ) -{ - if ( bufSize < 1 ) { - return 0; - } - - if ( paddr->sa_family != AF_INET ) { - static const char * pErrStr = ""; - unsigned len = strlen ( pErrStr ); - if ( len < bufSize ) { - strcpy ( pBuf, pErrStr ); - return len; - } - else { - strncpy ( pBuf, "", bufSize-1 ); - pBuf[bufSize-1] = '\0'; - return bufSize-1; - } - } - else { - const struct sockaddr_in * paddr_in = - (const struct sockaddr_in *) paddr; - return ipAddrToA ( paddr_in, pBuf, bufSize ); - } -} - -/* - * ipAddrToA() - * (convert IP address to ASCII host name) - */ -unsigned epicsShareAPI ipAddrToA ( - const struct sockaddr_in * paddr, char * pBuf, unsigned bufSize ) -{ - unsigned len = ipAddrToHostName ( - & paddr->sin_addr, pBuf, bufSize ); - if ( len == 0 ) { - len = ipAddrToDottedIP ( paddr, pBuf, bufSize ); - } - else { - unsigned reducedSize = bufSize - len; - int status = epicsSnprintf ( - &pBuf[len], reducedSize, ":%hu", - ntohs (paddr->sin_port) ); - if ( status > 0 ) { - unsigned portSize = (unsigned) status; - if ( portSize < reducedSize ) { - len += portSize; - } - } - } - return len; -} - -/* - * sockAddrToDottedIP () - */ -unsigned epicsShareAPI sockAddrToDottedIP ( - const struct sockaddr * paddr, char * pBuf, unsigned bufSize ) -{ - if ( paddr->sa_family != AF_INET ) { - const char * pErrStr = ""; - unsigned errStrLen = strlen ( pErrStr ); - if ( errStrLen < bufSize ) { - strcpy ( pBuf, pErrStr ); - return errStrLen; - } - else { - unsigned reducedSize = bufSize - 1u; - strncpy ( pBuf, pErrStr, reducedSize ); - pBuf[reducedSize] = '\0'; - return reducedSize; - } - } - else { - const struct sockaddr_in *paddr_in = ( const struct sockaddr_in * ) paddr; - return ipAddrToDottedIP ( paddr_in, pBuf, bufSize ); - } -} - -/* - * ipAddrToDottedIP () - */ -unsigned epicsShareAPI ipAddrToDottedIP ( - const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize ) -{ - static const char * pErrStr = ""; - unsigned chunk[nDigitsDottedIP]; - unsigned addr = ntohl ( paddr->sin_addr.s_addr ); - unsigned strLen; - unsigned i; - int status; - - if ( bufSize == 0u ) { - return 0u; - } - - for ( i = 0; i < nDigitsDottedIP; i++ ) { - chunk[i] = addr & makeMask ( chunkSize ); - addr >>= chunkSize; - } - - /* - * inet_ntoa() isnt used because it isnt thread safe - * (and the replacements are not standardized) - */ - status = epicsSnprintf ( - pBuf, bufSize, "%u.%u.%u.%u:%hu", - chunk[3], chunk[2], chunk[1], chunk[0], - ntohs ( paddr->sin_port ) ); - if ( status > 0 ) { - strLen = ( unsigned ) status; - if ( strLen < bufSize - 1 ) { - return strLen; - } - } - strLen = strlen ( pErrStr ); - if ( strLen < bufSize ) { - strcpy ( pBuf, pErrStr ); - return strLen; - } - else { - strncpy ( pBuf, pErrStr, bufSize ); - pBuf[bufSize-1] = '\0'; - return bufSize - 1u; - } -} - diff --git a/src/libCom/osi/osiSock.h b/src/libCom/osi/osiSock.h deleted file mode 100644 index 061619e89..000000000 --- a/src/libCom/osi/osiSock.h +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * socket support library API def - * - * 7-1-97 -joh- - */ -#ifndef osiSockh -#define osiSockh - -#include "shareLib.h" -#include "osdSock.h" -#include "ellLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct sockaddr; -struct sockaddr_in; -struct in_addr; - -epicsShareFunc SOCKET epicsShareAPI epicsSocketCreate ( - int domain, int type, int protocol ); -epicsShareFunc int epicsShareAPI epicsSocketAccept ( - int sock, struct sockaddr * pAddr, osiSocklen_t * addrlen ); -epicsShareFunc void epicsShareAPI epicsSocketDestroy ( - SOCKET ); -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressReuseDuringTimeWaitState ( SOCKET s ); -epicsShareFunc void epicsShareAPI - epicsSocketEnableAddressUseForDatagramFanout ( SOCKET s ); - -/* - * Fortunately, on most systems the combination of a shutdown of both - * directions and or a signal is sufficent to interrupt a blocking send, - * receive, or connect call. For odd ball systems this is stubbed out in the - * osi area. - */ -enum epicsSocketSystemCallInterruptMechanismQueryInfo { - esscimqi_socketCloseRequired, - esscimqi_socketBothShutdownRequired, - esscimqi_socketSigAlarmRequired /* NO LONGER USED/SUPPORTED */ -}; -epicsShareFunc enum epicsSocketSystemCallInterruptMechanismQueryInfo - epicsSocketSystemCallInterruptMechanismQuery (); - - -/* - * convert socket address to ASCII in this order - * 1) look for matching host name and typically add trailing IP port - * 2) failing that, convert to raw ascii address (typically this is a - * dotted IP address with trailing port) - * 3) failing that, writes "" into pBuf - * - * returns the number of character elements stored in buffer not - * including the null termination, but always writes at least a - * null ternminater in the string (if bufSize >= 1) - */ -epicsShareFunc unsigned epicsShareAPI sockAddrToA ( - const struct sockaddr * paddr, char * pBuf, unsigned bufSize ); - -/* - * convert IP address to ASCII in this order - * 1) look for matching host name and add trailing port - * 2) convert to raw dotted IP address with trailing port - * - * returns the number of character elements stored in buffer not - * including the null termination, but always writes at least a - * null ternminater in the string (if bufSize >= 1) - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToA ( - const struct sockaddr_in * pInetAddr, char * pBuf, unsigned bufSize ); - -/* - * sockAddrToDottedIP () - * typically convert to raw dotted IP address with trailing port - * - * returns the number of character elements stored in buffer not - * including the null termination, but always writes at least a - * null ternminater in the string (if bufSize >= 1) - */ -epicsShareFunc unsigned epicsShareAPI sockAddrToDottedIP ( - const struct sockaddr * paddr, char * pBuf, unsigned bufSize ); - -/* - * ipAddrToDottedIP () - * convert to raw dotted IP address with trailing port - * - * returns the number of character elements stored in buffer not - * including the null termination, but always writes at least a - * null ternminater in the string (if bufSize >= 1) - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToDottedIP ( - const struct sockaddr_in * paddr, char * pBuf, unsigned bufSize ); - -/* - * convert inet address to a host name string - * - * returns the number of character elements stored in buffer not - * including the null termination. This will be zero if a matching - * host name cant be found. - * - * there are many OS specific implementation stubs for this routine - */ -epicsShareFunc unsigned epicsShareAPI ipAddrToHostName ( - const struct in_addr * pAddr, char * pBuf, unsigned bufSize ); - -/* - * attempt to convert ASCII string to an IP address in this order - * 1) look for traditional doted ip with optional port - * 2) look for raw number form of ip address with optional port - * 3) look for valid host name with optional port - */ -epicsShareFunc int epicsShareAPI aToIPAddr - ( const char * pAddrString, unsigned short defaultPort, struct sockaddr_in * pIP); - -/* - * attempt to convert ASCII host name string with optional port to an IP address - */ -epicsShareFunc int epicsShareAPI hostToIPAddr - (const char *pHostName, struct in_addr *pIPA); -/* - * attach to BSD socket library - */ -epicsShareFunc int epicsShareAPI osiSockAttach (void); /* returns T if success, else F */ - -/* - * release BSD socket library - */ -epicsShareFunc void epicsShareAPI osiSockRelease (void); - -/* - * convert socket error numbers to a string - */ -epicsShareFunc void epicsSocketConvertErrorToString ( - char * pBuf, unsigned bufSize, int error ); -epicsShareFunc void epicsSocketConvertErrnoToString ( - char * pBuf, unsigned bufSize ); - -typedef union osiSockAddr { - struct sockaddr_in ia; - struct sockaddr sa; -} osiSockAddr; - -typedef struct osiSockAddrNode { - ELLNODE node; - osiSockAddr addr; -} osiSockAddrNode; - -/* - * sockAddrAreIdentical() - * (returns true if addresses are identical) - */ -epicsShareFunc int epicsShareAPI sockAddrAreIdentical - ( const osiSockAddr * plhs, const osiSockAddr * prhs ); - -/* - * osiSockDiscoverBroadcastAddresses () - * Returns the broadcast addresses of each network interface found. - * - * This routine is provided with the address of an ELLLIST, a socket, - * a destination port number, and a match address. When the - * routine returns there will be one additional entry - * (an osiSockAddrNode) in the list for each network interface found that - * is up and isnt a loop back interface (match addr is INADDR_ANY), - * or only the interfaces that match the specified addresses (match addr - * is other than INADDR_ANY). If the interface supports broadcasting - * then add its broadcast address to the list. If the interface is a - * point to point link then add the destination address of the point to - * point link to the list. - * - * Any mutex locking required to protect pList is applied externally. - * - */ -epicsShareFunc void epicsShareAPI osiSockDiscoverBroadcastAddresses - (ELLLIST *pList, SOCKET socket, const osiSockAddr *pMatchAddr); - -/* - * osiLocalAddr () - * Returns the osiSockAddr of the first non-loopback interface found - * that is operational (up flag is set). If no valid address can be - * located then return an osiSockAddr with the address family set to - * unspecified (AF_UNSPEC). - * - * Unfortunately in EPICS 3.13 beta 11 and before the CA - * repeater would not always allow the loopback address - * as a local client address so current clients alternate - * between the address of the first non-loopback interface - * found and the loopback addresss when subscribing with - * the CA repeater until all CA repeaters have been updated - * to current code. After all CA repeaters have been restarted - * this osi interface can be eliminated. - */ -epicsShareFunc osiSockAddr epicsShareAPI osiLocalAddr (SOCKET socket); - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef osiSockh */ diff --git a/src/libCom/osi/osiWireFormat.h b/src/libCom/osi/osiWireFormat.h deleted file mode 100644 index 4d7e6717f..000000000 --- a/src/libCom/osi/osiWireFormat.h +++ /dev/null @@ -1,257 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - */ - -#ifndef osiWireFormat -#define osiWireFormat - -#include "epicsTypes.h" - -// -// With future CA protocols user defined payload composition will be -// supported and we will need to move away from a naturally aligned -// protocol (because pad byte overhead will probably be excessive when -// maintaining 8 byte natural alignment if the user isnt thinking about -// placing like sized elements together). -// -// Nevertheless, the R3.14 protocol continues to be naturally aligned, -// and all of the fields within the DBR_XXXX types are naturally aligned. -// Therefore we support here two wire transfer interfaces (naturally -// aligned and otherwise) because there are important optimizations -// specific to each of them. -// -// At some point in the future the naturally aligned interfaces might -// be eliminated (or unbundled from base) should they be no-longer needed. -// - -template < class T > -void WireGet ( const epicsUInt8 * pWireSrc, T & ); - -template < class T > -void WireSet ( const T &, epicsUInt8 * pWireDst ); - -template < class T > -void AlignedWireGet ( const T &, T & ); - -template < class T > -void AlignedWireSet ( const T &, T & ); - -template < class T > -class AlignedWireRef { -public: - AlignedWireRef ( T & ref ); - operator T () const; - AlignedWireRef < T > & operator = ( const T & ); -private: - T & _ref; - AlignedWireRef ( const AlignedWireRef & ); - AlignedWireRef & operator = ( const AlignedWireRef & ); -}; - -template < class T > -class AlignedWireRef < const T > { -public: - AlignedWireRef ( const T & ref ); - operator T () const; -private: - const T & _ref; - AlignedWireRef ( const AlignedWireRef & ); - AlignedWireRef & operator = ( const AlignedWireRef & ); -}; - -template < class T > -inline AlignedWireRef < T > :: AlignedWireRef ( T & ref ) : - _ref ( ref ) -{ -} - -template < class T > -inline AlignedWireRef < T > :: operator T () const -{ - T tmp; - AlignedWireGet ( _ref, tmp ); - return tmp; -} - -template < class T > -inline AlignedWireRef < T > & AlignedWireRef < T > :: operator = ( const T & src ) -{ - AlignedWireSet ( src, _ref ); - return *this; -} - -template < class T > -inline AlignedWireRef < const T > :: AlignedWireRef ( const T & ref ) : - _ref ( ref ) -{ -} - -template < class T > -inline AlignedWireRef < const T > :: operator T () const -{ - T tmp; - AlignedWireGet ( _ref, tmp ); - return tmp; -} - -// may be useful when creating support for little endian -inline epicsUInt16 byteSwap ( const epicsUInt16 & src ) -{ - return static_cast < epicsUInt16 > - ( ( src << 8u ) | ( src >> 8u ) ); -} - -// may be useful when creating support for little endian -inline epicsUInt32 byteSwap ( const epicsUInt32 & src ) -{ - epicsUInt32 tmp0 = byteSwap ( - static_cast < epicsUInt16 > ( src >> 16u ) ); - epicsUInt32 tmp1 = byteSwap ( - static_cast < epicsUInt16 > ( src ) ); - return static_cast < epicsUInt32 > - ( ( tmp1 << 16u ) | tmp0 ); -} - -template < class T > union WireAlias; - -template <> -union WireAlias < epicsInt8 > { - epicsUInt8 _u; - epicsInt8 _o; -}; - -template <> -union WireAlias < epicsInt16 > { - epicsUInt16 _u; - epicsInt16 _o; -}; - -template <> -union WireAlias < epicsInt32 > { - epicsUInt32 _u; - epicsInt32 _o; -}; - -template <> -union WireAlias < epicsFloat32 > { - epicsUInt32 _u; - epicsFloat32 _o; -}; - -// -// Missaligned unsigned wire format get/set can be implemented generically -// w/o performance penalty. Attempts to improve this on architectures that -// dont have alignement requirements will probably get into trouble with -// over-aggressive optimization under strict aliasing rules. -// - -template < class T > -inline void WireGet ( const epicsUInt8 * pWireSrc, T & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - WireAlias < T > tmp; - WireGet ( pWireSrc, tmp._u ); - dst = tmp._o; -} - -template <> -inline void WireGet < epicsUInt8 > ( - const epicsUInt8 * pWireSrc, epicsUInt8 & dst ) -{ - dst = pWireSrc[0]; -} - -template <> -inline void WireGet < epicsUInt16 > ( - const epicsUInt8 * pWireSrc, epicsUInt16 & dst ) -{ - dst = static_cast < epicsUInt16 > ( - ( pWireSrc[0] << 8u ) | pWireSrc[1] ); -} - -template <> -inline void WireGet < epicsUInt32 > ( - const epicsUInt8 * pWireSrc, epicsUInt32 & dst ) -{ - dst = static_cast < epicsUInt32 > ( - ( pWireSrc[0] << 24u ) | - ( pWireSrc[1] << 16u ) | - ( pWireSrc[2] << 8u ) | - pWireSrc[3] ); -} - -template < class T > -inline void WireSet ( const T & src, epicsUInt8 * pWireDst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - WireAlias < T > tmp; - tmp._o = src; - WireSet ( tmp._u, pWireDst ); -} - -template <> -inline void WireSet < epicsUInt8 > ( - const epicsUInt8 & src, epicsUInt8 * pWireDst ) -{ - pWireDst[0] = src; -} - -template <> -inline void WireSet < epicsUInt16 > ( - const epicsUInt16 & src, epicsUInt8 * pWireDst ) -{ - pWireDst[0] = static_cast < epicsUInt8 > ( src >> 8u ); - pWireDst[1] = static_cast < epicsUInt8 > ( src ); -} - -template <> -inline void WireSet < epicsUInt32 > ( - const epicsUInt32 & src, epicsUInt8 * pWireDst ) -{ - pWireDst[0] = static_cast < epicsUInt8 > ( src >> 24u ); - pWireDst[1] = static_cast < epicsUInt8 > ( src >> 16u ); - pWireDst[2] = static_cast < epicsUInt8 > ( src >> 8u ); - pWireDst[3] = static_cast < epicsUInt8 > ( src ); -} - -template < class T > -inline void AlignedWireGet ( const T & src, T & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - WireAlias < T > srcu, dstu; - srcu._o = src; - AlignedWireGet ( srcu._u, dstu._u ); - dst = dstu._o; -} - -template < class T > -inline void AlignedWireSet ( const T & src, T & dst ) -{ - // copy through union here - // a) prevents over-aggressive optimization under strict aliasing rules - // b) doesnt preclude extra copy operation being optimized away - WireAlias < T > srcu, dstu; - srcu._o = src; - AlignedWireSet ( srcu._u, dstu._u ); - dst = dstu._o; -} - -#include "osdWireFormat.h" - -#endif // osiWireFormat diff --git a/src/libCom/pool/Makefile b/src/libCom/pool/Makefile deleted file mode 100644 index efaf66729..000000000 --- a/src/libCom/pool/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -#************************************************************************* -# Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/pool - -INC += epicsThreadPool.h - -Com_SRCS += poolJob.c -Com_SRCS += threadPool.c - diff --git a/src/libCom/pool/epicsThreadPool.h b/src/libCom/pool/epicsThreadPool.h deleted file mode 100644 index 3416bb23a..000000000 --- a/src/libCom/pool/epicsThreadPool.h +++ /dev/null @@ -1,160 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* General purpose worker thread pool manager - * mdavidsaver@bnl.gov - */ -#ifndef EPICSTHREADPOOL_H -#define EPICSTHREADPOOL_H - -#include -#include - -#include "shareLib.h" -#include "errMdef.h" - -#define S_pool_jobBusy (M_pool| 1) /*Job already queued or running*/ -#define S_pool_jobIdle (M_pool| 2) /*Job was not queued or running*/ -#define S_pool_noPool (M_pool| 3) /*Job not associated with a pool*/ -#define S_pool_paused (M_pool| 4) /*Pool not currently accepting jobs*/ -#define S_pool_noThreads (M_pool| 5) /*Can't create worker thread*/ -#define S_pool_timeout (M_pool| 6) /*Pool still busy after timeout*/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - unsigned int initialThreads; - unsigned int maxThreads; - unsigned int workerStack; - unsigned int workerPriority; -} epicsThreadPoolConfig; - -typedef struct epicsThreadPool epicsThreadPool; - -/* Job function call modes */ -typedef enum { - /* Normal run of job */ - epicsJobModeRun, - - /* Thread pool is being destroyed. - * A chance to cleanup the job immediately with epicsJobDestroy(). - * If ignored, the job is orphaned (dissociated from the thread pool) - * and epicsJobDestroy() must be called later. - */ - epicsJobModeCleanup -} epicsJobMode; - -typedef void (*epicsJobFunction)(void* arg, epicsJobMode mode); - -typedef struct epicsJob epicsJob; - -/* Pool operations */ - -/* Initialize a pool config with default values. - * This much be done to preserve future compatibility - * when new options are added. - */ -epicsShareFunc void epicsThreadPoolConfigDefaults(epicsThreadPoolConfig *); - -/* fetch or create a thread pool which can be shared with other users. - * may return NULL for allocation failures - */ -epicsShareFunc epicsThreadPool* epicsThreadPoolGetShared(epicsThreadPoolConfig *opts); -epicsShareFunc void epicsThreadPoolReleaseShared(epicsThreadPool *pool); - -/* If opts is NULL then defaults are used. - * The opts pointer is not stored by this call, and may exist on the stack. - */ -epicsShareFunc epicsThreadPool* epicsThreadPoolCreate(epicsThreadPoolConfig *opts); - -/* Blocks until all worker threads have stopped. - * Any jobs still attached to this pool receive a callback with EPICSJOB_CLEANUP - * and are then orphaned. - */ -epicsShareFunc void epicsThreadPoolDestroy(epicsThreadPool *); - -/* pool control options */ -typedef enum { - epicsThreadPoolQueueAdd, /* val==0 causes epicsJobQueue to fail, 1 is default */ - epicsThreadPoolQueueRun /* val==0 prevents workers from running jobs, 1 is default */ -} epicsThreadPoolOption; - -epicsShareFunc void epicsThreadPoolControl(epicsThreadPool* pool, - epicsThreadPoolOption opt, - unsigned int val); - -/* Block until job queue is emptied and no jobs are running. - * Useful after calling epicsThreadPoolControl() with option epicsThreadPoolQueueAdd=0 - * - * timeout<0 waits forever, timeout==0 polls, timeout>0 waits at most one timeout period - * Returns 0 for success or non-zero on error (timeout is ETIMEOUT) - */ -epicsShareFunc int epicsThreadPoolWait(epicsThreadPool* pool, double timeout); - - -/* Per job operations */ - -/* Special flag for epicsJobCreate(). - * When passed as the third argument "user" - * the argument passed to the job callback - * will be the epicsJob* - */ -#define EPICSJOB_SELF epicsJobArgSelfMagic -epicsShareExtern void* epicsJobArgSelfMagic; - -/* Creates, but does not add, a new job. - * If pool is NULL then the job is not associated with any pool and - * epicsJobMove() must be called before epicsJobQueue(). - * Safe to call from a running job function. - * Returns a new job pointer, or NULL on error. - */ -epicsShareFunc epicsJob* epicsJobCreate(epicsThreadPool* pool, - epicsJobFunction cb, - void* user); - -/* Cancel and free a job structure. Does not block. - * Job may not be immediately free'd. - * Safe to call from a running job function. - */ -epicsShareFunc void epicsJobDestroy(epicsJob*); - -/* Move the job to a different pool. - * If pool is NULL then the job will no longer be associated - * with any pool. - * Not thread safe. Job must not be running or queued. - * returns 0 on success, non-zero on error. - */ -epicsShareFunc int epicsJobMove(epicsJob* job, epicsThreadPool* pool); - -/* Adds the job to the run queue - * Safe to call from a running job function. - * returns 0 for success, non-zero on error. - */ -epicsShareFunc int epicsJobQueue(epicsJob*); - -/* Remove a job from the run queue if it is queued. - * Safe to call from a running job function. - * returns 0 if job was queued and now is not. - * 1 if job already ran, is running, or was not queued before, - * Other non-zero on error - */ -epicsShareFunc int epicsJobUnqueue(epicsJob*); - - -/* Mostly useful for debugging */ - -epicsShareFunc void epicsThreadPoolReport(epicsThreadPool *pool, FILE *fd); - -/* Current number of active workers. May be less than the maximum */ -epicsShareFunc unsigned int epicsThreadPoolNThreads(epicsThreadPool *); - -#ifdef __cplusplus -} -#endif - -#endif // EPICSTHREADPOOL_H diff --git a/src/libCom/pool/poolJob.c b/src/libCom/pool/poolJob.c deleted file mode 100644 index 8e86fb768..000000000 --- a/src/libCom/pool/poolJob.c +++ /dev/null @@ -1,327 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include - -#define epicsExportSharedSymbols - -#include "dbDefs.h" -#include "errlog.h" -#include "ellLib.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsInterrupt.h" - -#include "epicsThreadPool.h" -#include "poolPriv.h" - -void *epicsJobArgSelfMagic = &epicsJobArgSelfMagic; - -static -void workerMain(void *arg) -{ - epicsThreadPool *pool = arg; - unsigned int nrun, ocnt; - - /* workers are created with counts - * in the running, sleeping, and (possibly) waking counters - */ - - epicsMutexMustLock(pool->guard); - pool->threadsAreAwake++; - pool->threadsSleeping--; - - while (1) { - ELLNODE *cur; - - pool->threadsAreAwake--; - pool->threadsSleeping++; - epicsMutexUnlock(pool->guard); - - epicsEventMustWait(pool->workerWakeup); - - epicsMutexMustLock(pool->guard); - pool->threadsSleeping--; - pool->threadsAreAwake++; - - if (pool->threadsWaking==0) - continue; - - pool->threadsWaking--; - - CHECKCOUNT(pool); - - if (pool->shutdown) - break; - - if (pool->pauserun) - continue; - - /* more threads to wakeup */ - if (pool->threadsWaking) { - epicsEventSignal(pool->workerWakeup); - } - - while ((cur=ellGet(&pool->jobs)) != NULL) { - epicsJob *job = CONTAINER(cur, epicsJob, jobnode); - - assert(job->queued && !job->running); - - job->queued=0; - job->running=1; - - epicsMutexUnlock(pool->guard); - (*job->func)(job->arg, epicsJobModeRun); - epicsMutexMustLock(pool->guard); - - if (job->freewhendone) { - job->dead=1; - free(job); - } - else { - job->running=0; - /* job may be re-queued from within callback */ - if (job->queued) - ellAdd(&pool->jobs, &job->jobnode); - else - ellAdd(&pool->owned, &job->jobnode); - } - } - - if (pool->observerCount) - epicsEventSignal(pool->observerWakeup); - } - - pool->threadsAreAwake--; - pool->threadsRunning--; - - nrun = pool->threadsRunning; - ocnt = pool->observerCount; - epicsMutexUnlock(pool->guard); - - if (ocnt) - epicsEventSignal(pool->observerWakeup); - - if (nrun) - epicsEventSignal(pool->workerWakeup); /* pass along */ - else - epicsEventSignal(pool->shutdownEvent); -} - -int createPoolThread(epicsThreadPool *pool) -{ - epicsThreadId tid; - - tid = epicsThreadCreate("PoolWorker", - pool->conf.workerPriority, - pool->conf.workerStack, - &workerMain, - pool); - if (!tid) - return S_pool_noThreads; - - pool->threadsRunning++; - pool->threadsSleeping++; - return 0; -} - -epicsJob* epicsJobCreate(epicsThreadPool *pool, - epicsJobFunction func, - void *arg) -{ - epicsJob *job = calloc(1, sizeof(*job)); - - if (!job) - return NULL; - - if (arg == &epicsJobArgSelfMagic) - arg = job; - - job->pool = NULL; - job->func = func; - job->arg = arg; - - epicsJobMove(job, pool); - - return job; -} - -void epicsJobDestroy(epicsJob *job) -{ - epicsThreadPool *pool; - if (!job || !job->pool) { - free(job); - return; - } - pool = job->pool; - - epicsMutexMustLock(pool->guard); - - assert(!job->dead); - - epicsJobUnqueue(job); - - if (job->running || job->freewhendone) { - job->freewhendone = 1; - } - else { - ellDelete(&pool->owned, &job->jobnode); - job->dead = 1; - free(job); - } - - epicsMutexUnlock(pool->guard); -} - -int epicsJobMove(epicsJob *job, epicsThreadPool *newpool) -{ - epicsThreadPool *pool = job->pool; - - /* remove from current pool */ - if (pool) { - epicsMutexMustLock(pool->guard); - - if (job->queued || job->running) { - epicsMutexUnlock(pool->guard); - return S_pool_jobBusy; - } - - ellDelete(&pool->owned, &job->jobnode); - - epicsMutexUnlock(pool->guard); - } - - pool = job->pool = newpool; - - /* add to new pool */ - if (pool) { - epicsMutexMustLock(pool->guard); - - ellAdd(&pool->owned, &job->jobnode); - - epicsMutexUnlock(pool->guard); - } - - return 0; -} - -int epicsJobQueue(epicsJob *job) -{ - int ret = 0; - epicsThreadPool *pool = job->pool; - - if (!pool) - return S_pool_noPool; - - epicsMutexMustLock(pool->guard); - - assert(!job->dead); - - if (pool->pauseadd) { - ret = S_pool_paused; - goto done; - } - else if (job->freewhendone) { - ret = S_pool_jobBusy; - goto done; - } - else if (job->queued) { - goto done; - } - - job->queued = 1; - /* Job may be queued from within a callback */ - if (!job->running) { - ellDelete(&pool->owned, &job->jobnode); - ellAdd(&pool->jobs, &job->jobnode); - } - else { - /* some worker will find it again before sleeping */ - goto done; - } - - /* Since we hold the lock, we can be certain that all awake worker are - * executing work functions. The current thread may be a worker. - * We prefer to wakeup a new worker rather then wait for a busy worker to - * finish. However, after we initiate a wakeup there will be a race - * between the worker waking up, and a busy worker finishing. - * Thus we can't avoid spurious wakeups. - */ - - if (pool->threadsRunning >= pool->conf.maxThreads) { - /* all workers created... */ - /* ... but some are sleeping, so wake one up */ - if (pool->threadsWaking < pool->threadsSleeping) { - pool->threadsWaking++; - epicsEventSignal(pool->workerWakeup); - } - /*else one of the running workers will find this job before sleeping */ - CHECKCOUNT(pool); - - } - else { - /* could create more workers so - * will either create a new worker, or wakeup an existing worker - */ - - if (pool->threadsWaking >= pool->threadsSleeping) { - /* all sleeping workers have already been woken. - * start a new worker for this job - */ - if (createPoolThread(pool) && pool->threadsRunning == 0) { - /* oops, we couldn't lazy create our first worker - * so this job would never run! - */ - ret = S_pool_noThreads; - job->queued = 0; - /* if threadsRunning==0 then no jobs can be running */ - assert(!job->running); - ellDelete(&pool->jobs, &job->jobnode); - ellAdd(&pool->owned, &job->jobnode); - } - } - if (ret == 0) { - pool->threadsWaking++; - epicsEventSignal(pool->workerWakeup); - } - CHECKCOUNT(pool); - } - -done: - epicsMutexUnlock(pool->guard); - return ret; -} - -int epicsJobUnqueue(epicsJob *job) -{ - int ret = S_pool_jobIdle; - epicsThreadPool *pool = job->pool; - - if (!pool) - return S_pool_noPool; - - epicsMutexMustLock(pool->guard); - - assert(!job->dead); - - if (job->queued) { - if (!job->running) { - ellDelete(&pool->jobs, &job->jobnode); - ellAdd(&pool->owned, &job->jobnode); - } - job->queued = 0; - ret = 0; - } - - epicsMutexUnlock(pool->guard); - - return ret; -} - diff --git a/src/libCom/pool/poolPriv.h b/src/libCom/pool/poolPriv.h deleted file mode 100644 index 237cedf45..000000000 --- a/src/libCom/pool/poolPriv.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#ifndef POOLPRIV_H -#define POOLPRIV_H - -#include "epicsThreadPool.h" -#include "ellLib.h" -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsMutex.h" - -struct epicsThreadPool { - ELLNODE sharedNode; - size_t sharedCount; - - ELLLIST jobs; /* run queue */ - ELLLIST owned; /* unqueued jobs. */ - - /* Worker state counters. - * The life cycle of a worker is - * Wakeup -> Awake -> Sleeping - * Newly created workers go into the wakeup state - */ - - /* # of running workers which are not waiting for a wakeup event */ - unsigned int threadsAreAwake; - /* # of sleeping workers which need to be awakened */ - unsigned int threadsWaking; - /* # of workers waiting on the workerWakeup event */ - unsigned int threadsSleeping; - /* # of threads started and not stopped */ - unsigned int threadsRunning; - - /* # of observers waiting on pool events */ - unsigned int observerCount; - - epicsEventId workerWakeup; - epicsEventId shutdownEvent; - - epicsEventId observerWakeup; - - /* Disallow epicsJobQueue */ - unsigned int pauseadd:1; - /* Prevent workers from running new jobs */ - unsigned int pauserun:1; - /* Prevent further changes to pool options */ - unsigned int freezeopt:1; - /* tell workers to exit */ - unsigned int shutdown:1; - - epicsMutexId guard; - - /* copy of config passed when created */ - epicsThreadPoolConfig conf; -}; - -/* Called after manipulating counters to check that invariants are preserved */ -#define CHECKCOUNT(pPool) do { \ - if (!(pPool)->shutdown) { \ - assert((pPool)->threadsAreAwake + (pPool)->threadsSleeping == (pPool)->threadsRunning); \ - assert((pPool)->threadsWaking <= (pPool)->threadsSleeping); \ - } \ -} while(0) - -/* When created a job is idle. queued and running are false - * and jobnode is in the thread pool's owned list. - * - * When the job is added, the queued flag is set and jobnode - * is in the jobs list. - * - * When the job starts running the queued flag is cleared and - * the running flag is set. jobnode is not in any list - * (held locally by worker). - * - * When the job has finished running, the running flag is cleared. - * The queued flag may be set if the job re-added itself. - * Based on the queued flag jobnode is added to the appropriate - * list. - */ -struct epicsJob { - ELLNODE jobnode; - epicsJobFunction func; - void *arg; - epicsThreadPool *pool; - - unsigned int queued:1; - unsigned int running:1; - unsigned int freewhendone:1; /* lazy delete of running job */ - unsigned int dead:1; /* flag to catch use of freed objects */ -}; - -int createPoolThread(epicsThreadPool *pool); - -#endif // POOLPRIV_H diff --git a/src/libCom/pool/threadPool.c b/src/libCom/pool/threadPool.c deleted file mode 100644 index 3cfd06606..000000000 --- a/src/libCom/pool/threadPool.c +++ /dev/null @@ -1,403 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include - -#define epicsExportSharedSymbols - -#include "dbDefs.h" -#include "errlog.h" -#include "ellLib.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "epicsInterrupt.h" -#include "cantProceed.h" - -#include "epicsThreadPool.h" -#include "poolPriv.h" - - -void epicsThreadPoolConfigDefaults(epicsThreadPoolConfig *opts) -{ - memset(opts, 0, sizeof(*opts)); - opts->maxThreads = epicsThreadGetCPUs(); - opts->workerStack = epicsThreadGetStackSize(epicsThreadStackSmall); - - if (epicsThreadLowestPriorityLevelAbove(epicsThreadPriorityCAServerHigh, &opts->workerPriority) - != epicsThreadBooleanStatusSuccess) - opts->workerPriority = epicsThreadPriorityMedium; -} - -epicsThreadPool* epicsThreadPoolCreate(epicsThreadPoolConfig *opts) -{ - size_t i; - epicsThreadPool *pool; - - /* caller likely didn't initialize the options structure */ - if (opts && opts->maxThreads == 0) { - errlogMessage("Error: epicsThreadPoolCreate() options provided, but not initialized"); - return NULL; - } - - pool = calloc(1, sizeof(*pool)); - if (!pool) - return NULL; - - if (opts) - memcpy(&pool->conf, opts, sizeof(*opts)); - else - epicsThreadPoolConfigDefaults(&pool->conf); - - if (pool->conf.initialThreads > pool->conf.maxThreads) - pool->conf.initialThreads = pool->conf.maxThreads; - - pool->workerWakeup = epicsEventCreate(epicsEventEmpty); - pool->shutdownEvent = epicsEventCreate(epicsEventEmpty); - pool->observerWakeup = epicsEventCreate(epicsEventEmpty); - pool->guard = epicsMutexCreate(); - - if (!pool->workerWakeup || !pool->shutdownEvent || - !pool->observerWakeup || !pool->guard) - goto cleanup; - - ellInit(&pool->jobs); - ellInit(&pool->owned); - - epicsMutexMustLock(pool->guard); - - for (i = 0; i < pool->conf.initialThreads; i++) { - createPoolThread(pool); - } - - if (pool->threadsRunning == 0 && pool->conf.initialThreads != 0) { - epicsMutexUnlock(pool->guard); - errlogPrintf("Error: Unable to create any threads for thread pool\n"); - goto cleanup; - - } - else if (pool->threadsRunning < pool->conf.initialThreads) { - errlogPrintf("Warning: Unable to create all threads for thread pool (%u/%u)\n", - pool->threadsRunning, pool->conf.initialThreads); - } - - epicsMutexUnlock(pool->guard); - - return pool; - -cleanup: - if (pool->workerWakeup) - epicsEventDestroy(pool->workerWakeup); - if (pool->shutdownEvent) - epicsEventDestroy(pool->shutdownEvent); - if (pool->observerWakeup) - epicsEventDestroy(pool->observerWakeup); - if (pool->guard) - epicsMutexDestroy(pool->guard); - - free(pool); - return NULL; -} - -static -void epicsThreadPoolControlImpl(epicsThreadPool *pool, epicsThreadPoolOption opt, unsigned int val) -{ - if (pool->freezeopt) - return; - - if (opt == epicsThreadPoolQueueAdd) { - pool->pauseadd = !val; - } - else if (opt == epicsThreadPoolQueueRun) { - if (!val && !pool->pauserun) - pool->pauserun = 1; - - else if (val && pool->pauserun) { - int jobs = ellCount(&pool->jobs); - pool->pauserun = 0; - - if (jobs) { - int wakeable = pool->threadsSleeping - pool->threadsWaking; - - /* first try to give jobs to sleeping workers */ - if (wakeable) { - int wakeup = jobs > wakeable ? wakeable : jobs; - assert(wakeup > 0); - jobs -= wakeup; - pool->threadsWaking += wakeup; - epicsEventSignal(pool->workerWakeup); - CHECKCOUNT(pool); - } - } - while (jobs-- && pool->threadsRunning < pool->conf.maxThreads) { - if (createPoolThread(pool) == 0) { - pool->threadsWaking++; - epicsEventSignal(pool->workerWakeup); - } - else - break; /* oops, couldn't create worker */ - } - CHECKCOUNT(pool); - } - } - /* unknown options ignored */ - -} - -void epicsThreadPoolControl(epicsThreadPool *pool, epicsThreadPoolOption opt, unsigned int val) -{ - epicsMutexMustLock(pool->guard); - epicsThreadPoolControlImpl(pool, opt, val); - epicsMutexUnlock(pool->guard); -} - -int epicsThreadPoolWait(epicsThreadPool *pool, double timeout) -{ - int ret = 0; - epicsMutexMustLock(pool->guard); - - while (ellCount(&pool->jobs) > 0 || pool->threadsAreAwake > 0) { - pool->observerCount++; - epicsMutexUnlock(pool->guard); - - if (timeout < 0.0) { - epicsEventMustWait(pool->observerWakeup); - } - else { - switch (epicsEventWaitWithTimeout(pool->observerWakeup, timeout)) { - case epicsEventWaitError: - cantProceed("epicsThreadPoolWait: failed to wait for Event"); - break; - case epicsEventWaitTimeout: - ret = S_pool_timeout; - break; - case epicsEventWaitOK: - ret = 0; - break; - } - } - - epicsMutexMustLock(pool->guard); - pool->observerCount--; - - if (pool->observerCount) - epicsEventSignal(pool->observerWakeup); - - if (ret != 0) - break; - } - - epicsMutexUnlock(pool->guard); - return ret; -} - -void epicsThreadPoolDestroy(epicsThreadPool *pool) -{ - unsigned int nThr; - ELLLIST notify; - ELLNODE *cur; - - if (!pool) - return; - - ellInit(¬ify); - - epicsMutexMustLock(pool->guard); - - /* run remaining queued jobs */ - epicsThreadPoolControlImpl(pool, epicsThreadPoolQueueAdd, 0); - epicsThreadPoolControlImpl(pool, epicsThreadPoolQueueRun, 1); - nThr = pool->threadsRunning; - pool->freezeopt = 1; - - epicsMutexUnlock(pool->guard); - - epicsThreadPoolWait(pool, -1.0); - /* At this point all queued jobs have run */ - - epicsMutexMustLock(pool->guard); - - pool->shutdown = 1; - /* wakeup all */ - if (pool->threadsWaking < pool->threadsSleeping) { - pool->threadsWaking = pool->threadsSleeping; - epicsEventSignal(pool->workerWakeup); - } - - ellConcat(¬ify, &pool->owned); - ellConcat(¬ify, &pool->jobs); - - epicsMutexUnlock(pool->guard); - - if (nThr && epicsEventWait(pool->shutdownEvent) != epicsEventWaitOK){ - errlogMessage("epicsThreadPoolDestroy: wait error"); - return; - } - - /* all workers are now shutdown */ - - /* notify remaining jobs that pool is being destroyed */ - while ((cur = ellGet(¬ify)) != NULL) { - epicsJob *job = CONTAINER(cur, epicsJob, jobnode); - - job->running = 1; - job->func(job->arg, epicsJobModeCleanup); - job->running = 0; - if (job->freewhendone) - free(job); - else - job->pool = NULL; /* orphan */ - } - - epicsEventDestroy(pool->workerWakeup); - epicsEventDestroy(pool->shutdownEvent); - epicsEventDestroy(pool->observerWakeup); - epicsMutexDestroy(pool->guard); - - free(pool); -} - - -void epicsThreadPoolReport(epicsThreadPool *pool, FILE *fd) -{ - ELLNODE *cur; - epicsMutexMustLock(pool->guard); - - fprintf(fd, "Thread Pool with %u/%u threads\n" - " running %d jobs with %u threads\n", - pool->threadsRunning, - pool->conf.maxThreads, - ellCount(&pool->jobs), - pool->threadsAreAwake); - if (pool->pauseadd) - fprintf(fd, " Inhibit queueing\n"); - if (pool->pauserun) - fprintf(fd, " Pause workers\n"); - if (pool->shutdown) - fprintf(fd, " Shutdown in progress\n"); - - for (cur = ellFirst(&pool->jobs); cur; cur = ellNext(cur)) { - epicsJob *job = CONTAINER(cur, epicsJob, jobnode); - - fprintf(fd, " job %p func: %p, arg: %p ", - job, job->func, - job->arg); - if (job->queued) - fprintf(fd, "Queued "); - if (job->running) - fprintf(fd, "Running "); - if (job->freewhendone) - fprintf(fd, "Free "); - fprintf(fd, "\n"); - } - - epicsMutexUnlock(pool->guard); -} - -unsigned int epicsThreadPoolNThreads(epicsThreadPool *pool) -{ - unsigned int ret; - - epicsMutexMustLock(pool->guard); - ret = pool->threadsRunning; - epicsMutexUnlock(pool->guard); - - return ret; -} - -static -ELLLIST sharedPools = ELLLIST_INIT; - -static -epicsMutexId sharedPoolsGuard; - -static -epicsThreadOnceId sharedPoolsOnce = EPICS_THREAD_ONCE_INIT; - -static -void sharedPoolsInit(void* unused) -{ - sharedPoolsGuard = epicsMutexMustCreate(); -} - -epicsShareFunc epicsThreadPool* epicsThreadPoolGetShared(epicsThreadPoolConfig *opts) -{ - ELLNODE *node; - epicsThreadPool *cur; - epicsThreadPoolConfig defopts; - size_t N = epicsThreadGetCPUs(); - - if (!opts) { - epicsThreadPoolConfigDefaults(&defopts); - opts = &defopts; - } - /* shared pools must have a minimum allowed number of workers. - * Use the number of CPU cores - */ - if (opts->maxThreads < N) - opts->maxThreads = N; - - epicsThreadOnce(&sharedPoolsOnce, &sharedPoolsInit, NULL); - - epicsMutexMustLock(sharedPoolsGuard); - - for (node = ellFirst(&sharedPools); node; node = ellNext(node)) { - cur = CONTAINER(node, epicsThreadPool, sharedNode); - - /* Must have exactly the requested priority - * At least the requested max workers - * and at least the requested stack size - */ - if (cur->conf.workerPriority != opts->workerPriority) - continue; - if (cur->conf.maxThreads < opts->maxThreads) - continue; - if (cur->conf.workerStack < opts->workerStack) - continue; - - cur->sharedCount++; - assert(cur->sharedCount > 0); - epicsMutexUnlock(sharedPoolsGuard); - - epicsMutexMustLock(cur->guard); - *opts = cur->conf; - epicsMutexUnlock(cur->guard); - return cur; - } - - cur = epicsThreadPoolCreate(opts); - if (!cur) { - epicsMutexUnlock(sharedPoolsGuard); - return NULL; - } - cur->sharedCount = 1; - - ellAdd(&sharedPools, &cur->sharedNode); - epicsMutexUnlock(sharedPoolsGuard); - return cur; -} - -epicsShareFunc void epicsThreadPoolReleaseShared(epicsThreadPool *pool) -{ - if (!pool) - return; - - epicsMutexMustLock(sharedPoolsGuard); - - assert(pool->sharedCount > 0); - - pool->sharedCount--; - - if (pool->sharedCount == 0) { - ellDelete(&sharedPools, &pool->sharedNode); - epicsThreadPoolDestroy(pool); - } - - epicsMutexUnlock(sharedPoolsGuard); -} diff --git a/src/libCom/ring/Makefile b/src/libCom/ring/Makefile deleted file mode 100644 index ec2ecbd2d..000000000 --- a/src/libCom/ring/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/ring -#following needed for locating epicsRingPointer.h and epicsRingBytes.h -INC += epicsRingPointer.h -INC += epicsRingBytes.h -Com_SRCS += epicsRingPointer.cpp -Com_SRCS += epicsRingBytes.c diff --git a/src/libCom/ring/epicsRingBytes.c b/src/libCom/ring/epicsRingBytes.c deleted file mode 100644 index cb7e52e83..000000000 --- a/src/libCom/ring/epicsRingBytes.c +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer Date: 15JUL99 - * Eric Norum - * Ralph Lange - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsSpin.h" -#include "dbDefs.h" -#include "epicsRingBytes.h" - -/* - * Need at least one extra byte to be able to distinguish a completely - * full buffer from a completely empty one. Allow for a little extra - * space to try and keep good alignment and avoid multiple calls to - * memcpy for a single put/get operation. - */ -#define SLOP 16 - -typedef struct ringPvt { - epicsSpinId lock; - volatile int nextPut; - volatile int nextGet; - int size; - volatile char buffer[1]; /* actually larger */ -}ringPvt; - -epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int size) -{ - ringPvt *pring = malloc(sizeof(ringPvt) + size + SLOP); - if(!pring) - return NULL; - pring->size = size + SLOP; - pring->nextGet = 0; - pring->nextPut = 0; - pring->lock = 0; - return((void *)pring); -} - -epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesLockedCreate(int size) -{ - ringPvt *pring = (ringPvt *)epicsRingBytesCreate(size); - if(!pring) - return NULL; - pring->lock = epicsSpinCreate(); - return((void *)pring); -} - -epicsShareFunc void epicsShareAPI epicsRingBytesDelete(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - if (pring->lock) epicsSpinDestroy(pring->lock); - free((void *)pring); -} - -epicsShareFunc int epicsShareAPI epicsRingBytesGet( - epicsRingBytesId id, char *value,int nbytes) -{ - ringPvt *pring = (ringPvt *)id; - int nextGet, nextPut, size; - int count; - - if (pring->lock) epicsSpinLock(pring->lock); - nextGet = pring->nextGet; - nextPut = pring->nextPut; - size = pring->size; - - if (nextGet <= nextPut) { - count = nextPut - nextGet; - if (count < nbytes) - nbytes = count; - if (nbytes) - memcpy (value, (void *)&pring->buffer[nextGet], nbytes); - nextGet += nbytes; - } - else { - count = size - nextGet; - if (count > nbytes) - count = nbytes; - memcpy (value, (void *)&pring->buffer[nextGet], count); - nextGet += count; - if (nextGet == size) { - int nLeft = nbytes - count; - if (nLeft > nextPut) - nLeft = nextPut; - memcpy (value+count, (void *)&pring->buffer[0], nLeft); - nextGet = nLeft; - nbytes = count + nLeft; - } - else { - nbytes = count; - } - } - pring->nextGet = nextGet; - - if (pring->lock) epicsSpinUnlock(pring->lock); - return nbytes; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesPut( - epicsRingBytesId id, char *value,int nbytes) -{ - ringPvt *pring = (ringPvt *)id; - int nextGet, nextPut, size; - int freeCount, copyCount, topCount; - - if (pring->lock) epicsSpinLock(pring->lock); - nextGet = pring->nextGet; - nextPut = pring->nextPut; - size = pring->size; - - if (nextPut < nextGet) { - freeCount = nextGet - nextPut - SLOP; - if (nbytes > freeCount) { - if (pring->lock) epicsSpinUnlock(pring->lock); - return 0; - } - if (nbytes) - memcpy ((void *)&pring->buffer[nextPut], value, nbytes); - nextPut += nbytes; - } - else { - freeCount = size - nextPut + nextGet - SLOP; - if (nbytes > freeCount) { - if (pring->lock) epicsSpinUnlock(pring->lock); - return 0; - } - topCount = size - nextPut; - copyCount = (nbytes > topCount) ? topCount : nbytes; - if (copyCount) - memcpy ((void *)&pring->buffer[nextPut], value, copyCount); - nextPut += copyCount; - if (nextPut == size) { - int nLeft = nbytes - copyCount; - if (nLeft) - memcpy ((void *)&pring->buffer[0], value+copyCount, nLeft); - nextPut = nLeft; - } - } - pring->nextPut = nextPut; - - if (pring->lock) epicsSpinUnlock(pring->lock); - return nbytes; -} - -epicsShareFunc void epicsShareAPI epicsRingBytesFlush(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - - if (pring->lock) epicsSpinLock(pring->lock); - pring->nextGet = pring->nextPut; - if (pring->lock) epicsSpinUnlock(pring->lock); -} - -epicsShareFunc int epicsShareAPI epicsRingBytesFreeBytes(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - int nextGet, nextPut; - - if (pring->lock) epicsSpinLock(pring->lock); - nextGet = pring->nextGet; - nextPut = pring->nextPut; - if (pring->lock) epicsSpinUnlock(pring->lock); - - if (nextPut < nextGet) - return nextGet - nextPut - SLOP; - else - return pring->size - nextPut + nextGet - SLOP; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesUsedBytes(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - int nextGet, nextPut; - int used; - - if (pring->lock) epicsSpinLock(pring->lock); - nextGet = pring->nextGet; - nextPut = pring->nextPut; - if (pring->lock) epicsSpinUnlock(pring->lock); - - used = nextPut - nextGet; - if (used < 0) used += pring->size; - - return used; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesSize(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - - return pring->size - SLOP; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesIsEmpty(epicsRingBytesId id) -{ - ringPvt *pring = (ringPvt *)id; - int isEmpty; - - if (pring->lock) epicsSpinLock(pring->lock); - isEmpty = (pring->nextPut == pring->nextGet); - if (pring->lock) epicsSpinUnlock(pring->lock); - - return isEmpty; -} - -epicsShareFunc int epicsShareAPI epicsRingBytesIsFull(epicsRingBytesId id) -{ - return (epicsRingBytesFreeBytes(id) <= 0); -} diff --git a/src/libCom/ring/epicsRingBytes.h b/src/libCom/ring/epicsRingBytes.h deleted file mode 100644 index 011829bfe..000000000 --- a/src/libCom/ring/epicsRingBytes.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer Date: 15JUL99 - * Eric Norum - * Ralph Lange - */ - -#ifndef INCepicsRingBytesh -#define INCepicsRingBytesh - -#ifdef __cplusplus -extern "C" { -#endif - -#include "shareLib.h" - -typedef void *epicsRingBytesId; - -epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesCreate(int nbytes); -/* Same, but secured by a spinlock */ -epicsShareFunc epicsRingBytesId epicsShareAPI epicsRingBytesLockedCreate(int nbytes); -epicsShareFunc void epicsShareAPI epicsRingBytesDelete(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesGet( - epicsRingBytesId id, char *value,int nbytes); -epicsShareFunc int epicsShareAPI epicsRingBytesPut( - epicsRingBytesId id, char *value,int nbytes); -epicsShareFunc void epicsShareAPI epicsRingBytesFlush(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesFreeBytes(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesUsedBytes(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesSize(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesIsEmpty(epicsRingBytesId id); -epicsShareFunc int epicsShareAPI epicsRingBytesIsFull(epicsRingBytesId id); - -#ifdef __cplusplus -} -#endif - -/* NOTES - If there is only one writer it is not necessary to lock for put - If there is a single reader it is not necessary to lock for puts - - epicsRingBytesLocked uses a spinlock. -*/ - -#endif /* INCepicsRingBytesh */ diff --git a/src/libCom/ring/epicsRingPointer.cpp b/src/libCom/ring/epicsRingPointer.cpp deleted file mode 100644 index 9c144cec1..000000000 --- a/src/libCom/ring/epicsRingPointer.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer Date: 13OCT2000 - * Ralph Lange - */ - - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsRingPointer.h" -typedef epicsRingPointer voidPointer; - - -epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerCreate(int size) -{ - voidPointer *pvoidPointer = new voidPointer(size, false); - return(reinterpret_cast(pvoidPointer)); -} - -epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerLockedCreate(int size) -{ - voidPointer *pvoidPointer = new voidPointer(size, true); - return(reinterpret_cast(pvoidPointer)); -} - -epicsShareFunc void epicsShareAPI epicsRingPointerDelete(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - delete pvoidPointer; -} - -epicsShareFunc void* epicsShareAPI epicsRingPointerPop(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return pvoidPointer->pop(); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerPush(epicsRingPointerId id, void *p) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return((pvoidPointer->push(p) ? 1 : 0)); -} - -epicsShareFunc void epicsShareAPI epicsRingPointerFlush(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - pvoidPointer->flush(); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerGetFree(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return(pvoidPointer->getFree()); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerGetUsed(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return(pvoidPointer->getUsed()); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerGetSize(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return(pvoidPointer->getSize()); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerIsEmpty(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return((pvoidPointer->isEmpty()) ? 1 : 0); -} - -epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id) -{ - voidPointer *pvoidPointer = reinterpret_cast(id); - return((pvoidPointer->isFull()) ? 1 : 0); -} diff --git a/src/libCom/ring/epicsRingPointer.h b/src/libCom/ring/epicsRingPointer.h deleted file mode 100644 index 48d62036d..000000000 --- a/src/libCom/ring/epicsRingPointer.h +++ /dev/null @@ -1,201 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer Date: 15JUL99 - * Ralph Lange - */ - -#ifndef INCepicsRingPointerh -#define INCepicsRingPointerh - -/* NOTES - * If there is only one writer it is not necessary to lock push - * If there is a single reader it is not necessary to lock pop - * - * epicsRingPointerLocked uses a spinlock. - */ - -#include "epicsSpin.h" -#include "shareLib.h" - -#ifdef __cplusplus -template -class epicsRingPointer { -public: /* Functions */ - epicsRingPointer(int size, bool locked); - ~epicsRingPointer(); - bool push(T *p); - T* pop(); - void flush(); - int getFree() const; - int getUsed() const; - int getSize() const; - bool isEmpty() const; - bool isFull() const; - -private: /* Prevent compiler-generated member functions */ - /* default constructor, copy constructor, assignment operator */ - epicsRingPointer(); - epicsRingPointer(const epicsRingPointer &); - epicsRingPointer& operator=(const epicsRingPointer &); - -private: /* Data */ - epicsSpinId lock; - volatile int nextPush; - volatile int nextPop; - int size; - T * volatile * buffer; -}; - -extern "C" { -#endif /*__cplusplus */ - -typedef void *epicsRingPointerId; - -epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerCreate(int size); -/* Same, but secured by a spinlock */ -epicsShareFunc epicsRingPointerId epicsShareAPI epicsRingPointerLockedCreate(int size); -epicsShareFunc void epicsShareAPI epicsRingPointerDelete(epicsRingPointerId id); -/*ringPointerPush returns (0,1) if p (was not, was) put on ring*/ -epicsShareFunc int epicsShareAPI epicsRingPointerPush(epicsRingPointerId id,void *p); -/*ringPointerPop returns 0 if ring is empty*/ -epicsShareFunc void* epicsShareAPI epicsRingPointerPop(epicsRingPointerId id) ; -epicsShareFunc void epicsShareAPI epicsRingPointerFlush(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerGetFree(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerGetUsed(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerGetSize(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerIsEmpty(epicsRingPointerId id); -epicsShareFunc int epicsShareAPI epicsRingPointerIsFull(epicsRingPointerId id); - -/* This routine was incorrectly named in previous releases */ -#define epicsRingPointerSize epicsRingPointerGetSize - -#ifdef __cplusplus -} -#endif -/* END OF DECLARATIONS */ - -/* INLINE FUNCTIONS */ - -/* Algorithm note - * Space is allocated for one additional element. - * A put request is rejected if the it would cause nextPush to equal nextPop - * The algorithm does not require locking puts for a single writer - * or locking of gets for a single reader - */ -#ifdef __cplusplus - -template -inline epicsRingPointer::epicsRingPointer(int sz, bool locked) : - lock(0), nextPush(0), nextPop(0), size(sz+1), buffer(new T* [sz+1]) -{ - if (locked) - lock = epicsSpinCreate(); -} - -template -inline epicsRingPointer::~epicsRingPointer() -{ - if (lock) epicsSpinDestroy(lock); - delete [] buffer; -} - -template -inline bool epicsRingPointer::push(T *p) -{ - if (lock) epicsSpinLock(lock); - int next = nextPush; - int newNext = next + 1; - if(newNext>=size) newNext=0; - if (newNext == nextPop) { - if (lock) epicsSpinUnlock(lock); - return(false); - } - buffer[next] = p; - nextPush = newNext; - if (lock) epicsSpinUnlock(lock); - return(true); -} - -template -inline T* epicsRingPointer::pop() -{ - if (lock) epicsSpinLock(lock); - int next = nextPop; - if (next == nextPush) { - if (lock) epicsSpinUnlock(lock); - return(0); - } - T*p = buffer[next]; - ++next; - if(next >=size) next = 0; - nextPop = next; - if (lock) epicsSpinUnlock(lock); - return(p); -} - -template -inline void epicsRingPointer::flush() -{ - if (lock) epicsSpinLock(lock); - nextPop = 0; - nextPush = 0; - if (lock) epicsSpinUnlock(lock); -} - -template -inline int epicsRingPointer::getFree() const -{ - if (lock) epicsSpinLock(lock); - int n = nextPop - nextPush - 1; - if (n < 0) n += size; - if (lock) epicsSpinUnlock(lock); - return n; -} - -template -inline int epicsRingPointer::getUsed() const -{ - if (lock) epicsSpinLock(lock); - int n = nextPush - nextPop; - if (n < 0) n += size; - if (lock) epicsSpinUnlock(lock); - return n; -} - -template -inline int epicsRingPointer::getSize() const -{ - return(size-1); -} - -template -inline bool epicsRingPointer::isEmpty() const -{ - bool isEmpty; - if (lock) epicsSpinLock(lock); - isEmpty = (nextPush == nextPop); - if (lock) epicsSpinUnlock(lock); - return isEmpty; -} - -template -inline bool epicsRingPointer::isFull() const -{ - if (lock) epicsSpinLock(lock); - int count = nextPush - nextPop +1; - if (lock) epicsSpinUnlock(lock); - return((count == 0) || (count == size)); -} - -#endif /* __cplusplus */ - -#endif /* INCepicsRingPointerh */ diff --git a/src/libCom/taskwd/Makefile b/src/libCom/taskwd/Makefile deleted file mode 100644 index af738f0d6..000000000 --- a/src/libCom/taskwd/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/taskwd -INC += taskwd.h -Com_SRCS += taskwd.c diff --git a/src/libCom/taskwd/taskwd.c b/src/libCom/taskwd/taskwd.c deleted file mode 100644 index 44ddc779c..000000000 --- a/src/libCom/taskwd/taskwd.c +++ /dev/null @@ -1,430 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* taskwd.c */ - -/* tasks and subroutines for a general purpose task watchdog */ -/* - * Original Author: Marty Kraimer - * Date: 07-18-91 -*/ - -#include -#include - -#define epicsExportSharedSymbols -#include "cantProceed.h" -#include "dbDefs.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsStdioRedirect.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "valgrind/valgrind.h" -#include "errlog.h" -#include "ellLib.h" -#include "errMdef.h" -#include "taskwd.h" - -struct tNode { - ELLNODE node; - epicsThreadId tid; - TASKWDFUNC callback; - void *usr; - int suspended; -}; - -struct mNode { - ELLNODE node; - const taskwdMonitor *funcs; - void *usr; -}; - -struct aNode { - void *key; - TASKWDANYFUNC callback; - void *usr; -}; - -union twdNode { - struct tNode t; - struct mNode m; - struct aNode a; -}; - -/* Registered Tasks */ -static epicsMutexId tLock; -static ELLLIST tList = ELLLIST_INIT; - -/* Active Monitors */ -static epicsMutexId mLock; -static ELLLIST mList = ELLLIST_INIT; - -/* Free List */ -static epicsMutexId fLock; -static ELLLIST fList = ELLLIST_INIT; - -/* Watchdog task control */ -static volatile enum { - twdctlInit, twdctlRun, twdctlDisable, twdctlExit -} twdCtl; -static epicsEventId loopEvent; -static epicsEventId exitEvent; - -/* Task delay times (seconds) */ -#define TASKWD_DELAY 6.0 - - -/* forward definitions */ -static union twdNode *allocNode(void); -static void freeNode(union twdNode *); - -/* Initialization, lazy */ - -static void twdTask(void *arg) -{ - struct tNode *pt; - struct mNode *pm; - - while (twdCtl != twdctlExit) { - if (twdCtl == twdctlRun) { - epicsMutexMustLock(tLock); - pt = (struct tNode *)ellFirst(&tList); - while (pt) { - int susp = epicsThreadIsSuspended(pt->tid); - if (susp != pt->suspended) { - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs->notify) { - pm->funcs->notify(pm->usr, pt->tid, susp); - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - - if (susp) { - char tName[40]; - epicsThreadGetName(pt->tid, tName, sizeof(tName)); - errlogPrintf("Thread %s (%p) suspended\n", - tName, (void *)pt->tid); - if (pt->callback) { - pt->callback(pt->usr); - } - } - pt->suspended = susp; - } - pt = (struct tNode *)ellNext(&pt->node); - } - epicsMutexUnlock(tLock); - } - epicsEventWaitWithTimeout(loopEvent, TASKWD_DELAY); - } - epicsEventSignal(exitEvent); -} - - -static void twdShutdown(void *arg) -{ - ELLNODE *cur; - twdCtl = twdctlExit; - epicsEventSignal(loopEvent); - epicsEventWait(exitEvent); - while ((cur = ellGet(&fList)) != NULL) { - VALGRIND_MEMPOOL_FREE(&fList, cur); - free(cur); - } - VALGRIND_DESTROY_MEMPOOL(&fList); -} - -static void twdInitOnce(void *arg) -{ - epicsThreadId tid; - - tLock = epicsMutexMustCreate(); - mLock = epicsMutexMustCreate(); - fLock = epicsMutexMustCreate(); - ellInit(&fList); - VALGRIND_CREATE_MEMPOOL(&fList, 0, 0); - - twdCtl = twdctlRun; - loopEvent = epicsEventMustCreate(epicsEventEmpty); - exitEvent = epicsEventMustCreate(epicsEventEmpty); - - tid = epicsThreadCreate("taskwd", epicsThreadPriorityLow, - epicsThreadGetStackSize(epicsThreadStackSmall), - twdTask, NULL); - if (tid == 0) - cantProceed("Failed to spawn task watchdog thread\n"); - - epicsAtExit(twdShutdown, NULL); -} - -void taskwdInit(void) -{ - static epicsThreadOnceId twdOnceFlag = EPICS_THREAD_ONCE_INIT; - epicsThreadOnce(&twdOnceFlag, twdInitOnce, NULL); -} - - -/* For tasks to be monitored */ - -void taskwdInsert(epicsThreadId tid, TASKWDFUNC callback, void *usr) -{ - struct tNode *pt; - struct mNode *pm; - - taskwdInit(); - if (tid == 0) - tid = epicsThreadGetIdSelf(); - - pt = &allocNode()->t; - pt->tid = tid; - pt->callback = callback; - pt->usr = usr; - pt->suspended = FALSE; - - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs->insert) { - pm->funcs->insert(pm->usr, tid); - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - - epicsMutexMustLock(tLock); - ellAdd(&tList, (void *)pt); - epicsMutexUnlock(tLock); -} - -void taskwdRemove(epicsThreadId tid) -{ - struct tNode *pt; - struct mNode *pm; - char tName[40]; - - taskwdInit(); - - if (tid == 0) - tid = epicsThreadGetIdSelf(); - - epicsMutexMustLock(tLock); - pt = (struct tNode *)ellFirst(&tList); - while (pt != NULL) { - if (tid == pt->tid) { - ellDelete(&tList, (void *)pt); - epicsMutexUnlock(tLock); - freeNode((union twdNode *)pt); - - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs->remove) { - pm->funcs->remove(pm->usr, tid); - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - return; - } - pt = (struct tNode *)ellNext(&pt->node); - } - epicsMutexUnlock(tLock); - - epicsThreadGetName(tid, tName, sizeof(tName)); - errlogPrintf("taskwdRemove: Thread %s (%p) not registered!\n", - tName, (void *)tid); -} - - -/* Monitoring API */ - -void taskwdMonitorAdd(const taskwdMonitor *funcs, void *usr) -{ - struct mNode *pm; - - if (funcs == NULL) return; - - taskwdInit(); - - pm = &allocNode()->m; - pm->funcs = funcs; - pm->usr = usr; - - epicsMutexMustLock(mLock); - ellAdd(&mList, (void *)pm); - epicsMutexUnlock(mLock); -} - -void taskwdMonitorDel(const taskwdMonitor *funcs, void *usr) -{ - struct mNode *pm; - - if (funcs == NULL) return; - - taskwdInit(); - - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs == funcs && pm->usr == usr) { - ellDelete(&mList, (void *)pm); - freeNode((union twdNode *)pm); - epicsMutexUnlock(mLock); - return; - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - - errlogPrintf("taskwdMonitorDel: Unregistered!\n"); -} - - -/* Support old API for backwards compatibility */ - -static void anyNotify(void *usr, epicsThreadId tid, int suspended) -{ - struct aNode *pa = (struct aNode *)usr; - - if (suspended) { - pa->callback(pa->usr, tid); - } -} - -static taskwdMonitor anyFuncs = { - NULL, anyNotify, NULL -}; - -void taskwdAnyInsert(void *key, TASKWDANYFUNC callback, void *usr) -{ - struct mNode *pm; - struct aNode *pa; - - if (callback == NULL) return; - - taskwdInit(); - - pa = &allocNode()->a; - pa->key = key; - pa->callback = callback; - pa->usr = usr; - - pm = &allocNode()->m; - pm->funcs = &anyFuncs; - pm->usr = pa; - - epicsMutexMustLock(mLock); - ellAdd(&mList, (void *)pm); - epicsMutexUnlock(mLock); -} - -void taskwdAnyRemove(void *key) -{ - struct mNode *pm; - struct aNode *pa; - - taskwdInit(); - - epicsMutexMustLock(mLock); - pm = (struct mNode *)ellFirst(&mList); - while (pm) { - if (pm->funcs == &anyFuncs) { - pa = (struct aNode *)pm->usr; - if (pa->key == key) { - ellDelete(&mList, (void *)pm); - freeNode((union twdNode *)pa); - freeNode((union twdNode *)pm); - epicsMutexUnlock(mLock); - return; - } - } - pm = (struct mNode *)ellNext(&pm->node); - } - epicsMutexUnlock(mLock); - - errlogPrintf("taskwdAnyRemove: Unregistered key %p\n", key); -} - - -/* Report function */ - -epicsShareFunc void taskwdShow(int level) -{ - struct tNode *pt; - int mCount, fCount, tCount; - char tName[40]; - - epicsMutexMustLock(mLock); - mCount = ellCount(&mList); - epicsMutexUnlock(mLock); - - epicsMutexMustLock(fLock); - fCount = ellCount(&fList); - epicsMutexUnlock(fLock); - - epicsMutexMustLock(tLock); - tCount = ellCount(&tList); - printf("%d monitors, %d threads registered, %d free nodes\n", - mCount, tCount, fCount); - if (level) { - printf("%16.16s %9s %12s %12s %12s\n", - "THREAD NAME", "STATE", "EPICS TID", "CALLBACK", "USR ARG"); - pt = (struct tNode *)ellFirst(&tList); - while (pt != NULL) { - epicsThreadGetName(pt->tid, tName, sizeof(tName)); - printf("%16.16s %9s %12p %12p %12p\n", - tName, pt->suspended ? "Suspended" : "Ok ", - (void *)pt->tid, (void *)pt->callback, pt->usr); - pt = (struct tNode *)ellNext(&pt->node); - } - } - epicsMutexUnlock(tLock); -} - - -/* Free list management */ - -static union twdNode *newNode(void) -{ - union twdNode *pn; - - epicsMutexMustLock(fLock); - pn = (union twdNode *)ellGet(&fList); - if (pn) { - VALGRIND_MEMPOOL_FREE(&fList, pn); - } - epicsMutexUnlock(fLock); - if (!pn) - pn = calloc(1, sizeof(union twdNode)); - if (pn) - VALGRIND_MEMPOOL_ALLOC(&fList, pn, sizeof(*pn)); - return pn; -} - -static union twdNode *allocNode(void) -{ - union twdNode *pn = newNode(); - while (!pn) { - errlogPrintf("Thread taskwd suspending: out of memory\n"); - epicsThreadSuspendSelf(); - pn = newNode(); - } - return pn; -} - -static void freeNode(union twdNode *pn) -{ - VALGRIND_MEMPOOL_FREE(&fList, pn); - VALGRIND_MEMPOOL_ALLOC(&fList, pn, sizeof(ELLNODE)); - epicsMutexMustLock(fLock); - ellAdd(&fList, (void *)pn); - epicsMutexUnlock(fLock); -} diff --git a/src/libCom/taskwd/taskwd.h b/src/libCom/taskwd/taskwd.h deleted file mode 100644 index 4d5274d56..000000000 --- a/src/libCom/taskwd/taskwd.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* General purpose task watchdog */ -/* - * Original Author: Marty Kraimer - * Date: 07-18-91 -*/ - -#ifndef INC_taskwd_H -#define INC_taskwd_H - -#include "epicsThread.h" -#include "shareLib.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Initialization, optional */ -epicsShareFunc void taskwdInit(void); - - -/* For tasks to be monitored */ -typedef void (*TASKWDFUNC)(void *usr); - -epicsShareFunc void taskwdInsert(epicsThreadId tid, - TASKWDFUNC callback, void *usr); -epicsShareFunc void taskwdRemove(epicsThreadId tid); - - -/* Monitoring API */ -typedef struct { - void (*insert)(void *usr, epicsThreadId tid); - void (*notify)(void *usr, epicsThreadId tid, int suspended); - void (*remove)(void *usr, epicsThreadId tid); -} taskwdMonitor; - -epicsShareFunc void taskwdMonitorAdd(const taskwdMonitor *funcs, void *usr); -epicsShareFunc void taskwdMonitorDel(const taskwdMonitor *funcs, void *usr); - - -/* Old monitoring API, deprecated */ -typedef void (*TASKWDANYFUNC)(void *usr, epicsThreadId tid); - -epicsShareFunc void taskwdAnyInsert(void *key, - TASKWDANYFUNC callback, void *usr); -epicsShareFunc void taskwdAnyRemove(void *key); - - -/* Report function */ -epicsShareFunc void taskwdShow(int level); - - -#ifdef __cplusplus -} -#endif - -#endif /* INC_taskwd_H */ diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile deleted file mode 100755 index 04438854c..000000000 --- a/src/libCom/test/Makefile +++ /dev/null @@ -1,262 +0,0 @@ -#************************************************************************* -# Copyright (c) 2006 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../.. - -include $(TOP)/configure/CONFIG - -PROD_LIBS += Com -PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32 - -TESTPROD_HOST += epicsUnitTestTest -epicsUnitTestTest_SRCS += epicsUnitTestTest.c -# Not much point running this on vxWorks or RTEMS... -TESTS += epicsUnitTestTest - -TESTPROD_HOST += epicsTypesTest -epicsTypesTest_SRCS += epicsTypesTest.cpp -testHarness_SRCS += epicsTypesTest.cpp -TESTS += epicsTypesTest - -TESTPROD_HOST += epicsInlineTest -epicsInlineTest_SRCS += epicsInlineTest1.c -epicsInlineTest_SRCS += epicsInlineTest2.c -epicsInlineTest_SRCS += epicsInlineTest3.cpp -epicsInlineTest_SRCS += epicsInlineTest4.cpp -testHarness_SRCS += $(epicsInlineTest_SRCS) -TESTS += epicsInlineTest - -TESTPROD_HOST += epicsCalcTest -epicsCalcTest_SRCS += epicsCalcTest.cpp -testHarness_SRCS += epicsCalcTest.cpp -TESTS += epicsCalcTest - -TESTPROD_HOST += epicsAlgorithmTest -epicsAlgorithmTest_SRCS += epicsAlgorithmTest.cpp -testHarness_SRCS += epicsAlgorithmTest.cpp -TESTS += epicsAlgorithmTest - -TESTPROD_HOST += epicsMathTest -epicsMathTest_SRCS += epicsMathTest.c -testHarness_SRCS += epicsMathTest.c -TESTS += epicsMathTest - -TESTPROD_HOST += epicsMMIOTest -epicsMMIOTest_SRCS += epicsMMIOTest.c -epicsMMIOTest_SYS_LIBS_solaris = socket -epicsMMIOTest_SYS_LIBS_WIN32 = ws2_32 user32 -testHarness_SRCS += epicsMMIOTest.c -TESTS += epicsMMIOTest - -TESTPROD_HOST += epicsEllTest -epicsEllTest_SRCS += epicsEllTest.c -testHarness_SRCS += epicsEllTest.c -TESTS += epicsEllTest - -TESTPROD_HOST += epicsEnvTest -epicsEnvTest_SRCS += epicsEnvTest.c -testHarness_SRCS += epicsEnvTest.c -TESTS += epicsEnvTest - -TESTPROD_HOST += epicsErrlogTest -epicsErrlogTest_SRCS += epicsErrlogTest.c -epicsErrlogTest_SYS_LIBS_solaris = socket -epicsErrlogTest_SYS_LIBS_WIN32 = ws2_32 user32 -testHarness_SRCS += epicsErrlogTest.c -TESTS += epicsErrlogTest - -TESTPROD_HOST += epicsStdioTest -epicsStdioTest_SRCS += epicsStdioTest.c -testHarness_SRCS += epicsStdioTest.c -TESTS += epicsStdioTest - -TESTPROD_HOST += epicsStdlibTest -epicsStdlibTest_SRCS += epicsStdlibTest.c -testHarness_SRCS += epicsStdlibTest.c -TESTS += epicsStdlibTest - -TESTPROD_HOST += epicsSockResolveTest -epicsSockResolveTest_SRCS += epicsSockResolveTest.c -epicsSockResolveTest_SYS_LIBS_solaris = socket -epicsSockResolveTest_SYS_LIBS_WIN32 = ws2_32 user32 -testHarness_SRCS += epicsSockResolveTest.c -TESTS += epicsSockResolveTest - -TESTPROD_HOST += epicsStringTest -epicsStringTest_SRCS += epicsStringTest.c -testHarness_SRCS += epicsStringTest.c -TESTS += epicsStringTest - -TESTPROD_HOST += epicsTimeTest -epicsTimeTest_SRCS += epicsTimeTest.cpp -testHarness_SRCS += epicsTimeTest.cpp -TESTS += epicsTimeTest - -TESTPROD_HOST += epicsTimeZoneTest -epicsTimeZoneTest_SRCS += epicsTimeZoneTest.c -libComTestHarness_SRCS_RTEMS += epicsTimeZoneTest.c -TESTS += epicsTimeZoneTest - -TESTPROD_HOST += epicsThreadTest -epicsThreadTest_SRCS += epicsThreadTest.cpp -testHarness_SRCS += epicsThreadTest.cpp -TESTS += epicsThreadTest - -TESTPROD_HOST += epicsThreadOnceTest -epicsThreadOnceTest_SRCS += epicsThreadOnceTest.c -testHarness_SRCS += epicsThreadOnceTest.c -TESTS += epicsThreadOnceTest - -TESTPROD_HOST += epicsThreadPriorityTest -epicsThreadPriorityTest_SRCS += epicsThreadPriorityTest.cpp -testHarness_SRCS += epicsThreadPriorityTest.cpp -TESTS += epicsThreadPriorityTest - -TESTPROD_HOST += epicsThreadPrivateTest -epicsThreadPrivateTest_SRCS += epicsThreadPrivateTest.cpp -testHarness_SRCS += epicsThreadPrivateTest.cpp -TESTS += epicsThreadPrivateTest - -TESTPROD_HOST += epicsThreadHooksTest -epicsThreadHooksTest_SRCS += epicsThreadHooksTest.c -testHarness_SRCS += epicsThreadHooksTest.c -TESTS += epicsThreadHooksTest - -TESTPROD_HOST += epicsThreadPoolTest -epicsThreadPoolTest_SRCS += epicsThreadPoolTest.c -testHarness_SRCS += epicsThreadPoolTest.c -TESTS += epicsThreadPoolTest - -TESTPROD_HOST += epicsExitTest -epicsExitTest_SRCS += epicsExitTest.c -testHarness_SRCS += epicsExitTest.c -TESTS += epicsExitTest - -TESTPROD_HOST += epicsTimerTest -epicsTimerTest_SRCS += epicsTimerTest.cpp -testHarness_SRCS += epicsTimerTest.cpp -TESTS += epicsTimerTest - -TESTPROD_HOST += ringPointerTest -ringPointerTest_SRCS += ringPointerTest.c -testHarness_SRCS += ringPointerTest.c -TESTS += ringPointerTest - -TESTPROD_HOST += ringBytesTest -ringBytesTest_SRCS += ringBytesTest.c -testHarness_SRCS += ringBytesTest.c -TESTS += ringBytesTest - -TESTPROD_HOST += epicsEventTest -epicsEventTest_SRCS += epicsEventTest.cpp -testHarness_SRCS += epicsEventTest.cpp -TESTS += epicsEventTest - -TESTPROD_HOST += epicsMutexTest -epicsMutexTest_SRCS += epicsMutexTest.cpp -testHarness_SRCS += epicsMutexTest.cpp -TESTS += epicsMutexTest - -TESTPROD_HOST += epicsSpinTest -epicsSpinTest_SRCS += epicsSpinTest.c -testHarness_SRCS += epicsSpinTest.c -TESTS += epicsSpinTest - -TESTPROD_HOST += epicsAtomicTest -epicsAtomicTest_SRCS += epicsAtomicTest.cpp -testHarness_SRCS += epicsAtomicTest.cpp -TESTS += epicsAtomicTest - -TESTPROD_HOST += macDefExpandTest -macDefExpandTest_SRCS += macDefExpandTest.c -testHarness_SRCS += macDefExpandTest.c -TESTS += macDefExpandTest - -TESTPROD_HOST += cvtFastTest -cvtFastTest_SRCS += cvtFastTest.cpp -testHarness_SRCS += cvtFastTest.cpp -TESTS += cvtFastTest - -TESTPROD_HOST += macLibTest -macLibTest_SRCS += macLibTest.c -testHarness_SRCS += macLibTest.c -TESTS += macLibTest - -TESTPROD_HOST += taskwdTest -taskwdTest_SRCS += taskwdTest.c -testHarness_SRCS += taskwdTest.c -TESTS += taskwdTest - -TESTPROD_HOST += blockingSockTest -blockingSockTest_SRCS += blockingSockTest.cpp -testHarness_SRCS += blockingSockTest.cpp -# needed when its an object library build -blockingSockTest_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 -blockingSockTest_SYS_LIBS_solaris = socket -TESTS += blockingSockTest - -TESTPROD_HOST += epicsMessageQueueTest -epicsMessageQueueTest_SRCS += epicsMessageQueueTest.cpp -testHarness_SRCS += epicsMessageQueueTest.cpp -TESTS += epicsMessageQueueTest - -TESTPROD_HOST += epicsStackTraceTest -epicsStackTraceTest_SRCS += epicsStackTraceTest.c -testHarness_SRCS += epicsStackTraceTest.c -TESTS += epicsStackTraceTest - -TESTPROD_HOST += ipAddrToAsciiTest -ipAddrToAsciiTest_SRCS += ipAddrToAsciiTest.cpp -testHarness_SRCS += ipAddrToAsciiTest.cpp -TESTS += ipAddrToAsciiTest - -# The testHarness runs all the test programs in a known working order. -testHarness_SRCS += epicsRunLibComTests.c - -libComTestHarness_SRCS += $(testHarness_SRCS) -libComTestHarness_SRCS_RTEMS += rtemsTestHarness.c - -PROD_vxWorks = libComTestHarness -PROD_RTEMS += libComTestHarness - -TESTSPEC_vxWorks = libComTestHarness.munch; epicsRunLibComTests -TESTSPEC_RTEMS = libComTestHarness.boot; epicsRunLibComTests - -TESTSCRIPTS_HOST += $(TESTS:%=%.t) - - -# The following are not test programs, they measure performance. -# They should not be added to TESTS or to epicsRunLibComTests.c - -TESTPROD_HOST += epicsThreadPerform -epicsThreadPerform_SRCS += epicsThreadPerform.cpp -testHarness_SRCS += epicsThreadPerform.cpp - -TESTPROD_HOST += epicsMaxThreads -epicsMaxThreads_SRCS += epicsMaxThreads.c -testHarness_SRCS += epicsMaxThreads.c - -TESTPROD_HOST += buckTest -buckTest_SRCS += buckTest.c -testHarness_SRCS += buckTest.c - -#TESTPROD_HOST += fdmgrTest -fdmgrTest_SRCS += fdmgrTest.c -fdmgrTest_LIBS += ca -# FIXME: program never exits. - -TESTPROD_HOST += epicsAtomicPerform -epicsAtomicPerform_SRCS += epicsAtomicPerform.cpp -testHarness_SRCS += epicsAtomicPerform.cpp - -TESTPROD_HOST += cvtFastPerform -cvtFastPerform_SRCS += cvtFastPerform.cpp -testHarness_SRCS += cvtFastPerform.cpp - -include $(TOP)/configure/RULES - diff --git a/src/libCom/test/blockingSockTest.cpp b/src/libCom/test/blockingSockTest.cpp deleted file mode 100644 index 1a16bb9e6..000000000 --- a/src/libCom/test/blockingSockTest.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "osiSock.h" -#include "osiWireFormat.h" -#include "epicsThread.h" -#include "epicsSignal.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -union address { - struct sockaddr_in ia; - struct sockaddr sa; -}; - -class circuit { -public: - circuit ( SOCKET ); - void recvTest (); - void shutdown (); - void close (); - bool recvWakeupDetected () const; - bool sendWakeupDetected () const; - virtual const char * pName () = 0; -protected: - SOCKET sock; - epicsThreadId id; - bool recvWakeup; - bool sendWakeup; -protected: - virtual ~circuit() {} -}; - -class serverCircuit : public circuit { -public: - serverCircuit ( SOCKET ); -private: - const char * pName (); -}; - -class clientCircuit : public circuit { -public: - clientCircuit ( const address & ); -private: - const char * pName (); -}; - -class server { -public: - server ( const address & ); - void start (); - void daemon (); - void stop (); - address addr () const; -protected: - address srvaddr; - SOCKET sock; - epicsThreadId id; - bool exit; -}; - -circuit::circuit ( SOCKET sockIn ) : - sock ( sockIn ), - id ( 0 ), - recvWakeup ( false ), - sendWakeup ( false ) -{ - testOk ( this->sock != INVALID_SOCKET, "Socket valid" ); -} - -bool circuit::recvWakeupDetected () const -{ - return this->recvWakeup; -} - -bool circuit::sendWakeupDetected () const -{ - return this->sendWakeup; -} - -void circuit::shutdown () -{ - int status = ::shutdown ( this->sock, SHUT_RDWR ); - testOk ( status == 0, "Shutdown() returned Ok" ); -} - -void circuit::close () -{ - epicsSocketDestroy ( this->sock ); -} - -void circuit::recvTest () -{ - char buf [1]; - while ( true ) { - int status = recv ( this->sock, - buf, (int) sizeof ( buf ), 0 ); - if ( status == 0 ) { - testDiag ( "%s was disconnected", this->pName () ); - this->recvWakeup = true; - break; - } - else if ( status > 0 ) { - testDiag ( "%s received %i characters", this->pName (), status ); - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - testDiag ( "%s socket recv() error was \"%s\"", - this->pName (), sockErrBuf ); - this->recvWakeup = true; - break; - } - } -} - -extern "C" void socketRecvTest ( void * pParm ) -{ - circuit * pCir = reinterpret_cast < circuit * > ( pParm ); - pCir->recvTest (); -} - -clientCircuit::clientCircuit ( const address & addrIn ) : - circuit ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) -{ - address tmpAddr = addrIn; - int status = ::connect ( - this->sock, & tmpAddr.sa, sizeof ( tmpAddr ) ); - testOk ( status == 0, "Client end connected" ); - - circuit * pCir = this; - this->id = epicsThreadCreate ( - "client circuit", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - socketRecvTest, pCir ); - testOk ( this->id != 0, "Client thread created" ); -} - - -const char * clientCircuit::pName () -{ - return "client circuit"; -} - -extern "C" void serverDaemon ( void * pParam ) { - server * pSrv = reinterpret_cast < server * > ( pParam ); - pSrv->daemon (); -} - -server::server ( const address & addrIn ) : - srvaddr ( addrIn ), - sock ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ), - id ( 0 ), exit ( false ) -{ - testOk ( this->sock != INVALID_SOCKET, "Server socket valid" ); - - // setup server side - osiSocklen_t slen = sizeof ( this->srvaddr ); - int status = bind ( this->sock, & this->srvaddr.sa, slen ); - if ( status ) { - testDiag ( "bind to server socket failed, status = %d", status ); - } - if ( getsockname(this->sock, & this->srvaddr.sa, & slen) != 0 ) { - testAbort ( "Failed to read socket address" ); - } - status = listen ( this->sock, 10 ); - testOk ( status == 0, "Server socket listening" ); -} - -void server::start () -{ - this->id = epicsThreadCreate ( - "server daemon", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - serverDaemon, this ); - testOk ( this->id != 0, "Server thread created" ); -} - -void server::daemon () -{ - while ( ! this->exit ) { - // accept client side - address addr; - osiSocklen_t addressSize = sizeof ( addr ); - SOCKET ns = accept ( this->sock, - & addr.sa, & addressSize ); - if ( this->exit ) - break; - testOk ( ns != INVALID_SOCKET, "Accepted socket valid" ); - circuit * pCir = new serverCircuit ( ns ); - testOk ( pCir != 0, "Server circuit created" ); - } -} - -void server::stop () -{ - this->exit = true; - epicsSocketDestroy ( this->sock ); -} - -address server::addr () const -{ - return this->srvaddr; -} - -serverCircuit::serverCircuit ( SOCKET sockIn ) : - circuit ( sockIn ) -{ - circuit * pCir = this; - epicsThreadId threadId = epicsThreadCreate ( - "server circuit", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - socketRecvTest, pCir ); - testOk ( threadId != 0, "Server circuit thread created" ); -} - -const char * serverCircuit::pName () -{ - return "server circuit"; -} - -static const char *mechName(int mech) -{ - static const struct { - int mech; - const char *name; - } mechs[] = { - {-1, "Unknown shutdown mechanism" }, - {esscimqi_socketCloseRequired, "esscimqi_socketCloseRequired" }, - {esscimqi_socketBothShutdownRequired, "esscimqi_socketBothShutdownRequired" }, - {esscimqi_socketSigAlarmRequired, "esscimqi_socketSigAlarmRequired" } - }; - - for (unsigned i=0; i < (sizeof(mechs) / sizeof(mechs[0])); ++i) { - if (mech == mechs[i].mech) - return mechs[i].name; - } - return "Unknown shutdown mechanism value"; -} - -MAIN(blockingSockTest) -{ - testPlan(13); - osiSockAttach(); - - address addr; - memset ( (char *) & addr, 0, sizeof ( addr ) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - addr.ia.sin_port = 0; - - server srv ( addr ); - srv.start (); - addr = srv.addr (); - clientCircuit client ( addr ); - - epicsThreadSleep ( 1.0 ); - testOk ( ! client.recvWakeupDetected (), "Client is asleep" ); - - testDiag("Trying Shutdown mechanism"); - client.shutdown (); - epicsThreadSleep ( 1.0 ); - int mech = -1; - if ( client.recvWakeupDetected () ) { - mech = esscimqi_socketBothShutdownRequired; - testDiag("Shutdown succeeded"); - } - else { - testDiag("Trying Close mechanism"); - client.close (); - epicsThreadSleep ( 1.0 ); - if ( client.recvWakeupDetected () ) { - mech = esscimqi_socketCloseRequired; - testDiag("Close succeeded"); - } - } - testDiag("This OS behaves like \"%s\".", mechName(mech)); - - int query = epicsSocketSystemCallInterruptMechanismQuery (); - if (! testOk(mech == query, "Declared mechanism works") ) - testDiag("epicsSocketSystemCallInterruptMechanismQuery returned \"%s\"", - mechName(query)); - - srv.stop (); - epicsThreadSleep ( 1.0 ); - - osiSockRelease(); - return testDone(); -} - diff --git a/src/libCom/test/buckTest.c b/src/libCom/test/buckTest.c deleted file mode 100644 index 6fc34954e..000000000 --- a/src/libCom/test/buckTest.c +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "epicsTime.h" -#include "epicsAssert.h" -#include "bucketLib.h" -#include "testMain.h" - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -MAIN(buckTest) -{ - unsigned id1; - unsigned id2; - char * pValSave1; - char * pValSave2; - int s; - BUCKET * pb; - char * pVal; - unsigned i; - epicsTimeStamp start, finish; - double duration; - const int LOOPS = 500000; - - pb = bucketCreate(8); - if (!pb) { - return -1; - } - - id1 = 0x1000a432; - pValSave1 = "fred"; - s = bucketAddItemUnsignedId(pb, &id1, pValSave1); - verify (s == S_bucket_success); - - pValSave2 = "jane"; - id2 = 0x0000a432; - s = bucketAddItemUnsignedId(pb, &id2, pValSave2); - verify (s == S_bucket_success); - - epicsTimeGetCurrent(&start); - for (i=0; i -#include -#include -#include -#include -#include -#include - -#include "epicsStdio.h" -#include "cvtFast.h" -#include "epicsTime.h" -#include "testMain.h" - -using namespace std; - -class PerfConverter { -public: - virtual const char * name(void) const = 0; - virtual int maxPrecision(void) const = 0; - virtual void target (double srcD, float srcF, char *dst, size_t len, int prec) const = 0; - virtual void add(int prec, double elapsed) = 0; - virtual double total(int prec) = 0; - virtual ~PerfConverter () {}; -}; - -class Perf { -public: - Perf ( int maxConverters ); - virtual ~Perf (); - void addConverter( PerfConverter * c ); - void execute (int count, bool verbose); - void report (const char *title, int count); -protected: - static unsigned const nUnrolled = 10; - static const unsigned uSecPerSec = 1000000; - static unsigned const nIterations = 10000; - - const int maxConverters; - PerfConverter **converters; - int nConverters; - int maxPrecision; - bool verbose; - - void measure ( double srcD, float srcF, int prec ); - -private: - Perf ( const Perf & ); - Perf & operator = ( Perf & ); -}; - -Perf :: Perf ( int maxConverters_ ) : - maxConverters ( maxConverters_ ), - converters ( new PerfConverter * [ maxConverters_ ] ), - nConverters ( 0 ), - maxPrecision ( 0 ) -{ -} - -Perf :: ~Perf () -{ - for ( int j = 0; j < nConverters; j++ ) - delete converters[ j ]; - - delete [] converters; -} - -void Perf :: addConverter(PerfConverter *c) -{ - if ( nConverters >= maxConverters ) - throw std :: runtime_error ( "Too many converters" ); - - converters[ nConverters++ ] = c; - - int prec = c->maxPrecision(); - if ( prec > maxPrecision ) - maxPrecision = prec; -} - -void Perf :: execute (const int count, bool verbose_) -{ - verbose = verbose_; - - for ( int i = 0; i < count; i++ ) { - double srcDbl = rand (); - srcDbl /= (RAND_MAX + 1.0); - srcDbl *= 20.0; - srcDbl -= 10.0; - float srcFlt = (float) srcDbl; - - for ( int prec = 0; prec <= maxPrecision; prec++ ) { - measure (srcFlt, srcDbl, prec); - } - } - report ( "Small numbers, -10..+10", count ); - - for ( int i = 0; i < count; i++ ) { - double mVal = rand (); - mVal /= (RAND_MAX + 1.0); - double eVal = rand (); - eVal /= (RAND_MAX + 1.0); - - double dVal = eVal; - dVal *= FLT_MAX_EXP - FLT_MIN_EXP; - dVal += FLT_MIN_EXP; - int dEVal = static_cast < int > ( dVal + 0.5 ); - double srcDbl = ldexp ( mVal, dEVal ); - float srcFlt = (float) srcDbl; - - for ( int prec = 0; prec <= maxPrecision; prec++ ) { - measure (srcFlt, srcDbl, prec); - } - } - report ( "Random mantissa+exponent", count ); -} - -void Perf :: report (const char *title, const int count) -{ - printf( "\n%s\n\nprec\t", title ); - for ( int j = 0; j < nConverters; j++ ) - printf( "%-16s ", converters[j]->name() ); - - for (int prec = 0; prec <= maxPrecision; prec++ ) { - printf( "\n %2d\t", prec ); - for (int j = 0; j < nConverters; j++ ) { - PerfConverter *c = converters[j]; - if (prec > c->maxPrecision()) - printf( "%11s ", "-" ); - else { - printf( "%11.9f sec ", c->total(prec) / count ); - } - } - } - printf( "\n\n" ); -} - -void Perf :: measure (double srcD, float srcF, int prec) -{ - char buf[40]; - - for ( int j = 0; j < nConverters; j++ ) { - PerfConverter *c = converters[j]; - - if (prec > c->maxPrecision()) - continue; - - std::memset(buf, 0, sizeof(buf)); - - epicsTime beg = epicsTime :: getCurrent (); - for ( unsigned i = 0; i < nIterations; i++ ) { - c->target (srcD, srcF, buf, sizeof(buf) - 1, prec); - } - epicsTime end = epicsTime :: getCurrent (); - - double elapsed = end - beg; - elapsed /= nIterations * nUnrolled; - c->add( prec, elapsed ); - - if (verbose) - printf ( "%17s: %11.9f sec, prec=%2i '%s'\n", - c->name (), elapsed, prec, buf ); - } -} - - -// Conversions to be measured - -class PerfCvtFastFloat : public PerfConverter { - static const int digits = 12; -public: - PerfCvtFastFloat () - { - for (int i = 0; i <= digits; i++) - measured[i] = 0; // Some targets seem to need this - } - int maxPrecision (void) const { return digits; } - const char *name (void) const { return "cvtFloatToString"; } - void target (double srcD, float srcF, char *dst, size_t len, int prec) const - { - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - cvtFloatToString ( srcF, dst, prec ); - } - void add (int prec, double elapsed) { measured[prec] += elapsed; } - double total (int prec) { - double total = measured[prec]; - measured[prec] = 0; - return total; - } -private: - double measured[digits+1]; -}; - - -class PerfCvtFastDouble : public PerfConverter { - static const int digits = 17; -public: - PerfCvtFastDouble () - { - for (int i = 0; i <= digits; i++) - measured[i] = 0; // Some targets seem to need this - } - int maxPrecision (void) const { return digits; } - const char *name (void) const { return "cvtDoubleToString"; } - void target (double srcD, float srcF, char *dst, size_t len, int prec) const - { - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - cvtDoubleToString ( srcD, dst, prec ); - } - void add(int prec, double elapsed) { measured[prec] += elapsed; } - double total (int prec) { - double total = measured[prec]; - measured[prec] = 0; - return total; - } -private: - double measured[digits+1]; -}; - - -class PerfSNPrintf : public PerfConverter { - static const int digits = 17; -public: - PerfSNPrintf () - { - for (int i = 0; i <= digits; i++) - measured[i] = 0; // Some targets seem to need this - } - int maxPrecision (void) const { return digits; } - const char *name (void) const { return "epicsSnprintf"; } - void target (double srcD, float srcF, char *dst, size_t len, int prec) const - { - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - epicsSnprintf ( dst, len, "%.*g", prec, srcD ); - } - void add(int prec, double elapsed) { measured[prec] += elapsed; } - double total (int prec) { - double total = measured[prec]; - measured[prec] = 0; - return total; - } -private: - double measured[digits+1]; -}; - - -// This is a quick-and-dirty std::streambuf converter that writes directly -// into the output buffer. Performance is slower than epicsSnprintf(). - -struct membuf: public std::streambuf { - membuf(char *array, size_t size) { - this->setp(array, array + size - 1); - } -}; - -struct omemstream: virtual membuf, std::ostream { - omemstream(char *array, size_t size): - membuf(array, size), - std::ostream(this) { - } -}; - -static void ossConvertD(char *dst, size_t len, int prec, double src) { - omemstream oss(dst, len); - oss.precision(prec); - oss << src << ends; -} - -class PerfStreamBuf : public PerfConverter { - static const int digits = 17; -public: - PerfStreamBuf () - { - for (int i = 0; i <= digits; i++) - measured[i] = 0; // Some targets seem to need this - } - int maxPrecision (void) const { return digits; } - const char *name (void) const { return "std::streambuf"; } - void target (double srcD, float srcF, char *dst, size_t len, int prec) const - { - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - ossConvertD ( dst, len, prec, srcD ); - } - void add(int prec, double elapsed) { measured[prec] += elapsed; } - double total (int prec) { - double total = measured[prec]; - measured[prec] = 0; - return total; - } -private: - double measured[digits+1]; -}; - - -MAIN(cvtFastPerform) -{ - Perf t(4); - - t.addConverter( new PerfCvtFastFloat ); - t.addConverter( new PerfCvtFastDouble ); - t.addConverter( new PerfSNPrintf ); - t.addConverter( new PerfStreamBuf ); - - // The parameter to execute() below are: - // count = number of different random numbers to measure - // verbose = whether to display individual measurements - -#ifdef vxWorks - t.execute (3, true); // Slow... -#else - t.execute (5, false); -#endif - - return 0; -} diff --git a/src/libCom/test/cvtFastTest.c b/src/libCom/test/cvtFastTest.c deleted file mode 100644 index ac853ecc3..000000000 --- a/src/libCom/test/cvtFastTest.c +++ /dev/null @@ -1,459 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* cvtFastTest.c - * - * Test the string converters in libCom/cvtFast/cvtFast.c - * - * To Do: Test Char/Uchar/Short/Ushort/Long/Ulong versions - */ - -#include -#include -#include - -#include "epicsUnitTest.h" -#include "cvtFast.h" -#include "epicsStdlib.h" -#include "testMain.h" - -#define tryIString(typ, lit, siz) \ - len = cvt##typ##ToString(lit, buf); \ - testOk(len == siz, "cvt"#typ"ToString(" #lit ") == " #siz " (%u) -> \"%s\"", (unsigned)len, buf); \ - status = epicsParse##typ(buf, &val_##typ, 10, NULL); \ - testOk(!status, "epicsParse"#typ"('%s') OK", buf); \ - testOk(val_##typ == lit, #lit " => '%s'", buf); - -#define tryFString(typ, lit, prec, siz) \ - len = cvt##typ##ToString(lit, buf, prec); \ - testOk(len == siz, "cvt"#typ"ToString(" #lit ", %d) == " #siz " (%u) -> \"%s\"", prec, (unsigned)len, buf); \ - status = epicsParse##typ(buf, &val_##typ, NULL); \ - testOk(!status, "epicsParse"#typ"('%s') OK", buf); \ - testOk(fabs(val_##typ - lit) < 0.5 * pow(10, -prec), #lit " => '%s'", buf); - - -MAIN(cvtFastTest) -{ - char buf[80]; - size_t len; - long status; - epicsUInt32 val_UInt32; - epicsInt32 val_Int32; - epicsUInt64 val_UInt64; - epicsInt64 val_Int64; - epicsFloat32 val_Float; - epicsFloat64 val_Double; - -#ifdef _WIN32 -#if (defined(_MSC_VER) && _MSC_VER < 1900) || \ - (defined(_MINGW) && defined(_TWO_DIGIT_EXPONENT)) - _set_output_format(_TWO_DIGIT_EXPONENT); -#endif -#endif - - testPlan(1062); - - /* Arguments: type, value, num chars */ - testDiag("------------------------------------------------------"); - testDiag("** Positive Int32 **"); - tryIString(Int32, 0, 1); - tryIString(Int32, 1, 1); - tryIString(Int32, 10, 2); - tryIString(Int32, 100, 3); - tryIString(Int32, 254, 3); - tryIString(Int32, 255, 3); - tryIString(Int32, 256, 3); - tryIString(Int32, 257, 3); - tryIString(Int32, 1000, 4); - tryIString(Int32, 10000, 5); - tryIString(Int32, 32766, 5); - tryIString(Int32, 32767, 5); - tryIString(Int32, 32768, 5); - tryIString(Int32, 32769, 5); - tryIString(Int32, 65534, 5); - tryIString(Int32, 65535, 5); - tryIString(Int32, 65536, 5); - tryIString(Int32, 65537, 5); - tryIString(Int32, 2147483646, 10); - tryIString(Int32, 2147483647, 10); - - testDiag("------------------------------------------------------"); - testDiag("** Negative Int32 **"); - tryIString(Int32, -1, 2); - tryIString(Int32, -10, 3); - tryIString(Int32, -100, 4); - tryIString(Int32, -254, 4); - tryIString(Int32, -255, 4); - tryIString(Int32, -256, 4); - tryIString(Int32, -257, 4); - tryIString(Int32, -1000, 5); - tryIString(Int32, -10000, 6); - tryIString(Int32, -32766, 6); - tryIString(Int32, -32767, 6); - tryIString(Int32, -32768, 6); - tryIString(Int32, -32769, 6); - tryIString(Int32, -65534, 6); - tryIString(Int32, -65535, 6); - tryIString(Int32, -65536, 6); - tryIString(Int32, -65537, 6); - tryIString(Int32, -2147483647, 11); - tryIString(Int32, -2147483648LL, 11); - - testDiag("------------------------------------------------------"); - testDiag("** UInt32 **"); - tryIString(UInt32, 0, 1); - tryIString(UInt32, 1, 1); - tryIString(UInt32, 10, 2); - tryIString(UInt32, 100, 3); - tryIString(UInt32, 254, 3); - tryIString(UInt32, 255, 3); - tryIString(UInt32, 256, 3); - tryIString(UInt32, 257, 3); - tryIString(UInt32, 1000, 4); - tryIString(UInt32, 10000, 5); - tryIString(UInt32, 32766, 5); - tryIString(UInt32, 32767, 5); - tryIString(UInt32, 32768, 5); - tryIString(UInt32, 32769, 5); - tryIString(UInt32, 65534, 5); - tryIString(UInt32, 65535, 5); - tryIString(UInt32, 65536, 5); - tryIString(UInt32, 65537, 5); - tryIString(UInt32, 2147483646ULL, 10); - tryIString(UInt32, 2147483647ULL, 10); - tryIString(UInt32, 2147483648ULL, 10); - tryIString(UInt32, 4294967294ULL, 10); - tryIString(UInt32, 4294967295ULL, 10); - - testDiag("------------------------------------------------------"); - testDiag("** Positive Int64 **"); - tryIString(Int64, 0, 1); - tryIString(Int64, 1, 1); - tryIString(Int64, 10, 2); - tryIString(Int64, 100, 3); - tryIString(Int64, 254, 3); - tryIString(Int64, 255, 3); - tryIString(Int64, 256, 3); - tryIString(Int64, 257, 3); - tryIString(Int64, 1000, 4); - tryIString(Int64, 10000, 5); - tryIString(Int64, 32766, 5); - tryIString(Int64, 32767, 5); - tryIString(Int64, 32768, 5); - tryIString(Int64, 32769, 5); - tryIString(Int64, 65534, 5); - tryIString(Int64, 65535, 5); - tryIString(Int64, 65536, 5); - tryIString(Int64, 65537, 5); - tryIString(Int64, 2147483646, 10); - tryIString(Int64, 2147483647, 10); - tryIString(Int64, 2147483648LL, 10); - tryIString(Int64, 9223372036854775806LL, 19); - tryIString(Int64, 9223372036854775807LL, 19); - - testDiag("------------------------------------------------------"); - testDiag("** Negative Int64 **"); - tryIString(Int64, -1, 2); - tryIString(Int64, -10, 3); - tryIString(Int64, -100, 4); - tryIString(Int64, -254, 4); - tryIString(Int64, -255, 4); - tryIString(Int64, -256, 4); - tryIString(Int64, -257, 4); - tryIString(Int64, -1000, 5); - tryIString(Int64, -10000, 6); - tryIString(Int64, -32766, 6); - tryIString(Int64, -32767, 6); - tryIString(Int64, -32768, 6); - tryIString(Int64, -32769, 6); - tryIString(Int64, -65534, 6); - tryIString(Int64, -65535, 6); - tryIString(Int64, -65536, 6); - tryIString(Int64, -65537, 6); - tryIString(Int64, -2147483647, 11); - tryIString(Int64, -2147483648LL, 11); - tryIString(Int64, -2147483649LL, 11); - tryIString(Int64, -9223372036854775806LL, 20); - tryIString(Int64, -9223372036854775807LL, 20); - tryIString(Int64, -9223372036854775807LL-1, 20); - - testDiag("------------------------------------------------------"); - testDiag("** UInt64 **"); - tryIString(UInt64, 0, 1); - tryIString(UInt64, 1, 1); - tryIString(UInt64, 10, 2); - tryIString(UInt64, 100, 3); - tryIString(UInt64, 254, 3); - tryIString(UInt64, 255, 3); - tryIString(UInt64, 256, 3); - tryIString(UInt64, 257, 3); - tryIString(UInt64, 1000, 4); - tryIString(UInt64, 10000, 5); - tryIString(UInt64, 32766, 5); - tryIString(UInt64, 32767, 5); - tryIString(UInt64, 32768, 5); - tryIString(UInt64, 32769, 5); - tryIString(UInt64, 65534, 5); - tryIString(UInt64, 65535, 5); - tryIString(UInt64, 65536, 5); - tryIString(UInt64, 65537, 5); - tryIString(UInt64, 2147483646, 10); - tryIString(UInt64, 2147483647, 10); - tryIString(UInt64, 2147483648U, 10); - tryIString(UInt64, 2147483649U, 10); - tryIString(UInt64, 4294967294U, 10); - tryIString(UInt64, 4294967295U, 10); - tryIString(UInt64, 4294967296ULL, 10); - tryIString(UInt64, 4294967297ULL, 10); - tryIString(UInt64, 9223372036854775806ULL, 19); - tryIString(UInt64, 9223372036854775807ULL, 19); - tryIString(UInt64, 9223372036854775808ULL, 19); - tryIString(UInt64, 18446744073709551614ULL, 20); - tryIString(UInt64, 18446744073709551615ULL, 20); - - /* Arguments: type, value, precision, num chars */ - testDiag("------------------------------------------------------"); - testDiag("** Positive Float fixed-point **"); - tryFString(Float, 0, 0, 1); - tryFString(Float, 0, 1, 3); - tryFString(Float, 0, 2, 4); - tryFString(Float, 0, 3, 5); - tryFString(Float, 0, 4, 6); - tryFString(Float, 0, 5, 7); - tryFString(Float, 0, 6, 8); - tryFString(Float, 0, 7, 9); - tryFString(Float, 0, 8, 10); - tryFString(Float, FLT_MIN, 0, 1); - tryFString(Float, FLT_MIN, 1, 3); - tryFString(Float, FLT_MIN, 2, 4); - tryFString(Float, FLT_MIN, 3, 5); - tryFString(Float, FLT_MIN, 4, 6); - tryFString(Float, FLT_MIN, 5, 7); - tryFString(Float, FLT_MIN, 6, 8); - tryFString(Float, FLT_MIN, 7, 9); - tryFString(Float, FLT_MIN, 8, 10); - tryFString(Float, 0.000000004999999, 8, 10); - tryFString(Float, 0.000000005000001, 8, 10); - tryFString(Float, 0.00000004999999, 7, 9); - tryFString(Float, 0.00000005000001, 7, 9); - tryFString(Float, 0.0000004999999, 6, 8); - tryFString(Float, 0.0000005000001, 6, 8); - tryFString(Float, 0.000004999999, 5, 7); - tryFString(Float, 0.000005000001, 5, 7); - tryFString(Float, 0.00004999999, 4, 6); - tryFString(Float, 0.00005000001, 4, 6); - tryFString(Float, 0.0004999999, 3, 5); - tryFString(Float, 0.0005000001, 3, 5); - tryFString(Float, 0.004999999, 2, 4); - tryFString(Float, 0.005000001, 2, 4); - tryFString(Float, 0.04999999, 1, 3); - tryFString(Float, 0.05000001, 1, 3); - tryFString(Float, 0.4999999, 0, 1); - tryFString(Float, 0.5000001, 0, 1); - tryFString(Float, 1, 0, 1); - tryFString(Float, 1, 1, 3); - tryFString(Float, 1, 2, 4); - tryFString(Float, 1, 3, 5); - tryFString(Float, 1, 4, 6); - tryFString(Float, 1, 5, 7); - tryFString(Float, 1, 6, 8); - tryFString(Float, 1, 7, 9); - tryFString(Float, 1, 8, 10); - tryFString(Float, 1.0500001, 1, 3); - tryFString(Float, 1.1, 1, 3); - tryFString(Float, 1.1499999, 1, 3); - tryFString(Float, 9.5000001, 0, 2); - tryFString(Float, 10, 0, 2); - tryFString(Float, 10, 1, 4); - tryFString(Float, 10, 8, 11); - tryFString(Float, 100, 0, 3); - tryFString(Float, 100, 1, 5); - tryFString(Float, 100, 8, 12); - tryFString(Float, 1000, 0, 4); - tryFString(Float, 1000, 1, 6); - tryFString(Float, 1000, 8, 13); - tryFString(Float, 10000, 0, 5); - tryFString(Float, 10000, 1, 7); - tryFString(Float, 10000, 8, 14); - tryFString(Float, 100000, 0, 6); - tryFString(Float, 100000, 1, 8); - tryFString(Float, 100000, 8, 15); - tryFString(Float, 1000000, 0, 7); - tryFString(Float, 1000000, 1, 9); - tryFString(Float, 1000000, 8, 16); - tryFString(Float, 10000000, 0, 8); - tryFString(Float, 10000000, 1, 10); - tryFString(Float, 10000000, 8, 17); - - testDiag("------------------------------------------------------"); - testDiag("** Negative Float fixed-point **"); - tryFString(Float, -FLT_MIN, 0, 2); - tryFString(Float, -FLT_MIN, 1, 4); - tryFString(Float, -FLT_MIN, 8, 11); - tryFString(Float, -1, 0, 2); - tryFString(Float, -1, 1, 4); - tryFString(Float, -1, 8, 11); - tryFString(Float, -1.0500001, 1, 4); - tryFString(Float, -1.1, 1, 4); - tryFString(Float, -1.1499999, 1, 4); - tryFString(Float, -9.5000001, 0, 3); - tryFString(Float, -10, 0, 3); - tryFString(Float, -10, 1, 5); - tryFString(Float, -10, 8, 12); - tryFString(Float, -100, 0, 4); - tryFString(Float, -100, 1, 6); - tryFString(Float, -100, 8, 13); - tryFString(Float, -1000, 0, 5); - tryFString(Float, -1000, 1, 7); - tryFString(Float, -1000, 8, 14); - tryFString(Float, -10000, 0, 6); - tryFString(Float, -10000, 1, 8); - tryFString(Float, -10000, 8, 15); - tryFString(Float, -100000, 0, 7); - tryFString(Float, -100000, 1, 9); - tryFString(Float, -100000, 8, 16); - tryFString(Float, -1000000, 0, 8); - tryFString(Float, -1000000, 1, 10); - tryFString(Float, -1000000, 8, 17); - tryFString(Float, -10000000, 0, 9); - tryFString(Float, -10000000, 1, 11); - tryFString(Float, -10000000, 8, 18); - - /* - * Values > 1e7 trigger the %e format. - */ - testDiag("------------------------------------------------------"); - testDiag("** Positive Float scientific **"); - tryFString(Float, 1e+08, 0, 6); - tryFString(Float, 1e+08, 1, 7); - tryFString(Float, 1e+08, 2, 8); - tryFString(Float, 1e+08, 3, 9); - tryFString(Float, 1e+08, 4, 10); - tryFString(Float, 1e+08, 5, 11); - tryFString(Float, 1e+08, 6, 12); - - testDiag("------------------------------------------------------"); - testDiag("** Positive Double fixed-point **"); - tryFString(Double, 0, 0, 1); - tryFString(Double, 0, 1, 3); - tryFString(Double, 0, 2, 4); - tryFString(Double, 0, 3, 5); - tryFString(Double, 0, 4, 6); - tryFString(Double, 0, 5, 7); - tryFString(Double, 0, 6, 8); - tryFString(Double, 0, 7, 9); - tryFString(Double, 0, 8, 10); - tryFString(Double, DBL_MIN, 0, 1); - tryFString(Double, DBL_MIN, 1, 3); - tryFString(Double, DBL_MIN, 2, 4); - tryFString(Double, DBL_MIN, 3, 5); - tryFString(Double, DBL_MIN, 4, 6); - tryFString(Double, DBL_MIN, 5, 7); - tryFString(Double, DBL_MIN, 6, 8); - tryFString(Double, DBL_MIN, 7, 9); - tryFString(Double, DBL_MIN, 8, 10); - tryFString(Double, 0.000000004999999, 8, 10); - tryFString(Double, 0.000000005000001, 8, 10); - tryFString(Double, 0.00000004999999, 7, 9); - tryFString(Double, 0.00000005000001, 7, 9); - tryFString(Double, 0.0000004999999, 6, 8); - tryFString(Double, 0.0000005000001, 6, 8); - tryFString(Double, 0.000004999999, 5, 7); - tryFString(Double, 0.000005000001, 5, 7); - tryFString(Double, 0.00004999999, 4, 6); - tryFString(Double, 0.00005000001, 4, 6); - tryFString(Double, 0.0004999999, 3, 5); - tryFString(Double, 0.0005000001, 3, 5); - tryFString(Double, 0.004999999, 2, 4); - tryFString(Double, 0.005000001, 2, 4); - tryFString(Double, 0.04999999, 1, 3); - tryFString(Double, 0.05000001, 1, 3); - tryFString(Double, 0.4999999, 0, 1); - tryFString(Double, 0.5000001, 0, 1); - tryFString(Double, 1, 0, 1); - tryFString(Double, 1, 1, 3); - tryFString(Double, 1, 2, 4); - tryFString(Double, 1, 3, 5); - tryFString(Double, 1, 4, 6); - tryFString(Double, 1, 5, 7); - tryFString(Double, 1, 6, 8); - tryFString(Double, 1, 7, 9); - tryFString(Double, 1, 8, 10); - tryFString(Double, 1.0500001, 1, 3); - tryFString(Double, 1.1, 1, 3); - tryFString(Double, 1.1499999, 1, 3); - tryFString(Double, 9.5000001, 0, 2); - tryFString(Double, 10, 0, 2); - tryFString(Double, 10, 1, 4); - tryFString(Double, 10, 8, 11); - tryFString(Double, 100, 0, 3); - tryFString(Double, 100, 1, 5); - tryFString(Double, 100, 8, 12); - tryFString(Double, 1000, 0, 4); - tryFString(Double, 1000, 1, 6); - tryFString(Double, 1000, 8, 13); - tryFString(Double, 10000, 0, 5); - tryFString(Double, 10000, 1, 7); - tryFString(Double, 10000, 8, 14); - tryFString(Double, 100000, 0, 6); - tryFString(Double, 100000, 1, 8); - tryFString(Double, 100000, 8, 15); - tryFString(Double, 1000000, 0, 7); - tryFString(Double, 1000000, 1, 9); - tryFString(Double, 1000000, 8, 16); - tryFString(Double, 10000000, 0, 8); - tryFString(Double, 10000000, 1, 10); - tryFString(Double, 10000000, 8, 17); - - testDiag("------------------------------------------------------"); - testDiag("** Negative Double fixed-point **"); - tryFString(Double, -DBL_MIN, 0, 2); - tryFString(Double, -DBL_MIN, 1, 4); - tryFString(Double, -DBL_MIN, 8, 11); - tryFString(Double, -1, 0, 2); - tryFString(Double, -1, 1, 4); - tryFString(Double, -1, 8, 11); - tryFString(Double, -1.0500001, 1, 4); - tryFString(Double, -1.1, 1, 4); - tryFString(Double, -1.1499999, 1, 4); - tryFString(Double, -9.5000001, 0, 3); - tryFString(Double, -10, 0, 3); - tryFString(Double, -10, 1, 5); - tryFString(Double, -10, 8, 12); - tryFString(Double, -100, 0, 4); - tryFString(Double, -100, 1, 6); - tryFString(Double, -100, 8, 13); - tryFString(Double, -1000, 0, 5); - tryFString(Double, -1000, 1, 7); - tryFString(Double, -1000, 8, 14); - tryFString(Double, -10000, 0, 6); - tryFString(Double, -10000, 1, 8); - tryFString(Double, -10000, 8, 15); - tryFString(Double, -100000, 0, 7); - tryFString(Double, -100000, 1, 9); - tryFString(Double, -100000, 8, 16); - tryFString(Double, -1000000, 0, 8); - tryFString(Double, -1000000, 1, 10); - tryFString(Double, -1000000, 8, 17); - tryFString(Double, -10000000, 0, 9); - tryFString(Double, -10000000, 1, 11); - tryFString(Double, -10000000, 8, 18); - - /* - * Values > 1e7 trigger the %e format. - * Windows may print 3 digit exponents... - */ - testDiag("------------------------------------------------------"); - testDiag("** Positive Double scientific **"); - tryFString(Double, 1e+17, 0, 7); - tryFString(Double, 1e+17, 1, 8); - tryFString(Double, 1e+17, 2, 9); - tryFString(Double, 1e+17, 3, 10); - tryFString(Double, 1e+17, 4, 11); - tryFString(Double, 1e+17, 5, 12); - - return testDone(); -} diff --git a/src/libCom/test/epicsAlgorithmTest.cpp b/src/libCom/test/epicsAlgorithmTest.cpp deleted file mode 100644 index fa8c0c03f..000000000 --- a/src/libCom/test/epicsAlgorithmTest.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// epicsAlgorithmTest.cpp -// Authors: Jeff Hill & Andrew Johnson - -#include "epicsUnitTest.h" -#include "epicsAlgorithm.h" -#include "epicsMath.h" -#include "testMain.h" - -MAIN(epicsAlgorithm) -{ - testPlan(22); - - float f1 = 3.3f; - float f2 = 3.4f; - float Inf = epicsINF; - float NaN = epicsNAN; - - testOk(epicsMin(f1, f2) == f1, "epicsMin(f1, f2)"); - testOk(epicsMin(f1, -Inf) == -Inf, "epicsMin(f1, -Inf)"); - testOk(isnan(epicsMin(f1, NaN)), "epicsMin(f1, NaN)"); - testOk(epicsMin(f1, Inf) == f1, "epicsMin(f1, Inf)"); - - testOk(epicsMin(f2, f1) == f1, "epicsMin(f2, f1)"); - testOk(epicsMin(-Inf, f1) == -Inf, "epicsMin(-Inf, f1)"); - testOk(isnan(epicsMin(NaN, f1)), "epicsMin(NaN, f1)"); - testOk(epicsMin(Inf, f1) == f1, "epicsMin(Inf, f1)"); - - testOk(epicsMax(f2, f1) == f2, "epicsMax(f2, f1)"); - testOk(epicsMax(-Inf, f1) == f1, "epicsMax(-Inf, f1)"); - testOk(isnan(epicsMax(NaN, f1)), "epicsMax(NaN, f1)"); - testOk(epicsMax(Inf, f1) == Inf, "epicsMax(Inf, f1)"); - - testOk(epicsMax(f1, f2) == f2, "epicsMax(f1, f2)"); - testOk(epicsMax(f1, -Inf) == f1, "epicsMax(f1, -Inf)"); - testOk(isnan(epicsMax(f1, NaN)), "epicsMax(f1, NaN)"); - testOk(epicsMax(f1, Inf) == Inf, "epicsMax(f1, Inf)"); - - epicsSwap(f1, f2); - testOk(f1==3.4f && f2==3.3f, "epicsSwap(f1, f2)"); - - int i1 = 3; - int i2 = 4; - - testOk(epicsMin(i1, i2) == i1, "epicsMin(i1,i2)"); - testOk(epicsMin(i2, i1) == i1, "epicsMin(i2,i1)"); - - testOk(epicsMax(i1, i2) == i2, "epicsMax(i1,i2)"); - testOk(epicsMax(i2, i1) == i2, "epicsMax(i2,i1)"); - - epicsSwap(i1, i2); - testOk(i1 == 4 && i2 == 3, "epicsSwap(i1, i2)"); - - return testDone(); -} - diff --git a/src/libCom/test/epicsAtomicPerform.cpp b/src/libCom/test/epicsAtomicPerform.cpp deleted file mode 100644 index 2ef005efe..000000000 --- a/src/libCom/test/epicsAtomicPerform.cpp +++ /dev/null @@ -1,574 +0,0 @@ - -#include -#include -#include -#include - -#include "epicsInterrupt.h" -#include "epicsAtomic.h" -#include "epicsTime.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -using std :: size_t; -using namespace epics; -using namespace atomic; - -class RefCtr { -public: - RefCtr (); - ~RefCtr (); - void reference (); - void unreference (); -private: - size_t m_cnt; -}; - -class Ownership { -public: - Ownership (); - Ownership ( RefCtr & refCtr ); - Ownership ( const Ownership & ); - ~Ownership (); - Ownership & operator = ( const Ownership & ); -private: - RefCtr * _pRefCtr; - static RefCtr m_noOwnership; -}; - -inline RefCtr :: RefCtr () -{ - epicsAtomicSetSizeT ( & m_cnt, 0 ); -} - -inline RefCtr :: ~RefCtr () -{ - unsigned cnt = epicsAtomicGetSizeT ( & m_cnt ); - assert ( cnt == 0u ); -} - -inline void RefCtr :: reference () -{ - epicsAtomicIncrSizeT ( & m_cnt ); -} - -inline void RefCtr :: unreference () -{ - epicsAtomicDecrSizeT ( & m_cnt ); -} - -RefCtr Ownership :: m_noOwnership; - -inline Ownership :: Ownership () : - _pRefCtr ( & m_noOwnership ) -{ - m_noOwnership.reference (); -} - -inline Ownership :: Ownership ( RefCtr & refCtr ) : - _pRefCtr ( & refCtr ) -{ - refCtr.reference (); -} - -inline Ownership :: Ownership ( const Ownership & ownership ) : - _pRefCtr ( ownership._pRefCtr ) -{ - _pRefCtr->reference (); -} - -inline Ownership :: ~Ownership () -{ - _pRefCtr->unreference (); -} - -inline Ownership & Ownership :: - operator = ( const Ownership & ownership ) -{ - RefCtr * const pOldRefCtr = _pRefCtr; - _pRefCtr = ownership._pRefCtr; - _pRefCtr->reference (); - pOldRefCtr->unreference (); - return *this; -} - -inline Ownership retOwnership ( const Ownership & ownership ) -{ - return Ownership ( ownership ); -} - -inline Ownership recurRetOwner10 ( const Ownership & ownershipIn ) -{ - Ownership ownership = - retOwnership ( - retOwnership ( - retOwnership ( - retOwnership ( - retOwnership ( ownershipIn ) ) ) ) ); - return retOwnership ( - retOwnership ( - retOwnership ( - retOwnership ( - retOwnership ( ownership ) ) ) ) ); -} - -inline Ownership recurRetOwner100 ( const Ownership & ownershipIn ) -{ - Ownership ownership = - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( ownershipIn ) ) ) ) ); - return recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( - recurRetOwner10 ( ownership ) ) ) ) ); -} - -inline Ownership recurRetOwner1000 ( const Ownership & ownershipIn ) -{ - Ownership ownership = - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( ownershipIn ) ) ) ) ); - return recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( - recurRetOwner100 ( ownership ) ) ) ) ); -} - -inline void passRefOwnership ( const Ownership & ownershipIn, Ownership & ownershipOut ) -{ - ownershipOut = ownershipIn; -} - -inline void passRefOwnership10 ( const Ownership & ownershipIn, Ownership & ownershipOut ) -{ - Ownership ownershipTmp0; - passRefOwnership ( ownershipIn, ownershipTmp0 ); - Ownership ownershipTmp1; - passRefOwnership ( ownershipTmp0, ownershipTmp1 ); - Ownership ownershipTmp2; - passRefOwnership ( ownershipTmp1, ownershipTmp2 ); - Ownership ownershipTmp3; - passRefOwnership ( ownershipTmp2, ownershipTmp3 ); - Ownership ownershipTmp4; - passRefOwnership ( ownershipTmp3, ownershipTmp4 ); - Ownership ownershipTmp5; - passRefOwnership ( ownershipTmp4, ownershipTmp5 ); - Ownership ownershipTmp6; - passRefOwnership ( ownershipTmp5, ownershipTmp6 ); - Ownership ownershipTmp7; - passRefOwnership ( ownershipTmp6, ownershipTmp7 ); - Ownership ownershipTmp8; - passRefOwnership ( ownershipTmp7, ownershipTmp8 ); - passRefOwnership ( ownershipTmp8, ownershipOut ); -} - -inline void passRefOwnership100 ( const Ownership & ownershipIn, Ownership & ownershipOut ) -{ - Ownership ownershipTmp0; - passRefOwnership10 ( ownershipIn, ownershipTmp0 ); - Ownership ownershipTmp1; - passRefOwnership10 ( ownershipTmp0, ownershipTmp1 ); - Ownership ownershipTmp2; - passRefOwnership10 ( ownershipTmp1, ownershipTmp2 ); - Ownership ownershipTmp3; - passRefOwnership10 ( ownershipTmp2, ownershipTmp3 ); - Ownership ownershipTmp4; - passRefOwnership10 ( ownershipTmp3, ownershipTmp4 ); - Ownership ownershipTmp5; - passRefOwnership10 ( ownershipTmp4, ownershipTmp5 ); - Ownership ownershipTmp6; - passRefOwnership10 ( ownershipTmp5, ownershipTmp6 ); - Ownership ownershipTmp7; - passRefOwnership10 ( ownershipTmp6, ownershipTmp7 ); - Ownership ownershipTmp8; - passRefOwnership10 ( ownershipTmp7, ownershipTmp8 ); - passRefOwnership10 ( ownershipTmp8, ownershipOut ); -} - -inline void passRefOwnership1000 ( const Ownership & ownershipIn, Ownership & ownershipOut ) -{ - Ownership ownershipTmp0; - passRefOwnership100 ( ownershipIn, ownershipTmp0 ); - Ownership ownershipTmp1; - passRefOwnership100 ( ownershipTmp0, ownershipTmp1 ); - Ownership ownershipTmp2; - passRefOwnership100 ( ownershipTmp1, ownershipTmp2 ); - Ownership ownershipTmp3; - passRefOwnership100 ( ownershipTmp2, ownershipTmp3 ); - Ownership ownershipTmp4; - passRefOwnership100 ( ownershipTmp3, ownershipTmp4 ); - Ownership ownershipTmp5; - passRefOwnership100 ( ownershipTmp4, ownershipTmp5 ); - Ownership ownershipTmp6; - passRefOwnership100 ( ownershipTmp5, ownershipTmp6 ); - Ownership ownershipTmp7; - passRefOwnership100 ( ownershipTmp6, ownershipTmp7 ); - Ownership ownershipTmp8; - passRefOwnership100 ( ownershipTmp7, ownershipTmp8 ); - passRefOwnership100 ( ownershipTmp8, ownershipOut ); -} - -time_t extTime = 0; - -template < class T > -class OrdinaryIncr { -public: - OrdinaryIncr () : m_target ( 0 ) {} - void run (); - void diagnostic ( double delay ); -private: - T m_target; -}; - -// tests the time it takes to perform a call to an external -// function and also increment an integer word. The -// epicsInterruptIsInterruptContext function is an -// out-of-line function implemented in a sharable library -// so hopefully it wont be optimized away. -template < class T > -inline void OrdinaryIncr < T > :: run () -{ - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); - m_target += epicsInterruptIsInterruptContext (); -} - -template < class T > -void OrdinaryIncr < T > :: diagnostic ( double delay ) -{ - delay /= 10.0; - delay *= 1e6; - const char * const pName = typeid ( T ) . name (); - testDiag ( "raw incr of \"%s\" and a NOOP function call takes %f microseconds", - pName, delay ); -} - -template < class T > -class AtomicIncr { -public: - AtomicIncr () : m_target ( 0 ) {} - void run (); - void diagnostic ( double delay ); -private: - T m_target; -}; - -template < class T > -inline void AtomicIncr < T > :: run () -{ - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); - increment ( m_target ); -} - -template < class T > -void AtomicIncr < T > :: diagnostic ( double delay ) -{ - delay /= 10.0; - delay *= 1e6; - const char * const pName = typeid ( T ) . name (); - testDiag ( "epicsAtomicIncr \"%s\" takes %f microseconds", - pName, delay ); -} - -template < class T > T trueValue (); -template < class T > T falseValue (); - -// int -template <> -inline int trueValue < int > () { return 1; } - -template <> -inline int falseValue < int > () { return 0; } - -// size_t -template <> -inline size_t trueValue < size_t > () { return 1u; } - -template <> -inline size_t falseValue < size_t > () { return 0u; } - -// EpicsAtomicPtrT -template <> -inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > () -{ static char c; return & c; } - -template <> -inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > () -{ return 0u; } - -template < class T > -class AtomicCmpAndSwap { -public: - AtomicCmpAndSwap () : m_target ( 0 ) {} - void run (); - void diagnostic ( double delay ); -private: - T m_target; -}; - -template < class T > -inline void AtomicCmpAndSwap < T > :: run () -{ - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); - compareAndSwap ( m_target, falseValue < T > (), trueValue < T > () ); -} - -template < class T > -void AtomicCmpAndSwap < T > :: diagnostic ( double delay ) -{ - delay /= 10.0; - delay *= 1e6; - const char * const pName = typeid ( T ) . name (); - testDiag ( "epicsAtomicCmpAndSwap of \"%s\" takes %f microseconds", - pName, delay ); -} - -template < class T > -class AtomicSet { -public: - AtomicSet () : m_target ( 0 ) {} - void run (); - void diagnostic ( double delay ); -private: - T m_target; -}; - -template < class T > -inline void AtomicSet < T > :: run () -{ - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); - set ( m_target, 0 ); -} - -template < class T > -void AtomicSet < T > :: diagnostic ( double delay ) -{ - delay /= 10.0; - delay *= 1e6; - const char * const pName = typeid ( T ) . name (); - testDiag ( "epicsAtomicSet of \"%s\" takes %f microseconds", - pName, delay ); -} - -static const unsigned N = 10000; - -void recursiveOwnershipRetPerformance () -{ - RefCtr refCtr; - epicsTime begin = epicsTime::getCurrent (); - for ( size_t i = 0; i < N; i++ ) { - Ownership ownership ( refCtr ); - recurRetOwner1000 ( ownership ); - } - double delay = epicsTime::getCurrent () - begin; - delay /= N * 1000u; // convert to delay per call - delay *= 1e6; // convert to micro seconds - testDiag ( "retOwnership() takes %f microseconds", delay ); -} - -void ownershipPassRefPerformance () -{ - RefCtr refCtr; - epicsTime begin = epicsTime::getCurrent (); - for ( size_t i = 0; i < N; i++ ) { - Ownership ownershipSrc ( refCtr ); - Ownership ownershipDest; - passRefOwnership1000 ( ownershipSrc, ownershipDest ); - } - double delay = epicsTime::getCurrent () - begin; - delay /= N * 1000u; // convert to delay per call - delay *= 1e6; // convert to micro seconds - testDiag ( "passRefOwnership() takes %f microseconds", delay ); -} - -template < class T > -class Ten -{ -public: - void run (); - void diagnostic ( double delay ); - typedef Ten < Ten < T > > Hundred; - typedef Ten < Hundred > Thousand; -private: - T m_target; -}; - -template < class T > -inline void Ten < T > :: run () -{ - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); - m_target.run (); -} - -template < class T > -void Ten < T > :: diagnostic ( double delay ) -{ - m_target.diagnostic ( delay / 10.0 ); -} - -template < class T > -void measurePerformance () -{ - epicsTime begin = epicsTime::getCurrent (); - T target; - for ( size_t i = 0; i < N; i++ ) { - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - target.run (); - } - double delay = epicsTime::getCurrent () - begin; - delay /= ( N * 10u ); // convert to delay per call - target.diagnostic ( delay ); -} - -template < class T > -void measure () -{ - measurePerformance < typename Ten < T > :: Hundred > (); -} - - -// template instances, needed for vxWorks 5.5.2 - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class AtomicSet < int >; -template class AtomicSet < size_t >; -template class AtomicSet < EpicsAtomicPtrT >; -template class OrdinaryIncr < int >; -template class OrdinaryIncr < size_t >; -template class AtomicIncr < int >; -template class AtomicIncr < size_t >; -template class AtomicCmpAndSwap < int >; -template class AtomicCmpAndSwap < size_t >; -template class AtomicCmpAndSwap < EpicsAtomicPtrT >; - -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; -template class Ten >; - -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; -template class Ten > >; - -template void measurePerformance < Ten < Ten < AtomicSet < int > > > >(void); -template void measurePerformance < Ten < Ten < AtomicSet < size_t > > > >(void); -template void measurePerformance < Ten < Ten < AtomicSet < EpicsAtomicPtrT > > > >(void); -template void measurePerformance < Ten < Ten < OrdinaryIncr < int > > > >(void); -template void measurePerformance < Ten < Ten < OrdinaryIncr < size_t > > > >(void); -template void measurePerformance < Ten < Ten < AtomicIncr < int > > > >(void); -template void measurePerformance < Ten < Ten < AtomicIncr < size_t > > > >(void); -template void measurePerformance < Ten < Ten < AtomicCmpAndSwap < int > > > >(void); -template void measurePerformance < Ten < Ten < AtomicCmpAndSwap < size_t > > > >(void); -template void measurePerformance < Ten < Ten < AtomicCmpAndSwap < EpicsAtomicPtrT > > > >(void); - -template void measure < AtomicSet < int > > (void); -template void measure < AtomicSet < size_t > > (void); -template void measure < AtomicSet < EpicsAtomicPtrT > > (void); -template void measure < OrdinaryIncr < int > > (void); -template void measure < OrdinaryIncr < size_t > > (void); -template void measure < AtomicIncr < int > > (void); -template void measure < AtomicIncr < size_t > > (void); -template void measure < AtomicCmpAndSwap < int > > (void); -template void measure < AtomicCmpAndSwap < size_t > > (void); -template void measure < AtomicCmpAndSwap < EpicsAtomicPtrT > > (void); - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - - -MAIN ( epicsAtomicPerform ) -{ - testPlan ( 0 ); - // - // The tests running here are measuring fast - // functions so they tend to be impacted - // by where the cache lines are wrt to the - // virtual pages perhap - // - measure < AtomicSet < int > > (); - measure < AtomicSet < size_t > > (); - measure < AtomicSet < void * > > (); - measure < OrdinaryIncr < int > > (); - measure < OrdinaryIncr < size_t > > (); - measure < AtomicIncr < int > > (); - measure < AtomicIncr < size_t > > (); - measure < AtomicCmpAndSwap < int > > (); - measure < AtomicCmpAndSwap < size_t > > (); - measure < AtomicCmpAndSwap < void * > > (); - recursiveOwnershipRetPerformance (); - ownershipPassRefPerformance (); - return testDone(); -} diff --git a/src/libCom/test/epicsAtomicTest.cpp b/src/libCom/test/epicsAtomicTest.cpp deleted file mode 100644 index fd9fc2e6b..000000000 --- a/src/libCom/test/epicsAtomicTest.cpp +++ /dev/null @@ -1,426 +0,0 @@ - -#include -#include - -#include "epicsAtomic.h" -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -namespace { - -template < class T > -struct TestDataIncrDecr { - T m_testValue; - size_t m_testIterations; -}; - -template < class T > -struct TestDataAddSub { - T m_testValue; - size_t m_testIterations; - static const T delta = 17; -}; - -template < class T > -static void incr ( void *arg ) -{ - using epics::atomic::increment; - TestDataIncrDecr < T > * const pTestData = - reinterpret_cast < TestDataIncrDecr < T > * > ( arg ); - increment ( pTestData->m_testValue ); - increment ( pTestData->m_testIterations ); -} - -template < class T > -static void decr ( void *arg ) -{ - using epics::atomic::decrement; - using epics::atomic::increment; - TestDataIncrDecr < T > * const pTestData = - reinterpret_cast < TestDataIncrDecr < T > * > ( arg ); - decrement ( pTestData->m_testValue ); - increment ( pTestData->m_testIterations ); -} - - -template < class T > -static void add ( void *arg ) -{ - using epics::atomic::add; - using epics::atomic::increment; - TestDataAddSub < T > * const pTestData = - reinterpret_cast < TestDataAddSub < T > * > ( arg ); - add ( pTestData->m_testValue, TestDataAddSub < T > :: delta ); - increment ( pTestData->m_testIterations ); -} - -template < class T > -static void sub ( void *arg ) -{ - using epics::atomic::subtract; - using epics::atomic::increment; - TestDataAddSub < T > * const pTestData = - reinterpret_cast < TestDataAddSub < T > * > ( arg ); - subtract ( pTestData->m_testValue, TestDataAddSub < T > :: delta ); - increment ( pTestData->m_testIterations ); -} - -template < class T > -struct TestDataCAS { - T m_testValue; - size_t m_testIterationsSet; - size_t m_testIterationsNotSet; -}; - -template < class T > -static T trueValue (); -template < class T > -static T falseValue (); - -// int -template <> -inline int trueValue < int > () { return 1; } - -template <> -inline int falseValue < int > () { return 0; } - -// size_t -template <> -inline size_t trueValue < size_t > () { return 1u; } - -template <> -inline size_t falseValue < size_t > () { return 0u; } - -// EpicsAtomicPtrT -template <> -inline EpicsAtomicPtrT trueValue < EpicsAtomicPtrT > () -{ static char c; return & c; } - -template <> -inline EpicsAtomicPtrT falseValue < EpicsAtomicPtrT > () -{ return 0u; } - -template < class T > -static void cas ( void *arg ) -{ - using epics::atomic::set; - using epics::atomic::increment; - using epics::atomic::decrement; - using epics::atomic::compareAndSwap; - - TestDataCAS < T > * const pTestData = - reinterpret_cast < TestDataCAS < T > * > ( arg ); - /* - * intentionally waste cpu and maximize - * contention for the shared data - */ - increment ( pTestData->m_testIterationsNotSet ); - while ( ! compareAndSwap ( pTestData->m_testValue, - falseValue < T > (), - trueValue < T > () ) ) { - } - decrement ( pTestData->m_testIterationsNotSet ); - set ( pTestData->m_testValue, falseValue < T > () ); - increment ( pTestData->m_testIterationsSet ); -} - -template < class T > -void testIncrDecr () -{ - using epics::atomic::set; - using epics::atomic::get; - - static const size_t N = 90; - static const T NT = static_cast < T > ( N ); - - const unsigned int stackSize = - epicsThreadGetStackSize ( epicsThreadStackSmall ); - - TestDataIncrDecr < T > testData = { 0, N }; - set ( testData.m_testValue, NT ); - testOk ( get ( testData.m_testValue ) == NT, - "get returns initial incr/decr test data value that was set" ); - set ( testData.m_testIterations, 0u ); - testOk ( get ( testData.m_testIterations ) == 0u, - "get returns initial incr/decr test thread iterations value that was set" ); - for ( size_t i = 0u; i < N; i++ ) { - epicsThreadMustCreate ( "incr", - 50, stackSize, incr < T >, & testData ); - epicsThreadMustCreate ( "decr", - 50, stackSize, decr < T >, & testData ); - if(i%10==0) - testDiag("iteration %u", (unsigned)i); - } - while ( testData.m_testIterations < 2 * N ) { - epicsThreadSleep ( 0.01 ); - } - testOk ( get ( testData.m_testIterations ) == 2 * N, - "proper number of incr/decr test thread iterations" ); - testOk ( get ( testData.m_testValue ) == NT, - "proper final incr/decr test value" ); -} - -template < class T > -void testAddSub () -{ - using epics::atomic::set; - using epics::atomic::get; - - static const size_t N = 90; - static const T NDT = TestDataAddSub < T > :: delta * - static_cast < T > ( N ); - - const unsigned int stackSize = - epicsThreadGetStackSize ( epicsThreadStackSmall ); - - TestDataIncrDecr < T > testData = { 0, N }; - set ( testData.m_testValue, NDT ); - testOk ( get ( testData.m_testValue ) == NDT, - "get returns initial add/sub test data value that was set" ); - set ( testData.m_testIterations, 0u ); - testOk ( get ( testData.m_testIterations ) == 0u, - "get returns initial incr/decr test thread iterations value that was set" ); - for ( size_t i = 0u; i < N; i++ ) { - epicsThreadMustCreate ( "add", - 50, stackSize, add < T >, & testData ); - epicsThreadMustCreate ( "sub", - 50, stackSize, sub < T >, & testData ); - } - while ( testData.m_testIterations < 2 * N ) { - epicsThreadSleep ( 0.01 ); - } - testOk ( get ( testData.m_testIterations ) == 2 * N, - "proper number of add/sub test thread iterations" ); - testOk ( get ( testData.m_testValue ) == NDT, - "proper final add/sub test value" ); -} - -template < class T > -void testCAS () -{ - using epics::atomic::set; - using epics::atomic::get; - - static const size_t N = 10; - - const unsigned int stackSize = - epicsThreadGetStackSize ( epicsThreadStackSmall ); - - TestDataCAS < T > testData = { 0, N, N }; - set ( testData.m_testIterationsSet, 0 ); - testOk ( get ( testData.m_testIterationsSet ) == 0u, - "get returns initial CAS test thread " - "iterations set value" ); - set ( testData.m_testIterationsNotSet, 0 ); - testOk ( get ( testData.m_testIterationsNotSet ) == 0u, - "get returns initial CAS test thread " - "iterations not set value" ); - set ( testData.m_testValue, trueValue < T > () ); - testOk ( get ( testData.m_testValue ) == trueValue < T > (), - "set/get a true value" ); - for ( size_t i = 0u; i < N; i++ ) { - epicsThreadMustCreate ( "tns", - 50, stackSize, cas < T >, & testData ); - } - set ( testData.m_testValue, falseValue < T > () ); - while ( testData.m_testIterationsSet < N ) { - epicsThreadSleep ( 0.01 ); - } - testOk ( get ( testData.m_testIterationsSet ) == N, - "proper number of CAS test thread set iterations" ); - testOk ( get ( testData.m_testIterationsNotSet ) == 0u, - "proper number of CAS test thread not set iterations" ); -} - -// template instances, needed for vxWorks 5.5.2 - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template void incr < int > (void *); -template void decr < int > (void *); -template void incr < size_t > (void *); -template void decr < size_t > (void *); -template void add < int > (void *); -template void sub < int > (void *); -template void add < size_t > (void *); -template void sub < size_t > (void *); -template void cas < int > (void *); -template void cas < size_t > (void *); -template void cas < EpicsAtomicPtrT > (void *); - -template void testIncrDecr < int > (void); -template void testIncrDecr < size_t > (void); -template void testAddSub < int > (void); -template void testAddSub < size_t > (void); -template void testCAS < int > (void); -template void testCAS < size_t > (void); -template void testCAS < EpicsAtomicPtrT > (void); - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -static void testClassify() -{ - testDiag("Classify Build conditions"); -#ifdef EPICS_ATOMIC_CMPLR_NAME - testDiag("Compiler dependent impl name %s", EPICS_ATOMIC_CMPLR_NAME); -#else - testDiag("Compiler dependent impl name undefined"); -#endif -#ifdef EPICS_ATOMIC_OS_NAME - testDiag("OS dependent impl name %s", EPICS_ATOMIC_OS_NAME); -#else - testDiag("OS dependent impl name undefined"); -#endif - -#ifdef __GNUC__ -#if GCC_ATOMIC_INTRINSICS_GCC4_OR_BETTER - testDiag("GCC using atomic builtin memory barrier"); -#else - testDiag("GCC using asm memory barrier"); -#endif -#if GCC_ATOMIC_INTRINSICS_AVAIL_INT_T || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER - testDiag("GCC use builtin for int"); -#endif -#if GCC_ATOMIC_INTRINSICS_AVAIL_SIZE_T || GCC_ATOMIC_INTRINSICS_AVAIL_EARLIER - testDiag("GCC use builtin for size_t"); -#endif - -#ifndef EPICS_ATOMIC_INCR_INTT - testDiag("Use default epicsAtomicIncrIntT()"); -#endif -#ifndef EPICS_ATOMIC_INCR_SIZET - testDiag("Use default epicsAtomicIncrSizeT()"); -#endif -#ifndef EPICS_ATOMIC_DECR_INTT - testDiag("Use default epicsAtomicDecrIntT()"); -#endif -#ifndef EPICS_ATOMIC_DECR_SIZET - testDiag("Use default epicsAtomicDecrSizeT()"); -#endif -#ifndef EPICS_ATOMIC_ADD_INTT - testDiag("Use default epicsAtomicAddIntT()"); -#endif -#ifndef EPICS_ATOMIC_ADD_SIZET - testDiag("Use default epicsAtomicAddSizeT()"); -#endif -#ifndef EPICS_ATOMIC_SUB_SIZET - testDiag("Use default epicsAtomicSubSizeT()"); -#endif -#ifndef EPICS_ATOMIC_SET_INTT - testDiag("Use default epicsAtomicSetIntT()"); -#endif -#ifndef EPICS_ATOMIC_SET_SIZET - testDiag("Use default epicsAtomicSetSizeT()"); -#endif -#ifndef EPICS_ATOMIC_SET_PTRT - testDiag("Use default epicsAtomicSetPtrT()"); -#endif -#ifndef EPICS_ATOMIC_GET_INTT - testDiag("Use default epicsAtomicGetIntT()"); -#endif -#ifndef EPICS_ATOMIC_GET_SIZET - testDiag("Use default epicsAtomicGetSizeT()"); -#endif -#ifndef EPICS_ATOMIC_GET_PTRT - testDiag("Use default epicsAtomicGetPtrT()"); -#endif -#ifndef EPICS_ATOMIC_CAS_INTT - testDiag("Use default epicsAtomicCmpAndSwapIntT()"); -#endif -#ifndef EPICS_ATOMIC_CAS_SIZET - testDiag("Use default epicsAtomicCmpAndSwapSizeT()"); -#endif -#ifndef EPICS_ATOMIC_CAS_PTRT - testDiag("Use default epicsAtomicCmpAndSwapPtrT()"); -#endif -#endif /* __GNUC__ */ -} - -static -void testBasic() -{ - using epics::atomic::set; - using epics::atomic::get; - using epics::atomic::decrement; - using epics::atomic::increment; - using epics::atomic::add; - using epics::atomic::subtract; - using epics::atomic::compareAndSwap; - - testDiag("Test basic operation symantics"); - - int Int = 0; - size_t Sizet = 0; - void *voidp = NULL; - - set(Int, -42); - set(Sizet, 42); - set(voidp, (void*)&voidp); - - increment(Int); - increment(Sizet); - - testOk1(get(Int)==-41); - testOk1(get(Sizet)==43); - testOk1(get(voidp)==(void*)&voidp); - - decrement(Int); - decrement(Sizet); - - testOk1(get(Int)==-42); - testOk1(get(Sizet)==42); - - add(Int, -2); - subtract(Sizet, 2); - - testOk1(get(Int)==-44); - testOk1(get(Sizet)==40); - - testOk1(compareAndSwap(Int, -34, -10)==-44); - testOk1(compareAndSwap(Sizet, 34, 10)==40); - testOk1(compareAndSwap(voidp, NULL, (void*)&Sizet)==(void*)&voidp); - - testOk1(get(Int)==-44); - testOk1(get(Sizet)==40); - testOk1(get(voidp)==(void*)&voidp); - - testOk1(compareAndSwap(Int, -44, -10)==-44); - testOk1(compareAndSwap(Sizet, 40, 10)==40); - testOk1(compareAndSwap(voidp, (void*)&voidp, (void*)&Sizet)==(void*)&voidp); - - testOk1(get(Int)==-10); - testOk1(get(Sizet)==10); - testOk1(get(voidp)==(void*)&Sizet); -} - -} // namespace - -MAIN ( epicsAtomicTest ) -{ - - testPlan ( 50 ); - testDiag("In %s", EPICS_FUNCTION); - testClassify (); - testBasic(); -#if defined(__rtems__) - testSkip(31, "Tests assume time sliced thread scheduling"); -#else - testIncrDecr < int > (); - testIncrDecr < size_t > (); - testAddSub < int > (); - testAddSub < size_t > (); - testCAS < int > (); - testCAS < size_t > (); - testCAS < EpicsAtomicPtrT > (); -#endif - - return testDone (); -} - diff --git a/src/libCom/test/epicsCalcTest.cpp b/src/libCom/test/epicsCalcTest.cpp deleted file mode 100644 index 1ebc0c578..000000000 --- a/src/libCom/test/epicsCalcTest.cpp +++ /dev/null @@ -1,992 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// Author: Andrew Johnson - -#include -#include - -#include "epicsUnitTest.h" -#include "epicsTypes.h" -#include "epicsMath.h" -#include "epicsAlgorithm.h" -#include "postfix.h" -#include "testMain.h" - -/* Infrastructure for running tests */ - -double doCalc(const char *expr) { - /* Evaluate expression, return result */ - double args[CALCPERFORM_NARGS] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 - }; - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err; - double result = 0.0; - result /= result; /* Start as NaN */ - - if(!rpn) { - testAbort("postfix: %s no memory", expr); - return epicsNAN; - } - - if (postfix(expr, rpn, &err)) { - testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); - } else - if (calcPerform(args, &result, rpn) && finite(result)) { - testDiag("calcPerform: error evaluating '%s'", expr); - } - free(rpn); - return result; -} - -void testCalc(const char *expr, double expected) { - /* Evaluate expression, test against expected result */ - bool pass = false; - double args[CALCPERFORM_NARGS] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 - }; - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err; - double result = 0.0; - result /= result; /* Start as NaN */ - - if(!rpn) { - testFail("postfix: %s no memory", expr); - return; - } - - if (postfix(expr, rpn, &err)) { - testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); - } else - if (calcPerform(args, &result, rpn) && finite(result)) { - testDiag("calcPerform: error evaluating '%s'", expr); - } - - if (finite(expected) && finite(result)) { - pass = fabs(expected - result) < 1e-8; - } else if (isnan(expected)) { - pass = (bool) isnan(result); - } else { - pass = (result == expected); - } - if (!testOk(pass, "%s", expr)) { - testDiag("Expected result is %g, actually got %g", expected, result); - calcExprDump(rpn); - } - free(rpn); -} - -void testUInt32Calc(const char *expr, epicsUInt32 expected) { - /* Evaluate expression, test against expected result */ - bool pass = false; - double args[CALCPERFORM_NARGS] = { - 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0 - }; - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err; - epicsUInt32 uresult; - double result = 0.0; - result /= result; /* Start as NaN */ - - if(!rpn) { - testFail("postfix: %s no memory", expr); - return; - } - - if (postfix(expr, rpn, &err)) { - testDiag("postfix: %s in expression '%s'", calcErrorStr(err), expr); - } else - if (calcPerform(args, &result, rpn) && finite(result)) { - testDiag("calcPerform: error evaluating '%s'", expr); - } - - uresult = (epicsUInt32) result; - pass = (uresult == expected); - if (!testOk(pass, "%s", expr)) { - testDiag("Expected result is 0x%x (%u), actually got 0x%x (%u)", - expected, expected, uresult, uresult); - calcExprDump(rpn); - } - free(rpn); -} - -void testArgs(const char *expr, unsigned long einp, unsigned long eout) { - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err = 0; - unsigned long vinp, vout; - - if(!rpn) { - testFail("postfix: %s no memory", expr); - return; - } - - if (postfix(expr, rpn, &err)) { - testFail("postfix: %s in expression '%s'", calcErrorStr(err), expr); - return; - } - if (calcArgUsage(rpn, &vinp, &vout)) { - testFail("calcArgUsage returned error for '%s'", expr); - return; - } - if (!testOk(vinp == einp && vout == eout, "Args for '%s'", expr)) { - testDiag("Expected (%lx, %lx) got (%lx, %lx)", einp, eout, vinp, vout); - } - free(rpn); -} - -void testBadExpr(const char *expr, short expected_err) { - /* Parse an invalid expression, test against expected error code */ - char *rpn = (char*)malloc(INFIX_TO_POSTFIX_SIZE(strlen(expr)+1)); - short err = 0; - - if(!rpn) { - testFail("postfix: %s no memory", expr); - return; - } - - postfix(expr, rpn, &err); - if (!testOk(err == expected_err, "Bad expression '%s'", expr)) { - testDiag("Expected '%s', actually got '%s'", - calcErrorStr(expected_err), calcErrorStr(err)); - calcExprDump(rpn); - } - free(rpn); -} - -/* Test an expression that is also valid C code */ -#define testExpr(expr) testCalc(#expr, expr); - -/* These are the argument bits for testArgs */ -#define A_A 0x001 -#define A_B 0x002 -#define A_C 0x004 -#define A_D 0x008 -#define A_E 0x010 -#define A_F 0x020 -#define A_G 0x040 -#define A_H 0x080 -#define A_I 0x100 -#define A_J 0x200 -#define A_K 0x400 -#define A_L 0x800 - - -/* Macros and functions to make some expressions into valid C code */ - -#ifndef PI -#define PI 3.14159265358979 -#endif -#define Inf epicsINF -#define NaN epicsNAN -#define D2R (PI/180.) -#define R2D (180./PI) -#define ABS(x) fabs(x) -#define AND & -#define ATAN2(x,y) atan2(y,x) -#define LN(x) log(x) -#define LOG(x) log10(x) -#define LOGE(x) log(x) -#define NINT(x) (double)(long)((x) >= 0 ? (x)+0.5 : (x)-0.5) -#define OR | -#define SQR(x) sqrt(x) -#define XOR ^ - -static inline double MAX(double a) { - return a; -} -static inline double MAX(double a, double b) { - return epicsMax(a,b); -} -static inline double MAX(double a, double b, double c) { - return MAX(MAX(a,b),c); -} -static inline double MAX(double a, double b, double c, double d) { - return MAX(MAX(a,b,c),d); -} -static inline double MAX(double a, double b, double c, double d, double e) { - return MAX(MAX(a,b,c,d),e); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f) { - return MAX(MAX(a,b,c,d,e),f); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g) { - return MAX(MAX(a,b,c,d,e,f),g); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h) { - return MAX(MAX(a,b,c,d,e,f,g),h); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h, double i) { - return MAX(MAX(a,b,c,d,e,f,g,h),i); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j) { - return MAX(MAX(a,b,c,d,e,f,g,h,i),j); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j, double k) { - return MAX(MAX(a,b,c,d,e,f,g,h,i,j),k); -} -static inline double MAX(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j, double k, double l) { - return MAX(MAX(a,b,c,d,e,f,g,h,i,j,k),l); -} - -static inline double MIN(double a) { - return a; -} -static inline double MIN(double a, double b) { - return epicsMin(a,b); -} -static inline double MIN(double a, double b, double c) { - return MIN(MIN(a,b),c); -} -static inline double MIN(double a, double b, double c, double d) { - return MIN(MIN(a,b,c),d); -} -static inline double MIN(double a, double b, double c, double d, double e) { - return MIN(MIN(a,b,c,d),e); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f) { - return MIN(MIN(a,b,c,d,e),f); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g) { - return MIN(MIN(a,b,c,d,e,f),g); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h) { - return MIN(MIN(a,b,c,d,e,f,g),h); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h, double i) { - return MIN(MIN(a,b,c,d,e,f,g,h),i); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j) { - return MIN(MIN(a,b,c,d,e,f,g,h,i),j); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j, double k) { - return MIN(MIN(a,b,c,d,e,f,g,h,i,j),k); -} -static inline double MIN(double a, double b, double c, double d, double e, - double f, double g, double h, double i, double j, double k, double l) { - return MIN(MIN(a,b,c,d,e,f,g,h,i,j,k),l); -} - -/* The test code below generates lots of spurious warnings because - * it's making sure that our operator priorities match those of C. - * Disable them to quieten the compilation process where possible. - */ -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) -# pragma GCC diagnostic ignored "-Wparentheses" -#endif - -MAIN(epicsCalcTest) -{ - int repeat; - const double a=1.0, b=2.0, c=3.0, d=4.0, e=5.0, f=6.0, - g=7.0, h=8.0, i=9.0, j=10.0, k=11.0, l=12.0; - - testPlan(613); - - /* LITERAL_OPERAND elements */ - testExpr(0); - testExpr(1); - testExpr(2); - testExpr(3); - testExpr(4); - testExpr(5); - testExpr(6); - testExpr(7); - testExpr(8); - testExpr(9); - testExpr(.1); - testExpr(0.1); - testExpr(0X0); - testExpr(0x10); - testExpr(0x7fffffff); - testCalc("0x80000000", -2147483648.0); - testCalc("0xffffffff", -1); - testExpr(Inf); - testCalc("Infinity", Inf); - testExpr(NaN); - - /* OPERAND elements */ - testExpr(a); - testExpr(b); - testExpr(c); - testExpr(d); - testExpr(e); - testExpr(f); - testExpr(g); - testExpr(h); - testExpr(i); - testExpr(j); - testExpr(k); - testExpr(l); - testExpr(PI); - testExpr(D2R); - testExpr(R2D); - - for (repeat=0; repeat<100; repeat++) { - double res = doCalc("rndm"); - if (res<0 || res >1) { - testDiag("rndm returned %g", res); - break; - } - } - testOk(repeat == 100, "rndm"); - - /* UNARY_MINUS element */ - testExpr(-1); - testExpr(-Inf); - testExpr(- -1); - testCalc("-0x80000000", 2147483648.0); - - /* UNARY_OPERATOR elements */ - testExpr((1)); - testExpr(!0); - testExpr(!1); - testExpr(!!0); - testExpr(ABS(1.0)); - testExpr(ABS(-1.)); - testExpr(acos(1.)); - testExpr(asin(0.5)); - testExpr(atan(0.5)); - testExpr(ATAN2(1., 2.)); - testExpr(ceil(0.5)); - testExpr(cos(0.5)); - testExpr(cosh(0.5)); - testExpr(exp(1.)); - testExpr(floor(1.5)); - - testExpr(finite(0.)); - testExpr(finite(Inf)); - testExpr(finite(-Inf)); - testExpr(finite(NaN)); - testCalc("finite(0,1,2)", 1); - testCalc("finite(0,1,NaN)", 0); - testCalc("finite(0,NaN,2)", 0); - testCalc("finite(NaN,1,2)", 0); - testCalc("finite(0,1,Inf)", 0); - testCalc("finite(0,Inf,2)", 0); - testCalc("finite(Inf,1,2)", 0); - testCalc("finite(0,1,-Inf)", 0); - testCalc("finite(0,-Inf,2)", 0); - testCalc("finite(-Inf,1,2)", 0); - testExpr(isinf(0.)); - testExpr(isinf(Inf)); - testExpr(!!isinf(-Inf)); // Some GCCs return -1/0/+1 rather than 0/+1 - testExpr(isinf(NaN)); - testExpr(isnan(0.)); - testExpr(isnan(Inf)); - testExpr(isnan(-Inf)); - testExpr(isnan(NaN)); - testCalc("isnan(0,1,2)", 0); - testCalc("isnan(0,1,NaN)", 1); - testCalc("isnan(0,NaN,2)", 1); - testCalc("isnan(NaN,1,2)", 1); - testCalc("isnan(0,1,Inf)", 0); - testCalc("isnan(0,Inf,2)", 0); - testCalc("isnan(Inf,1,2)", 0); - testCalc("isnan(0,1,-Inf)", 0); - testCalc("isnan(0,-Inf,2)", 0); - testCalc("isnan(-Inf,1,2)", 0); - - testExpr(LN(5.)); - testExpr(LOG(5.)); - testExpr(LOGE(2.)); - - testExpr(MAX(-99)); - testExpr(MAX( 1., 2.)); - testExpr(MAX( 1., Inf)); - testExpr(MAX( 1.,-Inf)); - testExpr(MAX( 1., NaN)); - testExpr(MAX( Inf, 1.)); - testExpr(MAX(-Inf, 1.)); - testExpr(MAX( NaN, 1.)); - testExpr(MAX( 1., 2.,3.)); - testExpr(MAX( 1., 3.,2.)); - testExpr(MAX( 2., 1.,3.)); - testExpr(MAX( 2., 3.,1.)); - testExpr(MAX( 3., 1.,2.)); - testExpr(MAX( 3., 2.,1.)); - testExpr(MAX( 1., 2., Inf)); - testExpr(MAX( 1., 2.,-Inf)); - testExpr(MAX( 1., 2., NaN)); - testExpr(MAX( 1., Inf,2.)); - testExpr(MAX( 1.,-Inf,2.)); - testExpr(MAX( 1., NaN,2.)); - testExpr(MAX( Inf, 1.,2.)); - testExpr(MAX(-Inf, 1.,2.)); - testExpr(MAX( NaN, 1.,2.)); - testExpr(MAX( 1., 2., 3., 4.)); - testExpr(MAX( 1., 2., 4., 3.)); - testExpr(MAX( 1., 4., 3., 2.)); - testExpr(MAX( 4., 2., 3., 1.)); - testExpr(MAX( 1., 2., 3.,NaN)); - testExpr(MAX( 1., 2.,NaN, 3.)); - testExpr(MAX( 1.,NaN, 3., 2.)); - testExpr(MAX(NaN, 2., 3., 1.)); - testExpr(MAX( 1., 2., 3., 4., 5.)); - testExpr(MAX( 1., 2., 3., 5., 4.)); - testExpr(MAX( 1., 2., 5., 4., 3.)); - testExpr(MAX( 1., 5., 3., 4., 2.)); - testExpr(MAX( 5., 2., 3., 4., 1.)); - testExpr(MAX( 1., 2., 3., 4.,NaN)); - testExpr(MAX( 1., 2., 3.,NaN, 4.)); - testExpr(MAX( 1., 2.,NaN, 4., 3.)); - testExpr(MAX( 1.,NaN, 3., 4., 2.)); - testExpr(MAX(NaN, 2., 3., 4., 1.)); - testExpr(MAX( 1., 2., 3., 4., 5., 6.)); - testExpr(MAX( 1., 2., 3., 4., 6., 5.)); - testExpr(MAX( 1., 2., 3., 6., 5., 4.)); - testExpr(MAX( 1., 2., 6., 4., 5., 3.)); - testExpr(MAX( 1., 6., 3., 4., 5., 2.)); - testExpr(MAX( 6., 2., 3., 4., 5., 1.)); - testExpr(MAX( 1., 2., 3., 4., 5.,NaN)); - testExpr(MAX( 1., 2., 3., 4.,NaN, 5.)); - testExpr(MAX( 1., 2., 3.,NaN, 5., 4.)); - testExpr(MAX( 1., 2.,NaN, 4., 5., 3.)); - testExpr(MAX( 1.,NaN, 3., 4., 5., 2.)); - testExpr(MAX(NaN, 2., 3., 4., 5., 1.)); - testExpr(MAX( 1., 2., 3., 4., 5.,Inf)); - testExpr(MAX( 1., 2., 3., 4.,Inf, 5.)); - testExpr(MAX( 1., 2., 3.,Inf, 5., 4.)); - testExpr(MAX( 1., 2.,Inf, 4., 5., 3.)); - testExpr(MAX( 1.,Inf, 3., 4., 5., 2.)); - testExpr(MAX(Inf, 2., 3., 4., 5., 1.)); - testExpr(MAX(1,2,3,4,5,6,7,8,9,10,11,12)); - testExpr(MAX(5,4,3,2,1,0,-1,-2,-3,-4,-5,-6)); - testExpr(MAX(-1,1,0)); - - testExpr(MIN(99)); - testExpr(MIN(1.,2.)); - testExpr(MIN(1.,Inf)); - testExpr(MIN(1.,-Inf)); - testExpr(MIN(1.,NaN)); - testExpr(MIN(NaN,1.)); - testExpr(MIN( 1., 2.,3.)); - testExpr(MIN( 1., 3.,2.)); - testExpr(MIN( 2., 1.,3.)); - testExpr(MIN( 2., 3.,1.)); - testExpr(MIN( 3., 1.,2.)); - testExpr(MIN( 3., 2.,1.)); - testExpr(MIN( 1., 2., Inf)); - testExpr(MIN( 1., 2.,-Inf)); - testExpr(MIN( 1., 2., NaN)); - testExpr(MIN( 1., Inf,2.)); - testExpr(MIN( 1.,-Inf,2.)); - testExpr(MIN( 1., NaN,2.)); - testExpr(MIN( Inf, 1.,2.)); - testExpr(MIN(-Inf, 1.,2.)); - testExpr(MIN( NaN, 1.,2.)); - testExpr(MIN( 1., 2., 3., 4.)); - testExpr(MIN( 1., 2., 4., 3.)); - testExpr(MIN( 1., 4., 3., 2.)); - testExpr(MIN( 4., 2., 3., 1.)); - testExpr(MIN( 1., 2., 3.,NaN)); - testExpr(MIN( 1., 2.,NaN, 3.)); - testExpr(MIN( 1.,NaN, 3., 2.)); - testExpr(MIN(NaN, 2., 3., 1.)); - testExpr(MIN( 1., 2., 3., 4., 5.)); - testExpr(MIN( 1., 2., 3., 5., 4.)); - testExpr(MIN( 1., 2., 5., 4., 3.)); - testExpr(MIN( 1., 5., 3., 4., 2.)); - testExpr(MIN( 5., 2., 3., 4., 1.)); - testExpr(MIN( 1., 2., 3., 4.,NaN)); - testExpr(MIN( 1., 2., 3.,NaN, 4.)); - testExpr(MIN( 1., 2.,NaN, 4., 3.)); - testExpr(MIN( 1.,NaN, 3., 4., 2.)); - testExpr(MIN(NaN, 2., 3., 4., 1.)); - testExpr(MIN( 1., 2., 3., 4., 5., 6.)); - testExpr(MIN( 2., 1., 3., 4., 5., 6.)); - testExpr(MIN( 3., 2., 1., 4., 5., 6.)); - testExpr(MIN( 4., 2., 3., 1., 5., 6.)); - testExpr(MIN( 5., 2., 3., 4., 1., 6.)); - testExpr(MIN( 6., 2., 3., 4., 5., 1.)); - testExpr(MIN( 1., 2., 3., 4., 5.,NaN)); - testExpr(MIN( 1., 2., 3., 4.,NaN, 5.)); - testExpr(MIN( 1., 2., 3.,NaN, 5., 4.)); - testExpr(MIN( 1., 2.,NaN, 4., 5., 3.)); - testExpr(MIN( 1.,NaN, 3., 4., 5., 2.)); - testExpr(MIN(NaN, 2., 3., 4., 5., 1.)); - testExpr(MIN( 1., 2., 3., 4., 5.,-Inf)); - testExpr(MIN( 1., 2., 3., 4.,-Inf, 5.)); - testExpr(MIN( 1., 2., 3.,-Inf, 5., 4.)); - testExpr(MIN( 1., 2.,-Inf, 4., 5., 3.)); - testExpr(MIN( 1.,-Inf, 3., 4., 5., 2.)); - testExpr(MIN(-Inf, 2., 3., 4., 5., 1.)); - testExpr(MIN(1,2,3,4,5,6,7,8,9,10,11,12)); - testExpr(MIN(5,4,3,2,1,0,-1,-2,-3,-4,-5,-6)); - testExpr(MIN(1,-1,0)); - testExpr(MAX(MIN(0,2),MAX(0),MIN(3,2,1))); - - testExpr(NINT(0.4)); - testExpr(NINT(0.6)); - testExpr(NINT(-0.4)); - testExpr(NINT(-0.6)); - testExpr(sin(0.5)); - testExpr(sinh(0.5)); - testExpr(SQR(10.)); - testExpr(sqrt(16.)); - testExpr(tan(0.5)); - testExpr(tanh(0.5)); - testExpr(~5); - testExpr(~~5); - - /* BINARY_OPERATOR elements */ - testExpr(0 != 1); - testExpr(0 != 0); - testExpr(1 != 0); - testExpr(1 != 0 != 2); - testExpr(0.0 != Inf); - testExpr(0.0 != -Inf); - testExpr(0.0 != NaN); - testExpr(Inf != 0.0); - testExpr(Inf != Inf); - testExpr(Inf != -Inf); - testExpr(Inf != NaN); - testExpr(-Inf != 0.0); - testExpr(-Inf != Inf); - testExpr(-Inf != -Inf); - testExpr(-Inf != NaN); - testExpr(NaN != 0.0); - testExpr(NaN != Inf); - testExpr(NaN != -Inf); - testExpr(NaN != NaN); - - testCalc("0 # 1", 0 != 1); - testCalc("0 # 0", 0 != 0); - testCalc("1 # 0", 1 != 0); - testCalc("1 # 0 # 2", 1 != 0 != 2); - - testExpr(7 % 4); - testExpr(-7 % 4); - testExpr(63 % 16 % 6) - testCalc("1 % 0", NaN); - - testExpr(7 & 4); - - testExpr(0 && 0); - testExpr(0 && 1); - testExpr(1 && 0); - testExpr(1 && 1); - - testExpr(2 * 2); - testExpr(0.0 * Inf); - testExpr(0.0 * -Inf); - testExpr(0.0 * NaN); - testExpr(Inf * 0.0); - testExpr(Inf * Inf); - testExpr(Inf * -Inf); - testExpr(Inf * NaN); - testExpr(-Inf * 0.0); - testExpr(-Inf * Inf); - testExpr(-Inf * -Inf); - testExpr(-Inf * NaN); - testExpr(NaN * 0.0); - testExpr(NaN * Inf); - testExpr(NaN * -Inf); - testExpr(NaN * NaN); - - testCalc("2 ** 0.2", pow(2., 0.2)); - testCalc("2 ** -0.2", pow(2., -0.2)); - testCalc("-0.2 ** 2", pow(-0.2, 2.)); - testCalc("-0.2 ** -2", pow(-0.2, -2)); - testCalc("2 ** 2 ** 3", pow(pow(2., 2.), 3.)); - - testExpr(0 + 1); - testExpr(0.0 + Inf); - testExpr(0.0 + -Inf); - testExpr(0.0 + NaN); - testExpr(Inf + 0.0); - testExpr(Inf + Inf); -#if defined(_WIN64) && defined(_MSC_VER) - testCalc("Inf + -Inf", NaN); -#else - testExpr(Inf + -Inf); -#endif - testExpr(Inf + NaN); - testExpr(-Inf + 0.0); -#if defined(_WIN64) && defined(_MSC_VER) - testCalc("-Inf + Inf", NaN); -#else - testExpr(-Inf + Inf); -#endif - testExpr(-Inf + -Inf); - testExpr(-Inf + NaN); - testExpr(NaN + 0.0); - testExpr(NaN + Inf); - testExpr(NaN + -Inf); - testExpr(NaN + NaN); - - testExpr(0 - 1); - testExpr(0 - 1 - 2); - testExpr(0.0 - Inf); - testExpr(0.0 - -Inf); - testExpr(0.0 - NaN); - testExpr(Inf - 0.0); - testExpr(Inf - Inf); - testExpr(Inf - -Inf); - testExpr(Inf - NaN); - testExpr(-Inf - 0.0); - testExpr(-Inf - Inf); - testExpr(-Inf - -Inf); - testExpr(-Inf - NaN); - testExpr(NaN - 0.0); - testExpr(NaN - Inf); - testExpr(NaN - -Inf); - testExpr(NaN - NaN); - - testExpr(2.0 / 3.0); - testExpr(1.0 / 2.0 / 3.0); - testExpr(0.0 / Inf); - testExpr(0.0 / -Inf); - testExpr(0.0 / NaN); - testExpr(Inf / 1.0); - testExpr(Inf / Inf); - testExpr(Inf / -Inf); - testExpr(Inf / NaN); - testExpr(-Inf / 1.0); - testExpr(-Inf / Inf); - testExpr(-Inf / -Inf); - testExpr(-Inf / NaN); - testExpr(NaN / 1.0); - testExpr(NaN / Inf); - testExpr(NaN / -Inf); - testExpr(NaN / NaN); - - testExpr(0 < 1); - testExpr(0 < 0); - testExpr(1 < 0); - testExpr(2 < 0 < 2) - testExpr(0.0 < Inf); - testExpr(0.0 < -Inf); - testExpr(0.0 < NaN); - testExpr(Inf < 0.0); - testExpr(Inf < Inf); - testExpr(Inf < -Inf); - testExpr(Inf < NaN); - testExpr(-Inf < 0.0); - testExpr(-Inf < Inf); - testExpr(-Inf < -Inf); - testExpr(-Inf < NaN); - testExpr(NaN < 0.0); - testExpr(NaN < Inf); - testExpr(NaN < -Inf); - testExpr(NaN < NaN); - - testExpr(1 << 2); - testExpr(1 << 3 << 2) - - testExpr(0 <= 1); - testExpr(0 <= 0); - testExpr(1 <= 0); - testExpr(3 <= 2 <= 3) - testExpr(0.0 <= Inf); - testExpr(0.0 <= -Inf); - testExpr(0.0 <= NaN); - testExpr(Inf <= 0.0); - testExpr(Inf <= Inf); - testExpr(Inf <= -Inf); - testExpr(Inf <= NaN); - testExpr(-Inf <= 0.0); - testExpr(-Inf <= Inf); - testExpr(-Inf <= -Inf); - testExpr(-Inf <= NaN); - testExpr(NaN <= 0.0); - testExpr(NaN <= Inf); - testExpr(NaN <= -Inf); - testExpr(NaN <= NaN); - - testCalc("0 = 1", 0 == 1); - testCalc("0 = 0", 0 == 0); - testCalc("1 = 0", 1 == 0); - testCalc("2 = 2 = 1", 2 == 2 == 1); - - testExpr(0 == 1); - testExpr(0 == 0); - testExpr(1 == 0); - testExpr(2 == 2 == 1); - testExpr(0.0 == Inf); - testExpr(0.0 == -Inf); - testExpr(0.0 == NaN); - testExpr(Inf == 0.0); - testExpr(Inf == Inf); - testExpr(Inf == -Inf); - testExpr(Inf == NaN); - testExpr(-Inf == 0.0); - testExpr(-Inf == Inf); - testExpr(-Inf == -Inf); - testExpr(-Inf == NaN); - testExpr(NaN == 0.0); - testExpr(NaN == Inf); - testExpr(NaN == -Inf); - testExpr(NaN == NaN); - - testExpr(0 > 1); - testExpr(0 > 0); - testExpr(1 > 0); - testExpr(2 > 0 > 2); - testExpr(0.0 > Inf); - testExpr(0.0 > -Inf); - testExpr(0.0 > NaN); - testExpr(Inf > 0.0); - testExpr(Inf > Inf); - testExpr(Inf > -Inf); - testExpr(Inf > NaN); - testExpr(-Inf > 0.0); - testExpr(-Inf > Inf); - testExpr(-Inf > -Inf); - testExpr(-Inf > NaN); - testExpr(NaN > 0.0); - testExpr(NaN > Inf); - testExpr(NaN > -Inf); - testExpr(NaN > NaN); - - testExpr(0 >= 1); - testExpr(0 >= 0); - testExpr(1 >= 0); - testExpr(3 >= 2 >= 3); - testExpr(0.0 >= Inf); - testExpr(0.0 >= -Inf); - testExpr(0.0 >= NaN); - testExpr(Inf >= 0.0); - testExpr(Inf >= Inf); - testExpr(Inf >= -Inf); - testExpr(Inf >= NaN); - testExpr(-Inf >= 0.0); - testExpr(-Inf >= Inf); - testExpr(-Inf >= -Inf); - testExpr(-Inf >= NaN); - testExpr(NaN >= 0.0); - testExpr(NaN >= Inf); - testExpr(NaN >= -Inf); - testExpr(NaN >= NaN); - - testExpr(8 >> 1); - testExpr(64 >> 2 >> 1); - - testExpr(7 AND 4); - - testExpr(1 OR 8); - - testExpr(3 XOR 9); - - testCalc("2 ^ 0.2", pow(2., 0.2)); - testCalc("2 ^ -0.2", pow(2., -0.2)); - testCalc("(-0.2) ^ 2", pow(-0.2, 2.)); - testCalc("(-0.2) ^ -2", pow(-0.2, -2.)); - testCalc("2 ^ 2 ^ 3", pow(pow(2., 2.), 3.)); - - testExpr(1 | 8); - - testExpr(0 || 0); - testExpr(0 || 1); - testExpr(1 || 0); - testExpr(1 || 1); - - /* CONDITIONAL elements */ - testExpr(0 ? 1 : 2); - testExpr(1 ? 1 : 2); - testExpr(Inf ? 1 : 2); - testExpr(NaN ? 1 : 2); - testExpr(0 ? 0 ? 2 : 3 : 4); - testExpr(0 ? 1 ? 2 : 3 : 4); - testExpr(1 ? 0 ? 2 : 3 : 4); - testExpr(1 ? 1 ? 2 : 3 : 4); - testExpr(0 ? 2 : 0 ? 3 : 4); - testExpr(0 ? 2 : 1 ? 3 : 4); - testExpr(1 ? 2 : 0 ? 3 : 4); - testExpr(1 ? 2 : 1 ? 3 : 4); - - /* STORE_OPERATOR and EXPR_TERM elements*/ - testCalc("a := 0; a", 0); - testCalc("b := 0; b", 0); - testCalc("c := 0; c", 0); - testCalc("d := 0; d", 0); - testCalc("e := 0; e", 0); - testCalc("f := 0; f", 0); - testCalc("g := 0; g", 0); - testCalc("h := 0; h", 0); - testCalc("i := 0; i", 0); - testCalc("j := 0; j", 0); - testCalc("k := 0; k", 0); - testCalc("l := 0; l", 0); - - testCalc("a; a := 0", a); - testCalc("b; b := 0", b); - testCalc("c; c := 0", c); - testCalc("d; d := 0", d); - testCalc("e; e := 0", e); - testCalc("f; f := 0", f); - testCalc("g; g := 0", g); - testCalc("h; h := 0", h); - testCalc("i; i := 0", i); - testCalc("j; j := 0", j); - testCalc("k; k := 0", k); - testCalc("l; l := 0", l); - - // Check relative precedences. - testExpr(0 ? 1 : 2 | 4); // 0 1 - testExpr(1 ? 1 : 2 | 4); // 0 1 - testExpr(0 ? 2 | 4 : 1); // 0 1 - testExpr(1 ? 2 | 4 : 1); // 0 1 - testExpr(0 ? 1 : 2 & 3); // 0 2 - testExpr(1 ? 1 : 2 & 3); // 0 2 - testExpr(0 ? 2 & 3 : 1); // 0 2 - testExpr(1 ? 2 & 3 : 1); // 0 2 - testExpr(0 ? 2 : 3 >= 1); // 0 3 - testExpr(0 ? 3 >= 1 : 2); // 0 3 - testExpr(1 ? 0 == 1 : 2); // 0 3 - testExpr(1 ? 2 : 0 == 1); // 0 3 - testExpr(0 ? 1 : 2 + 4); // 0 4 - testExpr(1 ? 1 : 2 + 4); // 0 4 - testExpr(0 ? 2 + 4 : 1); // 0 4 - testExpr(1 ? 2 + 4 : 1); // 0 4 - testExpr(0 ? 1 : 2 * 4); // 0 5 - testExpr(1 ? 1 : 2 * 4); // 0 5 - testExpr(0 ? 2 * 4 : 1); // 0 5 - testExpr(1 ? 2 * 4 : 1); // 0 5 - testCalc("0 ? 1 : 2 ** 3", 8); // 0 6 - testCalc("1 ? 1 : 2 ** 3", 1); // 0 6 - testCalc("0 ? 2 ** 3 : 1", 1); // 0 6 - testCalc("1 ? 2 ** 3 : 1", 8); // 0 6 - testCalc("1 | 3 XOR 1", (1 | 3) ^ 1); // 1 1 - testExpr(1 XOR 3 | 1); // 1 1 - testExpr(3 | 1 & 2); // 1 2 - testExpr(2 | 4 > 3); // 1 3 - testExpr(2 OR 4 > 3); // 1 3 - testExpr(2 XOR 3 >= 0); // 1 3 - testExpr(2 | 1 - 3); // 1 4 - testExpr(2 | 4 / 2); // 1 5 - testCalc("1 | 2 ** 3", 1 | (int) pow(2., 3.));// 1 6 - testExpr(3 << 2 & 10); // 2 2 - testCalc("18 & 6 << 2", (18 & 6) << 2); // 2 2 - testExpr(36 >> 2 & 10); // 2 2 - testCalc("18 & 20 >> 2", (18 & 20) >> 2); // 2 2 - testExpr(3 & 4 == 4); // 2 3 - testExpr(3 AND 4 == 4); // 2 3 - testCalc("1 << 2 != 4", 1 << (2 != 4)); // 2 3 - testCalc("16 >> 2 != 4", 16 >> (2 != 4)); // 2 3 - testExpr(3 AND -2); // 2 8 - testExpr(0 < 1 ? 2 : 3); // 3 0 - testExpr(1 <= 0 ? 2 : 3); // 3 0 - testExpr(0 + -1); // 4 8 - testExpr(0 - -1); // 4 8 - testExpr(10 + 10 * 2); // 4 5 - testExpr(20 + 20 / 2); // 4 5 - testExpr(-1 + 1); // 7 4 - testExpr(-1 - 2); // 7 4 - testCalc("-2 ** 2", pow(-2., 2.)); // 7 6 - testCalc("-2 ^ 2", pow(-2., 2.)); // 7 6 - - // Check parentheses - testCalc("(1 | 2) ** 3", pow((double) (1 | 2), 3.));// 8 6 - testCalc("1+(1|2)**3", 1+pow((double) (1 | 2), 3.));// 8 6 - testExpr(1+(1?(1<2):(1>2))*2); - - testArgs("a", A_A, 0); - testArgs("A", A_A, 0); - testArgs("B", A_B, 0); - testArgs("C", A_C, 0); - testArgs("D", A_D, 0); - testArgs("E", A_E, 0); - testArgs("F", A_F, 0); - testArgs("G", A_G, 0); - testArgs("H", A_H, 0); - testArgs("I", A_I, 0); - testArgs("J", A_J, 0); - testArgs("K", A_K, 0); - testArgs("L", A_L, 0); - testArgs("A+B+C+D+E+F+G+H+I+J+K+L", - A_A|A_B|A_C|A_D|A_E|A_F|A_G|A_H|A_I|A_J|A_K|A_L, 0); - testArgs("0.1;A:=0", 0, A_A); - testArgs("1.1;B:=0", 0, A_B); - testArgs("2.1;C:=0", 0, A_C); - testArgs("3.1;D:=0", 0, A_D); - testArgs("4.1;E:=0", 0, A_E); - testArgs("5.1;F:=0", 0, A_F); - testArgs("6.1;G:=0", 0, A_G); - testArgs("7.1;H:=0", 0, A_H); - testArgs("8.1;I:=0", 0, A_I); - testArgs("9.1;J:=0", 0, A_J); - testArgs("10.1;K:=0", 0, A_K); - testArgs("11.1;L:=0", 0, A_L); - testArgs("12.1;A:=0;B:=A;C:=B;D:=C", 0, A_A|A_B|A_C|A_D); - testArgs("13.1;B:=A;A:=B;C:=D;D:=C", A_A|A_D, A_A|A_B|A_C|A_D); - - // Malformed expressions - testBadExpr("0x0.1", CALC_ERR_SYNTAX); - testBadExpr("1*", CALC_ERR_INCOMPLETE); - testBadExpr("*1", CALC_ERR_SYNTAX); - testBadExpr("MIN", CALC_ERR_INCOMPLETE); - testBadExpr("MIN()", CALC_ERR_SYNTAX); - testBadExpr("MIN(A,)", CALC_ERR_SYNTAX); - testBadExpr("MIN(A,B,)", CALC_ERR_SYNTAX); - testBadExpr("MAX", CALC_ERR_INCOMPLETE); - testBadExpr("MAX()", CALC_ERR_SYNTAX); - testBadExpr("MAX(A,)", CALC_ERR_SYNTAX); - testBadExpr("MAX(A,B,)", CALC_ERR_SYNTAX); - testBadExpr("1?", CALC_ERR_CONDITIONAL); - testBadExpr("1?1", CALC_ERR_CONDITIONAL); - testBadExpr(":1", CALC_ERR_SYNTAX); - - // Bit manipulations wrt bit 31 (bug lp:1514520) - // using integer literals - testUInt32Calc("0xaaaaaaaa AND 0xffff0000", 0xaaaa0000u); - testUInt32Calc("0xaaaaaaaa OR 0xffff0000", 0xffffaaaau); - testUInt32Calc("0xaaaaaaaa XOR 0xffff0000", 0x5555aaaau); - testUInt32Calc("~0xaaaaaaaa", 0x55555555u); - testUInt32Calc("~~0xaaaaaaaa", 0xaaaaaaaau); - testUInt32Calc("0xaaaaaaaa >> 8", 0xffaaaaaau); - testUInt32Calc("0xaaaaaaaa << 8", 0xaaaaaa00u); - // using integer literals assigned to variables - testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a AND b", 0xaaaa0000u); - testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a OR b", 0xffffaaaau); - testUInt32Calc("a:=0xaaaaaaaa; b:=0xffff0000; a XOR b", 0x5555aaaau); - testUInt32Calc("a:=0xaaaaaaaa; ~a", 0x55555555u); - testUInt32Calc("a:=0xaaaaaaaa; ~~a", 0xaaaaaaaau); - testUInt32Calc("a:=0xaaaaaaaa; a >> 8", 0xffaaaaaau); - testUInt32Calc("a:=0xaaaaaaaa; a << 8", 0xaaaaaa00u); - - // Test proper conversion of double values (+ 0.1 enforces double literal) - // when used as inputs to the bitwise operations. - // 0xaaaaaaaa = -1431655766 or 2863311530u - testUInt32Calc("-1431655766.1 OR 0", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 OR 0", 0xaaaaaaaau); - testUInt32Calc("0 OR -1431655766.1", 0xaaaaaaaau); - testUInt32Calc("0 OR 2863311530.1", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 XOR 0", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 XOR 0", 0xaaaaaaaau); - testUInt32Calc("0 XOR -1431655766.1", 0xaaaaaaaau); - testUInt32Calc("0 XOR 2863311530.1", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 AND 0xffffffff", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 AND 0xffffffff", 0xaaaaaaaau); - testUInt32Calc("0xffffffff AND -1431655766.1", 0xaaaaaaaau); - testUInt32Calc("0xffffffff AND 2863311530.1", 0xaaaaaaaau); - testUInt32Calc("~ -1431655766.1", 0x55555555u); - testUInt32Calc("~ 2863311530.1", 0x55555555u); - testUInt32Calc("-1431655766.1 >> 0", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 >> 0", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 >> 0.1", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 >> 0.1", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 << 0", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 << 0", 0xaaaaaaaau); - testUInt32Calc("-1431655766.1 << 0.1", 0xaaaaaaaau); - testUInt32Calc("2863311530.1 << 0.1", 0xaaaaaaaau); - - return testDone(); -} - diff --git a/src/libCom/test/epicsEllTest.c b/src/libCom/test/epicsEllTest.c deleted file mode 100644 index 62ee14e39..000000000 --- a/src/libCom/test/epicsEllTest.c +++ /dev/null @@ -1,268 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 Michael Davidsaver -* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "ellLib.h" -#include "dbDefs.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -struct myItem { - ELLNODE node; - int list; - int num; -}; - -static void testList(void) -{ - ELLLIST list1; - ELLLIST list2 = ELLLIST_INIT; - int i1 = 1; - struct myItem *pitem, *pfirst, *pick; - - list1.count = 27; - list1.node.next = (ELLNODE *) 0x01010101; - list1.node.previous = (ELLNODE *) 0x10101010; - - ellInit(&list1); - testOk1(list1.count == 0); - testOk1(list1.node.next == NULL); - testOk1(list1.node.previous == NULL); - - testOk1(list2.count == 0); - testOk1(list2.node.next == NULL); - testOk1(list2.node.previous == NULL); - - /* First build a couple lists and fill them with nodes. */ - pitem = (struct myItem *) malloc(sizeof(struct myItem)); - pitem->node.next = (ELLNODE *) 0x10101010; - pitem->node.previous = (ELLNODE *) 0x10101010; - pitem->list = 1; - pitem->num = i1++; - - ellAdd(&list1, &pitem->node); - - testOk1(list1.count == 1); - testOk1(list1.node.next == &pitem->node); - testOk1(list1.node.previous == &pitem->node); - testOk1(pitem->node.next == NULL); - testOk1(pitem->node.previous == NULL); - - pfirst = pitem; - while (i1 <= 21) { /* put 21 nodes into LIST1 */ - pitem = (struct myItem *) malloc(sizeof(struct myItem)); - pitem->list = 1; - pitem->num = i1++; - ellAdd(&list1, &pitem->node); - } - - testOk1(list1.count == 21); - testOk1(list1.node.next == &pfirst->node); - testOk1(list1.node.previous == &pitem->node); - testOk1(pitem->node.next == NULL); - - testOk1(ellFirst(&list1) == &pfirst->node); - testOk1(ellLast(&list1) == &pitem->node); - testOk1(ellNext(&pitem->node) == NULL); - testOk1(ellNext(&pfirst->node) == pfirst->node.next); - - testOk1(ellNth(&list1, 0) == NULL); - - pick = (struct myItem *)ellNth(&list1, 21); - testOk1(pick == pitem); - - testOk1(ellNth(&list1, 22) == NULL); - testOk1(ellNth(&list1, 1) == &pfirst->node); - testOk1(ellNth(&list1, 2) == pfirst->node.next); - testOk1(ellNth(&list1, 20) == pitem->node.previous); - - testOk1(ellPrevious(&pitem->node) == pitem->node.previous); - testOk1(ellPrevious(&pfirst->node) == NULL); - testOk1(ellPrevious(pfirst->node.next) == &pfirst->node); - - pick = (struct myItem *)ellGet(&list1); - testOk1(pick == pfirst); - testOk1(list1.node.next == pfirst->node.next); - - ellAdd(&list2, &pick->node); - - pick = (struct myItem *)ellGet(&list2); - testOk1(pick == pfirst); - testOk1(list2.node.next == NULL); - testOk1(list2.node.previous == NULL); - - testOk1(ellCount(&list1) == 20); - testOk1(ellCount(&list2) == 0); - - ellConcat(&list1, &list2); - - testOk1(ellCount(&list1) == 20); - testOk1(ellCount(&list2) == 0); - testOk1(list1.node.previous == &pitem->node); - - ellAdd(&list2, &pick->node); - ellConcat(&list1, &list2); - - testOk1(ellCount(&list1) == 21); - testOk1(ellCount(&list2) == 0); - testOk1(list1.node.previous == &pick->node); - testOk1(list2.node.next == NULL); - testOk1(list2.node.previous == NULL); - - ellDelete(&list1, &pick->node); - testOk1(ellCount(&list1) == 20); - - ellAdd(&list2, &pick->node); - ellConcat(&list2, &list1); - testOk1(ellFind(&list1, &pick->node) == -1); /* empty list */ - testOk1(ellFind(&list2, &pick->node) == pick->num); /* first node */ - - pick = (struct myItem *)ellNth(&list2, 18); - testOk1(ellFind(&list2, &pick->node) == 18); /* 18th node */ - - ellDelete(&list2, &pick->node); - ellInsert(&list2, NULL, &pick->node); /* move #18 to top */ - testOk1(ellCount(&list2) == 21); - testOk1(((struct myItem *)list2.node.next)->num == 18); - - testOk1(ellFind(&list2, ellNth(&list2, 21)) == 21); - - pick = (struct myItem *)ellGet(&list2); - pitem = (struct myItem *)ellNth(&list2, 17); - ellInsert(&list2, &pitem->node, &pick->node); - testOk1(ellFind(&list2, ellNth(&list2, 21)) == 21); - - testOk1(((struct myItem *)ellFirst(&list2))->num == 1); - testOk1(((struct myItem *)ellNth(&list2,17))->num == 17); - testOk1(((struct myItem *)ellNth(&list2,18))->num == 18); - - pick = (struct myItem *)ellLast(&list2); - pitem = (struct myItem *) malloc(sizeof(struct myItem)); - ellInsert(&list2, &pick->node, &pitem->node); - testOk1(ellCount(&list2) == 22); - testOk1(ellFind(&list2, ellNth(&list2, 22)) == 22); - - ellDelete(&list2, &pitem->node); - free(pitem); - - ellExtract(&list2, ellNth(&list2,9), ellNth(&list2, 19), &list1); - testOk1(ellCount(&list2) == 10); - testOk1(ellCount(&list1) == 11); - - testOk1(ellFind(&list2, ellNth(&list2, 10)) == 10); - testOk1(ellFind(&list1, ellNth(&list1, 11)) == 11); - - ellFree(&list2); - testOk1(ellCount(&list2) == 0); - - pick = (struct myItem *)ellFirst(&list1); - i1 = 1; - while(pick != NULL) { - pick->num = i1++; - pick = (struct myItem *)ellNext(&pick->node); - } - pick = (struct myItem *)ellFirst(&list1); - testOk1(pick != NULL); - - pitem = (struct myItem *)ellNStep(&pick->node, 3); - testOk1(pitem != NULL); - testOk1(pitem->num == 4); - - pitem = (struct myItem *)ellNStep(&pick->node, 30); - testOk1(pitem == NULL); - - pitem = (struct myItem *)ellNStep(&pick->node, 10); - testOk1(pitem != NULL); - testOk1(pitem->num == 11); - - pitem = (struct myItem *)ellNStep(&pitem->node, 0); - testOk1(pitem->num == 11); - - pitem = (struct myItem *)ellNStep(&pitem->node, -4); - testOk1(pitem->num == 7); - - ellFree2(&list1, free); - testOk1(ellCount(&list1) == 0); -} - -typedef struct { int A, B; } input_t; - -static int myItemCmp(const ELLNODE *a, const ELLNODE *b) -{ - struct myItem *A = CONTAINER(a, struct myItem, node), - *B = CONTAINER(b, struct myItem, node); - - if (A->num < B->num) return -1; - else if(A->num > B->num) return 1; - else if(A->list < B->list) return -1; - else if(A->list > B->list) return 1; - else return 0; -} - -static const input_t input[] = { - {-4, 0}, - {-5, 0}, - {0,0}, - {50,0}, - {0,1}, - {5,0}, - {5,1} -}; - -static -void testSort(const input_t *inp, size_t ninp) -{ - unsigned i; - ELLLIST list = ELLLIST_INIT; - struct myItem *alloc = calloc(ninp, sizeof(*alloc)); - - if(!alloc) testAbort("testSort allocation fails"); - - for(i=0; inum = inp[i].A; - it->list= inp[i].B; - - ellAdd(&list, &it->node); - } - - ellSortStable(&list, &myItemCmp); - - testOk(ellCount(&list)==ninp, "output length %u == %u", (unsigned)ellCount(&list), (unsigned)ninp); - if(ellCount(&list)==0) { - testSkip(ninp-1, "all items lost"); - } - - { - struct myItem *prev = CONTAINER(ellFirst(&list), struct myItem, node), - *next; - - for(next = CONTAINER(ellNext(&prev->node), struct myItem, node); - next; - prev = next, next = CONTAINER(ellNext(&next->node), struct myItem, node)) - { - int cond = (prev->numnum) || (prev->num==next->num && prev->listlist); - testOk(cond, "%d:%d < %d:%d", prev->num, prev->list, next->num, next->list); - } - } -} - -MAIN(epicsEllTest) -{ - testPlan(77); - - testList(); - testSort(input, NELEMENTS(input)); - - return testDone(); -} diff --git a/src/libCom/test/epicsEnvTest.c b/src/libCom/test/epicsEnvTest.c deleted file mode 100644 index bbce4b749..000000000 --- a/src/libCom/test/epicsEnvTest.c +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsEnvTest.c */ - -/* Author: Andrew Johnson - * Date: 2013-12-13 - */ - -/* Check environment variable APIs. - * TODO: Add tests for envDefs.h routines. - * - * The thread test is needed on VxWorks 6.x, where the OS can be - * configured to maintain separate, totally independent sets - * of environment variables for each thread. This configuration - * is not supported by EPICS which expects child threads to at - * least inherit the partent thread's environment variables. - */ - -#include -#include - -#include "envDefs.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define PARENT "Parent" -#define CHILD "Child" - -static void child(void *arg) -{ - const char *value = getenv(PARENT); - - if (!testOk(value && (strcmp(value, PARENT) == 0), - "Child thread sees parent environment values")) { -#ifdef vxWorks - testDiag("VxWorks image needs ENV_VAR_USE_HOOKS configured as FALSE"); -#else - testDiag("Check OS configuration, environment inheritance needed"); -#endif - } - - epicsEnvSet(CHILD, CHILD); -} - -MAIN(epicsEnvTest) -{ - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - const char *value; - - testPlan(3); - - epicsEnvSet(PARENT, PARENT); - - value = getenv(PARENT); - if (!testOk(value && (strcmp(value, PARENT) == 0), - "epicsEnvSet correctly modifies environment")) - testAbort("environment variables not working"); - - epicsThreadCreate("child", 50, stackSize, child, NULL); - epicsThreadSleep(0.1); - - value = getenv(CHILD); - if (value && (strcmp(value, CHILD) == 0)) - testDiag("Child and parent threads share a common environment"); - - value = getenv(PARENT); - testOk(value && (strcmp(value, PARENT) == 0), - "PARENT environment variable not modified"); - - testDone(); - return 0; -} - diff --git a/src/libCom/test/epicsErrlogTest.c b/src/libCom/test/epicsErrlogTest.c deleted file mode 100644 index 28d88f6af..000000000 --- a/src/libCom/test/epicsErrlogTest.c +++ /dev/null @@ -1,489 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Michael Davidsaver - * Date: 2010-09-24 - */ - -#include -#include -#include - -#include "epicsAssert.h" -#include "epicsThread.h" -#include "epicsEvent.h" -#include "dbDefs.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" -#include "iocLog.h" -#include "logClient.h" -#include "envDefs.h" -#include "osiSock.h" -#include "fdmgr.h" - -#define LOGBUFSIZE 2048 - -static -const char longmsg[]="A0123456789abcdef" - "B0123456789abcdef" - "C0123456789abcdef" - "D0123456789abcdef" - "E0123456789abcdef" - "F0123456789abcdef" - "G0123456789abcdef" - "H0123456789abcdef" - "I0123456789abcdef" - "J0123456789abcdef" - "K0123456789abcdef" - "L0123456789abcdef" - "M0123456789abcdef" - "N0123456789abcdef" - "O0123456789abcdef" - "P0123456789abcdef" - "Q0123456789abcdef" - "R0123456789abcdef" - "S0123456789abcdef" - ; -STATIC_ASSERT(NELEMENTS(longmsg)==324); - -static -const char truncmsg[]="A0123456789abcdef" - "B0123456789abcdef" - "C0123456789abcdef" - "D0123456789abcdef" - "E0123456789abcdef" - "F0123456789abcdef" - "G0123456789abcdef" - "H0123456789abcdef" - "I0123456789abcdef" - "J0123456789abcdef" - "K0123456789abcdef" - "L0123456789abcdef" - "M0123456789abcdef" - "N0123456789abcdef" - "O01<>\n" - ; -STATIC_ASSERT(NELEMENTS(truncmsg)==256); - -typedef struct { - unsigned int count; - const char* expect; - size_t checkLen; - epicsEventId jammer; - int jam; -} clientPvt; - -static void testLogPrefix(void); -static void acceptNewClient( void *pParam ); -static void readFromClient( void *pParam ); -static void testPrefixLogandCompare( const char* logmessage); - -static void *pfdctx; -static SOCKET sock; -static SOCKET insock; - -static const char* prefixactualmsg[]= { - "A message without prefix", - "A message with prefix", - "DONE" - }; -static const char *prefixstring = "fac=LI21 "; -static const char prefixexpectedmsg[] = "A message without prefix" - "fac=LI21 A message with prefix" - "fac=LI21 DONE" - ; -static char prefixmsgbuffer[1024]; - - -static -void testEqInt_(int lhs, int rhs, const char *LHS, const char *RHS) -{ - testOk(lhs==rhs, "%s (%d) == %s (%d)", LHS, lhs, RHS, rhs); -} -#define testEqInt(L, R) testEqInt_(L, R, #L, #R); -static -void logClient(void* raw, const char* msg) -{ - clientPvt *pvt = raw; - size_t len; - char show[46]; - - /* Simulate thread priority on non-realtime - * OSs like Linux. This will cause the logging - * thread to sleep with the buffer lock held. - */ - if (pvt->jam > 0) { - pvt->jam = 0; - epicsEventMustWait(pvt->jammer); - } else if (pvt->jam < 0) { - pvt->jam++; - if (pvt->jam == 0) - epicsEventMustWait(pvt->jammer); - } - - len = strlen(msg); - if (len > 45) { - /* Only show start and end of long messages */ - strncpy(show, msg, 20); - show[20] = 0; - strcat(show + 20, " ... "); - strcat(show + 25, msg + len - 20); - } - else { - strcpy(show, msg); - } - - if (pvt->checkLen) - if (!testOk(pvt->checkLen == len, "Received %d chars", (int) len)) { - testDiag("Expected %d", (int) pvt->checkLen); - if (!pvt->expect) - testDiag("Message is \"%s\"", show); - } - - if (pvt->expect) { - if (!testOk(strcmp(pvt->expect, msg) == 0, "Message is \"%s\"", show)) { - len = strlen(pvt->expect); - if (len > 45) { - testDiag("Expected \"%.20s ... %s\"", - pvt->expect, pvt->expect + len - 20); - } - else { - testDiag("Expected \"%s\"", pvt->expect); - } - } - } - - pvt->count++; -} - -MAIN(epicsErrlogTest) -{ - size_t mlen, i, N; - char msg[256]; - clientPvt pvt, pvt2; - - testPlan(32); - - strcpy(msg, truncmsg); - - errlogInit2(LOGBUFSIZE, 256); - - pvt.count = 0; - pvt2.count = 0; - - pvt.expect = NULL; - pvt2.expect = NULL; - - pvt.checkLen = 0; - pvt2.checkLen = 0; - - pvt.jam = 0; - pvt2.jam = 0; - - pvt.jammer = epicsEventMustCreate(epicsEventEmpty); - pvt2.jammer = epicsEventMustCreate(epicsEventEmpty); - - testDiag("Check listener registration"); - - errlogAddListener(&logClient, &pvt); - - pvt.expect = "Testing"; - pvt.checkLen = strlen(pvt.expect); - - errlogPrintfNoConsole("%s", pvt.expect); - errlogFlush(); - - testEqInt(pvt.count, 1); - - errlogAddListener(&logClient, &pvt2); - - pvt2.expect = pvt.expect = "Testing2"; - pvt2.checkLen = pvt.checkLen = strlen(pvt.expect); - - errlogPrintfNoConsole("%s", pvt.expect); - errlogFlush(); - - testEqInt(pvt.count, 2); - testEqInt(pvt2.count, 1); - - /* Removes the first listener */ - testOk(1 == errlogRemoveListeners(&logClient, &pvt), - "Removed 1 listener"); - - pvt2.expect = "Testing3"; - pvt2.checkLen = strlen(pvt2.expect); - - errlogPrintfNoConsole("%s", pvt2.expect); - errlogFlush(); - - testEqInt(pvt.count, 2); - testEqInt(pvt2.count, 2); - - /* Add the second listener again, then remove both instances */ - errlogAddListener(&logClient, &pvt2); - testOk(2 == errlogRemoveListeners(&logClient, &pvt2), - "Removed 2 listeners"); - - errlogPrintfNoConsole("Something different"); - errlogFlush(); - - testEqInt(pvt.count, 2); - testEqInt(pvt2.count, 2); - - /* Re-add one listener */ - errlogAddListener(&logClient, &pvt); - - testDiag("Check truncation"); - - pvt.expect = truncmsg; - pvt.checkLen = 255; - - errlogPrintfNoConsole("%s", longmsg); - errlogFlush(); - - testEqInt(pvt.count, 3); - - pvt.expect = NULL; - - testDiag("Check priority"); - /* For the following tests it is important that - * the buffer should not flush until we request it - */ - pvt.jam = 1; - - errlogPrintfNoConsole("%s", longmsg); - epicsThreadSleep(0.1); - - testEqInt(pvt.count, 3); - - epicsEventSignal(pvt.jammer); - errlogFlush(); - - testEqInt(pvt.count, 4); - - testDiag("Find buffer capacity (%u theoretical)",LOGBUFSIZE); - - pvt.checkLen = 0; - - for (mlen = 8; mlen <= 255; mlen *= 2) { - double eff; - char save = msg[mlen - 1]; - - N = LOGBUFSIZE / mlen; /* # of of messages to send */ - msg[mlen - 1] = '\0'; - pvt.count = 0; - /* pvt.checkLen = mlen - 1; */ - - pvt.jam = 1; - - for (i = 0; i < N; i++) { - errlogPrintfNoConsole("%s", msg); - } - - epicsEventSignal(pvt.jammer); - errlogFlush(); - - eff = (double) (pvt.count * mlen) / LOGBUFSIZE * 100.0; - testDiag(" For %d messages of length %d got %u (%.1f%% efficient)", - (int) N, (int) mlen, pvt.count, eff); - - msg[mlen - 1] = save; - N = pvt.count; /* Save final count for the test below */ - - /* Clear "errlog: messages were discarded" status */ - pvt.checkLen = 0; - errlogPrintfNoConsole("."); - errlogFlush(); - } - - testDiag("Checking buffer use after partial flush"); - - /* Use the numbers from the largest block size above */ - mlen /= 2; - msg[mlen - 1] = '\0'; - - pvt.jam = 1; - pvt.count = 0; - - testDiag("Filling with %d messages of size %d", (int) N, (int) mlen); - - for (i = 0; i < N; i++) { - errlogPrintfNoConsole("%s", msg); - } - epicsThreadSleep(0.1); /* should really be a second Event */ - - testEqInt(pvt.count, 0); - - /* Extract the first 2 messages, 2*(sizeof(msgNode) + 128) bytes */ - pvt.jam = -2; - epicsEventSignal(pvt.jammer); - epicsThreadSleep(0.1); - - testDiag("Drained %u messages", pvt.count); - testEqInt(pvt.count, 2); - - /* The buffer has space for 1 more message: sizeof(msgNode) + 256 bytes */ - errlogPrintfNoConsole("%s", msg); /* Use up that space */ - - testDiag("Overflow the buffer"); - errlogPrintfNoConsole("%s", msg); - - testEqInt(pvt.count, 2); - - epicsEventSignal(pvt.jammer); /* Empty */ - errlogFlush(); - - testDiag("Logged %u messages", pvt.count); - testEqInt(pvt.count, N+1); - - /* Clean up */ - testOk(1 == errlogRemoveListeners(&logClient, &pvt), - "Removed 1 listener"); - - testLogPrefix(); - - return testDone(); -} -/* - * Tests the log prefix code - * The prefix is only applied to log messages as they go out to the socket, - * so we need to create a server listening on a port, accept connections etc. - * This code is a reduced version of the code in iocLogServer. - */ -static void testLogPrefix(void) { - struct sockaddr_in serverAddr; - int status; - struct timeval timeout; - struct sockaddr_in actualServerAddr; - osiSocklen_t actualServerAddrSize; - char portstring[16]; - - - testDiag("Testing iocLogPrefix"); - - timeout.tv_sec = 5; /* in seconds */ - timeout.tv_usec = 0; - - memset((void*)prefixmsgbuffer, 0, sizeof prefixmsgbuffer); - - /* Clear "errlog: messages were discarded" status */ - errlogPrintfNoConsole("."); - errlogFlush(); - - sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - testAbort("epicsSocketCreate failed."); - } - - /* We listen on a an available port. */ - memset((void *)&serverAddr, 0, sizeof serverAddr); - serverAddr.sin_family = AF_INET; - serverAddr.sin_port = htons(0); - - status = bind (sock, (struct sockaddr *)&serverAddr, - sizeof (serverAddr) ); - if (status < 0) { - testAbort("bind failed; all ports in use?"); - } - - status = listen(sock, 10); - if (status < 0) { - testAbort("listen failed!"); - } - - /* Determine the port that the OS chose */ - actualServerAddrSize = sizeof actualServerAddr; - memset((void *)&actualServerAddr, 0, sizeof serverAddr); - status = getsockname(sock, (struct sockaddr *) &actualServerAddr, - &actualServerAddrSize); - if (status < 0) { - testAbort("Can't find port number!"); - } - - sprintf(portstring, "%d", ntohs(actualServerAddr.sin_port)); - testDiag("Listening on port %s", portstring); - - /* Set the EPICS environment variables for logging. */ - epicsEnvSet ( "EPICS_IOC_LOG_INET", "localhost" ); - epicsEnvSet ( "EPICS_IOC_LOG_PORT", portstring ); - - pfdctx = (void *) fdmgr_init(); - if (status < 0) { - testAbort("fdmgr_init failed!"); - } - - status = fdmgr_add_callback(pfdctx, sock, fdi_read, - acceptNewClient, &serverAddr); - - if (status < 0) { - testAbort("fdmgr_add_callback failed!"); - } - - testOk1(iocLogInit() == 0); - fdmgr_pend_event(pfdctx, &timeout); - - testPrefixLogandCompare(prefixactualmsg[0]); - - iocLogPrefix(prefixstring); - testPrefixLogandCompare(prefixactualmsg[1]); - testPrefixLogandCompare(prefixactualmsg[2]); - epicsSocketDestroy(sock); -} - -static void testPrefixLogandCompare( const char* logmessage ) { - struct timeval timeout; - timeout.tv_sec = 5; /* in seconds */ - timeout.tv_usec = 0; - - errlogPrintfNoConsole("%s", logmessage); - errlogFlush(); - iocLogFlush(); - fdmgr_pend_event(pfdctx, &timeout); -} - -static void acceptNewClient ( void *pParam ) -{ - osiSocklen_t addrSize; - struct sockaddr_in addr; - int status; - - addrSize = sizeof ( addr ); - insock = epicsSocketAccept ( sock, (struct sockaddr *)&addr, &addrSize ); - testOk(insock != INVALID_SOCKET && addrSize >= sizeof (addr), - "Accepted new client"); - - status = fdmgr_add_callback(pfdctx, insock, fdi_read, - readFromClient, NULL); - - testOk(status >= 0, "Client read configured"); -} - -static void readFromClient(void *pParam) -{ - char recvbuf[1024]; - int recvLength; - - memset(recvbuf, 0, 1024); - recvLength = recv(insock, recvbuf, 1024, 0); - if (recvLength > 0) { - strcat(prefixmsgbuffer, recvbuf); - - /* If we have received all of the messages. */ - if (strstr(prefixmsgbuffer, "DONE") != NULL) { - size_t msglen = strlen(prefixexpectedmsg); - int prefixcmp = strncmp(prefixexpectedmsg, prefixmsgbuffer, msglen); - - if (!testOk(prefixcmp == 0, "prefix matches")) { - testDiag("Expected '%s'\n", prefixexpectedmsg); - testDiag("Obtained '%s'\n", prefixmsgbuffer); - } - } - } -} diff --git a/src/libCom/test/epicsEventTest.cpp b/src/libCom/test/epicsEventTest.cpp deleted file mode 100644 index 7c1a24141..000000000 --- a/src/libCom/test/epicsEventTest.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsEventTest.cpp */ - -/* Author: Marty Kraimer Date: 26JAN2000 */ -/* timeout accuracy tests by Jeff Hill */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsRingPointer.h" -#include "epicsTime.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -typedef struct info { - epicsEventId event; - epicsMutexId lockRing; - int quit; - epicsRingPointerId ring; -} info; - -extern "C" { - -static void consumer(void *arg) -{ - info *pinfo = (info *)arg; - int errors = 0; - - testDiag("consumer: starting"); - while (!pinfo->quit) { - epicsEventStatus status = epicsEventWait(pinfo->event); - if (status != epicsEventOK) { - testDiag("consumer: epicsEventWait returned %d", status); - errors++; - } - while (epicsRingPointerGetUsed(pinfo->ring) >= 2) { - epicsRingPointerId message[2]; - for (int i = 0; i < 2; i++) { - message[i] = epicsRingPointerPop(pinfo->ring); - if (message[i] == 0) { - testDiag("consumer: epicsRingPointerPop returned 0"); - errors++; - } - } - if (message[0] != message[1]) { - testDiag("consumer: message %p %p\n", message[0], message[1]); - errors++; - } - } - } - testOk(errors == 0, "consumer: errors = %d", errors); -} - -static void producer(void *arg) -{ - info *pinfo = (info *)arg; - const char *name = epicsThreadGetNameSelf(); - epicsThreadId myId = epicsThreadGetIdSelf(); - int errors = 0; - int ntimes = 0; - - testDiag("%s: starting", name); - while(!pinfo->quit) { - ++ntimes; - epicsMutexLockStatus status = epicsMutexLock(pinfo->lockRing); - if (status != epicsMutexLockOK) { - testDiag("%s: epicsMutexLock returned %d", name, status); - errors++; - } - if (epicsRingPointerGetFree(pinfo->ring) >= 2) { - for (int i = 0; i < 2; i++) { - if (!epicsRingPointerPush(pinfo->ring, myId)) { - testDiag("%s: epicsRingPointerPush fail", name); - errors++; - } - if (i == 0 && (ntimes % 4 == 0)) - epicsThreadSleep(0.1); - } - } else { - testFail("%s: ring buffer full", name); - errors++; - } - epicsMutexUnlock(pinfo->lockRing); - epicsThreadSleep(1.0); - epicsEventMustTrigger(pinfo->event); - } - testOk(errors == 0, "%s: errors = %d", name, errors); -} - -#define SLEEPERCOUNT 3 -struct wakeInfo { - epicsEventId event; - epicsMutexId countMutex; - int count; -}; -static void sleeper(void *arg) -{ - struct wakeInfo *wp = (struct wakeInfo *)arg; - epicsEventMustWait(wp->event); - epicsMutexLock(wp->countMutex); - wp->count++; - epicsMutexUnlock(wp->countMutex); -} -static void eventWakeupTest(void) -{ - struct wakeInfo wakeInfo, *wp = &wakeInfo; - int i, c; - - wp->event = epicsEventMustCreate(epicsEventEmpty); - wp->countMutex = epicsMutexMustCreate(); - wp->count = 0; - for (i = 0 ; i < SLEEPERCOUNT ; i++) - epicsThreadCreate("Sleeper", - epicsThreadPriorityScanHigh, - epicsThreadGetStackSize(epicsThreadStackSmall), - sleeper, - wp); - epicsThreadSleep(0.5); - epicsMutexLock(wp->countMutex); - c = wp->count; - epicsMutexUnlock(wp->countMutex); - testOk(c == 0, "all threads still sleeping"); - for (i = 1 ; i <= SLEEPERCOUNT ; i++) { - epicsEventMustTrigger(wp->event); - epicsThreadSleep(0.5); - epicsMutexLock(wp->countMutex); - c = wp->count; - epicsMutexUnlock(wp->countMutex); - testOk(c == i, "%d thread%s awakened, expected %d", c, c == 1 ? "" : "s", i); - } - epicsEventDestroy(wp->event); - epicsMutexDestroy(wp->countMutex); -} - - -} // extern "C" - -static double eventWaitMeasureDelayError( const epicsEventId &id, const double & delay ) -{ - epicsTime beg = epicsTime::getCurrent(); - epicsEventWaitWithTimeout ( id, delay ); - epicsTime end = epicsTime::getCurrent(); - double meas = end - beg; - double error = fabs ( delay - meas ); - testDiag("epicsEventWaitWithTimeout(%.6f) delay error %.6f sec", - delay, error ); - return error; -} - -static void eventWaitTest() -{ - double errorSum = 0.0; - epicsEventId event = epicsEventMustCreate ( epicsEventEmpty ); - int i; - for ( i = 0u; i < 20; i++ ) { - double delay = ldexp ( 1.0 , -i ); - errorSum += eventWaitMeasureDelayError ( event, delay ); - } - errorSum += eventWaitMeasureDelayError ( event, 0.0 ); - epicsEventDestroy ( event ); - double meanError = errorSum / ( i + 1 ); - testOk(meanError < 0.05, "Average error %.6f sec", meanError); -} - - -MAIN(epicsEventTest) -{ - const int nthreads = 3; - epicsThreadId *id; - char **name; - epicsEventId event; - int status; - - testPlan(13+SLEEPERCOUNT); - - event = epicsEventMustCreate(epicsEventEmpty); - - status = epicsEventWaitWithTimeout(event, 0.0); - testOk(status == epicsEventWaitTimeout, - "epicsEventWaitWithTimeout(event, 0.0) = %d", status); - - status = epicsEventWaitWithTimeout(event, 1.0); - testOk(status == epicsEventWaitTimeout, - "epicsEventWaitWithTimeout(event, 1.0) = %d", status); - - status = epicsEventTryWait(event); - testOk(status == epicsEventWaitTimeout, - "epicsEventTryWait(event) = %d", status); - - status = epicsEventTrigger(event); - testOk(status == epicsEventOK, - "epicsEventTrigger(event) = %d", status); - status = epicsEventWaitWithTimeout(event, 1.0); - testOk(status == epicsEventOK, - "epicsEventWaitWithTimeout(event, 1.0) = %d", status); - - epicsEventMustTrigger(event); - status = epicsEventWaitWithTimeout(event,DBL_MAX); - testOk(status == epicsEventOK, - "epicsEventWaitWithTimeout(event, DBL_MAX) = %d", status); - - epicsEventMustTrigger(event); - status = epicsEventTryWait(event); - testOk(status == epicsEventOK, - "epicsEventTryWait(event) = %d", status); - - info *pinfo = (info *)calloc(1,sizeof(info)); - pinfo->event = event; - pinfo->lockRing = epicsMutexCreate(); - pinfo->ring = epicsRingPointerCreate(1024*2); - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - - epicsThreadCreate("consumer", 50, stackSize, consumer, pinfo); - id = (epicsThreadId *)calloc(nthreads, sizeof(epicsThreadId)); - name = (char **)calloc(nthreads, sizeof(char *)); - for(int i = 0; i < nthreads; i++) { - name[i] = (char *)calloc(16, sizeof(char)); - sprintf(name[i],"producer %d",i); - id[i] = epicsThreadCreate(name[i], 40, stackSize, producer, pinfo); - epicsThreadSleep(0.1); - } - epicsThreadSleep(5.0); - - testDiag("setting quit"); - pinfo->quit = 1; - epicsThreadSleep(2.0); - - epicsEventMustTrigger(pinfo->event); - epicsThreadSleep(1.0); - - eventWaitTest(); - eventWakeupTest(); - - free(name); - free(id); - epicsRingPointerDelete(pinfo->ring); - epicsMutexDestroy(pinfo->lockRing); - epicsEventDestroy(event); - free(pinfo); - - return testDone(); -} diff --git a/src/libCom/test/epicsExitTest.c b/src/libCom/test/epicsExitTest.c deleted file mode 100644 index dc901b5ac..000000000 --- a/src/libCom/test/epicsExitTest.c +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsExitTest.cpp */ - -/* Author: Marty Kraimer Date: 09JUL2004*/ - -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsAssert.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -typedef struct info { - char name[64]; - epicsEventId terminate; - epicsEventId terminated; -}info; - -static void atExit(void *pvt) -{ - info *pinfo = (info *)pvt; - testPass("%s reached atExit", pinfo->name); - epicsEventSignal(pinfo->terminate); - /*Now wait for thread to terminate*/ - epicsEventMustWait(pinfo->terminated); - testPass("%s destroying pinfo", pinfo->name); - epicsEventDestroy(pinfo->terminate); - epicsEventDestroy(pinfo->terminated); - free(pinfo); -} - -static void atThreadExit(void *pvt) -{ - info *pinfo = (info *)pvt; - testPass("%s terminating", pinfo->name); - epicsEventSignal(pinfo->terminated); -} - -static void thread(void *arg) -{ - info *pinfo = (info *)arg; - - strcpy(pinfo->name, epicsThreadGetNameSelf()); - testDiag("%s starting", pinfo->name); - pinfo->terminate = epicsEventMustCreate(epicsEventEmpty); - pinfo->terminated = epicsEventMustCreate(epicsEventEmpty); - testOk(!epicsAtExit(atExit, pinfo), "Registered atExit(%p)", pinfo); - testOk(!epicsAtThreadExit(atThreadExit, pinfo), - "Registered atThreadExit(%p)", pinfo); - testDiag("%s waiting for atExit", pinfo->name); - epicsEventMustWait(pinfo->terminate); -} - -int count; - -static void counter(void *pvt) -{ - count++; -} - -static void mainExit(void *pvt) -{ - testPass("Reached mainExit"); - testDone(); -} - -MAIN(epicsExitTest) -{ - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - info *pinfoA = (info *)calloc(1, sizeof(info)); - info *pinfoB = (info *)calloc(1, sizeof(info)); - - testPlan(15); - - testOk(!epicsAtExit(counter, NULL), "Registered counter()"); - count = 0; - epicsExitCallAtExits(); - testOk(count == 1, "counter() called once"); - epicsExitCallAtExits(); - testOk(count == 1, "unregistered counter() not called"); - - testOk(!epicsAtExit(mainExit, NULL), "Registered mainExit()"); - - epicsThreadCreate("threadA", 50, stackSize, thread, pinfoA); - epicsThreadSleep(0.1); - epicsThreadCreate("threadB", 50, stackSize, thread, pinfoB); - epicsThreadSleep(1.0); - - testDiag("Calling epicsExit"); - epicsExit(0); - return 0; -} diff --git a/src/libCom/test/epicsInlineTest1.c b/src/libCom/test/epicsInlineTest1.c deleted file mode 100644 index e377e5f1d..000000000 --- a/src/libCom/test/epicsInlineTest1.c +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* This test checks the variations on inline function defintions. - * - * "static inline int func(void) {...}" - * - * Consistent meaning in C89, C99, and C++ (98 and 11). - * If not inline'd results in a private symbol in each compilation unit. - * Thus the non-inline'd version is duplicated in each compilation unit. - * However, definitions in different compilation units may be different. - * - * "inline int func(void) {...}" - * Warning: Not consistent, avoid use in headers meant for C or C++ - * - * In C++ this may be safely defined in more than one compilation unit. - * Where not inlined it will result in a weak public symbol. - * Thus non-inline'd version isn't duplicated, but must be the same - * in all compilation units. - * - */ - -#include "compilerSpecific.h" -#include "epicsUnitTest.h" - -#include "testMain.h" - -static EPICS_ALWAYS_INLINE int epicsInlineTestFn1(void) -{ - return 1; -} - -/* Fails to link in C99 -inline int epicsInlineTestFn2(void) -{ - return 42; -} -*/ - -void epicsInlineTest1(void) -{ - testDiag("epicsInlineTest1()"); - testOk1(epicsInlineTestFn1()==1); - /*testOk1(epicsInlineTestFn2()==42);*/ -} - -void epicsInlineTest2(void); -void epicsInlineTest3(void); -void epicsInlineTest4(void); - -MAIN(epicsInlineTest) -{ - testPlan(6); - testDiag("Test variation on inline int func()"); - epicsInlineTest1(); - epicsInlineTest2(); - epicsInlineTest3(); - epicsInlineTest4(); - return testDone(); -} diff --git a/src/libCom/test/epicsInlineTest2.c b/src/libCom/test/epicsInlineTest2.c deleted file mode 100644 index b787276fb..000000000 --- a/src/libCom/test/epicsInlineTest2.c +++ /dev/null @@ -1,28 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "compilerSpecific.h" -#include "epicsUnitTest.h" - -static EPICS_ALWAYS_INLINE int epicsInlineTestFn1(void) -{ - return 2; -} - -/* Fails to link in C99 -inline int epicsInlineTestFn2(void) -{ - return 42; -} -*/ - -void epicsInlineTest2(void) -{ - testDiag("epicsInlineTest2()"); - testOk1(epicsInlineTestFn1()==2); - /*testOk1(epicsInlineTestFn2()==42);*/ -} diff --git a/src/libCom/test/epicsInlineTest3.cpp b/src/libCom/test/epicsInlineTest3.cpp deleted file mode 100644 index 9647be6dc..000000000 --- a/src/libCom/test/epicsInlineTest3.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "compilerSpecific.h" -#include "epicsUnitTest.h" - -static EPICS_ALWAYS_INLINE int epicsInlineTestFn1(void) -{ - return 3; -} - -inline int epicsInlineTestFn2(void) -{ - return 42; -} - -extern "C" -void epicsInlineTest3(void) -{ - testDiag("epicsInlineTest3()"); - testOk1(epicsInlineTestFn1()==3); - testOk1(epicsInlineTestFn2()==42); -} diff --git a/src/libCom/test/epicsInlineTest4.cpp b/src/libCom/test/epicsInlineTest4.cpp deleted file mode 100644 index 545b45ffd..000000000 --- a/src/libCom/test/epicsInlineTest4.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "compilerSpecific.h" -#include "epicsUnitTest.h" - -static EPICS_ALWAYS_INLINE int epicsInlineTestFn1(void) -{ - return 4; -} - -inline int epicsInlineTestFn2(void) -{ - return 42; -} - -extern "C" -void epicsInlineTest4(void) -{ - testDiag("epicsInlineTest4()"); - testOk1(epicsInlineTestFn1()==4); - testOk1(epicsInlineTestFn2()==42); -} diff --git a/src/libCom/test/epicsMMIOTest.c b/src/libCom/test/epicsMMIOTest.c deleted file mode 100644 index 939627348..000000000 --- a/src/libCom/test/epicsMMIOTest.c +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Michael Davidsaver - */ - -#include "epicsAssert.h" -#include "epicsEndian.h" -#include "epicsTypes.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#include "epicsMMIO.h" - -#if EPICS_BYTE_ORDER==EPICS_ENDIAN_BIG -#define BE16 0x1234 -#define BE32 0x12345678 -#define LE16 0x3412 -#define LE32 0x78563412 -#else -#define LE16 0x1234 -#define LE32 0x12345678 -#define BE16 0x3412 -#define BE32 0x78563412 -#endif - -union hydra16 { - epicsUInt16 u16; - epicsUInt8 bytes[2]; -}; - -union hydra32 { - epicsUInt32 u32; - epicsUInt8 bytes[4]; -}; - -MAIN(epicsMMIOTest) -{ - epicsUInt8 B; - union hydra16 H16; - union hydra32 H32; - - STATIC_ASSERT(sizeof(H16)==2); - STATIC_ASSERT(sizeof(H32)==4); - - testPlan(14); - - testDiag("8-bit ops"); - - iowrite8(&B, 5); - testOk1(B==5); - testOk1(ioread8(&B)==5); - - testDiag("16-bit ops"); - - nat_iowrite16(&H16.bytes, 0x1234); - testOk1(H16.u16==0x1234); - testOk1(nat_ioread16(&H16.bytes)==0x1234); - - be_iowrite16(&H16.bytes, 0x1234); - testOk1(H16.u16==BE16); - testOk1(be_ioread16(&H16.bytes)==0x1234); - - le_iowrite16(&H16.bytes, 0x1234); - testOk1(H16.u16==LE16); - testOk1(le_ioread16(&H16.bytes)==0x1234); - - testDiag("32-bit ops"); - - nat_iowrite32(&H32.bytes, 0x12345678); - testOk1(H32.u32==0x12345678); - testOk1(nat_ioread32(&H32.bytes)==0x12345678); - - be_iowrite32(&H32.bytes, 0x12345678); - testOk1(H32.u32==BE32); - testOk1(be_ioread32(&H32.bytes)==0x12345678); - - le_iowrite32(&H32.bytes, 0x12345678); - testOk1(H32.u32==LE32); - testOk1(le_ioread32(&H32.bytes)==0x12345678); - - return testDone(); -} diff --git a/src/libCom/test/epicsMathTest.c b/src/libCom/test/epicsMathTest.c deleted file mode 100644 index 8ea763cf0..000000000 --- a/src/libCom/test/epicsMathTest.c +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMathTest.c - * - * Author Marty Kraimer - */ - -#include "epicsUnitTest.h" -#include "epicsMath.h" -#include "testMain.h" - -MAIN(epicsMathTest) -{ - double huge = 1e300; - double tiny = 1e-300; - double c; - - testPlan(35); - - testOk1(!isnan(0.0)); - testOk1(!isinf(0.0)); - - testOk1(!isnan(epicsINF)); - testOk1(isinf(epicsINF)); - testOk1(epicsINF == epicsINF); - testOk1(epicsINF > 0.0); - testOk1(epicsINF - epicsINF != 0.0); - -#if defined(_WIN64) && defined(_MSC_VER) - testTodoBegin("Known failure on windows-x64"); -#endif - testOk1(epicsINF + -epicsINF != 0.0); - testOk1(-epicsINF + epicsINF != 0.0); -#if defined(_WIN64) && defined(_MSC_VER) - testTodoEnd(); -#endif - - testOk1(isnan(epicsINF - epicsINF)); - -#if defined(_WIN64) && defined(_MSC_VER) - testTodoBegin("Known failure on windows-x64"); -#endif - testOk1(isnan(epicsINF + -epicsINF)); - testOk1(isnan(-epicsINF + epicsINF)); -#if defined(_WIN64) && defined(_MSC_VER) - testTodoEnd(); -#endif - - testOk1(isnan(epicsNAN)); - testOk1(!isinf(epicsNAN)); - testOk1(epicsNAN != epicsNAN); - testOk1(!(epicsNAN < epicsNAN)); - testOk1(!(epicsNAN <= epicsNAN)); - testOk1(!(epicsNAN == epicsNAN)); - testOk1(!(epicsNAN >= epicsNAN)); - testOk1(!(epicsNAN > epicsNAN)); - testOk1(isnan(epicsNAN - epicsNAN)); - -#if defined(_WIN64) && defined(_MSC_VER) - testTodoBegin("Known failure on windows-x64"); -#endif - testOk1(isnan(epicsNAN + -epicsNAN)); - testOk1(isnan(-epicsNAN + epicsNAN)); -#if defined(_WIN64) && defined(_MSC_VER) - testTodoEnd(); -#endif - - c = huge / tiny; - testOk(!isnan(c), "!isnan(1e300 / 1e-300)"); - testOk(isinf(c), "isinf(1e300 / 1e-300)"); - testOk(c > 0.0, "1e300 / 1e-300 > 0.0"); - - c = (-huge) / tiny; - testOk(!isnan(c), "!isnan(-1e300 / 1e-300)"); - testOk(isinf(c), "isinf(-1e300 / 1e-300)"); - testOk(c < 0.0, "-1e300 / 1e-300 < 0.0"); - - c = huge / huge; - testOk(!isnan(c), "!isnan(1e300 / 1e300)"); - testOk(!isinf(c), "!isinf(1e300 / 1e300)"); - testOk(c == 1.0, "1e300 / 1e300 == 1.0"); - - c = tiny / tiny; - testOk(!isnan(c), "!isnan(1e-300 / 1e-300)"); - testOk(!isinf(c), "!isinf(1e-300 / 1e-300)"); - testOk(c == 1.0, "1e300 / 1e-300 == 1.0"); - - return testDone(); -} diff --git a/src/libCom/test/epicsMaxThreads.c b/src/libCom/test/epicsMaxThreads.c deleted file mode 100644 index 8d0d06da5..000000000 --- a/src/libCom/test/epicsMaxThreads.c +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMaxThreads.cpp */ - -/* Author: Marty Kraimer Date: 09JUL2004*/ - -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "errlog.h" -#include "testMain.h" - -static epicsEventId started; - -static void thread(void *arg) -{ - epicsEventSignal(started); - epicsThreadSuspendSelf(); -} - -MAIN(epicsMaxThreads) -{ - unsigned int stackSize; - epicsThreadId id; - int i = 0; - - stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - printf("stackSize %d\n",stackSize); - - started = epicsEventMustCreate(epicsEventEmpty); - - while(1) { - id = epicsThreadCreate("thread",50,stackSize,thread,0); - if(!id) break; - i++; - if ((i % 100) == 0) - printf ("Reached %d...\n", i); - epicsEventMustWait(started); - } - - printf("Max number of \"Small\" threads on this OS is %d\n", i); - return 0; -} diff --git a/src/libCom/test/epicsMessageQueueTest.cpp b/src/libCom/test/epicsMessageQueueTest.cpp deleted file mode 100644 index ae090fc47..000000000 --- a/src/libCom/test/epicsMessageQueueTest.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author W. Eric Norum - */ -#include -#include -#include -#include - -#include "epicsMessageQueue.h" -#include "epicsThread.h" -#include "epicsExit.h" -#include "epicsEvent.h" -#include "epicsAssert.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -static const char *msg1 = "1234567890This is a very long message."; -static volatile int sendExit = 0; -static volatile int recvExit = 0; -static epicsEventId finished; -static unsigned int mediumStack; - -/* - * In Numerical Recipes in C: The Art of Scientific Computing (William H. - * Press, Brian P. Flannery, Saul A. Teukolsky, William T. Vetterling; New - * York: Cambridge University Press, 1992 (2nd ed., p. 277)), the follow- - * ing comments are made: - * "If you want to generate a random integer between 1 and 10, you - * should always do it by using high-order bits, as in - * j=1+(int) (10.0*rand()/(RAND_MAX+1.0)); - * and never by anything resembling - * j=1+(rand() % 10); - */ -static int -randBelow(int n) -{ - return (int)((double)n*rand()/(RAND_MAX+1.0)); -} - -extern "C" void -badReceiver(void *arg) -{ - epicsMessageQueue *q = (epicsMessageQueue *)arg; - char cbuf[80]; - int len; - - cbuf[0] = '\0'; - len = q->receive(cbuf, 1); - if (len < 0 && cbuf[0] == '\0') - testPass("receive into undersized buffer returned error (%d)", len); - else if (len == 1 && cbuf[0] == *msg1) - testPass("receive into undersized buffer truncated message"); - else - testFail("receive into undersized buffer returned %d", len); - - epicsThreadSleep(3.0); - - cbuf[0] = '\0'; - len = q->receive(cbuf, 1); - if (len < 0 && cbuf[0] == '\0') - testPass("receive into undersized buffer returned error (%d)", len); - else if (len == 1 && cbuf[0] == *msg1) - testPass("receive into undersized buffer truncated message"); - else - testFail("receive into undersized buffer returned %d", len); -} - -extern "C" void -receiver(void *arg) -{ - epicsMessageQueue *q = (epicsMessageQueue *)arg; - const char *myName = epicsThreadGetNameSelf(); - char cbuf[80]; - int expectmsg[4]; - int len; - int sender, msgNum; - int errors = 0; - - for (sender = 1 ; sender <= 4 ; sender++) - expectmsg[sender-1] = 1; - while (!recvExit) { - cbuf[0] = '\0'; - len = q->receive(cbuf, sizeof cbuf, 5.0); - if (len < 0 && !recvExit) { - testDiag("receiver() received unexpected timeout"); - ++errors; - } - else if (sscanf(cbuf, "Sender %d -- %d", &sender, &msgNum) == 2 && - sender >= 1 && sender <= 4) { - if (expectmsg[sender-1] != msgNum) { - ++errors; - testDiag("%s received %d '%.*s' -- expected %d", - myName, len, len, cbuf, expectmsg[sender-1]); - } - expectmsg[sender-1] = msgNum + 1; - epicsThreadSleep(0.001 * (randBelow(20))); - } - } - for (sender = 1 ; sender <= 4 ; sender++) { - if (expectmsg[sender-1] > 1) - testDiag("Received %d messages from Sender %d", - expectmsg[sender-1]-1, sender); - } - if (!testOk1(errors == 0)) - testDiag("Error count was %d", errors); - testDiag("%s exiting", myName); - epicsEventSignal(finished); -} - -extern "C" void -sender(void *arg) -{ - epicsMessageQueue *q = (epicsMessageQueue *)arg; - char cbuf[80]; - int len; - int i = 0; - - while (!sendExit) { - len = sprintf(cbuf, "%s -- %d.", epicsThreadGetNameSelf(), ++i); - while (q->trySend((void *)cbuf, len) < 0) - epicsThreadSleep(0.005 * (randBelow(5))); - epicsThreadSleep(0.005 * (randBelow(20))); - } - testDiag("%s exiting, sent %d messages", epicsThreadGetNameSelf(), i); -} - -extern "C" void messageQueueTest(void *parm) -{ - epicsThreadId myThreadId = epicsThreadGetIdSelf(); - unsigned int i; - char cbuf[80]; - int len; - int pass; - int want; - - epicsMessageQueue *q1 = new epicsMessageQueue(4, 20); - - testDiag("Simple single-thread tests:"); - i = 0; - testOk1(q1->pending() == 0); - while (q1->trySend((void *)msg1, i ) == 0) { - i++; - testOk(q1->pending() == i, "q1->pending() == %d", i); - } - testOk1(q1->pending() == 4); - - want = 0; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 3); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - - want++; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 2); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - q1->trySend((void *)msg1, i++); - - want++; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 2); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - q1->trySend((void *)msg1, i++); - testOk1(q1->pending() == 3); - - i = 3; - while ((len = q1->receive(cbuf, sizeof cbuf, 1.0)) >= 0) { - --i; - testOk(q1->pending() == i, "q1->pending() == %d", i); - want++; - if (!testOk1((len == want) & (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - } - testOk1(q1->pending() == 0); - - testDiag("Test sender timeout:"); - i = 0; - testOk1(q1->pending() == 0); - while (q1->send((void *)msg1, i, 1.0 ) == 0) { - i++; - testOk(q1->pending() == i, "q1->pending() == %d", i); - } - testOk1(q1->pending() == 4); - - want = 0; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 3); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - - want++; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 2); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - q1->send((void *)msg1, i++, 1.0); - - want++; - len = q1->receive(cbuf, sizeof cbuf); - testOk1(q1->pending() == 2); - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - q1->send((void *)msg1, i++, 1.0); - testOk1(q1->pending() == 3); - - i = 3; - while ((len = q1->receive(cbuf, sizeof cbuf, 1.0)) >= 0) { - --i; - testOk(q1->pending() == i, "q1->pending() == %d", i); - want++; - if (!testOk1((len == want) && (strncmp(msg1, cbuf, len) == 0))) - testDiag("wanted:%d '%.*s' got:%d '%.*s'", - want, want, msg1, len, len, cbuf); - } - testOk1(q1->pending() == 0); - - testDiag("Test receiver with timeout:"); - for (i = 0 ; i < 4 ; i++) - testOk1 (q1->send((void *)msg1, i, 1.0) == 0); - testOk1(q1->pending() == 4); - for (i = 0 ; i < 4 ; i++) - testOk(q1->receive((void *)cbuf, sizeof cbuf, 1.0) == (int)i, - "q1->receive(...) == %d", i); - testOk1(q1->pending() == 0); - testOk1(q1->receive((void *)cbuf, sizeof cbuf, 1.0) < 0); - testOk1(q1->pending() == 0); - - testDiag("Single receiver with invalid size, single sender tests:"); - epicsThreadCreate("Bad Receiver", epicsThreadPriorityMedium, - mediumStack, badReceiver, q1); - epicsThreadSleep(1.0); - testOk(q1->send((void *)msg1, 10) == 0, "Send with waiting receiver"); - epicsThreadSleep(2.0); - testOk(q1->send((void *)msg1, 10) == 0, "Send with no receiver"); - epicsThreadSleep(2.0); - - testDiag("Single receiver, single sender tests:"); - epicsThreadSetPriority(myThreadId, epicsThreadPriorityHigh); - epicsThreadCreate("Receiver one", epicsThreadPriorityMedium, - mediumStack, receiver, q1); - for (pass = 1 ; pass <= 3 ; pass++) { - for (i = 0 ; i < 10 ; i++) { - if (q1->trySend((void *)msg1, i) < 0) - break; - if (pass >= 3) - epicsThreadSleep(0.5); - } - switch (pass) { - case 1: - if (i<6) - testDiag(" priority-based scheduler, sent %d messages", i); - epicsThreadSetPriority(myThreadId, epicsThreadPriorityLow); - break; - case 2: - if (i<10) - testDiag(" scheduler not strict priority, sent %d messages", i); - else - testDiag(" strict priority scheduler, sent 10 messages"); - break; - case 3: - testOk(i == 10, "%d of 10 messages sent with sender pauses", i); - break; - } - epicsThreadSleep(1.0); - } - - /* - * Single receiver, multiple sender tests - */ - testDiag("Single receiver, multiple sender tests:"); - testDiag("This test lasts 60 seconds..."); - testOk(!!epicsThreadCreate("Sender 1", epicsThreadPriorityLow, - mediumStack, sender, q1), - "Created Sender 1"); - testOk(!!epicsThreadCreate("Sender 2", epicsThreadPriorityMedium, - mediumStack, sender, q1), - "Created Sender 2"); - testOk(!!epicsThreadCreate("Sender 3", epicsThreadPriorityHigh, - mediumStack, sender, q1), - "Created Sender 3"); - testOk(!!epicsThreadCreate("Sender 4", epicsThreadPriorityHigh, - mediumStack, sender, q1), - "Created Sender 4"); - - for (i = 0; i < 10; i++) { - testDiag("... %2d", 10 - i); - epicsThreadSleep(6.0); - } - - sendExit = 1; - epicsThreadSleep(1.0); - recvExit = 1; - testDiag("Scheduler exiting"); -} - -MAIN(epicsMessageQueueTest) -{ - testPlan(62); - - finished = epicsEventMustCreate(epicsEventEmpty); - mediumStack = epicsThreadGetStackSize(epicsThreadStackMedium); - - epicsThreadCreate("messageQueueTest", epicsThreadPriorityMedium, - mediumStack, messageQueueTest, NULL); - - epicsEventMustWait(finished); - testDiag("Main thread signalled"); - epicsThreadSleep(1.0); - - return testDone(); -} diff --git a/src/libCom/test/epicsMutexTest.cpp b/src/libCom/test/epicsMutexTest.cpp deleted file mode 100644 index d44e5c0f1..000000000 --- a/src/libCom/test/epicsMutexTest.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsMutexTest.c */ - -/* - * Author: Marty Kraimer Date: 26JAN2000 - * Jeff Hill (added mutex performance test ) - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsMutex.h" -#include "epicsEvent.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -typedef struct info { - int threadnum; - epicsMutexId mutex; - int quit; -}info; - -extern "C" void mutexThread(void * arg) -{ - info *pinfo = (info *)arg; - testDiag("mutexThread %d starting", pinfo->threadnum); - while (pinfo->quit--) { - epicsMutexLockStatus status = epicsMutexLock(pinfo->mutex); - testOk(status == epicsMutexLockOK, - "mutexThread %d epicsMutexLock returned %d", - pinfo->threadnum, (int)status); - epicsThreadSleep(.1); - epicsMutexUnlock(pinfo->mutex); - epicsThreadSleep(.9); - } - testDiag("mutexThread %d exiting", pinfo->threadnum); - return; -} - -inline void lockPair ( epicsMutex & mutex ) -{ - mutex.lock (); - mutex.unlock (); -} - -inline void tenLockPairs ( epicsMutex & mutex ) -{ - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); - lockPair ( mutex ); -} - -inline void tenLockPairsSquared ( epicsMutex & mutex ) -{ - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); - tenLockPairs ( mutex ); -} - -inline void doubleRecursiveLockPair ( epicsMutex & mutex ) -{ - mutex.lock (); - mutex.lock (); - mutex.unlock (); - mutex.unlock (); -} - -inline void tenDoubleRecursiveLockPairs ( epicsMutex & mutex ) -{ - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); - doubleRecursiveLockPair ( mutex ); -} - -inline void tenDoubleRecursiveLockPairsSquared ( epicsMutex & mutex ) -{ - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); - tenDoubleRecursiveLockPairs ( mutex ); -} - -inline void quadRecursiveLockPair ( epicsMutex & mutex ) -{ - mutex.lock (); - mutex.lock (); - mutex.lock (); - mutex.lock (); - mutex.unlock (); - mutex.unlock (); - mutex.unlock (); - mutex.unlock (); -} - -inline void tenQuadRecursiveLockPairs ( epicsMutex & mutex ) -{ - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); - quadRecursiveLockPair ( mutex ); -} - -inline void tenQuadRecursiveLockPairsSquared ( epicsMutex & mutex ) -{ - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); - tenQuadRecursiveLockPairs ( mutex ); -} - -void epicsMutexPerformance () -{ - epicsMutex mutex; - unsigned i; - - // test a single lock pair - epicsTime begin = epicsTime::getCurrent (); - static const unsigned N = 1000; - for ( i = 0; i < N; i++ ) { - tenLockPairsSquared ( mutex ); - } - double delay = epicsTime::getCurrent () - begin; - delay /= N * 100u; // convert to delay per lock pair - delay *= 1e6; // convert to micro seconds - testDiag("lock()*1/unlock()*1 takes %f microseconds", delay); - - // test a two times recursive lock pair - begin = epicsTime::getCurrent (); - for ( i = 0; i < N; i++ ) { - tenDoubleRecursiveLockPairsSquared ( mutex ); - } - delay = epicsTime::getCurrent () - begin; - delay /= N * 100u; // convert to delay per lock pair - delay *= 1e6; // convert to micro seconds - testDiag("lock()*2/unlock()*2 takes %f microseconds", delay); - - // test a four times recursive lock pair - begin = epicsTime::getCurrent (); - for ( i = 0; i < N; i++ ) { - tenQuadRecursiveLockPairsSquared ( mutex ); - } - delay = epicsTime::getCurrent () - begin; - delay /= N * 100u; // convert to delay per lock pair - delay *= 1e6; // convert to micro seconds - testDiag("lock()*4/unlock()*4 takes %f microseconds", delay); -} - -struct verifyTryLock { - epicsMutexId mutex; - epicsEventId done; -}; - -extern "C" void verifyTryLockThread ( void *pArg ) -{ - struct verifyTryLock *pVerify = - ( struct verifyTryLock * ) pArg; - - testOk1(epicsMutexTryLock(pVerify->mutex) == epicsMutexLockTimeout); - epicsEventSignal ( pVerify->done ); -} - -void verifyTryLock () -{ - struct verifyTryLock verify; - - verify.mutex = epicsMutexMustCreate (); - verify.done = epicsEventMustCreate ( epicsEventEmpty ); - - testOk1(epicsMutexTryLock(verify.mutex) == epicsMutexLockOK); - - epicsThreadCreate ( "verifyTryLockThread", 40, - epicsThreadGetStackSize(epicsThreadStackSmall), - verifyTryLockThread, &verify ); - - testOk1(epicsEventWait ( verify.done ) == epicsEventWaitOK); - - epicsMutexUnlock ( verify.mutex ); - epicsMutexDestroy ( verify.mutex ); - epicsEventDestroy ( verify.done ); -} - -MAIN(epicsMutexTest) -{ - const int nthreads = 3; - const int nrounds = 5; - unsigned int stackSize; - epicsThreadId *id; - int i; - char **name; - void **arg; - info **pinfo; - epicsMutexId mutex; - int status; - - testPlan(5 + nthreads * nrounds); - - verifyTryLock (); - - mutex = epicsMutexMustCreate(); - status = epicsMutexLock(mutex); - testOk(status == 0, "epicsMutexLock returned %d", status); - status = epicsMutexTryLock(mutex); - testOk(status == 0, "epicsMutexTryLock returned %d", status); - epicsMutexUnlock(mutex); - epicsMutexUnlock(mutex); - - id = (epicsThreadId *)calloc(nthreads,sizeof(epicsThreadId)); - name = (char **)calloc(nthreads,sizeof(char *)); - arg = (void **)calloc(nthreads,sizeof(void *)); - pinfo = (info **)calloc(nthreads,sizeof(info *)); - stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - for(i=0; ithreadnum = i; - pinfo[i]->mutex = mutex; - pinfo[i]->quit = nrounds; - arg[i] = pinfo[i]; - id[i] = epicsThreadCreate(name[i],40,stackSize, - mutexThread, - arg[i]); - } - epicsThreadSleep(2.0 + nrounds); - - epicsMutexPerformance (); - - free(pinfo); - free(arg); - free(name); - free(id); - epicsMutexDestroy(mutex); - - return testDone(); -} diff --git a/src/libCom/test/epicsRunLibComTests.c b/src/libCom/test/epicsRunLibComTests.c deleted file mode 100644 index c4a76e777..000000000 --- a/src/libCom/test/epicsRunLibComTests.c +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Run libCom tests as a batch. - * - * Do *not* include performance measurements here, they don't help to - * prove functionality (which is the point of this convenience routine). - */ - -#include -#include -#include - -int blockingSockTest(void); -int epicsAlgorithm(void); -int epicsAtomicTest(void); -int epicsCalcTest(void); -int epicsEllTest(void); -int epicsEnvTest(void); -int epicsErrlogTest(void); -int epicsEventTest(void); -int epicsExitTest(void); -int epicsMathTest(void); -int epicsMessageQueueTest(void); -int epicsMMIOTest(void); -int epicsMutexTest(void); -int epicsSockResolveTest(void); -int epicsSpinTest(void); -int epicsStackTraceTest(void); -int epicsStdioTest(void); -int epicsStdlibTest(void); -int epicsStringTest(void); -int epicsThreadHooksTest(void); -int epicsThreadOnceTest(void); -int epicsThreadPoolTest(void); -int epicsThreadPriorityTest(void); -int epicsThreadPrivateTest(void); -int epicsThreadTest(void); -int epicsTimerTest(void); -int epicsTimeTest(void); -#ifdef __rtems__ -int epicsTimeZoneTest(void); -#endif -int epicsTypesTest(void); -int epicsInlineTest(void); -int ipAddrToAsciiTest(void); -int macDefExpandTest(void); -int macLibTest(void); -int ringBytesTest(void); -int ringPointerTest(void); -int taskwdTest(void); - -void epicsRunLibComTests(void) -{ - testHarness(); - - /* - * Thread startup sets some internal variables so do it first - */ - runTest(epicsThreadTest); - - /* - * Timer tests get confused if run after some of the other tests - */ - runTest(epicsTimerTest); - - /* - * Run the regular tests in alphabetical order - */ - runTest(blockingSockTest); - runTest(epicsAlgorithm); - runTest(epicsAtomicTest); - runTest(epicsCalcTest); - runTest(epicsEllTest); - runTest(epicsEnvTest); - runTest(epicsErrlogTest); - runTest(epicsEventTest); - runTest(epicsInlineTest); - runTest(epicsMathTest); - runTest(epicsMessageQueueTest); - runTest(epicsMMIOTest); - runTest(epicsMutexTest); - runTest(epicsSockResolveTest); - runTest(epicsSpinTest); - runTest(epicsStackTraceTest); - runTest(epicsStdioTest); - runTest(epicsStdlibTest); - runTest(epicsStringTest); - runTest(epicsThreadHooksTest); - runTest(epicsThreadOnceTest); - runTest(epicsThreadPoolTest); - runTest(epicsThreadPriorityTest); - runTest(epicsThreadPrivateTest); - runTest(epicsTimeTest); -#ifdef __rtems__ - runTest(epicsTimeZoneTest); -#endif - runTest(epicsTypesTest); - runTest(ipAddrToAsciiTest); - runTest(macDefExpandTest); - runTest(macLibTest); - runTest(ringBytesTest); - runTest(ringPointerTest); - runTest(taskwdTest); - - /* - * Report now in case epicsExitTest dies - */ - testHarnessDone(); - - /* - * epicsExitTest must come last as it never returns - */ - runTest(epicsExitTest); -} diff --git a/src/libCom/test/epicsSockResolveTest.c b/src/libCom/test/epicsSockResolveTest.c deleted file mode 100644 index 8131d9dbf..000000000 --- a/src/libCom/test/epicsSockResolveTest.c +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Brookhaven Science Associates as Operator of -* Brookhaven National Lab. -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -\*************************************************************************/ - -#include "dbDefs.h" -#include "osiSock.h" - -#include "epicsUnitTest.h" -#include "testMain.h" - -#define DEFAULT_PORT 4000 - -typedef struct { - const char *input; - unsigned long IP; - unsigned short port; -} testData; - -static testData okdata[] = { - {"127.0.0.1", 0x7f000001, DEFAULT_PORT}, - {"127.0.0.1:42", 0x7f000001, 42}, - {"localhost", 0x7f000001, DEFAULT_PORT}, - {"localhost:42", 0x7f000001, 42}, - {"2424", 2424, DEFAULT_PORT}, - {"2424:42", 2424, 42}, - {"255.255.255.255", 0xffffffff, DEFAULT_PORT}, - {"255.255.255.255:65535", 0xffffffff, 65535}, -}; - -static const char * baddata[] = { - "127.0.0.1:NaN", - "127.0.0.test", - "127.0.0.test:42", - "16name.invalid", - "16name.invalid:42", - "1.2.3.4.5", - "1.2.3.4.5:6", - "1.2.3.4:5.6", - "256.255.255.255", - "255.256.255.255", - "255.255.256.255", - "255.255.255.256", - "255.255.255.255:65536", -}; - -MAIN(epicsSockResolveTest) -{ - int i; - - testPlan(3*NELEMENTS(okdata) + NELEMENTS(baddata)); - osiSockAttach(); - - { - struct in_addr addr; - - /* See RFCs 2606 and 6761 */ - if (hostToIPAddr("guaranteed.invalid.", &addr) == 0) { - testAbort("hostToIPAddr() is broken, testing not possible"); - } - } - - testDiag("Tests of aToIPAddr"); - - for (i=0; i %d", - okdata[i].input, DEFAULT_PORT, ret); - if (ret) { - testSkip(2, " aToIPAddr() failed"); - } - else { - testOk(addr.sin_addr.s_addr == htonl(okdata[i].IP), " IP correct"); - testOk(addr.sin_port == htons(okdata[i].port), " Port correct"); - } - } - - for (i=0; i %d", - baddata[i], DEFAULT_PORT, ret); - if (ret==0) { - testDiag(" IP=0x%lx, port=%d", - (unsigned long) ntohl(addr.sin_addr.s_addr), - ntohs(addr.sin_port)); - } - } - - osiSockRelease(); - return testDone(); -} diff --git a/src/libCom/test/epicsSpinTest.c b/src/libCom/test/epicsSpinTest.c deleted file mode 100644 index c45348beb..000000000 --- a/src/libCom/test/epicsSpinTest.c +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2012 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - * - * based on epicsMutexTest by Marty Kraimer and Jeff Hill - * - */ - -#include -#include -#include -#include -#include -#include - -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsAtomic.h" -#include "epicsSpin.h" -#include "epicsEvent.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -typedef struct info { - int threadnum; - epicsSpinId spin; - int *counter; - int rounds; - epicsEventId done; -} info; - -#define spinDelay 0.016667 - -void spinThread(void *arg) -{ - info *pinfo = (info *) arg; - testDiag("spinThread %d starting", pinfo->threadnum); - epicsThreadSleep(0.1); /* Try to align threads */ - while (pinfo->rounds--) { - epicsThreadSleep(spinDelay); - epicsSpinLock(pinfo->spin); - pinfo->counter[0]++; - epicsSpinUnlock(pinfo->spin); - } - testDiag("spinThread %d exiting", pinfo->threadnum); - epicsEventSignal(pinfo->done); -} - -static void lockPair(struct epicsSpin *spin) -{ - epicsSpinLock(spin); - epicsSpinUnlock(spin); -} - -static void tenLockPairs(struct epicsSpin *spin) -{ - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); - lockPair(spin); -} - -static void tenLockPairsSquared(struct epicsSpin *spin) -{ - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); - tenLockPairs(spin); -} - -void epicsSpinPerformance () -{ - static const unsigned N = 10000; - unsigned i; - epicsSpinId spin; - epicsTimeStamp begin; - epicsTimeStamp end; - double delay; - - /* Initialize spinlock */ - spin = epicsSpinCreate(); - if (!spin) - testAbort("epicsSpinCreate() returned NULL"); - - /* test a single lock pair */ - epicsTimeGetCurrent(&begin); - for ( i = 0; i < N; i++ ) { - tenLockPairsSquared(spin); - } - epicsTimeGetCurrent(&end); - - delay = epicsTimeDiffInSeconds(&end, &begin); - delay /= N * 100u; /* convert to delay per lock pair */ - delay *= 1e6; /* convert to micro seconds */ - testDiag("lock()*1/unlock()*1 takes %f microseconds", delay); - epicsSpinDestroy(spin); -} - -struct verifyTryLock; - -struct verifyTryLockEnt { - epicsEventId done; - struct verifyTryLock *main; -}; - -struct verifyTryLock { - epicsSpinId spin; - int flag; - struct verifyTryLockEnt *ents; -}; - -static void verifyTryLockThread(void *pArg) -{ - struct verifyTryLockEnt *pVerify = - (struct verifyTryLockEnt *) pArg; - - while(epicsAtomicGetIntT(&pVerify->main->flag)==0) { - int ret = epicsSpinTryLock(pVerify->main->spin); - if(ret!=0) { - epicsAtomicCmpAndSwapIntT(&pVerify->main->flag, 0, ret); - break; - } else - epicsSpinUnlock(pVerify->main->spin); - } - - epicsEventSignal(pVerify->done); -} - -/* Start one thread per CPU which will all try lock - * the same spinlock. They break as soon as one - * fails to take the lock. - */ -static void verifyTryLock() -{ - int N, i; - struct verifyTryLock verify; - - N = epicsThreadGetCPUs(); - if(N==1) { - testSkip(1, "verifyTryLock() only for SMP systems"); - return; - } - - verify.flag = 0; - verify.spin = epicsSpinMustCreate(); - - testDiag("Starting %d spinners", N); - - verify.ents = calloc(N, sizeof(*verify.ents)); - for(i=0; ithreadnum = i; - pinfo[i]->spin = spin; - pinfo[i]->counter = &counter; - pinfo[i]->rounds = nrounds; - pinfo[i]->done = epicsEventMustCreate(epicsEventEmpty); - id[i] = epicsThreadCreate(name[i], 40, stackSize, - spinThread, - pinfo[i]); - } - for (i = 0; i < nthreads; i++) { - epicsEventMustWait(pinfo[i]->done); - epicsEventDestroy(pinfo[i]->done); - free(name[i]); - free(pinfo[i]); - } - testOk(counter == nthreads * nrounds, "Loops run = %d (expecting %d)", - counter, nthreads * nrounds); - - free(pinfo); - free(name); - free(id); - epicsSpinDestroy(spin); - - epicsSpinPerformance(); - - return testDone(); -} diff --git a/src/libCom/test/epicsStackTraceTest.c b/src/libCom/test/epicsStackTraceTest.c deleted file mode 100644 index b89fc7836..000000000 --- a/src/libCom/test/epicsStackTraceTest.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright: Stanford University / SLAC National Laboratory. - * - * EPICS BASE is distributed subject to a Software License Agreement found - * in file LICENSE that is included with this distribution. - * - * Author: Till Straumann , 2014 - */ - -/* - * Check stack trace functionality - */ - -#include "epicsStackTrace.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#include -#include -#include - -#define TST_BUFSZ 10000 - -#define MAXP 10 - -/* estimated size of (compiled) epicsStackTraceRecurseGbl */ -#define WINDOW_SZ 400 - -typedef struct TestDataRec_ { - char buf[TST_BUFSZ]; - int pos; -} TestDataRec, *TestData; - -typedef void (*RecFn)(int); - -/* We want a stack trace and need a few nested routines. - * The whole magic here is intended to prevent a compiler - * from optimizing the call stack away: - * - call via a volatile pointer - * - add a call to a no-op function at the end so that - * tail-call optimization doesn't eliminate the call - * stack. - * - * We use a local (static) and a global routine to test - * if the stacktrace supports either flavor. - */ - -void epicsStackTraceRecurseGbl(int lvl); -static void epicsStackTraceRecurseLcl(int lvl); - -void nopFn(int lvl) -{ -} - -RecFn volatile lfp = epicsStackTraceRecurseLcl; -RecFn volatile gfp = epicsStackTraceRecurseGbl; -RecFn volatile nfp = nopFn; - -static void -epicsStackTraceRecurseLcl(int lvl) -{ - if ( lvl ) - gfp(lvl-1); - else - epicsStackTrace(); - - /* call something so that the call through gfp() doesn't - * get optimized into a jump (tail-call optimization) - */ - nfp(0); -} - -void epicsStackTraceRecurseGbl(int lvl) -{ - if ( lvl ) - lfp(lvl-1); - else - epicsStackTrace(); - - /* call something so that the call through gfp() doesn't - * get optimized into a jump (tail-call optimization) - */ - nfp(0); -} - -static void logClient(void *ptr, const char *msg) -{ - TestData td = ptr; - size_t sz = strlen(msg); - size_t mx = sizeof(td->buf) - td->pos - 1; - - if ( sz > mx ) - sz = mx; - strncpy( td->buf+td->pos, msg, sz ); - td->pos += sz; -} - -static int -findStringOcc(const char *buf, const char *what) -{ - int rval = 0; - size_t l = strlen(what); - int ch; - - while ( (buf = strstr(buf, what)) ) { - /* Is it just a prefix? */ - ch = buf[l]; - if ( ! isalnum(ch) && '_' != ch ) { - rval++; - } - buf += l; - } - - testDiag("found %i x %s\n", rval, what); - - return rval; -} - -static int -findNumOcc(const char *buf) -{ - void *ptrs[MAXP]; - int n_ptrs = 0; - int i,j; - int rval = 0; - - while ( n_ptrs < sizeof(ptrs)/sizeof(ptrs[0]) && (buf=strchr(buf,'[')) ) { - if ( 1 == sscanf(buf+1,"%p", &ptrs[n_ptrs]) ) - n_ptrs++; - buf++; - } - /* We should find an address close to epicsStackTraceRecurseGbl twice */ - for (i=0; i= (char*)epicsStackTraceRecurseGbl && (char*)ptrs[i] < (char*)epicsStackTraceRecurseGbl + WINDOW_SZ ) { - rval ++; - testDiag("found address %p again\n", ptrs[i]); - } - } - j++; - } - } - return rval; -} - -MAIN(epicsStackTraceTest) -{ - int features, all_features; - TestDataRec testData; - int gblFound, lclFound, numFound, dynFound; - char *nl, *p; - - testData.pos = 0; - - testPlan(5); - - features = epicsStackTraceGetFeatures(); - - all_features = EPICS_STACKTRACE_LCL_SYMBOLS - | EPICS_STACKTRACE_GBL_SYMBOLS - | EPICS_STACKTRACE_DYN_SYMBOLS - | EPICS_STACKTRACE_ADDRESSES; - - if ( ! testOk( (features & ~all_features) == 0, - "epicsStackTraceGetFeatures() obtains features") ) - testAbort("epicsStackTraceGetFeatures() not working as expected"); - - testData.pos = 0; - - testDiag("calling a few nested routines and eventually dump a stack trace"); - - eltc(0); - errlogAddListener( logClient, &testData ); - gfp(3); - errlogRemoveListeners( logClient, &testData ); - eltc(1); - - /* ensure there's a terminating NUL -- we have reserved space for it */ - testData.buf[testData.pos] = 0; - - testDiag("now scan the result for what we expect"); - - dynFound = findStringOcc( testData.buf, "epicsStackTrace" ); - gblFound = findStringOcc( testData.buf, "epicsStackTraceRecurseGbl" ); - lclFound = findStringOcc( testData.buf, "epicsStackTraceRecurseLcl" ); - numFound = findNumOcc ( testData.buf ); - - if ( (features & EPICS_STACKTRACE_DYN_SYMBOLS) ) { - testOk( dynFound == 1, "dumping symbol from library" ); - } else { - testSkip(1, "no support for dumping library symbols on this platform"); - } - - if ( (features & EPICS_STACKTRACE_GBL_SYMBOLS) ) { - testOk( gblFound == 2, "dumping global symbols" ); - } else { - testSkip(1, "no support for dumping global symbols on this platform"); - } - - if ( (features & EPICS_STACKTRACE_LCL_SYMBOLS) ) { - testOk( lclFound == 2, "dumping local symbols" ); - } else { - testSkip(1, "no support for dumping local symbols on this platform"); - } - - if ( (features & EPICS_STACKTRACE_ADDRESSES) ) { - testOk( numFound > 0, "dumping addresses" ); - } else { - testSkip(1 , "no support for dumping addresses on this platform"); - } - - p = testData.buf; - while ( (nl = strchr(p,'\n')) ) { - *nl = 0; - testDiag("%s",p); - *nl = '\n'; - p = nl+1; - } - testDiag("%s", p); - - testDone(); - - return 0; -} diff --git a/src/libCom/test/epicsStdioTest.c b/src/libCom/test/epicsStdioTest.c deleted file mode 100644 index bf25784a5..000000000 --- a/src/libCom/test/epicsStdioTest.c +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsStdioTest.c - * - * Author Marty Kraimer - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsStdio.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -#define LINE_1 "# This is first line of sample report\n" -#define LINE_2 "# This is second and last line of sample report\n" - -static void testEpicsSnprintf(void) { - char exbuffer[80], buffer[80]; - const int ivalue = 1234; - const float fvalue = 1.23e4f; - const char *svalue = "OneTwoThreeFour"; - const char *format = "int %d float %8.2e string %s"; - const char *expected = exbuffer; - int size; - int rtn, rlen; - -#ifdef _WIN32 -#if (defined(_MSC_VER) && _MSC_VER < 1900) || \ - (defined(_MINGW) && defined(_TWO_DIGIT_EXPONENT)) - _set_output_format(_TWO_DIGIT_EXPONENT); -#endif -#endif - - sprintf(exbuffer, format, ivalue, fvalue, svalue); - rlen = strlen(expected)+1; - - strcpy(buffer, "AAAA"); - - for (size = 1; size < strlen(expected) + 5; ++size) { - rtn = epicsSnprintf(buffer, size, format, ivalue, fvalue, svalue); - testOk(rtn <= rlen-1, "epicsSnprintf(size=%d) = %d", size, rtn); - if (rtn != rlen-1) - testDiag("Return value does not indicate buffer size needed"); - testOk(strncmp(buffer, expected, size - 1) == 0, - "buffer = '%s'", buffer); - rtn = strlen(buffer); - testOk(rtn == (size < rlen ? size : rlen) - 1, - "length = %d", rtn); - } -} - -void testStdoutRedir (const char *report) -{ - FILE *realStdout = stdout; - FILE *stream = 0; - char linebuf[80]; - size_t buflen = sizeof linebuf; - - testOk1(epicsGetStdout() == stdout); - - errno = 0; - if (!testOk1((stream = fopen(report, "w")) != NULL)) { - testDiag("'%s' could not be opened for writing: %s", - report, strerror(errno)); - testSkip(11, "Can't create stream file"); - return; - } - - epicsSetThreadStdout(stream); - testOk1(stdout == stream); - - printf(LINE_1); - printf(LINE_2); - - epicsSetThreadStdout(0); - testOk1(epicsGetStdout() == realStdout); - testOk1(stdout == realStdout); - - errno = 0; - if (!testOk1(!fclose(stream))) { - testDiag("fclose error: %s", strerror(errno)); -#ifdef vxWorks - testDiag("The above test fails if you don't cd to a writable directory"); - testDiag("before running the test. The next test will also fail..."); -#endif - } - - if (!testOk1((stream = fopen(report, "r")) != NULL)) { - testDiag("'%s' could not be opened for reading: %s", - report, strerror(errno)); - testSkip(6, "Can't reopen stream file."); - return; - } - - if (!testOk1(fgets(linebuf, buflen, stream) != NULL)) { - testDiag("File read error: %s", strerror(errno)); - testSkip(5, "Read failed."); - fclose(stream); - return; - } - testOk(strcmp(linebuf, LINE_1) == 0, "First line correct"); - - if (!testOk1(fgets(linebuf, buflen, stream) != NULL)) { - testDiag("File read error: %s", strerror(errno)); - testSkip(1, "No line to compare."); - } else - testOk(strcmp(linebuf, LINE_2) == 0, "Second line"); - - testOk(!fgets(linebuf, buflen, stream), "File ends"); - - if (!testOk1(!fclose(stream))) - testDiag("fclose error: %s\n", strerror(errno)); -} - -MAIN(epicsStdioTest) -{ - testPlan(163); - testEpicsSnprintf(); -#ifdef __rtems__ - /* ensure there is a writeable area */ - mkdir( "/tmp", S_IRWXU ); - testStdoutRedir("/tmp/report"); -#else - testStdoutRedir("report"); -#endif - return testDone(); -} diff --git a/src/libCom/test/epicsStdlibTest.c b/src/libCom/test/epicsStdlibTest.c deleted file mode 100644 index d82f834b8..000000000 --- a/src/libCom/test/epicsStdlibTest.c +++ /dev/null @@ -1,567 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsStdlibTest.c - * - * Author Andrew Johnson - */ - -#include -#include -#include -#include - -#include "epicsTypes.h" -#include "epicsStdlib.h" -#include "epicsMath.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -/* Implement the epicsParseDouble() API for checking the native stdtod() - * so we can tell the user if our epicsStrtod() wrapper is unnecessary. - */ -int -parseStrtod(const char *str, double *to, char **units) -{ - int c; - char *endp; - double value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtod(str, &endp); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == ERANGE) - return (value == 0) ? S_stdlib_underflow : S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} -#define scanStrtod(str, to) !parseStrtod(str, to, NULL) - - -MAIN(epicsStdlibTest) -{ - unsigned long u; - long l; - unsigned long long ull; - long long ll; - double d; - float f; - char *endp; - epicsInt8 i8; - epicsUInt8 u8; - epicsInt16 i16; - epicsUInt16 u16; - epicsInt32 i32; - epicsUInt32 u32; - epicsInt64 i64; - epicsUInt64 u64; - - testPlan(199); - - testOk(epicsParseLong("", &l, 0, NULL) == S_stdlib_noConversion, - "Long '' => noConversion"); - testOk(epicsParseULong("", &u, 0, NULL) == S_stdlib_noConversion, - "ULong '' => noConversion"); - testOk(epicsParseLLong("", &ll, 0, NULL) == S_stdlib_noConversion, - "LLong '' => noConversion"); - testOk(epicsParseULLong("", &ull, 0, NULL) == S_stdlib_noConversion, - "ULLong '' => noConversion"); - testOk(epicsParseFloat("", &f, NULL) == S_stdlib_noConversion, - "Float '' => noConversion"); - testOk(epicsParseDouble("", &d, NULL) == S_stdlib_noConversion, - "Double '' => noConversion"); - - testOk(epicsParseLong("\t \n", &l, 0, NULL) == S_stdlib_noConversion, - "Long '\\t 1\\n' => noConversion"); - testOk(epicsParseULong("\t \n", &u, 0, NULL) == S_stdlib_noConversion, - "ULong '\\t 1\\n' => noConversion"); - testOk(epicsParseLLong("\t \n", &ll, 0, NULL) == S_stdlib_noConversion, - "LLong '\\t 1\\n' => noConversion"); - testOk(epicsParseULLong("\t \n", &ull, 0, NULL) == S_stdlib_noConversion, - "ULLong '\\t 1\\n' => noConversion"); - testOk(epicsParseFloat("\t \n", &f, NULL) == S_stdlib_noConversion, - "Float '\\t 1\\n' => noConversion"); - testOk(epicsParseDouble("\t \n", &d, NULL) == S_stdlib_noConversion, - "Double '\\t 1\\n' => noConversion"); - - testOk(epicsParseLong("!", &l, 0, NULL) == S_stdlib_noConversion, - "Long '!' => noConversion"); - testOk(epicsParseULong("!", &u, 0, NULL) == S_stdlib_noConversion, - "ULong '!' => noConversion"); - testOk(epicsParseLLong("!", &ll, 0, NULL) == S_stdlib_noConversion, - "LLong '!' => noConversion"); - testOk(epicsParseULLong("!", &ull, 0, NULL) == S_stdlib_noConversion, - "ULLong '!' => noConversion"); - testOk(epicsParseFloat("!", &f, NULL) == S_stdlib_noConversion, - "Float '!' => noConversion"); - testOk(epicsParseDouble("!", &d, NULL) == S_stdlib_noConversion, - "Double '!' => noConversion"); - - testOk(epicsScanLong("0", &l, 0) && l == 0, "Long '0'"); - testOk(epicsScanULong("0", &u, 0) && u == 0, "ULong '0'"); - testOk(epicsScanLLong("0", &ll, 0) && ll == 0, "LLong '0'"); - testOk(epicsScanULLong("0", &ull, 0) && ull == 0, "ULLong '0'"); - testOk(epicsScanFloat("0", &f) && f == 0, "Float '0'"); - testOk(epicsScanDouble("0", &d) && d == 0, "Double '0'"); - - testOk(epicsScanLong("\t 1\n", &l, 0) && l == 1, "Long '\\t 1\\n'"); - testOk(epicsScanULong("\t 1\n", &u, 0) && u == 1, "ULong '\\t 1\\n'"); - testOk(epicsScanLLong("\t 1\n", &ll, 0) && ll == 1, "LLong '\\t 1\\n'"); - testOk(epicsScanULLong("\t 1\n", &ull, 0) && ull == 1, "ULLong '\\t 1\\n'"); - testOk(epicsScanFloat("\t 1\n", &f) && f == 1, "Float '\\t 1\\n'"); - testOk(epicsScanDouble("\t 1\n", &d) && d == 1, "Double '\\t 1\\n'"); - - testOk(epicsScanLong("-1", &l, 0) && l == -1, "Long '-1'"); - testOk(epicsScanULong("-1", &u, 0) && u + 1 == 0, "ULong '-1'"); - testOk(epicsScanLLong("-1", &ll, 0) && ll == -1, "LLong '-1'"); - testOk(epicsScanULLong("-1", &ull, 0) && ull + 1 == 0, "ULLong '-1'"); - testOk(epicsScanFloat("-1", &f) && f == -1, "Float '-1'"); - testOk(epicsScanDouble("-1", &d) && d == -1, "Double '-1'"); - - testOk(epicsParseLong("2!", &l, 0, NULL) == S_stdlib_extraneous, - "Long '2!' => extraneous"); - testOk(epicsParseULong("2!", &u, 0, NULL) == S_stdlib_extraneous, - "ULong '2!' => extraneous"); - testOk(epicsParseLLong("2!", &ll, 0, NULL) == S_stdlib_extraneous, - "LLong '2!' => extraneous"); - testOk(epicsParseULLong("2!", &ull, 0, NULL) == S_stdlib_extraneous, - "ULLong '2!' => extraneous"); - testOk(epicsParseFloat("2!", &f, NULL) == S_stdlib_extraneous, - "Float '2!' => extraneous"); - testOk(epicsParseDouble("2!", &d, NULL) == S_stdlib_extraneous, - "Double '2!' => extraneous"); - - testOk(epicsParseLong("3 \n\t!", &l, 0, NULL) == S_stdlib_extraneous, - "Long '3 \\n\\t!' => extraneous"); - testOk(epicsParseULong("3 \n\t!", &u, 0, NULL) == S_stdlib_extraneous, - "ULong '3 \\n\\t!' => extraneous"); - testOk(epicsParseLLong("3 \n\t!", &ll, 0, NULL) == S_stdlib_extraneous, - "LLong '3 \\n\\t!' => extraneous"); - testOk(epicsParseULLong("3 \n\t!", &ull, 0, NULL) == S_stdlib_extraneous, - "ULLong '3 \\n\\t!' => extraneous"); - testOk(epicsParseFloat("3 \n\t!", &f, NULL) == S_stdlib_extraneous, - "Float '3 \\n\\t!' => extraneous"); - testOk(epicsParseDouble("3 \n\t!", &d, NULL) == S_stdlib_extraneous, - "Double '3 \\n\\t!' => extraneous"); - - testOk(!epicsParseLong("2!", &l, 0, &endp) && *endp == '!', - "Long '2!' => units='!'"); - testOk(!epicsParseULong("2!", &u, 0, &endp) && *endp == '!', - "ULong '2!' => units='!'"); - testOk(!epicsParseLLong("2!", &ll, 0, &endp) && *endp == '!', - "LLong '2!' => units='!'"); - testOk(!epicsParseULLong("2!", &ull, 0, &endp) && *endp == '!', - "ULLong '2!' => units='!'"); - testOk(!epicsParseFloat("2!", &f, &endp) && *endp == '!', - "Float '2!' => units='!'"); - testOk(!epicsParseDouble("2!", &d, &endp) && *endp == '!', - "Double '2!' => units='!'"); - - testOk(!epicsParseLong("3 \n\t!", &l, 0, &endp) && *endp == '!', - "Long '3 \\n\\t!' => units='!'"); - testOk(!epicsParseULong("3 \n\t!", &u, 0, &endp) && *endp == '!', - "ULong '3 \\n\\t!' => units='!'"); - testOk(!epicsParseLLong("3 \n\t!", &ll, 0, &endp) && *endp == '!', - "LLong '3 \\n\\t!' => units='!'"); - testOk(!epicsParseULLong("3 \n\t!", &ull, 0, &endp) && *endp == '!', - "ULLong '3 \\n\\t!' => units='!'"); - testOk(!epicsParseFloat("3 \n\t!", &f, &endp) && *endp == '!', - "Float '3 \\n\\t!' => units='!'"); - testOk(!epicsParseDouble("3 \n\t!", &d, &endp) && *endp == '!', - "Double '3 \\n\\t!' => units='!'"); - - testOk(epicsScanLong("0x0", &l, 0) && l == 0, "Long '0x0'"); - testOk(epicsScanULong("0x0", &u, 0) && u == 0, "ULong '0x0'"); - testOk(epicsScanLLong("0x0", &ll, 0) && ll == 0, "LLong '0x0'"); - testOk(epicsScanULLong("0x0", &ull, 0) && ull == 0, "ULLong '0x0'"); - testOk(epicsScanFloat("0x0", &f) && f == 0, "Float '0x0'"); - testOk(epicsScanDouble("0x0", &d) && d == 0, "Double '0x0'"); - - testOk(epicsScanLong("0x1", &l, 0) && l == 1, "Long '0x1'"); - testOk(epicsScanULong("0x1", &u, 0) && u == 1, "ULong '0x1'"); - testOk(epicsScanLLong("0x1", &ll, 0) && ll == 1, "LLong '0x1'"); - testOk(epicsScanULLong("0x1", &ull, 0) && ull == 1, "ULLong '0x1'"); - testOk(epicsScanFloat("0x1", &f) && f == 1, "Float '0x1'"); - testOk(epicsScanDouble("0x1", &d) && d == 1, "Double '0x1'"); - - testOk(epicsScanLong("+0x1", &l, 0) && l == 1, "Long '+0x1'"); - testOk(epicsScanULong("+0x1", &u, 0) && u == 1, "ULong '+0x1'"); - testOk(epicsScanLLong("+0x1", &ll, 0) && ll == 1, "LLong '+0x1'"); - testOk(epicsScanULLong("+0x1", &ull, 0) && ull == 1, "ULLong '+0x1'"); - testOk(epicsScanFloat("+0x1", &f) && f == 1, "Float '+0x1'"); - testOk(epicsScanDouble("+0x1", &d) && d == 1, "Double '+0x1'"); - - testOk(epicsScanLong("-0x1", &l, 0) && l == -1, "Long '-0x1'"); - testOk(epicsScanULong("-0x1", &u, 0) && u == -1, "ULong '-0x1'"); - testOk(epicsScanLLong("-0x1", &ll, 0) && ll == -1, "LLong '-0x1'"); - testOk(epicsScanULLong("-0x1", &ull, 0) && ull == -1, "ULLong '-0x1'"); - testOk(epicsScanFloat("-0x1", &f) && f == -1, "Float '-0x1'"); - testOk(epicsScanDouble("-0x1", &d) && d == -1, "Double '-0x1'"); - - testOk(epicsScanLong("0xf", &l, 0) && l == 15, "Long '0xf'"); - testOk(epicsScanULong("0xf", &u, 0) && u == 15, "ULong '0xf'"); - testOk(epicsScanLLong("0xf", &ll, 0) && ll == 15, "LLong '0xf'"); - testOk(epicsScanULLong("0xf", &ull, 0) && ull == 15, "ULLong '0xf'"); - testOk(epicsScanFloat("0xf", &f) && f == 15, "Float '0xf'"); - testOk(epicsScanDouble("0xf", &d) && d == 15, "Double '0xf'"); - - testOk(epicsScanLong("0XF", &l, 0) && l == 15, "Long '0XF'"); - testOk(epicsScanULong("0XF", &u, 0) && u == 15, "ULong '0XF'"); - testOk(epicsScanLLong("0XF", &ll, 0) && ll == 15, "LLong '0XF'"); - testOk(epicsScanULLong("0XF", &ull, 0) && ull == 15, "ULLong '0XF'"); - testOk(epicsScanFloat("0XF", &f) && f == 15, "Float '0XF'"); - testOk(epicsScanDouble("0XF", &d) && d == 15, "Double '0XF'"); - - testOk(epicsParseLong("0x0", &l, 10, NULL) == S_stdlib_extraneous, - "Long '0x0' in base 10 => extraneous"); - testOk(epicsParseULong("0x0", &u, 10, NULL) == S_stdlib_extraneous, - "ULong '0x0' in base 10 => extraneous"); - testOk(epicsParseLLong("0x0", &ll, 10, NULL) == S_stdlib_extraneous, - "LLong '0x0' in base 10 => extraneous"); - testOk(epicsParseULLong("0x0", &ull, 10, NULL) == S_stdlib_extraneous, - "ULLong '0x0' in base 10 => extraneous"); - - testOk(epicsScanLong("0x10", &l, 0) && l == 0x10, - "Long '0x10' in base 0"); - testOk(epicsScanULong("0x10", &u, 0) && u == 0x10, - "ULong '0x10' in base 0"); - testOk(epicsScanLong("0x10", &l, 16) && l == 0x10, - "Long '0x10' in base 16"); - testOk(epicsScanULong("0x10", &u, 16) && u == 0x10, - "ULong '0x10' in base 16"); - testOk(epicsScanLong("10", &l, 16) && l == 0x10, - "Long '10' in base 16"); - testOk(epicsScanULong("10", &u, 16) && u == 0x10, - "ULong '10' in base 16"); - - testOk(epicsScanLong("0x7fffffff", &l, 0) && l == 0x7fffffff, - "Long '0x7fffffff'"); - testOk(epicsScanULong("0xffffffff", &u, 0) && u == 0xffffffff, - "ULong '0xffffffff'"); - testOk(epicsScanLLong("0x7fffffffffffffff", &ll, 0) && - ll == 0x7fffffffffffffffLL, "LLong '0x7fffffffffffffff'"); - testOk(epicsScanULLong("0xffffffffffffffff", &ull, 0) && - ull == 0xffffffffffffffffULL, "ULLong '0xffffffffffffffff'"); - testOk(epicsScanFloat("0xffffff", &f) && f == 0xffffff, - "Float '0xffffff'"); - testOk(epicsScanDouble("0xffffffff", &d) && d == 0xffffffff, - "Double '0xffffffff'"); - - testOk(epicsScanLong("-0x7fffffff", &l, 0) && l == -0x7fffffff, - "Long '-0x7fffffff'"); - testOk(epicsScanULong("-0x7fffffff", &u, 0) && u == -0x7fffffff, - "ULong '-0x7fffffff'"); - testOk(epicsScanLLong("-0x7fffffffffffffff", &ll, 0) - && ll == -0x7fffffffffffffffLL, "LLong '-0x7fffffffffffffff'"); - testOk(epicsScanULLong("-0x7fffffffffffffff", &ull, 0) && - ull == -0x7fffffffffffffffULL, "ULLong '-0x7fffffffffffffff'"); - testOk(epicsScanFloat("-0xffffff", &f) && f == -0xffffff, - "Float '-0xffffff'"); - testOk(epicsScanDouble("-0x7fffffff", &d) && d == -0x7fffffff, - "Double '-0x7fffffff'"); - - testOk(!epicsParseInt8("0x7f", &i8, 0, NULL) && i8 == 0x7f, - "Int8 '0x7f'"); - testOk(!epicsParseInt8("-0x80", &i8, 0, NULL) && ((i8 + 0x80) & 0xff) == 0, - "Int8 '-0x80'"); - testOk(!epicsParseUInt8("0xff", &u8, 0, NULL) && u8 == 0xff, - "UInt8 '0xff'"); - testOk(!epicsParseUInt8("-1", &u8, 0, NULL) && u8 == 0xff, - "UInt8 '-1'"); - testOk(epicsParseInt8("0x80", &i8, 0, NULL) == S_stdlib_overflow, - "Int8 '0x80' => overflow"); - testOk(epicsParseInt8("-0x81", &i8, 0, NULL) == S_stdlib_overflow, - "Int8 '-0x81' => overflow"); - testOk(epicsParseUInt8("0x100", &u8, 0, NULL) == S_stdlib_overflow, - "UInt8 '0x100' => overflow"); - testOk(epicsParseUInt8("-0x100", &u8, 0, NULL) == S_stdlib_overflow, - "UInt8 '-0x100' => overflow"); - - testOk(!epicsParseInt16("0x7fff", &i16, 0, NULL) && i16 == 0x7fff, - "Int16 '0x7fff'"); - testOk(!epicsParseInt16("-0x8000", &i16, 0, NULL) && i16 == -0x8000, - "Int16 '-0x8000'"); - testOk(!epicsParseUInt16("0xffff", &u16, 0, NULL) && u16 == 0xffff, - "UInt16 '0xffff'"); - testOk(!epicsParseUInt16("-1", &u16, 0, NULL) && u16 == 0xffff, - "UInt16 '-1'"); - testOk(epicsParseInt16("0x8000", &i16, 0, NULL) == S_stdlib_overflow, - "Int16 '0x8000' => overflow"); - testOk(epicsParseInt16("-0x8001", &i16, 0, NULL) == S_stdlib_overflow, - "Int16 '-0x8001' => overflow"); - testOk(epicsParseUInt16("0x10000", &u16, 0, NULL) == S_stdlib_overflow, - "UInt16 '0x10000' => overflow"); - testOk(epicsParseUInt16("-0x10000", &u16, 0, NULL) == S_stdlib_overflow, - "UInt16 '-0x10000' => overflow"); - - testOk(!epicsParseInt32("0x7fffffff", &i32, 0, NULL) && i32 == 0x7fffffff, - "Int32 '0x7fffffff'"); - testOk(!epicsParseInt32("-0x80000000", &i32, 0, NULL) && i32 == -0x80000000L, - "Int32 '-0x80000000'"); - testOk(!epicsParseUInt32("0xffffffff", &u32, 0, NULL) && u32 == 0xffffffff, - "UInt32 '0xffffffff'"); - testOk(!epicsParseUInt32("-1", &u32, 0, NULL) && u32 == 0xffffffffU, - "UInt32 '-1'"); - testOk(epicsParseInt32("0x80000000", &i32, 0, NULL) == S_stdlib_overflow, - "Int32 '0x80000000' => overflow"); - testOk(epicsParseInt32("-0x80000001", &i32, 0, NULL) == S_stdlib_overflow, - "Int32 '-0x80000001' => overflow"); - testOk(epicsParseUInt32("0x100000000", &u32, 0, NULL) == S_stdlib_overflow, - "UInt32 '0x100000000' => overflow"); - testOk(epicsParseUInt32("-0x100000000", &u32, 0, NULL) == S_stdlib_overflow, - "UInt32 '-0x100000000' => overflow"); - - testOk(!epicsParseInt64("0x7fffffffffffffff", &i64, 0, NULL) && - i64 == 0x7fffffffffffffffLL, "Int64 '0x7fffffffffffffff'"); - testOk(!epicsParseInt64("-0x8000000000000000", &i64, 0, NULL) && - i64 == -0x8000000000000000LL, "Int64 '-0x8000000000000000'"); - testOk(!epicsParseUInt64("0xffffffffffffffff", &u64, 0, NULL) && - u64 == 0xffffffffffffffffULL, "UInt64 '0xffffffffffffffff'"); - testOk(!epicsParseUInt64("-1", &u64, 0, NULL) && u64 == 0xffffffffffffffffULL, - "UInt64 '-1'"); - testOk(epicsParseInt64("0x8000000000000000", &i64, 0, NULL) == S_stdlib_overflow, - "Int64 '0x8000000000000000' => overflow"); - testOk(epicsParseInt64("-0x8000000000000001", &i64, 0, NULL) == S_stdlib_overflow, - "Int64 '-0x8000000000000001' => overflow"); - testOk(epicsParseUInt64("0x10000000000000000", &u64, 0, NULL) == S_stdlib_overflow, - "UInt64 '0x10000000000000000' => overflow"); - testOk(epicsParseUInt64("-0x10000000000000000", &u64, 0, NULL) == S_stdlib_overflow, - "UInt64 '-0x10000000000000000' => overflow"); - - testOk(epicsScanFloat(".1", &f) && fabs(f - 0.1) < 1e-7, - "Float '.1'"); - testOk(epicsScanDouble(".1", &d) && fabs(d - 0.1) < 1e-15, - "Double '.1'"); - - testOk(epicsScanFloat("0.1", &f) && fabs(f - 0.1) < 1e-7, - "Float '0.1'"); - testOk(epicsScanDouble("0.1", &d) && fabs(d - 0.1) < 1e-15, - "Double '0.1'"); - - testOk(epicsScanFloat("1e-1", &f) && fabs(f - 1e-1) < 1e-7, - "Float '1e-1'"); - testOk(epicsScanDouble("1e-1", &d) && fabs(d - 1e-1) < 1e-15, - "Double '1e-1'"); - - testOk(epicsScanFloat("-.1", &f) && fabs(f + 0.1) < 1e-7, - "Float '-.1'"); - testOk(epicsScanDouble("-.1", &d) && fabs(d + 0.1) < 1e-15, - "Double '-.1'"); - - testOk(epicsScanFloat("-0.1", &f) && fabs(f + 0.1) < 1e-7, - "Float '-0.1'"); - testOk(epicsScanDouble("-0.1", &d) && fabs(d + 0.1) < 1e-15, - "Double '-0.1'"); - - testOk(epicsScanFloat("-1e-1", &f) && fabs(f + 1e-1) < 1e-7, - "Float '-1e-1'"); - testOk(epicsScanDouble("-1e-1", &d) && fabs(d + 1e-1) < 1e-15, - "Double '-1e-1'"); - - testOk(epicsScanFloat("1e-30", &f) && fabs(f - 1e-30) < 1e-36, - "Float '1e-30'"); - testOk(epicsScanDouble("1e-300", &d) && fabs(d - 1e-300) < 1e-306, - "Double '1e-300'"); - - testOk(epicsParseFloat("1e-40", &f, NULL) == S_stdlib_underflow, - "Float '1e-40' => underflow"); - testOk(epicsParseDouble("1e-330", &d, NULL) == S_stdlib_underflow, - "Double '1e-330' => underflow"); - - testOk(epicsScanFloat("1e30", &f) && fabs(f - 1e30) < 1e24, - "Float '1e30'"); - testOk(epicsScanDouble("1e300", &d) && fabs(d - 1e300) < 1e285, - "Double '1e300'"); - - testOk(epicsParseFloat("1e40", &f, NULL) == S_stdlib_overflow, - "Float '1e40' => overflow"); - testOk(epicsParseDouble("1e310", &d, NULL) == S_stdlib_overflow, - "Double '1e330' => overflow"); - - testOk(epicsScanLong("2147483647", &l, 0) && l == 2147483647, - "Long '2147483647'"); - testOk(epicsScanLong("-2147483647", &l, 0) && l == -2147483647, - "Long '-2147483647'"); - testOk(epicsScanULong("4294967295", &u, 0) && u == 4294967295u, - "ULong '4294967295'"); - testOk(epicsScanFloat("16777214", &f) && f == 16777214.0, - "Float '16777214'"); - testOk(epicsScanFloat("16777215", &f) && f == 16777215.0, - "Float '16777215'"); - testOk(epicsScanFloat("-16777215", &f) && f == -16777215.0, - "Float '-16777215'"); - testOk(epicsScanFloat("-16777216", &f) && f == -16777216.0, - "Float '-16777216'"); - testOk(epicsScanDouble("4294967294", &d) && d == 4294967294.0, - "Double '4294967294'"); - testOk(epicsScanDouble("4294967295", &d) && d == 4294967295.0, - "Double '4294967295'"); - testOk(epicsScanDouble("-4294967295", &d) && d == -4294967295.0, - "Double '-4294967295'"); - testOk(epicsScanDouble("-4294967296", &d) && d == -4294967296.0, - "Double '-4294967296'"); - - testOk(epicsScanFloat("NAN", &f) && isnan(f), "Float 'NAN'"); - testOk(epicsScanDouble("NAN", &d) && isnan(d), "Double 'NAN'"); - testOk(epicsScanFloat("Nan", &f) && isnan(f), "Float 'Nan'"); - testOk(epicsScanDouble("Nan", &d) && isnan(d), "Double 'Nan'"); -#ifdef __rtems__ - testTodoBegin("RTEMS (newlib) parser doesn't recognise 'nan()'"); -#endif - testOk(epicsScanFloat("nan()", &f) && isnan(f), "Float 'nan()'"); - testOk(epicsScanDouble("nan()", &d) && isnan(d), "Double 'nan()'"); -#ifdef __rtems__ - testTodoEnd(); -#endif - - testOk(epicsScanFloat("INF", &f) && f == epicsINF, - "Float 'INF'"); - testOk(epicsScanDouble("INF", &d) && d == epicsINF, - "Double 'INF'"); - testOk(epicsScanFloat("Infinity", &f) && f == epicsINF, - "Float 'Infinity'"); - testOk(epicsScanDouble("Infinity", &d) && d == epicsINF, - "Double 'Infinity'"); - - testOk(epicsScanFloat("+INF", &f) && f == epicsINF, - "Float '+INF'"); - testOk(epicsScanDouble("+INF", &d) && d == epicsINF, - "Double '+INF'"); - testOk(epicsScanFloat("+Infinity", &f) && f == epicsINF, - "Float '+Infinity'"); - testOk(epicsScanDouble("+Infinity", &d) && d == epicsINF, - "Double '+Infinity'"); - - testOk(epicsScanFloat("-INF", &f) && f == -epicsINF, - "Float '-INF'"); - testOk(epicsScanDouble("-INF", &d) && d == -epicsINF, - "Double '-INF'"); - testOk(epicsScanFloat("-Infinity", &f) && f == -epicsINF, - "Float '-Infinity'"); - testOk(epicsScanDouble("-Infinity", &d) && d == -epicsINF, - "Double '-Infinity'"); - -#ifdef epicsStrtod -#define CHECK_STRTOD epicsStrtod != strtod - if (epicsStrtod == strtod) - testDiag("This target defines epicsStrtod as strtod"); - else - testDiag("This target defines its own epicsStrtod macro"); -#else -#define CHECK_STRTOD 1 - testDiag("This target compiles epicsStrtod()"); -#endif - - if (CHECK_STRTOD) { - int pass = 0, fail = 0; - -#define CHECK(ok, msg) if (ok) pass++; else fail++, testDiag(msg) - - testDiag("Checking the native strtod(), only failures shown:"); - - CHECK(parseStrtod("", &d, NULL) == S_stdlib_noConversion, - " not ok - strtod('') => noConversion"); - CHECK(parseStrtod("\t \n", &d, NULL) == S_stdlib_noConversion, - " not ok - strtod('\\t 1\\n') => noConversion"); - CHECK(parseStrtod("!", &d, NULL) == S_stdlib_noConversion, - " not ok - strtod('!') => noConversion"); - CHECK(scanStrtod("0", &d) && d == 0, - " not ok - strtod('0')"); - CHECK(scanStrtod("\t 1\n", &d) && d == 1, - " not ok - strtod('\\t 1\\n')"); - CHECK(parseStrtod("2!", &d, NULL) == S_stdlib_extraneous, - " not ok - strtod('2!') => extraneous"); - CHECK(parseStrtod("3 !", &d, NULL) == S_stdlib_extraneous, - " not ok - strtod('3 !') => extraneous"); - CHECK(!parseStrtod("2!", &d, &endp) && *endp == '!', - " not ok - strtod('2!') => units='!'"); - CHECK(!parseStrtod("3 \n\t!", &d, &endp) && *endp == '!', - " not ok - strtod('3 \\n\\t!') => units='!'"); - CHECK(scanStrtod("0x0", &d) && d == 0, - " not ok - strtod('0x0')"); - CHECK(scanStrtod("0x1", &d) && d == 1, - " not ok - strtod('0x1')"); - CHECK(scanStrtod("+0x1", &d) && d == 1, - " not ok - strtod('+0x1')"); - CHECK(scanStrtod("-0x1", &d) && d == -1, - " not ok - strtod('-0x1')"); - CHECK(scanStrtod("0xf", &d) && d == 15, - " not ok - strtod('0xf')"); - CHECK(scanStrtod("0XF", &d) && d == 15, - " not ok - strtod('0XF')"); - CHECK(scanStrtod("0xffffffff", &d) && d == 0xffffffff, - " not ok - strtod('0xffffffff')"); - CHECK(scanStrtod("-0x7fffffff", &d) && d == -0x7fffffffl, - " not ok - strtod('-0x7fffffff')"); - CHECK(scanStrtod(".1", &d) && fabs(d - 0.1) < 1e-15, - " not ok - strtod('.1')"); - CHECK(scanStrtod("0.1", &d) && fabs(d - 0.1) < 1e-15, - " not ok - strtod('0.1')"); - CHECK(scanStrtod("1e-1", &d) && fabs(d - 1e-1) < 1e-15, - " not ok - strtod('1e-1')"); - CHECK(scanStrtod("-.1", &d) && fabs(d + 0.1) < 1e-15, - " not ok - strtod('-.1')"); - CHECK(scanStrtod("-0.1", &d) && fabs(d + 0.1) < 1e-15, - " not ok - strtod('-0.1')"); - CHECK(scanStrtod("-1e-1", &d) && fabs(d + 1e-1) < 1e-15, - " not ok - strtod('-1e-1')"); - CHECK(scanStrtod("1e-300", &d) && fabs(d - 1e-300) < 1e-306, - " not ok - strtod('1e-300')"); - CHECK(parseStrtod("1e-400", &d, NULL) == S_stdlib_underflow, - " not ok - strtod('1e-400') => underflow"); - CHECK(scanStrtod("4294967294", &d) && d == 4294967294.0, - " not ok - strtod('4294967294')"); - CHECK(scanStrtod("4294967295", &d) && d == 4294967295.0, - " not ok - strtod('4294967295')"); - CHECK(scanStrtod("-4294967295", &d) && d == -4294967295.0, - " not ok - strtod('-4294967295')"); - CHECK(scanStrtod("-4294967296", &d) && d == -4294967296.0, - " not ok - strtod('-4294967296')"); - CHECK(scanStrtod("NAN", &d) && isnan(d), - " not ok - strtod('NAN')"); - CHECK(scanStrtod("Nan", &d) && isnan(d), - " not ok - strtod('Nan')"); - CHECK(scanStrtod("nan()", &d) && isnan(d), - " not ok - strtod('nan()')"); - CHECK(scanStrtod("INF", &d) && d == epicsINF, - " not ok - strtod('INF')"); - CHECK(scanStrtod("Infinity", &d) && d == epicsINF, - " not ok - strtod('Infinity')"); - CHECK(scanStrtod("+INF", &d) && d == epicsINF, - " not ok - strtod('+INF')"); - CHECK(scanStrtod("+Infinity", &d) && d == epicsINF, - " not ok - strtod('+Infinity')"); - CHECK(scanStrtod("-INF", &d) && d == -epicsINF, - " not ok - strtod('-INF')"); - CHECK(scanStrtod("-Infinity", &d) && d == -epicsINF, - " not ok - strtod('-Infinity')"); - - if (fail) - testDiag("The native strtod() passed %d and failed %d tests", - pass, fail); - else { - testDiag("The native strtod() passed all %d tests", pass); -#ifndef epicsStrtod - testDiag("The compiled epicsStrtod() should not be needed"); -#endif - } - } - - return testDone(); -} diff --git a/src/libCom/test/epicsStringTest.c b/src/libCom/test/epicsStringTest.c deleted file mode 100644 index 3e4aed7e7..000000000 --- a/src/libCom/test/epicsStringTest.c +++ /dev/null @@ -1,327 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Marty Kraimer - */ - -#include -#include -#include - -#include "epicsUnitTest.h" -#include "epicsString.h" -#include "testMain.h" - -static -void testChars(void) { - int i; - char input[2] = {0, 0}; - char escaped[20]; - char result[20]; - size_t s, t, needed; - - for (i = 255; i >= 0; --i) { - input[0] = i; - needed = epicsStrnEscapedFromRawSize(input, 1); - s = epicsStrnEscapedFromRaw(escaped, sizeof(escaped), input, 1); - t = epicsStrnRawFromEscaped(result, sizeof(result), escaped, s); - testOk(needed == s && t == 1 && - result[0] == input[0] && result[1] == 0, - "escaped char 0x%2.2x -> \"%s\" (%d) -> 0x%2.2x", - input[0] & 0xff, escaped, (int) needed, result[0] & 0xff); - } -} - -static -void testGlob(void) { - testOk1(epicsStrGlobMatch("xyz","xyz")); - testOk1(!epicsStrGlobMatch("xyz","xyzm")); - testOk1(!epicsStrGlobMatch("xyzm","xyz")); - testOk1(!epicsStrGlobMatch("","xyzm")); - testOk1(!epicsStrGlobMatch("xyz","")); - testOk1(epicsStrGlobMatch("","")); - - testOk1(epicsStrGlobMatch("","*")); - testOk1(!epicsStrGlobMatch("","?")); - testOk1(!epicsStrGlobMatch("","?*")); - - testOk1(epicsStrGlobMatch("hello","h*o")); - testOk1(!epicsStrGlobMatch("hello","h*x")); - testOk1(!epicsStrGlobMatch("hellx","h*o")); - - testOk1(epicsStrGlobMatch("hello","he?lo")); - testOk1(!epicsStrGlobMatch("hello","he?xo")); - testOk1(epicsStrGlobMatch("hello","he??o")); - testOk1(!epicsStrGlobMatch("helllo","he?lo")); - - testOk1(epicsStrGlobMatch("hello world","he*o w*d")); - testOk1(!epicsStrGlobMatch("hello_world","he*o w*d")); - testOk1(epicsStrGlobMatch("hello world","he**d")); - - testOk1(epicsStrGlobMatch("hello hello world","he*o w*d")); - - testOk1(!epicsStrGlobMatch("hello hello xorld","he*o w*d")); - - testOk1(epicsStrGlobMatch("hello","he*")); - testOk1(epicsStrGlobMatch("hello","*lo")); - testOk1(epicsStrGlobMatch("hello","*")); -} - -MAIN(epicsStringTest) -{ - const char * const empty = ""; - const char * const space = " "; - const char * const A = "A"; - const char * const ABCD = "ABCD"; - const char * const ABCDE = "ABCDE"; - const char * const a = "a"; - const char * const abcd = "abcd"; - const char * const abcde = "abcde"; - char result[8]; - char *s; - int status; - - testPlan(406); - - testChars(); - - testOk1(epicsStrnCaseCmp(empty, "", 0) == 0); - testOk1(epicsStrnCaseCmp(empty, "", 1) == 0); - testOk1(epicsStrnCaseCmp(space, empty, 1) > 0); - testOk1(epicsStrnCaseCmp(empty, space, 1) < 0); - testOk1(epicsStrnCaseCmp(a, A, 1) == 0); - testOk1(epicsStrnCaseCmp(a, A, 2) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCD, 2) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCD, 4) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCD, 1000) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCDE, 2) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCDE, 4) == 0); - testOk1(epicsStrnCaseCmp(abcd, ABCDE, 1000) < 0); - testOk1(epicsStrnCaseCmp(abcde, ABCD, 2) == 0); - testOk1(epicsStrnCaseCmp(abcde, ABCD, 4) == 0); - testOk1(epicsStrnCaseCmp(abcde, ABCD, 1000) > 0); - - testOk1(epicsStrCaseCmp(empty, "") == 0); - testOk1(epicsStrCaseCmp(a, A) == 0); - testOk1(epicsStrCaseCmp(abcd, ABCD) == 0); - testOk1(epicsStrCaseCmp(abcd, ABCDE) < 0); - testOk1(epicsStrCaseCmp(abcde, ABCD) > 0); - testOk1(epicsStrCaseCmp(abcde, "ABCDF") < 0); - - s = epicsStrDup(abcd); - testOk(strcmp(s, abcd) == 0 && s != abcd, "epicsStrDup"); - free(s); - - testOk1(epicsStrHash(abcd, 0) != epicsStrHash("bacd", 0)); - testOk1(epicsStrHash(abcd, 0) == epicsMemHash(abcde, 4, 0)); - testOk1(epicsStrHash(abcd, 0) != epicsMemHash("abcd\0", 5, 0)); - - testOk1(epicsStrnLen("abcd", 5)==4); - testOk1(epicsStrnLen("abcd", 4)==4); - testOk1(epicsStrnLen("abcd", 3)==3); - testOk1(epicsStrnLen("abcd", 0)==0); - - testGlob(); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 0, ABCD, 4); - testOk(status == 4, "epicsStrnEscapedFromRaw(out, 0) -> %d (exp. 4)", status); - testOk(result[0] == 'x', " No output"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 0, ABCD, 4); - testOk(status == 0, "epicsStrnRawFromEscaped(out, 0) -> %d (exp. 0)", status); - testOk(result[0] == 'x', " No output"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 1, ABCD, 4); - testOk(status == 4, "epicsStrnEscapedFromRaw(out, 1) -> %d (exp. 4)", status); - testOk(result[0] == 0, " 0-terminated"); - testOk(result[1] == 'x', " No overrun"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 1, ABCD, 4); - testOk(status == 0, "epicsStrnRawFromEscaped(out, 1) -> %d (exp. 0)", status); - testOk(result[0] == 0, " 0-terminated"); - testOk(result[1] == 'x', " No overrun"); - - testDiag("Testing size = epicsStrnEscapedFromRawSize"); - - status = epicsStrnEscapedFromRawSize(ABCD, 3); - testOk(status == 3, "size(\"ABCD\", 3) -> %d (exp. 3)", status); - status = epicsStrnEscapedFromRawSize(ABCD, 4); - testOk(status == 4, "size(\"ABCD\", 4) -> %d (exp. 4)", status); - status = epicsStrnEscapedFromRawSize(ABCD, 5); - testOk(status == 8, "size(\"ABCD\", 5) -> %d (exp. 8)", status); - - testDiag("Testing esc = epicsStrnEscapedFromRaw(out, 4, ...)"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 4, ABCD, 3); - testOk(status == 3, "esc(\"ABCD\", 3) -> %d (exp. 3)", status); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No overrun"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 4, ABCD, 4); - testOk(status == 4, "esc(\"ABCD\", 4) -> %d (exp. 4)", status); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No overrun"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnEscapedFromRaw(result, 4, ABCD, 5); - testOk(status == 8, "esc(\"ABCD\", 5) -> %d (exp. 8)", status); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No overrun"); - - testDiag("Testing raw = epicsStrnRawFromEscaped(out, 4, ...)"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 0); - testOk(status == 0, "raw(\"ABCD\", 0) -> %d (exp. 0)", status); - testOk(result[0] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 1); - testOk(status == 1, "raw(\"ABCD\", 1) -> %d (exp. 1)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 2); - testOk(status == 2, "raw(\"ABCD\", 2) -> %d (exp. 2)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 'B', " Char '%c' (exp. 'B')", result[1]); - testOk(result[2] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 3); - testOk(status == 3, "raw(\"ABCD\", 3) -> %d (exp. 3)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 'B', " Char '%c' (exp. 'B')", result[1]); - testOk(result[2] == 'C', " Char '%c' (exp. 'C')", result[2]); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No write outside buffer"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCD, 4); - testOk(status == 3, "raw(\"ABCD\", 4) -> %d (exp. 3)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 'B', " Char '%c' (exp. 'B')", result[1]); - testOk(result[2] == 'C', " Char '%c' (exp. 'C')", result[2]); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No write outside buffer"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, ABCDE, 5); - testOk(status == 3, "raw(\"ABCDE\", 5) -> %d (exp. 3)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[1] == 'B', " Char '%c' (exp. 'B')", result[1]); - testOk(result[2] == 'C', " Char '%c' (exp. 'C')", result[2]); - testOk(result[3] == 0, " 0-terminated"); - testOk(result[4] == 'x', " No write outside buffer"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "A", 2); - testOk(status == 1, "raw(\"A\", 2) -> %d (exp. 1)", status); - testOk(result[0] == 'A', " Char '%c' (exp. 'A')", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\123", 1); - testOk(status == 0, "raw(\"\\123\", 1) -> %d (exp. 0)", status); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\123", 2); - testOk(status == 1, "raw(\"\\123\", 2) -> %d (exp. 1)", status); - testOk(result[0] == 1, " Octal escape (got \\%03o)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\123", 3); - testOk(status == 1, "raw(\"\\123\", 3) -> %d (exp. 1)", status); - testOk(result[0] == 012, " Octal escape (got \\%03o)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\123", 4); - testOk(status == 1, "raw(\"\\123\", 4) -> %d (exp. 1)", status); - testOk(result[0] == 0123, " Octal escape (got \\%03o)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\812", 2); - testOk(status == 1, "raw(\"\\812\", 2) -> %d (exp. 1)", status); - testOk(result[0] == '8', " Escaped '%c')", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\182", 3); - testOk(status == 2, "raw(\"\\182\", 3) -> %d (exp. 2)", status); - testOk(result[0] == 1, " Octal escape (got \\%03o)", result[0]); - testOk(result[1] == '8', " Terminated with '%c'", result[1]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\128", 4); - testOk(status == 2, "raw(\"\\128\", 4) -> %d (exp. 2)", status); - testOk(result[0] == 012, " Octal escape (got \\%03o)", result[0]); - testOk(result[1] == '8', " Terminator char got '%c'", result[1]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x12", 1); - testOk(status == 0, "raw(\"\\x12\", 1) -> %d (exp. 0)", status); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x12", 2); - testOk(status == 0, "raw(\"\\x12\", 2) -> %d (exp. 0)", status); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x12", 3); - testOk(status == 1, "raw(\"\\x12\", 3) -> %d (exp. 1)", status); - testOk(result[0] == 1, " Hex escape (got \\x%x)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x12", 4); - testOk(status == 1, "raw(\"\\x12\", 4) -> %d (exp. 1)", status); - testOk(result[0] == 0x12," Hex escape (got \\x%x)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\xaF", 4); - testOk(status == 1, "raw(\"\\xaF\", 4) -> %d (exp. 1)", status); - testOk(result[0] == '\xaF'," Hex escape (got \\x%x)", result[0] & 0xFF); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x012", 5); - testOk(status == 1, "raw(\"\\x012\", 5) -> %d (exp. 1)", status); - testOk(result[0] == 0x12," Hex escape (got \\x%x)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x0012", 6); - testOk(status == 1, "raw(\"\\x0012\", 6) -> %d (exp. 1)", status); - testOk(result[0] == 0x12," Hex escape (got \\x%x)", result[0]); - testOk(result[status] == 0, " 0-terminated"); - - memset(result, 'x', sizeof(result)); - status = epicsStrnRawFromEscaped(result, 4, "\\x1g", 4); - testOk(status == 2, "raw(\"\\x1g\", 4) -> %d (exp. 2)", status); - testOk(result[0] == 1, " Hex escape (got \\x%x)", result[0]); - testOk(result[1] == 'g', " Terminator char got '%c'", result[1]); - testOk(result[status] == 0, " 0-terminated"); - - return testDone(); -} diff --git a/src/libCom/test/epicsThreadHooksTest.c b/src/libCom/test/epicsThreadHooksTest.c deleted file mode 100644 index b6ba833e0..000000000 --- a/src/libCom/test/epicsThreadHooksTest.c +++ /dev/null @@ -1,176 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 ITER Organization -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* epicsThreadHooksTest.c */ - -#include - -#include "epicsThread.h" -#include "epicsExit.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define MAX_THREADS 16 -#define TEST_THREADS 8 -#define NUM_HOOKS 4 - -static int order[MAX_THREADS][NUM_HOOKS]; -static int cnt[MAX_THREADS]; -static int mine[MAX_THREADS]; -static int mapped[MAX_THREADS]; -static epicsThreadId tid[MAX_THREADS]; - -static epicsMutexId tidLock; -static epicsEventId shutdown[TEST_THREADS]; - -static int newThreadIndex(epicsThreadId id) -{ - int i = 0; - - if (epicsMutexLock(tidLock)) - testAbort("newThreadIndex: Locking problem"); - - while (i < MAX_THREADS && tid[i] != 0) - i++; - if (i < MAX_THREADS) - tid[i] = id; - else - testAbort("newThreadIndex: Too many threads!"); - - epicsMutexUnlock(tidLock); - return i; -} - -static int findThreadIndex(epicsThreadId id) -{ - int i = 0; - - while (i < MAX_THREADS && tid[i] != id) - i++; - return i; -} - -static void atExitHook1 (void *arg) -{ - int no = findThreadIndex(epicsThreadGetIdSelf()); - - if (no < MAX_THREADS) - order[no][3] = cnt[no]++; -} - -static void atExitHook2 (void *arg) -{ - int no = findThreadIndex(epicsThreadGetIdSelf()); - - if (no < MAX_THREADS) - order[no][2] = cnt[no]++; -} - -static void startHook1 (epicsThreadId id) -{ - int no = newThreadIndex(id); - - if (no < MAX_THREADS) - order[no][0] = cnt[no]++; - epicsAtThreadExit(atExitHook1, NULL); -} - -static void startHook2 (epicsThreadId id) -{ - int no = findThreadIndex(id); - - if (no < MAX_THREADS) - order[no][1] = cnt[no]++; - epicsAtThreadExit(atExitHook2, NULL); -} - -static void my_thread (void *arg) -{ - int no = findThreadIndex(epicsThreadGetIdSelf()); - - if (no < MAX_THREADS) - mine[no] = 1; - epicsEventMustWait((epicsEventId) arg); -} - -static void mapper (epicsThreadId id) -{ - int no = findThreadIndex(id); - - if (no < MAX_THREADS) - mapped[no]++; -} - -MAIN(epicsThreadHooksTest) -{ - int i; - int ok; - - testPlan(TEST_THREADS + 1); - - tidLock = epicsMutexMustCreate(); - - if (epicsThreadHookAdd(startHook1)) - testAbort("startHook1 registration failed"); - if (epicsThreadHookAdd(startHook2)) - testAbort("startHook2 registration failed"); - - for (i = 0; i < TEST_THREADS; i++) { - char name[10]; - - shutdown[i] = epicsEventCreate(epicsEventEmpty); - sprintf(name, "t%d", (int) i); - epicsThreadCreate(name, epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - my_thread, shutdown[i]); - } - epicsThreadSleep(1.0); - - epicsThreadMap(mapper); - - ok = 1; - for (i = 0; i < MAX_THREADS; i++) { - if (!mine[i]) continue; - - if (mapped[i] != 1) { - ok = 0; - testDiag("mapped[%d] = %d", i, mapped[i]); - } - } - testOk(ok, "All my tasks covered once by epicsThreadMap"); - - for (i = 0; i < TEST_THREADS; i++) { - epicsEventSignal(shutdown[i]); - } - - epicsThreadSleep(1.0); - - for (i = 0; i < MAX_THREADS; i++) { - int j; - - if (!mine[i]) continue; - - ok = 1; - for (j = 0; j < NUM_HOOKS; j++) { - if (order[i][j] != j) { - ok = 0; - testDiag("order[%d][%d] = %d", i, j, order[i][j]); - } - } - testOk(ok, "All hooks for task %d called in correct order", i); - } - - epicsThreadHookDelete(startHook1); - epicsThreadHookDelete(startHook2); - - return testDone(); -} diff --git a/src/libCom/test/epicsThreadOnceTest.c b/src/libCom/test/epicsThreadOnceTest.c deleted file mode 100644 index 2ecdf3a68..000000000 --- a/src/libCom/test/epicsThreadOnceTest.c +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "errlog.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsMutex.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define NUM_ONCE_THREADS 8 - -epicsThreadOnceId onceFlag = EPICS_THREAD_ONCE_INIT; -epicsThreadOnceId twiceFlag = EPICS_THREAD_ONCE_INIT; -epicsMutexId lock; -epicsEventId go; -epicsEventId done; - -int runCount = 0; -int initCount = 0; -char initBy[20]; -int doneCount = 0; - -void onceInit(void *ctx) -{ - initCount++; - strcpy(initBy, epicsThreadGetNameSelf()); -} - -void onceThread(void *ctx) -{ - epicsMutexMustLock(lock); - runCount++; - epicsMutexUnlock(lock); - - epicsEventMustWait(go); - epicsEventSignal(go); - - epicsThreadOnce(&onceFlag, onceInit, ctx); - testOk(initCount == 1, "%s: initCount = %d", - epicsThreadGetNameSelf(), initCount); - - epicsMutexMustLock(lock); - doneCount++; - if (doneCount == runCount) - epicsEventSignal(done); - epicsMutexUnlock(lock); -} - - -void recurseInit(void); -void onceRecurse(void *ctx) -{ - recurseInit(); -} - -void recurseInit(void) -{ - epicsThreadOnce(&twiceFlag, onceRecurse, 0); -} - -void recurseThread(void *ctx) -{ - recurseInit(); - testFail("Recursive epicsThreadOnce() not detected"); -} - - -MAIN(epicsThreadOnceTest) -{ - int i; - epicsThreadId tid; - - testPlan(3 + NUM_ONCE_THREADS); - - go = epicsEventMustCreate(epicsEventEmpty); - done = epicsEventMustCreate(epicsEventEmpty); - lock = epicsMutexMustCreate(); - - for (i = 0; i < NUM_ONCE_THREADS; i++) { - char name[20]; - - sprintf(name, "once-%d", i); - epicsThreadCreate(name, epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackSmall), - onceThread, 0); - } - epicsThreadSleep(0.1); - - testOk(runCount == NUM_ONCE_THREADS, "runCount = %d", runCount); - epicsEventSignal(go); /* Use epicsEventBroadcast(go) when available */ - epicsEventMustWait(done); - - testOk(doneCount == NUM_ONCE_THREADS, "doneCount = %d", doneCount); - testDiag("init was run by %s", initBy); - - eltc(0); - tid = epicsThreadCreate("recurse", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackSmall), - recurseThread, 0); - do { - epicsThreadSleep(0.1); - } while (!epicsThreadIsSuspended(tid)); - testPass("Recursive epicsThreadOnce() detected"); - - eltc(1); - return testDone(); -} diff --git a/src/libCom/test/epicsThreadPerform.cpp b/src/libCom/test/epicsThreadPerform.cpp deleted file mode 100644 index c8fd34515..000000000 --- a/src/libCom/test/epicsThreadPerform.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsThreadPerform.cpp */ - -/* sleep accuracy and sleep quantum tests by Jeff Hill */ -/* epicsThreadGetIdSelf performance by Jeff Hill */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "testMain.h" - -static void testPriority(const char *who) -{ - epicsThreadId id; - unsigned int oldPriority,newPriority; - - id = epicsThreadGetIdSelf(); - oldPriority = epicsThreadGetPriority(id); - epicsThreadSetPriority(id,epicsThreadPriorityMax); - newPriority = epicsThreadGetPriority(id); - epicsThreadSetPriority(id,oldPriority); - printf("testPriority %s\n id %p old %u new %u\n", - who,id,oldPriority,newPriority); -} - -extern "C" void testPriorityThread(void *arg) -{ - testPriority("thread"); -} - -static void epicsThreadPriorityTest() -{ - testPriority("main error expected from epicsThreadSetPriority"); - epicsThreadCreate("testPriorityThread",epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium),testPriorityThread,0); - epicsThreadSleep(0.5); -} - - -static double threadSleepMeasureDelayError ( const double & delay ) -{ - epicsTime beg = epicsTime::getCurrent(); - epicsThreadSleep ( delay ); - epicsTime end = epicsTime::getCurrent(); - double meas = end - beg; - double error = fabs ( delay - meas ); - return error; -} - -static double measureSleepQuantum ( - const unsigned iterations, const double testInterval ) -{ - double errorSum = 0.0; - printf ( "Estimating sleep quantum" ); - fflush ( stdout ); - for ( unsigned i = 0u; i < iterations; i++ ) { - // try to guarantee a uniform probability density function - // by intentionally burning some CPU until we are less - // likely to be aligned with the schedualing clock - double interval = rand (); - interval /= RAND_MAX; - interval *= testInterval; - epicsTime start = epicsTime::getCurrent (); - epicsTime current = start; - while ( current - start < interval ) { - current = epicsTime::getCurrent (); - } - errorSum += threadSleepMeasureDelayError ( testInterval ); - if ( i % ( iterations / 10 ) == 0 ) { - printf ( "." ); - fflush ( stdout ); - } - } - printf ( "done\n" ); - - // with a uniform probability density function the - // sleep delay error mean is one half of the quantum - double quantumEstimate = 2 * errorSum / iterations; - return quantumEstimate; -} - -static void threadSleepQuantumTest () -{ - const double quantum = epicsThreadSleepQuantum (); - - double quantumEstimate = measureSleepQuantum ( 10, 10 * quantum ); - quantumEstimate = measureSleepQuantum ( 100, 2 * quantumEstimate ); - - double quantumError = fabs ( quantumEstimate - quantum ) / quantum; - const char * pTol = 0; - if ( quantumError > 0.1 ) { - pTol = "10%"; - } - else if ( quantumError > 0.01 ) { - pTol = "1%"; - } - else if ( quantumError > 0.001 ) { - pTol = "0.1%"; - } - if ( pTol ) { - printf ( - "The epicsThreadSleepQuantum() call returns %f sec.\n", - quantum ); - printf ( - "This doesnt match the quantum estimate " - "of %f sec within %s.\n", - quantumEstimate, pTol ); - } -} - - -static void threadSleepTest () -{ - static const int iterations = 20; - const double quantum = epicsThreadSleepQuantum (); - double errorSum = threadSleepMeasureDelayError ( 0.0 ); - for ( int i = 0u; i < iterations; i++ ) { - double delay = ldexp ( 1.0 , -i ); - double error = - threadSleepMeasureDelayError ( delay ); - errorSum += error; - if ( error > quantum + quantum / 8.0 ) { - printf ( "epicsThreadSleep ( %10f ) delay err %10f sec\n", - delay, error ); - } - } - double averageError = errorSum / ( iterations + 1 ); - if ( averageError > quantum ) { - printf ( "Average sleep delay error was %f sec\n", averageError ); - } -} - -static void epicsThreadGetIdSelfPerfTest () -{ - static const unsigned N = 10000; - static const double microSecPerSec = 1e6; - epicsTime begin = epicsTime::getCurrent (); - for ( unsigned i = 0u; i < N; i++ ) { - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - epicsThreadGetIdSelf (); - }; - epicsTime end = epicsTime::getCurrent (); - printf ( "It takes %f micro sec to call epicsThreadGetIdSelf ()\n", - microSecPerSec * ( end - begin ) / (10 * N) ); -} - - -static epicsThreadPrivate < bool > priv; - -static inline void callItTenTimes () -{ - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); - (void) priv.get (); -} - -static inline void callItTenTimesSquared () -{ - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); - callItTenTimes (); -} - -static void timeEpicsThreadPrivateGet () -{ - priv.set ( 0 ); - - epicsTime begin = epicsTime::getCurrent (); - static const unsigned N = 1000u; - for ( unsigned i = 0u; i < N; i++ ) { - callItTenTimesSquared (); - } - double delay = epicsTime::getCurrent() - begin; - delay /= N * 100u; // convert to sec per call - delay *= 1e6; // convert to micro sec - printf("epicsThreadPrivateGet() takes %f microseconds\n", delay); -} - - -MAIN(epicsThreadPerform) -{ - epicsThreadPriorityTest (); - threadSleepQuantumTest (); - threadSleepTest (); - epicsThreadGetIdSelfPerfTest (); - timeEpicsThreadPrivateGet (); - return 0; -} diff --git a/src/libCom/test/epicsThreadPoolTest.c b/src/libCom/test/epicsThreadPoolTest.c deleted file mode 100644 index 6a4f3f435..000000000 --- a/src/libCom/test/epicsThreadPoolTest.c +++ /dev/null @@ -1,447 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "epicsThreadPool.h" - -/* included to allow tests to peek */ -#include "../../pool/poolPriv.h" - -#include "testMain.h" -#include "epicsUnitTest.h" - -#include "cantProceed.h" -#include "epicsEvent.h" -#include "epicsMutex.h" -#include "epicsThread.h" - -/* Do nothing */ -static void nullop(void) -{ - epicsThreadPool *pool; - testDiag("nullop()"); - { - epicsThreadPoolConfig conf; - epicsThreadPoolConfigDefaults(&conf); - testOk1(conf.maxThreads>0); - - testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); - if(!pool) - return; - } - - epicsThreadPoolDestroy(pool); -} - -/* Just create and destroy worker threads */ -static void oneop(void) -{ - epicsThreadPool *pool; - testDiag("oneop()"); - { - epicsThreadPoolConfig conf; - epicsThreadPoolConfigDefaults(&conf); - conf.initialThreads=2; - testOk1(conf.maxThreads>0); - - testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); - if(!pool) - return; - } - - epicsThreadPoolDestroy(pool); -} - -/* Test that Bursts of jobs will create enough threads to - * run all in parallel - */ -typedef struct { - epicsMutexId guard; - unsigned int count; - epicsEventId allrunning; - epicsEventId done; - epicsJob **job; -} countPriv; - -static void countjob(void *param, epicsJobMode mode) -{ - countPriv *cnt=param; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - return; - - epicsMutexMustLock(cnt->guard); - testDiag("Job %lu", (unsigned long)cnt->count); - cnt->count--; - if(cnt->count==0) { - testDiag("All jobs running"); - epicsEventSignal(cnt->allrunning); - } - epicsMutexUnlock(cnt->guard); - - epicsEventMustWait(cnt->done); - epicsEventSignal(cnt->done); /* pass along to next thread */ -} - -/* Starts "mcnt" jobs in a pool with initial and max - * thread counts "icnt" and "mcnt". - * The test ensures that all jobs run in parallel. - * "cork" checks the function of pausing the run queue - * with epicsThreadPoolQueueRun - */ -static void postjobs(size_t icnt, size_t mcnt, int cork) -{ - size_t i; - epicsThreadPool *pool; - countPriv *priv=callocMustSucceed(1, sizeof(*priv), "postjobs priv alloc"); - priv->guard=epicsMutexMustCreate(); - priv->done=epicsEventMustCreate(epicsEventEmpty); - priv->allrunning=epicsEventMustCreate(epicsEventEmpty); - priv->count=mcnt; - priv->job=callocMustSucceed(mcnt, sizeof(*priv->job), "postjobs job array"); - - testDiag("postjobs(%lu,%lu)", (unsigned long)icnt, (unsigned long)mcnt); - - { - epicsThreadPoolConfig conf; - epicsThreadPoolConfigDefaults(&conf); - conf.initialThreads=icnt; - conf.maxThreads=mcnt; - - testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); - if(!pool) - return; - } - - if(cork) - epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 0); - - for(i=0; ijob[i] = epicsJobCreate(pool, &countjob, priv); - testOk1(priv->job[i]!=NULL); - testOk1(epicsJobQueue(priv->job[i])==0); - } - - if(cork) { - /* no jobs should have run */ - epicsMutexMustLock(priv->guard); - testOk1(priv->count==mcnt); - epicsMutexUnlock(priv->guard); - - epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 1); - } - - testDiag("Waiting for all jobs to start"); - epicsEventMustWait(priv->allrunning); - testDiag("Stop all"); - epicsEventSignal(priv->done); - - for(i=0; ijob[i]); - } - - epicsThreadPoolDestroy(pool); - epicsMutexDestroy(priv->guard); - epicsEventDestroy(priv->allrunning); - epicsEventDestroy(priv->done); - free(priv->job); - free(priv); -} - -static unsigned int flag0 = 0; - -/* Test cancel from job (no-op) - * and destroy from job (lazy free) - */ -static void cleanupjob0(void* arg, epicsJobMode mode) -{ - epicsJob *job=arg; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - return; - - assert(flag0==0); - flag0=1; - - testOk1(epicsJobQueue(job)==0); - - epicsJobDestroy(job); /* delete while job is running */ -} -static void cleanupjob1(void* arg, epicsJobMode mode) -{ - epicsJob *job=arg; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - return; - - testOk1(epicsJobQueue(job)==0); - - testOk1(epicsJobUnqueue(job)==0); - /* delete later after job finishes, but before pool is destroyed */ -} -static void cleanupjob2(void* arg, epicsJobMode mode) -{ - epicsJob *job=arg; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - epicsJobDestroy(job); /* delete when threadpool is destroyed */ - else if(mode==epicsJobModeRun) - testOk1(epicsJobUnqueue(job)==S_pool_jobIdle); -} -static epicsJobFunction cleanupjobs[3] = {&cleanupjob0,&cleanupjob1,&cleanupjob2}; - -/* Tests three methods for job cleanup. - * 1. destroy which running - * 2. deferred cleanup after pool destroyed - * 3. immediate cleanup when pool destroyed - */ -static void testcleanup(void) -{ - int i=0; - epicsThreadPool *pool; - epicsJob *job[3]; - - testDiag("testcleanup()"); - - testOk1((pool=epicsThreadPoolCreate(NULL))!=NULL); - if(!pool) - return; - - /* unrolled so that valgrind can show which methods leaks */ - testOk1((job[0]=epicsJobCreate(pool, cleanupjobs[0], EPICSJOB_SELF))!=NULL); - testOk1((job[1]=epicsJobCreate(pool, cleanupjobs[1], EPICSJOB_SELF))!=NULL); - testOk1((job[2]=epicsJobCreate(pool, cleanupjobs[2], EPICSJOB_SELF))!=NULL); - for(i=0; i<3; i++) { - testOk1(epicsJobQueue(job[i])==0); - } - - epicsThreadPoolWait(pool, -1); - epicsJobDestroy(job[1]); - epicsThreadPoolDestroy(pool); -} - -/* Test re-add from inside job */ -typedef struct { - unsigned int count; - epicsEventId done; - epicsJob *job; - unsigned int inprogress; -} readdPriv; - -static void readdjob(void *arg, epicsJobMode mode) -{ - readdPriv *priv=arg; - testOk1(mode==epicsJobModeRun||mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - return; - testOk1(priv->inprogress==0); - testDiag("count==%u", priv->count); - - if(priv->count--) { - priv->inprogress=1; - epicsJobQueue(priv->job); - epicsThreadSleep(0.05); - priv->inprogress=0; - }else{ - epicsEventSignal(priv->done); - epicsJobDestroy(priv->job); - } -} - -/* Test re-queueing a job while it is running. - * Check that a single job won't run concurrently. - */ -static void testreadd(void) { - epicsThreadPoolConfig conf; - epicsThreadPool *pool; - readdPriv *priv=callocMustSucceed(1, sizeof(*priv), "testcleanup priv"); - readdPriv *priv2=callocMustSucceed(1, sizeof(*priv), "testcleanup priv"); - - testDiag("testreadd"); - - priv->done=epicsEventMustCreate(epicsEventEmpty); - priv->count=5; - priv2->done=epicsEventMustCreate(epicsEventEmpty); - priv2->count=5; - - epicsThreadPoolConfigDefaults(&conf); - conf.maxThreads = 2; - testOk1((pool=epicsThreadPoolCreate(&conf))!=NULL); - if(!pool) - return; - - testOk1((priv->job=epicsJobCreate(pool, &readdjob, priv))!=NULL); - testOk1((priv2->job=epicsJobCreate(pool, &readdjob, priv2))!=NULL); - - testOk1(epicsJobQueue(priv->job)==0); - testOk1(epicsJobQueue(priv2->job)==0); - epicsEventMustWait(priv->done); - epicsEventMustWait(priv2->done); - - testOk1(epicsThreadPoolNThreads(pool)==2); - testDiag("epicsThreadPoolNThreads = %d", epicsThreadPoolNThreads(pool)); - - epicsThreadPoolDestroy(pool); - epicsEventDestroy(priv->done); - epicsEventDestroy(priv2->done); - free(priv); - free(priv2); - -} - -static int shouldneverrun = 0; -static int numtoolate = 0; - -/* test job canceling */ -static -void neverrun(void *arg, epicsJobMode mode) -{ - epicsJob *job=arg; - testOk1(mode==epicsJobModeCleanup); - if(mode==epicsJobModeCleanup) - epicsJobDestroy(job); - else - shouldneverrun++; -} -static epicsEventId cancel[2]; -static -void toolate(void *arg, epicsJobMode mode) -{ - epicsJob *job=arg; - if(mode==epicsJobModeCleanup){ - epicsJobDestroy(job); - return; - } - testPass("Job runs"); - numtoolate++; - epicsEventSignal(cancel[0]); - epicsEventMustWait(cancel[1]); -} - -static -void testcancel(void) -{ - epicsJob *job[2]; - epicsThreadPool *pool; - testOk1((pool=epicsThreadPoolCreate(NULL))!=NULL); - if(!pool) - return; - - cancel[0]=epicsEventCreate(epicsEventEmpty); - cancel[1]=epicsEventCreate(epicsEventEmpty); - - testOk1((job[0]=epicsJobCreate(pool, &neverrun, EPICSJOB_SELF))!=NULL); - testOk1((job[1]=epicsJobCreate(pool, &toolate, EPICSJOB_SELF))!=NULL); - - /* freeze */ - epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 0); - - testOk1(epicsJobUnqueue(job[0])==S_pool_jobIdle); /* not queued yet */ - - epicsJobQueue(job[0]); - testOk1(epicsJobUnqueue(job[0])==0); - testOk1(epicsJobUnqueue(job[0])==S_pool_jobIdle); - - epicsThreadSleep(0.01); - epicsJobQueue(job[0]); - testOk1(epicsJobUnqueue(job[0])==0); - testOk1(epicsJobUnqueue(job[0])==S_pool_jobIdle); - - epicsThreadPoolControl(pool, epicsThreadPoolQueueRun, 1); - - epicsJobQueue(job[1]); /* actually let it run this time */ - - epicsEventMustWait(cancel[0]); - testOk1(epicsJobUnqueue(job[0])==S_pool_jobIdle); - epicsEventSignal(cancel[1]); - - epicsThreadPoolDestroy(pool); - epicsEventDestroy(cancel[0]); - epicsEventDestroy(cancel[1]); - - testOk1(shouldneverrun==0); - testOk1(numtoolate==1); -} - -static -unsigned int sharedWasDeleted=0; - -static -void lastjob(void *arg, epicsJobMode mode) -{ - epicsJob *job=arg; - if(mode==epicsJobModeCleanup) { - sharedWasDeleted=1; - epicsJobDestroy(job); - } -} - -static -void testshared(void) -{ - epicsThreadPool *poolA, *poolB; - epicsThreadPoolConfig conf; - epicsJob *job; - - epicsThreadPoolConfigDefaults(&conf); - - testDiag("Check reference counting of shared pools"); - - testOk1((poolA=epicsThreadPoolGetShared(&conf))!=NULL); - - testOk1(poolA->sharedCount==1); - - testOk1((poolB=epicsThreadPoolGetShared(&conf))!=NULL); - - testOk1(poolA==poolB); - - testOk1(poolA->sharedCount==2); - - epicsThreadPoolReleaseShared(poolA); - - testOk1(poolB->sharedCount==1); - - testOk1((job=epicsJobCreate(poolB, &lastjob, EPICSJOB_SELF))!=NULL); - - epicsThreadPoolReleaseShared(poolB); - - testOk1(sharedWasDeleted==1); - - testOk1((poolA=epicsThreadPoolGetShared(&conf))!=NULL); - - testOk1(poolA->sharedCount==1); - - epicsThreadPoolReleaseShared(poolA); - -} - -MAIN(epicsThreadPoolTest) -{ - testPlan(171); - - nullop(); - oneop(); - testDiag("Queue with delayed start"); - postjobs(1,1,1); - postjobs(0,1,1); - postjobs(4,4,1); - postjobs(0,4,1); - postjobs(2,4,1); - testDiag("Queue with immediate start"); - postjobs(1,1,0); - postjobs(0,1,0); - postjobs(4,4,0); - postjobs(0,4,0); - postjobs(2,4,0); - testcleanup(); - testreadd(); - testcancel(); - testshared(); - - return testDone(); -} diff --git a/src/libCom/test/epicsThreadPriorityTest.cpp b/src/libCom/test/epicsThreadPriorityTest.cpp deleted file mode 100644 index 4f5a82d9e..000000000 --- a/src/libCom/test/epicsThreadPriorityTest.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsdThreadPriorityTest.cpp */ - -/* Author: Marty Kraimer Date: 21NOV2005 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsEvent.h" -#include "epicsExit.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -typedef struct info { - epicsEventId waitForMaster; - epicsEventId waitForClient; -}info; - -extern "C" { - -static void client(void *arg) -{ - info *pinfo = (info *)arg; - epicsThreadId idSelf = epicsThreadGetIdSelf(); - int pass; - - for (pass = 0 ; pass < 3 ; pass++) { - epicsEventWaitStatus status; - status = epicsEventWait(pinfo->waitForMaster); - testOk(status == epicsEventWaitOK, - "task %p epicsEventWait returned %d", idSelf, status); - epicsThreadSleep(0.01); - epicsEventSignal(pinfo->waitForClient); - } -} - -static void runThreadPriorityTest(void *arg) -{ - epicsEventId testComplete = (epicsEventId) arg; - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - - epicsThreadId myId = epicsThreadGetIdSelf(); - epicsThreadSetPriority(myId, 50); - - info *pinfo = (info *)calloc(1, sizeof(info)); - pinfo->waitForMaster = epicsEventMustCreate(epicsEventEmpty); - pinfo->waitForClient = epicsEventMustCreate(epicsEventEmpty); - - epicsThreadId clientId = epicsThreadCreate("client", - 50, stackSize, client, pinfo); - epicsEventSignal(pinfo->waitForMaster); - - epicsEventWaitStatus status; - status = epicsEventWaitWithTimeout(pinfo->waitForClient, 0.1); - if (!testOk(status == epicsEventWaitOK, - "epicsEventWaitWithTimeout returned %d", status)) { - testSkip(2, "epicsEventWaitWithTimeout failed"); - goto done; - } - - epicsThreadSetPriority(clientId, 20); - /* expect that client will not be able to run */ - epicsEventSignal(pinfo->waitForMaster); - - status = epicsEventTryWait(pinfo->waitForClient); - if (status != epicsEventWaitTimeout) { - testFail("epicsEventTryWait returned %d", status); - } else { - status = epicsEventWaitWithTimeout(pinfo->waitForClient, 0.1); - if (!testOk(status == epicsEventWaitOK, - "epicsEventWaitWithTimeout returned %d", status)) { - testSkip(1, "epicsEventWaitWithTimeout failed"); - goto done; - } - } - epicsThreadSetPriority(clientId, 80); - /* expect that client will be able to run */ - epicsEventSignal(pinfo->waitForMaster); - status = epicsEventTryWait(pinfo->waitForClient); - if (status==epicsEventWaitOK) { - testPass("Strict priority scheduler"); - } else { - testDiag("No strict priority scheduler"); - status = epicsEventWaitWithTimeout(pinfo->waitForClient,.1); - testOk(status == epicsEventWaitOK, - "epicsEventWaitWithTimeout returned %d", status); - } -done: - epicsThreadSleep(1.0); - epicsEventSignal(testComplete); -} - -} /* extern "C" */ - - -MAIN(epicsThreadPriorityTest) -{ - testPlan(7); - epicsEventId testComplete = epicsEventMustCreate(epicsEventEmpty); - epicsThreadMustCreate("threadPriorityTest", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), - runThreadPriorityTest, testComplete); - epicsEventWaitStatus status = epicsEventWait(testComplete); - testOk(status == epicsEventWaitOK, - "epicsEventWait returned %d", status); - return testDone(); -} diff --git a/src/libCom/test/epicsThreadPrivateTest.cpp b/src/libCom/test/epicsThreadPrivateTest.cpp deleted file mode 100644 index 7ce28f4fd..000000000 --- a/src/libCom/test/epicsThreadPrivateTest.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Jeff Hill Date: March 28 2001 */ - -#include - -#include "epicsTime.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -static epicsThreadPrivate < bool > priv; - -extern "C" void epicsThreadPrivateTestThread ( void * ) -{ - testOk1 ( NULL == priv.get () ); - bool var = true; - priv.set ( &var ); - testOk1 ( &var == priv.get () ); -} - -MAIN(epicsThreadPrivateTest) -{ - testPlan(5); - - bool var = false; - priv.set ( &var ); - testOk1 ( &var == priv.get() ); - - epicsThreadCreate ( "epicsThreadPrivateTest", epicsThreadPriorityMax, - epicsThreadGetStackSize ( epicsThreadStackSmall ), - epicsThreadPrivateTestThread, 0 ); - epicsThreadSleep ( 1.0 ); - testOk1 ( &var == priv.get() ); - - priv.set ( NULL ); - testOk1 ( NULL == priv.get() ); - - return testDone(); -} - diff --git a/src/libCom/test/epicsThreadTest.cpp b/src/libCom/test/epicsThreadTest.cpp deleted file mode 100644 index f80d3da7e..000000000 --- a/src/libCom/test/epicsThreadTest.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsThreadTest.cpp */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsTime.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -static epicsThreadPrivate privateKey; - -class myThread: public epicsThreadRunable { -public: - myThread(int arg,const char *name); - virtual ~myThread(); - virtual void run(); - epicsThread thread; -private: - int *argvalue; -}; - -myThread::myThread(int arg,const char *name) : - thread(*this,name,epicsThreadGetStackSize(epicsThreadStackSmall),50+arg), - argvalue(0) -{ - argvalue = new int; - *argvalue = arg; - thread.start(); -} - -myThread::~myThread() {delete argvalue;} - -void myThread::run() -{ - int *pset = argvalue; - privateKey.set(argvalue); - epicsThreadSleep(2.0); - int *pget = privateKey.get(); - testOk1(pget == pset); - - epicsThreadId self = epicsThreadGetIdSelf(); - testOk1(thread.getPriority() == epicsThreadGetPriority(self)); -} - - -typedef struct info { - int isOkToBlock; -} info; - -extern "C" { -static void thread(void *arg) -{ - info *pinfo = (info *)arg; - - epicsThreadSetOkToBlock(pinfo->isOkToBlock); - epicsThreadSleep(1.0); - - testOk(epicsThreadIsOkToBlock() == pinfo->isOkToBlock, - "%s epicsThreadIsOkToBlock() = %d", - epicsThreadGetNameSelf(), pinfo->isOkToBlock); - epicsThreadSleep(0.1); -} -} - - -MAIN(epicsThreadTest) -{ - testPlan(9); - - unsigned int ncpus = epicsThreadGetCPUs(); - testDiag("System has %u CPUs", ncpus); - testOk1(ncpus > 0); - - const int ntasks = 3; - myThread *myThreads[ntasks]; - - int startPriority = 0; - for (int i = 0; i < ntasks; i++) { - char name[10]; - sprintf(name, "t%d", i); - myThreads[i] = new myThread(i, name); - if (i == 0) - startPriority = myThreads[i]->thread.getPriority(); - myThreads[i]->thread.setPriority(startPriority + i); - } - epicsThreadSleep(3.0); - - unsigned int stackSize = epicsThreadGetStackSize(epicsThreadStackSmall); - - info infoA = {0}; - epicsThreadCreate("threadA", 50, stackSize, thread, &infoA); - - info infoB = {1}; - epicsThreadCreate("threadB", 50, stackSize, thread, &infoB); - - epicsThreadSleep(2.0); - - return testDone(); -} diff --git a/src/libCom/test/epicsTimeTest.cpp b/src/libCom/test/epicsTimeTest.cpp deleted file mode 100644 index 55ad43cdd..000000000 --- a/src/libCom/test/epicsTimeTest.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Authors: Jeff Hill, Marty Kraimer and Andrew Johnson - */ -#include -#include -#include -#include -#include -#include - -#include "epicsTime.h" -#include "epicsThread.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -using namespace std; - -/* The functionality of the old invalidFormatTest () and badNanosecTest () - * routines is incorporated into epicsTimeTest () below. - */ - -struct l_fp { /* NTP time stamp */ - epicsUInt32 l_ui; /* sec past NTP epoch */ - epicsUInt32 l_uf; /* fractional seconds */ -}; - -static const unsigned mSecPerSec = 1000u; -static const unsigned uSecPerSec = 1000u * mSecPerSec; -static const unsigned nSecPerSec = 1000u * uSecPerSec; -static const double precisionEPICS = 1.0 / nSecPerSec; - -MAIN(epicsTimeTest) -{ - const int wasteTime = 100000; - const int nTimes = 10; - - testPlan(17 + nTimes * 19); - - try { - const epicsTimeStamp epochTS = {0, 0}; - epicsTime epochET = epochTS; - struct gm_tm_nano_sec epicsEpoch = epochET; - - testOk(epicsEpoch.ansi_tm.tm_sec == 0 && - epicsEpoch.ansi_tm.tm_min == 0 && - epicsEpoch.ansi_tm.tm_hour == 0 && - epicsEpoch.ansi_tm.tm_yday == 0 && - epicsEpoch.ansi_tm.tm_year == 90, - "epicsTime_gmtime() for EPICS epoch"); - } - catch ( ... ) { - testFail("epicsTime_gmtime() failed"); - testAbort("Can't continue, check your OS!"); - } - - { // badNanosecTest - static const char * pFormat = "%a %b %d %Y %H:%M:%S.%4f"; - try { - const epicsTimeStamp badTS = {1, 1000000000}; - epicsTime ts(badTS); - char buf [32]; - ts.strftime(buf, sizeof(buf), pFormat); - testFail("nanosecond overflow returned \"%s\"", buf); - } - catch ( ... ) { - testPass("nanosecond overflow throws"); - } - } - - { // strftime() output - char buf[80]; - epicsTime et; - - const char * pFormat = "%Y-%m-%d %H:%M:%S.%f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "") == 0, "undefined => '%s'", buf); - - // This is Noon GMT, when all timezones have the same date - const epicsTimeStamp tTS = {12*60*60, 98765432}; - et = tTS; - pFormat = "%Y-%m-%d %S.%09f"; // %H and %M change with timezone - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "1990-01-01 00.098765432") == 0, "'%s' => '%s'", pFormat, buf); - - pFormat = "%S.%03f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.099") == 0, "'%s' => '%s'", pFormat, buf); - - pFormat = "%S.%04f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.0988") == 0, "'%s' => '%s'", pFormat, buf); - - pFormat = "%S.%05f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.09877") == 0, "'%s' => '%s'", pFormat, buf); - - pFormat = "%S.%05f %S.%05f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.09877 00.09877") == 0, "'%s' => '%s'", pFormat, buf); - - char smbuf[5]; - pFormat = "%S.%05f"; - et.strftime(smbuf, sizeof(smbuf), pFormat); - testOk(strcmp(smbuf, "00.*") == 0, "'%s' => '%s'", pFormat, smbuf); - - pFormat = "%S.%03f"; - (et + 0.9).strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.999") == 0, "0.998765 => '%s'", buf); - - pFormat = "%S.%03f"; - (et + 0.901).strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "00.999") == 0, "0.999765 => '%s'", buf); - - pFormat = "%%S.%%05f"; - et.strftime(buf, sizeof(buf), pFormat); - testOk(strcmp(buf, "%S.%05f") == 0, "'%s' => '%s'", pFormat, buf); - - char bigBuf [512]; - memset(bigBuf, '\a', sizeof(bigBuf)); - bigBuf[ sizeof(bigBuf) - 1] = '\0'; - et.strftime(buf, sizeof(buf), bigBuf); - testOk(strcmp(buf, "") == 0, "bad format => '%s'", buf); - } - - epicsTime now; - try { - now = epicsTime::getCurrent(); - testPass("default time provider"); - } - catch ( ... ) { - testFail("epicsTime::getCurrent() throws"); - testAbort("Can't continue, check your time provider"); - } - - { - l_fp ntp = now; - epicsTime tsf = ntp; - const double diff = fabs(tsf - now); - // the difference in the precision of the two time formats - static const double precisionNTP = 1.0 / (1.0 + 0xffffffff); - testOk1(diff <= precisionEPICS + precisionNTP); - } - - testDiag("Running %d loops", nTimes); - - const epicsTime begin = epicsTime::getCurrent(); - - for (int loop = 0; loop < nTimes; ++loop) { - for (int i = 0; i < wasteTime; ++i) { - now = epicsTime::getCurrent(); - } - - const double diff = now - begin; - - if (loop == 0) { - testDiag ("%d calls to epicsTime::getCurrent() " - "averaged %6.3f usec each", wasteTime, - diff * 1e6 / wasteTime); - } - - epicsTime copy = now; - testOk1(copy == now); - testOk1(copy <= now); - testOk1(copy >= now); - - testOk1(now > begin); - testOk1(now >= begin); - testOk1(begin != now); - testOk1(begin < now); - testOk1(begin <= now); - - testOk1(now - now == 0); - testOk(fabs((now - begin) - diff) < precisionEPICS * 0.01, - "now - begin ~= diff"); - - testOk1(begin + 0 == begin); - testOk1(begin + diff == now); - testOk1(now - 0 == now); - testOk1(now - diff == begin); - - epicsTime end = begin; - end += diff; - testOk(end == now, "(begin += diff) == now"); - - end = now; - end -= diff; - testOk(end == begin, "(now -= diff) == begin"); - - // test struct tm round-trip conversion - local_tm_nano_sec ansiDate = begin; - epicsTime beginANSI = ansiDate; - testOk1(beginANSI + diff == now); - - // test struct gmtm round-trip conversion - gm_tm_nano_sec ansiGmDate = begin; - epicsTime beginGMANSI = ansiGmDate; - testOk1(beginGMANSI + diff == now); - - // test struct timespec round-trip conversion - struct timespec ts = begin; - epicsTime beginTS = ts; - testOk1(beginTS + diff == now); - } - - epicsTime ten_years_hence; - try { - now = epicsTime::getCurrent(); - ten_years_hence = now + 60 * 60 * 24 * 3652.5; - testPass("epicsTime can represent 10 years hence"); - } - catch ( ... ) { - testFail("epicsTime exception for value 10 years hence"); - } - - try { - /* This test exists because in libCom/osi/os/posix/osdTime.cpp - * the convertDoubleToWakeTime() routine limits the timeout delay - * to 10 years. libCom/timer/timerQueue.cpp returns DBL_MAX for - * queues with no timers present, and convertDoubleToWakeTime() - * has to return an absolute Posix timestamp. On 2028-01-19 any - * systems that still implement time_t as a signed 32-bit integer - * will be unable to represent that timestamp, so this will fail. - */ - time_t_wrapper os_time_t = ten_years_hence; - epicsTime then = os_time_t; // No fractional seconds - double delta = ten_years_hence - then; - - testOk(delta >= 0 && delta < 1.0, - "OS time_t can represent 10 years hence"); - } - catch ( ... ) { - testFail("OS time_t conversion exception for value 10 years hence"); - } - - return testDone(); -} diff --git a/src/libCom/test/epicsTimeZoneTest.c b/src/libCom/test/epicsTimeZoneTest.c deleted file mode 100644 index 685295fc4..000000000 --- a/src/libCom/test/epicsTimeZoneTest.c +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "envDefs.h" -#include "epicsTime.h" -#include "epicsUnitTest.h" - -#include "testMain.h" - -#if defined(_WIN32) -# define tzset _tzset -#endif - -static -void setTZ(const char *tz) -{ - testDiag("TZ = \"%s\"", tz); - epicsEnvSet("TZ", tz); - tzset(); -} - -static -void test_localtime(time_t T, int sec, int min, int hour, - int mday, int mon, int year, - int wday, int yday, int isdst) -{ - struct tm B; - testDiag("test_localtime(%ld, ...)", (long)T); - if(epicsTime_localtime(&T, &B)!=epicsTimeOK) { - testFail("epicsTime_localtime() error"); - testSkip(9, "epicsTime_localtime() failed"); - } else { - B.tm_year += 1900; /* for readability */ - testPass("epicsTime_localtime() success"); -#define TEST(FLD) testOk(B.tm_##FLD==FLD, "%s %d==%d", #FLD, B.tm_##FLD, FLD) - TEST(sec); - TEST(min); - TEST(hour); - TEST(mday); - TEST(mon); - TEST(year); - TEST(wday); - TEST(yday); - TEST(isdst); -#undef TEST - } -} - -static -void test_gmtime(time_t T, int sec, int min, int hour, - int mday, int mon, int year, - int wday, int yday, int isdst) -{ - struct tm B; - testDiag("test_gmtime(%ld, ...)", (long)T); - if(epicsTime_gmtime(&T, &B)!=epicsTimeOK) { - testFail("epicsTime_localtime() error"); - testSkip(9, "epicsTime_localtime() failed"); - } else { - B.tm_year += 1900; /* for readability */ - testPass("epicsTime_localtime() success"); -#define TEST(FLD) testOk(B.tm_##FLD==FLD, "%s %d==%d", #FLD, B.tm_##FLD, FLD) - TEST(sec); - TEST(min); - TEST(hour); - TEST(mday); - TEST(mon); - TEST(year); - TEST(wday); - TEST(yday); - TEST(isdst); -#undef TEST - } -} - -MAIN(epicsTimeZoneTest) -{ - testPlan(160); - /* 1445259616 - * Mon Oct 19 09:00:16 2015 EDT - * Mon Oct 19 08:00:16 2015 CDT - * Mon Oct 19 03:00:16 2015 HST (no dst) - * Mon Oct 19 13:00:16 2015 UTC - */ - testDiag("POSIX 1445259616"); - setTZ("EST5EDT"); - test_localtime(1445259616ul, 16, 0, 9, 19, 9, 2015, 1, 291, 1); - test_gmtime (1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); - setTZ("CST6CDT"); - test_localtime(1445259616ul, 16, 0, 8, 19, 9, 2015, 1, 291, 1); - test_gmtime (1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); -#if defined(__rtems__) - setTZ("HST10HST10"); -#else - setTZ("HST10"); -#endif - test_localtime(1445259616ul, 16, 0, 3, 19, 9, 2015, 1, 291, 0); - test_gmtime (1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); - setTZ("UTC0"); - test_localtime(1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); - test_gmtime (1445259616ul, 16, 0, 13, 19, 9, 2015, 1, 291, 0); - /* 1421244931 - * Wed Jan 14 09:15:31 2015 EST - * Wed Jan 14 08:15:31 2015 CST - * Wed Jan 14 04:15:31 2015 HST - * Wed Jan 14 14:15:31 2015 UTC - */ - testDiag("POSIX 1421244931"); - setTZ("EST5EDT"); - test_localtime(1421244931ul, 31, 15, 9, 14, 0, 2015, 3, 13, 0); - test_gmtime (1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); - setTZ("CST6CDT"); - test_localtime(1421244931ul, 31, 15, 8, 14, 0, 2015, 3, 13, 0); - test_gmtime (1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); -#if defined(__rtems__) - setTZ("HST10HST10"); -#else - setTZ("HST10"); -#endif - test_localtime(1421244931ul, 31, 15, 4, 14, 0, 2015, 3, 13, 0); - test_gmtime (1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); - setTZ("UTC0"); - test_localtime(1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); - test_gmtime (1421244931ul, 31, 15, 14, 14, 0, 2015, 3, 13, 0); - return testDone(); -} diff --git a/src/libCom/test/epicsTimerTest.cpp b/src/libCom/test/epicsTimerTest.cpp deleted file mode 100644 index f2a510819..000000000 --- a/src/libCom/test/epicsTimerTest.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include -#include - -#include "epicsTimer.h" -#include "epicsEvent.h" -#include "epicsAssert.h" -#include "epicsGuard.h" -#include "tsFreeList.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -class notified : public epicsTimerNotify -{ -public: - bool done; - notified() : epicsTimerNotify(), done(false) {} - - expireStatus expire(const epicsTime ¤tTime) - {done=true; return expireStatus(noRestart);} -}; - -void testRefCount() -{ - notified action; - - epicsTimerQueueActive *Q1, *Q2; - epicsTimer *T1, *T2; - - Q1 = &epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - T1 = &Q1->createTimer(); - //timer->start(action, 0.0); - - Q2 = &epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - testOk1(Q1==Q2); - - T2 = &Q2->createTimer(); - - T2->destroy(); - Q2->release(); - - T1->destroy(); - Q1->release(); -} - -static const double delayVerifyOffset = 1.0; // sec - -class delayVerify : public epicsTimerNotify { -public: - delayVerify ( double expectedDelay, epicsTimerQueue & ); - void start ( const epicsTime &expireTime ); - void setBegin ( const epicsTime & ); - double delay () const; - double checkError () const; -protected: - virtual ~delayVerify (); -private: - epicsTimer &timer; - epicsTime beginStamp; - epicsTime expireStamp; - double expectedDelay; - expireStatus expire ( const epicsTime & ); - delayVerify ( const delayVerify & ); - delayVerify & operator = ( const delayVerify & ); -}; - -static volatile unsigned expireCount; -static epicsEvent expireEvent; - -delayVerify::delayVerify ( double expectedDelayIn, epicsTimerQueue &queueIn ) : - timer ( queueIn.createTimer() ), expectedDelay ( expectedDelayIn ) -{ -} - -delayVerify::~delayVerify () -{ - this->timer.destroy (); -} - -inline void delayVerify::setBegin ( const epicsTime &beginIn ) -{ - this->beginStamp = beginIn; -} - -inline double delayVerify::delay () const -{ - return this->expectedDelay; -} - -double delayVerify::checkError () const -{ - const double messageThresh = 2.0; // percent - double actualDelay = this->expireStamp - this->beginStamp; - double measuredError = actualDelay - this->expectedDelay; - double percentError = 100.0 * fabs ( measuredError ) / this->expectedDelay; - if ( ! testOk1 ( percentError < messageThresh ) ) { - testDiag ( "delay = %f s, error = %f s (%.1f %%)", - this->expectedDelay, measuredError, percentError ); - } - return measuredError; -} - -inline void delayVerify::start ( const epicsTime &expireTime ) -{ - this->timer.start ( *this, expireTime ); -} - -epicsTimerNotify::expireStatus delayVerify::expire ( const epicsTime ¤tTime ) -{ - this->expireStamp = currentTime; - if ( --expireCount == 0u ) { - expireEvent.signal (); - } - return noRestart; -} - -// -// verify reasonable timer interval accuracy -// -void testAccuracy () -{ - static const unsigned nTimers = 25u; - delayVerify *pTimers[nTimers]; - unsigned i; - unsigned timerCount = 0; - - testDiag ( "Testing timer accuracy" ); - - epicsTimerQueueActive &queue = - epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMax ); - - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i] = new delayVerify ( i * 0.1 + delayVerifyOffset, queue ); - timerCount += pTimers[i] ? 1 : 0; - } - testOk1 ( timerCount == nTimers ); - - expireCount = nTimers; - for ( i = 0u; i < nTimers; i++ ) { - epicsTime cur = epicsTime::getCurrent (); - pTimers[i]->setBegin ( cur ); - pTimers[i]->start ( cur + pTimers[i]->delay () ); - } - while ( expireCount != 0u ) { - expireEvent.wait (); - } - double averageMeasuredError = 0.0; - for ( i = 0u; i < nTimers; i++ ) { - averageMeasuredError += pTimers[i]->checkError (); - } - averageMeasuredError /= nTimers; - testDiag ("average timer delay error %f ms", - averageMeasuredError * 1000 ); - queue.release (); -} - - -class cancelVerify : public epicsTimerNotify { -public: - cancelVerify ( epicsTimerQueue & ); - void start ( const epicsTime &expireTime ); - void cancel (); - static unsigned cancelCount; - static unsigned expireCount; -protected: - virtual ~cancelVerify (); -private: - epicsTimer &timer; - expireStatus expire ( const epicsTime & ); - cancelVerify ( const cancelVerify & ); - cancelVerify & operator = ( const cancelVerify & ); -}; - -unsigned cancelVerify::cancelCount; -unsigned cancelVerify::expireCount; - -cancelVerify::cancelVerify ( epicsTimerQueue &queueIn ) : - timer ( queueIn.createTimer () ) -{ -} - -cancelVerify::~cancelVerify () -{ - this->timer.destroy (); -} - -inline void cancelVerify::start ( const epicsTime &expireTime ) -{ - this->timer.start ( *this, expireTime ); -} - -inline void cancelVerify::cancel () -{ - this->timer.cancel (); - ++cancelVerify::cancelCount; -} - -epicsTimerNotify::expireStatus cancelVerify::expire ( const epicsTime & ) -{ - ++cancelVerify::expireCount; - double root = 3.14159; - for ( unsigned i = 0u; i < 1000; i++ ) { - root = sqrt ( root ); - } - return noRestart; -} - -// -// verify that expire() won't be called after the timer is cancelled -// -void testCancel () -{ - static const unsigned nTimers = 25u; - cancelVerify *pTimers[nTimers]; - unsigned i; - unsigned timerCount = 0; - - cancelVerify::cancelCount = 0; - cancelVerify::expireCount = 0; - - testDiag ( "Testing timer cancellation" ); - - epicsTimerQueueActive &queue = - epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i] = new cancelVerify ( queue ); - timerCount += pTimers[i] ? 1 : 0; - } - testOk1 ( timerCount == nTimers ); - if ( ! testOk1 ( cancelVerify::expireCount == 0 ) ) - testDiag ( "expireCount = %u", cancelVerify::expireCount ); - if ( ! testOk1 ( cancelVerify::cancelCount == 0 ) ) - testDiag ( "cancelCount = %u", cancelVerify::cancelCount ); - - testDiag ( "starting %d timers", nTimers ); - epicsTime exp = epicsTime::getCurrent () + 4.0; - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i]->start ( exp ); - } - testOk1 ( cancelVerify::expireCount == 0 ); - testOk1 ( cancelVerify::cancelCount == 0 ); - - testDiag ( "cancelling timers" ); - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i]->cancel (); - } - testOk1 ( cancelVerify::expireCount == 0 ); - testOk1 ( cancelVerify::cancelCount == nTimers ); - - testDiag ( "waiting until after timers should have expired" ); - epicsThreadSleep ( 5.0 ); - testOk1 ( cancelVerify::expireCount == 0 ); - testOk1 ( cancelVerify::cancelCount == nTimers ); - - epicsThreadSleep ( 1.0 ); - queue.release (); -} - - -class expireDestroyVerify : public epicsTimerNotify { -public: - expireDestroyVerify ( epicsTimerQueue & ); - void start ( const epicsTime &expireTime ); - static unsigned destroyCount; -protected: - virtual ~expireDestroyVerify (); -private: - epicsTimer & timer; - expireStatus expire ( const epicsTime & ); - expireDestroyVerify ( const expireDestroyVerify & ); - expireDestroyVerify & operator = ( const expireDestroyVerify & ); -}; - -unsigned expireDestroyVerify::destroyCount; - -expireDestroyVerify::expireDestroyVerify ( epicsTimerQueue & queueIn ) : - timer ( queueIn.createTimer () ) -{ -} - -expireDestroyVerify::~expireDestroyVerify () -{ - this->timer.destroy (); - ++expireDestroyVerify::destroyCount; -} - -inline void expireDestroyVerify::start ( const epicsTime & expireTime ) -{ - this->timer.start ( *this, expireTime ); -} - -epicsTimerNotify::expireStatus expireDestroyVerify::expire ( const epicsTime & ) -{ - delete this; - return noRestart; -} - -// -// verify that a timer can be destroyed in expire -// -void testExpireDestroy () -{ - static const unsigned nTimers = 25u; - expireDestroyVerify *pTimers[nTimers]; - unsigned i; - unsigned timerCount = 0; - expireDestroyVerify::destroyCount = 0; - - testDiag ( "Testing timer destruction in expire()" ); - - epicsTimerQueueActive &queue = - epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i] = new expireDestroyVerify ( queue ); - timerCount += pTimers[i] ? 1 : 0; - } - testOk1 ( timerCount == nTimers ); - testOk1 ( expireDestroyVerify::destroyCount == 0 ); - - testDiag ( "starting %d timers", nTimers ); - epicsTime cur = epicsTime::getCurrent (); - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i]->start ( cur ); - } - - testDiag ( "waiting until all timers should have expired" ); - epicsThreadSleep ( 5.0 ); - - testOk1 ( expireDestroyVerify::destroyCount == nTimers ); - queue.release (); -} - - -class periodicVerify : public epicsTimerNotify { -public: - periodicVerify ( epicsTimerQueue & ); - void start ( const epicsTime &expireTime ); - void cancel (); - bool verifyCount (); -protected: - virtual ~periodicVerify (); -private: - epicsTimer &timer; - unsigned nExpire; - bool cancelCalled; - expireStatus expire ( const epicsTime & ); - periodicVerify ( const periodicVerify & ); - periodicVerify & operator = ( const periodicVerify & ); -}; - -periodicVerify::periodicVerify ( epicsTimerQueue & queueIn ) : - timer ( queueIn.createTimer () ), nExpire ( 0u ), - cancelCalled ( false ) -{ -} - -periodicVerify::~periodicVerify () -{ - this->timer.destroy (); -} - -inline void periodicVerify::start ( const epicsTime &expireTime ) -{ - this->timer.start ( *this, expireTime ); -} - -inline void periodicVerify::cancel () -{ - this->timer.cancel (); - this->cancelCalled = true; -} - -inline bool periodicVerify::verifyCount () -{ - return ( this->nExpire > 1u ); -} - -epicsTimerNotify::expireStatus periodicVerify::expire ( const epicsTime & ) -{ - this->nExpire++; - double root = 3.14159; - for ( unsigned i = 0u; i < 1000; i++ ) { - root = sqrt ( root ); - } - verify ( ! this->cancelCalled ); - double delay = rand (); - delay = delay / RAND_MAX; - delay /= 10.0; - return expireStatus ( restart, delay ); -} - -// -// verify periodic timers -// -void testPeriodic () -{ - static const unsigned nTimers = 25u; - periodicVerify *pTimers[nTimers]; - unsigned i; - unsigned timerCount = 0; - - testDiag ( "Testing periodic timers" ); - - epicsTimerQueueActive &queue = - epicsTimerQueueActive::allocate ( true, epicsThreadPriorityMin ); - - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i] = new periodicVerify ( queue ); - timerCount += pTimers[i] ? 1 : 0; - } - testOk1 ( timerCount == nTimers ); - - testDiag ( "starting %d timers", nTimers ); - epicsTime cur = epicsTime::getCurrent (); - for ( i = 0u; i < nTimers; i++ ) { - pTimers[i]->start ( cur ); - } - - testDiag ( "waiting until all timers should have expired" ); - epicsThreadSleep ( 5.0 ); - - bool notWorking = false; - for ( i = 0u; i < nTimers; i++ ) { - notWorking |= ! pTimers[i]->verifyCount (); - pTimers[i]->cancel (); - } - testOk( ! notWorking, "All timers expiring" ); - epicsThreadSleep ( 1.0 ); - queue.release (); -} - -MAIN(epicsTimerTest) -{ - testPlan(41); - testRefCount(); - testAccuracy (); - testCancel (); - testExpireDestroy (); - testPeriodic (); - return testDone(); -} diff --git a/src/libCom/test/epicsTypesTest.c b/src/libCom/test/epicsTypesTest.c deleted file mode 100644 index aa882aa9f..000000000 --- a/src/libCom/test/epicsTypesTest.c +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsTypesTest.c - * - * Size-check epicsTypes - * - */ - -#include "epicsUnitTest.h" -#include "epicsTypes.h" -#include "testMain.h" -#include "epicsAssert.h" - -/* - * Might as well check at compile-time too, since we can. - */ - -STATIC_ASSERT(sizeof(epicsInt8) == 1); -STATIC_ASSERT(sizeof(epicsUInt8) == 1); -STATIC_ASSERT(sizeof(epicsInt16) == 2); -STATIC_ASSERT(sizeof(epicsUInt16) == 2); -STATIC_ASSERT(sizeof(epicsInt32) == 4); -STATIC_ASSERT(sizeof(epicsUInt32) == 4); -STATIC_ASSERT(sizeof(epicsInt64) == 8); -STATIC_ASSERT(sizeof(epicsUInt64) == 8); -STATIC_ASSERT(sizeof(epicsFloat32) == 4); -STATIC_ASSERT(sizeof(epicsFloat64) == 8); - -MAIN(epicsTypesTest) -{ - testPlan(10); - - testOk1(sizeof(epicsInt8) == 1); - testOk1(sizeof(epicsUInt8) == 1); - - testOk1(sizeof(epicsInt16) == 2); - testOk1(sizeof(epicsUInt16) == 2); - - testOk1(sizeof(epicsInt32) == 4); - testOk1(sizeof(epicsUInt32) == 4); - - testOk1(sizeof(epicsInt64) == 8); - testOk1(sizeof(epicsUInt64) == 8); - - testOk1(sizeof(epicsFloat32) == 4); - testOk1(sizeof(epicsFloat64) == 8); - - return testDone(); -} diff --git a/src/libCom/test/epicsUnitTestTest.c b/src/libCom/test/epicsUnitTestTest.c deleted file mode 100644 index b16bad52a..000000000 --- a/src/libCom/test/epicsUnitTestTest.c +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 The University of Chicago, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Andrew Johnson - * - * Test for the unit test module... - */ - -#include "epicsUnitTest.h" - -#define testOk1_success 1 -#define testOk1_failure 0 - -int main (void) { - testPlan(11); - testOk(1, "testOk(1)"); - testOk(0, "testOk(0)"); - testPass("testPass()"); - testFail("testFail()"); - testSkip(2, "Skipping two"); - testTodoBegin("Testing Todo"); - testOk(1, "Todo pass"); - testOk(0, "Todo fail"); - testSkip(1, "Todo skip"); - testTodoEnd(); - testOk1(testOk1_success); - testOk1(testOk1_failure); - testDiag("Diagnostic"); -/* testAbort("testAbort"); */ - return testDone(); -} diff --git a/src/libCom/test/epicsUnitTestTest.plt b/src/libCom/test/epicsUnitTestTest.plt deleted file mode 100644 index 1cb9e0c1b..000000000 --- a/src/libCom/test/epicsUnitTestTest.plt +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Test; - -BEGIN {plan tests => 1} - -my $prog = "./$0"; -$prog =~ s/\.t$//; - -my $expected = join '', ; - -$ENV{HARNESS_ACTIVE} = 1; -my $result = `$prog`; - -ok($result, $expected); # test output matches - -__DATA__ -1..11 -ok 1 - testOk(1) -not ok 2 - testOk(0) -ok 3 - testPass() -not ok 4 - testFail() -ok 5 # SKIP Skipping two -ok 6 # SKIP Skipping two -ok 7 - Todo pass # TODO Testing Todo -not ok 8 - Todo fail # TODO Testing Todo -ok 9 # SKIP Todo skip -ok 10 - testOk1_success -not ok 11 - testOk1_failure -# Diagnostic diff --git a/src/libCom/test/fdmgrTest.c b/src/libCom/test/fdmgrTest.c deleted file mode 100644 index e41784ccf..000000000 --- a/src/libCom/test/fdmgrTest.c +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "fdmgr.h" -#include "epicsTime.h" -#include "epicsAssert.h" -#include "cadef.h" - -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -static const unsigned uSecPerSec = 1000000; - -typedef struct cbStructCreateDestroyFD { - fdctx *pfdm; - int trig; -} cbStructCreateDestroyFD; - -void fdHandler (void *pArg) -{ - cbStructCreateDestroyFD *pCBFD = (cbStructCreateDestroyFD *) pArg; - - printf ("triggered\n"); - pCBFD->trig = 1; -} - -void fdCreateDestroyHandler (void *pArg, int fd, int open) -{ - cbStructCreateDestroyFD *pCBFD = (cbStructCreateDestroyFD *) pArg; - int status; - - if (open) { - printf ("new fd = %d\n", fd); - status = fdmgr_add_callback (pCBFD->pfdm, fd, fdi_read, fdHandler, pArg); - verify (status==0); - } - else { - printf ("terminated fd = %d\n", fd); - status = fdmgr_clear_callback (pCBFD->pfdm, fd, fdi_read); - verify (status==0); - } -} - -typedef struct cbStuctTimer { - epicsTimeStamp time; - int done; -} cbStruct; - -void alarmCB (void *parg) -{ - cbStruct *pCBS = (cbStruct *) parg; - epicsTimeGetCurrent (&pCBS->time); - pCBS->done = 1; -} - -void testTimer (fdctx *pfdm, double delay) -{ - int status; - fdmgrAlarmId aid; - struct timeval tmo; - epicsTimeStamp begin; - cbStruct cbs; - double measuredDelay; - double measuredError; - - epicsTimeGetCurrent (&begin); - cbs.done = 0; - tmo.tv_sec = (time_t) delay; - tmo.tv_usec = (unsigned long) ((delay - tmo.tv_sec) * uSecPerSec); - aid = fdmgr_add_timeout (pfdm, &tmo, alarmCB, &cbs); - verify (aid!=fdmgrNoAlarm); - - while (!cbs.done) { - tmo.tv_sec = (time_t) delay; - tmo.tv_usec = (unsigned long) ((delay - tmo.tv_sec) * uSecPerSec); - status = fdmgr_pend_event (pfdm, &tmo); - verify (status==0); - } - - measuredDelay = epicsTimeDiffInSeconds (&cbs.time, &begin); - measuredError = fabs (measuredDelay-delay); - printf ("measured delay for %lf sec was off by %lf sec (%lf %%)\n", - delay, measuredError, 100.0*measuredError/delay); -} - -int main (int argc, char **argv) -{ - int status; - fdctx *pfdm; - cbStructCreateDestroyFD cbsfd; - struct timeval tmo; - chid chan; - - pfdm = fdmgr_init (); - verify (pfdm); - - SEVCHK (ca_task_initialize(), NULL); - cbsfd.pfdm = pfdm; - SEVCHK (ca_add_fd_registration (fdCreateDestroyHandler, &cbsfd), NULL); - - /* - * timer test - */ - testTimer (pfdm, 0.001); - testTimer (pfdm, 0.01); - testTimer (pfdm, 0.1); - testTimer (pfdm, 1.0); - - if (argc==2) { - SEVCHK(ca_search (argv[1], &chan), NULL); - } - - while (1) { - tmo.tv_sec = 0; - tmo.tv_usec = 100000; - cbsfd.trig = 0; - status = fdmgr_pend_event (pfdm, &tmo); - verify (status==0); - ca_poll (); - } - - status = fdmgr_delete (pfdm); - verify (status==0); - - printf ( "Test Complete\n" ); - - return 0; -} - diff --git a/src/libCom/test/ipAddrToAsciiTest.cpp b/src/libCom/test/ipAddrToAsciiTest.cpp deleted file mode 100644 index f9323374d..000000000 --- a/src/libCom/test/ipAddrToAsciiTest.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2017 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#define EPICS_PRIVATE_API - -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsThread.h" -#include "epicsEvent.h" -#include "ipAddrToAsciiAsynchronous.h" - -#include "epicsUnitTest.h" -#include "testMain.h" - -namespace { - -typedef epicsGuard Guard; -typedef epicsGuardRelease UnGuard; - -struct CB : public ipAddrToAsciiCallBack -{ - const char *name; - epicsMutex mutex; - epicsEvent starter, blocker, complete; - bool started, cont, done; - CB(const char *name) : name(name), started(false), cont(false), done(false) {} - virtual ~CB() {} - virtual void transactionComplete ( const char * pHostName ) - { - Guard G(mutex); - started = true; - starter.signal(); - testDiag("In transactionComplete(%s) for %s", pHostName, name); - while(!cont) { - UnGuard U(G); - if(!blocker.wait(2.0)) - break; - } - done = true; - complete.signal(); - } - void waitStart() - { - Guard G(mutex); - while(!started) { - UnGuard U(G); - if(!starter.wait(2.0)) - break; - } - } - void poke() - { - testDiag("Poke"); - Guard G(mutex); - cont = true; - blocker.signal(); - } - void finish() - { - testDiag("Finish"); - Guard G(mutex); - while(!done) { - UnGuard U(G); - if(!complete.wait(2.0)) - break; - } - testDiag("Finished"); - } -}; - -// ensure that lookup of 127.0.0.1 works -void doLookup(ipAddrToAsciiEngine& engine) -{ - testDiag("In doLookup"); - - ipAddrToAsciiTransaction& trn(engine.createTransaction()); - CB cb("cb"); - osiSockAddr addr; - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addr.ia.sin_port = htons(42); - - testDiag("Start lookup"); - trn.ipAddrToAscii(addr, cb); - cb.poke(); - cb.finish(); - testOk1(cb.cont); - testOk1(cb.done); - - trn.release(); -} - -// Test cancel of pending transaction -void doCancel() -{ - testDiag("In doCancel"); - - ipAddrToAsciiEngine& engine1(ipAddrToAsciiEngine::allocate()); - ipAddrToAsciiEngine& engine2(ipAddrToAsciiEngine::allocate()); - - ipAddrToAsciiTransaction& trn1(engine1.createTransaction()), - & trn2(engine2.createTransaction()); - testOk1(&trn1!=&trn2); - CB cb1("cb1"), cb2("cb2"); - - osiSockAddr addr; - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addr.ia.sin_port = htons(42); - - // ensure that the worker thread is blocked with a transaction from engine1 - testDiag("Start lookup1"); - trn1.ipAddrToAscii(addr, cb1); - testDiag("Wait start1"); - cb1.waitStart(); - - testDiag("Start lookup2"); - trn2.ipAddrToAscii(addr, cb2); - - testDiag("release engine2, implicitly cancels lookup2"); - engine2.release(); - - cb2.poke(); - testDiag("Wait for lookup2 timeout"); - cb2.finish(); - testOk1(!cb2.done); - - testDiag("Complete lookup1"); - cb1.poke(); - cb1.finish(); - testOk1(cb1.done); - - engine1.release(); - - trn1.release(); - trn2.release(); -} - -} // namespace - -MAIN(ipAddrToAsciiTest) -{ - testPlan(5); - { - ipAddrToAsciiEngine& engine(ipAddrToAsciiEngine::allocate()); - doLookup(engine); - engine.release(); - } - doCancel(); - // TODO: somehow test cancel of in-progress callback - // allow time for any un-canceled transcations to crash us... - epicsThreadSleep(1.0); - -#ifdef __linux__ - ipAddrToAsciiEngine::cleanup(); -#endif - - return testDone(); -} diff --git a/src/libCom/test/macDefExpandTest.c b/src/libCom/test/macDefExpandTest.c deleted file mode 100644 index a5e45a420..000000000 --- a/src/libCom/test/macDefExpandTest.c +++ /dev/null @@ -1,254 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include - -#include "macLib.h" -#include "envDefs.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -static void checkMac(MAC_HANDLE *handle, const char *name, const char *value) -{ - char buf[20]; - - buf[19]='\0'; - if(macGetValue(handle, name, buf, 19)<0) { - if(value) - testFail("Macro %s undefined, expected %s", name, value); - else - testPass("Macro %s undefined", name); - } else { - if(!value) - testFail("Macro %s is %s, expected undefined", name, buf); - else if(strcmp(value, buf)==0) - testPass("Macro %s is %s", name, value); - else - testFail("Macro %s is %s, expected %s", name, buf, value); - } -} - -static void macEnvScope(void) -{ - MAC_HANDLE *handle; - char **defines; - static const char *pairs[] = { "", "environ", NULL, NULL }; - - epicsEnvSet("C","3"); - epicsEnvSet("D","4"); - epicsEnvSet("E","5"); - - macCreateHandle(&handle, pairs); - macParseDefns(NULL, "A=1,B=2,E=15", &defines); - macInstallMacros(handle, defines); - - checkMac(handle, "A", "1"); - checkMac(handle, "B", "2"); - checkMac(handle, "C", "3"); - checkMac(handle, "D", "4"); - checkMac(handle, "E", "15"); - checkMac(handle, "F", NULL); - - { - macPushScope(handle); - - macParseDefns(NULL, "A=11,C=13,D=14,G=7", &defines); - macInstallMacros(handle, defines); - - checkMac(handle, "A", "11"); - checkMac(handle, "B", "2"); - checkMac(handle, "C", "13"); - checkMac(handle, "D", "14"); - checkMac(handle, "E", "15"); - checkMac(handle, "F", NULL); - checkMac(handle, "G", "7"); - - epicsEnvSet("D", "24"); - macPutValue(handle, "D", NULL); /* implicit when called through in iocshBody */ - epicsEnvSet("F", "6"); - macPutValue(handle, "F", NULL); /* implicit */ - epicsEnvSet("G", "17"); - macPutValue(handle, "G", NULL); /* implicit */ - - checkMac(handle, "D", "24"); - checkMac(handle, "F", "6"); - checkMac(handle, "G", "17"); - - macPopScope(handle); - } - - checkMac(handle, "A", "1"); - checkMac(handle, "B", "2"); - checkMac(handle, "C", "3"); - checkMac(handle, "D", "24"); - checkMac(handle, "E", "15"); - checkMac(handle, "F", "6"); - checkMac(handle, "G", "17"); - - { - macPushScope(handle); - - macParseDefns(NULL, "D=34,G=27", &defines); - macInstallMacros(handle, defines); - - checkMac(handle, "D", "34"); - checkMac(handle, "G", "27"); - - macPopScope(handle); - } - - checkMac(handle, "D", "24"); - - macDeleteHandle(handle); -} - -static void check(const char *str, const char *macros, const char *expect) -{ - MAC_HANDLE *handle; - char **defines; - static const char *pairs[] = { "", "environ", NULL, NULL }; - char *got; - int pass = 1; - - macCreateHandle(&handle, pairs); - macParseDefns(NULL, macros, &defines); - macInstallMacros(handle, defines); - - got = macDefExpand(str, handle); - - if (expect && !got) { - testDiag("Got NULL, expected \"%s\".\n", expect); - pass = 0; - } - else if (!expect && got) { - testDiag("Got \"%s\", expected NULL.\n", got); - pass = 0; - } - else if (expect && got && strcmp(got, expect)) { - testDiag("Got \"%s\", expected \"%s\".\n", got, expect); - pass = 0; - } - testOk(pass, "%s", str); - - macDeleteHandle(handle); -} - -MAIN(macDefExpandTest) -{ - eltc(0); - testPlan(97); - - check("FOO", "", "FOO"); - - check("${FOO}", "", NULL); - check("${FOO,BAR}", "", NULL); - check("${FOO,BAR=baz}", "", NULL); - check("${FOO,BAR=$(FOO)}", "", NULL); - check("${FOO,FOO}", "", NULL); - check("${FOO,FOO=$(FOO)}", "", NULL); - check("${FOO,BAR=baz,FUM}", "", NULL); - - check("${=}", "", ""); - check("x${=}y", "", "xy"); - - check("${,=}", "", ""); - check("x${,=}y", "", "xy"); - - check("${FOO=}", "", ""); - check("x${FOO=}y", "", "xy"); - - check("${FOO=,}", "", ""); - check("x${FOO=,}y", "", "xy"); - - check("${FOO,FOO=}", "", ""); - check("x${FOO,FOO=}y", "", "xy"); - - check("${FOO=,BAR}", "", ""); - check("x${FOO=,BAR}y", "", "xy"); - - check("${FOO=$(BAR=)}", "", ""); - check("x${FOO=$(BAR=)}y", "", "xy"); - - check("${FOO=,BAR=baz}", "", ""); - check("x${FOO=,BAR=baz}y", "", "xy"); - - check("${FOO=$(BAR),BAR=}", "", ""); - check("x${FOO=$(BAR),BAR=}y", "", "xy"); - - check("${=BAR}", "", "BAR"); - check("x${=BAR}y", "", "xBARy"); - - check("${FOO=BAR}", "", "BAR"); - check("x${FOO=BAR}y", "", "xBARy"); - - epicsEnvSet("FOO","BLETCH"); - check("${FOO}", "", "BLETCH"); - check("${FOO,FOO}", "", "BLETCH"); - check("x${FOO}y", "", "xBLETCHy"); - check("x${FOO}y${FOO}z", "", "xBLETCHyBLETCHz"); - check("${FOO=BAR}", "", "BLETCH"); - check("x${FOO=BAR}y", "", "xBLETCHy"); - check("${FOO=${BAZ}}", "", "BLETCH"); - check("${FOO=${BAZ},BAR=$(BAZ)}", "", "BLETCH"); - check("x${FOO=${BAZ}}y", "", "xBLETCHy"); - check("x${FOO=${BAZ},BAR=$(BAZ)}y", "", "xBLETCHy"); - check("${BAR=${FOO}}", "", "BLETCH"); - check("x${BAR=${FOO}}y", "", "xBLETCHy"); - check("w${BAR=x${FOO}y}z", "", "wxBLETCHyz"); - - check("${FOO,FOO=BAR}", "", "BAR"); - check("x${FOO,FOO=BAR}y", "", "xBARy"); - check("${BAR,BAR=$(FOO)}", "", "BLETCH"); - check("x${BAR,BAR=$(FOO)}y", "", "xBLETCHy"); - check("${BAR,BAR=$($(FOO)),BLETCH=GRIBBLE}", "", "GRIBBLE"); - check("x${BAR,BAR=$($(FOO)),BLETCH=GRIBBLE}y", "", "xGRIBBLEy"); - check("${$(BAR,BAR=$(FOO)),BLETCH=GRIBBLE}", "", "GRIBBLE"); - check("x${$(BAR,BAR=$(FOO)),BLETCH=GRIBBLE}y", "", "xGRIBBLEy"); - - check("${FOO}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - check("x${FOO}/${BAR}y", "BAR=GLEEP", "xBLETCH/GLEEPy"); - check("${FOO,BAR}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - check("${FOO,BAR=x}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - check("${BAZ=BLETCH,BAR}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - check("${BAZ=BLETCH,BAR=x}/${BAR}", "BAR=GLEEP", "BLETCH/GLEEP"); - - check("${${FOO}}", "BAR=GLEEP,BLETCH=BAR", "BAR"); - check("x${${FOO}}y", "BAR=GLEEP,BLETCH=BAR", "xBARy"); - check("${${FOO}=GRIBBLE}", "BAR=GLEEP,BLETCH=BAR", "BAR"); - check("x${${FOO}=GRIBBLE}y", "BAR=GLEEP,BLETCH=BAR", "xBARy"); - - check("${${FOO}}", "BAR=GLEEP,BLETCH=${BAR}", "GLEEP"); - - epicsEnvSet("FOO","${BAR}"); - check("${FOO}", "BAR=GLEEP,BLETCH=${BAR}" ,"GLEEP"); - - check("${FOO}", "BAR=${BAZ},BLETCH=${BAR}", NULL); - - check("${FOO}", "BAR=${BAZ=GRIBBLE},BLETCH=${BAR}", "GRIBBLE"); - - check("${FOO}", "BAR=${STR1},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", "VAL1"); - - check("${FOO}", "BAR=${STR2},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", "VAL2"); - - check("${FOO}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL); - check("${FOO,FOO=$(FOO)}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL); - check("${FOO=$(FOO)}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL); - check("${FOO=$(BAR),BAR=$(FOO)}", "BAR=${FOO},BLETCH=${BAR},STR1=VAL1,STR2=VAL2", NULL); - - macEnvScope(); - - errlogFlush(); - eltc(1); - return testDone(); -} diff --git a/src/libCom/test/macLibTest.c b/src/libCom/test/macLibTest.c deleted file mode 100644 index 7f1e2c544..000000000 --- a/src/libCom/test/macLibTest.c +++ /dev/null @@ -1,221 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include -#include -#include - -#include "macLib.h" -#include "dbDefs.h" -#include "envDefs.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -MAC_HANDLE *h; - -static void check(const char *str, const char *expect) -{ - char output[MAC_SIZE] = {'\0'}; - long status = macExpandString(h, str, output, MAC_SIZE); - long expect_len = strlen(expect+1); - int expect_error = (expect[0] == '!'); - int statBad = expect_error ^ (status < 0); - int strBad = strcmp(output, expect+1); - - testOk(!statBad && !strBad, "%s => %s", str, output); - - if (strBad) { - testDiag("Got \"%s\", expected \"%s\"", output, expect+1); - } - if (statBad) { - testDiag("Return status was %ld, expected %ld", - status, expect_error ? -expect_len : expect_len); - } -} - -static void ovcheck(void) -{ - char output[54]; - long status; - - macPutValue(h, "OVVAR","abcdefghijklmnopqrstuvwxyz"); - - memset(output, '~', sizeof output); - status = macExpandString(h, "abcdefghijklmnopqrstuvwxyz$(OVVAR)", output, 52); - testOk(status == 51, "expansion returned %ld, expected 51", status); - testOk(output[50] == 'y', "final character %x, expect 79 (y)", output[50]); - testOk(output[51] == '\0', "terminator character %x, expect 0", output[51]); - testOk(output[52] == '~', "sentinel character %x, expect 7e, (~)", output[52]); - - memset(output, '~', sizeof output); - status = macExpandString(h, "abcdefghijklmnopqrstuvwxyz$(OVVAR)", output, 53); - testOk(status == 52, "expansion returned %ld, expected 52", status); - testOk(output[51] == 'z', "final character %x, expect 7a (z)", output[51]); - testOk(output[52] == '\0', "terminator character %x, expect 0", output[52]); - testOk(output[53] == '~', "sentinel character %x, expect 7e, (~)", output[53]); -} - -MAIN(macLibTest) -{ - testPlan(91); - - if (macCreateHandle(&h, NULL)) - testAbort("macCreateHandle() failed"); - macSuppressWarning(h, TRUE); - - check("FOO", " FOO"); - - check("$(FOO)", "!$(FOO,undefined)"); - check("${FOO}", "!$(FOO,undefined)"); - check("${FOO=${FOO}}", "!$(FOO,undefined)"); - check("${FOO,FOO}", "!$(FOO,undefined)"); - check("${FOO,FOO=${FOO}}", "!$(FOO,recursive)"); - check("${FOO,BAR}", "!$(FOO,undefined)"); - check("${FOO,BAR=baz}", "!$(FOO,undefined)"); - check("${FOO,BAR=${FOO}}", "!$(FOO,undefined)"); - check("${FOO,BAR=baz,FUM}", "!$(FOO,undefined)"); - check("${FOO=${BAR},BAR=${FOO}}", "!$(FOO,undefined)"); - check("${FOO,FOO=${BAR},BAR=${FOO}}", "!$(BAR,recursive)"); - - check("${=}", " "); - check("x${=}y", " xy"); - - check("${,=}", " "); - check("x${,=}y", " xy"); - - check("${FOO=}", " "); - check("x${FOO=}y", " xy"); - - check("${FOO=,}", " "); - check("x${FOO=,}y", " xy"); - - check("${FOO,FOO=}", " "); - check("x${FOO,FOO=}y", " xy"); - - check("${FOO=,BAR}", " "); - check("x${FOO=,BAR}y", " xy"); - - check("${FOO=${BAR=}}", " "); - check("x${FOO=${BAR=}}y", " xy"); - - check("${FOO=,BAR=baz}", " "); - check("x${FOO=,BAR=baz}y", " xy"); - - check("${FOO=${BAR},BAR=}", " "); - check("x${FOO=${BAR},BAR=}y", " xy"); - - check("${=BAR}", " BAR"); - check("x${=BAR}y", " xBARy"); - - check("${FOO=BAR}", " BAR"); - check("x${FOO=BAR}y", " xBARy"); - - macPutValue(h, "FOO", "BLETCH"); - /* FOO = "BLETCH" */ - check("${FOO}", " BLETCH"); - check("${FOO,FOO}", " BLETCH"); - check("x${FOO}y", " xBLETCHy"); - check("x${FOO}y${FOO}z", " xBLETCHyBLETCHz"); - check("${FOO=BAR}", " BLETCH"); - check("x${FOO=BAR}y", " xBLETCHy"); - check("${FOO=${BAZ}}", " BLETCH"); - check("${FOO=${BAZ},BAR=${BAZ}}", " BLETCH"); - check("x${FOO=${BAZ}}y", " xBLETCHy"); - check("x${FOO=${BAZ},BAR=${BAZ}}y", " xBLETCHy"); - check("${BAR=${FOO}}", " BLETCH"); - check("x${BAR=${FOO}}y", " xBLETCHy"); - check("w${BAR=x${FOO}y}z", " wxBLETCHyz"); - - check("${FOO,FOO=BAR}", " BAR"); - check("x${FOO,FOO=BAR}y", " xBARy"); - check("${BAR,BAR=${FOO}}", " BLETCH"); - check("x${BAR,BAR=${FOO}}y", " xBLETCHy"); - check("${BAR,BAR=${${FOO}},BLETCH=GRIBBLE}", " GRIBBLE"); - check("x${BAR,BAR=${${FOO}},BLETCH=GRIBBLE}y", " xGRIBBLEy"); - check("${${BAR,BAR=${FOO}},BLETCH=GRIBBLE}", " GRIBBLE"); - check("x${${BAR,BAR=${FOO}},BLETCH=GRIBBLE}y", " xGRIBBLEy"); - check("${N=${FOO}/${BAR},BAR=GLEEP}", " BLETCH/GLEEP"); - - macPutValue(h, "BAR","GLEEP"); - /* FOO = "BLETCH" */ - /* BAR = "GLEEP" */ - check("${FOO}/${BAR}", " BLETCH/GLEEP"); - check("x${FOO}/${BAR}y", " xBLETCH/GLEEPy"); - check("${FOO,BAR}/${BAR}", " BLETCH/GLEEP"); - check("${FOO,BAR=x}/${BAR}", " BLETCH/GLEEP"); - check("${BAZ=BLETCH,BAR}/${BAR}", " BLETCH/GLEEP"); - check("${BAZ=BLETCH,BAR=x}/${BAR}", " BLETCH/GLEEP"); - check("${N=${FOO}/${BAR}}", " BLETCH/GLEEP"); - - macPutValue(h, "BLETCH","BAR"); - /* FOO = "BLETCH" */ - /* BLETCH = "BAR" */ - check("${${FOO}}", " BAR"); - check("x${${FOO}}y", " xBARy"); - check("${${FOO}=GRIBBLE}", " BAR"); - check("x${${FOO}=GRIBBLE}y", " xBARy"); - - macPutValue(h, "BLETCH","${BAR}"); - /* FOO = "BLETCH" */ - /* BLETCH = "${BAR}" */ - /* BAR = "GLEEP" */ - check("${${FOO}}", " GLEEP"); - check("${BLETCH=${FOO}}", " GLEEP"); - - macPutValue(h, "FOO","${BAR}"); - /* FOO = "${BAR}" */ - /* BAR = "GLEEP" */ - check("${FOO}", " GLEEP"); - check("${FOO=BLETCH,BAR=BAZ}", " BAZ"); - - macPutValue(h, "BAR","${BAZ}"); - /* FOO = "${BAR}" */ - /* BAR = "${BAZ}" */ - check("${FOO}", "!$(BAZ,undefined)"); - - macPutValue(h, "BAR","${BAZ=GRIBBLE}"); - /* FOO = "${BAR}" */ - /* BAR = "${BAZ=GRIBBLE}" */ - check("${FOO}", " GRIBBLE"); - check("${FOO,BAZ=GEEK}", " GEEK"); - - macPutValue(h, "BAR","${STR1}"); - macPutValue(h, "STR1","VAL1"); - macPutValue(h, "STR2","VAL2"); - /* FOO = "${BAR}" */ - /* BAR = "${STR1}" */ - /* STR1 = "VAL1" */ - /* STR2 = "VAL2" */ - check("${FOO}", " VAL1"); - - macPutValue(h, "BAR","${STR2}"); - /* FOO = "${BAR}" */ - /* BAR = "${STR2}" */ - /* STR1 = "VAL1" */ - /* STR2 = "VAL2" */ - check("${FOO}", " VAL2"); - - check("$(FOO)$(FOO1)", "!VAL2$(FOO1,undefined)"); - check("$(FOO1)$(FOO)", "!$(FOO1,undefined)VAL2"); - - macPutValue(h, "BAR","${FOO}"); - /* FOO = "${BAR}" */ - /* BAR = "${FOO}" */ - check("${FOO}", "!$(BAR,recursive)"); - check("${FOO=GRIBBLE}", "!$(BAR,recursive)"); - check("${FOO=GRIBBLE,BAR=${FOO}}", "!$(BAR,recursive)"); - check("${FOO,FOO=${FOO}}", "!$(FOO,recursive)"); - check("${FOO=GRIBBLE,FOO=${FOO}}", "!$(FOO,recursive)"); - - ovcheck(); - - return testDone(); -} diff --git a/src/libCom/test/ringBytesTest.c b/src/libCom/test/ringBytesTest.c deleted file mode 100644 index 6cef93334..000000000 --- a/src/libCom/test/ringBytesTest.c +++ /dev/null @@ -1,123 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* ringBytesTest.c */ - -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsRingBytes.h" -#include "errlog.h" -#include "epicsEvent.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -#define RINGSIZE 10 - -typedef struct info { - epicsEventId consumerEvent; - epicsRingBytesId ring; -}info; - -static void check(epicsRingBytesId ring, int expectedFree) -{ - int expectedUsed = RINGSIZE - expectedFree; - int expectedEmpty = (expectedUsed == 0); - int expectedFull = (expectedFree == 0); - int nFree = epicsRingBytesFreeBytes(ring); - int nUsed = epicsRingBytesUsedBytes(ring); - int isEmpty = epicsRingBytesIsEmpty(ring); - int isFull = epicsRingBytesIsFull(ring); - - testOk(nFree == expectedFree, "Free: %d == %d", nFree, expectedFree); - testOk(nUsed == expectedUsed, "Used: %d == %d", nUsed, expectedUsed); - testOk(isEmpty == expectedEmpty, "Empty: %d == %d", isEmpty, expectedEmpty); - testOk(isFull == expectedFull, "Full: %d == %d", isFull, expectedFull); -} - -MAIN(ringBytesTest) -{ - int i, n; - info *pinfo; - epicsEventId consumerEvent; - char put[RINGSIZE+1]; - char get[RINGSIZE+1]; - epicsRingBytesId ring; - - testPlan(245); - - pinfo = calloc(1,sizeof(info)); - if (!pinfo) { - testAbort("calloc failed"); - } - pinfo->consumerEvent = consumerEvent = epicsEventCreate(epicsEventEmpty); - if (!consumerEvent) { - testAbort("epicsEventCreate failed"); - } - - pinfo->ring = ring = epicsRingBytesCreate(RINGSIZE); - if (!ring) { - testAbort("epicsRingBytesCreate failed"); - } - check(ring, RINGSIZE); - - for (i = 0 ; i < sizeof(put) ; i++) - put[i] = i; - for(i = 0 ; i < RINGSIZE ; i++) { - n = epicsRingBytesPut(ring, put, i); - testOk(n==i, "ring put %d", i); - check(ring, RINGSIZE-i); - n = epicsRingBytesGet(ring, get, i); - testOk(n==i, "ring get %d", i); - check(ring, RINGSIZE); - testOk(memcmp(put,get,i)==0, "get matches write"); - } - - for(i = 0 ; i < RINGSIZE ; i++) { - n = epicsRingBytesPut(ring, put+i, 1); - testOk(n==1, "ring put 1, %d", i); - check(ring, RINGSIZE-1-i); - } - n = epicsRingBytesPut(ring, put+RINGSIZE, 1); - testOk(n==0, "put to full ring"); - check(ring, 0); - for(i = 0 ; i < RINGSIZE ; i++) { - n = epicsRingBytesGet(ring, get+i, 1); - testOk(n==1, "ring get 1, %d", i); - check(ring, 1+i); - } - testOk(memcmp(put,get,RINGSIZE)==0, "get matches write"); - n = epicsRingBytesGet(ring, get+RINGSIZE, 1); - testOk(n==0, "get from empty ring"); - check(ring, RINGSIZE); - - n = epicsRingBytesPut(ring, put, RINGSIZE+1); - testOk(n==0, "ring put beyond ring capacity (%d, expected 0)",n); - check(ring, RINGSIZE); - n = epicsRingBytesPut(ring, put, 1); - testOk(n==1, "ring put %d", 1); - check(ring, RINGSIZE-1); - n = epicsRingBytesPut(ring, put, RINGSIZE); - testOk(n==0, "ring put beyond ring capacity (%d, expected 0)",n); - check(ring, RINGSIZE-1); - n = epicsRingBytesGet(ring, get, 1); - testOk(n==1, "ring get %d", 1); - check(ring, RINGSIZE); - - epicsRingBytesDelete(ring); - epicsEventDestroy(consumerEvent); - free(pinfo); - - return testDone(); -} diff --git a/src/libCom/test/ringPointerTest.c b/src/libCom/test/ringPointerTest.c deleted file mode 100644 index 92401d123..000000000 --- a/src/libCom/test/ringPointerTest.c +++ /dev/null @@ -1,246 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2006 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2013 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* ringPointerTest.c */ - -/* Author: Marty Kraimer Date: 13OCT2000 */ - -#include -#include -#include -#include -#include -#include -#include - -#include "epicsThread.h" -#include "epicsRingPointer.h" -#include "errlog.h" -#include "epicsEvent.h" -#include "epicsUnitTest.h" -#include "testMain.h" - -static -void *int2ptr(size_t i) -{ - char *zero = 0; - i = i|(i<<16); - return zero+i; -} - -static int foundCorruption; - -static -size_t ptr2int(void *p) -{ - char *zero = 0, *p2 = p; - size_t i = p2-zero; - if((i&0xffff)!=((i>>16)&0xffff)) { - testDiag("Pointer value corruption %p", p); - foundCorruption = 1; - } - return i&0xffff; -} - -static void testSingle(void) -{ - int i; - const int rsize = 100; - void *addr = 0; - epicsRingPointerId ring = epicsRingPointerCreate(rsize); - - foundCorruption = 0; - - testDiag("Testing operations w/o threading"); - - testOk1(epicsRingPointerIsEmpty(ring)); - testOk1(!epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==rsize); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==0); - - testOk1(epicsRingPointerPop(ring)==NULL); - - addr = int2ptr(1); - testOk1(epicsRingPointerPush(ring, addr)==1); - - testOk1(!epicsRingPointerIsEmpty(ring)); - testOk1(!epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==rsize-1); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==1); - - testDiag("Fill it up"); - for(i=2; i<2*rsize; i++) { - int ret; - addr = int2ptr(i); - ret = epicsRingPointerPush(ring, addr); - if(!ret) - break; - } - - /* Note: +1 because we started with 1 */ - testOk(i==rsize+1, "%d == %d", i, rsize+1); - testOk1(!epicsRingPointerIsEmpty(ring)); - testOk1(epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==0); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==rsize); - - testDiag("Drain it out"); - for(i=1; i<2*rsize; i++) { - addr = epicsRingPointerPop(ring); - if(addr==NULL || ptr2int(addr)!=i) - break; - } - - testOk1(!foundCorruption); - - testOk(i==rsize+1, "%d == %d", i, rsize+1); - testOk1(epicsRingPointerIsEmpty(ring)); - testOk1(!epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==rsize); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==0); - - testDiag("Fill it up again"); - for(i=2; i<2*rsize; i++) { - int ret; - addr = int2ptr(i); - ret = epicsRingPointerPush(ring, addr); - if(!ret) - break; - } - - testDiag("flush"); - testOk1(epicsRingPointerIsFull(ring)); - epicsRingPointerFlush(ring); - - testOk1(epicsRingPointerIsEmpty(ring)); - testOk1(!epicsRingPointerIsFull(ring)); - testOk1(epicsRingPointerGetFree(ring)==rsize); - testOk1(epicsRingPointerGetSize(ring)==rsize); - testOk1(epicsRingPointerGetUsed(ring)==0); - - epicsRingPointerDelete(ring); -} - -typedef struct { - epicsRingPointerId ring; - epicsEventId sync, wait; - int stop; - void *lastaddr; -} pairPvt; - -static void pairConsumer(void *raw) -{ - pairPvt *pvt = raw; - void *prev = pvt->lastaddr; - - epicsEventMustTrigger(pvt->sync); - - while(1) { - size_t c,p; - - epicsEventMustWait(pvt->wait); - if(pvt->stop) - break; - - pvt->lastaddr = epicsRingPointerPop(pvt->ring); - c = ptr2int(pvt->lastaddr); - p = ptr2int(prev); - if(p+1!=c) { - testFail("consumer skip %p %p", prev, pvt->lastaddr); - break; - } - prev = pvt->lastaddr; - } - - pvt->stop = 1; - epicsEventMustTrigger(pvt->sync); -} - -static void testPair(int locked) -{ - unsigned int myprio = epicsThreadGetPrioritySelf(), consumerprio; - pairPvt pvt; - const int rsize = 100; - int i, expect; - epicsRingPointerId ring; - if(locked) - ring = epicsRingPointerLockedCreate(rsize); - else - ring = epicsRingPointerCreate(rsize); - - pvt.ring = ring; - pvt.sync = epicsEventCreate(epicsEventEmpty); - pvt.wait = epicsEventCreate(epicsEventEmpty); - pvt.stop = 0; - pvt.lastaddr = 0; - - foundCorruption = 0; - - testDiag("single producer, single consumer with%s locking", locked?"":"out"); - - /* give the consumer thread a slightly higher priority so that - * it can preempt us on RTOS targets. On non-RTOS targets - * we expect to be preempted at some random time - */ - if(!epicsThreadLowestPriorityLevelAbove(myprio, &consumerprio)) - testAbort("Can't run test from thread with highest priority"); - - epicsThreadMustCreate("pair", consumerprio, - epicsThreadGetStackSize(epicsThreadStackSmall), - &pairConsumer, &pvt); - /* wait for worker to start */ - epicsEventMustWait(pvt.sync); - - i=1; - while(i - -#include "taskwd.h" -#include "errlog.h" -#include "epicsThread.h" -#include "epicsUnitTest.h" -#include "testMain.h" - - -void monInsert(void *usr, epicsThreadId tid) -{ - testPass("monInsert(tid=%p)", (void *)tid); -} - -void monNotify(void *usr, epicsThreadId tid, int suspended) -{ - testPass("monNotify(tid=%p, suspended=%d)", (void *)tid, suspended); - epicsThreadResume(tid); -} - -void monRemove(void *usr, epicsThreadId tid) -{ - testPass("monRemove(tid=%p)", (void *)tid); -} - -taskwdMonitor monFuncs = {monInsert, monNotify, monRemove}; - -void anyNotify(void *usr, epicsThreadId tid) -{ - testPass("anyNotify(tid=%p)", (void *)tid); -} - -void taskNotify(void *usr) -{ - testPass("taskNotify"); -} - -void testTask1(void *arg) -{ - taskwdInsert(0, taskNotify, NULL); - epicsThreadSleep(10.0); - taskwdRemove(0); -} - -void testTask2(void *arg) -{ - taskwdInsert(0, taskNotify, NULL); - testDiag("Task suspending"); - epicsThreadSuspendSelf(); - epicsThreadSleep(1.0); - testDiag("Alive again"); - epicsThreadSleep(10.0); - taskwdRemove(0); -} - -MAIN(taskwdTest) -{ - eltc(0); - testPlan(8); - - taskwdInit(); - taskwdMonitorAdd(&monFuncs, NULL); - taskwdAnyInsert(NULL, anyNotify, NULL); - - epicsThreadCreate("testTask1", epicsThreadPriorityMax, - epicsThreadGetStackSize(epicsThreadStackSmall), - testTask1, NULL); - epicsThreadSleep(1.0); - - epicsThreadCreate("testTask2", epicsThreadPriorityMax, - epicsThreadGetStackSize(epicsThreadStackSmall), - testTask2, NULL); - - /* taskwd checks tasks every 6 seconds */ - epicsThreadSleep(18.0); - - taskwdMonitorDel(&monFuncs, NULL); - taskwdAnyRemove(NULL); - - eltc(1); - return testDone(); -} - diff --git a/src/libCom/timer/Makefile b/src/libCom/timer/Makefile deleted file mode 100644 index 51094d069..000000000 --- a/src/libCom/timer/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/timer -INC += epicsTimer.h -Com_SRCS += epicsTimer.cpp -Com_SRCS += timer.cpp -Com_SRCS += timerQueue.cpp -Com_SRCS += timerQueueActive.cpp -Com_SRCS += timerQueueActiveMgr.cpp -Com_SRCS += timerQueuePassive.cpp diff --git a/src/libCom/timer/epicsTimer.cpp b/src/libCom/timer/epicsTimer.cpp deleted file mode 100644 index e55280e7e..000000000 --- a/src/libCom/timer/epicsTimer.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMath.h" -#include "epicsTimer.h" -#include "epicsGuard.h" -#include "timerPrivate.h" - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -template class tsFreeList < epicsTimerForC, 0x20 >; - -epicsTimer::~epicsTimer () {} - -epicsTimerQueueNotify::~epicsTimerQueueNotify () {} - -epicsTimerNotify::~epicsTimerNotify () {} - -void epicsTimerNotify::show ( unsigned /* level */ ) const {} - -epicsTimerForC::epicsTimerForC ( timerQueue &queue, epicsTimerCallback pCBIn, void *pPrivateIn ) : - timer ( queue ), pCallBack ( pCBIn ), pPrivate ( pPrivateIn ) -{ -} - -epicsTimerForC::~epicsTimerForC () -{ -} - -void epicsTimerForC::destroy () -{ - timerQueue & queueTmp = this->queue; - this->~epicsTimerForC (); - queueTmp.timerForCFreeList.release ( this ); -} - -epicsTimerNotify::expireStatus epicsTimerForC::expire ( const epicsTime & ) -{ - ( *this->pCallBack ) ( this->pPrivate ); - return noRestart; -} - -epicsTimerQueueActiveForC :: - epicsTimerQueueActiveForC ( RefMgr & refMgr, - bool okToShare, unsigned priority ) : - timerQueueActive ( refMgr, okToShare, priority ) -{ - timerQueueActive::start(); -} - -epicsTimerQueueActiveForC::~epicsTimerQueueActiveForC () -{ -} - -void epicsTimerQueueActiveForC::release () -{ - _refMgr->release ( *this ); -} - -epicsTimerQueuePassiveForC::epicsTimerQueuePassiveForC ( - epicsTimerQueueNotifyReschedule pRescheduleCallbackIn, - epicsTimerQueueNotifyQuantum pSleepQuantumCallbackIn, - void * pPrivateIn ) : - timerQueuePassive ( * static_cast < epicsTimerQueueNotify * > ( this ) ), - pRescheduleCallback ( pRescheduleCallbackIn ), - pSleepQuantumCallback ( pSleepQuantumCallbackIn ), - pPrivate ( pPrivateIn ) -{ -} - -epicsTimerQueuePassiveForC::~epicsTimerQueuePassiveForC () -{ -} - -void epicsTimerQueuePassiveForC::reschedule () -{ - (*this->pRescheduleCallback) ( this->pPrivate ); -} - -double epicsTimerQueuePassiveForC::quantum () -{ - return (*this->pSleepQuantumCallback) ( this->pPrivate ); -} - -void epicsTimerQueuePassiveForC::destroy () -{ - delete this; -} - -epicsShareFunc epicsTimerNotify::expireStatus::expireStatus ( restart_t restart ) : - delay ( - DBL_MAX ) -{ - if ( restart != noRestart ) { - throw std::logic_error - ( "timer restart was requested without specifying a delay?" ); - } -} - -epicsShareFunc epicsTimerNotify::expireStatus::expireStatus - ( restart_t restartIn, const double & expireDelaySec ) : - delay ( expireDelaySec ) -{ - if ( restartIn != epicsTimerNotify::restart ) { - throw std::logic_error - ( "no timer restart was requested, but a delay was specified?" ); - } - if ( this->delay < 0.0 || !finite(this->delay) ) { - throw std::logic_error - ( "timer restart was requested, but a negative delay was specified?" ); - } -} - -epicsShareFunc bool epicsTimerNotify::expireStatus::restart () const -{ - return this->delay >= 0.0 && finite(this->delay); -} - -epicsShareFunc double epicsTimerNotify::expireStatus::expirationDelay () const -{ - if ( this->delay < 0.0 || !finite(this->delay) ) { - throw std::logic_error - ( "no timer restart was requested, but you are asking for a restart delay?" ); - } - return this->delay; -} - -extern "C" epicsTimerQueuePassiveId epicsShareAPI - epicsTimerQueuePassiveCreate ( - epicsTimerQueueNotifyReschedule pRescheduleCallbackIn, - epicsTimerQueueNotifyQuantum pSleepQuantumCallbackIn, - void * pPrivateIn ) -{ - try { - return new epicsTimerQueuePassiveForC ( - pRescheduleCallbackIn, - pSleepQuantumCallbackIn, - pPrivateIn ); - } - catch ( ... ) { - return 0; - } -} - -extern "C" void epicsShareAPI - epicsTimerQueuePassiveDestroy ( epicsTimerQueuePassiveId pQueue ) -{ - pQueue->destroy (); -} - -extern "C" double epicsShareAPI - epicsTimerQueuePassiveProcess ( epicsTimerQueuePassiveId pQueue ) -{ - try { - return pQueue->process ( epicsTime::getCurrent() ); - } - catch ( ... ) { - return 1.0; - } -} - -extern "C" epicsTimerId epicsShareAPI epicsTimerQueuePassiveCreateTimer ( - epicsTimerQueuePassiveId pQueue, epicsTimerCallback pCallback, void *pArg ) -{ - try { - return & pQueue->createTimerForC ( pCallback, pArg ); - } - catch ( ... ) { - return 0; - } -} - -extern "C" epicsShareFunc void epicsShareAPI epicsTimerQueuePassiveDestroyTimer ( - epicsTimerQueuePassiveId /* pQueue */, epicsTimerId pTmr ) -{ - pTmr->destroy (); -} - -extern "C" void epicsShareAPI epicsTimerQueuePassiveShow ( - epicsTimerQueuePassiveId pQueue, unsigned int level ) -{ - pQueue->show ( level ); -} - -extern "C" epicsTimerQueueId epicsShareAPI - epicsTimerQueueAllocate ( int okToShare, unsigned int threadPriority ) -{ - try { - epicsSingleton < timerQueueActiveMgr > :: reference ref = - timerQueueMgrEPICS.getReference (); - epicsTimerQueueActiveForC & tmr = - ref->allocate ( ref, okToShare ? true : false, threadPriority ); - return &tmr; - } - catch ( ... ) { - return 0; - } -} - -extern "C" void epicsShareAPI epicsTimerQueueRelease ( epicsTimerQueueId pQueue ) -{ - pQueue->release (); -} - -extern "C" epicsTimerId epicsShareAPI epicsTimerQueueCreateTimer ( - epicsTimerQueueId pQueue, epicsTimerCallback pCallback, void *pArg ) -{ - try { - return & pQueue->createTimerForC ( pCallback, pArg ); - } - catch ( ... ) { - return 0; - } -} - -extern "C" void epicsShareAPI epicsTimerQueueShow ( - epicsTimerQueueId pQueue, unsigned int level ) -{ - pQueue->show ( level ); -} - -extern "C" void epicsShareAPI epicsTimerQueueDestroyTimer ( - epicsTimerQueueId /* pQueue */, epicsTimerId pTmr ) -{ - pTmr->destroy (); -} - -extern "C" void epicsShareAPI epicsTimerStartTime ( - epicsTimerId pTmr, const epicsTimeStamp *pTime ) -{ - pTmr->start ( *pTmr, *pTime ); -} - -extern "C" void epicsShareAPI epicsTimerStartDelay ( - epicsTimerId pTmr, double delaySeconds ) -{ - pTmr->start ( *pTmr, delaySeconds ); -} - -extern "C" void epicsShareAPI epicsTimerCancel ( epicsTimerId pTmr ) -{ - pTmr->cancel (); -} - -extern "C" double epicsShareAPI epicsTimerGetExpireDelay ( epicsTimerId pTmr ) -{ - return pTmr->getExpireDelay (); -} - -extern "C" void epicsShareAPI epicsTimerShow ( - epicsTimerId pTmr, unsigned int level ) -{ - pTmr->timer::show ( level ); -} - diff --git a/src/libCom/timer/epicsTimer.h b/src/libCom/timer/epicsTimer.h deleted file mode 100644 index 72270f273..000000000 --- a/src/libCom/timer/epicsTimer.h +++ /dev/null @@ -1,185 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* epicsTimer.h */ - -/* Authors: Marty Kraimer, Jeff Hill */ - -#ifndef epicsTimerH -#define epicsTimerH - -#include - -#include "shareLib.h" -#include "epicsTime.h" -#include "epicsThread.h" - -#ifdef __cplusplus - -/* - * Notes: - * 1) epicsTimer does not hold its lock when calling callbacks. - */ - -/* code using a timer must implement epicsTimerNotify */ -class epicsShareClass epicsTimerNotify { -public: - enum restart_t { noRestart, restart }; - class expireStatus { - public: - epicsShareFunc expireStatus ( restart_t ); - epicsShareFunc expireStatus ( restart_t, const double & expireDelaySec ); - epicsShareFunc bool restart () const; - epicsShareFunc double expirationDelay () const; - private: - double delay; - }; - - virtual ~epicsTimerNotify () = 0; - /* return "noRestart" or "expireStatus ( restart, 30.0 )" */ - virtual expireStatus expire ( const epicsTime & currentTime ) = 0; - virtual void show ( unsigned int level ) const; -}; - -class epicsShareClass epicsTimer { -public: - /* calls cancel (see warning below) and then destroys the timer */ - virtual void destroy () = 0; - virtual void start ( epicsTimerNotify &, const epicsTime & ) = 0; - virtual void start ( epicsTimerNotify &, double delaySeconds ) = 0; - /* WARNING: A deadlock will occur if you hold a lock while - * calling this function that you also take within the timer - * expiration callback. - */ - virtual void cancel () = 0; - struct expireInfo { - expireInfo ( bool active, const epicsTime & expireTime ); - bool active; - epicsTime expireTime; - }; - virtual expireInfo getExpireInfo () const = 0; - double getExpireDelay (); - virtual void show ( unsigned int level ) const = 0; -protected: - virtual ~epicsTimer () = 0; /* protected => delete() must not be called */ -}; - -class epicsTimerQueue { -public: - virtual epicsTimer & createTimer () = 0; - virtual void show ( unsigned int level ) const = 0; -protected: - epicsShareFunc virtual ~epicsTimerQueue () = 0; -}; - -class epicsTimerQueueActive - : public epicsTimerQueue { -public: - static epicsShareFunc epicsTimerQueueActive & allocate ( - bool okToShare, unsigned threadPriority = epicsThreadPriorityMin + 10 ); - virtual void release () = 0; -protected: - epicsShareFunc virtual ~epicsTimerQueueActive () = 0; -}; - -class epicsTimerQueueNotify { -public: - /* called when a new timer is inserted into the queue and the */ - /* delay to the next expire has changed */ - virtual void reschedule () = 0; - /* if there is a quantum in the scheduling of timer intervals */ - /* return this quantum in seconds. If unknown then return zero. */ - virtual double quantum () = 0; -protected: - epicsShareFunc virtual ~epicsTimerQueueNotify () = 0; -}; - -class epicsTimerQueuePassive - : public epicsTimerQueue { -public: - static epicsShareFunc epicsTimerQueuePassive & create ( epicsTimerQueueNotify & ); - epicsShareFunc virtual ~epicsTimerQueuePassive () = 0; /* ok to call delete */ - virtual double process ( const epicsTime & currentTime ) = 0; /* returns delay to next expire */ -}; - -inline epicsTimer::expireInfo::expireInfo ( bool activeIn, - const epicsTime & expireTimeIn ) : - active ( activeIn ), expireTime ( expireTimeIn ) -{ -} - -inline double epicsTimer::getExpireDelay () -{ - epicsTimer::expireInfo info = this->getExpireInfo (); - if ( info.active ) { - double delay = info.expireTime - epicsTime::getCurrent (); - if ( delay < 0.0 ) { - delay = 0.0; - } - return delay; - } - return - DBL_MAX; -} - -extern "C" { -#endif /* __cplusplus */ - -typedef struct epicsTimerForC * epicsTimerId; -typedef void ( *epicsTimerCallback ) ( void *pPrivate ); - -/* thread managed timer queue */ -typedef struct epicsTimerQueueActiveForC * epicsTimerQueueId; -epicsShareFunc epicsTimerQueueId epicsShareAPI - epicsTimerQueueAllocate ( int okToShare, unsigned int threadPriority ); -epicsShareFunc void epicsShareAPI - epicsTimerQueueRelease ( epicsTimerQueueId ); -epicsShareFunc epicsTimerId epicsShareAPI - epicsTimerQueueCreateTimer ( epicsTimerQueueId queueid, - epicsTimerCallback callback, void *arg ); -epicsShareFunc void epicsShareAPI - epicsTimerQueueDestroyTimer ( epicsTimerQueueId queueid, epicsTimerId id ); -epicsShareFunc void epicsShareAPI - epicsTimerQueueShow ( epicsTimerQueueId id, unsigned int level ); - -/* passive timer queue */ -typedef struct epicsTimerQueuePassiveForC * epicsTimerQueuePassiveId; -typedef void ( * epicsTimerQueueNotifyReschedule ) ( void * pPrivate ); -typedef double ( * epicsTimerQueueNotifyQuantum ) ( void * pPrivate ); -epicsShareFunc epicsTimerQueuePassiveId epicsShareAPI - epicsTimerQueuePassiveCreate ( epicsTimerQueueNotifyReschedule, - epicsTimerQueueNotifyQuantum, void *pPrivate ); -epicsShareFunc void epicsShareAPI - epicsTimerQueuePassiveDestroy ( epicsTimerQueuePassiveId ); -epicsShareFunc epicsTimerId epicsShareAPI - epicsTimerQueuePassiveCreateTimer ( - epicsTimerQueuePassiveId queueid, epicsTimerCallback pCallback, void *pArg ); -epicsShareFunc void epicsShareAPI - epicsTimerQueuePassiveDestroyTimer ( epicsTimerQueuePassiveId queueid, epicsTimerId id ); -epicsShareFunc double epicsShareAPI - epicsTimerQueuePassiveProcess ( epicsTimerQueuePassiveId ); -epicsShareFunc void epicsShareAPI - epicsTimerQueuePassiveShow ( epicsTimerQueuePassiveId id, unsigned int level ); - -/* timer */ -epicsShareFunc void epicsShareAPI - epicsTimerStartTime ( epicsTimerId id, const epicsTimeStamp *pTime ); -epicsShareFunc void epicsShareAPI - epicsTimerStartDelay ( epicsTimerId id, double delaySeconds ); -epicsShareFunc void epicsShareAPI - epicsTimerCancel ( epicsTimerId id ); -epicsShareFunc double epicsShareAPI - epicsTimerGetExpireDelay ( epicsTimerId id ); -epicsShareFunc void epicsShareAPI - epicsTimerShow ( epicsTimerId id, unsigned int level ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* epicsTimerH */ diff --git a/src/libCom/timer/timer.cpp b/src/libCom/timer/timer.cpp deleted file mode 100644 index 35d6e47bf..000000000 --- a/src/libCom/timer/timer.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsGuard.h" -#include "timerPrivate.h" -#include "errlog.h" - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class tsFreeList < timer, 0x20 >; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -timer::timer ( timerQueue & queueIn ) : - queue ( queueIn ), curState ( stateLimbo ), pNotify ( 0 ) -{ -} - -timer::~timer () -{ - this->cancel (); -} - -void timer::destroy () -{ - timerQueue & queueTmp = this->queue; - this->~timer (); - queueTmp.timerFreeList.release ( this ); -} - -void timer::start ( epicsTimerNotify & notify, double delaySeconds ) -{ - this->start ( notify, epicsTime::getCurrent () + delaySeconds ); -} - -void timer::start ( epicsTimerNotify & notify, const epicsTime & expire ) -{ - epicsGuard < epicsMutex > locker ( this->queue.mutex ); - this->privateStart ( notify, expire ); -} - -void timer::privateStart ( epicsTimerNotify & notify, const epicsTime & expire ) -{ - this->pNotify = & notify; - this->exp = expire - ( this->queue.notify.quantum () / 2.0 ); - - bool reschedualNeeded = false; - if ( this->curState == stateActive ) { - // above expire time and notify will override any restart parameters - // that may be returned from the timer expire callback - return; - } - else if ( this->curState == statePending ) { - this->queue.timerList.remove ( *this ); - if ( this->queue.timerList.first() == this && - this->queue.timerList.count() > 0 ) { - reschedualNeeded = true; - } - } - -# ifdef DEBUG - unsigned preemptCount=0u; -# endif - - // - // insert into the pending queue - // - // Finds proper time sorted location using a linear search. - // - // **** this should use a binary tree ???? - // - tsDLIter < timer > pTmr = this->queue.timerList.lastIter (); - while ( true ) { - if ( ! pTmr.valid () ) { - // - // add to the beginning of the list - // - this->queue.timerList.push ( *this ); - reschedualNeeded = true; - break; - } - if ( pTmr->exp <= this->exp ) { - // - // add after the item found that expires earlier - // - this->queue.timerList.insertAfter ( *this, *pTmr ); - break; - } -# ifdef DEBUG - preemptCount++; -# endif - --pTmr; - } - - this->curState = timer::statePending; - - if ( reschedualNeeded ) { - this->queue.notify.reschedule (); - } - -# if defined(DEBUG) && 0 - this->show ( 10u ); - this->queue.show ( 10u ); -# endif - - debugPrintf ( ("Start of \"%s\" with delay %f at %p preempting %u\n", - typeid ( this->notify ).name (), - expire - epicsTime::getCurrent (), - this, preemptCount ) ); -} - -void timer::cancel () -{ - bool reschedual = false; - bool wakeupCancelBlockingThreads = false; - { - epicsGuard < epicsMutex > locker ( this->queue.mutex ); - this->pNotify = 0; - if ( this->curState == statePending ) { - this->queue.timerList.remove ( *this ); - this->curState = stateLimbo; - if ( this->queue.timerList.first() == this && - this->queue.timerList.count() > 0 ) { - reschedual = true; - } - } - else if ( this->curState == stateActive ) { - this->queue.cancelPending = true; - this->curState = timer::stateLimbo; - if ( this->queue.processThread != epicsThreadGetIdSelf() ) { - // make certain timer expire() does not run after cancel () returns, - // but dont require that lock is applied while calling expire() - while ( this->queue.cancelPending && - this->queue.pExpireTmr == this ) { - epicsGuardRelease < epicsMutex > autoRelease ( locker ); - this->queue.cancelBlockingEvent.wait (); - } - // in case other threads are waiting - wakeupCancelBlockingThreads = true; - } - } - } - if ( reschedual ) { - this->queue.notify.reschedule (); - } - if ( wakeupCancelBlockingThreads ) { - this->queue.cancelBlockingEvent.signal (); - } -} - -epicsTimer::expireInfo timer::getExpireInfo () const -{ - // taking a lock here guarantees that users will not - // see brief intervals when a timer isnt active because - // it is is canceled when start is called - epicsGuard < epicsMutex > locker ( this->queue.mutex ); - if ( this->curState == statePending || this->curState == stateActive ) { - return expireInfo ( true, this->exp ); - } - return expireInfo ( false, epicsTime() ); -} - -void timer::show ( unsigned int level ) const -{ - epicsGuard < epicsMutex > locker ( this->queue.mutex ); - double delay; - if ( this->curState == statePending || this->curState == stateActive ) { - try { - delay = this->exp - epicsTime::getCurrent(); - } - catch ( ... ) { - delay = - DBL_MAX; - } - } - else { - delay = -DBL_MAX; - } - const char *pStateName; - if ( this->curState == statePending ) { - pStateName = "pending"; - } - else if ( this->curState == stateActive ) { - pStateName = "active"; - } - else if ( this->curState == stateLimbo ) { - pStateName = "limbo"; - } - else { - pStateName = "corrupt"; - } - printf ( "timer, state = %s, delay = %f\n", - pStateName, delay ); - if ( level >= 1u && this->pNotify ) { - this->pNotify->show ( level - 1u ); - } -} - -void timer::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - -void epicsTimerForC::operator delete ( void * ) -{ - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - errlogPrintf ( "%s:%d this compiler is confused about placement delete - memory was probably leaked", - __FILE__, __LINE__ ); -} - diff --git a/src/libCom/timer/timerPrivate.h b/src/libCom/timer/timerPrivate.h deleted file mode 100644 index 55291309c..000000000 --- a/src/libCom/timer/timerPrivate.h +++ /dev/null @@ -1,277 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef epicsTimerPrivate_h -#define epicsTimerPrivate_h - -#include - -#include "tsFreeList.h" -#include "epicsSingleton.h" -#include "tsDLList.h" -#include "epicsTimer.h" -#include "compilerDependencies.h" - -#ifdef DEBUG -# define debugPrintf(ARGSINPAREN) printf ARGSINPAREN -#else -# define debugPrintf(ARGSINPAREN) -#endif - -template < class T > class epicsGuard; - -class timer : public epicsTimer, public tsDLNode < timer > { -public: - void destroy (); - void start ( class epicsTimerNotify &, const epicsTime & ); - void start ( class epicsTimerNotify &, double delaySeconds ); - void cancel (); - expireInfo getExpireInfo () const; - void show ( unsigned int level ) const; - void * operator new ( size_t size, tsFreeList < timer, 0x20 > & ); - epicsPlacementDeleteOperator (( void *, tsFreeList < timer, 0x20 > & )) -protected: - timer ( class timerQueue & ); - ~timer (); - timerQueue & queue; -private: - enum state { statePending = 45, stateActive = 56, stateLimbo = 78 }; - epicsTime exp; // experation time - state curState; // current state - epicsTimerNotify * pNotify; // callback - void privateStart ( epicsTimerNotify & notify, const epicsTime & ); - timer & operator = ( const timer & ); - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - void operator delete ( void * ); - friend class timerQueue; -}; - -struct epicsTimerForC : public epicsTimerNotify, public timer { -public: - void destroy (); -protected: - epicsTimerForC ( timerQueue &, epicsTimerCallback, void *pPrivateIn ); - ~epicsTimerForC (); - void * operator new ( size_t size, tsFreeList < epicsTimerForC, 0x20 > & ); - epicsPlacementDeleteOperator (( void *, tsFreeList < epicsTimerForC, 0x20 > & )) -private: - epicsTimerCallback pCallBack; - void * pPrivate; - expireStatus expire ( const epicsTime & currentTime ); - epicsTimerForC & operator = ( const epicsTimerForC & ); - // Visual C++ .net appears to require operator delete if - // placement operator delete is defined? I smell a ms rat - // because if I declare placement new and delete, but - // comment out the placement delete definition there are - // no undefined symbols. - void operator delete ( void * ); - friend class timerQueue; -}; - -using std :: type_info; - -class timerQueue : public epicsTimerQueue { -public: - timerQueue ( epicsTimerQueueNotify ¬ify ); - virtual ~timerQueue (); - epicsTimer & createTimer (); - epicsTimerForC & createTimerForC ( epicsTimerCallback pCallback, void *pArg ); - double process ( const epicsTime & currentTime ); - void show ( unsigned int level ) const; -private: - tsFreeList < timer, 0x20 > timerFreeList; - tsFreeList < epicsTimerForC, 0x20 > timerForCFreeList; - mutable epicsMutex mutex; - epicsEvent cancelBlockingEvent; - tsDLList < timer > timerList; - epicsTimerQueueNotify & notify; - timer * pExpireTmr; - epicsThreadId processThread; - epicsTime exceptMsgTimeStamp; - bool cancelPending; - static const double exceptMsgMinPeriod; - void printExceptMsg ( const char * pName, - const type_info & type ); - timerQueue ( const timerQueue & ); - timerQueue & operator = ( const timerQueue & ); - friend class timer; - friend struct epicsTimerForC; -}; - -class timerQueueActiveMgrPrivate { -public: - timerQueueActiveMgrPrivate (); -protected: - virtual ~timerQueueActiveMgrPrivate () = 0; -private: - unsigned referenceCount; - friend class timerQueueActiveMgr; -}; - -class timerQueueActiveMgr; - -class timerQueueActive : public epicsTimerQueueActive, - public epicsThreadRunable, public epicsTimerQueueNotify, - public timerQueueActiveMgrPrivate { -public: - typedef epicsSingleton < timerQueueActiveMgr > :: reference RefMgr; - timerQueueActive ( RefMgr &, bool okToShare, unsigned priority ); - void start (); - epicsTimer & createTimer (); - epicsTimerForC & createTimerForC ( epicsTimerCallback pCallback, void *pArg ); - void show ( unsigned int level ) const; - bool sharingOK () const; - unsigned threadPriority () const; -protected: - ~timerQueueActive (); - RefMgr _refMgr; -private: - timerQueue queue; - epicsEvent rescheduleEvent; - epicsEvent exitEvent; - epicsThread thread; - const double sleepQuantum; - bool okToShare; - bool exitFlag; - bool terminateFlag; - void run (); - void reschedule (); - double quantum (); - void _printLastChanceExceptionMessage ( - const char * pExceptionTypeName, - const char * pExceptionContext ); - epicsTimerQueue & getEpicsTimerQueue (); - timerQueueActive ( const timerQueueActive & ); - timerQueueActive & operator = ( const timerQueueActive & ); -}; - -class timerQueueActiveMgr { -public: - typedef epicsSingleton < timerQueueActiveMgr > :: reference RefThis; - timerQueueActiveMgr (); - ~timerQueueActiveMgr (); - epicsTimerQueueActiveForC & allocate ( RefThis &, bool okToShare, - unsigned threadPriority = epicsThreadPriorityMin + 10 ); - void release ( epicsTimerQueueActiveForC & ); -private: - epicsMutex mutex; - tsDLList < epicsTimerQueueActiveForC > sharedQueueList; - timerQueueActiveMgr ( const timerQueueActiveMgr & ); - timerQueueActiveMgr & operator = ( const timerQueueActiveMgr & ); -}; - -extern epicsSingleton < timerQueueActiveMgr > timerQueueMgrEPICS; - -class timerQueuePassive : public epicsTimerQueuePassive { -public: - timerQueuePassive ( epicsTimerQueueNotify & ); - epicsTimer & createTimer (); - epicsTimerForC & createTimerForC ( epicsTimerCallback pCallback, void *pArg ); - void show ( unsigned int level ) const; - double process ( const epicsTime & currentTime ); -protected: - timerQueue queue; - ~timerQueuePassive (); - epicsTimerQueue & getEpicsTimerQueue (); - timerQueuePassive ( const timerQueuePassive & ); - timerQueuePassive & operator = ( const timerQueuePassive & ); -}; - -struct epicsTimerQueuePassiveForC : - public epicsTimerQueueNotify, public timerQueuePassive { -public: - epicsTimerQueuePassiveForC ( - epicsTimerQueueNotifyReschedule, - epicsTimerQueueNotifyQuantum, - void * pPrivate ); - void destroy (); -protected: - ~epicsTimerQueuePassiveForC (); -private: - epicsTimerQueueNotifyReschedule pRescheduleCallback; - epicsTimerQueueNotifyQuantum pSleepQuantumCallback; - void * pPrivate; - static epicsSingleton < tsFreeList < epicsTimerQueuePassiveForC, 0x10 > > pFreeList; - void reschedule (); - double quantum (); -}; - -struct epicsTimerQueueActiveForC : public timerQueueActive, - public tsDLNode < epicsTimerQueueActiveForC > { -public: - epicsTimerQueueActiveForC ( RefMgr &, bool okToShare, unsigned priority ); - void release (); - void * operator new ( size_t ); - void operator delete ( void * ); -protected: - virtual ~epicsTimerQueueActiveForC (); -private: - epicsTimerQueueActiveForC ( const epicsTimerQueueActiveForC & ); - epicsTimerQueueActiveForC & operator = ( const epicsTimerQueueActiveForC & ); -}; - -inline bool timerQueueActive::sharingOK () const -{ - return this->okToShare; -} - -inline unsigned timerQueueActive::threadPriority () const -{ - return thread.getPriority (); -} - -inline void * timer::operator new ( size_t size, - tsFreeList < timer, 0x20 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void timer::operator delete ( void * pCadaver, - tsFreeList < timer, 0x20 > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline void * epicsTimerForC::operator new ( size_t size, - tsFreeList < epicsTimerForC, 0x20 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -inline void epicsTimerForC::operator delete ( void * pCadaver, - tsFreeList < epicsTimerForC, 0x20 > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -inline void * epicsTimerQueueActiveForC::operator new ( size_t size ) -{ - return ::operator new ( size ); -} - -inline void epicsTimerQueueActiveForC::operator delete ( void * pCadaver ) -{ - ::operator delete ( pCadaver ); -} - -#endif // epicsTimerPrivate_h - diff --git a/src/libCom/timer/timerQueue.cpp b/src/libCom/timer/timerQueue.cpp deleted file mode 100644 index 5a798d4d4..000000000 --- a/src/libCom/timer/timerQueue.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "epicsGuard.h" -#include "timerPrivate.h" -#include "errlog.h" - -const double timerQueue :: exceptMsgMinPeriod = 60.0 * 5.0; // seconds - -epicsTimerQueue::~epicsTimerQueue () {} - -timerQueue::timerQueue ( epicsTimerQueueNotify & notifyIn ) : - notify ( notifyIn ), - pExpireTmr ( 0 ), - processThread ( 0 ), - exceptMsgTimeStamp ( - epicsTime :: getCurrent () - exceptMsgMinPeriod ), - cancelPending ( false ) -{ -} - -timerQueue::~timerQueue () -{ - timer *pTmr; - while ( ( pTmr = this->timerList.get () ) ) { - pTmr->curState = timer::stateLimbo; - } -} - -void timerQueue :: - printExceptMsg ( const char * pName, const type_info & type ) -{ - char date[64]; - double delay; - try { - epicsTime cur = epicsTime :: getCurrent (); - delay = cur - this->exceptMsgTimeStamp; - cur.strftime ( date, sizeof ( date ), - "%a %b %d %Y %H:%M:%S.%f" ); - if ( delay >= exceptMsgMinPeriod ) { - this->exceptMsgTimeStamp = cur; - } - } - catch ( ... ) { - delay = DBL_MAX; - strcpy ( date, "UKN DATE" ); - } - if ( delay >= exceptMsgMinPeriod ) { - // we dont touch the typeid for the timer expiration - // notify interface here because they might have - // destroyed the timer during its callback - errlogPrintf ( - "timerQueue: Unexpected C++ exception \"%s\" " - "with type \"%s\" during timer expiration " - "callback at %s\n", - pName, - type.name (), - date ); - errlogFlush (); - } -} - -double timerQueue::process ( const epicsTime & currentTime ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - if ( this->pExpireTmr ) { - // if some other thread is processing the queue - // (or if this is a recursive call) - timer * pTmr = this->timerList.first (); - if ( pTmr ) { - double delay = pTmr->exp - currentTime; - if ( delay < 0.0 ) { - delay = 0.0; - } - return delay; - } - else { - return DBL_MAX; - } - } - - // - // Tag current epired tmr so that we can detect if call back - // is in progress when canceling the timer. - // - if ( this->timerList.first () ) { - if ( currentTime >= this->timerList.first ()->exp ) { - this->pExpireTmr = this->timerList.first (); - this->timerList.remove ( *this->pExpireTmr ); - this->pExpireTmr->curState = timer::stateActive; - this->processThread = epicsThreadGetIdSelf (); -# ifdef DEBUG - this->pExpireTmr->show ( 0u ); -# endif - } - else { - double delay = this->timerList.first ()->exp - currentTime; - debugPrintf ( ( "no activity process %f to next\n", delay ) ); - return delay; - } - } - else { - return DBL_MAX; - } - -# ifdef DEBUG - unsigned N = 0u; -# endif - - double delay = DBL_MAX; - while ( true ) { - epicsTimerNotify *pTmpNotify = this->pExpireTmr->pNotify; - this->pExpireTmr->pNotify = 0; - epicsTimerNotify::expireStatus expStat ( epicsTimerNotify::noRestart ); - - { - epicsGuardRelease < epicsMutex > unguard ( guard ); - - debugPrintf ( ( "%5u expired \"%s\" with error %f sec\n", - N++, typeid ( this->pExpireTmr->notify ).name (), - currentTime - this->pExpireTmr->exp ) ); - try { - expStat = pTmpNotify->expire ( currentTime ); - } - catch ( std::exception & except ) { - printExceptMsg ( except.what (), typeid ( except ) ); - } - catch ( ... ) { - printExceptMsg ( "non-standard exception", typeid ( void ) ); - } - } - - // - // only restart if they didnt cancel() the timer - // while the call back was running - // - if ( this->cancelPending ) { - // 1) if another thread is canceling then cancel() waits for - // the event below - // 2) if this thread is canceling in the timer callback then - // dont touch timer or notify here because the cancel might - // have occurred because they destroyed the timer in the - // callback - this->cancelPending = false; - this->cancelBlockingEvent.signal (); - } - else { - this->pExpireTmr->curState = timer::stateLimbo; - if ( this->pExpireTmr->pNotify ) { - // pNotify was cleared above so if it is valid now we know that - // someone has started the timer from another thread and that - // predominates over the restart parameters from expire. - this->pExpireTmr->privateStart ( - *this->pExpireTmr->pNotify, this->pExpireTmr->exp ); - } - else if ( expStat.restart() ) { - // restart as nec - this->pExpireTmr->privateStart ( - *pTmpNotify, currentTime + expStat.expirationDelay() ); - } - } - this->pExpireTmr = 0; - - if ( this->timerList.first () ) { - if ( currentTime >= this->timerList.first ()->exp ) { - this->pExpireTmr = this->timerList.first (); - this->timerList.remove ( *this->pExpireTmr ); - this->pExpireTmr->curState = timer::stateActive; -# ifdef DEBUG - this->pExpireTmr->show ( 0u ); -# endif - } - else { - delay = this->timerList.first ()->exp - currentTime; - this->processThread = 0; - break; - } - } - else { - this->processThread = 0; - delay = DBL_MAX; - break; - } - } - return delay; -} - -epicsTimer & timerQueue::createTimer () -{ - return * new ( this->timerFreeList ) timer ( * this ); -} - -epicsTimerForC & timerQueue::createTimerForC ( epicsTimerCallback pCallback, void *pArg ) -{ - return * new ( this->timerForCFreeList ) epicsTimerForC ( *this, pCallback, pArg ); -} - -void timerQueue::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > locker ( this->mutex ); - printf ( "epicsTimerQueue with %u items pending\n", this->timerList.count () ); - if ( level >= 1u ) { - tsDLIterConst < timer > iter = this->timerList.firstIter (); - while ( iter.valid () ) { - iter->show ( level - 1u ); - ++iter; - } - } -} diff --git a/src/libCom/timer/timerQueueActive.cpp b/src/libCom/timer/timerQueueActive.cpp deleted file mode 100644 index 5d8b72951..000000000 --- a/src/libCom/timer/timerQueueActive.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -#define epicsExportSharedSymbols -#include "timerPrivate.h" -#include "errlog.h" - -#ifdef _MSC_VER -# pragma warning ( push ) -# pragma warning ( disable:4660 ) -#endif - -template class epicsSingleton < timerQueueActiveMgr >; - -#ifdef _MSC_VER -# pragma warning ( pop ) -#endif - -epicsSingleton < timerQueueActiveMgr > timerQueueMgrEPICS; - -epicsTimerQueueActive::~epicsTimerQueueActive () {} - -epicsTimerQueueActive & epicsTimerQueueActive::allocate ( bool okToShare, unsigned threadPriority ) -{ - epicsSingleton < timerQueueActiveMgr >::reference pMgr = - timerQueueMgrEPICS.getReference (); - return pMgr->allocate ( pMgr, okToShare, threadPriority ); -} - -timerQueueActive :: - timerQueueActive ( RefMgr & refMgr, - bool okToShareIn, unsigned priority ) : - _refMgr ( refMgr ), queue ( *this ), thread ( *this, "timerQueue", - epicsThreadGetStackSize ( epicsThreadStackMedium ), priority ), - sleepQuantum ( epicsThreadSleepQuantum() ), okToShare ( okToShareIn ), - exitFlag ( false ), terminateFlag ( false ) -{ -} - -void timerQueueActive::start () -{ - this->thread.start (); -} - -timerQueueActive::~timerQueueActive () -{ - this->terminateFlag = true; - this->rescheduleEvent.signal (); - while ( ! this->exitFlag ) { - this->exitEvent.wait ( 1.0 ); - } - // in case other threads are waiting here also - this->exitEvent.signal (); -} - -void timerQueueActive :: _printLastChanceExceptionMessage ( - const char * pExceptionTypeName, - const char * pExceptionContext ) -{ - char date[64]; - try { - epicsTime cur = epicsTime :: getCurrent (); - cur.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f"); - } - catch ( ... ) { - strcpy ( date, "" ); - } - errlogPrintf ( - "timerQueueActive: Unexpected C++ exception \"%s\" with type \"%s\" " - "while processing timer queue, at %s\n", - pExceptionContext, pExceptionTypeName, date ); -} - - -void timerQueueActive :: run () -{ - this->exitFlag = false; - while ( ! this->terminateFlag ) { - try { - double delay = this->queue.process ( epicsTime::getCurrent() ); - debugPrintf ( ( "timer thread sleeping for %g sec (max)\n", delay ) ); - this->rescheduleEvent.wait ( delay ); - } - catch ( std :: exception & except ) { - _printLastChanceExceptionMessage ( - typeid ( except ).name (), except.what () ); - epicsThreadSleep ( 10.0 ); - } - catch ( ... ) { - _printLastChanceExceptionMessage ( - "catch ( ... )", "Non-standard C++ exception" ); - epicsThreadSleep ( 10.0 ); - } - } - this->exitFlag = true; - this->exitEvent.signal (); // no access to queue after exitEvent signal -} - -epicsTimer & timerQueueActive::createTimer () -{ - return this->queue.createTimer(); -} - -epicsTimerForC & timerQueueActive::createTimerForC ( epicsTimerCallback pCallback, void * pArg ) -{ - return this->queue.createTimerForC ( pCallback, pArg ); -} - -void timerQueueActive::reschedule () -{ - this->rescheduleEvent.signal (); -} - -double timerQueueActive::quantum () -{ - return this->sleepQuantum; -} - -void timerQueueActive::show ( unsigned int level ) const -{ - printf ( "EPICS threaded timer queue at %p\n", - static_cast ( this ) ); - if ( level > 0u ) { - // specifying level one here avoids recursive - // show callback - this->thread.show ( 1u ); - this->queue.show ( level - 1u ); - printf ( "reschedule event\n" ); - this->rescheduleEvent.show ( level - 1u ); - printf ( "exit event\n" ); - this->exitEvent.show ( level - 1u ); - printf ( "exitFlag = %c, terminateFlag = %c\n", - this->exitFlag ? 'T' : 'F', - this->terminateFlag ? 'T' : 'F' ); - } -} - -epicsTimerQueue & timerQueueActive::getEpicsTimerQueue () -{ - return static_cast < epicsTimerQueue &> ( * this ); -} - diff --git a/src/libCom/timer/timerQueueActiveMgr.cpp b/src/libCom/timer/timerQueueActiveMgr.cpp deleted file mode 100644 index d6349a84c..000000000 --- a/src/libCom/timer/timerQueueActiveMgr.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -#define epicsExportSharedSymbols -#include "epicsGuard.h" -#include "timerPrivate.h" - -timerQueueActiveMgr::timerQueueActiveMgr () -{ -} - -timerQueueActiveMgr::~timerQueueActiveMgr () -{ - epicsGuard < epicsMutex > locker ( this->mutex ); -} - -epicsTimerQueueActiveForC & timerQueueActiveMgr :: - allocate ( RefThis & refThis, bool okToShare, unsigned threadPriority ) -{ - epicsGuard < epicsMutex > locker ( this->mutex ); - if ( okToShare ) { - tsDLIter < epicsTimerQueueActiveForC > iter = this->sharedQueueList.firstIter (); - while ( iter.valid () ) { - if ( iter->threadPriority () == threadPriority ) { - assert ( iter->timerQueueActiveMgrPrivate::referenceCount < UINT_MAX ); - iter->timerQueueActiveMgrPrivate::referenceCount++; - return *iter; - } - iter++; - } - } - - epicsTimerQueueActiveForC & queue = - * new epicsTimerQueueActiveForC ( refThis, okToShare, threadPriority ); - queue.timerQueueActiveMgrPrivate::referenceCount = 1u; - if ( okToShare ) { - this->sharedQueueList.add ( queue ); - } - return queue; -} - -void timerQueueActiveMgr :: - release ( epicsTimerQueueActiveForC & queue ) -{ - { - epicsGuard < epicsMutex > locker ( this->mutex ); - assert ( queue.timerQueueActiveMgrPrivate::referenceCount > 0u ); - queue.timerQueueActiveMgrPrivate::referenceCount--; - if ( queue.timerQueueActiveMgrPrivate::referenceCount > 0u ) { - return; - } - else if ( queue.sharingOK () ) { - this->sharedQueueList.remove ( queue ); - } - } - // delete only after we release the guard in case the embedded - // reference is the last one and this object is destroyed - // as a side effect - timerQueueActiveMgrPrivate * pPriv = & queue; - delete pPriv; -} - -timerQueueActiveMgrPrivate::timerQueueActiveMgrPrivate () : - referenceCount ( 0u ) -{ -} - -timerQueueActiveMgrPrivate::~timerQueueActiveMgrPrivate () -{ -} diff --git a/src/libCom/timer/timerQueuePassive.cpp b/src/libCom/timer/timerQueuePassive.cpp deleted file mode 100644 index a352c5672..000000000 --- a/src/libCom/timer/timerQueuePassive.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -// -// Note, a free list for this class is not currently used because of -// entanglements between the file scope free list destructor and a -// file scope fdManager destructor which is trying to call a -// destructor for a passive timer queue which is no longer valid -// in pool. -// - -#include - -#define epicsExportSharedSymbols -#include "timerPrivate.h" - -epicsTimerQueuePassive::~epicsTimerQueuePassive () {} - -epicsTimerQueuePassive & epicsTimerQueuePassive::create ( epicsTimerQueueNotify ¬ify ) -{ - return * new timerQueuePassive ( notify ); -} - -timerQueuePassive::timerQueuePassive ( epicsTimerQueueNotify ¬ifyIn ) : - queue ( notifyIn ) {} - -timerQueuePassive::~timerQueuePassive () {} - -epicsTimer & timerQueuePassive::createTimer () -{ - return this->queue.createTimer (); -} - -epicsTimerForC & timerQueuePassive::createTimerForC ( epicsTimerCallback pCallback, void * pArg ) -{ - return this->queue.createTimerForC ( pCallback, pArg ); -} - -double timerQueuePassive::process ( const epicsTime & currentTime ) -{ - return this->queue.process ( currentTime ); -} - -void timerQueuePassive::show ( unsigned int level ) const -{ - printf ( "EPICS non-threaded timer queue at %p\n", - static_cast ( this ) ); - if ( level >=1u ) { - this->queue.show ( level - 1u ); - } -} - -epicsTimerQueue & timerQueuePassive::getEpicsTimerQueue () -{ - return static_cast < epicsTimerQueue &> ( * this ); -} - diff --git a/src/libCom/valgrind/valgrind.h b/src/libCom/valgrind/valgrind.h deleted file mode 100755 index c503172d5..000000000 --- a/src/libCom/valgrind/valgrind.h +++ /dev/null @@ -1,6587 +0,0 @@ -/* -*- c -*- - ---------------------------------------------------------------- - - Notice that the following BSD-style license applies to this one - file (valgrind.h) only. The rest of Valgrind is licensed under the - terms of the GNU General Public License, version 2, unless - otherwise indicated. See the COPYING file in the source - distribution for details. - - ---------------------------------------------------------------- - - This file is part of Valgrind, a dynamic binary instrumentation - framework. - - Copyright (C) 2000-2013 Julian Seward. 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. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - - 3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 4. 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. - - ---------------------------------------------------------------- - - Notice that the above BSD-style license applies to this one file - (valgrind.h) only. The entire rest of Valgrind is licensed under - the terms of the GNU General Public License, version 2. See the - COPYING file in the source distribution for details. - - ---------------------------------------------------------------- -*/ - - -/* This file is for inclusion into client (your!) code. - - You can use these macros to manipulate and query Valgrind's - execution inside your own programs. - - The resulting executables will still run without Valgrind, just a - little bit more slowly than they otherwise would, but otherwise - unchanged. When not running on valgrind, each client request - consumes very few (eg. 7) instructions, so the resulting performance - loss is negligible unless you plan to execute client requests - millions of times per second. Nevertheless, if that is still a - problem, you can compile with the NVALGRIND symbol defined (gcc - -DNVALGRIND) so that client requests are not even compiled in. */ - -#ifndef __VALGRIND_H -#define __VALGRIND_H - - -/* ------------------------------------------------------------------ */ -/* VERSION NUMBER OF VALGRIND */ -/* ------------------------------------------------------------------ */ - -/* Specify Valgrind's version number, so that user code can - conditionally compile based on our version number. Note that these - were introduced at version 3.6 and so do not exist in version 3.5 - or earlier. The recommended way to use them to check for "version - X.Y or later" is (eg) - -#if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \ - && (__VALGRIND_MAJOR__ > 3 \ - || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6)) -*/ -#define __VALGRIND_MAJOR__ 3 -#define __VALGRIND_MINOR__ 10 - - -#include - -/* Nb: this file might be included in a file compiled with -ansi. So - we can't use C++ style "//" comments nor the "asm" keyword (instead - use "__asm__"). */ - -/* Derive some tags indicating what the target platform is. Note - that in this file we're using the compiler's CPP symbols for - identifying architectures, which are different to the ones we use - within the rest of Valgrind. Note, __powerpc__ is active for both - 32 and 64-bit PPC, whereas __powerpc64__ is only active for the - latter (on Linux, that is). - - Misc note: how to find out what's predefined in gcc by default: - gcc -Wp,-dM somefile.c -*/ -#undef PLAT_x86_darwin -#undef PLAT_amd64_darwin -#undef PLAT_x86_win32 -#undef PLAT_amd64_win64 -#undef PLAT_x86_linux -#undef PLAT_amd64_linux -#undef PLAT_ppc32_linux -#undef PLAT_ppc64be_linux -#undef PLAT_ppc64le_linux -#undef PLAT_arm_linux -#undef PLAT_arm64_linux -#undef PLAT_s390x_linux -#undef PLAT_mips32_linux -#undef PLAT_mips64_linux - - -#if defined(__APPLE__) && defined(__i386__) -# define PLAT_x86_darwin 1 -#elif defined(__APPLE__) && defined(__x86_64__) -# define PLAT_amd64_darwin 1 -#elif (defined(__MINGW32__) && !defined(__MINGW64__)) \ - || defined(__CYGWIN32__) \ - || (defined(_WIN32) && defined(_M_IX86) && defined(__GNUC__)) -# define PLAT_x86_win32 1 -#elif defined(__MINGW64__) \ - || (defined(_WIN64) && defined(_M_X64) && defined(__GNUC__)) -# define PLAT_amd64_win64 1 -#elif defined(__linux__) && defined(__i386__) -# define PLAT_x86_linux 1 -#elif defined(__linux__) && defined(__x86_64__) -# define PLAT_amd64_linux 1 -#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) -# define PLAT_ppc32_linux 1 -#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF != 2 -/* Big Endian uses ELF version 1 */ -# define PLAT_ppc64be_linux 1 -#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF == 2 -/* Little Endian uses ELF version 2 */ -# define PLAT_ppc64le_linux 1 -#elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__) -# define PLAT_arm_linux 1 -#elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__) -# define PLAT_arm64_linux 1 -#elif defined(__linux__) && defined(__s390__) && defined(__s390x__) -# define PLAT_s390x_linux 1 -#elif defined(__linux__) && defined(__mips__) && (__mips==64) -# define PLAT_mips64_linux 1 -#elif defined(__linux__) && defined(__mips__) && (__mips!=64) -# define PLAT_mips32_linux 1 -#else -/* If we're not compiling for our target platform, don't generate - any inline asms. */ -# if !defined(NVALGRIND) -# define NVALGRIND 1 -# endif -#endif - - -/* ------------------------------------------------------------------ */ -/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */ -/* in here of use to end-users -- skip to the next section. */ -/* ------------------------------------------------------------------ */ - -/* - * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client - * request. Accepts both pointers and integers as arguments. - * - * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind - * client request that does not return a value. - - * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind - * client request and whose value equals the client request result. Accepts - * both pointers and integers as arguments. Note that such calls are not - * necessarily pure functions -- they may have side effects. - */ - -#define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \ - _zzq_request, _zzq_arg1, _zzq_arg2, \ - _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \ - (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ - (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) - -#define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1, \ - _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ - (_zzq_request), (_zzq_arg1), (_zzq_arg2), \ - (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0) - -#if defined(NVALGRIND) - -/* Define NVALGRIND to completely remove the Valgrind magic sequence - from the compiled code (analogous to NDEBUG's effects on - assert()) */ -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - (_zzq_default) - -#else /* ! NVALGRIND */ - -/* The following defines the magic code sequences which the JITter - spots and handles magically. Don't look too closely at them as - they will rot your brain. - - The assembly code sequences for all architectures is in this one - file. This is because this file must be stand-alone, and we don't - want to have multiple files. - - For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default - value gets put in the return slot, so that everything works when - this is executed not under Valgrind. Args are passed in a memory - block, and so there's no intrinsic limit to the number that could - be passed, but it's currently five. - - The macro args are: - _zzq_rlval result lvalue - _zzq_default default value (result returned when running on real CPU) - _zzq_request request code - _zzq_arg1..5 request params - - The other two macros are used to support function wrapping, and are - a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the - guest's NRADDR pseudo-register and whatever other information is - needed to safely run the call original from the wrapper: on - ppc64-linux, the R2 value at the divert point is also needed. This - information is abstracted into a user-visible type, OrigFn. - - VALGRIND_CALL_NOREDIR_* behaves the same as the following on the - guest, but guarantees that the branch instruction will not be - redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64: - branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a - complete inline asm, since it needs to be combined with more magic - inline asm stuff to be useful. -*/ - -/* ------------------------- x86-{linux,darwin} ---------------- */ - -#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \ - || (defined(PLAT_x86_win32) && defined(__GNUC__)) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "roll $3, %%edi ; roll $13, %%edi\n\t" \ - "roll $29, %%edi ; roll $19, %%edi\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EDX = client_request ( %EAX ) */ \ - "xchgl %%ebx,%%ebx" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "memory" \ - ); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EAX = guest_NRADDR */ \ - "xchgl %%ecx,%%ecx" \ - : "=a" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_EAX \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%EAX */ \ - "xchgl %%edx,%%edx\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "xchgl %%edi,%%edi\n\t" \ - : : : "cc", "memory" \ - ); \ - } while (0) - -#endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */ - -/* ------------------------- x86-Win32 ------------------------- */ - -#if defined(PLAT_x86_win32) && !defined(__GNUC__) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#if defined(_MSC_VER) - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - __asm rol edi, 3 __asm rol edi, 13 \ - __asm rol edi, 29 __asm rol edi, 19 - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \ - (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \ - (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \ - (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5)) - -static __inline uintptr_t -valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request, - uintptr_t _zzq_arg1, uintptr_t _zzq_arg2, - uintptr_t _zzq_arg3, uintptr_t _zzq_arg4, - uintptr_t _zzq_arg5) -{ - volatile uintptr_t _zzq_args[6]; - volatile unsigned int _zzq_result; - _zzq_args[0] = (uintptr_t)(_zzq_request); - _zzq_args[1] = (uintptr_t)(_zzq_arg1); - _zzq_args[2] = (uintptr_t)(_zzq_arg2); - _zzq_args[3] = (uintptr_t)(_zzq_arg3); - _zzq_args[4] = (uintptr_t)(_zzq_arg4); - _zzq_args[5] = (uintptr_t)(_zzq_arg5); - __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default - __SPECIAL_INSTRUCTION_PREAMBLE - /* %EDX = client_request ( %EAX ) */ - __asm xchg ebx,ebx - __asm mov _zzq_result, edx - } - return _zzq_result; -} - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %EAX = guest_NRADDR */ \ - __asm xchg ecx,ecx \ - __asm mov __addr, eax \ - } \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_EAX ERROR - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm { __SPECIAL_INSTRUCTION_PREAMBLE \ - __asm xchg edi,edi \ - } \ - } while (0) - -#else -#error Unsupported compiler. -#endif - -#endif /* PLAT_x86_win32 */ - -/* ------------------------ amd64-{linux,darwin} --------------- */ - -#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) \ - || (defined(PLAT_amd64_win64) && defined(__GNUC__)) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \ - "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({ volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %RDX = client_request ( %RAX ) */ \ - "xchgq %%rbx,%%rbx" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "memory" \ - ); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %RAX = guest_NRADDR */ \ - "xchgq %%rcx,%%rcx" \ - : "=a" (__addr) \ - : \ - : "cc", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_RAX \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%RAX */ \ - "xchgq %%rdx,%%rdx\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "xchgq %%rdi,%%rdi\n\t" \ - : : : "cc", "memory" \ - ); \ - } while (0) - -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ - -/* ------------------------- amd64-Win64 ------------------------- */ - -#if defined(PLAT_amd64_win64) && !defined(__GNUC__) - -#error Unsupported compiler. - -#endif /* PLAT_amd64_win64 */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rlwinm 0,0,3,0,31 ; rlwinm 0,0,13,0,31\n\t" \ - "rlwinm 0,0,29,0,31 ; rlwinm 0,0,19,0,31\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({ unsigned int _zzq_args[6]; \ - unsigned int _zzq_result; \ - unsigned int* _zzq_ptr; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 3,%1\n\t" /*default*/ \ - "mr 4,%2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" /*result*/ \ - : "=b" (_zzq_result) \ - : "b" (_zzq_default), "b" (_zzq_ptr) \ - : "cc", "memory", "r3", "r4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or 5,5,5\n\t" \ - ); \ - } while (0) - -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ - -#if defined(PLAT_ppc64be_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({ unsigned long long int _zzq_args[6]; \ - unsigned long long int _zzq_result; \ - unsigned long long int* _zzq_ptr; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 3,%1\n\t" /*default*/ \ - "mr 4,%2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" /*result*/ \ - : "=b" (_zzq_result) \ - : "b" (_zzq_default), "b" (_zzq_ptr) \ - : "cc", "memory", "r3", "r4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R11 */ \ - "or 3,3,3\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or 5,5,5\n\t" \ - ); \ - } while (0) - -#endif /* PLAT_ppc64be_linux */ - -#if defined(PLAT_ppc64le_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - unsigned long long int r2; /* what tocptr do we need? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \ - "rotldi 0,0,61 ; rotldi 0,0,51\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({ unsigned long long int _zzq_args[6]; \ - unsigned long long int _zzq_result; \ - unsigned long long int* _zzq_ptr; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - _zzq_ptr = _zzq_args; \ - __asm__ volatile("mr 3,%1\n\t" /*default*/ \ - "mr 4,%2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = client_request ( %R4 ) */ \ - "or 1,1,1\n\t" \ - "mr %0,3" /*result*/ \ - : "=b" (_zzq_result) \ - : "b" (_zzq_default), "b" (_zzq_ptr) \ - : "cc", "memory", "r3", "r4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR */ \ - "or 2,2,2\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %R3 = guest_NRADDR_GPR2 */ \ - "or 4,4,4\n\t" \ - "mr %0,3" \ - : "=b" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->r2 = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R12 */ \ - "or 3,3,3\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or 5,5,5\n\t" \ - ); \ - } while (0) - -#endif /* PLAT_ppc64le_linux */ - -/* ------------------------- arm-linux ------------------------- */ - -#if defined(PLAT_arm_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \ - "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile("mov r3, %1\n\t" /*default*/ \ - "mov r4, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* R3 = client_request ( R4 ) */ \ - "orr r10, r10, r10\n\t" \ - "mov %0, r3" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "cc","memory", "r3", "r4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* R3 = guest_NRADDR */ \ - "orr r11, r11, r11\n\t" \ - "mov %0, r3" \ - : "=r" (__addr) \ - : \ - : "cc", "memory", "r3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir *%R4 */ \ - "orr r12, r12, r12\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "orr r9, r9, r9\n\t" \ - : : : "cc", "memory" \ - ); \ - } while (0) - -#endif /* PLAT_arm_linux */ - -/* ------------------------ arm64-linux ------------------------- */ - -#if defined(PLAT_arm64_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - } - OrigFn; - -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "ror x12, x12, #3 ; ror x12, x12, #13 \n\t" \ - "ror x12, x12, #51 ; ror x12, x12, #61 \n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - \ - __extension__ \ - ({volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile("mov x3, %1\n\t" /*default*/ \ - "mov x4, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* X3 = client_request ( X4 ) */ \ - "orr x10, x10, x10\n\t" \ - "mov %0, x3" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "cc","memory", "x3", "x4"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* X3 = guest_NRADDR */ \ - "orr x11, x11, x11\n\t" \ - "mov %0, x3" \ - : "=r" (__addr) \ - : \ - : "cc", "memory", "x3" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* branch-and-link-to-noredir X8 */ \ - "orr x12, x12, x12\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "orr x9, x9, x9\n\t" \ - : : : "cc", "memory" \ - ); \ - } while (0) - -#endif /* PLAT_arm64_linux */ - -/* ------------------------ s390x-linux ------------------------ */ - -#if defined(PLAT_s390x_linux) - -typedef - struct { - unsigned long long int nraddr; /* where's the code? */ - } - OrigFn; - -/* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific - * code. This detection is implemented in platform specific toIR.c - * (e.g. VEX/priv/guest_s390_decoder.c). - */ -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "lr 15,15\n\t" \ - "lr 1,1\n\t" \ - "lr 2,2\n\t" \ - "lr 3,3\n\t" - -#define __CLIENT_REQUEST_CODE "lr 2,2\n\t" -#define __GET_NR_CONTEXT_CODE "lr 3,3\n\t" -#define __CALL_NO_REDIR_CODE "lr 4,4\n\t" -#define __VEX_INJECT_IR_CODE "lr 5,5\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile(/* r2 = args */ \ - "lgr 2,%1\n\t" \ - /* r3 = default */ \ - "lgr 3,%2\n\t" \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - __CLIENT_REQUEST_CODE \ - /* results = r3 */ \ - "lgr %0, 3\n\t" \ - : "=d" (_zzq_result) \ - : "a" (&_zzq_args[0]), "0" (_zzq_default) \ - : "cc", "2", "3", "memory" \ - ); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - __GET_NR_CONTEXT_CODE \ - "lgr %0, 3\n\t" \ - : "=a" (__addr) \ - : \ - : "cc", "3", "memory" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_R1 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - __CALL_NO_REDIR_CODE - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - __VEX_INJECT_IR_CODE); \ - } while (0) - -#endif /* PLAT_s390x_linux */ - -/* ------------------------- mips32-linux ---------------- */ - -#if defined(PLAT_mips32_linux) - -typedef - struct { - unsigned int nraddr; /* where's the code? */ - } - OrigFn; - -/* .word 0x342 - * .word 0x742 - * .word 0xC2 - * .word 0x4C2*/ -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "srl $0, $0, 13\n\t" \ - "srl $0, $0, 29\n\t" \ - "srl $0, $0, 3\n\t" \ - "srl $0, $0, 19\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({ volatile unsigned int _zzq_args[6]; \ - volatile unsigned int _zzq_result; \ - _zzq_args[0] = (unsigned int)(_zzq_request); \ - _zzq_args[1] = (unsigned int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned int)(_zzq_arg5); \ - __asm__ volatile("move $11, %1\n\t" /*default*/ \ - "move $12, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* T3 = client_request ( T4 ) */ \ - "or $13, $13, $13\n\t" \ - "move %0, $11\n\t" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "$11", "$12"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* %t9 = guest_NRADDR */ \ - "or $14, $14, $14\n\t" \ - "move %0, $11" /*result*/ \ - : "=r" (__addr) \ - : \ - : "$11" \ - ); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_T9 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir *%t9 */ \ - "or $15, $15, $15\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or $11, $11, $11\n\t" \ - ); \ - } while (0) - - -#endif /* PLAT_mips32_linux */ - -/* ------------------------- mips64-linux ---------------- */ - -#if defined(PLAT_mips64_linux) - -typedef - struct { - unsigned long long nraddr; /* where's the code? */ - } - OrigFn; - -/* dsll $0,$0, 3 - * dsll $0,$0, 13 - * dsll $0,$0, 29 - * dsll $0,$0, 19*/ -#define __SPECIAL_INSTRUCTION_PREAMBLE \ - "dsll $0,$0, 3 ; dsll $0,$0,13\n\t" \ - "dsll $0,$0,29 ; dsll $0,$0,19\n\t" - -#define VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - _zzq_default, _zzq_request, \ - _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \ - __extension__ \ - ({ volatile unsigned long long int _zzq_args[6]; \ - volatile unsigned long long int _zzq_result; \ - _zzq_args[0] = (unsigned long long int)(_zzq_request); \ - _zzq_args[1] = (unsigned long long int)(_zzq_arg1); \ - _zzq_args[2] = (unsigned long long int)(_zzq_arg2); \ - _zzq_args[3] = (unsigned long long int)(_zzq_arg3); \ - _zzq_args[4] = (unsigned long long int)(_zzq_arg4); \ - _zzq_args[5] = (unsigned long long int)(_zzq_arg5); \ - __asm__ volatile("move $11, %1\n\t" /*default*/ \ - "move $12, %2\n\t" /*ptr*/ \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* $11 = client_request ( $12 ) */ \ - "or $13, $13, $13\n\t" \ - "move %0, $11\n\t" /*result*/ \ - : "=r" (_zzq_result) \ - : "r" (_zzq_default), "r" (&_zzq_args[0]) \ - : "$11", "$12"); \ - _zzq_result; \ - }) - -#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \ - { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \ - volatile unsigned long long int __addr; \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - /* $11 = guest_NRADDR */ \ - "or $14, $14, $14\n\t" \ - "move %0, $11" /*result*/ \ - : "=r" (__addr) \ - : \ - : "$11"); \ - _zzq_orig->nraddr = __addr; \ - } - -#define VALGRIND_CALL_NOREDIR_T9 \ - __SPECIAL_INSTRUCTION_PREAMBLE \ - /* call-noredir $25 */ \ - "or $15, $15, $15\n\t" - -#define VALGRIND_VEX_INJECT_IR() \ - do { \ - __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \ - "or $11, $11, $11\n\t" \ - ); \ - } while (0) - -#endif /* PLAT_mips64_linux */ - -/* Insert assembly code for other platforms here... */ - -#endif /* NVALGRIND */ - - -/* ------------------------------------------------------------------ */ -/* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */ -/* ugly. It's the least-worst tradeoff I can think of. */ -/* ------------------------------------------------------------------ */ - -/* This section defines magic (a.k.a appalling-hack) macros for doing - guaranteed-no-redirection macros, so as to get from function - wrappers to the functions they are wrapping. The whole point is to - construct standard call sequences, but to do the call itself with a - special no-redirect call pseudo-instruction that the JIT - understands and handles specially. This section is long and - repetitious, and I can't see a way to make it shorter. - - The naming scheme is as follows: - - CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc} - - 'W' stands for "word" and 'v' for "void". Hence there are - different macros for calling arity 0, 1, 2, 3, 4, etc, functions, - and for each, the possibility of returning a word-typed result, or - no result. -*/ - -/* Use these to write the name of your wrapper. NOTE: duplicates - VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. NOTE also: inserts - the default behaviour equivalance class tag "0000" into the name. - See pub_tool_redir.h for details -- normally you don't need to - think about this, though. */ - -/* Use an extra level of macroisation so as to ensure the soname/fnname - args are fully macro-expanded before pasting them together. */ -#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd - -#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \ - VG_CONCAT4(_vgw00000ZU_,soname,_,fnname) - -#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \ - VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname) - -/* Use this macro from within a wrapper function to collect the - context (address and possibly other info) of the original function. - Once you have that you can then use it in one of the CALL_FN_ - macros. The type of the argument _lval is OrigFn. */ -#define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval) - -/* Also provide end-user facilities for function replacement, rather - than wrapping. A replacement function differs from a wrapper in - that it has no way to get hold of the original function being - called, and hence no way to call onwards to it. In a replacement - function, VALGRIND_GET_ORIG_FN always returns zero. */ - -#define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname) \ - VG_CONCAT4(_vgr00000ZU_,soname,_,fnname) - -#define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname) \ - VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname) - -/* Derivatives of the main macros below, for calling functions - returning void. */ - -#define CALL_FN_v_v(fnptr) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_v(_junk,fnptr); } while (0) - -#define CALL_FN_v_W(fnptr, arg1) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_W(_junk,fnptr,arg1); } while (0) - -#define CALL_FN_v_WW(fnptr, arg1,arg2) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0) - -#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0) - -#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0) - -#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0) - -#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0) - -#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \ - do { volatile unsigned long _junk; \ - CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0) - -/* ------------------------- x86-{linux,darwin} ---------------- */ - -#if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) - -/* These regs are trashed by the hidden call. No need to mention eax - as gcc can already see that, plus causes gcc to bomb. */ -#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "movl %%esp,%%edi\n\t" \ - "andl $0xfffffff0,%%esp\n\t" -#define VALGRIND_RESTORE_STACK \ - "movl %%edi,%%esp\n\t" - -/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $12, %%esp\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $8, %%esp\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $4, %%esp\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $12, %%esp\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $8, %%esp\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $4, %%esp\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $12, %%esp\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $8, %%esp\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "subl $4, %%esp\n\t" \ - "pushl 44(%%eax)\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "pushl 48(%%eax)\n\t" \ - "pushl 44(%%eax)\n\t" \ - "pushl 40(%%eax)\n\t" \ - "pushl 36(%%eax)\n\t" \ - "pushl 32(%%eax)\n\t" \ - "pushl 28(%%eax)\n\t" \ - "pushl 24(%%eax)\n\t" \ - "pushl 20(%%eax)\n\t" \ - "pushl 16(%%eax)\n\t" \ - "pushl 12(%%eax)\n\t" \ - "pushl 8(%%eax)\n\t" \ - "pushl 4(%%eax)\n\t" \ - "movl (%%eax), %%eax\n\t" /* target->%eax */ \ - VALGRIND_CALL_NOREDIR_EAX \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_x86_linux || PLAT_x86_darwin */ - -/* ------------------------ amd64-{linux,darwin} --------------- */ - -#if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin) - -/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \ - "rdi", "r8", "r9", "r10", "r11" - -/* This is all pretty complex. It's so as to make stack unwinding - work reliably. See bug 243270. The basic problem is the sub and - add of 128 of %rsp in all of the following macros. If gcc believes - the CFA is in %rsp, then unwinding may fail, because what's at the - CFA is not what gcc "expected" when it constructs the CFIs for the - places where the macros are instantiated. - - But we can't just add a CFI annotation to increase the CFA offset - by 128, to match the sub of 128 from %rsp, because we don't know - whether gcc has chosen %rsp as the CFA at that point, or whether it - has chosen some other register (eg, %rbp). In the latter case, - adding a CFI annotation to change the CFA offset is simply wrong. - - So the solution is to get hold of the CFA using - __builtin_dwarf_cfa(), put it in a known register, and add a - CFI annotation to say what the register is. We choose %rbp for - this (perhaps perversely), because: - - (1) %rbp is already subject to unwinding. If a new register was - chosen then the unwinder would have to unwind it in all stack - traces, which is expensive, and - - (2) %rbp is already subject to precise exception updates in the - JIT. If a new register was chosen, we'd have to have precise - exceptions for it too, which reduces performance of the - generated code. - - However .. one extra complication. We can't just whack the result - of __builtin_dwarf_cfa() into %rbp and then add %rbp to the - list of trashed registers at the end of the inline assembly - fragments; gcc won't allow %rbp to appear in that list. Hence - instead we need to stash %rbp in %r15 for the duration of the asm, - and say that %r15 is trashed instead. gcc seems happy to go with - that. - - Oh .. and this all needs to be conditionalised so that it is - unchanged from before this commit, when compiled with older gccs - that don't support __builtin_dwarf_cfa. Furthermore, since - this header file is freestanding, it has to be independent of - config.h, and so the following conditionalisation cannot depend on - configure time checks. - - Although it's not clear from - 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)', - this expression excludes Darwin. - .cfi directives in Darwin assembly appear to be completely - different and I haven't investigated how they work. - - For even more entertainment value, note we have to use the - completely undocumented __builtin_dwarf_cfa(), which appears to - really compute the CFA, whereas __builtin_frame_address(0) claims - to but actually doesn't. See - https://bugs.kde.org/show_bug.cgi?id=243270#c47 -*/ -#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) -# define __FRAME_POINTER \ - ,"r"(__builtin_dwarf_cfa()) -# define VALGRIND_CFI_PROLOGUE \ - "movq %%rbp, %%r15\n\t" \ - "movq %2, %%rbp\n\t" \ - ".cfi_remember_state\n\t" \ - ".cfi_def_cfa rbp, 0\n\t" -# define VALGRIND_CFI_EPILOGUE \ - "movq %%r15, %%rbp\n\t" \ - ".cfi_restore_state\n\t" -#else -# define __FRAME_POINTER -# define VALGRIND_CFI_PROLOGUE -# define VALGRIND_CFI_EPILOGUE -#endif - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "movq %%rsp,%%r14\n\t" \ - "andq $0xfffffffffffffff0,%%rsp\n\t" -#define VALGRIND_RESTORE_STACK \ - "movq %%r14,%%rsp\n\t" - -/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned - long) == 8. */ - -/* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_ - macros. In order not to trash the stack redzone, we need to drop - %rsp by 128 before the hidden call, and restore afterwards. The - nastyness is that it is only by luck that the stack still appears - to be unwindable during the hidden call - since then the behaviour - of any routine using this macro does not match what the CFI data - says. Sigh. - - Why is this important? Imagine that a wrapper has a stack - allocated local, and passes to the hidden call, a pointer to it. - Because gcc does not know about the hidden call, it may allocate - that local in the redzone. Unfortunately the hidden call may then - trash it before it comes to use it. So we must step clear of the - redzone, for the duration of the hidden call, to make it safe. - - Probably the same problem afflicts the other redzone-style ABIs too - (ppc64-linux); but for those, the stack is - self describing (none of this CFI nonsense) so at least messing - with the stack pointer doesn't give a danger of non-unwindable - stack. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $136,%%rsp\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $136,%%rsp\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $136,%%rsp\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - VALGRIND_ALIGN_STACK \ - "subq $128,%%rsp\n\t" \ - "pushq 96(%%rax)\n\t" \ - "pushq 88(%%rax)\n\t" \ - "pushq 80(%%rax)\n\t" \ - "pushq 72(%%rax)\n\t" \ - "pushq 64(%%rax)\n\t" \ - "pushq 56(%%rax)\n\t" \ - "movq 48(%%rax), %%r9\n\t" \ - "movq 40(%%rax), %%r8\n\t" \ - "movq 32(%%rax), %%rcx\n\t" \ - "movq 24(%%rax), %%rdx\n\t" \ - "movq 16(%%rax), %%rsi\n\t" \ - "movq 8(%%rax), %%rdi\n\t" \ - "movq (%%rax), %%rax\n\t" /* target->%rax */ \ - VALGRIND_CALL_NOREDIR_RAX \ - VALGRIND_RESTORE_STACK \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=a" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */ - -/* ------------------------ ppc32-linux ------------------------ */ - -#if defined(PLAT_ppc32_linux) - -/* This is useful for finding out about the on-stack stuff: - - extern int f9 ( int,int,int,int,int,int,int,int,int ); - extern int f10 ( int,int,int,int,int,int,int,int,int,int ); - extern int f11 ( int,int,int,int,int,int,int,int,int,int,int ); - extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int ); - - int g9 ( void ) { - return f9(11,22,33,44,55,66,77,88,99); - } - int g10 ( void ) { - return f10(11,22,33,44,55,66,77,88,99,110); - } - int g11 ( void ) { - return f11(11,22,33,44,55,66,77,88,99,110,121); - } - int g12 ( void ) { - return f12(11,22,33,44,55,66,77,88,99,110,121,132); - } -*/ - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "mr 28,1\n\t" \ - "rlwinm 1,1,0,0,27\n\t" -#define VALGRIND_RESTORE_STACK \ - "mr 1,28\n\t" - -/* These CALL_FN_ macros assume that on ppc32-linux, - sizeof(unsigned long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "addi 1,1,-16\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - _argvec[12] = (unsigned long)arg12; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "addi 1,1,-32\n\t" \ - /* arg12 */ \ - "lwz 3,48(11)\n\t" \ - "stw 3,20(1)\n\t" \ - /* arg11 */ \ - "lwz 3,44(11)\n\t" \ - "stw 3,16(1)\n\t" \ - /* arg10 */ \ - "lwz 3,40(11)\n\t" \ - "stw 3,12(1)\n\t" \ - /* arg9 */ \ - "lwz 3,36(11)\n\t" \ - "stw 3,8(1)\n\t" \ - /* args1-8 */ \ - "lwz 3,4(11)\n\t" /* arg1->r3 */ \ - "lwz 4,8(11)\n\t" \ - "lwz 5,12(11)\n\t" \ - "lwz 6,16(11)\n\t" /* arg4->r6 */ \ - "lwz 7,20(11)\n\t" \ - "lwz 8,24(11)\n\t" \ - "lwz 9,28(11)\n\t" \ - "lwz 10,32(11)\n\t" /* arg8->r10 */ \ - "lwz 11,0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - VALGRIND_RESTORE_STACK \ - "mr %0,3" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc32_linux */ - -/* ------------------------ ppc64-linux ------------------------ */ - -#if defined(PLAT_ppc64be_linux) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "mr 28,1\n\t" \ - "rldicr 1,1,0,59\n\t" -#define VALGRIND_RESTORE_STACK \ - "mr 1,28\n\t" - -/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned - long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 11,%1\n\t" \ - "std 2,-16(11)\n\t" /* save tocptr */ \ - "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg12 */ \ - "ld 3,96(11)\n\t" \ - "std 3,136(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(11)\n\t" \ - "std 3,128(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(11)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(11)\n\t" \ - "std 3,112(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(11)\n\t" /* arg1->r3 */ \ - "ld 4, 16(11)\n\t" /* arg2->r4 */ \ - "ld 5, 24(11)\n\t" /* arg3->r5 */ \ - "ld 6, 32(11)\n\t" /* arg4->r6 */ \ - "ld 7, 40(11)\n\t" /* arg5->r7 */ \ - "ld 8, 48(11)\n\t" /* arg6->r8 */ \ - "ld 9, 56(11)\n\t" /* arg7->r9 */ \ - "ld 10, 64(11)\n\t" /* arg8->r10 */ \ - "ld 11, 0(11)\n\t" /* target->r11 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \ - "mr 11,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(11)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc64be_linux */ - -/* ------------------------- ppc64le-linux ----------------------- */ -#if defined(PLAT_ppc64le_linux) - -/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */ - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "lr", "ctr", "xer", \ - "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ - "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ - "r11", "r12", "r13" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -#define VALGRIND_ALIGN_STACK \ - "mr 28,1\n\t" \ - "rldicr 1,1,0,59\n\t" -#define VALGRIND_RESTORE_STACK \ - "mr 1,28\n\t" - -/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned - long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+0]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+1]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+2]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+3]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+4]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+5]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+6]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+7]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+8]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+9]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg9 */ \ - "ld 3,72(12)\n\t" \ - "std 3,96(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+10]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-128\n\t" /* expand stack frame */ \ - /* arg10 */ \ - "ld 3,80(12)\n\t" \ - "std 3,104(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(12)\n\t" \ - "std 3,96(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+11]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg11 */ \ - "ld 3,88(12)\n\t" \ - "std 3,112(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(12)\n\t" \ - "std 3,104(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(12)\n\t" \ - "std 3,96(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3+12]; \ - volatile unsigned long _res; \ - /* _argvec[0] holds current r2 across the call */ \ - _argvec[1] = (unsigned long)_orig.r2; \ - _argvec[2] = (unsigned long)_orig.nraddr; \ - _argvec[2+1] = (unsigned long)arg1; \ - _argvec[2+2] = (unsigned long)arg2; \ - _argvec[2+3] = (unsigned long)arg3; \ - _argvec[2+4] = (unsigned long)arg4; \ - _argvec[2+5] = (unsigned long)arg5; \ - _argvec[2+6] = (unsigned long)arg6; \ - _argvec[2+7] = (unsigned long)arg7; \ - _argvec[2+8] = (unsigned long)arg8; \ - _argvec[2+9] = (unsigned long)arg9; \ - _argvec[2+10] = (unsigned long)arg10; \ - _argvec[2+11] = (unsigned long)arg11; \ - _argvec[2+12] = (unsigned long)arg12; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "mr 12,%1\n\t" \ - "std 2,-16(12)\n\t" /* save tocptr */ \ - "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ - "addi 1,1,-144\n\t" /* expand stack frame */ \ - /* arg12 */ \ - "ld 3,96(12)\n\t" \ - "std 3,120(1)\n\t" \ - /* arg11 */ \ - "ld 3,88(12)\n\t" \ - "std 3,112(1)\n\t" \ - /* arg10 */ \ - "ld 3,80(12)\n\t" \ - "std 3,104(1)\n\t" \ - /* arg9 */ \ - "ld 3,72(12)\n\t" \ - "std 3,96(1)\n\t" \ - /* args1-8 */ \ - "ld 3, 8(12)\n\t" /* arg1->r3 */ \ - "ld 4, 16(12)\n\t" /* arg2->r4 */ \ - "ld 5, 24(12)\n\t" /* arg3->r5 */ \ - "ld 6, 32(12)\n\t" /* arg4->r6 */ \ - "ld 7, 40(12)\n\t" /* arg5->r7 */ \ - "ld 8, 48(12)\n\t" /* arg6->r8 */ \ - "ld 9, 56(12)\n\t" /* arg7->r9 */ \ - "ld 10, 64(12)\n\t" /* arg8->r10 */ \ - "ld 12, 0(12)\n\t" /* target->r12 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ - "mr 12,%1\n\t" \ - "mr %0,3\n\t" \ - "ld 2,-16(12)\n\t" /* restore tocptr */ \ - VALGRIND_RESTORE_STACK \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[2]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_ppc64le_linux */ - -/* ------------------------- arm-linux ------------------------- */ - -#if defined(PLAT_arm_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14" - -/* Macros to save and align the stack before making a function - call and restore it afterwards as gcc may not keep the stack - pointer aligned if it doesn't realise calls are being made - to other functions. */ - -/* This is a bit tricky. We store the original stack pointer in r10 - as it is callee-saves. gcc doesn't allow the use of r11 for some - reason. Also, we can't directly "bic" the stack pointer in thumb - mode since r13 isn't an allowed register number in that context. - So use r4 as a temporary, since that is about to get trashed - anyway, just after each use of this macro. Side effect is we need - to be very careful about any future changes, since - VALGRIND_ALIGN_STACK simply assumes r4 is usable. */ -#define VALGRIND_ALIGN_STACK \ - "mov r10, sp\n\t" \ - "mov r4, sp\n\t" \ - "bic r4, r4, #7\n\t" \ - "mov sp, r4\n\t" -#define VALGRIND_RESTORE_STACK \ - "mov sp, r10\n\t" - -/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #4 \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "push {r0} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "push {r0, r1} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #4 \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "push {r0, r1, r2} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "push {r0, r1, r2, r3} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #4 \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #40] \n\t" \ - "push {r0} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #4 \n\t" \ - "ldr r0, [%1, #40] \n\t" \ - "ldr r1, [%1, #44] \n\t" \ - "push {r0, r1} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr r0, [%1, #40] \n\t" \ - "ldr r1, [%1, #44] \n\t" \ - "ldr r2, [%1, #48] \n\t" \ - "push {r0, r1, r2} \n\t" \ - "ldr r0, [%1, #20] \n\t" \ - "ldr r1, [%1, #24] \n\t" \ - "ldr r2, [%1, #28] \n\t" \ - "ldr r3, [%1, #32] \n\t" \ - "ldr r4, [%1, #36] \n\t" \ - "push {r0, r1, r2, r3, r4} \n\t" \ - "ldr r0, [%1, #4] \n\t" \ - "ldr r1, [%1, #8] \n\t" \ - "ldr r2, [%1, #12] \n\t" \ - "ldr r3, [%1, #16] \n\t" \ - "ldr r4, [%1] \n\t" /* target->r4 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \ - VALGRIND_RESTORE_STACK \ - "mov %0, r0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_arm_linux */ - -/* ------------------------ arm64-linux ------------------------ */ - -#if defined(PLAT_arm64_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS \ - "x0", "x1", "x2", "x3","x4", "x5", "x6", "x7", "x8", "x9", \ - "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", \ - "x18", "x19", "x20", "x30", \ - "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \ - "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", \ - "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", \ - "v26", "v27", "v28", "v29", "v30", "v31" - -/* x21 is callee-saved, so we can use it to save and restore SP around - the hidden call. */ -#define VALGRIND_ALIGN_STACK \ - "mov x21, sp\n\t" \ - "bic sp, x21, #15\n\t" -#define VALGRIND_RESTORE_STACK \ - "mov sp, x21\n\t" - -/* These CALL_FN_ macros assume that on arm64-linux, - sizeof(unsigned long) == 8. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #0x20 \n\t" \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1, #72] \n\t" \ - "str x8, [sp, #0] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #0x20 \n\t" \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1, #72] \n\t" \ - "str x8, [sp, #0] \n\t" \ - "ldr x8, [%1, #80] \n\t" \ - "str x8, [sp, #8] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #0x30 \n\t" \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1, #72] \n\t" \ - "str x8, [sp, #0] \n\t" \ - "ldr x8, [%1, #80] \n\t" \ - "str x8, [sp, #8] \n\t" \ - "ldr x8, [%1, #88] \n\t" \ - "str x8, [sp, #16] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10,arg11, \ - arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - VALGRIND_ALIGN_STACK \ - "sub sp, sp, #0x30 \n\t" \ - "ldr x0, [%1, #8] \n\t" \ - "ldr x1, [%1, #16] \n\t" \ - "ldr x2, [%1, #24] \n\t" \ - "ldr x3, [%1, #32] \n\t" \ - "ldr x4, [%1, #40] \n\t" \ - "ldr x5, [%1, #48] \n\t" \ - "ldr x6, [%1, #56] \n\t" \ - "ldr x7, [%1, #64] \n\t" \ - "ldr x8, [%1, #72] \n\t" \ - "str x8, [sp, #0] \n\t" \ - "ldr x8, [%1, #80] \n\t" \ - "str x8, [sp, #8] \n\t" \ - "ldr x8, [%1, #88] \n\t" \ - "str x8, [sp, #16] \n\t" \ - "ldr x8, [%1, #96] \n\t" \ - "str x8, [sp, #24] \n\t" \ - "ldr x8, [%1] \n\t" /* target->x8 */ \ - VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8 \ - VALGRIND_RESTORE_STACK \ - "mov %0, x0" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_arm64_linux */ - -/* ------------------------- s390x-linux ------------------------- */ - -#if defined(PLAT_s390x_linux) - -/* Similar workaround as amd64 (see above), but we use r11 as frame - pointer and save the old r11 in r7. r11 might be used for - argvec, therefore we copy argvec in r1 since r1 is clobbered - after the call anyway. */ -#if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM) -# define __FRAME_POINTER \ - ,"d"(__builtin_dwarf_cfa()) -# define VALGRIND_CFI_PROLOGUE \ - ".cfi_remember_state\n\t" \ - "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \ - "lgr 7,11\n\t" \ - "lgr 11,%2\n\t" \ - ".cfi_def_cfa r11, 0\n\t" -# define VALGRIND_CFI_EPILOGUE \ - "lgr 11, 7\n\t" \ - ".cfi_restore_state\n\t" -#else -# define __FRAME_POINTER -# define VALGRIND_CFI_PROLOGUE \ - "lgr 1,%1\n\t" -# define VALGRIND_CFI_EPILOGUE -#endif - -/* Nb: On s390 the stack pointer is properly aligned *at all times* - according to the s390 GCC maintainer. (The ABI specification is not - precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and - VALGRIND_RESTORE_STACK are not defined here. */ - -/* These regs are trashed by the hidden call. Note that we overwrite - r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the - function a proper return address. All others are ABI defined call - clobbers. */ -#define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \ - "f0","f1","f2","f3","f4","f5","f6","f7" - -/* Nb: Although r11 is modified in the asm snippets below (inside - VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for - two reasons: - (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not - modified - (2) GCC will complain that r11 cannot appear inside a clobber section, - when compiled with -O -fno-omit-frame-pointer - */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 1, 0(1)\n\t" /* target->r1 */ \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -/* The call abi has the arguments in r2-r6 and stack */ -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1, arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-160\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,160\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-168\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,168\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-176\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,176\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-184\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,184\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8, arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-192\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,192\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8, arg9, arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-200\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,200\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8, arg9, arg10, arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-208\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "mvc 200(8,15), 88(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,208\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \ - arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)arg1; \ - _argvec[2] = (unsigned long)arg2; \ - _argvec[3] = (unsigned long)arg3; \ - _argvec[4] = (unsigned long)arg4; \ - _argvec[5] = (unsigned long)arg5; \ - _argvec[6] = (unsigned long)arg6; \ - _argvec[7] = (unsigned long)arg7; \ - _argvec[8] = (unsigned long)arg8; \ - _argvec[9] = (unsigned long)arg9; \ - _argvec[10] = (unsigned long)arg10; \ - _argvec[11] = (unsigned long)arg11; \ - _argvec[12] = (unsigned long)arg12; \ - __asm__ volatile( \ - VALGRIND_CFI_PROLOGUE \ - "aghi 15,-216\n\t" \ - "lg 2, 8(1)\n\t" \ - "lg 3,16(1)\n\t" \ - "lg 4,24(1)\n\t" \ - "lg 5,32(1)\n\t" \ - "lg 6,40(1)\n\t" \ - "mvc 160(8,15), 48(1)\n\t" \ - "mvc 168(8,15), 56(1)\n\t" \ - "mvc 176(8,15), 64(1)\n\t" \ - "mvc 184(8,15), 72(1)\n\t" \ - "mvc 192(8,15), 80(1)\n\t" \ - "mvc 200(8,15), 88(1)\n\t" \ - "mvc 208(8,15), 96(1)\n\t" \ - "lg 1, 0(1)\n\t" \ - VALGRIND_CALL_NOREDIR_R1 \ - "lgr %0, 2\n\t" \ - "aghi 15,216\n\t" \ - VALGRIND_CFI_EPILOGUE \ - : /*out*/ "=d" (_res) \ - : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \ - : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - - -#endif /* PLAT_s390x_linux */ - -/* ------------------------- mips32-linux ----------------------- */ - -#if defined(PLAT_mips32_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ -"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ -"$25", "$31" - -/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16\n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $4, 4(%1) \n\t" /* arg1*/ \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "subu $29, $29, 16 \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 16 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 24\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 24 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 32\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "nop\n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 32 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 32\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 32 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 40\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 40 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 40\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 36(%1) \n\t" \ - "sw $4, 32($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 40 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 48\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 36(%1) \n\t" \ - "sw $4, 32($29) \n\t" \ - "lw $4, 40(%1) \n\t" \ - "sw $4, 36($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 48 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 48\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 36(%1) \n\t" \ - "sw $4, 32($29) \n\t" \ - "lw $4, 40(%1) \n\t" \ - "sw $4, 36($29) \n\t" \ - "lw $4, 44(%1) \n\t" \ - "sw $4, 40($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 48 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - "subu $29, $29, 8 \n\t" \ - "sw $28, 0($29) \n\t" \ - "sw $31, 4($29) \n\t" \ - "lw $4, 20(%1) \n\t" \ - "subu $29, $29, 56\n\t" \ - "sw $4, 16($29) \n\t" \ - "lw $4, 24(%1) \n\t" \ - "sw $4, 20($29) \n\t" \ - "lw $4, 28(%1) \n\t" \ - "sw $4, 24($29) \n\t" \ - "lw $4, 32(%1) \n\t" \ - "sw $4, 28($29) \n\t" \ - "lw $4, 36(%1) \n\t" \ - "sw $4, 32($29) \n\t" \ - "lw $4, 40(%1) \n\t" \ - "sw $4, 36($29) \n\t" \ - "lw $4, 44(%1) \n\t" \ - "sw $4, 40($29) \n\t" \ - "lw $4, 48(%1) \n\t" \ - "sw $4, 44($29) \n\t" \ - "lw $4, 4(%1) \n\t" \ - "lw $5, 8(%1) \n\t" \ - "lw $6, 12(%1) \n\t" \ - "lw $7, 16(%1) \n\t" \ - "lw $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "addu $29, $29, 56 \n\t" \ - "lw $28, 0($29) \n\t" \ - "lw $31, 4($29) \n\t" \ - "addu $29, $29, 8 \n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_mips32_linux */ - -/* ------------------------- mips64-linux ------------------------- */ - -#if defined(PLAT_mips64_linux) - -/* These regs are trashed by the hidden call. */ -#define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6", \ -"$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ -"$25", "$31" - -/* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned - long) == 4. */ - -#define CALL_FN_W_v(lval, orig) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[1]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - __asm__ volatile( \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "0" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_W(lval, orig, arg1) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[2]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" /* arg1*/ \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WW(lval, orig, arg1,arg2) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[3]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[4]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[5]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[6]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[7]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[8]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[9]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - __asm__ volatile( \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1) \n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[10]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - __asm__ volatile( \ - "dsubu $29, $29, 8\n\t" \ - "ld $4, 72(%1)\n\t" \ - "sd $4, 0($29)\n\t" \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "daddu $29, $29, 8\n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \ - arg7,arg8,arg9,arg10) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[11]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - __asm__ volatile( \ - "dsubu $29, $29, 16\n\t" \ - "ld $4, 72(%1)\n\t" \ - "sd $4, 0($29)\n\t" \ - "ld $4, 80(%1)\n\t" \ - "sd $4, 8($29)\n\t" \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "daddu $29, $29, 16\n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[12]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - __asm__ volatile( \ - "dsubu $29, $29, 24\n\t" \ - "ld $4, 72(%1)\n\t" \ - "sd $4, 0($29)\n\t" \ - "ld $4, 80(%1)\n\t" \ - "sd $4, 8($29)\n\t" \ - "ld $4, 88(%1)\n\t" \ - "sd $4, 16($29)\n\t" \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "daddu $29, $29, 24\n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \ - arg6,arg7,arg8,arg9,arg10, \ - arg11,arg12) \ - do { \ - volatile OrigFn _orig = (orig); \ - volatile unsigned long _argvec[13]; \ - volatile unsigned long _res; \ - _argvec[0] = (unsigned long)_orig.nraddr; \ - _argvec[1] = (unsigned long)(arg1); \ - _argvec[2] = (unsigned long)(arg2); \ - _argvec[3] = (unsigned long)(arg3); \ - _argvec[4] = (unsigned long)(arg4); \ - _argvec[5] = (unsigned long)(arg5); \ - _argvec[6] = (unsigned long)(arg6); \ - _argvec[7] = (unsigned long)(arg7); \ - _argvec[8] = (unsigned long)(arg8); \ - _argvec[9] = (unsigned long)(arg9); \ - _argvec[10] = (unsigned long)(arg10); \ - _argvec[11] = (unsigned long)(arg11); \ - _argvec[12] = (unsigned long)(arg12); \ - __asm__ volatile( \ - "dsubu $29, $29, 32\n\t" \ - "ld $4, 72(%1)\n\t" \ - "sd $4, 0($29)\n\t" \ - "ld $4, 80(%1)\n\t" \ - "sd $4, 8($29)\n\t" \ - "ld $4, 88(%1)\n\t" \ - "sd $4, 16($29)\n\t" \ - "ld $4, 96(%1)\n\t" \ - "sd $4, 24($29)\n\t" \ - "ld $4, 8(%1)\n\t" \ - "ld $5, 16(%1)\n\t" \ - "ld $6, 24(%1)\n\t" \ - "ld $7, 32(%1)\n\t" \ - "ld $8, 40(%1)\n\t" \ - "ld $9, 48(%1)\n\t" \ - "ld $10, 56(%1)\n\t" \ - "ld $11, 64(%1)\n\t" \ - "ld $25, 0(%1)\n\t" /* target->t9 */ \ - VALGRIND_CALL_NOREDIR_T9 \ - "daddu $29, $29, 32\n\t" \ - "move %0, $2\n" \ - : /*out*/ "=r" (_res) \ - : /*in*/ "r" (&_argvec[0]) \ - : /*trash*/ "memory", __CALLER_SAVED_REGS \ - ); \ - lval = (__typeof__(lval)) _res; \ - } while (0) - -#endif /* PLAT_mips64_linux */ - - -/* ------------------------------------------------------------------ */ -/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */ -/* */ -/* ------------------------------------------------------------------ */ - -/* Some request codes. There are many more of these, but most are not - exposed to end-user view. These are the public ones, all of the - form 0x1000 + small_number. - - Core ones are in the range 0x00000000--0x0000ffff. The non-public - ones start at 0x2000. -*/ - -/* These macros are used by tools -- they must be public, but don't - embed them into other programs. */ -#define VG_USERREQ_TOOL_BASE(a,b) \ - ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16)) -#define VG_IS_TOOL_USERREQ(a, b, v) \ - (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000)) - -/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! - This enum comprises an ABI exported by Valgrind to programs - which use client requests. DO NOT CHANGE THE ORDER OF THESE - ENTRIES, NOR DELETE ANY -- add new ones at the end. */ -typedef - enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001, - VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002, - - /* These allow any function to be called from the simulated - CPU but run on the real CPU. Nb: the first arg passed to - the function is always the ThreadId of the running - thread! So CLIENT_CALL0 actually requires a 1 arg - function, etc. */ - VG_USERREQ__CLIENT_CALL0 = 0x1101, - VG_USERREQ__CLIENT_CALL1 = 0x1102, - VG_USERREQ__CLIENT_CALL2 = 0x1103, - VG_USERREQ__CLIENT_CALL3 = 0x1104, - - /* Can be useful in regression testing suites -- eg. can - send Valgrind's output to /dev/null and still count - errors. */ - VG_USERREQ__COUNT_ERRORS = 0x1201, - - /* Allows the client program and/or gdbserver to execute a monitor - command. */ - VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202, - - /* These are useful and can be interpreted by any tool that - tracks malloc() et al, by using vg_replace_malloc.c. */ - VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301, - VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b, - VG_USERREQ__FREELIKE_BLOCK = 0x1302, - /* Memory pool support. */ - VG_USERREQ__CREATE_MEMPOOL = 0x1303, - VG_USERREQ__DESTROY_MEMPOOL = 0x1304, - VG_USERREQ__MEMPOOL_ALLOC = 0x1305, - VG_USERREQ__MEMPOOL_FREE = 0x1306, - VG_USERREQ__MEMPOOL_TRIM = 0x1307, - VG_USERREQ__MOVE_MEMPOOL = 0x1308, - VG_USERREQ__MEMPOOL_CHANGE = 0x1309, - VG_USERREQ__MEMPOOL_EXISTS = 0x130a, - - /* Allow printfs to valgrind log. */ - /* The first two pass the va_list argument by value, which - assumes it is the same size as or smaller than a UWord, - which generally isn't the case. Hence are deprecated. - The second two pass the vargs by reference and so are - immune to this problem. */ - /* both :: char* fmt, va_list vargs (DEPRECATED) */ - VG_USERREQ__PRINTF = 0x1401, - VG_USERREQ__PRINTF_BACKTRACE = 0x1402, - /* both :: char* fmt, va_list* vargs */ - VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404, - - /* Stack support. */ - VG_USERREQ__STACK_REGISTER = 0x1501, - VG_USERREQ__STACK_DEREGISTER = 0x1502, - VG_USERREQ__STACK_CHANGE = 0x1503, - - /* Wine support */ - VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601, - - /* Querying of debug info. */ - VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701, - - /* Disable/enable error reporting level. Takes a single - Word arg which is the delta to this thread's error - disablement indicator. Hence 1 disables or further - disables errors, and -1 moves back towards enablement. - Other values are not allowed. */ - VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801, - - /* Initialise IR injection */ - VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901 - } Vg_ClientRequest; - -#if !defined(__GNUC__) -# define __extension__ /* */ -#endif - - -/* Returns the number of Valgrinds this code is running under. That - is, 0 if running natively, 1 if running under Valgrind, 2 if - running under Valgrind which is running under another Valgrind, - etc. */ -#define RUNNING_ON_VALGRIND \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \ - VG_USERREQ__RUNNING_ON_VALGRIND, \ - 0, 0, 0, 0, 0) \ - - -/* Discard translation of code in the range [_qzz_addr .. _qzz_addr + - _qzz_len - 1]. Useful if you are debugging a JITter or some such, - since it provides a way to make sure valgrind will retranslate the - invalidated area. Returns no value. */ -#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS, \ - _qzz_addr, _qzz_len, 0, 0, 0) - - -/* These requests are for getting Valgrind itself to print something. - Possibly with a backtrace. This is a really ugly hack. The return value - is the number of characters printed, excluding the "**** " part at the - start and the backtrace (if present). */ - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) -/* Modern GCC will optimize the static routine out if unused, - and unused attribute will shut down warnings about it. */ -static int VALGRIND_PRINTF(const char *format, ...) - __attribute__((format(__printf__, 1, 2), __unused__)); -#endif -static int -#if defined(_MSC_VER) -__inline -#endif -VALGRIND_PRINTF(const char *format, ...) -{ -#if defined(NVALGRIND) - return 0; -#else /* NVALGRIND */ -#if defined(_MSC_VER) || defined(__MINGW64__) - uintptr_t _qzz_res; -#else - unsigned long _qzz_res; -#endif - va_list vargs; - va_start(vargs, format); -#if defined(_MSC_VER) || defined(__MINGW64__) - _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, - VG_USERREQ__PRINTF_VALIST_BY_REF, - (uintptr_t)format, - (uintptr_t)&vargs, - 0, 0, 0); -#else - _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, - VG_USERREQ__PRINTF_VALIST_BY_REF, - (unsigned long)format, - (unsigned long)&vargs, - 0, 0, 0); -#endif - va_end(vargs); - return (int)_qzz_res; -#endif /* NVALGRIND */ -} - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER) -static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...) - __attribute__((format(__printf__, 1, 2), __unused__)); -#endif -static int -#if defined(_MSC_VER) -__inline -#endif -VALGRIND_PRINTF_BACKTRACE(const char *format, ...) -{ -#if defined(NVALGRIND) - return 0; -#else /* NVALGRIND */ -#if defined(_MSC_VER) || defined(__MINGW64__) - uintptr_t _qzz_res; -#else - unsigned long _qzz_res; -#endif - va_list vargs; - va_start(vargs, format); -#if defined(_MSC_VER) || defined(__MINGW64__) - _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, - (uintptr_t)format, - (uintptr_t)&vargs, - 0, 0, 0); -#else - _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0, - VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF, - (unsigned long)format, - (unsigned long)&vargs, - 0, 0, 0); -#endif - va_end(vargs); - return (int)_qzz_res; -#endif /* NVALGRIND */ -} - - -/* These requests allow control to move from the simulated CPU to the - real CPU, calling an arbitary function. - - Note that the current ThreadId is inserted as the first argument. - So this call: - - VALGRIND_NON_SIMD_CALL2(f, arg1, arg2) - - requires f to have this signature: - - Word f(Word tid, Word arg1, Word arg2) - - where "Word" is a word-sized type. - - Note that these client requests are not entirely reliable. For example, - if you call a function with them that subsequently calls printf(), - there's a high chance Valgrind will crash. Generally, your prospects of - these working are made higher if the called function does not refer to - any global variables, and does not refer to any libc or other functions - (printf et al). Any kind of entanglement with libc or dynamic linking is - likely to have a bad outcome, for tricky reasons which we've grappled - with a lot in the past. -*/ -#define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ - VG_USERREQ__CLIENT_CALL0, \ - _qyy_fn, \ - 0, 0, 0, 0) - -#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ - VG_USERREQ__CLIENT_CALL1, \ - _qyy_fn, \ - _qyy_arg1, 0, 0, 0) - -#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ - VG_USERREQ__CLIENT_CALL2, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, 0, 0) - -#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \ - VG_USERREQ__CLIENT_CALL3, \ - _qyy_fn, \ - _qyy_arg1, _qyy_arg2, \ - _qyy_arg3, 0) - - -/* Counts the number of errors that have been recorded by a tool. Nb: - the tool must record the errors with VG_(maybe_record_error)() or - VG_(unique_error)() for them to be counted. */ -#define VALGRIND_COUNT_ERRORS \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \ - 0 /* default return */, \ - VG_USERREQ__COUNT_ERRORS, \ - 0, 0, 0, 0, 0) - -/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing - when heap blocks are allocated in order to give accurate results. This - happens automatically for the standard allocator functions such as - malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete, - delete[], etc. - - But if your program uses a custom allocator, this doesn't automatically - happen, and Valgrind will not do as well. For example, if you allocate - superblocks with mmap() and then allocates chunks of the superblocks, all - Valgrind's observations will be at the mmap() level and it won't know that - the chunks should be considered separate entities. In Memcheck's case, - that means you probably won't get heap block overrun detection (because - there won't be redzones marked as unaddressable) and you definitely won't - get any leak detection. - - The following client requests allow a custom allocator to be annotated so - that it can be handled accurately by Valgrind. - - VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated - by a malloc()-like function. For Memcheck (an illustrative case), this - does two things: - - - It records that the block has been allocated. This means any addresses - within the block mentioned in error messages will be - identified as belonging to the block. It also means that if the block - isn't freed it will be detected by the leak checker. - - - It marks the block as being addressable and undefined (if 'is_zeroed' is - not set), or addressable and defined (if 'is_zeroed' is set). This - controls how accesses to the block by the program are handled. - - 'addr' is the start of the usable block (ie. after any - redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator - can apply redzones -- these are blocks of padding at the start and end of - each block. Adding redzones is recommended as it makes it much more likely - Valgrind will spot block overruns. `is_zeroed' indicates if the memory is - zeroed (or filled with another predictable value), as is the case for - calloc(). - - VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a - heap block -- that will be used by the client program -- is allocated. - It's best to put it at the outermost level of the allocator if possible; - for example, if you have a function my_alloc() which calls - internal_alloc(), and the client request is put inside internal_alloc(), - stack traces relating to the heap block will contain entries for both - my_alloc() and internal_alloc(), which is probably not what you want. - - For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out - custom blocks from within a heap block, B, that has been allocated with - malloc/calloc/new/etc, then block B will be *ignored* during leak-checking - -- the custom blocks will take precedence. - - VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For - Memcheck, it does two things: - - - It records that the block has been deallocated. This assumes that the - block was annotated as having been allocated via - VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. - - - It marks the block as being unaddressable. - - VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a - heap block is deallocated. - - VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For - Memcheck, it does four things: - - - It records that the size of a block has been changed. This assumes that - the block was annotated as having been allocated via - VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued. - - - If the block shrunk, it marks the freed memory as being unaddressable. - - - If the block grew, it marks the new area as undefined and defines a red - zone past the end of the new block. - - - The V-bits of the overlap between the old and the new block are preserved. - - VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block - and before deallocation of the old block. - - In many cases, these three client requests will not be enough to get your - allocator working well with Memcheck. More specifically, if your allocator - writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call - will be necessary to mark the memory as addressable just before the zeroing - occurs, otherwise you'll get a lot of invalid write errors. For example, - you'll need to do this if your allocator recycles freed blocks, but it - zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK). - Alternatively, if your allocator reuses freed blocks for allocator-internal - data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary. - - Really, what's happening is a blurring of the lines between the client - program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the - memory should be considered unaddressable to the client program, but the - allocator knows more than the rest of the client program and so may be able - to safely access it. Extra client requests are necessary for Valgrind to - understand the distinction between the allocator and the rest of the - program. - - Ignored if addr == 0. -*/ -#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK, \ - addr, sizeB, rzB, is_zeroed, 0) - -/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. - Ignored if addr == 0. -*/ -#define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK, \ - addr, oldSizeB, newSizeB, rzB, 0) - -/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. - Ignored if addr == 0. -*/ -#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK, \ - addr, rzB, 0, 0, 0) - -/* Create a memory pool. */ -#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL, \ - pool, rzB, is_zeroed, 0, 0) - -/* Destroy a memory pool. */ -#define VALGRIND_DESTROY_MEMPOOL(pool) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL, \ - pool, 0, 0, 0, 0) - -/* Associate a piece of memory with a memory pool. */ -#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC, \ - pool, addr, size, 0, 0) - -/* Disassociate a piece of memory from a memory pool. */ -#define VALGRIND_MEMPOOL_FREE(pool, addr) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE, \ - pool, addr, 0, 0, 0) - -/* Disassociate any pieces outside a particular range. */ -#define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM, \ - pool, addr, size, 0, 0) - -/* Resize and/or move a piece associated with a memory pool. */ -#define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL, \ - poolA, poolB, 0, 0, 0) - -/* Resize and/or move a piece associated with a memory pool. */ -#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE, \ - pool, addrA, addrB, size, 0) - -/* Return 1 if a mempool exists, else 0. */ -#define VALGRIND_MEMPOOL_EXISTS(pool) \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ - VG_USERREQ__MEMPOOL_EXISTS, \ - pool, 0, 0, 0, 0) - -/* Mark a piece of memory as being a stack. Returns a stack id. - start is the lowest addressable stack byte, end is the highest - addressable stack byte. */ -#define VALGRIND_STACK_REGISTER(start, end) \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ - VG_USERREQ__STACK_REGISTER, \ - start, end, 0, 0, 0) - -/* Unmark the piece of memory associated with a stack id as being a - stack. */ -#define VALGRIND_STACK_DEREGISTER(id) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \ - id, 0, 0, 0, 0) - -/* Change the start and end address of the stack id. - start is the new lowest addressable stack byte, end is the new highest - addressable stack byte. */ -#define VALGRIND_STACK_CHANGE(id, start, end) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE, \ - id, start, end, 0, 0) - -/* Load PDB debug info for Wine PE image_map. */ -#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \ - fd, ptr, total_size, delta, 0) - -/* Map a code address to a source file name and line number. buf64 - must point to a 64-byte buffer in the caller's address space. The - result will be dumped in there and is guaranteed to be zero - terminated. If no info is found, the first byte is set to zero. */ -#define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \ - (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \ - VG_USERREQ__MAP_IP_TO_SRCLOC, \ - addr, buf64, 0, 0, 0) - -/* Disable error reporting for this thread. Behaves in a stack like - way, so you can safely call this multiple times provided that - VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times - to re-enable reporting. The first call of this macro disables - reporting. Subsequent calls have no effect except to increase the - number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable - reporting. Child threads do not inherit this setting from their - parents -- they are always created with reporting enabled. */ -#define VALGRIND_DISABLE_ERROR_REPORTING \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ - 1, 0, 0, 0, 0) - -/* Re-enable error reporting, as per comments on - VALGRIND_DISABLE_ERROR_REPORTING. */ -#define VALGRIND_ENABLE_ERROR_REPORTING \ - VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \ - -1, 0, 0, 0, 0) - -/* Execute a monitor command from the client program. - If a connection is opened with GDB, the output will be sent - according to the output mode set for vgdb. - If no connection is opened, output will go to the log output. - Returns 1 if command not recognised, 0 otherwise. */ -#define VALGRIND_MONITOR_COMMAND(command) \ - VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \ - command, 0, 0, 0, 0) - - -#undef PLAT_x86_darwin -#undef PLAT_amd64_darwin -#undef PLAT_x86_win32 -#undef PLAT_amd64_win64 -#undef PLAT_x86_linux -#undef PLAT_amd64_linux -#undef PLAT_ppc32_linux -#undef PLAT_ppc64be_linux -#undef PLAT_ppc64le_linux -#undef PLAT_arm_linux -#undef PLAT_s390x_linux -#undef PLAT_mips32_linux -#undef PLAT_mips64_linux - -#endif /* __VALGRIND_H */ diff --git a/src/libCom/yacc/ACKNOWLEDGEMENTS b/src/libCom/yacc/ACKNOWLEDGEMENTS deleted file mode 100644 index b66bb2506..000000000 --- a/src/libCom/yacc/ACKNOWLEDGEMENTS +++ /dev/null @@ -1,25 +0,0 @@ - Berkeley Yacc owes much to the unflagging efforts of Keith Bostic. -His badgering kept me working on it long after I was ready to quit. - - Berkeley Yacc is based on the excellent algorithm for computing LALR(1) -lookaheads developed by Tom Pennello and Frank DeRemer. The algorithm is -described in their almost impenetrable article in TOPLAS 4,4. - - Finally, much of the credit for the latest version must go to those -who pointed out deficiencies of my earlier releases. Among the most -prolific contributors were - - Benson I. Margulies - Dave Gentzel - Antoine Verheijen - Peter S. Housel - Dale Smith - Ozan Yigit - John Campbell - Bill Sommerfeld - Paul Hilfinger - Gary Bridgewater - Dave Bakken - Dan Lanciani - Richard Sargent - Parag Patel diff --git a/src/libCom/yacc/EPICS_READ_THIS b/src/libCom/yacc/EPICS_READ_THIS deleted file mode 100644 index c6869244a..000000000 --- a/src/libCom/yacc/EPICS_READ_THIS +++ /dev/null @@ -1,54 +0,0 @@ - -This is the source of the BSD version of yacc that is distributed in the NET2 -release of BSD Unix. We chose this over Bison due to the bison license -agreement. And if you are scratching you head over that comment, read the -addendum in the xxx-info-1 file that comes with bison. - -Anyway, this BSD-yacc has been hacked on to make it generate an all-static -parser C program so that it may be used on an IOC w/o getting things confused. -They way we intend to use it is with the epics-hacked version of flex that -also generates an all-static source program. The general idea is that -your yacc source (xxx.y) file could be formatted like this: - -========================================================= - -%% -YOUR YACC PROGRAM -%% - -int MyYaccParser(char *f1) -{ - static int FirstFlag = 1; - - printf("processing file >%s<\n", f1); - - yyin = fopen(f1, "r"); - if (!FirstFlag) yyrestart(yyin); - FirstFlag = 0; - yyparse(); - fclose(yyin); - - return(0); -} - -static int yyerror(char *str) -{ - printf("Error: %s\n", str); - return(0); -} -========================================================= - -The FirstFlag and yyrestart jazz is the flex-flavored version of how you -restart the scanner if you want to parse another file. Without it, the -scanner can only be used one time. Even if you think your code will only -be used one time, it is desireable to put in the restart stuff anyway, -because some day you (or your boss) will change your mind and without it -the IOC will crash when you make your second call to your parser. - -Note also that there is a yyerror function present. This is mandatory for the -way we are using flex. Without, results are indeterminate... because you will -end up calling some other random yyerror() in the ioc.. probably the one for -the console command interpreter. - - ---John diff --git a/src/libCom/yacc/Makefile b/src/libCom/yacc/Makefile deleted file mode 100644 index 4f2083037..000000000 --- a/src/libCom/yacc/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/yacc - -antelope_SRCS += closure.c -antelope_SRCS += error.c -antelope_SRCS += lalr.c -antelope_SRCS += lr0.c -antelope_SRCS += antelope.c -antelope_SRCS += mkpar.c -antelope_SRCS += output.c -antelope_SRCS += reader.c -antelope_SRCS += skeleton.c -antelope_SRCS += symtab.c -antelope_SRCS += verbose.c -antelope_SRCS += warshall.c -antelope_OBJS += epicsTempFile$(OBJ) - -PROD_HOST += antelope - diff --git a/src/libCom/yacc/NEW_FEATURES b/src/libCom/yacc/NEW_FEATURES deleted file mode 100644 index b030c625b..000000000 --- a/src/libCom/yacc/NEW_FEATURES +++ /dev/null @@ -1,46 +0,0 @@ - The -r option has been implemented. The -r option tells Yacc to -put the read-only tables in y.tab.c and the code and variables in -y.code.c. Keith Bostic asked for this option so that :yyfix could be -eliminated. - - The -l and -t options have been implemented. The -l option tells -Yacc not to include #line directives in the code it produces. The -t -option causes debugging code to be included in the compiled parser. - - The code for error recovery has been changed to implement the same -algorithm as AT&T Yacc. There will still be differences in the way -error recovery works because AT&T Yacc uses more default reductions -than Berkeley Yacc. - - The environment variable TMPDIR determines the directory where -temporary files will be created. If TMPDIR is defined, temporary files -will be created in the directory whose pathname is the value of TMPDIR. -By default, temporary files are created in /tmp. - - The keywords are now case-insensitive. For example, %nonassoc, -%NONASSOC, %NonAssoc, and %nOnAsSoC are all equivalent. - - Commas and semicolons that are not part of C code are treated as -commentary. - - Line-end comments, as in BCPL, are permitted. Line-end comments -begin with // and end at the next end-of-line. Line-end comments are -permitted in C code; they are converted to C comments on output. - - The form of y.output files has been changed to look more like -those produced by AT&T Yacc. - - A new kind of declaration has been added. The form of the declaration -is - - %ident string - -where string is a sequence of characters begining with a double quote -and ending with either a double quote or the next end-of-line, whichever -comes first. The declaration will cause a #ident directive to be written -near the start of the output file. - - If a parser has been compiled with debugging code, that code can be -enabled by setting an environment variable. If the environment variable -YYDEBUG is set to 0, debugging output is suppressed. If it is set to 1, -debugging output is written to standard output. diff --git a/src/libCom/yacc/NOTES b/src/libCom/yacc/NOTES deleted file mode 100644 index 9db3c96ce..000000000 --- a/src/libCom/yacc/NOTES +++ /dev/null @@ -1,9 +0,0 @@ -Berkeley Yacc reflects its origins. The reason so many routines -use exactly six register variables is that Berkeley Yacc was -developed on a VAX using PCC. PCC placed at most six variables -in registers. I went to considerable effort to find which six -variables most belonged in registers. Changes in machines and -compilers make that effort worthless, perhaps even harmful. - -The code contains many instances where address calculations are -performed in particular ways to optimize the code for the VAX. diff --git a/src/libCom/yacc/NO_WARRANTY b/src/libCom/yacc/NO_WARRANTY deleted file mode 100644 index 06e8d93a2..000000000 --- a/src/libCom/yacc/NO_WARRANTY +++ /dev/null @@ -1,3 +0,0 @@ - Berkeley Yacc is distributed with no warranty whatever. The author -and any other contributors take no responsibility for the consequences of -its use. diff --git a/src/libCom/yacc/README b/src/libCom/yacc/README deleted file mode 100644 index 091f23343..000000000 --- a/src/libCom/yacc/README +++ /dev/null @@ -1,23 +0,0 @@ - Berkeley Yacc is an LALR(1) parser generator. Berkeley Yacc has been made -as compatible as possible with AT&T Yacc. Berkeley Yacc can accept any input -specification that conforms to the AT&T Yacc documentation. Specifications -that take advantage of undocumented features of AT&T Yacc will probably be -rejected. - - Berkeley Yacc is distributed with no warranty whatever. The code is certain -to contain errors. Neither the author nor any contributor takes responsibility -for any consequences of its use. - - Berkeley Yacc is in the public domain. The data structures and algorithms -used in Berkeley Yacc are all either taken from documents available to the -general public or are inventions of the author. Anyone may freely distribute -source or binary forms of Berkeley Yacc whether unchanged or modified. -Distributers may charge whatever fees they can obtain for Berkeley Yacc. -Programs generated by Berkeley Yacc may be distributed freely. - - Please report bugs to - - robert.corbett@eng.Sun.COM - -Include a small example if possible. Please include the banner string from -skeleton.c with the bug report. Do not expect rapid responses. diff --git a/src/libCom/yacc/antelope.c b/src/libCom/yacc/antelope.c deleted file mode 100644 index 7143b38ff..000000000 --- a/src/libCom/yacc/antelope.c +++ /dev/null @@ -1,347 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include -#include "defs.h" -#define epicsExportSharedSymbols -#include "epicsTempFile.h" -#undef epicsExportSharedSymbols - -char dflag; -char lflag; -char rflag; -char tflag; -char vflag; - -char *symbol_prefix; -char *file_prefix = "y"; -char *myname = "yacc"; -char *temp_form = "yacc.XXXXXXX"; - -int lineno; -int outline; - -char *code_file_name; -char *defines_file_name; -char *input_file_name = ""; -char *output_file_name; -char *verbose_file_name; - -FILE *action_file; /* a temp file, used to save actions associated */ - /* with rules until the parser is written */ -FILE *code_file; /* y.code.c (used when the -r option is specified) */ -FILE *defines_file; /* y.tab.h */ -FILE *input_file; /* the input file */ -FILE *output_file; /* y.tab.c */ -FILE *text_file; /* a temp file, used to save text until all */ - /* symbols have been defined */ -FILE *union_file; /* a temp file, used to save the union */ - /* definition until all symbol have been */ - /* defined */ -FILE *verbose_file; /* y.output */ - -int nitems; -int nrules; -int nsyms; -int ntokens; -int nvars; - -int start_symbol; -char **symbol_name; -short *symbol_value; -short *symbol_prec; -char *symbol_assoc; - -short *ritem; -short *rlhs; -short *rrhs; -short *rprec; -char *rassoc; -short **derives; -char *nullable; - - -void -done(int k) -{ - if (action_file) { fclose(action_file); } - if (text_file) { fclose(text_file); } - if (union_file) { fclose(union_file); } - exit(k); -} - - -static void -onintr(int StupidInconsistantSignalTypes) -{ - done(1); -} - - -static void -set_signals(void) -{ -#ifdef SIGINT - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, onintr); -#endif -#ifdef SIGTERM - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) - signal(SIGTERM, onintr); -#endif -#ifdef SIGHUP - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, onintr); -#endif -} - - -static void -usage(void) -{ - fprintf(stderr, "usage: %s [-dlrtv] [-b file_prefix] [-p symbol_prefix] filename\n", myname); - exit(1); -} - - -static int -getargs(int argc, char *argv[]) -{ - int i; - char *s; - - if (argc > 0) { - myname = strrchr(argv[0], '/'); - if (myname) myname++; - else myname = argv[0]; - } - for (i = 1; i < argc; ++i) - { - s = argv[i]; - if (*s != '-') break; - switch (*++s) - { - case '\0': - input_file = stdin; - if (i + 1 < argc) usage(); - return(0); - - case '-': - ++i; - goto no_more_options; - - case 'b': - if (*++s) - file_prefix = s; - else if (++i < argc) - file_prefix = argv[i]; - else - usage(); - continue; - - case 'd': - dflag = 1; - break; - - case 'l': - lflag = 1; - break; - - case 'p': - if (*++s) - symbol_prefix = s; - else if (++i < argc) - symbol_prefix = argv[i]; - else - usage(); - continue; - - case 'r': - rflag = 1; - break; - - case 't': - tflag = 1; - break; - - case 'v': - vflag = 1; - break; - - default: - usage(); - } - - for (;;) - { - switch (*++s) - { - case '\0': - goto end_of_option; - - case 'd': - dflag = 1; - break; - - case 'l': - lflag = 1; - break; - - case 'r': - rflag = 1; - break; - - case 't': - tflag = 1; - break; - - case 'v': - vflag = 1; - break; - - default: - usage(); - } - } -end_of_option:; - } - -no_more_options:; - if (i + 1 != argc) usage(); - input_file_name = argv[i]; - - return(0); -} - - -char * -allocate(unsigned int n) -{ - char *p; - - p = NULL; - if (n) - { - p = CALLOC(1, n); - if (!p) no_space(); - } - return (p); -} - - -static void -create_file_names(void) -{ - int len; - - len = strlen(file_prefix); - - output_file_name = MALLOC(len + 7); - if (output_file_name == 0) - no_space(); - strcpy(output_file_name, file_prefix); - strcpy(output_file_name + len, OUTPUT_SUFFIX); - - if (rflag) - { - code_file_name = MALLOC(len + 8); - if (code_file_name == 0) - no_space(); - strcpy(code_file_name, file_prefix); - strcpy(code_file_name + len, CODE_SUFFIX); - } - else - code_file_name = output_file_name; - - if (dflag) - { - defines_file_name = MALLOC(len + 7); - if (defines_file_name == 0) - no_space(); - strcpy(defines_file_name, file_prefix); - strcpy(defines_file_name + len, DEFINES_SUFFIX); - } - - if (vflag) - { - verbose_file_name = MALLOC(len + 8); - if (verbose_file_name == 0) - no_space(); - strcpy(verbose_file_name, file_prefix); - strcpy(verbose_file_name + len, VERBOSE_SUFFIX); - } -} - - -static void -open_files(void) -{ - create_file_names(); - - if (input_file == 0) - { - input_file = fopen(input_file_name, "r"); - if (input_file == 0) - open_error(input_file_name); - } - - action_file = epicsTempFile(); - if (action_file == 0) - open_error("temp action file"); - - text_file = epicsTempFile(); - if (text_file == 0) - open_error("temp text file"); - - if (vflag) - { - verbose_file = fopen(verbose_file_name, "w"); - if (verbose_file == 0) - open_error(verbose_file_name); - } - - if (dflag) - { - defines_file = fopen(defines_file_name, "w"); - if (defines_file == 0) - open_error(defines_file_name); - union_file = epicsTempFile(); - if (union_file == 0) - open_error("temp union file"); - } - - output_file = fopen(output_file_name, "w"); - if (output_file == 0) - open_error(output_file_name); - - if (rflag) - { - code_file = fopen(code_file_name, "w"); - if (code_file == 0) - open_error(code_file_name); - } - else - code_file = output_file; -} - - -int -main(int argc, char *argv[]) -{ - set_signals(); - getargs(argc, argv); - open_files(); - reader(); - lr0(); - lalr(); - make_parser(); - verbose(); - output(); - done(0); - /*NOTREACHED*/ -} diff --git a/src/libCom/yacc/closure.c b/src/libCom/yacc/closure.c deleted file mode 100644 index f08c8cd92..000000000 --- a/src/libCom/yacc/closure.c +++ /dev/null @@ -1,274 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "defs.h" - -short *itemset; -short *itemsetend; -unsigned *ruleset; - -static unsigned *first_derives; -static unsigned *EFF; - -#ifdef DEBUG -static void print_closure(int n); -static void print_EFF(void); -static void print_first_derives(void); -#endif - - -static void -set_EFF(void) -{ - unsigned *row; - int symbol; - short *sp; - int rowsize; - int i; - int rule; - - rowsize = WORDSIZE(nvars); - EFF = NEW2(nvars * rowsize, unsigned); - - row = EFF; - for (i = start_symbol; i < nsyms; i++) - { - sp = derives[i]; - for (rule = *sp; rule > 0; rule = *++sp) - { - symbol = ritem[rrhs[rule]]; - if (ISVAR(symbol)) - { - symbol -= start_symbol; - SETBIT(row, symbol); - } - } - row += rowsize; - } - - reflexive_transitive_closure(EFF, nvars); - -#ifdef DEBUG - print_EFF(); -#endif -} - - -void -set_first_derives(void) -{ - unsigned *rrow; - unsigned *vrow; - int j; - unsigned k; - unsigned cword = 0; - short *rp; - - int rule; - int i; - int rulesetsize; - int varsetsize; - - rulesetsize = WORDSIZE(nrules); - varsetsize = WORDSIZE(nvars); - first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize; - - set_EFF(); - - rrow = first_derives + ntokens * rulesetsize; - for (i = start_symbol; i < nsyms; i++) - { - vrow = EFF + ((i - ntokens) * varsetsize); - k = BITS_PER_WORD; - for (j = start_symbol; j < nsyms; k++, j++) - { - if (k >= BITS_PER_WORD) - { - cword = *vrow++; - k = 0; - } - - if (cword & (1 << k)) - { - rp = derives[j]; - while ((rule = *rp++) >= 0) - { - SETBIT(rrow, rule); - } - } - } - - vrow += varsetsize; - rrow += rulesetsize; - } - -#ifdef DEBUG - print_first_derives(); -#endif - - FREE(EFF); -} - - -void -closure(short int *nucleus, int n) -{ - int ruleno; - unsigned word; - unsigned i; - short *csp; - unsigned *dsp; - unsigned *rsp; - int rulesetsize; - - short *csend; - unsigned *rsend; - int symbol; - int itemno; - - rulesetsize = WORDSIZE(nrules); - rsp = ruleset; - rsend = ruleset + rulesetsize; - for (rsp = ruleset; rsp < rsend; rsp++) - *rsp = 0; - - csend = nucleus + n; - for (csp = nucleus; csp < csend; ++csp) - { - symbol = ritem[*csp]; - if (ISVAR(symbol)) - { - dsp = first_derives + symbol * rulesetsize; - rsp = ruleset; - while (rsp < rsend) - *rsp++ |= *dsp++; - } - } - - ruleno = 0; - itemsetend = itemset; - csp = nucleus; - for (rsp = ruleset; rsp < rsend; ++rsp) - { - word = *rsp; - if (word) - { - for (i = 0; i < BITS_PER_WORD; ++i) - { - if (word & (1 << i)) - { - itemno = rrhs[ruleno+i]; - while (csp < csend && *csp < itemno) - *itemsetend++ = *csp++; - *itemsetend++ = itemno; - while (csp < csend && *csp == itemno) - ++csp; - } - } - } - ruleno += BITS_PER_WORD; - } - - while (csp < csend) - *itemsetend++ = *csp++; - -#ifdef DEBUG - print_closure(n); -#endif -} - - - -void -finalize_closure(void) -{ - FREE(itemset); - FREE(ruleset); - FREE(first_derives + ntokens * WORDSIZE(nrules)); -} - - -#ifdef DEBUG - -static void -print_closure(int n) -{ - short *isp; - - printf("\n\nn = %d\n\n", n); - for (isp = itemset; isp < itemsetend; isp++) - printf(" %d\n", *isp); -} - - -static void -print_EFF(void) -{ - int i, j; - unsigned *rowp; - unsigned word; - unsigned k; - - printf("\n\nEpsilon Free Firsts\n"); - - for (i = start_symbol; i < nsyms; i++) - { - printf("\n%s", symbol_name[i]); - rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars)); - word = *rowp++; - - k = BITS_PER_WORD; - for (j = 0; j < nvars; k++, j++) - { - if (k >= BITS_PER_WORD) - { - word = *rowp++; - k = 0; - } - - if (word & (1 << k)) - printf(" %s", symbol_name[start_symbol + j]); - } - } -} - - -static void -print_first_derives(void) -{ - int i; - int j; - unsigned *rp; - unsigned cword; - unsigned k; - - printf("\n\n\nFirst Derives\n"); - - for (i = start_symbol; i < nsyms; i++) - { - printf("\n%s derives\n", symbol_name[i]); - rp = first_derives + i * WORDSIZE(nrules); - k = BITS_PER_WORD; - for (j = 0; j <= nrules; k++, j++) - { - if (k >= BITS_PER_WORD) - { - cword = *rp++; - k = 0; - } - - if (cword & (1 << k)) - printf(" %d\n", j); - } - } - - fflush(stdout); -} - -#endif diff --git a/src/libCom/yacc/defs.h b/src/libCom/yacc/defs.h deleted file mode 100644 index 36b295fa8..000000000 --- a/src/libCom/yacc/defs.h +++ /dev/null @@ -1,367 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include -#include -#include - - -/* machine-dependent definitions */ -/* the following definitions are for the Tahoe */ -/* they might have to be changed for other machines */ - -/* MAXCHAR is the largest unsigned character value */ -/* MAXSHORT is the largest value of a C short */ -/* MINSHORT is the most negative value of a C short */ -/* MAXTABLE is the maximum table size */ -/* BITS_PER_WORD is the number of bits in a C unsigned */ -/* WORDSIZE computes the number of words needed to */ -/* store n bits */ -/* BIT returns the value of the n-th bit starting */ -/* from r (0-indexed) */ -/* SETBIT sets the n-th bit starting from r */ - -#define MAXCHAR 255 -#define MAXSHORT 32767 -#define MINSHORT -32768 -#define MAXTABLE 32500 -#define BITS_PER_WORD 32 -#define WORDSIZE(n) (((n)+(BITS_PER_WORD-1))/BITS_PER_WORD) -#define BIT(r, n) ((((r)[(n)>>5])>>((n)&31))&1) -#define SETBIT(r, n) ((r)[(n)>>5]|=((unsigned)1<<((n)&31))) - - -/* character names */ - -#define NUL '\0' /* the null character */ -#define NEWLINE '\n' /* line feed */ -#define SP ' ' /* space */ -#define BS '\b' /* backspace */ -#define HT '\t' /* horizontal tab */ -#define VT '\013' /* vertical tab */ -#define CR '\r' /* carriage return */ -#define FF '\f' /* form feed */ -#define QUOTE '\'' /* single quote */ -#define DOUBLE_QUOTE '\"' /* double quote */ -#define BACKSLASH '\\' /* backslash */ - - -/* defines for constructing filenames */ - -#define CODE_SUFFIX ".code.c" -#define DEFINES_SUFFIX ".tab.h" -#define OUTPUT_SUFFIX ".tab.c" -#define VERBOSE_SUFFIX ".output" - - -/* keyword codes */ - -#define TOKEN 0 -#define LEFT 1 -#define RIGHT 2 -#define NONASSOC 3 -#define MARK 4 -#define TEXT 5 -#define TYPE 6 -#define START 7 -#define UNION 8 -#define IDENT 9 - - -/* symbol classes */ - -#define UNKNOWN 0 -#define TERM 1 -#define NONTERM 2 - - -/* the undefined value */ - -#define UNDEFINED (-1) - - -/* action codes */ - -#define SHIFT 1 -#define REDUCE 2 - - -/* character macros */ - -#define IS_IDENT(c) (isalnum(c) || (c) == '_' || (c) == '.' || (c) == '$') -#define IS_OCTAL(c) ((c) >= '0' && (c) <= '7') -#define NUMERIC_VALUE(c) ((c) - '0') - - -/* symbol macros */ - -#define ISTOKEN(s) ((s) < start_symbol) -#define ISVAR(s) ((s) >= start_symbol) - - -/* storage allocation macros */ - -#define CALLOC(k,n) (calloc((unsigned)(k),(unsigned)(n))) -#define FREE(x) (free((char*)(x))) -#define MALLOC(n) (malloc((unsigned)(n))) -#define NEW(t) ((t*)allocate(sizeof(t))) -#define NEW2(n,t) ((t*)allocate((unsigned)((n)*sizeof(t)))) -#define REALLOC(p,n) (realloc((char*)(p),(unsigned)(n))) - - -/* the structure of a symbol table entry */ - -typedef struct bucket bucket; -struct bucket -{ - struct bucket *link; - struct bucket *next; - char *name; - char *tag; - short value; - short index; - short prec; - char class; - char assoc; -}; - - -/* the structure of the LR(0) state machine */ - -typedef struct core core; -struct core -{ - struct core *next; - struct core *link; - short number; - short accessing_symbol; - short nitems; - short items[1]; -}; - - -/* the structure used to record shifts */ - -typedef struct shifts shifts; -struct shifts -{ - struct shifts *next; - short number; - short nshifts; - short shift[1]; -}; - - -/* the structure used to store reductions */ - -typedef struct reductions reductions; -struct reductions -{ - struct reductions *next; - short number; - short nreds; - short rules[1]; -}; - - -/* the structure used to represent parser actions */ - -typedef struct action action; -struct action -{ - struct action *next; - short symbol; - short number; - short prec; - char action_code; - char assoc; - char suppressed; -}; - - -/* global variables */ - -extern char dflag; -extern char lflag; -extern char rflag; -extern char tflag; -extern char vflag; -extern char *symbol_prefix; - -extern char *myname; -extern char *cptr; -extern char *line; -extern int lineno; -extern int outline; - -extern char *banner[]; -extern char *tables[]; -extern char *header[]; -extern char *body[]; -extern char *trailer[]; - -extern char *code_file_name; -extern char *defines_file_name; -extern char *input_file_name; -extern char *output_file_name; -extern char *verbose_file_name; - -extern FILE *action_file; -extern FILE *code_file; -extern FILE *defines_file; -extern FILE *input_file; -extern FILE *output_file; -extern FILE *text_file; -extern FILE *union_file; -extern FILE *verbose_file; - -extern int nitems; -extern int nrules; -extern int nsyms; -extern int ntokens; -extern int nvars; -extern int ntags; - -extern char unionized; -extern char line_format[]; - -extern int start_symbol; -extern char **symbol_name; -extern short *symbol_value; -extern short *symbol_prec; -extern char *symbol_assoc; - -extern short *ritem; -extern short *rlhs; -extern short *rrhs; -extern short *rprec; -extern char *rassoc; - -extern short **derives; -extern char *nullable; - -extern bucket *first_symbol; -extern bucket *last_symbol; - -extern int nstates; -extern core *first_state; -extern shifts *first_shift; -extern reductions *first_reduction; -extern short *accessing_symbol; -extern core **state_table; -extern shifts **shift_table; -extern reductions **reduction_table; -extern unsigned *LA; -extern short *LAruleno; -extern short *lookaheads; -extern short *goto_map; -extern short *from_state; -extern short *to_state; - -extern action **parser; -extern int SRtotal; -extern int RRtotal; -extern short *SRconflicts; -extern short *RRconflicts; -extern short *defred; -extern short *rules_used; -extern short nunused; -extern short final_state; - -/* - * global functions - */ - -#ifdef __GNUC__ -#define NORETURN __attribute__((noreturn)) -#else -#define NORETURN -#endif - -/* main.c */ -extern void done(int k) NORETURN; -extern char *allocate(unsigned int n); - -/* error.c */ -extern void no_space(void) NORETURN; -extern void fatal(char *msg) NORETURN; -extern void open_error(char *filename) NORETURN; -extern void unexpected_EOF(void) NORETURN; -extern void syntax_error(int st_lineno, char *st_line, char *st_cptr) NORETURN; -extern void unterminated_comment(int c_lineno, char *c_line, char *c_cptr) NORETURN; -extern void unterminated_string(int s_lineno, char *s_line, char *s_cptr) NORETURN; -extern void unterminated_text(int t_lineno, char *t_line, char *t_cptr) NORETURN; -extern void unterminated_union(int u_lineno, char *u_line, char *u_cptr) NORETURN; -extern void over_unionized(char *u_cptr) NORETURN; -extern void illegal_tag(int t_lineno, char *t_line, char *t_cptr) NORETURN; -extern void illegal_character(char *c_cptr) NORETURN; -extern void used_reserved(char *s) NORETURN; -extern void tokenized_start(char *s) NORETURN; -extern void retyped_warning(char *s); -extern void reprec_warning(char *s); -extern void revalued_warning(char *s); -extern void terminal_start(char *s); -extern void restarted_warning(void); -extern void no_grammar(void) NORETURN; -extern void terminal_lhs(int s_lineno) NORETURN; -extern void prec_redeclared(void); -extern void unterminated_action(int a_lineno, char *a_line, char *a_cptr) NORETURN; -extern void dollar_warning(int a_lineno, int i); -extern void dollar_error(int a_lineno, char *a_line, char *a_cptr) NORETURN; -extern void untyped_lhs(void) NORETURN; -extern void untyped_rhs(int i, char *s) NORETURN; -extern void unknown_rhs(int i) NORETURN; -extern void default_action_warning(void); -extern void undefined_goal(char *s) NORETURN; -extern void undefined_symbol_warning(char *s); - -/* symtab.c */ -extern bucket *make_bucket(char *name); -extern bucket *lookup(char *name); -extern void create_symbol_table(void); -extern void free_symbol_table(void); -extern void free_symbols(void); - -/* closure.c */ -extern void set_first_derives(void); -extern void closure(short int *nucleus, int n); -extern void finalize_closure(void); - -/* reader.c */ -extern void reader(void); - -/* lr0.c */ -extern void lr0(void); - -/* lalr.c */ -extern void lalr(void); - -/* mkpar.c */ -extern void make_parser(void); -extern void free_parser(void); - -/* warshall.c */ -extern void reflexive_transitive_closure(unsigned int *R, int n); - -/* output.c */ -extern void output(void); -extern int default_goto(int symbol); -extern int matching_vector(int vector); -extern int pack_vector(int vector); - -/* skeleton.c */ -extern void write_section(char *section[]); - -/* verbose.c */ -extern void verbose(void); - -/* system includes */ - -#include -#include -#include diff --git a/src/libCom/yacc/error.c b/src/libCom/yacc/error.c deleted file mode 100644 index d95c92a3a..000000000 --- a/src/libCom/yacc/error.c +++ /dev/null @@ -1,314 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* routines for printing error messages */ - -#include "defs.h" - - -void -fatal(char *msg) -{ - fprintf(stderr, "%s: fatal - %s\n", myname, msg); - done(2); -} - - -void -no_space(void) -{ - fprintf(stderr, "%s: fatal - out of space\n", myname); - done(2); -} - - -void -open_error(char *filename) -{ - fprintf(stderr, "%s: fatal - cannot open \"%s\"\n", myname, filename); - done(2); -} - - -void -unexpected_EOF(void) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unexpected end-of-file\n", - myname, lineno, input_file_name); - done(1); -} - - -static int -print_pos(char *st_line, char *st_cptr) -{ - char *s; - - if (st_line == 0) return(0); - for (s = st_line; *s != '\n'; ++s) - { - if (isprint((int) *s) || *s == '\t') - putc(*s, stderr); - else - putc('?', stderr); - } - putc('\n', stderr); - for (s = st_line; s < st_cptr; ++s) - { - if (*s == '\t') - putc('\t', stderr); - else - putc(' ', stderr); - } - putc('^', stderr); - putc('\n', stderr); - return(0); -} - - -void -syntax_error(int st_lineno, char *st_line, char *st_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", syntax error\n", - myname, st_lineno, input_file_name); - print_pos(st_line, st_cptr); - done(1); -} - - -void -unterminated_comment(int c_lineno, char *c_line, char *c_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unmatched /*\n", - myname, c_lineno, input_file_name); - print_pos(c_line, c_cptr); - done(1); -} - - -void -unterminated_string(int s_lineno, char *s_line, char *s_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unterminated string\n", - myname, s_lineno, input_file_name); - print_pos(s_line, s_cptr); - done(1); -} - - -void -unterminated_text(int t_lineno, char *t_line, char *t_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unmatched %%{\n", - myname, t_lineno, input_file_name); - print_pos(t_line, t_cptr); - done(1); -} - - -void -unterminated_union(int u_lineno, char *u_line, char *u_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unterminated %%union \ -declaration\n", myname, u_lineno, input_file_name); - print_pos(u_line, u_cptr); - done(1); -} - - -void -over_unionized(char *u_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", too many %%union \ -declarations\n", myname, lineno, input_file_name); - print_pos(line, u_cptr); - done(1); -} - - -void -illegal_tag(int t_lineno, char *t_line, char *t_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", illegal tag\n", - myname, t_lineno, input_file_name); - print_pos(t_line, t_cptr); - done(1); -} - - -void -illegal_character(char *c_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", illegal character\n", - myname, lineno, input_file_name); - print_pos(line, c_cptr); - done(1); -} - - -void -used_reserved(char *s) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", illegal use of reserved symbol \ -%s\n", myname, lineno, input_file_name, s); - done(1); -} - - -void -tokenized_start(char *s) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", the start symbol %s cannot be \ -declared to be a token\n", myname, lineno, input_file_name, s); - done(1); -} - - -void -retyped_warning(char *s) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the type of %s has been \ -redeclared\n", myname, lineno, input_file_name, s); -} - - -void -reprec_warning(char *s) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the precedence of %s has been \ -redeclared\n", myname, lineno, input_file_name, s); -} - - -void -revalued_warning(char *s) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the value of %s has been \ -redeclared\n", myname, lineno, input_file_name, s); -} - - -void -terminal_start(char *s) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", the start symbol %s is a \ -token\n", myname, lineno, input_file_name, s); - done(1); -} - - -void -restarted_warning(void) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the start symbol has been \ -redeclared\n", myname, lineno, input_file_name); -} - - -void -no_grammar(void) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", no grammar has been \ -specified\n", myname, lineno, input_file_name); - done(1); -} - - -void -terminal_lhs(int s_lineno) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", a token appears on the lhs \ -of a production\n", myname, s_lineno, input_file_name); - done(1); -} - - -void -prec_redeclared(void) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", conflicting %%prec \ -specifiers\n", myname, lineno, input_file_name); -} - - -void -unterminated_action(int a_lineno, char *a_line, char *a_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", unterminated action\n", - myname, a_lineno, input_file_name); - print_pos(a_line, a_cptr); - done(1); -} - - -void -dollar_warning(int a_lineno, int i) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", $%d references beyond the \ -end of the current rule\n", myname, a_lineno, input_file_name, i); -} - - -void -dollar_error(int a_lineno, char *a_line, char *a_cptr) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", illegal $-name\n", - myname, a_lineno, input_file_name); - print_pos(a_line, a_cptr); - done(1); -} - - -void -untyped_lhs(void) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", $$ is untyped\n", - myname, lineno, input_file_name); - done(1); -} - - -void -untyped_rhs(int i, char *s) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", $%d (%s) is untyped\n", - myname, lineno, input_file_name, i, s); - done(1); -} - - -void -unknown_rhs(int i) -{ - fprintf(stderr, "%s: error - line %d of \"%s\", $%d is untyped\n", - myname, lineno, input_file_name, i); - done(1); -} - - -void -default_action_warning(void) -{ - fprintf(stderr, "%s: warning - line %d of \"%s\", the default action assigns an \ -undefined value to $$\n", myname, lineno, input_file_name); -} - - -void -undefined_goal(char *s) -{ - fprintf(stderr, "%s: error - the start symbol %s is undefined\n", myname, s); - done(1); -} - - -void -undefined_symbol_warning(char *s) -{ - fprintf(stderr, "%s: warning - the symbol %s is undefined\n", myname, s); -} diff --git a/src/libCom/yacc/lalr.c b/src/libCom/yacc/lalr.c deleted file mode 100644 index 1c8850f60..000000000 --- a/src/libCom/yacc/lalr.c +++ /dev/null @@ -1,668 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -typedef - struct shorts - { - struct shorts *next; - short value; - } - shorts; - -int tokensetsize; -short *lookaheads; -short *LAruleno; -unsigned *LA; -short *accessing_symbol; -core **state_table; -shifts **shift_table; -reductions **reduction_table; -short *goto_map; -short *from_state; -short *to_state; - -static void set_state_table(void); -static void set_accessing_symbol(void); -static void set_shift_table(void); -static void set_reduction_table(void); -static void set_maxrhs(void); -static void initialize_LA(void); -static void set_goto_map(void); -static void initialize_F(void); -static void build_relations(void); -static void add_lookback_edge(int stateno, int ruleno, int gotono); -static short **transpose(short int **R, int n); -static void compute_FOLLOWS(void); -static void compute_lookaheads(void); -static void digraph(short **relation); -static void traverse(int i); - -static int infinity; -static int maxrhs; -static int ngotos; -static unsigned *F; -static short **includes; -static shorts **lookback; -static short **R; -static short *INDEX; -static short *VERTICES; -static int top; - - -void -lalr(void) -{ - tokensetsize = WORDSIZE(ntokens); - - set_state_table(); - set_accessing_symbol(); - set_shift_table(); - set_reduction_table(); - set_maxrhs(); - initialize_LA(); - set_goto_map(); - initialize_F(); - build_relations(); - compute_FOLLOWS(); - compute_lookaheads(); -} - - - -static void -set_state_table(void) -{ - core *sp; - - state_table = NEW2(nstates, core *); - for (sp = first_state; sp; sp = sp->next) - state_table[sp->number] = sp; -} - - - -static void -set_accessing_symbol(void) -{ - core *sp; - - accessing_symbol = NEW2(nstates, short); - for (sp = first_state; sp; sp = sp->next) - accessing_symbol[sp->number] = sp->accessing_symbol; -} - - - -static void -set_shift_table(void) -{ - shifts *sp; - - shift_table = NEW2(nstates, shifts *); - for (sp = first_shift; sp; sp = sp->next) - shift_table[sp->number] = sp; -} - - - -static void -set_reduction_table(void) -{ - reductions *rp; - - reduction_table = NEW2(nstates, reductions *); - for (rp = first_reduction; rp; rp = rp->next) - reduction_table[rp->number] = rp; -} - - - -static void -set_maxrhs(void) -{ - short *itemp; - short *item_end; - int length; - int max; - - length = 0; - max = 0; - item_end = ritem + nitems; - for (itemp = ritem; itemp < item_end; itemp++) - { - if (*itemp >= 0) - { - length++; - } - else - { - if (length > max) max = length; - length = 0; - } - } - - maxrhs = max; -} - - - -static void -initialize_LA(void) -{ - int i, j, k; - reductions *rp; - - lookaheads = NEW2(nstates + 1, short); - - k = 0; - for (i = 0; i < nstates; i++) - { - lookaheads[i] = k; - rp = reduction_table[i]; - if (rp) - k += rp->nreds; - } - lookaheads[nstates] = k; - - LA = NEW2(k * tokensetsize, unsigned); - LAruleno = NEW2(k, short); - lookback = NEW2(k, shorts *); - - k = 0; - for (i = 0; i < nstates; i++) - { - rp = reduction_table[i]; - if (rp) - { - for (j = 0; j < rp->nreds; j++) - { - LAruleno[k] = rp->rules[j]; - k++; - } - } - } -} - - -static void -set_goto_map(void) -{ - shifts *sp; - int i; - int symbol; - int k; - short *temp_map; - int state2; - int state1; - - goto_map = NEW2(nvars + 1, short) - ntokens; - temp_map = NEW2(nvars + 1, short) - ntokens; - - ngotos = 0; - for (sp = first_shift; sp; sp = sp->next) - { - for (i = sp->nshifts - 1; i >= 0; i--) - { - symbol = accessing_symbol[sp->shift[i]]; - - if (ISTOKEN(symbol)) break; - - if (ngotos == MAXSHORT) - fatal("too many gotos"); - - ngotos++; - goto_map[symbol]++; - } - } - - k = 0; - for (i = ntokens; i < nsyms; i++) - { - temp_map[i] = k; - k += goto_map[i]; - } - - for (i = ntokens; i < nsyms; i++) - goto_map[i] = temp_map[i]; - - goto_map[nsyms] = ngotos; - temp_map[nsyms] = ngotos; - - from_state = NEW2(ngotos, short); - to_state = NEW2(ngotos, short); - - for (sp = first_shift; sp; sp = sp->next) - { - state1 = sp->number; - for (i = sp->nshifts - 1; i >= 0; i--) - { - state2 = sp->shift[i]; - symbol = accessing_symbol[state2]; - - if (ISTOKEN(symbol)) break; - - k = temp_map[symbol]++; - from_state[k] = state1; - to_state[k] = state2; - } - } - - FREE(temp_map + ntokens); -} - - - -/* Map_goto maps a state/symbol pair into its numeric representation. */ - -int -map_goto(int state, int symbol) -{ - int high; - int low; - int middle; - int s; - - low = goto_map[symbol]; - high = goto_map[symbol + 1]; - - for (;;) - { - assert(low <= high); - middle = (low + high) >> 1; - s = from_state[middle]; - if (s == state) - return (middle); - else if (s < state) - low = middle + 1; - else - high = middle - 1; - } -} - - - -static void -initialize_F(void) -{ - int i; - int j; - int k; - shifts *sp; - short *edge; - unsigned *rowp; - short *rp; - short **reads; - int nedges; - int stateno; - int symbol; - int nwords; - - nwords = ngotos * tokensetsize; - F = NEW2(nwords, unsigned); - - reads = NEW2(ngotos, short *); - edge = NEW2(ngotos + 1, short); - nedges = 0; - - rowp = F; - for (i = 0; i < ngotos; i++) - { - stateno = to_state[i]; - sp = shift_table[stateno]; - - if (sp) - { - k = sp->nshifts; - - for (j = 0; j < k; j++) - { - symbol = accessing_symbol[sp->shift[j]]; - if (ISVAR(symbol)) - break; - SETBIT(rowp, symbol); - } - - for (; j < k; j++) - { - symbol = accessing_symbol[sp->shift[j]]; - if (nullable[symbol]) - edge[nedges++] = map_goto(stateno, symbol); - } - - if (nedges) - { - reads[i] = rp = NEW2(nedges + 1, short); - - for (j = 0; j < nedges; j++) - rp[j] = edge[j]; - - rp[nedges] = -1; - nedges = 0; - } - } - - rowp += tokensetsize; - } - - SETBIT(F, 0); - digraph(reads); - - for (i = 0; i < ngotos; i++) - { - if (reads[i]) - FREE(reads[i]); - } - - FREE(reads); - FREE(edge); -} - - - -static void -build_relations(void) -{ - int i; - int j; - int k; - short *rulep; - short *rp; - shifts *sp; - int length; - int nedges; - int done; - int state1; - int stateno; - int symbol1; - int symbol2; - short *shortp; - short *edge; - short *states; - short **new_includes; - - includes = NEW2(ngotos, short *); - edge = NEW2(ngotos + 1, short); - states = NEW2(maxrhs + 1, short); - - for (i = 0; i < ngotos; i++) - { - nedges = 0; - state1 = from_state[i]; - symbol1 = accessing_symbol[to_state[i]]; - - for (rulep = derives[symbol1]; *rulep >= 0; rulep++) - { - length = 1; - states[0] = state1; - stateno = state1; - - for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++) - { - symbol2 = *rp; - sp = shift_table[stateno]; - k = sp->nshifts; - - for (j = 0; j < k; j++) - { - stateno = sp->shift[j]; - if (accessing_symbol[stateno] == symbol2) break; - } - - states[length++] = stateno; - } - - add_lookback_edge(stateno, *rulep, i); - - length--; - done = 0; - while (!done) - { - done = 1; - rp--; - if (ISVAR(*rp)) - { - stateno = states[--length]; - edge[nedges++] = map_goto(stateno, *rp); - if (nullable[*rp] && length > 0) done = 0; - } - } - } - - if (nedges) - { - includes[i] = shortp = NEW2(nedges + 1, short); - for (j = 0; j < nedges; j++) - shortp[j] = edge[j]; - shortp[nedges] = -1; - } - } - - new_includes = transpose(includes, ngotos); - - for (i = 0; i < ngotos; i++) - if (includes[i]) - FREE(includes[i]); - - FREE(includes); - - includes = new_includes; - - FREE(edge); - FREE(states); -} - - -static void -add_lookback_edge(int stateno, int ruleno, int gotono) -{ - int i, k; - int found; - shorts *sp; - - i = lookaheads[stateno]; - k = lookaheads[stateno + 1]; - found = 0; - while (!found && i < k) - { - if (LAruleno[i] == ruleno) - found = 1; - else - ++i; - } - assert(found); - - sp = NEW(shorts); - sp->next = lookback[i]; - sp->value = gotono; - lookback[i] = sp; -} - - - -short ** -transpose(short int **R, int n) -{ - short **new_R; - short **temp_R; - short *nedges; - short *sp; - int i; - int k; - - nedges = NEW2(n, short); - - for (i = 0; i < n; i++) - { - sp = R[i]; - if (sp) - { - while (*sp >= 0) - nedges[*sp++]++; - } - } - - new_R = NEW2(n, short *); - temp_R = NEW2(n, short *); - - for (i = 0; i < n; i++) - { - k = nedges[i]; - if (k > 0) - { - sp = NEW2(k + 1, short); - new_R[i] = sp; - temp_R[i] = sp; - sp[k] = -1; - } - } - - FREE(nedges); - - for (i = 0; i < n; i++) - { - sp = R[i]; - if (sp) - { - while (*sp >= 0) - *temp_R[*sp++]++ = i; - } - } - - FREE(temp_R); - - return (new_R); -} - - - -static void -compute_FOLLOWS(void) -{ - digraph(includes); -} - - -static void -compute_lookaheads(void) -{ - int i, n; - unsigned *fp1, *fp2, *fp3; - shorts *sp, *next; - unsigned *rowp; - - rowp = LA; - n = lookaheads[nstates]; - for (i = 0; i < n; i++) - { - fp3 = rowp + tokensetsize; - for (sp = lookback[i]; sp; sp = sp->next) - { - fp1 = rowp; - fp2 = F + tokensetsize * sp->value; - while (fp1 < fp3) - *fp1++ |= *fp2++; - } - rowp = fp3; - } - - for (i = 0; i < n; i++) - for (sp = lookback[i]; sp; sp = next) - { - next = sp->next; - FREE(sp); - } - - FREE(lookback); - FREE(F); -} - - -static void -digraph(short **relation) -{ - int i; - - infinity = ngotos + 2; - INDEX = NEW2(ngotos + 1, short); - VERTICES = NEW2(ngotos + 1, short); - top = 0; - - R = relation; - - for (i = 0; i < ngotos; i++) - INDEX[i] = 0; - - for (i = 0; i < ngotos; i++) - { - if (INDEX[i] == 0 && R[i]) - traverse(i); - } - - FREE(INDEX); - FREE(VERTICES); -} - - - -static void -traverse(int i) -{ - unsigned *fp1; - unsigned *fp2; - unsigned *fp3; - int j; - short *rp; - - int height; - unsigned *base; - - VERTICES[++top] = i; - INDEX[i] = height = top; - - base = F + i * tokensetsize; - fp3 = base + tokensetsize; - - rp = R[i]; - if (rp) - { - while ((j = *rp++) >= 0) - { - if (INDEX[j] == 0) - traverse(j); - - if (INDEX[i] > INDEX[j]) - INDEX[i] = INDEX[j]; - - fp1 = base; - fp2 = F + j * tokensetsize; - - while (fp1 < fp3) - *fp1++ |= *fp2++; - } - } - - if (INDEX[i] == height) - { - for (;;) - { - j = VERTICES[top--]; - INDEX[j] = infinity; - - if (i == j) - break; - - fp1 = base; - fp2 = F + j * tokensetsize; - - while (fp1 < fp3) - *fp2++ = *fp1++; - } - } -} diff --git a/src/libCom/yacc/lr0.c b/src/libCom/yacc/lr0.c deleted file mode 100644 index 23b950930..000000000 --- a/src/libCom/yacc/lr0.c +++ /dev/null @@ -1,613 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "defs.h" - -extern short *itemset; -extern short *itemsetend; -extern unsigned *ruleset; - -int nstates; -core *first_state; -shifts *first_shift; -reductions *first_reduction; - -static core **state_set; -static core *this_state; -static core *last_state; -static shifts *last_shift; -static reductions *last_reduction; - -static int nshifts; -static short *shift_symbol; - -static short *redset; -static short *shiftset; - -static short **kernel_base; -static short **kernel_end; -static short *kernel_items; - -static int get_state(int symbol); -static void initialize_states(void); -static void new_itemsets(void); -static core *new_state(int symbol); -static void save_shifts(void); -static void save_reductions(void); -#ifdef DEBUG -static void print_derives(void); -#endif - - -static void -allocate_itemsets(void) -{ - short *itemp; - short *item_end; - int symbol; - int i; - int count; - int max; - short *symbol_count; - - count = 0; - symbol_count = NEW2(nsyms, short); - - item_end = ritem + nitems; - for (itemp = ritem; itemp < item_end; itemp++) - { - symbol = *itemp; - if (symbol >= 0) - { - count++; - symbol_count[symbol]++; - } - } - - kernel_base = NEW2(nsyms, short *); - kernel_items = NEW2(count, short); - - count = 0; - max = 0; - for (i = 0; i < nsyms; i++) - { - kernel_base[i] = kernel_items + count; - count += symbol_count[i]; - if (max < symbol_count[i]) - max = symbol_count[i]; - } - - shift_symbol = symbol_count; - kernel_end = NEW2(nsyms, short *); -} - -static void -allocate_storage(void) -{ - allocate_itemsets(); - shiftset = NEW2(nsyms, short); - redset = NEW2(nrules + 1, short); - state_set = NEW2(nitems, core *); -} - -static void -append_states(void) -{ - int i; - int j; - int symbol; - -#ifdef TRACE - fprintf(stderr, "Entering append_states()\n"); -#endif - for (i = 1; i < nshifts; i++) - { - symbol = shift_symbol[i]; - j = i; - while (j > 0 && shift_symbol[j - 1] > symbol) - { - shift_symbol[j] = shift_symbol[j - 1]; - j--; - } - shift_symbol[j] = symbol; - } - - for (i = 0; i < nshifts; i++) - { - symbol = shift_symbol[i]; - shiftset[i] = get_state(symbol); - } -} - -static void -free_storage(void) -{ - FREE(shift_symbol); - FREE(redset); - FREE(shiftset); - FREE(kernel_base); - FREE(kernel_end); - FREE(kernel_items); - FREE(state_set); -} - - -static void -generate_states(void) -{ - allocate_storage(); - itemset = NEW2(nitems, short); - ruleset = NEW2(WORDSIZE(nrules), unsigned); - set_first_derives(); - initialize_states(); - - while (this_state) - { - closure(this_state->items, this_state->nitems); - save_reductions(); - new_itemsets(); - append_states(); - - if (nshifts > 0) - save_shifts(); - - this_state = this_state->next; - } - - finalize_closure(); - free_storage(); -} - - - -static int -get_state(int symbol) -{ - int key; - short *isp1; - short *isp2; - short *iend; - core *sp; - int found; - int n; - -#ifdef TRACE - fprintf(stderr, "Entering get_state(%d)\n", symbol); -#endif - - isp1 = kernel_base[symbol]; - iend = kernel_end[symbol]; - n = iend - isp1; - - key = *isp1; - assert(0 <= key && key < nitems); - sp = state_set[key]; - if (sp) - { - found = 0; - while (!found) - { - if (sp->nitems == n) - { - found = 1; - isp1 = kernel_base[symbol]; - isp2 = sp->items; - - while (found && isp1 < iend) - { - if (*isp1++ != *isp2++) - found = 0; - } - } - - if (!found) - { - if (sp->link) - { - sp = sp->link; - } - else - { - sp = sp->link = new_state(symbol); - found = 1; - } - } - } - } - else - { - state_set[key] = sp = new_state(symbol); - } - - return (sp->number); -} - - -static void -initialize_states(void) -{ - int i; - short *start_derives; - core *p; - - start_derives = derives[start_symbol]; - for (i = 0; start_derives[i] >= 0; ++i) - continue; - - p = (core *) MALLOC(sizeof(core) + i*sizeof(short)); - if (p == 0) no_space(); - - p->next = 0; - p->link = 0; - p->number = 0; - p->accessing_symbol = 0; - p->nitems = i; - - for (i = 0; start_derives[i] >= 0; ++i) - p->items[i] = rrhs[start_derives[i]]; - - first_state = last_state = this_state = p; - nstates = 1; -} - -static void -new_itemsets(void) -{ - int i; - int shiftcount; - short *isp; - short *ksp; - int symbol; - - for (i = 0; i < nsyms; i++) - kernel_end[i] = 0; - - shiftcount = 0; - isp = itemset; - while (isp < itemsetend) - { - i = *isp++; - symbol = ritem[i]; - if (symbol > 0) - { - ksp = kernel_end[symbol]; - if (!ksp) - { - shift_symbol[shiftcount++] = symbol; - ksp = kernel_base[symbol]; - } - - *ksp++ = i + 1; - kernel_end[symbol] = ksp; - } - } - - nshifts = shiftcount; -} - - - -static core * -new_state(int symbol) -{ - int n; - core *p; - short *isp1; - short *isp2; - short *iend; - -#ifdef TRACE - fprintf(stderr, "Entering new_state(%d)\n", symbol); -#endif - - if (nstates >= MAXSHORT) - fatal("too many states"); - - isp1 = kernel_base[symbol]; - iend = kernel_end[symbol]; - n = iend - isp1; - - p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short))); - p->accessing_symbol = symbol; - p->number = nstates; - p->nitems = n; - - isp2 = p->items; - while (isp1 < iend) - *isp2++ = *isp1++; - - last_state->next = p; - last_state = p; - - nstates++; - - return (p); -} - - -#ifdef DEBUG -static void -show_cores(void) -{ - core *p; - int i, j, k, n; - int itemno; - - k = 0; - for (p = first_state; p; ++k, p = p->next) - { - if (k) printf("\n"); - printf("state %d, number = %d, accessing symbol = %s\n", - k, p->number, symbol_name[p->accessing_symbol]); - n = p->nitems; - for (i = 0; i < n; ++i) - { - itemno = p->items[i]; - printf("%4d ", itemno); - j = itemno; - while (ritem[j] >= 0) ++j; - printf("%s :", symbol_name[rlhs[-ritem[j]]]); - j = rrhs[-ritem[j]]; - while (j < itemno) - printf(" %s", symbol_name[ritem[j++]]); - printf(" ."); - while (ritem[j] >= 0) - printf(" %s", symbol_name[ritem[j++]]); - printf("\n"); - fflush(stdout); - } - } -} - - -static void -show_ritems(void) -{ - int i; - - for (i = 0; i < nitems; ++i) - printf("ritem[%d] = %d\n", i, ritem[i]); -} - - -static void -show_rrhs(void) -{ - int i; - - for (i = 0; i < nrules; ++i) - printf("rrhs[%d] = %d\n", i, rrhs[i]); -} - - -static void -show_shifts(void) -{ - shifts *p; - int i, j, k; - - k = 0; - for (p = first_shift; p; ++k, p = p->next) - { - if (k) printf("\n"); - printf("shift %d, number = %d, nshifts = %d\n", k, p->number, - p->nshifts); - j = p->nshifts; - for (i = 0; i < j; ++i) - printf("\t%d\n", p->shift[i]); - } -} -#endif - -static void -save_shifts(void) -{ - shifts *p; - short *sp1; - short *sp2; - short *send; - - p = (shifts *) allocate((unsigned) (sizeof(shifts) + - (nshifts - 1) * sizeof(short))); - - p->number = this_state->number; - p->nshifts = nshifts; - - sp1 = shiftset; - sp2 = p->shift; - send = shiftset + nshifts; - - while (sp1 < send) - *sp2++ = *sp1++; - - if (last_shift) - { - last_shift->next = p; - last_shift = p; - } - else - { - first_shift = p; - last_shift = p; - } -} - - -static void -save_reductions(void) -{ - short *isp; - short *rp1; - short *rp2; - int item; - int count; - reductions *p; - short *rend; - - count = 0; - for (isp = itemset; isp < itemsetend; isp++) - { - item = ritem[*isp]; - if (item < 0) - { - redset[count++] = -item; - } - } - - if (count) - { - p = (reductions *) allocate((unsigned) (sizeof(reductions) + - (count - 1) * sizeof(short))); - - p->number = this_state->number; - p->nreds = count; - - rp1 = redset; - rp2 = p->rules; - rend = rp1 + count; - - while (rp1 < rend) - *rp2++ = *rp1++; - - if (last_reduction) - { - last_reduction->next = p; - last_reduction = p; - } - else - { - first_reduction = p; - last_reduction = p; - } - } -} - -static void -set_derives(void) -{ - int i, k; - int lhs; - short *rules; - - derives = NEW2(nsyms, short *); - rules = NEW2(nvars + nrules, short); - - k = 0; - for (lhs = start_symbol; lhs < nsyms; lhs++) - { - derives[lhs] = rules + k; - for (i = 0; i < nrules; i++) - { - if (rlhs[i] == lhs) - { - rules[k] = i; - k++; - } - } - rules[k] = -1; - k++; - } - -#ifdef DEBUG - print_derives(); -#endif -} - -void -free_derives(void) -{ - FREE(derives[start_symbol]); - FREE(derives); -} - -#ifdef DEBUG -static void -print_derives(void) -{ - int i; - short *sp; - - printf("\nDERIVES\n\n"); - - for (i = start_symbol; i < nsyms; i++) - { - printf("%s derives ", symbol_name[i]); - for (sp = derives[i]; *sp >= 0; sp++) - { - printf(" %d", *sp); - } - putchar('\n'); - } - - putchar('\n'); -} -#endif - -static void -set_nullable(void) -{ - int i, j; - int empty; - int done; - - nullable = MALLOC(nsyms); - if (nullable == 0) no_space(); - - for (i = 0; i < nsyms; ++i) - nullable[i] = 0; - - done = 0; - while (!done) - { - done = 1; - for (i = 1; i < nitems; i++) - { - empty = 1; - while ((j = ritem[i]) >= 0) - { - if (!nullable[j]) - empty = 0; - ++i; - } - if (empty) - { - j = rlhs[-j]; - if (!nullable[j]) - { - nullable[j] = 1; - done = 0; - } - } - } - } - -#ifdef DEBUG - for (i = 0; i < nsyms; i++) - { - if (nullable[i]) - printf("%s is nullable\n", symbol_name[i]); - else - printf("%s is not nullable\n", symbol_name[i]); - } -#endif -} - -void -free_nullable(void) -{ - FREE(nullable); -} - -void -lr0(void) -{ - set_derives(); - set_nullable(); - generate_states(); -} diff --git a/src/libCom/yacc/mkpar.c b/src/libCom/yacc/mkpar.c deleted file mode 100644 index 5385f0e00..000000000 --- a/src/libCom/yacc/mkpar.c +++ /dev/null @@ -1,372 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "defs.h" - -action **parser; -int SRtotal; -int RRtotal; -short *SRconflicts; -short *RRconflicts; -short *defred; -short *rules_used; -short nunused; -short final_state; - -static int SRcount; -static int RRcount; - - -static action *parse_actions(int stateno); -static action *get_shifts(int stateno); -static action *add_reductions(int stateno, action *actions); -static action *add_reduce(action *actions, int ruleno, int symbol); -static void find_final_state(void); -static void unused_rules(void); -static void remove_conflicts(void); -static void total_conflicts(void); -static void defreds(void); - -void -make_parser(void) -{ - int i; - - parser = NEW2(nstates, action *); - for (i = 0; i < nstates; i++) - parser[i] = parse_actions(i); - - find_final_state(); - remove_conflicts(); - unused_rules(); - if (SRtotal + RRtotal > 0) total_conflicts(); - defreds(); -} - - -static action * -parse_actions(int stateno) -{ - action *actions; - - actions = get_shifts(stateno); - actions = add_reductions(stateno, actions); - return (actions); -} - - -static action * -get_shifts(int stateno) -{ - action *actions, *temp; - shifts *sp; - short *to_state; - int i, k; - int symbol; - - actions = 0; - sp = shift_table[stateno]; - if (sp) - { - to_state = sp->shift; - for (i = sp->nshifts - 1; i >= 0; i--) - { - k = to_state[i]; - symbol = accessing_symbol[k]; - if (ISTOKEN(symbol)) - { - temp = NEW(action); - temp->next = actions; - temp->symbol = symbol; - temp->number = k; - temp->prec = symbol_prec[symbol]; - temp->action_code = SHIFT; - temp->assoc = symbol_assoc[symbol]; - actions = temp; - } - } - } - return (actions); -} - -static action * -add_reductions(int stateno, action *actions) -{ - int i, j, m, n; - int ruleno, tokensetsize; - unsigned *rowp; - - tokensetsize = WORDSIZE(ntokens); - m = lookaheads[stateno]; - n = lookaheads[stateno + 1]; - for (i = m; i < n; i++) - { - ruleno = LAruleno[i]; - rowp = LA + i * tokensetsize; - for (j = ntokens - 1; j >= 0; j--) - { - if (BIT(rowp, j)) - actions = add_reduce(actions, ruleno, j); - } - } - return (actions); -} - - -static action * -add_reduce(action *actions, int ruleno, int symbol) -{ - action *temp, *prev, *next; - - prev = 0; - for (next = actions; next && next->symbol < symbol; next = next->next) - prev = next; - - while (next && next->symbol == symbol && next->action_code == SHIFT) - { - prev = next; - next = next->next; - } - - while (next && next->symbol == symbol && - next->action_code == REDUCE && next->number < ruleno) - { - prev = next; - next = next->next; - } - - temp = NEW(action); - temp->next = next; - temp->symbol = symbol; - temp->number = ruleno; - temp->prec = rprec[ruleno]; - temp->action_code = REDUCE; - temp->assoc = rassoc[ruleno]; - - if (prev) - prev->next = temp; - else - actions = temp; - - return (actions); -} - - -static void -find_final_state(void) -{ - int goal, i; - short *to_state; - shifts *p; - - p = shift_table[0]; - to_state = p->shift; - goal = ritem[1]; - for (i = p->nshifts - 1; i >= 0; --i) - { - final_state = to_state[i]; - if (accessing_symbol[final_state] == goal) break; - } -} - - -static void -unused_rules(void) -{ - int i; - action *p; - - rules_used = (short *) MALLOC(nrules*sizeof(short)); - if (rules_used == 0) no_space(); - - for (i = 0; i < nrules; ++i) - rules_used[i] = 0; - - for (i = 0; i < nstates; ++i) - { - for (p = parser[i]; p; p = p->next) - { - if (p->action_code == REDUCE && p->suppressed == 0) - rules_used[p->number] = 1; - } - } - - nunused = 0; - for (i = 3; i < nrules; ++i) - if (!rules_used[i]) ++nunused; - - if (nunused) - { - if (nunused == 1) - fprintf(stderr, "%s: 1 rule never reduced\n", myname); - else - fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused); - } -} - - -static void -remove_conflicts(void) -{ - int i; - int symbol; - action *p, *pref = NULL; - - SRtotal = 0; - RRtotal = 0; - SRconflicts = NEW2(nstates, short); - RRconflicts = NEW2(nstates, short); - for (i = 0; i < nstates; i++) - { - SRcount = 0; - RRcount = 0; - symbol = -1; - for (p = parser[i]; p; p = p->next) - { - if (p->symbol != symbol) - { - pref = p; - symbol = p->symbol; - } - else if (i == final_state && symbol == 0) - { - SRcount++; - p->suppressed = 1; - } - else if (pref && pref->action_code == SHIFT) - { - if (pref->prec > 0 && p->prec > 0) - { - if (pref->prec < p->prec) - { - pref->suppressed = 2; - pref = p; - } - else if (pref->prec > p->prec) - { - p->suppressed = 2; - } - else if (pref->assoc == LEFT) - { - pref->suppressed = 2; - pref = p; - } - else if (pref->assoc == RIGHT) - { - p->suppressed = 2; - } - else - { - pref->suppressed = 2; - p->suppressed = 2; - } - } - else - { - SRcount++; - p->suppressed = 1; - } - } - else - { - RRcount++; - p->suppressed = 1; - } - } - SRtotal += SRcount; - RRtotal += RRcount; - SRconflicts[i] = SRcount; - RRconflicts[i] = RRcount; - } -} - - -static void -total_conflicts(void) -{ - fprintf(stderr, "%s: ", myname); - if (SRtotal == 1) - fprintf(stderr, "1 shift/reduce conflict"); - else if (SRtotal > 1) - fprintf(stderr, "%d shift/reduce conflicts", SRtotal); - - if (SRtotal && RRtotal) - fprintf(stderr, ", "); - - if (RRtotal == 1) - fprintf(stderr, "1 reduce/reduce conflict"); - else if (RRtotal > 1) - fprintf(stderr, "%d reduce/reduce conflicts", RRtotal); - - fprintf(stderr, ".\n"); -} - - -static int -sole_reduction(int stateno) -{ - int count, ruleno; - action *p; - - count = 0; - ruleno = 0; - for (p = parser[stateno]; p; p = p->next) - { - if (p->action_code == SHIFT && p->suppressed == 0) - return 0; - else if (p->action_code == REDUCE && p->suppressed == 0) - { - if (ruleno > 0 && p->number != ruleno) - return 0; - if (p->symbol != 1) - ++count; - ruleno = p->number; - } - } - - if (count == 0) - return 0; - return ruleno; -} - - -static void -defreds(void) -{ - int i; - - defred = NEW2(nstates, short); - for (i = 0; i < nstates; i++) - defred[i] = sole_reduction(i); -} - -static void -free_action_row(action *p) -{ - action *q; - - while (p) - { - q = p->next; - FREE(p); - p = q; - } -} - -void -free_parser(void) -{ - int i; - - for (i = 0; i < nstates; i++) - free_action_row(parser[i]); - - FREE(parser); -} - diff --git a/src/libCom/yacc/output.c b/src/libCom/yacc/output.c deleted file mode 100644 index a1913ed77..000000000 --- a/src/libCom/yacc/output.c +++ /dev/null @@ -1,1247 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -static int nvectors; -static int nentries; -static short **froms; -static short **tos; -static short *tally; -static short *width; -static short *state_count; -static short *order; -static short *base; -static short *pos; -static int maxtable; -static short *table; -static short *check; -static int lowzero; -static int high; - -static void output_prefix(void); -static void output_rule_data(void); -static void output_yydefred(void); -static void output_actions(void); -static void token_actions(void); -static void goto_actions(void); -static void save_column(int symbol, int default_state); -static void sort_actions(void); -static void pack_table(void); -static void output_base(void); -static void output_table(void); -static void output_check(void); -static void output_defines(void); -static void output_stored_text(void); -static void output_debug(void); -static void output_stype(void); -static void output_trailing_text(void); -static void output_semantic_actions(void); -static void free_itemsets(void); -static void free_shifts(void); -static void free_reductions(void); - - -void -output(void) -{ - free_itemsets(); - free_shifts(); - free_reductions(); - output_prefix(); - output_stored_text(); - output_defines(); - output_rule_data(); - output_yydefred(); - output_actions(); - free_parser(); - output_debug(); - output_stype(); - if (rflag) write_section(tables); - write_section(header); - output_trailing_text(); - write_section(body); - output_semantic_actions(); - write_section(trailer); -} - - -static void -output_prefix(void) -{ - if (symbol_prefix == NULL) - symbol_prefix = "yy"; - else - { - ++outline; - fprintf(code_file, "#define yyparse %sparse\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yylex %slex\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyerror %serror\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yychar %schar\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyval %sval\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yylval %slval\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yydebug %sdebug\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yynerrs %snerrs\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyerrflag %serrflag\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyss %sss\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyssp %sssp\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyvs %svs\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyvsp %svsp\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yylhs %slhs\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yylen %slen\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yydefred %sdefred\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yydgoto %sdgoto\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yysindex %ssindex\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyrindex %srindex\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yygindex %sgindex\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yytable %stable\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yycheck %scheck\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyname %sname\n", symbol_prefix); - ++outline; - fprintf(code_file, "#define yyrule %srule\n", symbol_prefix); - } - ++outline; - fprintf(code_file, "#define YYPREFIX \"%s\"\n", symbol_prefix); -} - - -static void -output_rule_data(void) -{ - int i; - int j; - - fprintf(output_file, "static short %slhs[] = {%42d,", symbol_prefix, - symbol_value[start_symbol]); - - j = 10; - for (i = 3; i < nrules; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", symbol_value[rlhs[i]]); - } - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - - fprintf(output_file, "static short %slen[] = {%42d,", symbol_prefix, 2); - - j = 10; - for (i = 3; i < nrules; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - j++; - - fprintf(output_file, "%5d,", rrhs[i + 1] - rrhs[i] - 1); - } - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); -} - - -static void -output_yydefred(void) -{ - int i, j; - - fprintf(output_file, "static short %sdefred[] = {%39d,", symbol_prefix, - (defred[0] ? defred[0] - 2 : 0)); - - j = 10; - for (i = 1; i < nstates; i++) - { - if (j < 10) - ++j; - else - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - - fprintf(output_file, "%5d,", (defred[i] ? defred[i] - 2 : 0)); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); -} - - -static void -output_actions(void) -{ - nvectors = 2*nstates + nvars; - - froms = NEW2(nvectors, short *); - tos = NEW2(nvectors, short *); - tally = NEW2(nvectors, short); - width = NEW2(nvectors, short); - - token_actions(); - FREE(lookaheads); - FREE(LA); - FREE(LAruleno); - FREE(accessing_symbol); - - goto_actions(); - FREE(goto_map + ntokens); - FREE(from_state); - FREE(to_state); - - sort_actions(); - pack_table(); - output_base(); - output_table(); - output_check(); -} - - -static void -token_actions(void) -{ - int i, j; - int shiftcount, reducecount; - int max, min; - short *actionrow, *r, *s; - action *p; - - actionrow = NEW2(2*ntokens, short); - for (i = 0; i < nstates; ++i) - { - if (parser[i]) - { - for (j = 0; j < 2*ntokens; ++j) - actionrow[j] = 0; - - shiftcount = 0; - reducecount = 0; - for (p = parser[i]; p; p = p->next) - { - if (p->suppressed == 0) - { - if (p->action_code == SHIFT) - { - ++shiftcount; - actionrow[p->symbol] = p->number; - } - else if (p->action_code == REDUCE && p->number != defred[i]) - { - ++reducecount; - actionrow[p->symbol + ntokens] = p->number; - } - } - } - - tally[i] = shiftcount; - tally[nstates+i] = reducecount; - width[i] = 0; - width[nstates+i] = 0; - if (shiftcount > 0) - { - froms[i] = r = NEW2(shiftcount, short); - tos[i] = s = NEW2(shiftcount, short); - min = MAXSHORT; - max = 0; - for (j = 0; j < ntokens; ++j) - { - if (actionrow[j]) - { - if (min > symbol_value[j]) - min = symbol_value[j]; - if (max < symbol_value[j]) - max = symbol_value[j]; - *r++ = symbol_value[j]; - *s++ = actionrow[j]; - } - } - width[i] = max - min + 1; - } - if (reducecount > 0) - { - froms[nstates+i] = r = NEW2(reducecount, short); - tos[nstates+i] = s = NEW2(reducecount, short); - min = MAXSHORT; - max = 0; - for (j = 0; j < ntokens; ++j) - { - if (actionrow[ntokens+j]) - { - if (min > symbol_value[j]) - min = symbol_value[j]; - if (max < symbol_value[j]) - max = symbol_value[j]; - *r++ = symbol_value[j]; - *s++ = actionrow[ntokens+j] - 2; - } - } - width[nstates+i] = max - min + 1; - } - } - } - FREE(actionrow); -} - -static void -goto_actions(void) -{ - int i, j, k; - - state_count = NEW2(nstates, short); - - k = default_goto(start_symbol + 1); - fprintf(output_file, "static short %sdgoto[] = {%40d,", symbol_prefix, k); - save_column(start_symbol + 1, k); - - j = 10; - for (i = start_symbol + 2; i < nsyms; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - k = default_goto(i); - fprintf(output_file, "%5d,", k); - save_column(i, k); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(state_count); -} - -int -default_goto(int symbol) -{ - int i; - int m; - int n; - int default_state; - int max; - - m = goto_map[symbol]; - n = goto_map[symbol + 1]; - - if (m == n) return (0); - - for (i = 0; i < nstates; i++) - state_count[i] = 0; - - for (i = m; i < n; i++) - state_count[to_state[i]]++; - - max = 0; - default_state = 0; - for (i = 0; i < nstates; i++) - { - if (state_count[i] > max) - { - max = state_count[i]; - default_state = i; - } - } - - return (default_state); -} - - - - -static void -save_column(int symbol, int default_state) -{ - int i; - int m; - int n; - short *sp; - short *sp1; - short *sp2; - int count; - int symno; - - m = goto_map[symbol]; - n = goto_map[symbol + 1]; - - count = 0; - for (i = m; i < n; i++) - { - if (to_state[i] != default_state) - ++count; - } - if (count == 0) return; - - symno = symbol_value[symbol] + 2*nstates; - - froms[symno] = sp1 = sp = NEW2(count, short); - tos[symno] = sp2 = NEW2(count, short); - - for (i = m; i < n; i++) - { - if (to_state[i] != default_state) - { - *sp1++ = from_state[i]; - *sp2++ = to_state[i]; - } - } - - tally[symno] = count; - width[symno] = sp1[-1] - sp[0] + 1; -} - -static void -sort_actions(void) -{ - int i; - int j; - int k; - int t; - int w; - - order = NEW2(nvectors, short); - nentries = 0; - - for (i = 0; i < nvectors; i++) - { - if (tally[i] > 0) - { - t = tally[i]; - w = width[i]; - j = nentries - 1; - - while (j >= 0 && (width[order[j]] < w)) - j--; - - while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t)) - j--; - - for (k = nentries - 1; k > j; k--) - order[k + 1] = order[k]; - - order[j + 1] = i; - nentries++; - } - } -} - - -static void -pack_table(void) -{ - int i; - int place; - int state; - - base = NEW2(nvectors, short); - pos = NEW2(nentries, short); - - maxtable = 1000; - table = NEW2(maxtable, short); - check = NEW2(maxtable, short); - - lowzero = 0; - high = 0; - - for (i = 0; i < maxtable; i++) - check[i] = -1; - - for (i = 0; i < nentries; i++) - { - state = matching_vector(i); - - if (state < 0) - place = pack_vector(i); - else - place = base[state]; - - pos[i] = place; - base[order[i]] = place; - } - - for (i = 0; i < nvectors; i++) - { - if (froms[i]) - FREE(froms[i]); - if (tos[i]) - FREE(tos[i]); - } - - FREE(froms); - FREE(tos); - FREE(pos); -} - - -/* The function matching_vector determines if the vector specified by */ -/* the input parameter matches a previously considered vector. The */ -/* test at the start of the function checks if the vector represents */ -/* a row of shifts over terminal symbols or a row of reductions, or a */ -/* column of shifts over a nonterminal symbol. Berkeley Yacc does not */ -/* check if a column of shifts over a nonterminal symbols matches a */ -/* previously considered vector. Because of the nature of LR parsing */ -/* tables, no two columns can match. Therefore, the only possible */ -/* match would be between a row and a column. Such matches are */ -/* unlikely. Therefore, to save time, no attempt is made to see if a */ -/* column matches a previously considered vector. */ -/* */ -/* Matching_vector is poorly designed. The test could easily be made */ -/* faster. Also, it depends on the vectors being in a specific */ -/* order. */ - -int -matching_vector(int vector) -{ - int i; - int j; - int k; - int t; - int w; - int match; - int prev; - - i = order[vector]; - if (i >= 2*nstates) - return (-1); - - t = tally[i]; - w = width[i]; - - for (prev = vector - 1; prev >= 0; prev--) - { - j = order[prev]; - if (width[j] != w || tally[j] != t) - return (-1); - - match = 1; - for (k = 0; match && k < t; k++) - { - if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k]) - match = 0; - } - - if (match) - return (j); - } - - return (-1); -} - - - -int -pack_vector(int vector) -{ - int i, j, k, l; - int t; - int loc; - int ok; - short *from; - short *to; - int newmax; - - i = order[vector]; - t = tally[i]; - assert(t); - - from = froms[i]; - to = tos[i]; - - j = lowzero - from[0]; - for (k = 1; k < t; ++k) - if (lowzero - from[k] > j) - j = lowzero - from[k]; - for (;; ++j) - { - if (j == 0) - continue; - ok = 1; - for (k = 0; ok && k < t; k++) - { - loc = j + from[k]; - if (loc >= maxtable) - { - if (loc >= MAXTABLE) - fatal("maximum table size exceeded"); - - newmax = maxtable; - do { newmax += 200; } while (newmax <= loc); - table = (short *) REALLOC(table, newmax*sizeof(short)); - if (table == 0) no_space(); - check = (short *) REALLOC(check, newmax*sizeof(short)); - if (check == 0) no_space(); - for (l = maxtable; l < newmax; ++l) - { - table[l] = 0; - check[l] = -1; - } - maxtable = newmax; - } - - if (check[loc] != -1) - ok = 0; - } - for (k = 0; ok && k < vector; k++) - { - if (pos[k] == j) - ok = 0; - } - if (ok) - { - for (k = 0; k < t; k++) - { - loc = j + from[k]; - table[loc] = to[k]; - check[loc] = from[k]; - if (loc > high) high = loc; - } - - while (check[lowzero] != -1) - ++lowzero; - - return (j); - } - } -} - - - -static void -output_base(void) -{ - int i, j; - - fprintf(output_file, "static short %ssindex[] = {%39d,", symbol_prefix, base[0]); - - j = 10; - for (i = 1; i < nstates; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", base[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\nstatic short %srindex[] = {%39d,", symbol_prefix, - base[nstates]); - - j = 10; - for (i = nstates + 1; i < 2*nstates; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", base[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\nstatic short %sgindex[] = {%39d,", symbol_prefix, - base[2*nstates]); - - j = 10; - for (i = 2*nstates + 1; i < nvectors - 1; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", base[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(base); -} - - - -static void -output_table(void) -{ - int i; - int j; - - ++outline; - fprintf(code_file, "#define YYTABLESIZE %d\n", high); - fprintf(output_file, "static short %stable[] = {%40d,", symbol_prefix, - table[0]); - - j = 10; - for (i = 1; i <= high; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", table[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(table); -} - - - -static void -output_check(void) -{ - int i; - int j; - - fprintf(output_file, "static short %scheck[] = {%40d,", symbol_prefix, - check[0]); - - j = 10; - for (i = 1; i <= high; i++) - { - if (j >= 10) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 1; - } - else - ++j; - - fprintf(output_file, "%5d,", check[i]); - } - - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(check); -} - - -static int -is_C_identifier(char *name) -{ - char *s; - int c; - - s = name; - c = *s; - if (c == '"') - { - c = *++s; - if (!isalpha(c) && c != '_' && c != '$') - return (0); - while ((c = *++s) != '"') - { - if (!isalnum(c) && c != '_' && c != '$') - return (0); - } - return (1); - } - - if (!isalpha(c) && c != '_' && c != '$') - return (0); - while ((c = *++s)) - { - if (!isalnum(c) && c != '_' && c != '$') - return (0); - } - return (1); -} - - -static void -output_defines(void) -{ - int c, i; - char *s; - - for (i = 2; i < ntokens; ++i) - { - s = symbol_name[i]; - if (is_C_identifier(s)) - { - fprintf(code_file, "#define "); - if (dflag) fprintf(defines_file, "#define "); - c = *s; - if (c == '"') - { - while ((c = *++s) != '"') - { - putc(c, code_file); - if (dflag) putc(c, defines_file); - } - } - else - { - do - { - putc(c, code_file); - if (dflag) putc(c, defines_file); - } - while ((c = *++s)); - } - ++outline; - fprintf(code_file, " %d\n", symbol_value[i]); - if (dflag) fprintf(defines_file, " %d\n", symbol_value[i]); - } - } - - ++outline; - fprintf(code_file, "#define YYERRCODE %d\n", symbol_value[1]); - - if (dflag && unionized) - { - rewind(union_file); - while ((c = getc(union_file)) != EOF) - putc(c, defines_file); - fprintf(defines_file, " YYSTYPE;\nstatic YYSTYPE %slval;\n", - symbol_prefix); - } -} - - -static void -output_stored_text(void) -{ - int c; - FILE *in, *out; - - rewind(text_file); - in = text_file; - if ((c = getc(in)) == EOF) - return; - out = code_file; - if (c == '\n') - ++outline; - putc(c, out); - while ((c = getc(in)) != EOF) - { - if (c == '\n') - ++outline; - putc(c, out); - } - if (!lflag) - fprintf(out, line_format, ++outline + 1, code_file_name); -} - - -static void -output_debug(void) -{ - int i, j, k, max; - char **symnam, *s; - - ++outline; - fprintf(code_file, "#define YYFINAL %d\n", final_state); - outline += 3; - fprintf(code_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", - tflag); - if (rflag) - fprintf(output_file, "#ifndef YYDEBUG\n#define YYDEBUG %d\n#endif\n", - tflag); - - max = 0; - for (i = 2; i < ntokens; ++i) - if (symbol_value[i] > max) - max = symbol_value[i]; - ++outline; - fprintf(code_file, "#define YYMAXTOKEN %d\n", max); - - symnam = (char **) MALLOC((max+1)*sizeof(char *)); - if (symnam == 0) no_space(); - - /* Note that it is not necessary to initialize the element */ - /* symnam[max]. */ - for (i = 0; i < max; ++i) - symnam[i] = 0; - for (i = ntokens - 1; i >= 2; --i) - symnam[symbol_value[i]] = symbol_name[i]; - symnam[0] = "end-of-file"; - - if (!rflag) ++outline; - fprintf(output_file, "#if YYDEBUG\nstatic char *%sname[] = {", symbol_prefix); - j = 80; - for (i = 0; i <= max; ++i) - { - if ((s = symnam[i])) - { - if (s[0] == '"') - { - k = 7; - while (*++s != '"') - { - ++k; - if (*s == '\\') - { - k += 2; - if (*++s == '\\') - ++k; - } - } - j += k; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = k; - } - fprintf(output_file, "\"\\\""); - s = symnam[i]; - while (*++s != '"') - { - if (*s == '\\') - { - fprintf(output_file, "\\\\"); - if (*++s == '\\') - fprintf(output_file, "\\\\"); - else - putc(*s, output_file); - } - else - putc(*s, output_file); - } - fprintf(output_file, "\\\"\","); - } - else if (s[0] == '\'') - { - if (s[1] == '"') - { - j += 7; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 7; - } - fprintf(output_file, "\"'\\\"'\","); - } - else - { - k = 5; - while (*++s != '\'') - { - ++k; - if (*s == '\\') - { - k += 2; - if (*++s == '\\') - ++k; - } - } - j += k; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = k; - } - fprintf(output_file, "\"'"); - s = symnam[i]; - while (*++s != '\'') - { - if (*s == '\\') - { - fprintf(output_file, "\\\\"); - if (*++s == '\\') - fprintf(output_file, "\\\\"); - else - putc(*s, output_file); - } - else - putc(*s, output_file); - } - fprintf(output_file, "'\","); - } - } - else - { - k = strlen(s) + 3; - j += k; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = k; - } - putc('"', output_file); - do { putc(*s, output_file); } while (*++s); - fprintf(output_file, "\","); - } - } - else - { - j += 2; - if (j > 80) - { - if (!rflag) ++outline; - putc('\n', output_file); - j = 2; - } - fprintf(output_file, "0,"); - } - } - if (!rflag) outline += 2; - fprintf(output_file, "\n};\n"); - FREE(symnam); - - if (!rflag) ++outline; - fprintf(output_file, "static char *%srule[] = {\n", symbol_prefix); - for (i = 2; i < nrules; ++i) - { - fprintf(output_file, "\"%s :", symbol_name[rlhs[i]]); - for (j = rrhs[i]; ritem[j] > 0; ++j) - { - s = symbol_name[ritem[j]]; - if (s[0] == '"') - { - fprintf(output_file, " \\\""); - while (*++s != '"') - { - if (*s == '\\') - { - if (s[1] == '\\') - fprintf(output_file, "\\\\\\\\"); - else - fprintf(output_file, "\\\\%c", s[1]); - ++s; - } - else - putc(*s, output_file); - } - fprintf(output_file, "\\\""); - } - else if (s[0] == '\'') - { - if (s[1] == '"') - fprintf(output_file, " '\\\"'"); - else if (s[1] == '\\') - { - if (s[2] == '\\') - fprintf(output_file, " '\\\\\\\\"); - else - fprintf(output_file, " '\\\\%c", s[2]); - s += 2; - while (*++s != '\'') - putc(*s, output_file); - putc('\'', output_file); - } - else - fprintf(output_file, " '%c'", s[1]); - } - else - fprintf(output_file, " %s", s); - } - if (!rflag) ++outline; - fprintf(output_file, "\",\n"); - } - - if (!rflag) outline += 2; - fprintf(output_file, "};\n#endif\n"); -} - - -static void -output_stype(void) -{ - if (!unionized && ntags == 0) - { - outline += 3; - fprintf(code_file, "#ifndef YYSTYPE\ntypedef int YYSTYPE;\n#endif\n"); - } -} - - -static void -output_trailing_text(void) -{ - int c, last; - FILE *in, *out; - - if (line == 0) - return; - - in = input_file; - out = code_file; - c = *cptr; - if (c == '\n') - { - ++lineno; - if ((c = getc(in)) == EOF) - return; - if (!lflag) - { - ++outline; - fprintf(out, line_format, lineno, input_file_name); - } - if (c == '\n') - ++outline; - putc(c, out); - last = c; - } - else - { - if (!lflag) - { - ++outline; - fprintf(out, line_format, lineno, input_file_name); - } - do { putc(c, out); } while ((c = *++cptr) != '\n'); - ++outline; - putc('\n', out); - last = '\n'; - } - - while ((c = getc(in)) != EOF) - { - if (c == '\n') - ++outline; - putc(c, out); - last = c; - } - - if (last != '\n') - { - ++outline; - putc('\n', out); - } - if (!lflag) - fprintf(out, line_format, ++outline + 1, code_file_name); -} - - -static void -output_semantic_actions(void) -{ - int c, last; - FILE *out; - - rewind(action_file); - - if ((c = getc(action_file)) == EOF) - return; - - out = code_file; - last = c; - if (c == '\n') - ++outline; - putc(c, out); - while ((c = getc(action_file)) != EOF) - { - if (c == '\n') - ++outline; - putc(c, out); - last = c; - } - - if (last != '\n') - { - ++outline; - putc('\n', out); - } - - if (!lflag) - fprintf(out, line_format, ++outline + 1, code_file_name); -} - - -static void -free_itemsets(void) -{ - core *cp, *next; - - FREE(state_table); - for (cp = first_state; cp; cp = next) - { - next = cp->next; - FREE(cp); - } -} - - -static void -free_shifts(void) -{ - shifts *sp, *next; - - FREE(shift_table); - for (sp = first_shift; sp; sp = next) - { - next = sp->next; - FREE(sp); - } -} - - -static void -free_reductions(void) -{ - reductions *rp, *next; - - FREE(reduction_table); - for (rp = first_reduction; rp; rp = next) - { - next = rp->next; - FREE(rp); - } -} diff --git a/src/libCom/yacc/reader.c b/src/libCom/yacc/reader.c deleted file mode 100644 index 93a1a42de..000000000 --- a/src/libCom/yacc/reader.c +++ /dev/null @@ -1,1805 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -/* The line size must be a positive integer. One hundred was chosen */ -/* because few lines in Yacc input grammars exceed 100 characters. */ -/* Note that if a line exceeds LINESIZE characters, the line buffer */ -/* will be expanded to accomodate it. */ - -#define LINESIZE 100 - -char *cache; -int cinc, cache_size; - -int ntags, tagmax; -char **tag_table; - -char saw_eof, unionized; -char *cptr, *line; -int linesize; - -bucket *goal; -int prec; -int gensym; -char last_was_action; - -int maxitems; -bucket **pitem; - -int maxrules; -bucket **plhs; - -int name_pool_size; -char *name_pool; - -char line_format[] = "#line %d \"%s\"\n"; - -#define static - -static void start_rule(bucket *bp, int s_lineno); - - -static void -cachec(int c) -{ - assert(cinc >= 0); - if (cinc >= cache_size) - { - cache_size += 256; - cache = REALLOC(cache, cache_size); - if (cache == 0) no_space(); - } - cache[cinc] = c; - ++cinc; -} - - -static void -get_line(void) -{ - FILE *f = input_file; - int c; - int i; - - if (saw_eof || (c = getc(f)) == EOF) - { - if (line) { FREE(line); line = 0; } - cptr = 0; - saw_eof = 1; - return; - } - - if (line == 0 || linesize != (LINESIZE + 1)) - { - if (line) FREE(line); - linesize = LINESIZE + 1; - line = MALLOC(linesize); - if (line == 0) no_space(); - } - - i = 0; - ++lineno; - for (;;) - { - line[i] = c; - if (c == '\n') { cptr = line; return; } - if (++i >= linesize) - { - linesize += LINESIZE; - line = REALLOC(line, linesize); - if (line == 0) no_space(); - } - c = getc(f); - if (c == EOF) - { - line[i] = '\n'; - saw_eof = 1; - cptr = line; - return; - } - } -} - - -static char * -dup_line(void) -{ - char *p, *s, *t; - - if (line == 0) return (0); - s = line; - while (*s != '\n') ++s; - p = MALLOC(s - line + 1); - if (p == 0) no_space(); - - s = line; - t = p; - while ((*t++ = *s++) != '\n') continue; - return (p); -} - - -static void -skip_comment(void) -{ - char *s; - - int st_lineno = lineno; - char *st_line = dup_line(); - char *st_cptr = st_line + (cptr - line); - - s = cptr + 2; - for (;;) - { - if (*s == '*' && s[1] == '/') - { - cptr = s + 2; - FREE(st_line); - return; - } - if (*s == '\n') - { - get_line(); - if (line == 0) - unterminated_comment(st_lineno, st_line, st_cptr); - s = cptr; - } - else - ++s; - } -} - - -static int -nextc(void) -{ - char *s; - - if (line == 0) - { - get_line(); - if (line == 0) - return (EOF); - } - - s = cptr; - for (;;) - { - switch (*s) - { - case '\n': - get_line(); - if (line == 0) return (EOF); - s = cptr; - break; - - case ' ': - case '\t': - case '\f': - case '\r': - case '\v': - case ',': - case ';': - ++s; - break; - - case '\\': - cptr = s; - return ('%'); - - case '/': - if (s[1] == '*') - { - cptr = s; - skip_comment(); - s = cptr; - break; - } - else if (s[1] == '/') - { - get_line(); - if (line == 0) return (EOF); - s = cptr; - break; - } - /* fall through */ - - default: - cptr = s; - return (*s); - } - } -} - - -static int -keyword(void) -{ - int c; - char *t_cptr = cptr; - - c = *++cptr; - if (isalpha(c)) - { - cinc = 0; - for (;;) - { - if (isalpha(c)) - { - if (isupper(c)) c = tolower(c); - cachec(c); - } - else if (isdigit(c) || c == '_' || c == '.' || c == '$') - cachec(c); - else - break; - c = *++cptr; - } - cachec(NUL); - - if (strcmp(cache, "token") == 0 || strcmp(cache, "term") == 0) - return (TOKEN); - if (strcmp(cache, "type") == 0) - return (TYPE); - if (strcmp(cache, "left") == 0) - return (LEFT); - if (strcmp(cache, "right") == 0) - return (RIGHT); - if (strcmp(cache, "nonassoc") == 0 || strcmp(cache, "binary") == 0) - return (NONASSOC); - if (strcmp(cache, "start") == 0) - return (START); - if (strcmp(cache, "union") == 0) - return (UNION); - if (strcmp(cache, "ident") == 0) - return (IDENT); - } - else - { - ++cptr; - if (c == '{') - return (TEXT); - if (c == '%' || c == '\\') - return (MARK); - if (c == '<') - return (LEFT); - if (c == '>') - return (RIGHT); - if (c == '0') - return (TOKEN); - if (c == '2') - return (NONASSOC); - } - syntax_error(lineno, line, t_cptr); - /*NOTREACHED*/ -} - - -static void -copy_ident(void) -{ - int c; - FILE *f = output_file; - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != '"') syntax_error(lineno, line, cptr); - ++outline; - fprintf(f, "#ident \""); - for (;;) - { - c = *++cptr; - if (c == '\n') - { - fprintf(f, "\"\n"); - return; - } - putc(c, f); - if (c == '"') - { - putc('\n', f); - ++cptr; - return; - } - } -} - - -static void -copy_text(void) -{ - int c; - int quote; - FILE *f = text_file; - int need_newline = 0; - int t_lineno = lineno; - char *t_line = dup_line(); - char *t_cptr = t_line + (cptr - line - 2); - - if (*cptr == '\n') - { - get_line(); - if (line == 0) - unterminated_text(t_lineno, t_line, t_cptr); - } - if (!lflag) fprintf(f, line_format, lineno, input_file_name); - -loop: - c = *cptr++; - switch (c) - { - case '\n': - next_line: - putc('\n', f); - need_newline = 0; - get_line(); - if (line) goto loop; - unterminated_text(t_lineno, t_line, t_cptr); - - case '\'': - case '"': - { - int s_lineno = lineno; - char *s_line = dup_line(); - char *s_cptr = s_line + (cptr - line - 1); - - quote = c; - putc(c, f); - for (;;) - { - c = *cptr++; - putc(c, f); - if (c == quote) - { - need_newline = 1; - FREE(s_line); - goto loop; - } - if (c == '\n') - unterminated_string(s_lineno, s_line, s_cptr); - if (c == '\\') - { - c = *cptr++; - putc(c, f); - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_string(s_lineno, s_line, s_cptr); - } - } - } - } - - case '/': - putc(c, f); - need_newline = 1; - c = *cptr; - if (c == '/') - { - putc('*', f); - while ((c = *++cptr) != '\n') - { - if (c == '*' && cptr[1] == '/') - fprintf(f, "* "); - else - putc(c, f); - } - fprintf(f, "*/"); - goto next_line; - } - if (c == '*') - { - int c_lineno = lineno; - char *c_line = dup_line(); - char *c_cptr = c_line + (cptr - line - 1); - - putc('*', f); - ++cptr; - for (;;) - { - c = *cptr++; - putc(c, f); - if (c == '*' && *cptr == '/') - { - putc('/', f); - ++cptr; - FREE(c_line); - goto loop; - } - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_comment(c_lineno, c_line, c_cptr); - } - } - } - need_newline = 1; - goto loop; - - case '%': - case '\\': - if (*cptr == '}') - { - if (need_newline) putc('\n', f); - ++cptr; - FREE(t_line); - return; - } - /* fall through */ - - default: - putc(c, f); - need_newline = 1; - goto loop; - } -} - - -static void -copy_union(void) -{ - int c; - int quote; - int depth; - int u_lineno = lineno; - char *u_line = dup_line(); - char *u_cptr = u_line + (cptr - line - 6); - - if (unionized) over_unionized(cptr - 6); - unionized = 1; - - if (!lflag) - fprintf(text_file, line_format, lineno, input_file_name); - - fprintf(text_file, "typedef union"); - if (dflag) fprintf(union_file, "typedef union"); - - depth = 0; -loop: - c = *cptr++; - putc(c, text_file); - if (dflag) putc(c, union_file); - switch (c) - { - case '\n': - next_line: - get_line(); - if (line == 0) unterminated_union(u_lineno, u_line, u_cptr); - goto loop; - - case '{': - ++depth; - goto loop; - - case '}': - if (--depth == 0) - { - fprintf(text_file, " YYSTYPE;\n"); - FREE(u_line); - return; - } - goto loop; - - case '\'': - case '"': - { - int s_lineno = lineno; - char *s_line = dup_line(); - char *s_cptr = s_line + (cptr - line - 1); - - quote = c; - for (;;) - { - c = *cptr++; - putc(c, text_file); - if (dflag) putc(c, union_file); - if (c == quote) - { - FREE(s_line); - goto loop; - } - if (c == '\n') - unterminated_string(s_lineno, s_line, s_cptr); - if (c == '\\') - { - c = *cptr++; - putc(c, text_file); - if (dflag) putc(c, union_file); - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_string(s_lineno, s_line, s_cptr); - } - } - } - } - - case '/': - c = *cptr; - if (c == '/') - { - putc('*', text_file); - if (dflag) putc('*', union_file); - while ((c = *++cptr) != '\n') - { - if (c == '*' && cptr[1] == '/') - { - fprintf(text_file, "* "); - if (dflag) fprintf(union_file, "* "); - } - else - { - putc(c, text_file); - if (dflag) putc(c, union_file); - } - } - fprintf(text_file, "*/\n"); - if (dflag) fprintf(union_file, "*/\n"); - goto next_line; - } - if (c == '*') - { - int c_lineno = lineno; - char *c_line = dup_line(); - char *c_cptr = c_line + (cptr - line - 1); - - putc('*', text_file); - if (dflag) putc('*', union_file); - ++cptr; - for (;;) - { - c = *cptr++; - putc(c, text_file); - if (dflag) putc(c, union_file); - if (c == '*' && *cptr == '/') - { - putc('/', text_file); - if (dflag) putc('/', union_file); - ++cptr; - FREE(c_line); - goto loop; - } - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_comment(c_lineno, c_line, c_cptr); - } - } - } - goto loop; - - default: - goto loop; - } -} - - -static int -hexval(int c) -{ - if (c >= '0' && c <= '9') - return (c - '0'); - if (c >= 'A' && c <= 'F') - return (c - 'A' + 10); - if (c >= 'a' && c <= 'f') - return (c - 'a' + 10); - return (-1); -} - - -static bucket * -get_literal(void) -{ - int c, quote; - int i; - int n; - char *s; - bucket *bp; - int s_lineno = lineno; - char *s_line = dup_line(); - char *s_cptr = s_line + (cptr - line); - - quote = *cptr++; - cinc = 0; - for (;;) - { - c = *cptr++; - if (c == quote) break; - if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr); - if (c == '\\') - { - char *c_cptr = cptr - 1; - - c = *cptr++; - switch (c) - { - case '\n': - get_line(); - if (line == 0) unterminated_string(s_lineno, s_line, s_cptr); - continue; - - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - n = c - '0'; - c = *cptr; - if (IS_OCTAL(c)) - { - n = (n << 3) + (c - '0'); - c = *++cptr; - if (IS_OCTAL(c)) - { - n = (n << 3) + (c - '0'); - ++cptr; - } - } - if (n > MAXCHAR) illegal_character(c_cptr); - c = n; - break; - - case 'x': - c = *cptr++; - n = hexval(c); - if (n < 0 || n >= 16) - illegal_character(c_cptr); - for (;;) - { - c = *cptr; - i = hexval(c); - if (i < 0 || i >= 16) break; - ++cptr; - n = (n << 4) + i; - if (n > MAXCHAR) illegal_character(c_cptr); - } - c = n; - break; - - case 'a': c = 7; break; - case 'b': c = '\b'; break; - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - case 'v': c = '\v'; break; - } - } - cachec(c); - } - FREE(s_line); - - n = cinc; - s = MALLOC(n); - if (s == 0) no_space(); - - for (i = 0; i < n; ++i) - s[i] = cache[i]; - - cinc = 0; - if (n == 1) - cachec('\''); - else - cachec('"'); - - for (i = 0; i < n; ++i) - { - c = ((unsigned char *)s)[i]; - if (c == '\\' || c == cache[0]) - { - cachec('\\'); - cachec(c); - } - else if (isprint(c)) - cachec(c); - else - { - cachec('\\'); - switch (c) - { - case 7: cachec('a'); break; - case '\b': cachec('b'); break; - case '\f': cachec('f'); break; - case '\n': cachec('n'); break; - case '\r': cachec('r'); break; - case '\t': cachec('t'); break; - case '\v': cachec('v'); break; - default: - cachec(((c >> 6) & 7) + '0'); - cachec(((c >> 3) & 7) + '0'); - cachec((c & 7) + '0'); - break; - } - } - } - - if (n == 1) - cachec('\''); - else - cachec('"'); - - cachec(NUL); - bp = lookup(cache); - bp->class = TERM; - if (n == 1 && bp->value == UNDEFINED) - bp->value = *(unsigned char *)s; - FREE(s); - - return (bp); -} - - -static int -is_reserved(char *name) -{ - char *s; - - if (strcmp(name, ".") == 0 || - strcmp(name, "$accept") == 0 || - strcmp(name, "$end") == 0) - return (1); - - if (name[0] == '$' && name[1] == '$' && isdigit((int) name[2])) - { - s = name + 3; - while (isdigit((int) *s)) ++s; - if (*s == NUL) return (1); - } - - return (0); -} - - -static bucket * -get_name(void) -{ - int c; - - cinc = 0; - for (c = *cptr; IS_IDENT(c); c = *++cptr) - cachec(c); - cachec(NUL); - - if (is_reserved(cache)) used_reserved(cache); - - return (lookup(cache)); -} - - -static int -get_number(void) -{ - int c; - int n; - - n = 0; - for (c = *cptr; isdigit(c); c = *++cptr) - n = 10*n + (c - '0'); - - return (n); -} - - -static char * -get_tag(void) -{ - int c; - int i; - char *s; - int t_lineno = lineno; - char *t_line = dup_line(); - char *t_cptr = t_line + (cptr - line); - - ++cptr; - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (!isalpha(c) && c != '_' && c != '$') - illegal_tag(t_lineno, t_line, t_cptr); - - cinc = 0; - do { cachec(c); c = *++cptr; } while (IS_IDENT(c)); - cachec(NUL); - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != '>') - illegal_tag(t_lineno, t_line, t_cptr); - ++cptr; - - for (i = 0; i < ntags; ++i) - { - if (strcmp(cache, tag_table[i]) == 0) - return (tag_table[i]); - } - - if (ntags >= tagmax) - { - tagmax += 16; - tag_table = (char **) - (tag_table ? REALLOC(tag_table, tagmax*sizeof(char *)) - : MALLOC(tagmax*sizeof(char *))); - if (tag_table == 0) no_space(); - } - - s = MALLOC(cinc); - if (s == 0) no_space(); - strcpy(s, cache); - tag_table[ntags] = s; - ++ntags; - FREE(t_line); - return (s); -} - - -static void -declare_tokens(int assoc) -{ - int c; - bucket *bp; - int value; - char *tag = 0; - - if (assoc != TOKEN) ++prec; - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c == '<') - { - tag = get_tag(); - c = nextc(); - if (c == EOF) unexpected_EOF(); - } - - for (;;) - { - if (isalpha(c) || c == '_' || c == '.' || c == '$') - bp = get_name(); - else if (c == '\'' || c == '"') - bp = get_literal(); - else - return; - - if (bp == goal) tokenized_start(bp->name); - bp->class = TERM; - - if (tag) - { - if (bp->tag && tag != bp->tag) - retyped_warning(bp->name); - bp->tag = tag; - } - - if (assoc != TOKEN) - { - if (bp->prec && prec != bp->prec) - reprec_warning(bp->name); - bp->assoc = assoc; - bp->prec = prec; - } - - c = nextc(); - if (c == EOF) unexpected_EOF(); - value = UNDEFINED; - if (isdigit(c)) - { - value = get_number(); - if (bp->value != UNDEFINED && value != bp->value) - revalued_warning(bp->name); - bp->value = value; - c = nextc(); - if (c == EOF) unexpected_EOF(); - } - } -} - - -static void -declare_types(void) -{ - int c; - bucket *bp; - char *tag; - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != '<') syntax_error(lineno, line, cptr); - tag = get_tag(); - - for (;;) - { - c = nextc(); - if (isalpha(c) || c == '_' || c == '.' || c == '$') - bp = get_name(); - else if (c == '\'' || c == '"') - bp = get_literal(); - else - return; - - if (bp->tag && tag != bp->tag) - retyped_warning(bp->name); - bp->tag = tag; - } -} - - -static void -declare_start(void) -{ - int c; - bucket *bp; - - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (!isalpha(c) && c != '_' && c != '.' && c != '$') - syntax_error(lineno, line, cptr); - bp = get_name(); - if (bp->class == TERM) - terminal_start(bp->name); - if (goal && goal != bp) - restarted_warning(); - goal = bp; -} - - -static void -read_declarations(void) -{ - int c, k; - - cache_size = 256; - cache = MALLOC(cache_size); - if (cache == 0) no_space(); - - for (;;) - { - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != '%') syntax_error(lineno, line, cptr); - switch (k = keyword()) - { - case MARK: - return; - - case IDENT: - copy_ident(); - break; - - case TEXT: - copy_text(); - break; - - case UNION: - copy_union(); - break; - - case TOKEN: - case LEFT: - case RIGHT: - case NONASSOC: - declare_tokens(k); - break; - - case TYPE: - declare_types(); - break; - - case START: - declare_start(); - break; - } - } -} - - -static void -initialize_grammar(void) -{ - nitems = 4; - maxitems = 300; - pitem = (bucket **) MALLOC(maxitems*sizeof(bucket *)); - if (pitem == 0) no_space(); - pitem[0] = 0; - pitem[1] = 0; - pitem[2] = 0; - pitem[3] = 0; - - nrules = 3; - maxrules = 100; - plhs = (bucket **) MALLOC(maxrules*sizeof(bucket *)); - if (plhs == 0) no_space(); - plhs[0] = 0; - plhs[1] = 0; - plhs[2] = 0; - rprec = (short *) MALLOC(maxrules*sizeof(short)); - if (rprec == 0) no_space(); - rprec[0] = 0; - rprec[1] = 0; - rprec[2] = 0; - rassoc = (char *) MALLOC(maxrules*sizeof(char)); - if (rassoc == 0) no_space(); - rassoc[0] = TOKEN; - rassoc[1] = TOKEN; - rassoc[2] = TOKEN; -} - - -static void -expand_items(void) -{ - maxitems += 300; - pitem = (bucket **) REALLOC(pitem, maxitems*sizeof(bucket *)); - if (pitem == 0) no_space(); -} - - -static void -expand_rules(void) -{ - maxrules += 100; - plhs = (bucket **) REALLOC(plhs, maxrules*sizeof(bucket *)); - if (plhs == 0) no_space(); - rprec = (short *) REALLOC(rprec, maxrules*sizeof(short)); - if (rprec == 0) no_space(); - rassoc = (char *) REALLOC(rassoc, maxrules*sizeof(char)); - if (rassoc == 0) no_space(); -} - - -static void -advance_to_start(void) -{ - int c; - bucket *bp; - char *s_cptr; - int s_lineno; - - for (;;) - { - c = nextc(); - if (c != '%') break; - s_cptr = cptr; - switch (keyword()) - { - case MARK: - no_grammar(); - - case TEXT: - copy_text(); - break; - - case START: - declare_start(); - break; - - default: - syntax_error(lineno, line, s_cptr); - } - } - - c = nextc(); - if (!isalpha(c) && c != '_' && c != '.' && c != '_') - syntax_error(lineno, line, cptr); - bp = get_name(); - if (goal == 0) - { - if (bp->class == TERM) - terminal_start(bp->name); - goal = bp; - } - - s_lineno = lineno; - c = nextc(); - if (c == EOF) unexpected_EOF(); - if (c != ':') syntax_error(lineno, line, cptr); - start_rule(bp, s_lineno); - ++cptr; -} - - -static void -start_rule(bucket *bp, int s_lineno) -{ - if (bp->class == TERM) - terminal_lhs(s_lineno); - bp->class = NONTERM; - if (nrules >= maxrules) - expand_rules(); - plhs[nrules] = bp; - rprec[nrules] = UNDEFINED; - rassoc[nrules] = TOKEN; -} - - -static void -end_rule(void) -{ - int i; - - if (!last_was_action && plhs[nrules]->tag) - { - for (i = nitems - 1; pitem[i]; --i) continue; - if (pitem[i+1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag) - default_action_warning(); - } - - last_was_action = 0; - if (nitems >= maxitems) expand_items(); - pitem[nitems] = 0; - ++nitems; - ++nrules; -} - - -static void -insert_empty_rule(void) -{ - bucket *bp, **bpp; - - assert(cache); - sprintf(cache, "$$%d", ++gensym); - bp = make_bucket(cache); - last_symbol->next = bp; - last_symbol = bp; - bp->tag = plhs[nrules]->tag; - bp->class = NONTERM; - - if ((nitems += 2) > maxitems) - expand_items(); - bpp = pitem + nitems - 1; - *bpp-- = bp; - while ((bpp[0] = bpp[-1])) --bpp; - - if (++nrules >= maxrules) - expand_rules(); - plhs[nrules] = plhs[nrules-1]; - plhs[nrules-1] = bp; - rprec[nrules] = rprec[nrules-1]; - rprec[nrules-1] = 0; - rassoc[nrules] = rassoc[nrules-1]; - rassoc[nrules-1] = TOKEN; -} - - -static void -add_symbol(void) -{ - int c; - bucket *bp; - int s_lineno = lineno; - - c = *cptr; - if (c == '\'' || c == '"') - bp = get_literal(); - else - bp = get_name(); - - c = nextc(); - if (c == ':') - { - end_rule(); - start_rule(bp, s_lineno); - ++cptr; - return; - } - - if (last_was_action) - insert_empty_rule(); - last_was_action = 0; - - if (++nitems > maxitems) - expand_items(); - pitem[nitems-1] = bp; -} - - -static void -copy_action(void) -{ - int c; - int i, n; - int depth; - int quote; - char *tag; - FILE *f = action_file; - int a_lineno = lineno; - char *a_line = dup_line(); - char *a_cptr = a_line + (cptr - line); - - if (last_was_action) - insert_empty_rule(); - last_was_action = 1; - - fprintf(f, "case %d:\n", nrules - 2); - if (!lflag) - fprintf(f, line_format, lineno, input_file_name); - if (*cptr == '=') ++cptr; - - n = 0; - for (i = nitems - 1; pitem[i]; --i) ++n; - - depth = 0; -loop: - c = *cptr; - if (c == '$') - { - if (cptr[1] == '<') - { - int d_lineno = lineno; - char *d_line = dup_line(); - char *d_cptr = d_line + (cptr - line); - - ++cptr; - tag = get_tag(); - c = *cptr; - if (c == '$') - { - fprintf(f, "yyval.%s", tag); - ++cptr; - FREE(d_line); - goto loop; - } - else if (isdigit(c)) - { - i = get_number(); - if (i > n) dollar_warning(d_lineno, i); - fprintf(f, "yyvsp[%d].%s", i - n, tag); - FREE(d_line); - goto loop; - } - else if (c == '-' && isdigit((int) cptr[1])) - { - ++cptr; - i = -get_number() - n; - fprintf(f, "yyvsp[%d].%s", i, tag); - FREE(d_line); - goto loop; - } - else - dollar_error(d_lineno, d_line, d_cptr); - } - else if (cptr[1] == '$') - { - if (ntags) - { - tag = plhs[nrules]->tag; - if (tag == 0) untyped_lhs(); - fprintf(f, "yyval.%s", tag); - } - else - fprintf(f, "yyval"); - cptr += 2; - goto loop; - } - else if (isdigit((int) cptr[1])) - { - ++cptr; - i = get_number(); - if (ntags) - { - if (i <= 0 || i > n) - unknown_rhs(i); - tag = pitem[nitems + i - n - 1]->tag; - if (tag == 0) untyped_rhs(i, pitem[nitems + i - n - 1]->name); - fprintf(f, "yyvsp[%d].%s", i - n, tag); - } - else - { - if (i > n) - dollar_warning(lineno, i); - fprintf(f, "yyvsp[%d]", i - n); - } - goto loop; - } - else if (cptr[1] == '-') - { - cptr += 2; - i = get_number(); - if (ntags) - unknown_rhs(-i); - fprintf(f, "yyvsp[%d]", -i - n); - goto loop; - } - } - if (isalpha(c) || c == '_' || c == '$') - { - do - { - putc(c, f); - c = *++cptr; - } while (isalnum(c) || c == '_' || c == '$'); - goto loop; - } - putc(c, f); - ++cptr; - switch (c) - { - case '\n': - next_line: - get_line(); - if (line) goto loop; - unterminated_action(a_lineno, a_line, a_cptr); - - case ';': - if (depth > 0) goto loop; - fprintf(f, "\nbreak;\n"); - FREE(a_line); - return; - - case '{': - ++depth; - goto loop; - - case '}': - if (--depth > 0) goto loop; - fprintf(f, "\nbreak;\n"); - FREE(a_line); - return; - - case '\'': - case '"': - { - int s_lineno = lineno; - char *s_line = dup_line(); - char *s_cptr = s_line + (cptr - line - 1); - - quote = c; - for (;;) - { - c = *cptr++; - putc(c, f); - if (c == quote) - { - FREE(s_line); - goto loop; - } - if (c == '\n') - unterminated_string(s_lineno, s_line, s_cptr); - if (c == '\\') - { - c = *cptr++; - putc(c, f); - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_string(s_lineno, s_line, s_cptr); - } - } - } - } - - case '/': - c = *cptr; - if (c == '/') - { - putc('*', f); - while ((c = *++cptr) != '\n') - { - if (c == '*' && cptr[1] == '/') - fprintf(f, "* "); - else - putc(c, f); - } - fprintf(f, "*/\n"); - goto next_line; - } - if (c == '*') - { - int c_lineno = lineno; - char *c_line = dup_line(); - char *c_cptr = c_line + (cptr - line - 1); - - putc('*', f); - ++cptr; - for (;;) - { - c = *cptr++; - putc(c, f); - if (c == '*' && *cptr == '/') - { - putc('/', f); - ++cptr; - FREE(c_line); - goto loop; - } - if (c == '\n') - { - get_line(); - if (line == 0) - unterminated_comment(c_lineno, c_line, c_cptr); - } - } - } - goto loop; - - default: - goto loop; - } -} - - -static int -mark_symbol(void) -{ - int c; - bucket *bp; - - c = cptr[1]; - if (c == '%' || c == '\\') - { - cptr += 2; - return (1); - } - - if (c == '=') - cptr += 2; - else if ((c == 'p' || c == 'P') && - ((c = cptr[2]) == 'r' || c == 'R') && - ((c = cptr[3]) == 'e' || c == 'E') && - ((c = cptr[4]) == 'c' || c == 'C') && - ((c = cptr[5], !IS_IDENT(c)))) - cptr += 5; - else - syntax_error(lineno, line, cptr); - - c = nextc(); - if (isalpha(c) || c == '_' || c == '.' || c == '$') - bp = get_name(); - else if (c == '\'' || c == '"') - bp = get_literal(); - else - { - syntax_error(lineno, line, cptr); - /*NOTREACHED*/ - } - - if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules]) - prec_redeclared(); - - rprec[nrules] = bp->prec; - rassoc[nrules] = bp->assoc; - return (0); -} - - -static void -read_grammar(void) -{ - int c; - - initialize_grammar(); - advance_to_start(); - - for (;;) - { - c = nextc(); - if (c == EOF) break; - if (isalpha(c) || c == '_' || c == '.' || c == '$' || c == '\'' || - c == '"') - add_symbol(); - else if (c == '{' || c == '=') - copy_action(); - else if (c == '|') - { - end_rule(); - start_rule(plhs[nrules-1], 0); - ++cptr; - } - else if (c == '%') - { - if (mark_symbol()) break; - } - else - syntax_error(lineno, line, cptr); - } - end_rule(); -} - - -static void -free_tags(void) -{ - int i; - - if (tag_table == 0) return; - - for (i = 0; i < ntags; ++i) - { - assert(tag_table[i]); - FREE(tag_table[i]); - } - FREE(tag_table); -} - - -static void -pack_names(void) -{ - bucket *bp; - char *p, *s, *t; - - name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */ - for (bp = first_symbol; bp; bp = bp->next) - name_pool_size += strlen(bp->name) + 1; - name_pool = MALLOC(name_pool_size); - if (name_pool == 0) no_space(); - - strcpy(name_pool, "$accept"); - strcpy(name_pool+8, "$end"); - t = name_pool + 13; - for (bp = first_symbol; bp; bp = bp->next) - { - p = t; - s = bp->name; - while ((*t++ = *s++)) continue; - FREE(bp->name); - bp->name = p; - } -} - - -static void -check_symbols(void) -{ - bucket *bp; - - if (goal->class == UNKNOWN) - undefined_goal(goal->name); - - for (bp = first_symbol; bp; bp = bp->next) - { - if (bp->class == UNKNOWN) - { - undefined_symbol_warning(bp->name); - bp->class = TERM; - } - } -} - - -static void -pack_symbols(void) -{ - bucket *bp; - bucket **v; - int i, j, k, n; - - nsyms = 2; - ntokens = 1; - for (bp = first_symbol; bp; bp = bp->next) - { - ++nsyms; - if (bp->class == TERM) ++ntokens; - } - start_symbol = ntokens; - nvars = nsyms - ntokens; - - symbol_name = (char **) MALLOC(nsyms*sizeof(char *)); - if (symbol_name == 0) no_space(); - symbol_value = (short *) MALLOC(nsyms*sizeof(short)); - if (symbol_value == 0) no_space(); - symbol_prec = (short *) MALLOC(nsyms*sizeof(short)); - if (symbol_prec == 0) no_space(); - symbol_assoc = MALLOC(nsyms); - if (symbol_assoc == 0) no_space(); - - v = (bucket **) MALLOC(nsyms*sizeof(bucket *)); - if (v == 0) no_space(); - - v[0] = 0; - v[start_symbol] = 0; - - i = 1; - j = start_symbol + 1; - for (bp = first_symbol; bp; bp = bp->next) - { - if (bp->class == TERM) - v[i++] = bp; - else - v[j++] = bp; - } - assert(i == ntokens && j == nsyms); - - for (i = 1; i < ntokens; ++i) - v[i]->index = i; - - goal->index = start_symbol + 1; - k = start_symbol + 2; - while (++i < nsyms) - if (v[i] != goal) - { - v[i]->index = k; - ++k; - } - - goal->value = 0; - k = 1; - for (i = start_symbol + 1; i < nsyms; ++i) - { - if (v[i] != goal) - { - v[i]->value = k; - ++k; - } - } - - k = 0; - for (i = 1; i < ntokens; ++i) - { - n = v[i]->value; - if (n > 256) - { - for (j = k++; j > 0 && symbol_value[j-1] > n; --j) - symbol_value[j] = symbol_value[j-1]; - symbol_value[j] = n; - } - } - - if (v[1]->value == UNDEFINED) - v[1]->value = 256; - - j = 0; - n = 257; - for (i = 2; i < ntokens; ++i) - { - if (v[i]->value == UNDEFINED) - { - while (j < k && n == symbol_value[j]) - { - while (++j < k && n == symbol_value[j]) continue; - ++n; - } - v[i]->value = n; - ++n; - } - } - - symbol_name[0] = name_pool + 8; - symbol_value[0] = 0; - symbol_prec[0] = 0; - symbol_assoc[0] = TOKEN; - for (i = 1; i < ntokens; ++i) - { - symbol_name[i] = v[i]->name; - symbol_value[i] = v[i]->value; - symbol_prec[i] = v[i]->prec; - symbol_assoc[i] = v[i]->assoc; - } - symbol_name[start_symbol] = name_pool; - symbol_value[start_symbol] = -1; - symbol_prec[start_symbol] = 0; - symbol_assoc[start_symbol] = TOKEN; - for (++i; i < nsyms; ++i) - { - k = v[i]->index; - symbol_name[k] = v[i]->name; - symbol_value[k] = v[i]->value; - symbol_prec[k] = v[i]->prec; - symbol_assoc[k] = v[i]->assoc; - } - - FREE(v); -} - - -static void -pack_grammar(void) -{ - int i, j; - int assoc, prec; - - ritem = (short *) MALLOC(nitems*sizeof(short)); - if (ritem == 0) no_space(); - rlhs = (short *) MALLOC(nrules*sizeof(short)); - if (rlhs == 0) no_space(); - rrhs = (short *) MALLOC((nrules+1)*sizeof(short)); - if (rrhs == 0) no_space(); - rprec = (short *) REALLOC(rprec, nrules*sizeof(short)); - if (rprec == 0) no_space(); - rassoc = REALLOC(rassoc, nrules); - if (rassoc == 0) no_space(); - - ritem[0] = -1; - ritem[1] = goal->index; - ritem[2] = 0; - ritem[3] = -2; - rlhs[0] = 0; - rlhs[1] = 0; - rlhs[2] = start_symbol; - rrhs[0] = 0; - rrhs[1] = 0; - rrhs[2] = 1; - - j = 4; - for (i = 3; i < nrules; ++i) - { - rlhs[i] = plhs[i]->index; - rrhs[i] = j; - assoc = TOKEN; - prec = 0; - while (pitem[j]) - { - ritem[j] = pitem[j]->index; - if (pitem[j]->class == TERM) - { - prec = pitem[j]->prec; - assoc = pitem[j]->assoc; - } - ++j; - } - ritem[j] = -i; - ++j; - if (rprec[i] == UNDEFINED) - { - rprec[i] = prec; - rassoc[i] = assoc; - } - } - rrhs[i] = j; - - FREE(plhs); - FREE(pitem); -} - - -static void -print_grammar(void) -{ - int i, j, k; - int spacing = 0; - FILE *f = verbose_file; - - if (!vflag) return; - - k = 1; - for (i = 2; i < nrules; ++i) - { - if (rlhs[i] != rlhs[i-1]) - { - if (i != 2) fprintf(f, "\n"); - fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]); - spacing = strlen(symbol_name[rlhs[i]]) + 1; - } - else - { - fprintf(f, "%4d ", i - 2); - j = spacing; - while (--j >= 0) putc(' ', f); - putc('|', f); - } - - while (ritem[k] >= 0) - { - fprintf(f, " %s", symbol_name[ritem[k]]); - ++k; - } - ++k; - putc('\n', f); - } -} - - -void -reader(void) -{ - write_section(banner); - create_symbol_table(); - read_declarations(); - read_grammar(); - free_symbol_table(); - free_tags(); - pack_names(); - check_symbols(); - pack_symbols(); - pack_grammar(); - free_symbols(); - print_grammar(); -} diff --git a/src/libCom/yacc/skeleton.c b/src/libCom/yacc/skeleton.c deleted file mode 100644 index ab683c666..000000000 --- a/src/libCom/yacc/skeleton.c +++ /dev/null @@ -1,302 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -/* If the skeleton is changed, the banner should be changed so that */ -/* the altered version can be easily distinguished from the original. */ -/* */ -/* The #defines included with the banner are there because they are */ -/* useful in subsequent code. The macros #defined in the header or */ -/* the body either are not useful outside of semantic actions or */ -/* are conditional. */ - -char *banner[] = -{ - "#define YYBYACC 1", - "#define YYMAJOR 1", - "#define YYMINOR 9", - "#define yyclearin (yychar=(-1))", - "#define yyerrok (yyerrflag=0)", - "#define YYRECOVERING (yyerrflag!=0)", - "static int yyparse(void);",/* JRW */ - 0 -}; - - -char *tables[] = -{ - "static short yylhs[];", /* JRW */ - "static short yylen[];", /* JRW */ - "static short yydefred[];", /* JRW */ - "static short yydgoto[];", /* JRW */ - "static short yysindex[];", /* JRW */ - "static short yyrindex[];", /* JRW */ - "static short yygindex[];", /* JRW */ - "static short yytable[];", /* JRW */ - "static short yycheck[];", /* JRW */ - "#if YYDEBUG", - "static char *yyname[];", /* JRW */ - "static char *yyrule[];", /* JRW */ - "#endif", - 0 -}; - - -char *header[] = -{ - "#ifdef YYSTACKSIZE", - "#undef YYMAXDEPTH", - "#define YYMAXDEPTH YYSTACKSIZE", - "#else", - "#ifdef YYMAXDEPTH", - "#define YYSTACKSIZE YYMAXDEPTH", - "#else", - "#define YYSTACKSIZE 500", - "#define YYMAXDEPTH 500", - "#endif", - "#endif", - "#if YYDEBUG", /* MRK */ - "static int yydebug;", /* JRW */ - "#endif", /* MRK */ - "static int yynerrs;", /* JRW */ - "static int yyerrflag;", /* JRW */ - "static int yychar;", /* JRW */ - "static short *yyssp;", /* JRW */ - "static YYSTYPE *yyvsp;", /* JRW */ - "static YYSTYPE yyval;", /* JRW */ - "static YYSTYPE yylval;", /* JRW */ - "static short yyss[YYSTACKSIZE];", /* JRW */ - "static YYSTYPE yyvs[YYSTACKSIZE];", /* JRW */ - "#define yystacksize YYSTACKSIZE", - 0 -}; - - -char *body[] = -{ - "#define YYABORT goto yyabort", - "#define YYREJECT goto yyabort", - "#define YYACCEPT goto yyaccept", - "#define YYERROR goto yyerrlab", - "static int", /* JRW */ - "yyparse(void)", /* JRW */ - "{", - " int yym, yyn, yystate;", - "#if YYDEBUG", - " char *yys;", - " extern char *getenv();", - "", - " if ((yys = getenv(\"YYDEBUG\")))", - " {", - " yyn = *yys;", - " if (yyn >= '0' && yyn <= '9')", - " yydebug = yyn - '0';", - " }", - "#endif", - "", - " yynerrs = 0;", - " yyerrflag = 0;", - " yychar = (-1);", - "", - " yyssp = yyss;", - " yyvsp = yyvs;", - " *yyssp = yystate = 0;", - "", - "yyloop:", - " if ((yyn = yydefred[yystate])) goto yyreduce;", - " if (yychar < 0)", - " {", - " if ((yychar = yylex()) < 0) yychar = 0;", - "#if YYDEBUG", - " if (yydebug)", - " {", - " yys = 0;", - " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", - " if (!yys) yys = \"illegal-symbol\";", - " printf(\"%sdebug: state %d, reading %d (%s)\\n\",", - " YYPREFIX, yystate, yychar, yys);", - " }", - "#endif", - " }", - " if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&", - " yyn <= YYTABLESIZE && yycheck[yyn] == yychar)", - " {", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: state %d, shifting to state %d\\n\",", - " YYPREFIX, yystate, yytable[yyn]);", - "#endif", - " if (yyssp >= yyss + yystacksize - 1)", - " {", - " goto yyoverflow;", - " }", - " *++yyssp = yystate = yytable[yyn];", - " *++yyvsp = yylval;", - " yychar = (-1);", - " if (yyerrflag > 0) --yyerrflag;", - " goto yyloop;", - " }", - " if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&", - " yyn <= YYTABLESIZE && yycheck[yyn] == yychar)", - " {", - " yyn = yytable[yyn];", - " goto yyreduce;", - " }", - " if (yyerrflag) goto yyinrecovery;", - " yyerror(\"syntax error\");", - " ++yynerrs;", - "yyinrecovery:", - " if (yyerrflag < 3)", - " {", - " yyerrflag = 3;", - " for (;;)", - " {", - " if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&", - " yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)", - " {", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: state %d, error recovery shifting\\", - " to state %d\\n\", YYPREFIX, *yyssp, yytable[yyn]);", - "#endif", - " if (yyssp >= yyss + yystacksize - 1)", - " {", - " goto yyoverflow;", - " }", - " *++yyssp = yystate = yytable[yyn];", - " *++yyvsp = yylval;", - " goto yyloop;", - " }", - " else", - " {", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: error recovery discarding state %d\ -\\n\",", - " YYPREFIX, *yyssp);", - "#endif", - " if (yyssp <= yyss) goto yyabort;", - " --yyssp;", - " --yyvsp;", - " }", - " }", - " }", - " else", - " {", - " if (yychar == 0) goto yyabort;", - "#if YYDEBUG", - " if (yydebug)", - " {", - " yys = 0;", - " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", - " if (!yys) yys = \"illegal-symbol\";", - " printf(\"%sdebug: state %d, error recovery discards token %d\ - (%s)\\n\",", - " YYPREFIX, yystate, yychar, yys);", - " }", - "#endif", - " yychar = (-1);", - " goto yyloop;", - " }", - "yyreduce:", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: state %d, reducing by rule %d (%s)\\n\",", - " YYPREFIX, yystate, yyn, yyrule[yyn]);", - "#endif", - " yym = yylen[yyn];", - " yyval = yyvsp[1-yym];", - " switch (yyn)", - " {", - 0 -}; - - -char *trailer[] = -{ - " }", - " yyssp -= yym;", - " yystate = *yyssp;", - " yyvsp -= yym;", - " yym = yylhs[yyn];", - " if (yystate == 0 && yym == 0)", - " {", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: after reduction, shifting from state 0 to\\", - " state %d\\n\", YYPREFIX, YYFINAL);", - "#endif", - " yystate = YYFINAL;", - " *++yyssp = YYFINAL;", - " *++yyvsp = yyval;", - " if (yychar < 0)", - " {", - " if ((yychar = yylex()) < 0) yychar = 0;", - "#if YYDEBUG", - " if (yydebug)", - " {", - " yys = 0;", - " if (yychar <= YYMAXTOKEN) yys = yyname[yychar];", - " if (!yys) yys = \"illegal-symbol\";", - " printf(\"%sdebug: state %d, reading %d (%s)\\n\",", - " YYPREFIX, YYFINAL, yychar, yys);", - " }", - "#endif", - " }", - " if (yychar == 0) goto yyaccept;", - " goto yyloop;", - " }", - " if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&", - " yyn <= YYTABLESIZE && yycheck[yyn] == yystate)", - " yystate = yytable[yyn];", - " else", - " yystate = yydgoto[yym];", - "#if YYDEBUG", - " if (yydebug)", - " printf(\"%sdebug: after reduction, shifting from state %d \\", - "to state %d\\n\", YYPREFIX, *yyssp, yystate);", - "#endif", - " if (yyssp >= yyss + yystacksize - 1)", - " {", - " goto yyoverflow;", - " }", - " *++yyssp = yystate;", - " *++yyvsp = yyval;", - " goto yyloop;", - "yyoverflow:", - " yyerror(\"yacc stack overflow\");", - "yyabort:", - " return (1);", - "yyaccept:", - " return (0);", - "}", - 0 -}; - - -void -write_section(char *section[]) -{ - int c; - int i; - char *s; - FILE *f; - - f = code_file; - for (i = 0; (s = section[i]); ++i) - { - ++outline; - while ((c = *s)) - { - putc(c, f); - ++s; - } - putc('\n', f); - } -} diff --git a/src/libCom/yacc/symtab.c b/src/libCom/yacc/symtab.c deleted file mode 100644 index 486835a21..000000000 --- a/src/libCom/yacc/symtab.c +++ /dev/null @@ -1,126 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - - -/* TABLE_SIZE is the number of entries in the symbol table. */ -/* TABLE_SIZE must be a power of two. */ - -#define TABLE_SIZE 1024 - - -bucket **symbol_table; -bucket *first_symbol; -bucket *last_symbol; - - -static int -hash(char *name) -{ - char *s; - int c, k; - - assert(name && *name); - s = name; - k = *s; - while ((c = *++s)) - k = (31*k + c) & (TABLE_SIZE - 1); - - return (k); -} - - -bucket * -make_bucket(char *name) -{ - bucket *bp; - - assert(name); - bp = (bucket *) MALLOC(sizeof(bucket)); - if (bp == 0) no_space(); - bp->link = 0; - bp->next = 0; - bp->name = MALLOC(strlen(name) + 1); - if (bp->name == 0) no_space(); - bp->tag = 0; - bp->value = UNDEFINED; - bp->index = 0; - bp->prec = 0; - bp-> class = UNKNOWN; - bp->assoc = TOKEN; - - if (bp->name == 0) no_space(); - strcpy(bp->name, name); - - return (bp); -} - - -bucket * -lookup(char *name) -{ - bucket *bp, **bpp; - - bpp = symbol_table + hash(name); - bp = *bpp; - - while (bp) - { - if (strcmp(name, bp->name) == 0) return (bp); - bpp = &bp->link; - bp = *bpp; - } - - *bpp = bp = make_bucket(name); - last_symbol->next = bp; - last_symbol = bp; - - return (bp); -} - -void -create_symbol_table(void) -{ - int i; - bucket *bp; - - symbol_table = (bucket **) MALLOC(TABLE_SIZE*sizeof(bucket *)); - if (symbol_table == 0) no_space(); - for (i = 0; i < TABLE_SIZE; i++) - symbol_table[i] = 0; - - bp = make_bucket("error"); - bp->index = 1; - bp->class = TERM; - - first_symbol = bp; - last_symbol = bp; - symbol_table[hash("error")] = bp; -} - - -void -free_symbol_table(void) -{ - FREE(symbol_table); - symbol_table = 0; -} - - -void -free_symbols(void) -{ - bucket *p, *q; - - for (p = first_symbol; p; p = q) - { - q = p->next; - FREE(p); - } -} diff --git a/src/libCom/yacc/verbose.c b/src/libCom/yacc/verbose.c deleted file mode 100644 index eb03cf386..000000000 --- a/src/libCom/yacc/verbose.c +++ /dev/null @@ -1,349 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "defs.h" - -static short *null_rules; - -static void log_unused(void); -static void log_conflicts(void); -static void print_state(int state); -static void print_conflicts(int state); -static void print_core(int state); -static void print_nulls(int state); -static void print_actions(int state); -static void print_shifts(action *p); -static void print_reductions(action *p, int defred); -static void print_gotos(int stateno); - - -void -verbose(void) -{ - int i; - - if (!vflag) return; - - null_rules = (short *) MALLOC(nrules*sizeof(short)); - if (null_rules == 0) no_space(); - fprintf(verbose_file, "\f\n"); - for (i = 0; i < nstates; i++) - print_state(i); - FREE(null_rules); - - if (nunused) - log_unused(); - if (SRtotal || RRtotal) - log_conflicts(); - - fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens, nvars); - fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates); -} - - -static void -log_unused(void) -{ - int i; - short *p; - - fprintf(verbose_file, "\n\nRules never reduced:\n"); - for (i = 3; i < nrules; ++i) - { - if (!rules_used[i]) - { - fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]); - for (p = ritem + rrhs[i]; *p >= 0; ++p) - fprintf(verbose_file, " %s", symbol_name[*p]); - fprintf(verbose_file, " (%d)\n", i - 2); - } - } -} - - -static void -log_conflicts(void) -{ - int i; - - fprintf(verbose_file, "\n\n"); - for (i = 0; i < nstates; i++) - { - if (SRconflicts[i] || RRconflicts[i]) - { - fprintf(verbose_file, "State %d contains ", i); - if (SRconflicts[i] == 1) - fprintf(verbose_file, "1 shift/reduce conflict"); - else if (SRconflicts[i] > 1) - fprintf(verbose_file, "%d shift/reduce conflicts", - SRconflicts[i]); - if (SRconflicts[i] && RRconflicts[i]) - fprintf(verbose_file, ", "); - if (RRconflicts[i] == 1) - fprintf(verbose_file, "1 reduce/reduce conflict"); - else if (RRconflicts[i] > 1) - fprintf(verbose_file, "%d reduce/reduce conflicts", - RRconflicts[i]); - fprintf(verbose_file, ".\n"); - } - } -} - - -static void -print_state(int state) -{ - if (state) - fprintf(verbose_file, "\n\n"); - if (SRconflicts[state] || RRconflicts[state]) - print_conflicts(state); - fprintf(verbose_file, "state %d\n", state); - print_core(state); - print_nulls(state); - print_actions(state); -} - - -static void -print_conflicts(int state) -{ - int symbol, act = 0, number = 0; - action *p; - - symbol = -1; - for (p = parser[state]; p; p = p->next) - { - if (p->suppressed == 2) - continue; - - if (p->symbol != symbol) - { - symbol = p->symbol; - number = p->number; - if (p->action_code == SHIFT) - act = SHIFT; - else - act = REDUCE; - } - else if (p->suppressed == 1) - { - if (state == final_state && symbol == 0) - { - fprintf(verbose_file, "%d: shift/reduce conflict \ -(accept, reduce %d) on $end\n", state, p->number - 2); - } - else - { - if (act == SHIFT) - { - fprintf(verbose_file, "%d: shift/reduce conflict \ -(shift %d, reduce %d) on %s\n", state, number, p->number - 2, - symbol_name[symbol]); - } - else - { - fprintf(verbose_file, "%d: reduce/reduce conflict \ -(reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2, - symbol_name[symbol]); - } - } - } - } -} - - -static void -print_core(int state) -{ - int i; - int k; - int rule; - core *statep; - short *sp; - short *sp1; - - statep = state_table[state]; - k = statep->nitems; - - for (i = 0; i < k; i++) - { - sp1 = sp = ritem + statep->items[i]; - - while (*sp >= 0) ++sp; - rule = -(*sp); - fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]); - - for (sp = ritem + rrhs[rule]; sp < sp1; sp++) - fprintf(verbose_file, "%s ", symbol_name[*sp]); - - putc('.', verbose_file); - - while (*sp >= 0) - { - fprintf(verbose_file, " %s", symbol_name[*sp]); - sp++; - } - fprintf(verbose_file, " (%d)\n", -2 - *sp); - } -} - - -static void -print_nulls(int state) -{ - action *p; - int i, j, k, nnulls; - - nnulls = 0; - for (p = parser[state]; p; p = p->next) - { - if (p->action_code == REDUCE && - (p->suppressed == 0 || p->suppressed == 1)) - { - i = p->number; - if (rrhs[i] + 1 == rrhs[i+1]) - { - for (j = 0; j < nnulls && i > null_rules[j]; ++j) - continue; - - if (j == nnulls) - { - ++nnulls; - null_rules[j] = i; - } - else if (i != null_rules[j]) - { - ++nnulls; - for (k = nnulls - 1; k > j; --k) - null_rules[k] = null_rules[k-1]; - null_rules[j] = i; - } - } - } - } - - for (i = 0; i < nnulls; ++i) - { - j = null_rules[i]; - fprintf(verbose_file, "\t%s : . (%d)\n", symbol_name[rlhs[j]], - j - 2); - } - fprintf(verbose_file, "\n"); -} - - -static void -print_actions(int stateno) -{ - action *p; - shifts *sp; - int as; - - if (stateno == final_state) - fprintf(verbose_file, "\t$end accept\n"); - - p = parser[stateno]; - if (p) - { - print_shifts(p); - print_reductions(p, defred[stateno]); - } - - sp = shift_table[stateno]; - if (sp && sp->nshifts > 0) - { - as = accessing_symbol[sp->shift[sp->nshifts - 1]]; - if (ISVAR(as)) - print_gotos(stateno); - } -} - - -static void -print_shifts(action *p) -{ - int count; - action *q; - - count = 0; - for (q = p; q; q = q->next) - { - if (q->suppressed < 2 && q->action_code == SHIFT) - ++count; - } - - if (count > 0) - { - for (; p; p = p->next) - { - if (p->action_code == SHIFT && p->suppressed == 0) - fprintf(verbose_file, "\t%s shift %d\n", - symbol_name[p->symbol], p->number); - } - } -} - - -static void -print_reductions(action *p, int defred) -{ - int k, anyreds; - action *q; - - anyreds = 0; - for (q = p; q ; q = q->next) - { - if (q->action_code == REDUCE && q->suppressed < 2) - { - anyreds = 1; - break; - } - } - - if (anyreds == 0) - fprintf(verbose_file, "\t. error\n"); - else - { - for (; p; p = p->next) - { - if (p->action_code == REDUCE && p->number != defred) - { - k = p->number - 2; - if (p->suppressed == 0) - fprintf(verbose_file, "\t%s reduce %d\n", - symbol_name[p->symbol], k); - } - } - - if (defred > 0) - fprintf(verbose_file, "\t. reduce %d\n", defred - 2); - } -} - - -static void -print_gotos(int stateno) -{ - int i, k; - int as; - short *to_state; - shifts *sp; - - putc('\n', verbose_file); - sp = shift_table[stateno]; - to_state = sp->shift; - for (i = 0; i < sp->nshifts; ++i) - { - k = to_state[i]; - as = accessing_symbol[k]; - if (ISVAR(as)) - fprintf(verbose_file, "\t%s goto %d\n", symbol_name[as], k); - } -} - diff --git a/src/libCom/yacc/warshall.c b/src/libCom/yacc/warshall.c deleted file mode 100644 index 4477074c5..000000000 --- a/src/libCom/yacc/warshall.c +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -#include "defs.h" - -static void -transitive_closure(unsigned int *R, int n) -{ - int rowsize; - unsigned i; - unsigned *rowj; - unsigned *rp; - unsigned *rend; - unsigned *ccol; - unsigned *relend; - unsigned *cword; - unsigned *rowi; - - rowsize = WORDSIZE(n); - relend = R + n*rowsize; - - cword = R; - i = 0; - rowi = R; - while (rowi < relend) - { - ccol = cword; - rowj = R; - - while (rowj < relend) - { - if (*ccol & (1 << i)) - { - rp = rowi; - rend = rowj + rowsize; - while (rowj < rend) - *rowj++ |= *rp++; - } - else - { - rowj += rowsize; - } - - ccol += rowsize; - } - - if (++i >= BITS_PER_WORD) - { - i = 0; - cword++; - } - - rowi += rowsize; - } -} - -void -reflexive_transitive_closure(unsigned int *R, int n) -{ - int rowsize; - unsigned i; - unsigned *rp; - unsigned *relend; - - transitive_closure(R, n); - - rowsize = WORDSIZE(n); - relend = R + n*rowsize; - - i = 0; - rp = R; - while (rp < relend) - { - *rp |= (1 << i); - if (++i >= BITS_PER_WORD) - { - i = 0; - rp++; - } - - rp += rowsize; - } -} diff --git a/src/libCom/yacc/yacc.html b/src/libCom/yacc/yacc.html deleted file mode 100644 index 1258b439f..000000000 --- a/src/libCom/yacc/yacc.html +++ /dev/null @@ -1,135 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - -
-
-
-
-

NAME

-     Yacc - an LALR(1) parser generator
-
-
-
-

SYNOPSIS

-     yacc [ -dlrtv ] [ -b file_prefix  ]  [  -p  symbol_prefix  ]
-     filename
-
-
-
-

DESCRIPTION

-     Yacc reads the grammar specification in  the  file  filename
-     and  generates  an LR(1) parser for it.  The parsers consist
-     of a set of LALR(1) parsing  tables  and  a  driver  routine
-     written in the C programming language.  Yacc normally writes
-     the parse tables and the driver routine to the file y.tab.c.
-
-     The following options are available:
-
-          -b file_prefix
-               The -b option changes the prefix prepended to  the
-               output   file  names  to  the  string  denoted  by
-               file_prefix.  The default prefix is the  character
-               y.
-
-          -d   The -d option causes the header file y.tab.h to be
-               written.
-
-          -l   If the -l  option  is  not  specified,  yacc  will
-               insert  #line  directives  in  the generated code.
-               The #line directives let  the  C  compiler  relate
-               errors  in the generated code to the user's origi-
-               nal code.  If the -l  option  is  specified,  yacc
-               will  not  insert  the  #line  directives.   #line
-               directives specified by the user will be retained.
-
-          -p symbol_prefix
-               The -p option  changes  the  prefix  prepended  to
-               yacc-generated  symbols  to  the string denoted by
-               symbol_prefix.  The default prefix is  the  string
-               yy.
-
-          -r   The -r option  causes  yacc  to  produce  separate
-               files for code and tables.  The code file is named
-               y.code.c, and the tables file is named y.tab.c.
-
-          -t   The -t option changes the preprocessor  directives
-               generated  by  yacc  so  that debugging statements
-               will be incorporated in the compiled code.
-
-          -v   The -v option causes a human-readable  description
-               of  the generated parser to be written to the file
-               y.output.
-
-
-     If the  environment  variable  TMPDIR  is  set,  the  string
-     denoted  by TMPDIR will be used as the name of the directory
-     where the temporary files are created.
-
-
-
-

FILES

-     y.code.c
-     y.tab.c
-     y.tab.h
-     y.output
-     /tmp/yacc.aXXXXXX
-     /tmp/yacc.tXXXXXX
-     /tmp/yacc.uXXXXXX
-
-
-
-

DIAGNOSTICS

-     If there are rules that are never  reduced,  the  number  of
-     such  rules is reported on standard error.  If there are any
-     LALR(1) conflicts, the number of conflicts  is  reported  on
-     standard error.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Man(1) output converted with -man2html -
- - diff --git a/src/libCom/yajl/Makefile b/src/libCom/yajl/Makefile deleted file mode 100644 index 39146ca79..000000000 --- a/src/libCom/yajl/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/libCom/Makefile. - -SRC_DIRS += $(LIBCOM)/yacc - -# Yet Another JSON Library -SRC_DIRS += $(LIBCOM)/yajl -INC += yajl_alloc.h -INC += yajl_common.h -INC += yajl_gen.h -INC += yajl_parse.h -# The other yajl_*.h files are for internal use only - -Com_SRCS += yajl.c -Com_SRCS += yajl_alloc.c -Com_SRCS += yajl_buf.c -Com_SRCS += yajl_encode.c -Com_SRCS += yajl_gen.c -Com_SRCS += yajl_lex.c -Com_SRCS += yajl_parser.c diff --git a/src/libCom/yajl/yajl.c b/src/libCom/yajl/yajl.c deleted file mode 100644 index 063e8f8b9..000000000 --- a/src/libCom/yajl/yajl.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_parse.h" -#include "yajl_lex.h" -#include "yajl_parser.h" -#include "yajl_alloc.h" - -const char * -yajl_status_to_string(yajl_status stat) -{ - const char * statStr = "unknown"; - switch (stat) { - case yajl_status_ok: - statStr = "ok, no error"; - break; - case yajl_status_client_canceled: - statStr = "client canceled parse"; - break; - case yajl_status_insufficient_data: - statStr = "eof was met before the parse could complete"; - break; - case yajl_status_error: - statStr = "parse error"; - break; - } - return statStr; -} - -yajl_handle -yajl_alloc(const yajl_callbacks * callbacks, - const yajl_parser_config * config, - const yajl_alloc_funcs * afs, - void * ctx) -{ - unsigned int allowComments = 0; - unsigned int validateUTF8 = 0; - yajl_handle hand = NULL; - yajl_alloc_funcs afsBuffer; - - /* first order of business is to set up memory allocation routines */ - if (afs != NULL) { - if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL) - { - return NULL; - } - } else { - yajl_set_default_alloc_funcs(&afsBuffer); - afs = &afsBuffer; - } - - hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t)); - - /* copy in pointers to allocation routines */ - memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs)); - - if (config != NULL) { - allowComments = config->allowComments; - validateUTF8 = config->checkUTF8; - } - - hand->callbacks = callbacks; - hand->ctx = ctx; - hand->lexer = yajl_lex_alloc(&(hand->alloc), allowComments, validateUTF8); - hand->bytesConsumed = 0; - hand->decodeBuf = yajl_buf_alloc(&(hand->alloc)); - yajl_bs_init(hand->stateStack, &(hand->alloc)); - - yajl_bs_push(hand->stateStack, yajl_state_start); - - return hand; -} - -void -yajl_free(yajl_handle handle) -{ - yajl_bs_free(handle->stateStack); - yajl_buf_free(handle->decodeBuf); - yajl_lex_free(handle->lexer); - YA_FREE(&(handle->alloc), handle); -} - -yajl_status -yajl_parse(yajl_handle hand, const unsigned char * jsonText, - unsigned int jsonTextLen) -{ - yajl_status status; - status = yajl_do_parse(hand, jsonText, jsonTextLen); - return status; -} - -yajl_status -yajl_parse_complete(yajl_handle hand) -{ - /* The particular case we want to handle is a trailing number. - * Further input consisting of digits could cause our interpretation - * of the number to change (buffered "1" but "2" comes in). - * A very simple approach to this is to inject whitespace to terminate - * any number in the lex buffer. - */ - return yajl_parse(hand, (const unsigned char *)" ", 1); -} - -unsigned char * -yajl_get_error(yajl_handle hand, int verbose, - const unsigned char * jsonText, unsigned int jsonTextLen) -{ - return yajl_render_error_string(hand, jsonText, jsonTextLen, verbose); -} - -unsigned int -yajl_get_bytes_consumed(yajl_handle hand) -{ - if (!hand) return 0; - else return hand->bytesConsumed; -} - - -void -yajl_free_error(yajl_handle hand, unsigned char * str) -{ - /* use memory allocation functions if set */ - YA_FREE(&(hand->alloc), str); -} - -/* XXX: add utility routines to parse from file */ diff --git a/src/libCom/yajl/yajl_alloc.c b/src/libCom/yajl/yajl_alloc.c deleted file mode 100644 index 2f6e5650c..000000000 --- a/src/libCom/yajl/yajl_alloc.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -/** - * \file yajl_alloc.h - * default memory allocation routines for yajl which use malloc/realloc and - * free - */ - -#include - -#define epicsExportSharedSymbols -#include "yajl_alloc.h" - -static void * yajl_internal_malloc(void *ctx, unsigned int sz) -{ - return malloc(sz); -} - -static void * yajl_internal_realloc(void *ctx, void * previous, - unsigned int sz) -{ - return realloc(previous, sz); -} - -static void yajl_internal_free(void *ctx, void * ptr) -{ - free(ptr); -} - -void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf) -{ - yaf->malloc = yajl_internal_malloc; - yaf->free = yajl_internal_free; - yaf->realloc = yajl_internal_realloc; - yaf->ctx = NULL; -} - diff --git a/src/libCom/yajl/yajl_alloc.h b/src/libCom/yajl/yajl_alloc.h deleted file mode 100644 index 3935eef58..000000000 --- a/src/libCom/yajl/yajl_alloc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -/** - * \file yajl_alloc.h - * default memory allocation routines for yajl which use malloc/realloc and - * free - */ - -#ifndef __YAJL_ALLOC_H__ -#define __YAJL_ALLOC_H__ - -#include "yajl_common.h" - -#define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz)) -#define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr)) -#define YA_REALLOC(afs, ptr, sz) (afs)->realloc((afs)->ctx, (ptr), (sz)) - -YAJL_API void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf); - -#endif diff --git a/src/libCom/yajl/yajl_buf.c b/src/libCom/yajl/yajl_buf.c deleted file mode 100644 index 132633c9a..000000000 --- a/src/libCom/yajl/yajl_buf.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_buf.h" - -#define YAJL_BUF_INIT_SIZE 2048 - -struct yajl_buf_t { - unsigned int len; - unsigned int used; - unsigned char * data; - yajl_alloc_funcs * alloc; -}; - -static -void yajl_buf_ensure_available(yajl_buf buf, unsigned int want) -{ - unsigned int need; - - assert(buf != NULL); - - /* first call */ - if (buf->data == NULL) { - buf->len = YAJL_BUF_INIT_SIZE; - buf->data = (unsigned char *) YA_MALLOC(buf->alloc, buf->len); - buf->data[0] = 0; - } - - need = buf->len; - - while (want >= (need - buf->used)) need <<= 1; - - if (need != buf->len) { - buf->data = (unsigned char *) YA_REALLOC(buf->alloc, buf->data, need); - buf->len = need; - } -} - -yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc) -{ - yajl_buf b = YA_MALLOC(alloc, sizeof(struct yajl_buf_t)); - memset((void *) b, 0, sizeof(struct yajl_buf_t)); - b->alloc = alloc; - return b; -} - -void yajl_buf_free(yajl_buf buf) -{ - assert(buf != NULL); - if (buf->data) YA_FREE(buf->alloc, buf->data); - YA_FREE(buf->alloc, buf); -} - -void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len) -{ - yajl_buf_ensure_available(buf, len); - if (len > 0) { - assert(data != NULL); - memcpy(buf->data + buf->used, data, len); - buf->used += len; - buf->data[buf->used] = 0; - } -} - -void yajl_buf_clear(yajl_buf buf) -{ - buf->used = 0; - if (buf->data) buf->data[buf->used] = 0; -} - -const unsigned char * yajl_buf_data(yajl_buf buf) -{ - return buf->data; -} - -unsigned int yajl_buf_len(yajl_buf buf) -{ - return buf->used; -} - -void -yajl_buf_truncate(yajl_buf buf, unsigned int len) -{ - assert(len <= buf->used); - buf->used = len; -} diff --git a/src/libCom/yajl/yajl_buf.h b/src/libCom/yajl/yajl_buf.h deleted file mode 100644 index a6dcbe9a5..000000000 --- a/src/libCom/yajl/yajl_buf.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#ifndef __YAJL_BUF_H__ -#define __YAJL_BUF_H__ - -#include "yajl_common.h" -#include "yajl_alloc.h" - -/* - * Implementation/performance notes. If this were moved to a header - * only implementation using #define's where possible we might be - * able to sqeeze a little performance out of the guy by killing function - * call overhead. YMMV. - */ - -/** - * yajl_buf is a buffer with exponential growth. the buffer ensures that - * you are always null padded. - */ -typedef struct yajl_buf_t * yajl_buf; - -/* allocate a new buffer */ -yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc); - -/* free the buffer */ -void yajl_buf_free(yajl_buf buf); - -/* append a number of bytes to the buffer */ -void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len); - -/* empty the buffer */ -void yajl_buf_clear(yajl_buf buf); - -/* get a pointer to the beginning of the buffer */ -const unsigned char * yajl_buf_data(yajl_buf buf); - -/* get the length of the buffer */ -unsigned int yajl_buf_len(yajl_buf buf); - -/* truncate the buffer */ -void yajl_buf_truncate(yajl_buf buf, unsigned int len); - -#endif diff --git a/src/libCom/yajl/yajl_bytestack.h b/src/libCom/yajl/yajl_bytestack.h deleted file mode 100644 index 3b49d17f9..000000000 --- a/src/libCom/yajl/yajl_bytestack.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -/* - * A header only implementation of a simple stack of bytes, used in YAJL - * to maintain parse state. - */ - -#ifndef __YAJL_BYTESTACK_H__ -#define __YAJL_BYTESTACK_H__ - -#include "yajl_common.h" - -#define YAJL_BS_INC 128 - -typedef struct yajl_bytestack_t -{ - unsigned char * stack; - unsigned int size; - unsigned int used; - yajl_alloc_funcs * yaf; -} yajl_bytestack; - -/* initialize a bytestack */ -#define yajl_bs_init(obs, _yaf) { \ - (obs).stack = NULL; \ - (obs).size = 0; \ - (obs).used = 0; \ - (obs).yaf = (_yaf); \ - } \ - - -/* initialize a bytestack */ -#define yajl_bs_free(obs) \ - if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack); - -#define yajl_bs_current(obs) \ - (assert((obs).used > 0), (obs).stack[(obs).used - 1]) - -#define yajl_bs_push(obs, byte) { \ - if (((obs).size - (obs).used) == 0) { \ - (obs).size += YAJL_BS_INC; \ - (obs).stack = (obs).yaf->realloc((obs).yaf->ctx,\ - (void *) (obs).stack, (obs).size);\ - } \ - (obs).stack[((obs).used)++] = (byte); \ -} - -/* removes the top item of the stack, returns nothing */ -#define yajl_bs_pop(obs) { ((obs).used)--; } - -#define yajl_bs_set(obs, byte) \ - (obs).stack[((obs).used) - 1] = (byte); - - -#endif diff --git a/src/libCom/yajl/yajl_common.h b/src/libCom/yajl/yajl_common.h deleted file mode 100644 index b9badbf1e..000000000 --- a/src/libCom/yajl/yajl_common.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#ifndef __YAJL_COMMON_H__ -#define __YAJL_COMMON_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define YAJL_MAX_DEPTH 128 - -#define YAJL_API epicsShareFunc - -/** pointer to a malloc function, supporting client overriding memory - * allocation routines */ -typedef void * (*yajl_malloc_func)(void *ctx, unsigned int sz); - -/** pointer to a free function, supporting client overriding memory - * allocation routines */ -typedef void (*yajl_free_func)(void *ctx, void * ptr); - -/** pointer to a realloc function which can resize an allocation. */ -typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, unsigned int sz); - -/** A structure which can be passed to yajl_*_alloc routines to allow the - * client to specify memory allocation functions to be used. */ -typedef struct -{ - /** pointer to a function that can allocate uninitialized memory */ - yajl_malloc_func malloc; - /** pointer to a function that can resize memory allocations */ - yajl_realloc_func realloc; - /** pointer to a function that can free memory allocated using - * reallocFunction or mallocFunction */ - yajl_free_func free; - /** a context pointer that will be passed to above allocation routines */ - void * ctx; -} yajl_alloc_funcs; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/yajl/yajl_encode.c b/src/libCom/yajl/yajl_encode.c deleted file mode 100644 index d6f9dc0fe..000000000 --- a/src/libCom/yajl/yajl_encode.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_encode.h" - -static void CharToHex(unsigned char c, char * hexBuf) -{ - const char * hexchar = "0123456789ABCDEF"; - hexBuf[0] = hexchar[c >> 4]; - hexBuf[1] = hexchar[c & 0x0F]; -} - -void -yajl_string_encode(yajl_buf buf, const unsigned char * str, - unsigned int len) -{ - yajl_string_encode2((const yajl_print_t) &yajl_buf_append, buf, str, len); -} - -void -yajl_string_encode2(const yajl_print_t print, - void * ctx, - const unsigned char * str, - unsigned int len) -{ - unsigned int beg = 0; - unsigned int end = 0; - char hexBuf[7]; - hexBuf[0] = '\\'; hexBuf[1] = 'u'; hexBuf[2] = '0'; hexBuf[3] = '0'; - hexBuf[6] = 0; - - while (end < len) { - const char * escaped = NULL; - switch (str[end]) { - case '\r': escaped = "\\r"; break; - case '\n': escaped = "\\n"; break; - case '\\': escaped = "\\\\"; break; - /* case '/': escaped = "\\/"; break; */ - case '"': escaped = "\\\""; break; - case '\f': escaped = "\\f"; break; - case '\b': escaped = "\\b"; break; - case '\t': escaped = "\\t"; break; - default: - if ((unsigned char) str[end] < 32) { - CharToHex(str[end], hexBuf + 4); - escaped = hexBuf; - } - break; - } - if (escaped != NULL) { - print(ctx, (const char *) (str + beg), end - beg); - print(ctx, escaped, (unsigned int)strlen(escaped)); - beg = ++end; - } else { - ++end; - } - } - print(ctx, (const char *) (str + beg), end - beg); -} - -static void hexToDigit(unsigned int * val, const unsigned char * hex) -{ - unsigned int i; - for (i=0;i<4;i++) { - unsigned char c = hex[i]; - if (c >= 'A') c = (c & ~0x20) - 7; - c -= '0'; - assert(!(c & 0xF0)); - *val = (*val << 4) | c; - } -} - -static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf) -{ - if (codepoint < 0x80) { - utf8Buf[0] = (char) codepoint; - utf8Buf[1] = 0; - } else if (codepoint < 0x0800) { - utf8Buf[0] = (char) ((codepoint >> 6) | 0xC0); - utf8Buf[1] = (char) ((codepoint & 0x3F) | 0x80); - utf8Buf[2] = 0; - } else if (codepoint < 0x10000) { - utf8Buf[0] = (char) ((codepoint >> 12) | 0xE0); - utf8Buf[1] = (char) (((codepoint >> 6) & 0x3F) | 0x80); - utf8Buf[2] = (char) ((codepoint & 0x3F) | 0x80); - utf8Buf[3] = 0; - } else if (codepoint < 0x200000) { - utf8Buf[0] =(char)((codepoint >> 18) | 0xF0); - utf8Buf[1] =(char)(((codepoint >> 12) & 0x3F) | 0x80); - utf8Buf[2] =(char)(((codepoint >> 6) & 0x3F) | 0x80); - utf8Buf[3] =(char)((codepoint & 0x3F) | 0x80); - utf8Buf[4] = 0; - } else { - utf8Buf[0] = '?'; - utf8Buf[1] = 0; - } -} - -void yajl_string_decode(yajl_buf buf, const unsigned char * str, - unsigned int len) -{ - unsigned int beg = 0; - unsigned int end = 0; - - while (end < len) { - if (str[end] == '\\') { - char utf8Buf[5]; - const char * unescaped = "?"; - yajl_buf_append(buf, str + beg, end - beg); - switch (str[++end]) { - case 'r': unescaped = "\r"; break; - case 'n': unescaped = "\n"; break; - case '\\': unescaped = "\\"; break; - case '/': unescaped = "/"; break; - case '"': unescaped = "\""; break; - case 'f': unescaped = "\f"; break; - case 'b': unescaped = "\b"; break; - case 't': unescaped = "\t"; break; - case 'u': { - unsigned int codepoint = 0; - hexToDigit(&codepoint, str + ++end); - end+=3; - /* check if this is a surrogate */ - if ((codepoint & 0xFC00) == 0xD800) { - end++; - if (str[end] == '\\' && str[end + 1] == 'u') { - unsigned int surrogate = 0; - hexToDigit(&surrogate, str + end + 2); - codepoint = - (((codepoint & 0x3F) << 10) | - ((((codepoint >> 6) & 0xF) + 1) << 16) | - (surrogate & 0x3FF)); - end += 5; - } else { - unescaped = "?"; - break; - } - } - - Utf32toUtf8(codepoint, utf8Buf); - unescaped = utf8Buf; - - if (codepoint == 0) { - yajl_buf_append(buf, unescaped, 1); - beg = ++end; - continue; - } - - break; - } - default: - assert("this should never happen" == NULL); - } - yajl_buf_append(buf, unescaped, (unsigned int)strlen(unescaped)); - beg = ++end; - } else { - end++; - } - } - yajl_buf_append(buf, str + beg, end - beg); -} diff --git a/src/libCom/yajl/yajl_encode.h b/src/libCom/yajl/yajl_encode.h deleted file mode 100644 index 3e3b0923d..000000000 --- a/src/libCom/yajl/yajl_encode.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#ifndef __YAJL_ENCODE_H__ -#define __YAJL_ENCODE_H__ - -#include "yajl_buf.h" -#include "yajl_gen.h" - -void yajl_string_encode2(const yajl_print_t printer, - void * ctx, - const unsigned char * str, - unsigned int length); - -void yajl_string_encode(yajl_buf buf, const unsigned char * str, - unsigned int length); - -void yajl_string_decode(yajl_buf buf, const unsigned char * str, - unsigned int length); - -#endif diff --git a/src/libCom/yajl/yajl_gen.c b/src/libCom/yajl/yajl_gen.c deleted file mode 100644 index 8d93e2726..000000000 --- a/src/libCom/yajl/yajl_gen.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "epicsMath.h" -#include "yajl_gen.h" -#include "yajl_buf.h" -#include "yajl_encode.h" - -typedef enum { - yajl_gen_start, - yajl_gen_map_start, - yajl_gen_map_key, - yajl_gen_map_val, - yajl_gen_array_start, - yajl_gen_in_array, - yajl_gen_complete, - yajl_gen_error -} yajl_gen_state; - -struct yajl_gen_t -{ - unsigned int depth; - unsigned int pretty; - const char * indentString; - yajl_gen_state state[YAJL_MAX_DEPTH]; - yajl_print_t print; - void * ctx; /* yajl_buf */ - /* memory allocation routines */ - yajl_alloc_funcs alloc; -}; - -yajl_gen -yajl_gen_alloc(const yajl_gen_config * config, - const yajl_alloc_funcs * afs) -{ - return yajl_gen_alloc2(NULL, config, afs, NULL); -} - -yajl_gen -yajl_gen_alloc2(const yajl_print_t callback, - const yajl_gen_config * config, - const yajl_alloc_funcs * afs, - void * ctx) -{ - yajl_gen g = NULL; - yajl_alloc_funcs afsBuffer; - - /* first order of business is to set up memory allocation routines */ - if (afs != NULL) { - if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL) - { - return NULL; - } - } else { - yajl_set_default_alloc_funcs(&afsBuffer); - afs = &afsBuffer; - } - - g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t)); - if (!g) return NULL; - - memset((void *) g, 0, sizeof(struct yajl_gen_t)); - /* copy in pointers to allocation routines */ - memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs)); - - if (config) { - const char *indent = config->indentString; - g->pretty = config->beautify; - g->indentString = config->indentString; - if (indent) { - for (; *indent; indent++) { - if (*indent != '\n' - && *indent != '\v' - && *indent != '\f' - && *indent != '\t' - && *indent != '\r' - && *indent != ' ') { - g->indentString = NULL; - break; - } - } - } - if (!g->indentString) { - g->indentString = " "; - } - } - - if (callback) { - g->print = callback; - g->ctx = ctx; - } else { - g->print = (yajl_print_t)&yajl_buf_append; - g->ctx = yajl_buf_alloc(&(g->alloc)); - } - - return g; -} - -void -yajl_gen_free(yajl_gen g) -{ - if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_free((yajl_buf)g->ctx); - YA_FREE(&(g->alloc), g); -} - -#define INSERT_SEP \ - if (g->state[g->depth] == yajl_gen_map_key || \ - g->state[g->depth] == yajl_gen_in_array) { \ - g->print(g->ctx, ",", 1); \ - if (g->pretty) g->print(g->ctx, "\n", 1); \ - } else if (g->state[g->depth] == yajl_gen_map_val) { \ - g->print(g->ctx, ":", 1); \ - if (g->pretty) g->print(g->ctx, " ", 1); \ - } - -#define INSERT_WHITESPACE \ - if (g->pretty) { \ - if (g->state[g->depth] != yajl_gen_map_val) { \ - unsigned int _i; \ - for (_i=0;_idepth;_i++) \ - g->print(g->ctx, \ - g->indentString, \ - (unsigned int)strlen(g->indentString)); \ - } \ - } - -#define ENSURE_NOT_KEY \ - if (g->state[g->depth] == yajl_gen_map_key || \ - g->state[g->depth] == yajl_gen_map_start) { \ - return yajl_gen_keys_must_be_strings; \ - } \ - -/* check that we're not complete, or in error state. in a valid state - * to be generating */ -#define ENSURE_VALID_STATE \ - if (g->state[g->depth] == yajl_gen_error) { \ - return yajl_gen_in_error_state;\ - } else if (g->state[g->depth] == yajl_gen_complete) { \ - return yajl_gen_generation_complete; \ - } - -#define INCREMENT_DEPTH \ - if (++(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded; - -#define DECREMENT_DEPTH \ - if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded; - -#define APPENDED_ATOM \ - switch (g->state[g->depth]) { \ - case yajl_gen_start: \ - g->state[g->depth] = yajl_gen_complete; \ - break; \ - case yajl_gen_map_start: \ - case yajl_gen_map_key: \ - g->state[g->depth] = yajl_gen_map_val; \ - break; \ - case yajl_gen_array_start: \ - g->state[g->depth] = yajl_gen_in_array; \ - break; \ - case yajl_gen_map_val: \ - g->state[g->depth] = yajl_gen_map_key; \ - break; \ - default: \ - break; \ - } \ - -#define FINAL_NEWLINE \ - if (g->pretty && g->state[g->depth] == yajl_gen_complete) \ - g->print(g->ctx, "\n", 1); - -yajl_gen_status -yajl_gen_integer(yajl_gen g, long int number) -{ - char i[32]; - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - sprintf(i, "%ld", number); - g->print(g->ctx, i, (unsigned int)strlen(i)); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_double(yajl_gen g, double number) -{ - char i[32]; - ENSURE_VALID_STATE; ENSURE_NOT_KEY; - if (isnan(number) || isinf(number)) return yajl_gen_invalid_number; - INSERT_SEP; INSERT_WHITESPACE; - sprintf(i, "%.20g", number); - g->print(g->ctx, i, (unsigned int)strlen(i)); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_number(yajl_gen g, const char * s, unsigned int l) -{ - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - g->print(g->ctx, s, l); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_string(yajl_gen g, const unsigned char * str, - unsigned int len) -{ - ENSURE_VALID_STATE; INSERT_SEP; INSERT_WHITESPACE; - g->print(g->ctx, "\"", 1); - yajl_string_encode2(g->print, g->ctx, str, len); - g->print(g->ctx, "\"", 1); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_null(yajl_gen g) -{ - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - g->print(g->ctx, "null", strlen("null")); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_bool(yajl_gen g, int boolean) -{ - const char * val = boolean ? "true" : "false"; - - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - g->print(g->ctx, val, (unsigned int)strlen(val)); - APPENDED_ATOM; - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_map_open(yajl_gen g) -{ - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - INCREMENT_DEPTH; - - g->state[g->depth] = yajl_gen_map_start; - g->print(g->ctx, "{", 1); - if (g->pretty) g->print(g->ctx, "\n", 1); - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_map_close(yajl_gen g) -{ - ENSURE_VALID_STATE; - DECREMENT_DEPTH; - - if (g->pretty) g->print(g->ctx, "\n", 1); - APPENDED_ATOM; - INSERT_WHITESPACE; - g->print(g->ctx, "}", 1); - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_array_open(yajl_gen g) -{ - ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; - INCREMENT_DEPTH; - g->state[g->depth] = yajl_gen_array_start; - g->print(g->ctx, "[", 1); - if (g->pretty) g->print(g->ctx, "\n", 1); - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_array_close(yajl_gen g) -{ - ENSURE_VALID_STATE; - DECREMENT_DEPTH; - if (g->pretty) g->print(g->ctx, "\n", 1); - APPENDED_ATOM; - INSERT_WHITESPACE; - g->print(g->ctx, "]", 1); - FINAL_NEWLINE; - return yajl_gen_status_ok; -} - -yajl_gen_status -yajl_gen_get_buf(yajl_gen g, const unsigned char ** buf, - unsigned int * len) -{ - if (g->print != (yajl_print_t)&yajl_buf_append) return yajl_gen_no_buf; - *buf = yajl_buf_data((yajl_buf)g->ctx); - *len = yajl_buf_len((yajl_buf)g->ctx); - return yajl_gen_status_ok; -} - -void -yajl_gen_clear(yajl_gen g) -{ - if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_clear((yajl_buf)g->ctx); -} diff --git a/src/libCom/yajl/yajl_gen.h b/src/libCom/yajl/yajl_gen.h deleted file mode 100644 index 34b147596..000000000 --- a/src/libCom/yajl/yajl_gen.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -/** - * \file yajl_gen.h - * Interface to YAJL's JSON generation facilities. - */ - -#ifndef __YAJL_GEN_H__ -#define __YAJL_GEN_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - /** generator status codes */ - typedef enum { - /** no error */ - yajl_gen_status_ok = 0, - /** at a point where a map key is generated, a function other than - * yajl_gen_string was called */ - yajl_gen_keys_must_be_strings, - /** YAJL's maximum generation depth was exceeded. see - * YAJL_MAX_DEPTH */ - yajl_max_depth_exceeded, - /** A generator function (yajl_gen_XXX) was called while in an error - * state */ - yajl_gen_in_error_state, - /** A complete JSON document has been generated */ - yajl_gen_generation_complete, - /** yajl_gen_double was passed an invalid floating point value - * (infinity or NaN). */ - yajl_gen_invalid_number, - /** A print callback was passed in, so there is no internal - * buffer to get from */ - yajl_gen_no_buf - } yajl_gen_status; - - /** an opaque handle to a generator */ - typedef struct yajl_gen_t * yajl_gen; - - /** a callback used for "printing" the results. */ - typedef void (*yajl_print_t)(void * ctx, - const char * str, - unsigned int len); - - /** configuration structure for the generator */ - typedef struct { - /** generate indented (beautiful) output */ - unsigned int beautify; - /** an opportunity to define an indent string. such as \\t or - * some number of spaces. default is four spaces ' '. This - * member is only relevant when beautify is true */ - const char * indentString; - } yajl_gen_config; - - /** allocate a generator handle - * \param config a pointer to a structure containing parameters which - * configure the behavior of the json generator - * \param allocFuncs an optional pointer to a structure which allows - * the client to overide the memory allocation - * used by yajl. May be NULL, in which case - * malloc/free/realloc will be used. - * - * \returns an allocated handle on success, NULL on failure (bad params) - */ - YAJL_API yajl_gen yajl_gen_alloc(const yajl_gen_config * config, - const yajl_alloc_funcs * allocFuncs); - - /** allocate a generator handle that will print to the specified - * callback rather than storing the results in an internal buffer. - * \param callback a pointer to a printer function. May be NULL - * in which case, the results will be store in an - * internal buffer. - * \param config a pointer to a structure containing parameters - * which configure the behavior of the json - * generator. - * \param allocFuncs an optional pointer to a structure which allows - * the client to overide the memory allocation - * used by yajl. May be NULL, in which case - * malloc/free/realloc will be used. - * \param ctx a context pointer that will be passed to the - * printer callback. - * - * \returns an allocated handle on success, NULL on failure (bad params) - */ - YAJL_API yajl_gen yajl_gen_alloc2(const yajl_print_t callback, - const yajl_gen_config * config, - const yajl_alloc_funcs * allocFuncs, - void * ctx); - - /** free a generator handle */ - YAJL_API void yajl_gen_free(yajl_gen handle); - - YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long int number); - /** generate a floating point number. number may not be infinity or - * NaN, as these have no representation in JSON. In these cases the - * generator will return 'yajl_gen_invalid_number' */ - YAJL_API yajl_gen_status yajl_gen_double(yajl_gen hand, double number); - YAJL_API yajl_gen_status yajl_gen_number(yajl_gen hand, - const char * num, - unsigned int len); - YAJL_API yajl_gen_status yajl_gen_string(yajl_gen hand, - const unsigned char * str, - unsigned int len); - YAJL_API yajl_gen_status yajl_gen_null(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_bool(yajl_gen hand, int boolean); - YAJL_API yajl_gen_status yajl_gen_map_open(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_map_close(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_array_open(yajl_gen hand); - YAJL_API yajl_gen_status yajl_gen_array_close(yajl_gen hand); - - /** access the null terminated generator buffer. If incrementally - * outputing JSON, one should call yajl_gen_clear to clear the - * buffer. This allows stream generation. */ - YAJL_API yajl_gen_status yajl_gen_get_buf(yajl_gen hand, - const unsigned char ** buf, - unsigned int * len); - - /** clear yajl's output buffer, but maintain all internal generation - * state. This function will not "reset" the generator state, and is - * intended to enable incremental JSON outputing. */ - YAJL_API void yajl_gen_clear(yajl_gen hand); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/yajl/yajl_lex.c b/src/libCom/yajl/yajl_lex.c deleted file mode 100644 index 3abd21698..000000000 --- a/src/libCom/yajl/yajl_lex.c +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_lex.h" -#include "yajl_buf.h" - -#ifdef YAJL_LEXER_DEBUG -static const char * -tokToStr(yajl_tok tok) -{ - switch (tok) { - case yajl_tok_bool: return "bool"; - case yajl_tok_colon: return "colon"; - case yajl_tok_comma: return "comma"; - case yajl_tok_eof: return "eof"; - case yajl_tok_error: return "error"; - case yajl_tok_left_brace: return "brace"; - case yajl_tok_left_bracket: return "bracket"; - case yajl_tok_null: return "null"; - case yajl_tok_integer: return "integer"; - case yajl_tok_double: return "double"; - case yajl_tok_right_brace: return "brace"; - case yajl_tok_right_bracket: return "bracket"; - case yajl_tok_string: return "string"; - case yajl_tok_string_with_escapes: return "string_with_escapes"; - } - return "unknown"; -} -#endif - -/* Impact of the stream parsing feature on the lexer: - * - * YAJL support stream parsing. That is, the ability to parse the first - * bits of a chunk of JSON before the last bits are available (still on - * the network or disk). This makes the lexer more complex. The - * responsibility of the lexer is to handle transparently the case where - * a chunk boundary falls in the middle of a token. This is - * accomplished is via a buffer and a character reading abstraction. - * - * Overview of implementation - * - * When we lex to end of input string before end of token is hit, we - * copy all of the input text composing the token into our lexBuf. - * - * Every time we read a character, we do so through the readChar function. - * readChar's responsibility is to handle pulling all chars from the buffer - * before pulling chars from input text - */ - -struct yajl_lexer_t { - /* the overal line and char offset into the data */ - unsigned int lineOff; - unsigned int charOff; - - /* error */ - yajl_lex_error error; - - /* a input buffer to handle the case where a token is spread over - * multiple chunks */ - yajl_buf buf; - - /* in the case where we have data in the lexBuf, bufOff holds - * the current offset into the lexBuf. */ - unsigned int bufOff; - - /* are we using the lex buf? */ - unsigned int bufInUse; - - /* shall we allow comments? */ - unsigned int allowComments; - - /* shall we validate utf8 inside strings? */ - unsigned int validateUTF8; - - yajl_alloc_funcs * alloc; -}; - -#define readChar(lxr, txt, off) \ - (((lxr)->bufInUse && yajl_buf_len((lxr)->buf) && lxr->bufOff < yajl_buf_len((lxr)->buf)) ? \ - (*((const unsigned char *) yajl_buf_data((lxr)->buf) + ((lxr)->bufOff)++)) : \ - ((txt)[(*(off))++])) - -#define unreadChar(lxr, off) ((*(off) > 0) ? (*(off))-- : ((lxr)->bufOff--)) - -yajl_lexer -yajl_lex_alloc(yajl_alloc_funcs * alloc, - unsigned int allowComments, unsigned int validateUTF8) -{ - yajl_lexer lxr = (yajl_lexer) YA_MALLOC(alloc, sizeof(struct yajl_lexer_t)); - memset((void *) lxr, 0, sizeof(struct yajl_lexer_t)); - lxr->buf = yajl_buf_alloc(alloc); - lxr->allowComments = allowComments; - lxr->validateUTF8 = validateUTF8; - lxr->alloc = alloc; - return lxr; -} - -void -yajl_lex_free(yajl_lexer lxr) -{ - yajl_buf_free(lxr->buf); - YA_FREE(lxr->alloc, lxr); - return; -} - -/* a lookup table which lets us quickly determine three things: - * VEC - valid escaped conrol char - * IJC - invalid json char - * VHC - valid hex char - * note. the solidus '/' may be escaped or not. - * note. the - */ -#define VEC 1 -#define IJC 2 -#define VHC 4 -static const char charLookupTable[256] = -{ -/*00*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , -/*08*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , -/*10*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , -/*18*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , - -/*20*/ 0 , 0 , VEC|IJC, 0 , 0 , 0 , 0 , 0 , -/*28*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , VEC , -/*30*/ VHC , VHC , VHC , VHC , VHC , VHC , VHC , VHC , -/*38*/ VHC , VHC , 0 , 0 , 0 , 0 , 0 , 0 , - -/*40*/ 0 , VHC , VHC , VHC , VHC , VHC , VHC , 0 , -/*48*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -/*50*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -/*58*/ 0 , 0 , 0 , 0 , VEC|IJC, 0 , 0 , 0 , - -/*60*/ 0 , VHC , VEC|VHC, VHC , VHC , VHC , VEC|VHC, 0 , -/*68*/ 0 , 0 , 0 , 0 , 0 , 0 , VEC , 0 , -/*70*/ 0 , 0 , VEC , 0 , VEC , 0 , 0 , 0 , -/*78*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - -/* include these so we don't have to always check the range of the char */ - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , - 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 -}; - -/** process a variable length utf8 encoded codepoint. - * - * returns: - * yajl_tok_string - if valid utf8 char was parsed and offset was - * advanced - * yajl_tok_eof - if end of input was hit before validation could - * complete - * yajl_tok_error - if invalid utf8 was encountered - * - * NOTE: on error the offset will point to the first char of the - * invalid utf8 */ -#define UTF8_CHECK_EOF if (*offset >= jsonTextLen) { return yajl_tok_eof; } - -static yajl_tok -yajl_lex_utf8_char(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset, - unsigned char curChar) -{ - if (curChar <= 0x7f) { - /* single byte */ - return yajl_tok_string; - } else if ((curChar >> 5) == 0x6) { - /* two byte */ - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) return yajl_tok_string; - } else if ((curChar >> 4) == 0x0e) { - /* three byte */ - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) { - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) return yajl_tok_string; - } - } else if ((curChar >> 3) == 0x1e) { - /* four byte */ - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) { - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) { - UTF8_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if ((curChar >> 6) == 0x2) return yajl_tok_string; - } - } - } - - return yajl_tok_error; -} - -/* lex a string. input is the lexer, pointer to beginning of - * json text, and start of string (offset). - * a token is returned which has the following meanings: - * yajl_tok_string: lex of string was successful. offset points to - * terminating '"'. - * yajl_tok_eof: end of text was encountered before we could complete - * the lex. - * yajl_tok_error: embedded in the string were unallowable chars. offset - * points to the offending char - */ -#define STR_CHECK_EOF \ -if (*offset >= jsonTextLen) { \ - tok = yajl_tok_eof; \ - goto finish_string_lex; \ -} - -static yajl_tok -yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset) -{ - yajl_tok tok = yajl_tok_error; - int hasEscapes = 0; - - for (;;) { - unsigned char curChar; - - STR_CHECK_EOF; - - curChar = readChar(lexer, jsonText, offset); - - /* quote terminates */ - if (curChar == '"') { - tok = yajl_tok_string; - break; - } - /* backslash escapes a set of control chars, */ - else if (curChar == '\\') { - hasEscapes = 1; - STR_CHECK_EOF; - - /* special case \u */ - curChar = readChar(lexer, jsonText, offset); - if (curChar == 'u') { - unsigned int i = 0; - - for (i=0;i<4;i++) { - STR_CHECK_EOF; - curChar = readChar(lexer, jsonText, offset); - if (!(charLookupTable[curChar] & VHC)) { - /* back up to offending char */ - unreadChar(lexer, offset); - lexer->error = yajl_lex_string_invalid_hex_char; - goto finish_string_lex; - } - } - } else if (!(charLookupTable[curChar] & VEC)) { - /* back up to offending char */ - unreadChar(lexer, offset); - lexer->error = yajl_lex_string_invalid_escaped_char; - goto finish_string_lex; - } - } - /* when not validating UTF8 it's a simple table lookup to determine - * if the present character is invalid */ - else if(charLookupTable[curChar] & IJC) { - /* back up to offending char */ - unreadChar(lexer, offset); - lexer->error = yajl_lex_string_invalid_json_char; - goto finish_string_lex; - } - /* when in validate UTF8 mode we need to do some extra work */ - else if (lexer->validateUTF8) { - yajl_tok t = yajl_lex_utf8_char(lexer, jsonText, jsonTextLen, - offset, curChar); - - if (t == yajl_tok_eof) { - tok = yajl_tok_eof; - goto finish_string_lex; - } else if (t == yajl_tok_error) { - lexer->error = yajl_lex_string_invalid_utf8; - goto finish_string_lex; - } - } - /* accept it, and move on */ - } - finish_string_lex: - /* tell our buddy, the parser, wether he needs to process this string - * again */ - if (hasEscapes && tok == yajl_tok_string) { - tok = yajl_tok_string_with_escapes; - } - - return tok; -} - -#define RETURN_IF_EOF if (*offset >= jsonTextLen) return yajl_tok_eof; - -static yajl_tok -yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset) -{ - /** XXX: numbers are the only entities in json that we must lex - * _beyond_ in order to know that they are complete. There - * is an ambiguous case for integers at EOF. */ - - unsigned char c; - - yajl_tok tok = yajl_tok_integer; - - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - - /* optional leading minus */ - if (c == '-') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } - - /* a single zero, or a series of integers */ - if (c == '0') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } else if (c >= '1' && c <= '9') { - do { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } while (c >= '0' && c <= '9'); - } else { - unreadChar(lexer, offset); - lexer->error = yajl_lex_missing_integer_after_minus; - return yajl_tok_error; - } - - /* optional fraction (indicates this is floating point) */ - if (c == '.') { - int numRd = 0; - - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - - while (c >= '0' && c <= '9') { - numRd++; - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } - - if (!numRd) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_missing_integer_after_decimal; - return yajl_tok_error; - } - tok = yajl_tok_double; - } - - /* optional exponent (indicates this is floating point) */ - if (c == 'e' || c == 'E') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - - /* optional sign */ - if (c == '+' || c == '-') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } - - if (c >= '0' && c <= '9') { - do { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } while (c >= '0' && c <= '9'); - } else { - unreadChar(lexer, offset); - lexer->error = yajl_lex_missing_integer_after_exponent; - return yajl_tok_error; - } - tok = yajl_tok_double; - } - - /* we always go "one too far" */ - unreadChar(lexer, offset); - - return tok; -} - -static yajl_tok -yajl_lex_comment(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset) -{ - unsigned char c; - - yajl_tok tok = yajl_tok_comment; - - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - - /* either slash or star expected */ - if (c == '/') { - /* now we throw away until end of line */ - do { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - } while (c != '\n'); - } else if (c == '*') { - /* now we throw away until end of comment */ - for (;;) { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - if (c == '*') { - RETURN_IF_EOF; - c = readChar(lexer, jsonText, offset); - if (c == '/') { - break; - } else { - unreadChar(lexer, offset); - } - } - } - } else { - lexer->error = yajl_lex_invalid_char; - tok = yajl_tok_error; - } - - return tok; -} - -yajl_tok -yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset, - const unsigned char ** outBuf, unsigned int * outLen) -{ - yajl_tok tok = yajl_tok_error; - unsigned char c; - unsigned int startOffset = *offset; - - *outBuf = NULL; - *outLen = 0; - - for (;;) { - assert(*offset <= jsonTextLen); - - if (*offset >= jsonTextLen) { - tok = yajl_tok_eof; - goto lexed; - } - - c = readChar(lexer, jsonText, offset); - - switch (c) { - case '{': - tok = yajl_tok_left_bracket; - goto lexed; - case '}': - tok = yajl_tok_right_bracket; - goto lexed; - case '[': - tok = yajl_tok_left_brace; - goto lexed; - case ']': - tok = yajl_tok_right_brace; - goto lexed; - case ',': - tok = yajl_tok_comma; - goto lexed; - case ':': - tok = yajl_tok_colon; - goto lexed; - case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': - startOffset++; - break; - case 't': { - const char * want = "rue"; - do { - if (*offset >= jsonTextLen) { - tok = yajl_tok_eof; - goto lexed; - } - c = readChar(lexer, jsonText, offset); - if (c != *want) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_invalid_string; - tok = yajl_tok_error; - goto lexed; - } - } while (*(++want)); - tok = yajl_tok_bool; - goto lexed; - } - case 'f': { - const char * want = "alse"; - do { - if (*offset >= jsonTextLen) { - tok = yajl_tok_eof; - goto lexed; - } - c = readChar(lexer, jsonText, offset); - if (c != *want) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_invalid_string; - tok = yajl_tok_error; - goto lexed; - } - } while (*(++want)); - tok = yajl_tok_bool; - goto lexed; - } - case 'n': { - const char * want = "ull"; - do { - if (*offset >= jsonTextLen) { - tok = yajl_tok_eof; - goto lexed; - } - c = readChar(lexer, jsonText, offset); - if (c != *want) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_invalid_string; - tok = yajl_tok_error; - goto lexed; - } - } while (*(++want)); - tok = yajl_tok_null; - goto lexed; - } - case '"': { - tok = yajl_lex_string(lexer, (const unsigned char *) jsonText, - jsonTextLen, offset); - goto lexed; - } - case '-': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - /* integer parsing wants to start from the beginning */ - unreadChar(lexer, offset); - tok = yajl_lex_number(lexer, (const unsigned char *) jsonText, - jsonTextLen, offset); - goto lexed; - } - case '/': - /* hey, look, a probable comment! If comments are disabled - * it's an error. */ - if (!lexer->allowComments) { - unreadChar(lexer, offset); - lexer->error = yajl_lex_unallowed_comment; - tok = yajl_tok_error; - goto lexed; - } - /* if comments are enabled, then we should try to lex - * the thing. possible outcomes are - * - successful lex (tok_comment, which means continue), - * - malformed comment opening (slash not followed by - * '*' or '/') (tok_error) - * - eof hit. (tok_eof) */ - tok = yajl_lex_comment(lexer, (const unsigned char *) jsonText, - jsonTextLen, offset); - if (tok == yajl_tok_comment) { - /* "error" is silly, but that's the initial - * state of tok. guilty until proven innocent. */ - tok = yajl_tok_error; - yajl_buf_clear(lexer->buf); - lexer->bufInUse = 0; - startOffset = *offset; - break; - } - /* hit error or eof, bail */ - goto lexed; - default: - lexer->error = yajl_lex_invalid_char; - tok = yajl_tok_error; - goto lexed; - } - } - - - lexed: - /* need to append to buffer if the buffer is in use or - * if it's an EOF token */ - if (tok == yajl_tok_eof || lexer->bufInUse) { - if (!lexer->bufInUse) yajl_buf_clear(lexer->buf); - lexer->bufInUse = 1; - yajl_buf_append(lexer->buf, jsonText + startOffset, *offset - startOffset); - lexer->bufOff = 0; - - if (tok != yajl_tok_eof) { - *outBuf = yajl_buf_data(lexer->buf); - *outLen = yajl_buf_len(lexer->buf); - lexer->bufInUse = 0; - } - } else if (tok != yajl_tok_error) { - *outBuf = jsonText + startOffset; - *outLen = *offset - startOffset; - } - - /* special case for strings. skip the quotes. */ - if (tok == yajl_tok_string || tok == yajl_tok_string_with_escapes) - { - assert(*outLen >= 2); - (*outBuf)++; - *outLen -= 2; - } - - -#ifdef YAJL_LEXER_DEBUG - if (tok == yajl_tok_error) { - printf("lexical error: %s\n", - yajl_lex_error_to_string(yajl_lex_get_error(lexer))); - } else if (tok == yajl_tok_eof) { - printf("EOF hit\n"); - } else { - printf("lexed %s: '", tokToStr(tok)); - fwrite(*outBuf, 1, *outLen, stdout); - printf("'\n"); - } -#endif - - return tok; -} - -const char * -yajl_lex_error_to_string(yajl_lex_error error) -{ - switch (error) { - case yajl_lex_e_ok: - return "ok, no error"; - case yajl_lex_string_invalid_utf8: - return "invalid bytes in UTF8 string."; - case yajl_lex_string_invalid_escaped_char: - return "inside a string, '\\' occurs before a character " - "which it may not."; - case yajl_lex_string_invalid_json_char: - return "invalid character inside string."; - case yajl_lex_string_invalid_hex_char: - return "invalid (non-hex) character occurs after '\\u' inside " - "string."; - case yajl_lex_invalid_char: - return "invalid char in json text."; - case yajl_lex_invalid_string: - return "invalid string in json text."; - case yajl_lex_missing_integer_after_exponent: - return "malformed number, a digit is required after the exponent."; - case yajl_lex_missing_integer_after_decimal: - return "malformed number, a digit is required after the " - "decimal point."; - case yajl_lex_missing_integer_after_minus: - return "malformed number, a digit is required after the " - "minus sign."; - case yajl_lex_unallowed_comment: - return "probable comment found in input text, comments are " - "not enabled."; - } - return "unknown error code"; -} - - -/** allows access to more specific information about the lexical - * error when yajl_lex_lex returns yajl_tok_error. */ -yajl_lex_error -yajl_lex_get_error(yajl_lexer lexer) -{ - if (lexer == NULL) return (yajl_lex_error) -1; - return lexer->error; -} - -unsigned int yajl_lex_current_line(yajl_lexer lexer) -{ - return lexer->lineOff; -} - -unsigned int yajl_lex_current_char(yajl_lexer lexer) -{ - return lexer->charOff; -} - -yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int offset) -{ - const unsigned char * outBuf; - unsigned int outLen; - unsigned int bufLen = yajl_buf_len(lexer->buf); - unsigned int bufOff = lexer->bufOff; - unsigned int bufInUse = lexer->bufInUse; - yajl_tok tok; - - tok = yajl_lex_lex(lexer, jsonText, jsonTextLen, &offset, - &outBuf, &outLen); - - lexer->bufOff = bufOff; - lexer->bufInUse = bufInUse; - yajl_buf_truncate(lexer->buf, bufLen); - - return tok; -} diff --git a/src/libCom/yajl/yajl_lex.h b/src/libCom/yajl/yajl_lex.h deleted file mode 100644 index 559e54dba..000000000 --- a/src/libCom/yajl/yajl_lex.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#ifndef __YAJL_LEX_H__ -#define __YAJL_LEX_H__ - -#include "yajl_common.h" - -typedef enum { - yajl_tok_bool, - yajl_tok_colon, - yajl_tok_comma, - yajl_tok_eof, - yajl_tok_error, - yajl_tok_left_brace, - yajl_tok_left_bracket, - yajl_tok_null, - yajl_tok_right_brace, - yajl_tok_right_bracket, - - /* we differentiate between integers and doubles to allow the - * parser to interpret the number without re-scanning */ - yajl_tok_integer, - yajl_tok_double, - - /* we differentiate between strings which require further processing, - * and strings that do not */ - yajl_tok_string, - yajl_tok_string_with_escapes, - - /* comment tokens are not currently returned to the parser, ever */ - yajl_tok_comment -} yajl_tok; - -typedef struct yajl_lexer_t * yajl_lexer; - -yajl_lexer yajl_lex_alloc(yajl_alloc_funcs * alloc, - unsigned int allowComments, - unsigned int validateUTF8); - -void yajl_lex_free(yajl_lexer lexer); - -/** - * run/continue a lex. "offset" is an input/output parameter. - * It should be initialized to zero for a - * new chunk of target text, and upon subsetquent calls with the same - * target text should passed with the value of the previous invocation. - * - * the client may be interested in the value of offset when an error is - * returned from the lexer. This allows the client to render useful -n * error messages. - * - * When you pass the next chunk of data, context should be reinitialized - * to zero. - * - * Finally, the output buffer is usually just a pointer into the jsonText, - * however in cases where the entity being lexed spans multiple chunks, - * the lexer will buffer the entity and the data returned will be - * a pointer into that buffer. - * - * This behavior is abstracted from client code except for the performance - * implications which require that the client choose a reasonable chunk - * size to get adequate performance. - */ -yajl_tok yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int * offset, - const unsigned char ** outBuf, unsigned int * outLen); - -/** have a peek at the next token, but don't move the lexer forward */ -yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText, - unsigned int jsonTextLen, unsigned int offset); - - -typedef enum { - yajl_lex_e_ok = 0, - yajl_lex_string_invalid_utf8, - yajl_lex_string_invalid_escaped_char, - yajl_lex_string_invalid_json_char, - yajl_lex_string_invalid_hex_char, - yajl_lex_invalid_char, - yajl_lex_invalid_string, - yajl_lex_missing_integer_after_decimal, - yajl_lex_missing_integer_after_exponent, - yajl_lex_missing_integer_after_minus, - yajl_lex_unallowed_comment -} yajl_lex_error; - -const char * yajl_lex_error_to_string(yajl_lex_error error); - -/** allows access to more specific information about the lexical - * error when yajl_lex_lex returns yajl_tok_error. */ -yajl_lex_error yajl_lex_get_error(yajl_lexer lexer); - -/** get the current offset into the most recently lexed json string. */ -unsigned int yajl_lex_current_offset(yajl_lexer lexer); - -/** get the number of lines lexed by this lexer instance */ -unsigned int yajl_lex_current_line(yajl_lexer lexer); - -/** get the number of chars lexed by this lexer instance since the last - * \n or \r */ -unsigned int yajl_lex_current_char(yajl_lexer lexer); - -#endif diff --git a/src/libCom/yajl/yajl_parse.h b/src/libCom/yajl/yajl_parse.h deleted file mode 100644 index a70a8fd56..000000000 --- a/src/libCom/yajl/yajl_parse.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -/** - * \file yajl_parse.h - * Interface to YAJL's JSON parsing facilities. - */ - -#ifndef __YAJL_PARSE_H__ -#define __YAJL_PARSE_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - /** error codes returned from this interface */ - typedef enum { - /** no error was encountered */ - yajl_status_ok, - /** a client callback returned zero, stopping the parse */ - yajl_status_client_canceled, - /** The parse cannot yet complete because more json input text - * is required, call yajl_parse with the next buffer of input text. - * (pertinent only when stream parsing) */ - yajl_status_insufficient_data, - /** An error occured during the parse. Call yajl_get_error for - * more information about the encountered error */ - yajl_status_error - } yajl_status; - - /** attain a human readable, english, string for an error */ - YAJL_API const char * yajl_status_to_string(yajl_status code); - - /** an opaque handle to a parser */ - typedef struct yajl_handle_t * yajl_handle; - - /** yajl is an event driven parser. this means as json elements are - * parsed, you are called back to do something with the data. The - * functions in this table indicate the various events for which - * you will be called back. Each callback accepts a "context" - * pointer, this is a void * that is passed into the yajl_parse - * function which the client code may use to pass around context. - * - * All callbacks return an integer. If non-zero, the parse will - * continue. If zero, the parse will be canceled and - * yajl_status_client_canceled will be returned from the parse. - * - * Note about handling of numbers: - * yajl will only convert numbers that can be represented in a double - * or a long int. All other numbers will be passed to the client - * in string form using the yajl_number callback. Furthermore, if - * yajl_number is not NULL, it will always be used to return numbers, - * that is yajl_integer and yajl_double will be ignored. If - * yajl_number is NULL but one of yajl_integer or yajl_double are - * defined, parsing of a number larger than is representable - * in a double or long int will result in a parse error. - */ - typedef struct { - int (* yajl_null)(void * ctx); - int (* yajl_boolean)(void * ctx, int boolVal); - int (* yajl_integer)(void * ctx, long integerVal); - int (* yajl_double)(void * ctx, double doubleVal); - /** A callback which passes the string representation of the number - * back to the client. Will be used for all numbers when present */ - int (* yajl_number)(void * ctx, const char * numberVal, - unsigned int numberLen); - - /** strings are returned as pointers into the JSON text when, - * possible, as a result, they are _not_ null padded */ - int (* yajl_string)(void * ctx, const unsigned char * stringVal, - unsigned int stringLen); - - int (* yajl_start_map)(void * ctx); - int (* yajl_map_key)(void * ctx, const unsigned char * key, - unsigned int stringLen); - int (* yajl_end_map)(void * ctx); - - int (* yajl_start_array)(void * ctx); - int (* yajl_end_array)(void * ctx); - } yajl_callbacks; - - /** configuration structure for the generator */ - typedef struct { - /** if nonzero, javascript style comments will be allowed in - * the json input, both slash star and slash slash */ - unsigned int allowComments; - /** if nonzero, invalid UTF8 strings will cause a parse - * error */ - unsigned int checkUTF8; - } yajl_parser_config; - - /** allocate a parser handle - * \param callbacks a yajl callbacks structure specifying the - * functions to call when different JSON entities - * are encountered in the input text. May be NULL, - * which is only useful for validation. - * \param config configuration parameters for the parse. - * \param ctx a context pointer that will be passed to callbacks. - */ - YAJL_API yajl_handle yajl_alloc(const yajl_callbacks * callbacks, - const yajl_parser_config * config, - const yajl_alloc_funcs * allocFuncs, - void * ctx); - - /** free a parser handle */ - YAJL_API void yajl_free(yajl_handle handle); - - /** Parse some json! - * \param hand - a handle to the json parser allocated with yajl_alloc - * \param jsonText - a pointer to the UTF8 json text to be parsed - * \param jsonTextLength - the length, in bytes, of input text - */ - YAJL_API yajl_status yajl_parse(yajl_handle hand, - const unsigned char * jsonText, - unsigned int jsonTextLength); - - /** Parse any remaining buffered json. - * Since yajl is a stream-based parser, without an explicit end of - * input, yajl sometimes can't decide if content at the end of the - * stream is valid or not. For example, if "1" has been fed in, - * yajl can't know whether another digit is next or some character - * that would terminate the integer token. - * - * \param hand - a handle to the json parser allocated with yajl_alloc - */ - YAJL_API yajl_status yajl_parse_complete(yajl_handle hand); - - /** get an error string describing the state of the - * parse. - * - * If verbose is non-zero, the message will include the JSON - * text where the error occured, along with an arrow pointing to - * the specific char. - * - * \returns A dynamically allocated string will be returned which should - * be freed with yajl_free_error - */ - YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose, - const unsigned char * jsonText, - unsigned int jsonTextLength); - - /** - * get the amount of data consumed from the last chunk passed to YAJL. - * - * In the case of a successful parse this can help you understand if - * the entire buffer was consumed (which will allow you to handle - * "junk at end of input". - * - * In the event an error is encountered during parsing, this function - * affords the client a way to get the offset into the most recent - * chunk where the error occured. 0 will be returned if no error - * was encountered. - */ - YAJL_API unsigned int yajl_get_bytes_consumed(yajl_handle hand); - - /** free an error returned from yajl_get_error */ - YAJL_API void yajl_free_error(yajl_handle hand, unsigned char * str); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/libCom/yajl/yajl_parser.c b/src/libCom/yajl/yajl_parser.c deleted file mode 100644 index bbcf80880..000000000 --- a/src/libCom/yajl/yajl_parser.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "yajl_lex.h" -#include "yajl_parser.h" -#include "yajl_encode.h" -#include "yajl_bytestack.h" - -unsigned char * -yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, - unsigned int jsonTextLen, int verbose) -{ - unsigned int offset = hand->bytesConsumed; - unsigned char * str; - const char * errorType = NULL; - const char * errorText = NULL; - char text[72]; - const char * arrow = " (right here) ------^\n"; - - if (yajl_bs_current(hand->stateStack) == yajl_state_parse_error) { - errorType = "parse"; - errorText = hand->parseError; - } else if (yajl_bs_current(hand->stateStack) == yajl_state_lexical_error) { - errorType = "lexical"; - errorText = yajl_lex_error_to_string(yajl_lex_get_error(hand->lexer)); - } else { - errorType = "unknown"; - } - - { - unsigned int memneeded = 0; - memneeded += strlen(errorType); - memneeded += strlen(" error"); - if (errorText != NULL) { - memneeded += strlen(": "); - memneeded += strlen(errorText); - } - str = (unsigned char *) YA_MALLOC(&(hand->alloc), memneeded + 2); - str[0] = 0; - strcat((char *) str, errorType); - strcat((char *) str, " error"); - if (errorText != NULL) { - strcat((char *) str, ": "); - strcat((char *) str, errorText); - } - strcat((char *) str, "\n"); - } - - /* now we append as many spaces as needed to make sure the error - * falls at char 41, if verbose was specified */ - if (verbose) { - unsigned int start, end, i; - unsigned int spacesNeeded; - - spacesNeeded = (offset < 30 ? 40 - offset : 10); - start = (offset >= 30 ? offset - 30 : 0); - end = (offset + 30 > jsonTextLen ? jsonTextLen : offset + 30); - - for (i=0;ialloc), (unsigned int)(strlen((char *) str) + - strlen((char *) text) + - strlen(arrow) + 1)); - newStr[0] = 0; - strcat((char *) newStr, (char *) str); - strcat((char *) newStr, text); - strcat((char *) newStr, arrow); - YA_FREE(&(hand->alloc), str); - str = (unsigned char *) newStr; - } - } - return str; -} - -/* check for client cancelation */ -#define _CC_CHK(x) \ - if (!(x)) { \ - yajl_bs_set(hand->stateStack, yajl_state_parse_error); \ - hand->parseError = \ - "client cancelled parse via callback return value"; \ - return yajl_status_client_canceled; \ - } - - -yajl_status -yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, - unsigned int jsonTextLen) -{ - yajl_tok tok; - const unsigned char * buf; - unsigned int bufLen; - unsigned int * offset = &(hand->bytesConsumed); - - *offset = 0; - - - around_again: - switch (yajl_bs_current(hand->stateStack)) { - case yajl_state_parse_complete: - return yajl_status_ok; - case yajl_state_lexical_error: - case yajl_state_parse_error: - return yajl_status_error; - case yajl_state_start: - case yajl_state_map_need_val: - case yajl_state_array_need_val: - case yajl_state_array_start: { - /* for arrays and maps, we advance the state for this - * depth, then push the state of the next depth. - * If an error occurs during the parsing of the nesting - * enitity, the state at this level will not matter. - * a state that needs pushing will be anything other - * than state_start */ - yajl_state stateToPush = yajl_state_start; - - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - - switch (tok) { - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - case yajl_tok_string: - if (hand->callbacks && hand->callbacks->yajl_string) { - _CC_CHK(hand->callbacks->yajl_string(hand->ctx, - buf, bufLen)); - } - break; - case yajl_tok_string_with_escapes: - if (hand->callbacks && hand->callbacks->yajl_string) { - yajl_buf_clear(hand->decodeBuf); - yajl_string_decode(hand->decodeBuf, buf, bufLen); - _CC_CHK(hand->callbacks->yajl_string( - hand->ctx, yajl_buf_data(hand->decodeBuf), - yajl_buf_len(hand->decodeBuf))); - } - break; - case yajl_tok_bool: - if (hand->callbacks && hand->callbacks->yajl_boolean) { - _CC_CHK(hand->callbacks->yajl_boolean(hand->ctx, - *buf == 't')); - } - break; - case yajl_tok_null: - if (hand->callbacks && hand->callbacks->yajl_null) { - _CC_CHK(hand->callbacks->yajl_null(hand->ctx)); - } - break; - case yajl_tok_left_bracket: - if (hand->callbacks && hand->callbacks->yajl_start_map) { - _CC_CHK(hand->callbacks->yajl_start_map(hand->ctx)); - } - stateToPush = yajl_state_map_start; - break; - case yajl_tok_left_brace: - if (hand->callbacks && hand->callbacks->yajl_start_array) { - _CC_CHK(hand->callbacks->yajl_start_array(hand->ctx)); - } - stateToPush = yajl_state_array_start; - break; - case yajl_tok_integer: - /* - * note. strtol does not respect the length of - * the lexical token. in a corner case where the - * lexed number is a integer with a trailing zero, - * immediately followed by the end of buffer, - * sscanf could run off into oblivion and cause a - * crash. for this reason we copy the integer - * (and doubles), into our parse buffer (the same - * one used for unescaping strings), before - * calling strtol. yajl_buf ensures null padding, - * so we're safe. - */ - if (hand->callbacks) { - if (hand->callbacks->yajl_number) { - _CC_CHK(hand->callbacks->yajl_number( - hand->ctx,(const char *) buf, bufLen)); - } else if (hand->callbacks->yajl_integer) { - long int i = 0; - yajl_buf_clear(hand->decodeBuf); - yajl_buf_append(hand->decodeBuf, buf, bufLen); - buf = yajl_buf_data(hand->decodeBuf); - i = strtol((const char *) buf, NULL, 10); - if ((i == LONG_MIN || i == LONG_MAX) && - errno == ERANGE) - { - yajl_bs_set(hand->stateStack, - yajl_state_parse_error); - hand->parseError = "integer overflow" ; - /* try to restore error offset */ - if (*offset >= bufLen) *offset -= bufLen; - else *offset = 0; - goto around_again; - } - _CC_CHK(hand->callbacks->yajl_integer(hand->ctx, - i)); - } - } - break; - case yajl_tok_double: - if (hand->callbacks) { - if (hand->callbacks->yajl_number) { - _CC_CHK(hand->callbacks->yajl_number( - hand->ctx, (const char *) buf, bufLen)); - } else if (hand->callbacks->yajl_double) { - double d = 0.0; - yajl_buf_clear(hand->decodeBuf); - yajl_buf_append(hand->decodeBuf, buf, bufLen); - buf = yajl_buf_data(hand->decodeBuf); - d = strtod((char *) buf, NULL); - if ((d == HUGE_VAL || d == -HUGE_VAL) && - errno == ERANGE) - { - yajl_bs_set(hand->stateStack, - yajl_state_parse_error); - hand->parseError = "numeric (floating point) " - "overflow"; - /* try to restore error offset */ - if (*offset >= bufLen) *offset -= bufLen; - else *offset = 0; - goto around_again; - } - _CC_CHK(hand->callbacks->yajl_double(hand->ctx, - d)); - } - } - break; - case yajl_tok_right_brace: { - if (yajl_bs_current(hand->stateStack) == - yajl_state_array_start) - { - if (hand->callbacks && - hand->callbacks->yajl_end_array) - { - _CC_CHK(hand->callbacks->yajl_end_array(hand->ctx)); - } - yajl_bs_pop(hand->stateStack); - goto around_again; - } - /* intentional fall-through */ - } - case yajl_tok_colon: - case yajl_tok_comma: - case yajl_tok_right_bracket: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = - "unallowed token at this point in JSON text"; - goto around_again; - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = "invalid token, internal error"; - goto around_again; - } - /* got a value. transition depends on the state we're in. */ - { - yajl_state s = yajl_bs_current(hand->stateStack); - if (s == yajl_state_start) { - yajl_bs_set(hand->stateStack, yajl_state_parse_complete); - } else if (s == yajl_state_map_need_val) { - yajl_bs_set(hand->stateStack, yajl_state_map_got_val); - } else { - yajl_bs_set(hand->stateStack, yajl_state_array_got_val); - } - } - if (stateToPush != yajl_state_start) { - yajl_bs_push(hand->stateStack, stateToPush); - } - - goto around_again; - } - case yajl_state_map_start: - case yajl_state_map_need_key: { - /* only difference between these two states is that in - * start '}' is valid, whereas in need_key, we've parsed - * a comma, and a string key _must_ follow */ - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - switch (tok) { - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - case yajl_tok_string_with_escapes: - if (hand->callbacks && hand->callbacks->yajl_map_key) { - yajl_buf_clear(hand->decodeBuf); - yajl_string_decode(hand->decodeBuf, buf, bufLen); - buf = yajl_buf_data(hand->decodeBuf); - bufLen = yajl_buf_len(hand->decodeBuf); - } - /* intentional fall-through */ - case yajl_tok_string: - if (hand->callbacks && hand->callbacks->yajl_map_key) { - _CC_CHK(hand->callbacks->yajl_map_key(hand->ctx, buf, - bufLen)); - } - yajl_bs_set(hand->stateStack, yajl_state_map_sep); - goto around_again; - case yajl_tok_right_bracket: - if (yajl_bs_current(hand->stateStack) == - yajl_state_map_start) - { - if (hand->callbacks && hand->callbacks->yajl_end_map) { - _CC_CHK(hand->callbacks->yajl_end_map(hand->ctx)); - } - yajl_bs_pop(hand->stateStack); - goto around_again; - } - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = - "invalid object key (must be a string)"; - goto around_again; - } - } - case yajl_state_map_sep: { - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - switch (tok) { - case yajl_tok_colon: - yajl_bs_set(hand->stateStack, yajl_state_map_need_val); - goto around_again; - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = "object key and value must " - "be separated by a colon (':')"; - goto around_again; - } - } - case yajl_state_map_got_val: { - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - switch (tok) { - case yajl_tok_right_bracket: - if (hand->callbacks && hand->callbacks->yajl_end_map) { - _CC_CHK(hand->callbacks->yajl_end_map(hand->ctx)); - } - yajl_bs_pop(hand->stateStack); - goto around_again; - case yajl_tok_comma: - yajl_bs_set(hand->stateStack, yajl_state_map_need_key); - goto around_again; - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = "after key and value, inside map, " - "I expect ',' or '}'"; - /* try to restore error offset */ - if (*offset >= bufLen) *offset -= bufLen; - else *offset = 0; - goto around_again; - } - } - case yajl_state_array_got_val: { - tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, - offset, &buf, &bufLen); - switch (tok) { - case yajl_tok_right_brace: - if (hand->callbacks && hand->callbacks->yajl_end_array) { - _CC_CHK(hand->callbacks->yajl_end_array(hand->ctx)); - } - yajl_bs_pop(hand->stateStack); - goto around_again; - case yajl_tok_comma: - yajl_bs_set(hand->stateStack, yajl_state_array_need_val); - goto around_again; - case yajl_tok_eof: - return yajl_status_insufficient_data; - case yajl_tok_error: - yajl_bs_set(hand->stateStack, yajl_state_lexical_error); - goto around_again; - default: - yajl_bs_set(hand->stateStack, yajl_state_parse_error); - hand->parseError = - "after array element, I expect ',' or ']'"; - goto around_again; - } - } - } - - abort(); - return yajl_status_error; -} - diff --git a/src/libCom/yajl/yajl_parser.h b/src/libCom/yajl/yajl_parser.h deleted file mode 100644 index 2d59882a3..000000000 --- a/src/libCom/yajl/yajl_parser.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2010, Lloyd Hilaiel. - * - * 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 Lloyd Hilaiel 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 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. - */ - -#ifndef __YAJL_PARSER_H__ -#define __YAJL_PARSER_H__ - -#include "yajl_parse.h" -#include "yajl_bytestack.h" -#include "yajl_buf.h" - - -typedef enum { - yajl_state_start = 0, - yajl_state_parse_complete, - yajl_state_parse_error, - yajl_state_lexical_error, - yajl_state_map_start, - yajl_state_map_sep, - yajl_state_map_need_val, - yajl_state_map_got_val, - yajl_state_map_need_key, - yajl_state_array_start, - yajl_state_array_got_val, - yajl_state_array_need_val -} yajl_state; - -struct yajl_handle_t { - const yajl_callbacks * callbacks; - void * ctx; - yajl_lexer lexer; - const char * parseError; - /* the number of bytes consumed from the last client buffer, - * in the case of an error this will be an error offset, in the - * case of an error this can be used as the error offset */ - unsigned int bytesConsumed; - /* temporary storage for decoded strings */ - yajl_buf decodeBuf; - /* a stack of states. access with yajl_state_XXX routines */ - yajl_bytestack stateStack; - /* memory allocation routines */ - yajl_alloc_funcs alloc; -}; - -yajl_status -yajl_do_parse(yajl_handle handle, const unsigned char * jsonText, - unsigned int jsonTextLen); - -unsigned char * -yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, - unsigned int jsonTextLen, int verbose); - - -#endif diff --git a/src/ca/legacy/pcas/Makefile b/src/pcas/Makefile similarity index 100% rename from src/ca/legacy/pcas/Makefile rename to src/pcas/Makefile diff --git a/src/ca/legacy/pcas/README b/src/pcas/README similarity index 100% rename from src/ca/legacy/pcas/README rename to src/pcas/README diff --git a/src/ca/legacy/pcas/RELEASE_NOTES b/src/pcas/RELEASE_NOTES similarity index 100% rename from src/ca/legacy/pcas/RELEASE_NOTES rename to src/pcas/RELEASE_NOTES diff --git a/src/ca/legacy/pcas/build/Makefile b/src/pcas/build/Makefile similarity index 100% rename from src/ca/legacy/pcas/build/Makefile rename to src/pcas/build/Makefile diff --git a/src/ca/legacy/pcas/build/cas.rc b/src/pcas/build/cas.rc similarity index 100% rename from src/ca/legacy/pcas/build/cas.rc rename to src/pcas/build/cas.rc diff --git a/src/ca/legacy/pcas/ex/Makefile b/src/pcas/ex/Makefile similarity index 100% rename from src/ca/legacy/pcas/ex/Makefile rename to src/pcas/ex/Makefile diff --git a/src/ca/legacy/pcas/example/Makefile b/src/pcas/example/Makefile similarity index 100% rename from src/ca/legacy/pcas/example/Makefile rename to src/pcas/example/Makefile diff --git a/src/ca/legacy/pcas/example/README b/src/pcas/example/README similarity index 100% rename from src/ca/legacy/pcas/example/README rename to src/pcas/example/README diff --git a/src/ca/legacy/pcas/example/directoryService/Makefile b/src/pcas/example/directoryService/Makefile similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/Makefile rename to src/pcas/example/directoryService/Makefile diff --git a/src/ca/legacy/pcas/example/directoryService/README b/src/pcas/example/directoryService/README similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/README rename to src/pcas/example/directoryService/README diff --git a/src/ca/legacy/pcas/example/directoryService/directoryServer.cc b/src/pcas/example/directoryService/directoryServer.cc similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/directoryServer.cc rename to src/pcas/example/directoryService/directoryServer.cc diff --git a/src/ca/legacy/pcas/example/directoryService/directoryServer.h b/src/pcas/example/directoryService/directoryServer.h similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/directoryServer.h rename to src/pcas/example/directoryService/directoryServer.h diff --git a/src/ca/legacy/pcas/example/directoryService/main.cc b/src/pcas/example/directoryService/main.cc similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/main.cc rename to src/pcas/example/directoryService/main.cc diff --git a/src/ca/legacy/pcas/example/directoryService/pvDirectory.txt b/src/pcas/example/directoryService/pvDirectory.txt similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/pvDirectory.txt rename to src/pcas/example/directoryService/pvDirectory.txt diff --git a/src/ca/legacy/pcas/example/directoryService/test.adl b/src/pcas/example/directoryService/test.adl similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/test.adl rename to src/pcas/example/directoryService/test.adl diff --git a/src/ca/legacy/pcas/example/directoryService/vxEntry.cc b/src/pcas/example/directoryService/vxEntry.cc similarity index 100% rename from src/ca/legacy/pcas/example/directoryService/vxEntry.cc rename to src/pcas/example/directoryService/vxEntry.cc diff --git a/src/ca/legacy/pcas/generic/README b/src/pcas/generic/README similarity index 100% rename from src/ca/legacy/pcas/generic/README rename to src/pcas/generic/README diff --git a/src/ca/legacy/pcas/generic/beaconAnomalyGovernor.cc b/src/pcas/generic/beaconAnomalyGovernor.cc similarity index 100% rename from src/ca/legacy/pcas/generic/beaconAnomalyGovernor.cc rename to src/pcas/generic/beaconAnomalyGovernor.cc diff --git a/src/ca/legacy/pcas/generic/beaconAnomalyGovernor.h b/src/pcas/generic/beaconAnomalyGovernor.h similarity index 100% rename from src/ca/legacy/pcas/generic/beaconAnomalyGovernor.h rename to src/pcas/generic/beaconAnomalyGovernor.h diff --git a/src/ca/legacy/pcas/generic/beaconTimer.cc b/src/pcas/generic/beaconTimer.cc similarity index 100% rename from src/ca/legacy/pcas/generic/beaconTimer.cc rename to src/pcas/generic/beaconTimer.cc diff --git a/src/ca/legacy/pcas/generic/beaconTimer.h b/src/pcas/generic/beaconTimer.h similarity index 100% rename from src/ca/legacy/pcas/generic/beaconTimer.h rename to src/pcas/generic/beaconTimer.h diff --git a/src/ca/legacy/pcas/generic/caHdrLargeArray.h b/src/pcas/generic/caHdrLargeArray.h similarity index 100% rename from src/ca/legacy/pcas/generic/caHdrLargeArray.h rename to src/pcas/generic/caHdrLargeArray.h diff --git a/src/ca/legacy/pcas/generic/caNetAddr.cc b/src/pcas/generic/caNetAddr.cc similarity index 100% rename from src/ca/legacy/pcas/generic/caNetAddr.cc rename to src/pcas/generic/caNetAddr.cc diff --git a/src/ca/legacy/pcas/generic/caNetAddr.h b/src/pcas/generic/caNetAddr.h similarity index 100% rename from src/ca/legacy/pcas/generic/caNetAddr.h rename to src/pcas/generic/caNetAddr.h diff --git a/src/ca/legacy/pcas/generic/caServer.cc b/src/pcas/generic/caServer.cc similarity index 100% rename from src/ca/legacy/pcas/generic/caServer.cc rename to src/pcas/generic/caServer.cc diff --git a/src/ca/legacy/pcas/generic/caServerDefs.h b/src/pcas/generic/caServerDefs.h similarity index 100% rename from src/ca/legacy/pcas/generic/caServerDefs.h rename to src/pcas/generic/caServerDefs.h diff --git a/src/ca/legacy/pcas/generic/caServerI.cc b/src/pcas/generic/caServerI.cc similarity index 100% rename from src/ca/legacy/pcas/generic/caServerI.cc rename to src/pcas/generic/caServerI.cc diff --git a/src/ca/legacy/pcas/generic/caServerI.h b/src/pcas/generic/caServerI.h similarity index 100% rename from src/ca/legacy/pcas/generic/caServerI.h rename to src/pcas/generic/caServerI.h diff --git a/src/ca/legacy/pcas/generic/casAddr.h b/src/pcas/generic/casAddr.h similarity index 100% rename from src/ca/legacy/pcas/generic/casAddr.h rename to src/pcas/generic/casAddr.h diff --git a/src/ca/legacy/pcas/generic/casAsyncIOI.cc b/src/pcas/generic/casAsyncIOI.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncIOI.cc rename to src/pcas/generic/casAsyncIOI.cc diff --git a/src/ca/legacy/pcas/generic/casAsyncIOI.h b/src/pcas/generic/casAsyncIOI.h similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncIOI.h rename to src/pcas/generic/casAsyncIOI.h diff --git a/src/ca/legacy/pcas/generic/casAsyncPVAttachIO.cc b/src/pcas/generic/casAsyncPVAttachIO.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncPVAttachIO.cc rename to src/pcas/generic/casAsyncPVAttachIO.cc diff --git a/src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.cpp b/src/pcas/generic/casAsyncPVAttachIOI.cpp similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.cpp rename to src/pcas/generic/casAsyncPVAttachIOI.cpp diff --git a/src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.h b/src/pcas/generic/casAsyncPVAttachIOI.h similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.h rename to src/pcas/generic/casAsyncPVAttachIOI.h diff --git a/src/ca/legacy/pcas/generic/casAsyncPVExistIO.cc b/src/pcas/generic/casAsyncPVExistIO.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncPVExistIO.cc rename to src/pcas/generic/casAsyncPVExistIO.cc diff --git a/src/ca/legacy/pcas/generic/casAsyncPVExistIOI.cpp b/src/pcas/generic/casAsyncPVExistIOI.cpp similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncPVExistIOI.cpp rename to src/pcas/generic/casAsyncPVExistIOI.cpp diff --git a/src/ca/legacy/pcas/generic/casAsyncPVExistIOI.h b/src/pcas/generic/casAsyncPVExistIOI.h similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncPVExistIOI.h rename to src/pcas/generic/casAsyncPVExistIOI.h diff --git a/src/ca/legacy/pcas/generic/casAsyncReadIO.cc b/src/pcas/generic/casAsyncReadIO.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncReadIO.cc rename to src/pcas/generic/casAsyncReadIO.cc diff --git a/src/ca/legacy/pcas/generic/casAsyncReadIOI.cc b/src/pcas/generic/casAsyncReadIOI.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncReadIOI.cc rename to src/pcas/generic/casAsyncReadIOI.cc diff --git a/src/ca/legacy/pcas/generic/casAsyncReadIOI.h b/src/pcas/generic/casAsyncReadIOI.h similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncReadIOI.h rename to src/pcas/generic/casAsyncReadIOI.h diff --git a/src/ca/legacy/pcas/generic/casAsyncWriteIO.cc b/src/pcas/generic/casAsyncWriteIO.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncWriteIO.cc rename to src/pcas/generic/casAsyncWriteIO.cc diff --git a/src/ca/legacy/pcas/generic/casAsyncWriteIOI.cpp b/src/pcas/generic/casAsyncWriteIOI.cpp similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncWriteIOI.cpp rename to src/pcas/generic/casAsyncWriteIOI.cpp diff --git a/src/ca/legacy/pcas/generic/casAsyncWriteIOI.h b/src/pcas/generic/casAsyncWriteIOI.h similarity index 100% rename from src/ca/legacy/pcas/generic/casAsyncWriteIOI.h rename to src/pcas/generic/casAsyncWriteIOI.h diff --git a/src/ca/legacy/pcas/generic/casChannel.cc b/src/pcas/generic/casChannel.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casChannel.cc rename to src/pcas/generic/casChannel.cc diff --git a/src/ca/legacy/pcas/generic/casChannelI.cc b/src/pcas/generic/casChannelI.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casChannelI.cc rename to src/pcas/generic/casChannelI.cc diff --git a/src/ca/legacy/pcas/generic/casChannelI.h b/src/pcas/generic/casChannelI.h similarity index 100% rename from src/ca/legacy/pcas/generic/casChannelI.h rename to src/pcas/generic/casChannelI.h diff --git a/src/ca/legacy/pcas/generic/casCoreClient.cc b/src/pcas/generic/casCoreClient.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casCoreClient.cc rename to src/pcas/generic/casCoreClient.cc diff --git a/src/ca/legacy/pcas/generic/casCoreClient.h b/src/pcas/generic/casCoreClient.h similarity index 100% rename from src/ca/legacy/pcas/generic/casCoreClient.h rename to src/pcas/generic/casCoreClient.h diff --git a/src/ca/legacy/pcas/generic/casCtx.cc b/src/pcas/generic/casCtx.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casCtx.cc rename to src/pcas/generic/casCtx.cc diff --git a/src/ca/legacy/pcas/generic/casCtx.h b/src/pcas/generic/casCtx.h similarity index 100% rename from src/ca/legacy/pcas/generic/casCtx.h rename to src/pcas/generic/casCtx.h diff --git a/src/ca/legacy/pcas/generic/casCtxIL.h b/src/pcas/generic/casCtxIL.h similarity index 100% rename from src/ca/legacy/pcas/generic/casCtxIL.h rename to src/pcas/generic/casCtxIL.h diff --git a/src/ca/legacy/pcas/generic/casDGClient.cc b/src/pcas/generic/casDGClient.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casDGClient.cc rename to src/pcas/generic/casDGClient.cc diff --git a/src/ca/legacy/pcas/generic/casDGClient.h b/src/pcas/generic/casDGClient.h similarity index 100% rename from src/ca/legacy/pcas/generic/casDGClient.h rename to src/pcas/generic/casDGClient.h diff --git a/src/ca/legacy/pcas/generic/casEvent.h b/src/pcas/generic/casEvent.h similarity index 100% rename from src/ca/legacy/pcas/generic/casEvent.h rename to src/pcas/generic/casEvent.h diff --git a/src/ca/legacy/pcas/generic/casEventMask.cc b/src/pcas/generic/casEventMask.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casEventMask.cc rename to src/pcas/generic/casEventMask.cc diff --git a/src/ca/legacy/pcas/generic/casEventMask.h b/src/pcas/generic/casEventMask.h similarity index 100% rename from src/ca/legacy/pcas/generic/casEventMask.h rename to src/pcas/generic/casEventMask.h diff --git a/src/ca/legacy/pcas/generic/casEventRegistry.h b/src/pcas/generic/casEventRegistry.h similarity index 100% rename from src/ca/legacy/pcas/generic/casEventRegistry.h rename to src/pcas/generic/casEventRegistry.h diff --git a/src/ca/legacy/pcas/generic/casEventSys.cc b/src/pcas/generic/casEventSys.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casEventSys.cc rename to src/pcas/generic/casEventSys.cc diff --git a/src/ca/legacy/pcas/generic/casEventSys.h b/src/pcas/generic/casEventSys.h similarity index 100% rename from src/ca/legacy/pcas/generic/casEventSys.h rename to src/pcas/generic/casEventSys.h diff --git a/src/ca/legacy/pcas/generic/casMonEvent.cc b/src/pcas/generic/casMonEvent.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casMonEvent.cc rename to src/pcas/generic/casMonEvent.cc diff --git a/src/ca/legacy/pcas/generic/casMonEvent.h b/src/pcas/generic/casMonEvent.h similarity index 100% rename from src/ca/legacy/pcas/generic/casMonEvent.h rename to src/pcas/generic/casMonEvent.h diff --git a/src/ca/legacy/pcas/generic/casMonitor.cc b/src/pcas/generic/casMonitor.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casMonitor.cc rename to src/pcas/generic/casMonitor.cc diff --git a/src/ca/legacy/pcas/generic/casMonitor.h b/src/pcas/generic/casMonitor.h similarity index 100% rename from src/ca/legacy/pcas/generic/casMonitor.h rename to src/pcas/generic/casMonitor.h diff --git a/src/ca/legacy/pcas/generic/casOpaqueAddr.cc b/src/pcas/generic/casOpaqueAddr.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casOpaqueAddr.cc rename to src/pcas/generic/casOpaqueAddr.cc diff --git a/src/ca/legacy/pcas/generic/casOpaqueAddrIL.h b/src/pcas/generic/casOpaqueAddrIL.h similarity index 100% rename from src/ca/legacy/pcas/generic/casOpaqueAddrIL.h rename to src/pcas/generic/casOpaqueAddrIL.h diff --git a/src/ca/legacy/pcas/generic/casPV.cc b/src/pcas/generic/casPV.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casPV.cc rename to src/pcas/generic/casPV.cc diff --git a/src/ca/legacy/pcas/generic/casPVI.cc b/src/pcas/generic/casPVI.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casPVI.cc rename to src/pcas/generic/casPVI.cc diff --git a/src/ca/legacy/pcas/generic/casPVI.h b/src/pcas/generic/casPVI.h similarity index 100% rename from src/ca/legacy/pcas/generic/casPVI.h rename to src/pcas/generic/casPVI.h diff --git a/src/ca/legacy/pcas/generic/casStrmClient.cc b/src/pcas/generic/casStrmClient.cc similarity index 100% rename from src/ca/legacy/pcas/generic/casStrmClient.cc rename to src/pcas/generic/casStrmClient.cc diff --git a/src/ca/legacy/pcas/generic/casStrmClient.h b/src/pcas/generic/casStrmClient.h similarity index 100% rename from src/ca/legacy/pcas/generic/casStrmClient.h rename to src/pcas/generic/casStrmClient.h diff --git a/src/ca/legacy/pcas/generic/casdef.h b/src/pcas/generic/casdef.h similarity index 100% rename from src/ca/legacy/pcas/generic/casdef.h rename to src/pcas/generic/casdef.h diff --git a/src/ca/legacy/pcas/generic/chanIntfForPV.cc b/src/pcas/generic/chanIntfForPV.cc similarity index 100% rename from src/ca/legacy/pcas/generic/chanIntfForPV.cc rename to src/pcas/generic/chanIntfForPV.cc diff --git a/src/ca/legacy/pcas/generic/chanIntfForPV.h b/src/pcas/generic/chanIntfForPV.h similarity index 100% rename from src/ca/legacy/pcas/generic/chanIntfForPV.h rename to src/pcas/generic/chanIntfForPV.h diff --git a/src/ca/legacy/pcas/generic/channelDestroyEvent.cpp b/src/pcas/generic/channelDestroyEvent.cpp similarity index 100% rename from src/ca/legacy/pcas/generic/channelDestroyEvent.cpp rename to src/pcas/generic/channelDestroyEvent.cpp diff --git a/src/ca/legacy/pcas/generic/channelDestroyEvent.h b/src/pcas/generic/channelDestroyEvent.h similarity index 100% rename from src/ca/legacy/pcas/generic/channelDestroyEvent.h rename to src/pcas/generic/channelDestroyEvent.h diff --git a/src/ca/legacy/pcas/generic/clientBufMemoryManager.cpp b/src/pcas/generic/clientBufMemoryManager.cpp similarity index 100% rename from src/ca/legacy/pcas/generic/clientBufMemoryManager.cpp rename to src/pcas/generic/clientBufMemoryManager.cpp diff --git a/src/ca/legacy/pcas/generic/clientBufMemoryManager.h b/src/pcas/generic/clientBufMemoryManager.h similarity index 100% rename from src/ca/legacy/pcas/generic/clientBufMemoryManager.h rename to src/pcas/generic/clientBufMemoryManager.h diff --git a/src/ca/legacy/pcas/generic/inBuf.cc b/src/pcas/generic/inBuf.cc similarity index 100% rename from src/ca/legacy/pcas/generic/inBuf.cc rename to src/pcas/generic/inBuf.cc diff --git a/src/ca/legacy/pcas/generic/inBuf.h b/src/pcas/generic/inBuf.h similarity index 100% rename from src/ca/legacy/pcas/generic/inBuf.h rename to src/pcas/generic/inBuf.h diff --git a/src/ca/legacy/pcas/generic/ioBlocked.h b/src/pcas/generic/ioBlocked.h similarity index 100% rename from src/ca/legacy/pcas/generic/ioBlocked.h rename to src/pcas/generic/ioBlocked.h diff --git a/src/ca/legacy/pcas/generic/mt/README b/src/pcas/generic/mt/README similarity index 100% rename from src/ca/legacy/pcas/generic/mt/README rename to src/pcas/generic/mt/README diff --git a/src/ca/legacy/pcas/generic/mt/ioBlocked.cc b/src/pcas/generic/mt/ioBlocked.cc similarity index 100% rename from src/ca/legacy/pcas/generic/mt/ioBlocked.cc rename to src/pcas/generic/mt/ioBlocked.cc diff --git a/src/ca/legacy/pcas/generic/outBuf.cc b/src/pcas/generic/outBuf.cc similarity index 100% rename from src/ca/legacy/pcas/generic/outBuf.cc rename to src/pcas/generic/outBuf.cc diff --git a/src/ca/legacy/pcas/generic/outBuf.h b/src/pcas/generic/outBuf.h similarity index 100% rename from src/ca/legacy/pcas/generic/outBuf.h rename to src/pcas/generic/outBuf.h diff --git a/src/ca/legacy/pcas/generic/pvAttachReturn.cc b/src/pcas/generic/pvAttachReturn.cc similarity index 100% rename from src/ca/legacy/pcas/generic/pvAttachReturn.cc rename to src/pcas/generic/pvAttachReturn.cc diff --git a/src/ca/legacy/pcas/generic/pvExistReturn.cc b/src/pcas/generic/pvExistReturn.cc similarity index 100% rename from src/ca/legacy/pcas/generic/pvExistReturn.cc rename to src/pcas/generic/pvExistReturn.cc diff --git a/src/ca/legacy/pcas/generic/st/README b/src/pcas/generic/st/README similarity index 100% rename from src/ca/legacy/pcas/generic/st/README rename to src/pcas/generic/st/README diff --git a/src/ca/legacy/pcas/generic/st/caServerOS.cc b/src/pcas/generic/st/caServerOS.cc similarity index 100% rename from src/ca/legacy/pcas/generic/st/caServerOS.cc rename to src/pcas/generic/st/caServerOS.cc diff --git a/src/ca/legacy/pcas/generic/st/casDGEvWakeup.h b/src/pcas/generic/st/casDGEvWakeup.h similarity index 100% rename from src/ca/legacy/pcas/generic/st/casDGEvWakeup.h rename to src/pcas/generic/st/casDGEvWakeup.h diff --git a/src/ca/legacy/pcas/generic/st/casDGIOWakeup.h b/src/pcas/generic/st/casDGIOWakeup.h similarity index 100% rename from src/ca/legacy/pcas/generic/st/casDGIOWakeup.h rename to src/pcas/generic/st/casDGIOWakeup.h diff --git a/src/ca/legacy/pcas/generic/st/casDGIntfOS.cc b/src/pcas/generic/st/casDGIntfOS.cc similarity index 100% rename from src/ca/legacy/pcas/generic/st/casDGIntfOS.cc rename to src/pcas/generic/st/casDGIntfOS.cc diff --git a/src/ca/legacy/pcas/generic/st/casDGIntfOS.h b/src/pcas/generic/st/casDGIntfOS.h similarity index 100% rename from src/ca/legacy/pcas/generic/st/casDGIntfOS.h rename to src/pcas/generic/st/casDGIntfOS.h diff --git a/src/ca/legacy/pcas/generic/st/casIntfOS.cc b/src/pcas/generic/st/casIntfOS.cc similarity index 100% rename from src/ca/legacy/pcas/generic/st/casIntfOS.cc rename to src/pcas/generic/st/casIntfOS.cc diff --git a/src/ca/legacy/pcas/generic/st/casIntfOS.h b/src/pcas/generic/st/casIntfOS.h similarity index 100% rename from src/ca/legacy/pcas/generic/st/casIntfOS.h rename to src/pcas/generic/st/casIntfOS.h diff --git a/src/ca/legacy/pcas/generic/st/casOSD.h b/src/pcas/generic/st/casOSD.h similarity index 100% rename from src/ca/legacy/pcas/generic/st/casOSD.h rename to src/pcas/generic/st/casOSD.h diff --git a/src/ca/legacy/pcas/generic/st/casStreamOS.cc b/src/pcas/generic/st/casStreamOS.cc similarity index 100% rename from src/ca/legacy/pcas/generic/st/casStreamOS.cc rename to src/pcas/generic/st/casStreamOS.cc diff --git a/src/ca/legacy/pcas/generic/st/casStreamOS.h b/src/pcas/generic/st/casStreamOS.h similarity index 100% rename from src/ca/legacy/pcas/generic/st/casStreamOS.h rename to src/pcas/generic/st/casStreamOS.h diff --git a/src/ca/legacy/pcas/generic/st/ioBlocked.cc b/src/pcas/generic/st/ioBlocked.cc similarity index 100% rename from src/ca/legacy/pcas/generic/st/ioBlocked.cc rename to src/pcas/generic/st/ioBlocked.cc diff --git a/src/ca/legacy/pcas/generic/st/osiMutexCAS.h b/src/pcas/generic/st/osiMutexCAS.h similarity index 100% rename from src/ca/legacy/pcas/generic/st/osiMutexCAS.h rename to src/pcas/generic/st/osiMutexCAS.h diff --git a/src/ca/legacy/pcas/io/bsdSocket/README b/src/pcas/io/bsdSocket/README similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/README rename to src/pcas/io/bsdSocket/README diff --git a/src/ca/legacy/pcas/io/bsdSocket/caServerIO.cc b/src/pcas/io/bsdSocket/caServerIO.cc similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/caServerIO.cc rename to src/pcas/io/bsdSocket/caServerIO.cc diff --git a/src/ca/legacy/pcas/io/bsdSocket/caServerIO.h b/src/pcas/io/bsdSocket/caServerIO.h similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/caServerIO.h rename to src/pcas/io/bsdSocket/caServerIO.h diff --git a/src/ca/legacy/pcas/io/bsdSocket/casDGIntfIO.cc b/src/pcas/io/bsdSocket/casDGIntfIO.cc similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/casDGIntfIO.cc rename to src/pcas/io/bsdSocket/casDGIntfIO.cc diff --git a/src/ca/legacy/pcas/io/bsdSocket/casDGIntfIO.h b/src/pcas/io/bsdSocket/casDGIntfIO.h similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/casDGIntfIO.h rename to src/pcas/io/bsdSocket/casDGIntfIO.h diff --git a/src/ca/legacy/pcas/io/bsdSocket/casIOD.h b/src/pcas/io/bsdSocket/casIOD.h similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/casIOD.h rename to src/pcas/io/bsdSocket/casIOD.h diff --git a/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc b/src/pcas/io/bsdSocket/casIntfIO.cc similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc rename to src/pcas/io/bsdSocket/casIntfIO.cc diff --git a/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.h b/src/pcas/io/bsdSocket/casIntfIO.h similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/casIntfIO.h rename to src/pcas/io/bsdSocket/casIntfIO.h diff --git a/src/ca/legacy/pcas/io/bsdSocket/casStreamIO.cc b/src/pcas/io/bsdSocket/casStreamIO.cc similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/casStreamIO.cc rename to src/pcas/io/bsdSocket/casStreamIO.cc diff --git a/src/ca/legacy/pcas/io/bsdSocket/casStreamIO.h b/src/pcas/io/bsdSocket/casStreamIO.h similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/casStreamIO.h rename to src/pcas/io/bsdSocket/casStreamIO.h diff --git a/src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.cpp b/src/pcas/io/bsdSocket/ipIgnoreEntry.cpp similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.cpp rename to src/pcas/io/bsdSocket/ipIgnoreEntry.cpp diff --git a/src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.h b/src/pcas/io/bsdSocket/ipIgnoreEntry.h similarity index 100% rename from src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.h rename to src/pcas/io/bsdSocket/ipIgnoreEntry.h diff --git a/src/ca/legacy/pcas/os/vms/BUILD_VMS.COM b/src/pcas/os/vms/BUILD_VMS.COM similarity index 100% rename from src/ca/legacy/pcas/os/vms/BUILD_VMS.COM rename to src/pcas/os/vms/BUILD_VMS.COM diff --git a/src/ca/legacy/pcas/os/vms/README b/src/pcas/os/vms/README similarity index 100% rename from src/ca/legacy/pcas/os/vms/README rename to src/pcas/os/vms/README diff --git a/src/ca/legacy/pcas/os/vms/casSpecificOS.h b/src/pcas/os/vms/casSpecificOS.h similarity index 100% rename from src/ca/legacy/pcas/os/vms/casSpecificOS.h rename to src/pcas/os/vms/casSpecificOS.h diff --git a/src/ca/legacy/pcas/os/vms/login.com b/src/pcas/os/vms/login.com similarity index 100% rename from src/ca/legacy/pcas/os/vms/login.com rename to src/pcas/os/vms/login.com diff --git a/src/ca/legacy/pcas/os/vms/mitfp.c b/src/pcas/os/vms/mitfp.c similarity index 100% rename from src/ca/legacy/pcas/os/vms/mitfp.c rename to src/pcas/os/vms/mitfp.c diff --git a/src/ca/legacy/pcas/os/vms/mitfp.cc b/src/pcas/os/vms/mitfp.cc similarity index 100% rename from src/ca/legacy/pcas/os/vms/mitfp.cc rename to src/pcas/os/vms/mitfp.cc diff --git a/src/ca/legacy/pcas/os/vms/mitfp.h b/src/pcas/os/vms/mitfp.h similarity index 100% rename from src/ca/legacy/pcas/os/vms/mitfp.h rename to src/pcas/os/vms/mitfp.h diff --git a/src/ca/legacy/pcas/os/vms/vms_depen.h b/src/pcas/os/vms/vms_depen.h similarity index 100% rename from src/ca/legacy/pcas/os/vms/vms_depen.h rename to src/pcas/os/vms/vms_depen.h diff --git a/src/ca/legacy/pcas/test/gddAppFuncTableTest.cc b/src/pcas/test/gddAppFuncTableTest.cc similarity index 100% rename from src/ca/legacy/pcas/test/gddAppFuncTableTest.cc rename to src/pcas/test/gddAppFuncTableTest.cc diff --git a/src/std/Makefile b/src/std/Makefile deleted file mode 100644 index dcfcb6a22..000000000 --- a/src/std/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../.. - -include $(TOP)/configure/CONFIG - -STDDIR=$(TOP)/src/std - -LIBRARY_IOC += dbRecStd -dbRecStd_LIBS = dbCore ca Com - -dbRecStd_RCS += dbRecStd.rc - -include $(STDDIR)/rec/Makefile -include $(STDDIR)/dev/Makefile -include $(STDDIR)/filters/Makefile -include $(STDDIR)/link/Makefile -include $(STDDIR)/softIoc/Makefile - -include $(TOP)/configure/RULES - -include $(STDDIR)/rec/RULES -include $(STDDIR)/softIoc/RULES - diff --git a/src/std/dbRecStd.rc b/src/std/dbRecStd.rc deleted file mode 100644 index f55b7d682..000000000 --- a/src/std/dbRecStd.rc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "epicsVersion.h" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - PRODUCTVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_UNKNOWN - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments","Record and Soft Device Support Library for EPICS\0" - VALUE "CompanyName", "The EPICS collaboration\0" - VALUE "FileDescription", "Record and Soft Device Support Library\0" - VALUE "FileVersion", EPICS_VERSION_STRING "\0" - VALUE "InternalName", "dbRecStd\0" - VALUE "LegalCopyright", "Copyright (C) Univ. of California, Univ. of Chicago\0" - VALUE "OriginalFilename", "dbRecStd.dll\0" - VALUE "ProductName", "Experimental Physics and Industrial Control System (EPICS)\0" - VALUE "ProductVersion", EPICS_VERSION_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/std/dev/Makefile b/src/std/dev/Makefile deleted file mode 100644 index ec3713bd6..000000000 --- a/src/std/dev/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/std/Makefile. - -SRC_DIRS += $(STDDIR)/dev - -DBD += devSoft.dbd - -dbRecStd_SRCS += devAaiSoft.c -dbRecStd_SRCS += devAaoSoft.c -dbRecStd_SRCS += devAiSoft.c -dbRecStd_SRCS += devAiSoftRaw.c -dbRecStd_SRCS += devAoSoft.c -dbRecStd_SRCS += devAoSoftRaw.c -dbRecStd_SRCS += devBiSoft.c -dbRecStd_SRCS += devBiSoftRaw.c -dbRecStd_SRCS += devBiDbState.c -dbRecStd_SRCS += devBoSoft.c -dbRecStd_SRCS += devBoSoftRaw.c -dbRecStd_SRCS += devBoDbState.c -dbRecStd_SRCS += devCalcoutSoft.c -dbRecStd_SRCS += devEventSoft.c -dbRecStd_SRCS += devHistogramSoft.c -dbRecStd_SRCS += devI64inSoft.c -dbRecStd_SRCS += devI64outSoft.c -dbRecStd_SRCS += devLiSoft.c -dbRecStd_SRCS += devLoSoft.c -dbRecStd_SRCS += devLsiSoft.c -dbRecStd_SRCS += devLsoSoft.c -dbRecStd_SRCS += devMbbiDirectSoft.c -dbRecStd_SRCS += devMbbiDirectSoftRaw.c -dbRecStd_SRCS += devMbbiSoft.c -dbRecStd_SRCS += devMbbiSoftRaw.c -dbRecStd_SRCS += devMbboDirectSoft.c -dbRecStd_SRCS += devMbboDirectSoftRaw.c -dbRecStd_SRCS += devMbboSoft.c -dbRecStd_SRCS += devMbboSoftRaw.c -dbRecStd_SRCS += devPrintfSoft.c -dbRecStd_SRCS += devSASoft.c -dbRecStd_SRCS += devSiSoft.c -dbRecStd_SRCS += devSoSoft.c -dbRecStd_SRCS += devWfSoft.c -dbRecStd_SRCS += devGeneralTime.c - -dbRecStd_SRCS += devAiSoftCallback.c -dbRecStd_SRCS += devBiSoftCallback.c -dbRecStd_SRCS += devI64inSoftCallback.c -dbRecStd_SRCS += devLiSoftCallback.c -dbRecStd_SRCS += devMbbiDirectSoftCallback.c -dbRecStd_SRCS += devMbbiSoftCallback.c -dbRecStd_SRCS += devSiSoftCallback.c - -dbRecStd_SRCS += devAoSoftCallback.c -dbRecStd_SRCS += devBoSoftCallback.c -dbRecStd_SRCS += devCalcoutSoftCallback.c -dbRecStd_SRCS += devI64outSoftCallback.c -dbRecStd_SRCS += devLoSoftCallback.c -dbRecStd_SRCS += devLsoSoftCallback.c -dbRecStd_SRCS += devMbboSoftCallback.c -dbRecStd_SRCS += devMbboDirectSoftCallback.c -dbRecStd_SRCS += devPrintfSoftCallback.c -dbRecStd_SRCS += devSoSoftCallback.c - -dbRecStd_SRCS += devTimestamp.c -dbRecStd_SRCS += devStdio.c -dbRecStd_SRCS += devEnviron.c - -dbRecStd_SRCS += asSubRecordFunctions.c - diff --git a/src/std/dev/asSubRecordFunctions.c b/src/std/dev/asSubRecordFunctions.c deleted file mode 100644 index 76943e94b..000000000 --- a/src/std/dev/asSubRecordFunctions.c +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* asSubRecordFunctions.c */ - -/* Author: Marty Kraimer Date: 01MAY2000 */ - -#include -#include -#include -#include -#include - -#include "dbAccess.h" -#include "cantProceed.h" -#include "callback.h" -#include "alarm.h" -#include "errlog.h" -#include "dbEvent.h" -#include "recSup.h" -#include "recGbl.h" -#include "registryFunction.h" -#include "asLib.h" -#include "asDbLib.h" -#include "subRecord.h" -#include "epicsExport.h" - -/* The following is provided for access security*/ -/*It allows a CA client to force access security initialization*/ - -static void myCallback(CALLBACK *pcallback) -{ - ASDBCALLBACK *pasdbcallback = (ASDBCALLBACK *)pcallback; - subRecord *precord; - rset *prset; - - callbackGetUser(precord,pcallback); - prset=(rset *)(precord->rset); - precord->val = 0.0; - if(pasdbcallback->status) { - recGblSetSevr(precord,READ_ALARM,precord->brsv); - recGblRecordError(pasdbcallback->status,precord,"asInit Failed"); - } - dbScanLock((dbCommon *)precord); - (*prset->process)((dbCommon *)precord); - dbScanUnlock((dbCommon *)precord); -} - -long asSubInit(subRecord *precord,void *process) -{ - ASDBCALLBACK *pcallback; - - pcallback = (ASDBCALLBACK *)callocMustSucceed( - 1,sizeof(ASDBCALLBACK),"asSubInit"); - precord->dpvt = (void *)pcallback; - callbackSetCallback(myCallback,&pcallback->callback); - callbackSetUser(precord,&pcallback->callback); - return(0); -} - -long asSubProcess(subRecord *precord) -{ - ASDBCALLBACK *pcallback = (ASDBCALLBACK *)precord->dpvt; - - if(!precord->pact && precord->val==1.0) { - db_post_events(precord,&precord->val,DBE_VALUE); - callbackSetPriority(precord->prio,&pcallback->callback); - asInitAsyn(pcallback); - precord->pact=TRUE; - return(1); - } - db_post_events(precord,&precord->val,DBE_VALUE); - return(0); -} - -static registryFunctionRef asSubRef[] = { - {"asSubInit",(REGISTRYFUNCTION)asSubInit}, - {"asSubProcess",(REGISTRYFUNCTION)asSubProcess} -}; - -static void asSub(void) -{ - registryFunctionRefAdd(asSubRef,NELEMENTS(asSubRef)); -} -epicsExportRegistrar(asSub); diff --git a/src/std/dev/devAaiSoft.c b/src/std/dev/devAaiSoft.c deleted file mode 100644 index d2a9875ee..000000000 --- a/src/std/dev/devAaiSoft.c +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * devAaiSoft.c - Device Support Routines for soft Waveform Records - * - * Original Author: Bob Dalesio - * Current Author: Dirk Zimoch - * Date: 27-MAY-2010 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbConstLink.h" -#include "recGbl.h" -#include "devSup.h" -#include "cantProceed.h" -#include "menuYesNo.h" -#include "aaiRecord.h" -#include "epicsExport.h" - -/* Create the dset for devAaiSoft */ -static long init_record(); -static long read_aai(); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_aai; -} devAaiSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_aai -}; -epicsExportAddress(dset,devAaiSoft); - -static long init_record(aaiRecord *prec) -{ - DBLINK *plink = &prec->inp; - - /* This is pass 0, link hasn't been initialized yet */ - dbInitLink(plink, DBF_INLINK); - - if (dbLinkIsConstant(plink)) { - long nRequest = prec->nelm; - long status; - - /* Allocate a buffer, record support hasn't done that yet */ - if (!prec->bptr) { - prec->bptr = callocMustSucceed(nRequest, dbValueSize(prec->ftvl), - "devAaiSoft: buffer calloc failed"); - } - - status = dbLoadLinkArray(plink, prec->ftvl, prec->bptr, &nRequest); - if (!status && nRequest > 0) { - prec->nord = nRequest; - prec->udf = FALSE; - } - } - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - aaiRecord *prec = (aaiRecord *) pinp->precord; - long nRequest = prec->nelm; - long status = dbGetLink(pinp, prec->ftvl, prec->bptr, 0, &nRequest); - - if (!status && nRequest > 0) { - prec->nord = nRequest; - prec->udf = FALSE; - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - } - return status; -} - -static long read_aai(aaiRecord *prec) -{ - struct link *pinp = prec->simm == menuYesNoYES ? &prec->siol : &prec->inp; - long status = dbLinkDoLocked(pinp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(pinp, NULL); - - return status; -} diff --git a/src/std/dev/devAaoSoft.c b/src/std/dev/devAaoSoft.c deleted file mode 100644 index 3331ec1bf..000000000 --- a/src/std/dev/devAaoSoft.c +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * devAaoSoft.c - Device Support Routines for soft Waveform Records - * - * Original Author: Bob Dalesio - * Current Author: Dirk Zimoch - * Date: 27-MAY-2010 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "cantProceed.h" -#include "menuYesNo.h" -#include "aaoRecord.h" -#include "epicsExport.h" - -/* Create the dset for devAaoSoft */ -static long init_record(); -static long write_aao(); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_aao; -} devAaoSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - write_aao -}; -epicsExportAddress(dset,devAaoSoft); - -static long init_record(aaoRecord *prec) -{ - if (dbLinkIsConstant(&prec->out)) { - prec->nord = 0; - } - return 0; -} - -static long write_aao(aaoRecord *prec) -{ - long nRequest = prec->nord; - dbPutLink(prec->simm == menuYesNoYES ? &prec->siol : &prec->out, - prec->ftvl, prec->bptr, nRequest); - - return 0; -} diff --git a/src/std/dev/devAiSoft.c b/src/std/dev/devAiSoft.c deleted file mode 100644 index 0ecc1b13f..000000000 --- a/src/std/dev/devAiSoft.c +++ /dev/null @@ -1,104 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Marty Kraimer - * Date: 3/6/91 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "epicsMath.h" -#include "recGbl.h" -#include "devSup.h" -#include "aiRecord.h" -#include "epicsExport.h" - -/* Create the dset for devAiSoft */ -static long init_record(aiRecord *prec); -static long read_ai(aiRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} devAiSoft = { - 6, - NULL, - NULL, - init_record, - NULL, - read_ai, - NULL -}; -epicsExportAddress(dset, devAiSoft); - -static long init_record(aiRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_DOUBLE, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -struct aivt { - double val; - epicsTimeStamp *ptime; -}; - -static long readLocked(struct link *pinp, void *vvt) -{ - struct aivt *pvt = (struct aivt *) vvt; - long status = dbGetLink(pinp, DBR_DOUBLE, &pvt->val, 0, 0); - - if (!status && pvt->ptime) - dbGetTimeStamp(pinp, pvt->ptime); - - return status; -} - -static long read_ai(aiRecord *prec) -{ - long status; - struct aivt vt; - - if (dbLinkIsConstant(&prec->inp)) - return 2; - - vt.ptime = (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) ? &prec->time : NULL; - - status = dbLinkDoLocked(&prec->inp, readLocked, &vt); - if (status == S_db_noLSET) - status = readLocked(&prec->inp, &vt); - - if (!status) { - /* Apply smoothing algorithm */ - if (prec->smoo != 0.0 && prec->dpvt && finite(prec->val)) - prec->val = vt.val * (1.0 - prec->smoo) + (prec->val * prec->smoo); - else - prec->val = vt.val; - - prec->udf = FALSE; - prec->dpvt = &devAiSoft; /* Any non-zero value */ - } - else - prec->dpvt = NULL; - - return 2; -} diff --git a/src/std/dev/devAiSoftCallback.c b/src/std/dev/devAiSoftCallback.c deleted file mode 100644 index cf38c8713..000000000 --- a/src/std/dev/devAiSoftCallback.c +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devAiSoftCallback.c */ -/* - * Authors: Marty Kraimer & Andrew Johnson - */ - -#include -#include - -#include "alarm.h" -#include "callback.h" -#include "cantProceed.h" -#include "dbCommon.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbChannel.h" -#include "dbNotify.h" -#include "epicsAssert.h" -#include "epicsMath.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "aiRecord.h" -#include "epicsExport.h" - - -#define GET_OPTIONS (DBR_STATUS | DBR_TIME) - -typedef struct devPvt { - processNotify pn; - CALLBACK callback; - long options; - int status; - int smooth; - struct { - DBRstatus - DBRtime - epicsFloat64 value; - } buffer; -} devPvt; - - -static void getCallback(processNotify *ppn, notifyGetType type) -{ - aiRecord *prec = (aiRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - long no_elements = 1; - - if (ppn->status == notifyCanceled) { - printf("devAiSoftCallback::getCallback notifyCanceled\n"); - return; - } - - assert(type == getFieldType); - pdevPvt->status = dbChannelGetField(ppn->chan, DBR_DOUBLE, - &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); -} - -static void doneCallback(processNotify *ppn) -{ - aiRecord *prec = (aiRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); -} - -static long add_record(dbCommon *pcommon) -{ - aiRecord *prec = (aiRecord *)pcommon; - DBLINK *plink = &prec->inp; - dbChannel *chan; - devPvt *pdevPvt; - processNotify *ppn; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - if (plink->type != PV_LINK) { - long status = S_db_badField; - - recGblRecordError(status, (void *)prec, - "devAiSoftCallback (add_record) Illegal INP field"); - return status; - } - - chan = dbChannelCreate(plink->value.pv_link.pvname); - if (!chan) { - long status = S_db_notFound; - - recGblRecordError(status, (void *)prec, - "devAiSoftCallback (add_record) link target not found"); - return status; - } - - pdevPvt = calloc(1, sizeof(*pdevPvt)); - if (!pdevPvt) { - long status = S_db_noMemory; - - recGblRecordError(status, (void *)prec, - "devAiSoftCallback (add_record) out of memory, calloc() failed"); - return status; - } - ppn = &pdevPvt->pn; - - plink->type = PN_LINK; - plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - - ppn->usrPvt = prec; - ppn->chan = chan; - ppn->getCallback = getCallback; - ppn->doneCallback = doneCallback; - ppn->requestType = processGetRequest; - - pdevPvt->options = GET_OPTIONS; - - prec->dpvt = pdevPvt; - return 0; -} - -static long del_record(dbCommon *pcommon) { - aiRecord *prec = (aiRecord *)pcommon; - DBLINK *plink = &prec->inp; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - assert(plink->type == PN_LINK); - - dbNotifyCancel(&pdevPvt->pn); - dbChannelDelete(pdevPvt->pn.chan); - free(pdevPvt); - - plink->type = PV_LINK; - return 0; -} - -static struct dsxt dsxtSoftCallback = { - add_record, del_record -}; - -static long init(int pass) -{ - if (pass == 0) devExtend(&dsxtSoftCallback); - return 0; -} - -static long init_record(aiRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_DOUBLE, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long read_ai(aiRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (!prec->dpvt) - return 2; - - if (!prec->pact) { - dbProcessNotify(&pdevPvt->pn); - prec->pact = TRUE; - return 0; - } - - if (pdevPvt->status) { - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - pdevPvt->smooth = FALSE; - return 2; - } - - /* Apply smoothing algorithm */ - if (prec->smoo != 0.0 && pdevPvt->smooth && finite(prec->val)) - prec->val = prec->val * prec->smoo + - pdevPvt->buffer.value * (1.0 - prec->smoo); - else - prec->val = pdevPvt->buffer.value; - - prec->udf = FALSE; - pdevPvt->smooth = TRUE; - - switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (pdevPvt->buffer.severity < INVALID_ALARM) - break; - /* else fall through */ - case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); - break; - case pvlOptMSS: - recGblSetSevr(prec, pdevPvt->buffer.status, - pdevPvt->buffer.severity); - break; - } - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - prec->time = pdevPvt->buffer.time; - - return 2; -} - -/* Create the dset for devAiSoftCallback */ -struct { - dset common; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} devAiSoftCallback = { - {6, NULL, init, init_record, NULL}, - read_ai, - NULL -}; -epicsExportAddress(dset, devAiSoftCallback); diff --git a/src/std/dev/devAiSoftRaw.c b/src/std/dev/devAiSoftRaw.c deleted file mode 100644 index f2cfd5df5..000000000 --- a/src/std/dev/devAiSoftRaw.c +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Marty Kraimer - * Date: 6-1-90 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "aiRecord.h" -#include "epicsExport.h" - -/* Create the dset for devAiSoftRaw */ -static long init_record(aiRecord *prec); -static long read_ai(aiRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai; - DEVSUPFUN special_linconv; -} devAiSoftRaw = { - 6, - NULL, - NULL, - init_record, - NULL, - read_ai, - NULL -}; -epicsExportAddress(dset, devAiSoftRaw); - -static long init_record(aiRecord *prec) -{ - recGblInitConstantLink(&prec->inp, DBF_LONG, &prec->rval); - - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - aiRecord *prec = (aiRecord *) pinp->precord; - long status = dbGetLink(pinp, DBR_LONG, &prec->rval, 0, 0); - - if (status) return status; - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return status; -} - -static long read_ai(aiRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - return status; -} diff --git a/src/std/dev/devAoSoft.c b/src/std/dev/devAoSoft.c deleted file mode 100644 index 56bd05620..000000000 --- a/src/std/dev/devAoSoft.c +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devAoSoft.c */ - -/* Device Support Routines for soft Analog Output Records*/ -/* - * Original Author: Bob Dalesio - * Current Author: Marty Kraimer - * Date: 6-1-90 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "special.h" -#include "aoRecord.h" -#include "epicsExport.h" - -/* added for Channel Access Links */ -static long init_record(aoRecord *prec); - -/* Create the dset for devAoSoft */ -static long write_ao(aoRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_ao; - DEVSUPFUN special_linconv; -}devAoSoft={ - 6, - NULL, - NULL, - init_record, - NULL, - write_ao, - NULL}; -epicsExportAddress(dset,devAoSoft); - - -static long init_record(aoRecord *prec) -{ - - long status=0; - status = 2; - return status; - -} /* end init_record() */ - -static long write_ao(aoRecord *prec) -{ - long status; - - status = dbPutLink(&prec->out,DBR_DOUBLE, &prec->oval,1); - - return(status); -} diff --git a/src/std/dev/devAoSoftCallback.c b/src/std/dev/devAoSoftCallback.c deleted file mode 100644 index c1fb72f13..000000000 --- a/src/std/dev/devAoSoftCallback.c +++ /dev/null @@ -1,68 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devAoSoftCallbackCallback.c */ -/* - * Author: Marty Kraimer - * Date: 04NOV2003 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "dbCa.h" -#include "link.h" -#include "special.h" -#include "aoRecord.h" -#include "epicsExport.h" - -/* Create the dset for devAoSoftCallback */ -static long write_ao(aoRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_ao; - DEVSUPFUN special_linconv; -}devAoSoftCallback={ - 6, - NULL, - NULL, - NULL, - NULL, - write_ao, - NULL}; -epicsExportAddress(dset,devAoSoftCallback); - -static long write_ao(aoRecord *prec) -{ - struct link *plink = &prec->out; - long status; - - if (prec->pact) - return 0; - - status = dbPutLinkAsync(plink, DBR_DOUBLE, &prec->oval, 1); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, DBR_DOUBLE, &prec->oval, 1); - - return status; -} - diff --git a/src/std/dev/devAoSoftRaw.c b/src/std/dev/devAoSoftRaw.c deleted file mode 100644 index 05aed035e..000000000 --- a/src/std/dev/devAoSoftRaw.c +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devAoSoftRaw.c */ - -/* Device Support Routines for soft raw Analog Output Records*/ -/* - * Author: Janet Anderson - * Date: 09-25-91 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "special.h" -#include "aoRecord.h" -#include "epicsExport.h" - -/* Create the dset for devAoSoftRaw */ -static long write_ao(aoRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_ao; - DEVSUPFUN special_linconv; -}devAoSoftRaw={ - 6, - NULL, - NULL, - NULL, - NULL, - write_ao, - NULL -}; -epicsExportAddress(dset,devAoSoftRaw); - -static long write_ao(aoRecord *prec) -{ - long status; - - status = dbPutLink(&prec->out,DBR_LONG,&prec->rval,1); - - return(status); -} diff --git a/src/std/dev/devBiDbState.c b/src/std/dev/devBiDbState.c deleted file mode 100644 index fcb6c8f63..000000000 --- a/src/std/dev/devBiDbState.c +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include "errlog.h" -#include "dbState.h" -#include "devSup.h" -#include "recGbl.h" -#include "dbLink.h" -#include "dbAccessDefs.h" -#include "biRecord.h" -#include "epicsExport.h" - -#define DEVSUPNAME "devBiDbState" - -static long add_record (struct dbCommon *pdbc) -{ - biRecord *prec = (biRecord *) pdbc; - - if (INST_IO != prec->inp.type) { - recGblRecordError(S_db_badField, (void *) prec, DEVSUPNAME ": Illegal INP field"); - return(S_db_badField); - } - - if (!(prec->dpvt = dbStateFind(prec->inp.value.instio.string)) && - prec->inp.value.instio.string && - '\0' != *prec->inp.value.instio.string) { - errlogSevPrintf(errlogInfo, DEVSUPNAME ": Creating new db state '%s'\n", - prec->inp.value.instio.string); - prec->dpvt = dbStateCreate(prec->inp.value.instio.string); - } - return 0; -} - -static long del_record (struct dbCommon *pdbc) -{ - biRecord *prec = (biRecord *) pdbc; - prec->dpvt = NULL; - return 0; -} - -static struct dsxt myDsxt = { - add_record, - del_record -}; - -static long init(int pass) -{ - if (pass == 0) - devExtend(&myDsxt); - return 0; -} - -static long read_bi(biRecord *prec) -{ - if (prec->dpvt) { - prec->val = dbStateGet(prec->dpvt); - prec->udf = FALSE; - } - - return 2; -} - -static struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi; -} devBiDbState = { - 5, - NULL, - init, - NULL, - NULL, - read_bi -}; - -epicsExportAddress(dset, devBiDbState); diff --git a/src/std/dev/devBiSoft.c b/src/std/dev/devBiSoft.c deleted file mode 100644 index 12640ad0c..000000000 --- a/src/std/dev/devBiSoft.c +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Marty Kraimer - * Date: 6-1-90 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "biRecord.h" -#include "epicsExport.h" - -/* Create the dset for devBiSoft */ -static long init_record(biRecord *prec); -static long read_bi(biRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi; -} devBiSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_bi -}; -epicsExportAddress(dset, devBiSoft); - -static long init_record(biRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_ENUM, &prec->val)) - prec->udf = FALSE; - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - biRecord *prec = (biRecord *) pinp->precord; - long status = dbGetLink(pinp, DBR_USHORT, &prec->val, 0, 0); - - if (status) return status; - - prec->udf = FALSE; - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return 2; -} - -static long read_bi(biRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - return status; -} diff --git a/src/std/dev/devBiSoftCallback.c b/src/std/dev/devBiSoftCallback.c deleted file mode 100644 index 314460049..000000000 --- a/src/std/dev/devBiSoftCallback.c +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devBiSoftCallback.c */ -/* - * Authors: Marty Kraimer & Andrew Johnson - */ - -#include -#include - -#include "alarm.h" -#include "callback.h" -#include "cantProceed.h" -#include "dbCommon.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbChannel.h" -#include "dbNotify.h" -#include "epicsAssert.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "biRecord.h" -#include "epicsExport.h" - - -#define GET_OPTIONS (DBR_STATUS | DBR_TIME) - -typedef struct devPvt { - processNotify pn; - CALLBACK callback; - long options; - int status; - struct { - DBRstatus - DBRtime - epicsEnum16 value; - } buffer; -} devPvt; - - -static void getCallback(processNotify *ppn,notifyGetType type) -{ - biRecord *prec = (biRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - long no_elements = 1; - - if (ppn->status == notifyCanceled) { - printf("devBiSoftCallback::getCallback notifyCanceled\n"); - return; - } - - assert(type == getFieldType); - pdevPvt->status = dbChannelGetField(ppn->chan, DBR_ENUM, - &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); -} - -static void doneCallback(processNotify *ppn) -{ - biRecord *prec = (biRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); -} - -static long add_record(dbCommon *pcommon) -{ - biRecord *prec = (biRecord *)pcommon; - DBLINK *plink = &prec->inp; - dbChannel *chan; - devPvt *pdevPvt; - processNotify *ppn; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - if (plink->type != PV_LINK) { - long status = S_db_badField; - - recGblRecordError(status, (void *)prec, - "devBiSoftCallback (add_record) Illegal INP field"); - return status; - } - - chan = dbChannelCreate(plink->value.pv_link.pvname); - if (!chan) { - long status = S_db_notFound; - - recGblRecordError(status, (void *)prec, - "devBiSoftCallback (add_record) link target not found"); - return status; - } - - pdevPvt = calloc(1, sizeof(*pdevPvt)); - if (!pdevPvt) { - long status = S_db_noMemory; - - recGblRecordError(status, (void *)prec, - "devBiSoftCallback (add_record) out of memory, calloc() failed"); - return status; - } - ppn = &pdevPvt->pn; - - plink->type = PN_LINK; - plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - - ppn->usrPvt = prec; - ppn->chan = chan; - ppn->getCallback = getCallback; - ppn->doneCallback = doneCallback; - ppn->requestType = processGetRequest; - - pdevPvt->options = GET_OPTIONS; - - prec->dpvt = pdevPvt; - return 0; -} - -static long del_record(dbCommon *pcommon) { - biRecord *prec = (biRecord *)pcommon; - DBLINK *plink = &prec->inp; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - assert(plink->type == PN_LINK); - - dbNotifyCancel(&pdevPvt->pn); - dbChannelDelete(pdevPvt->pn.chan); - free(pdevPvt); - - plink->type = PV_LINK; - return 0; -} - -static struct dsxt dsxtSoftCallback = { - add_record, del_record -}; - -static long init(int pass) -{ - if (pass == 0) devExtend(&dsxtSoftCallback); - return 0; -} - -static long init_record(biRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long read_bi(biRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (!prec->dpvt) - return 2; - - if (!prec->pact) { - dbProcessNotify(&pdevPvt->pn); - prec->pact = TRUE; - return 0; - } - - if (pdevPvt->status) { - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return 2; - } - - prec->val = pdevPvt->buffer.value; - prec->udf = FALSE; - - switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (pdevPvt->buffer.severity < INVALID_ALARM) - break; - /* else fall through */ - case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); - break; - case pvlOptMSS: - recGblSetSevr(prec, pdevPvt->buffer.status, - pdevPvt->buffer.severity); - break; - } - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - prec->time = pdevPvt->buffer.time; - - return 2; -} - -/* Create the dset for devBiSoftCallback */ -struct { - dset common; - DEVSUPFUN read_bi; -} devBiSoftCallback = { - {5, NULL, init, init_record, NULL}, - read_bi -}; -epicsExportAddress(dset, devBiSoftCallback); diff --git a/src/std/dev/devBiSoftRaw.c b/src/std/dev/devBiSoftRaw.c deleted file mode 100644 index a71bf89cb..000000000 --- a/src/std/dev/devBiSoftRaw.c +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Marty Kraimer - * Date: 6-1-90 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "biRecord.h" -#include "epicsExport.h" - -/* Create the dset for devBiSoftRaw */ -static long init_record(biRecord *prec); -static long read_bi(biRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi; -} devBiSoftRaw = { - 5, - NULL, - NULL, - init_record, - NULL, - read_bi -}; -epicsExportAddress(dset, devBiSoftRaw); - -static long init_record(biRecord *prec) -{ - recGblInitConstantLink(&prec->inp, DBF_ULONG, &prec->rval); - - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - biRecord *prec = (biRecord *) pinp->precord; - long status = dbGetLink(pinp, DBR_ULONG, &prec->rval, 0, 0); - - if (status) return status; - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return status; -} - -static long read_bi(biRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - return status; -} diff --git a/src/std/dev/devBoDbState.c b/src/std/dev/devBoDbState.c deleted file mode 100644 index 26e97ae5b..000000000 --- a/src/std/dev/devBoDbState.c +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include "errlog.h" -#include "dbState.h" -#include "devSup.h" -#include "recGbl.h" -#include "dbAccessDefs.h" -#include "boRecord.h" -#include "epicsExport.h" - -#define DEVSUPNAME "devBoDbState" - -static long add_record (struct dbCommon *pdbc) -{ - boRecord *prec = (boRecord *) pdbc; - - if (INST_IO != prec->out.type) { - recGblRecordError(S_db_badField, (void *) prec, DEVSUPNAME ": Illegal OUT field"); - return(S_db_badField); - } - - if (!(prec->dpvt = dbStateFind(prec->out.value.instio.string)) && - prec->out.value.instio.string && - '\0' != *prec->out.value.instio.string) { - errlogSevPrintf(errlogInfo, DEVSUPNAME ": Creating new db state '%s'\n", - prec->out.value.instio.string); - prec->dpvt = dbStateCreate(prec->out.value.instio.string); - } - return 0; -} - -static long del_record (struct dbCommon *pdbc) -{ - boRecord *prec = (boRecord *) pdbc; - prec->dpvt = NULL; - return 0; -} - -static struct dsxt myDsxt = { - add_record, - del_record -}; - -static long init(int pass) -{ - if (pass == 0) - devExtend(&myDsxt); - return 0; -} - -static long write_bo(boRecord *prec) -{ - if (prec->val) - dbStateSet(prec->dpvt); - else - dbStateClear(prec->dpvt); - return 0; -} - -static struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_bo; -} devBoDbState = { - 5, - NULL, - init, - NULL, - NULL, - write_bo -}; - -epicsExportAddress(dset, devBoDbState); diff --git a/src/std/dev/devBoSoft.c b/src/std/dev/devBoSoft.c deleted file mode 100644 index ba6ff14a7..000000000 --- a/src/std/dev/devBoSoft.c +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* devBoSoft.c - Device Support Routines for Soft Binary Output*/ -/* - * Original Author: Bob Dalesio - * Current Author: Marty Kraimer - * Date: 6-1-90 - */ - - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "boRecord.h" -#include "epicsExport.h" - -static long init_record(boRecord *prec); - -/* Create the dset for devBoSoft */ -static long write_bo(boRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_bo; -}devBoSoft={ - 5, - NULL, - NULL, - init_record, - NULL, - write_bo -}; -epicsExportAddress(dset,devBoSoft); - -static long init_record(boRecord *prec) -{ - - long status=0; - - /* dont convert */ - status=2; - return status; - -} /* end init_record() */ - -static long write_bo(boRecord *prec) -{ - long status; - - status = dbPutLink(&prec->out,DBR_USHORT,&prec->val,1); - - return(status); -} diff --git a/src/std/dev/devBoSoftCallback.c b/src/std/dev/devBoSoftCallback.c deleted file mode 100644 index ffb68e525..000000000 --- a/src/std/dev/devBoSoftCallback.c +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* devBoCallbackSoft.c */ -/* - * Author: Marty Kraimer - * Date: 04NOV2003 - */ - - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbLock.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "boRecord.h" -#include "epicsExport.h" - -/* Create the dset for devBoCallbackSoft */ -static long write_bo(boRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_bo; -}devBoSoftCallback={ - 5, - NULL, - NULL, - NULL, - NULL, - write_bo -}; -epicsExportAddress(dset,devBoSoftCallback); - -static long write_bo(boRecord *prec) -{ - struct link *plink = &prec->out; - long status; - - if (prec->pact) - return 0; - - status = dbPutLinkAsync(plink, DBR_USHORT, &prec->val, 1); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, DBR_USHORT, &prec->val, 1); - - return status; -} - diff --git a/src/std/dev/devBoSoftRaw.c b/src/std/dev/devBoSoftRaw.c deleted file mode 100644 index df1ba5b4e..000000000 --- a/src/std/dev/devBoSoftRaw.c +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* devBoSoftRaw.c - Device Support Routines for SoftRaw Binary Output*/ -/* - * Author: Janet Anderson - * Date: 3-28-92 - */ - - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "boRecord.h" -#include "epicsExport.h" - -/* added for Channel Access Links */ -static long init_record(boRecord *prec); - -/* Create the dset for devBoSoftRaw */ -static long write_bo(boRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_bo; -}devBoSoftRaw={ - 5, - NULL, - NULL, - init_record, - NULL, - write_bo -}; -epicsExportAddress(dset,devBoSoftRaw); - -static long init_record(boRecord *prec) -{ - long status; - - /*Don't convert*/ - status = 2; - return status; - -} /* end init_record() */ - -static long write_bo(boRecord *prec) -{ - long status; - - status = dbPutLink(&prec->out,DBR_LONG, &prec->rval,1); - - return(status); -} diff --git a/src/std/dev/devCalcoutSoft.c b/src/std/dev/devCalcoutSoft.c deleted file mode 100644 index f931e6ac0..000000000 --- a/src/std/dev/devCalcoutSoft.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devCalcoutSoft.c */ - -/* - * Author: Marty Kraimer - * Date: 05DEC2003 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "special.h" -#include "postfix.h" -#include "calcoutRecord.h" -#include "epicsExport.h" - -static long write_calcout(calcoutRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write; -} devCalcoutSoft = { - 5, NULL, NULL, NULL, NULL, write_calcout -}; -epicsExportAddress(dset, devCalcoutSoft); - -static long write_calcout(calcoutRecord *prec) -{ - return dbPutLink(&prec->out, DBR_DOUBLE, &prec->oval, 1); -} diff --git a/src/std/dev/devCalcoutSoftCallback.c b/src/std/dev/devCalcoutSoftCallback.c deleted file mode 100644 index 94f9d4f99..000000000 --- a/src/std/dev/devCalcoutSoftCallback.c +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devCalcoutSoftCallback.c */ - -/* - * Author: Marty Kraimer - * Date: 05DEC2003 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "special.h" -#include "postfix.h" -#include "calcoutRecord.h" -#include "epicsExport.h" - -static long write_calcout(calcoutRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write; -} devCalcoutSoftCallback = { - 5, NULL, NULL, NULL, NULL, write_calcout -}; -epicsExportAddress(dset, devCalcoutSoftCallback); - -static long write_calcout(calcoutRecord *prec) -{ - struct link *plink = &prec->out; - long status; - - if (prec->pact) - return 0; - - status = dbPutLinkAsync(plink, DBR_DOUBLE, &prec->oval, 1); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, DBR_DOUBLE, &prec->oval, 1); - - return 0; -} - diff --git a/src/std/dev/devEnviron.c b/src/std/dev/devEnviron.c deleted file mode 100644 index 9672d6ce5..000000000 --- a/src/std/dev/devEnviron.c +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* devEnviron.c */ - -#include -#include - -#include "alarm.h" -#include "dbCommon.h" -#include "devSup.h" -#include "errlog.h" -#include "recGbl.h" -#include "recSup.h" - -#include "lsiRecord.h" -#include "stringinRecord.h" -#include "epicsExport.h" - -/* lsi device support */ - -static long add_lsi(dbCommon *pcommon) { - lsiRecord *prec = (lsiRecord *) pcommon; - - if (prec->inp.type != INST_IO) - return S_dev_badInpType; - - return 0; -} - -static long del_lsi(dbCommon *pcommon) { - return 0; -} - -static struct dsxt dsxtLsiEnviron = { - add_lsi, del_lsi -}; - -static long init_lsi(int pass) -{ - if (pass == 0) - devExtend(&dsxtLsiEnviron); - - return 0; -} - -static long read_lsi(lsiRecord *prec) -{ - const char *val = getenv(prec->inp.value.instio.string); - - if (val) { - strncpy(prec->val, val, prec->sizv); - prec->val[prec->sizv - 1] = 0; - prec->len = strlen(prec->val); - prec->udf = FALSE; - } - else { - prec->val[0] = 0; - prec->len = 1; - prec->udf = TRUE; - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - } - - return 0; -} - -lsidset devLsiEnviron = { - 5, NULL, init_lsi, NULL, NULL, read_lsi -}; -epicsExportAddress(dset, devLsiEnviron); - - -/* stringin device support */ - -static long add_stringin(dbCommon *pcommon) { - stringinRecord *prec = (stringinRecord *) pcommon; - - if (prec->inp.type != INST_IO) - return S_dev_badInpType; - - return 0; -} - -static long del_stringin(dbCommon *pcommon) { - return 0; -} - -static struct dsxt dsxtSiEnviron = { - add_stringin, del_stringin -}; - -static long init_stringin(int pass) -{ - if (pass == 0) - devExtend(&dsxtSiEnviron); - - return 0; -} - -static long read_stringin(stringinRecord *prec) -{ - const char *val = getenv(prec->inp.value.instio.string); - - if (val) { - strncpy(prec->val, val, MAX_STRING_SIZE); - prec->val[MAX_STRING_SIZE - 1] = 0; - prec->udf = FALSE; - } - else { - prec->val[0] = 0; - prec->udf = TRUE; - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - } - - return 0; -} - -static struct { - dset common; - DEVSUPFUN read; -} devSiEnviron = { - {5, NULL, init_stringin, NULL, NULL}, read_stringin -}; -epicsExportAddress(dset, devSiEnviron); diff --git a/src/std/dev/devEventSoft.c b/src/std/dev/devEventSoft.c deleted file mode 100644 index a748dda66..000000000 --- a/src/std/dev/devEventSoft.c +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Janet Anderson - * Date: 04-21-91 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "eventRecord.h" -#include "epicsExport.h" - -/* Create the dset for devEventSoft */ -static long init_record(eventRecord *prec); -static long read_event(eventRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_event; -} devEventSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_event -}; -epicsExportAddress(dset, devEventSoft); - -static long init_record(eventRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_STRING, prec->val)) - prec->udf = FALSE; - - return 0; -} - -struct eventvt { - char newEvent[MAX_STRING_SIZE]; - epicsTimeStamp *ptime; -}; - -static long readLocked(struct link *pinp, void *vvt) -{ - struct eventvt *pvt = (struct eventvt *) vvt; - long status = dbGetLink(pinp, DBR_STRING, pvt->newEvent, 0, 0); - - if (!status && pvt->ptime) - dbGetTimeStamp(pinp, pvt->ptime); - - return status; -} - -static long read_event(eventRecord *prec) -{ - long status; - struct eventvt vt; - - if (dbLinkIsConstant(&prec->inp)) - return 0; - - vt.ptime = (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) ? &prec->time : NULL; - - status = dbLinkDoLocked(&prec->inp, readLocked, &vt); - if (status == S_db_noLSET) - status = readLocked(&prec->inp, &vt); - - if (!status) { - if (strcmp(vt.newEvent, prec->val) != 0) { - strcpy(prec->val, vt.newEvent); - prec->epvt = eventNameToHandle(prec->val); - } - prec->udf = FALSE; - } - - return status; -} diff --git a/src/std/dev/devGeneralTime.c b/src/std/dev/devGeneralTime.c deleted file mode 100644 index 1b821d582..000000000 --- a/src/std/dev/devGeneralTime.c +++ /dev/null @@ -1,297 +0,0 @@ -/*************************************************************************\ -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Author: Sheng Peng, ORNL / SNS Project - * Date: 07/2004 - * - * EPICS device support for general timestamp support - * - * Integrated into base by Peter Denison, Diamond Light Source - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "epicsString.h" -#include "epicsGeneralTime.h" - -#include "aiRecord.h" -#include "boRecord.h" -#include "longinRecord.h" -#include "stringinRecord.h" -#include "epicsExport.h" - - -/********* ai record **********/ -static int getCurrentTime(double * pseconds) -{ - epicsTimeStamp ts; - - if (epicsTimeOK == epicsTimeGetCurrent(&ts)) { - *pseconds = ts.secPastEpoch + ((double)(ts.nsec)) * 1e-9; - return 0; - } - return -1; -} - -static struct ai_channel { - char *name; - int (*get)(double *); -} ai_channels[] = { - {"TIME", getCurrentTime}, -}; - -static long init_ai(aiRecord *prec) -{ - int i; - - if (prec->inp.type != INST_IO) { - recGblRecordError(S_db_badField, (void *)prec, - "devAiGeneralTime::init_ai: Illegal INP field"); - prec->pact = TRUE; - return S_db_badField; - } - - for (i = 0; i < NELEMENTS(ai_channels); i++) { - struct ai_channel *pchan = &ai_channels[i]; - if (!epicsStrCaseCmp(prec->inp.value.instio.string, pchan->name)) { - prec->dpvt = pchan; - return 0; - } - } - - recGblRecordError(S_db_badField, (void *)prec, - "devAiGeneralTime::init_ai: Bad parm"); - prec->pact = TRUE; - prec->dpvt = NULL; - return S_db_badField; -} - -static long read_ai(aiRecord *prec) -{ - struct ai_channel *pchan = (struct ai_channel *)prec->dpvt; - - if (!pchan) return -1; - - if (pchan->get(&prec->val) == 0) { - prec->udf = FALSE; - return 2; - } - prec->udf = TRUE; - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return -1; -} - -struct { - dset common; - DEVSUPFUN read_write; - DEVSUPFUN special_linconv; -} devAiGeneralTime = { - {6, NULL, NULL, init_ai, NULL}, read_ai, NULL -}; -epicsExportAddress(dset, devAiGeneralTime); - - -/********* bo record **********/ -static void resetErrors(void) -{ - generalTimeResetErrorCounts(); -} - -static struct bo_channel { - char *name; - void (*put)(void); -} bo_channels[] = { - {"RSTERRCNT", resetErrors}, -}; - -static long init_bo(boRecord *prec) -{ - int i; - - if (prec->out.type != INST_IO) { - recGblRecordError(S_db_badField, (void *)prec, - "devAiGeneralTime::init_ai: Illegal INP field"); - prec->pact = TRUE; - return S_db_badField; - } - - for (i = 0; i < NELEMENTS(bo_channels); i++) { - struct bo_channel *pchan = &bo_channels[i]; - if (!epicsStrCaseCmp(prec->out.value.instio.string, pchan->name)) { - prec->dpvt = pchan; - prec->mask = 0; - return 2; - } - } - - recGblRecordError(S_db_badField, (void *)prec, - "devBoGeneralTime::init_bo: Bad parm"); - prec->pact = TRUE; - prec->dpvt = NULL; - return S_db_badField; -} - -static long write_bo(boRecord *prec) -{ - struct bo_channel *pchan = (struct bo_channel *)prec->dpvt; - - if (!pchan) return -1; - - pchan->put(); - return 0; -} - -struct { - dset common; - DEVSUPFUN read_write; -} devBoGeneralTime = { - {5, NULL, NULL, init_bo, NULL}, write_bo -}; -epicsExportAddress(dset, devBoGeneralTime); - - -/******* longin record *************/ -static int errorCount(void) -{ - return generalTimeGetErrorCounts(); -} - -static struct li_channel { - char *name; - int (*get)(void); -} li_channels[] = { - {"GETERRCNT", errorCount}, -}; - -static long init_li(longinRecord *prec) -{ - int i; - - if (prec->inp.type != INST_IO) { - recGblRecordError(S_db_badField, (void *)prec, - "devLiGeneralTime::init_li: Illegal INP field"); - prec->pact = TRUE; - return S_db_badField; - } - - for (i = 0; i < NELEMENTS(li_channels); i++) { - struct li_channel *pchan = &li_channels[i]; - if (!epicsStrCaseCmp(prec->inp.value.instio.string, pchan->name)) { - prec->dpvt = pchan; - return 0; - } - } - - recGblRecordError(S_db_badField, (void *)prec, - "devLiGeneralTime::init_li: Bad parm"); - prec->pact = TRUE; - prec->dpvt = NULL; - return S_db_badField; -} - -static long read_li(longinRecord *prec) -{ - struct li_channel *pchan = (struct li_channel *)prec->dpvt; - - if (!pchan) return -1; - - prec->val = pchan->get(); - return 0; -} - -struct { - dset common; - DEVSUPFUN read_write; -} devLiGeneralTime = { - {5, NULL, NULL, init_li, NULL}, read_li -}; -epicsExportAddress(dset, devLiGeneralTime); - - -/********** stringin record **********/ -static const char * timeProvider(void) -{ - return generalTimeCurrentProviderName(); -} - -static const char * highestProvider(void) -{ - return generalTimeHighestCurrentName(); -} - -static const char * eventProvider(void) -{ - return generalTimeEventProviderName(); -} - -static struct si_channel { - char *name; - const char * (*get)(void); -} si_channels[] = { - {"BESTTCP", timeProvider}, - {"TOPTCP", highestProvider}, - {"BESTTEP", eventProvider}, -}; - -static long init_si(stringinRecord *prec) -{ - int i; - - if (prec->inp.type != INST_IO) { - recGblRecordError(S_db_badField, (void *)prec, - "devSiGeneralTime::init_si: Illegal INP field"); - prec->pact = TRUE; - return S_db_badField; - } - - for (i = 0; i < NELEMENTS(si_channels); i++) { - struct si_channel *pchan = &si_channels[i]; - if (!epicsStrCaseCmp(prec->inp.value.instio.string, pchan->name)) { - prec->dpvt = pchan; - return 0; - } - } - - recGblRecordError(S_db_badField, (void *)prec, - "devSiGeneralTime::init_si: Bad parm"); - prec->pact = TRUE; - prec->dpvt = NULL; - return S_db_badField; -} - -static long read_si(stringinRecord *prec) -{ - struct si_channel *pchan = (struct si_channel *)prec->dpvt; - const char *name; - - if (!pchan) return -1; - - name = pchan->get(); - if (name) { - strncpy(prec->val, name, sizeof(prec->val)); - prec->val[sizeof(prec->val) - 1] = '\0'; - } else { - strcpy(prec->val, "No working providers"); - recGblSetSevr(prec, READ_ALARM, MAJOR_ALARM); - } - prec->udf = FALSE; - return 0; -} - -struct { - dset common; - DEVSUPFUN read_write; -} devSiGeneralTime = { - {5, NULL, NULL, init_si, NULL}, read_si -}; -epicsExportAddress(dset, devSiGeneralTime); diff --git a/src/std/dev/devHistogramSoft.c b/src/std/dev/devHistogramSoft.c deleted file mode 100644 index 3b46b5d99..000000000 --- a/src/std/dev/devHistogramSoft.c +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devHistogramSoft.c */ -/* - * Author: Janet Anderson - * Date: 07/02/91 - */ -#include -#include -#include - -#include "alarm.h" -#include "cvtTable.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "histogramRecord.h" -#include "epicsExport.h" - -/* Create the dset for devHistogramSoft */ -static long init_record(histogramRecord *prec); -static long read_histogram(histogramRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_histogram; - DEVSUPFUN special_linconv; -}devHistogramSoft={ - 6, - NULL, - NULL, - init_record, - NULL, - read_histogram, - NULL -}; -epicsExportAddress(dset,devHistogramSoft); - -static long init_record(histogramRecord *prec) -{ - if (recGblInitConstantLink(&prec->svl,DBF_DOUBLE,&prec->sgnl)) - prec->udf = FALSE; - - return 0; -} - -static long read_histogram(histogramRecord *prec) -{ - dbGetLink(&prec->svl, DBR_DOUBLE, &prec->sgnl, 0, 0); - return 0; /*add count*/ -} diff --git a/src/std/dev/devI64inSoft.c b/src/std/dev/devI64inSoft.c deleted file mode 100644 index 8d4ad90b7..000000000 --- a/src/std/dev/devI64inSoft.c +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Author: Janet Anderson - * Date: 09-23-91 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "int64inRecord.h" -#include "epicsExport.h" - -/* Create the dset for devI64inSoft */ -static long init_record(int64inRecord *prec); -static long read_int64in(int64inRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_int64in; -} devI64inSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_int64in -}; -epicsExportAddress(dset, devI64inSoft); - -static long init_record(int64inRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_INT64, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - int64inRecord *prec = (int64inRecord *) pinp->precord; - long status = dbGetLink(&prec->inp, DBR_INT64, &prec->val, 0, 0); - - if (status) return status; - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return status; -} - -static long read_int64in(int64inRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - return status; -} diff --git a/src/std/dev/devI64inSoftCallback.c b/src/std/dev/devI64inSoftCallback.c deleted file mode 100644 index 9eb5656bb..000000000 --- a/src/std/dev/devI64inSoftCallback.c +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devI64inSoftCallback.c */ -/* - * Authors: Marty Kraimer & Andrew Johnson - */ - -#include -#include - -#include "alarm.h" -#include "callback.h" -#include "cantProceed.h" -#include "dbCommon.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbChannel.h" -#include "dbNotify.h" -#include "epicsAssert.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "int64inRecord.h" -#include "epicsExport.h" - - -#define GET_OPTIONS (DBR_STATUS | DBR_TIME) - -typedef struct devPvt { - processNotify pn; - CALLBACK callback; - long options; - int status; - struct { - DBRstatus - DBRtime - epicsInt64 value; - } buffer; -} devPvt; - - -static void getCallback(processNotify *ppn, notifyGetType type) -{ - int64inRecord *prec = (int64inRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - long no_elements = 1; - - if (ppn->status == notifyCanceled) { - printf("devI64inSoftCallback::getCallback notifyCanceled\n"); - return; - } - - assert(type == getFieldType); - pdevPvt->status = dbChannelGetField(ppn->chan, DBR_INT64, - &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); -} - -static void doneCallback(processNotify *ppn) -{ - int64inRecord *prec = (int64inRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); -} - -static long add_record(dbCommon *pcommon) -{ - int64inRecord *prec = (int64inRecord *)pcommon; - DBLINK *plink = &prec->inp; - dbChannel *chan; - devPvt *pdevPvt; - processNotify *ppn; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - if (plink->type != PV_LINK) { - long status = S_db_badField; - - recGblRecordError(status, (void *)prec, - "devI64inSoftCallback (add_record) Illegal INP field"); - return status; - } - - chan = dbChannelCreate(plink->value.pv_link.pvname); - if (!chan) { - long status = S_db_notFound; - - recGblRecordError(status, (void *)prec, - "devI64inSoftCallback (init_record) linked record not found"); - return status; - } - - pdevPvt = calloc(1, sizeof(*pdevPvt)); - if (!pdevPvt) { - long status = S_db_noMemory; - - recGblRecordError(status, (void *)prec, - "devI64inSoftCallback (add_record) out of memory, calloc() failed"); - return status; - } - ppn = &pdevPvt->pn; - - plink->type = PN_LINK; - plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - - ppn->usrPvt = prec; - ppn->chan = chan; - ppn->getCallback = getCallback; - ppn->doneCallback = doneCallback; - ppn->requestType = processGetRequest; - - pdevPvt->options = GET_OPTIONS; - - prec->dpvt = pdevPvt; - return 0; -} - -static long del_record(dbCommon *pcommon) { - int64inRecord *prec = (int64inRecord *)pcommon; - DBLINK *plink = &prec->inp; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - assert(plink->type == PN_LINK); - - dbNotifyCancel(&pdevPvt->pn); - dbChannelDelete(pdevPvt->pn.chan); - free(pdevPvt); - - plink->type = PV_LINK; - return 0; -} - -static struct dsxt dsxtSoftCallback = { - add_record, del_record -}; - -static long init(int pass) -{ - if (pass == 0) devExtend(&dsxtSoftCallback); - return 0; -} - -static long init_record(int64inRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBR_INT64, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long read_int64in(int64inRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (!prec->dpvt) - return 0; - - if (!prec->pact) { - dbProcessNotify(&pdevPvt->pn); - prec->pact = TRUE; - return 0; - } - - if (pdevPvt->status) { - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return pdevPvt->status; - } - - prec->val = pdevPvt->buffer.value; - prec->udf = FALSE; - - switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (pdevPvt->buffer.severity < INVALID_ALARM) - break; - /* else fall through */ - case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); - break; - case pvlOptMSS: - recGblSetSevr(prec, pdevPvt->buffer.status, - pdevPvt->buffer.severity); - break; - } - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - prec->time = pdevPvt->buffer.time; - - return 0; -} - -/* Create the dset for devI64inSoftCallback */ -struct { - dset common; - DEVSUPFUN read_int64in; -} devI64inSoftCallback = { - {5, NULL, init, init_record, NULL}, - read_int64in -}; -epicsExportAddress(dset, devI64inSoftCallback); diff --git a/src/std/dev/devI64outSoft.c b/src/std/dev/devI64outSoft.c deleted file mode 100644 index f9ac70a7e..000000000 --- a/src/std/dev/devI64outSoft.c +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Author: Janet Anderson - * Date: 09-23-91 -*/ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "int64outRecord.h" -#include "epicsExport.h" - -/* Create the dset for devI64outSoft */ -static long init_record(int64outRecord *prec); -static long write_int64out(int64outRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_int64out; -} devI64outSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - write_int64out -}; -epicsExportAddress(dset, devI64outSoft); - -static long init_record(int64outRecord *prec) -{ - return 0; -} - -static long write_int64out(int64outRecord *prec) -{ - dbPutLink(&prec->out, DBR_INT64, &prec->val,1); - return 0; -} diff --git a/src/std/dev/devI64outSoftCallback.c b/src/std/dev/devI64outSoftCallback.c deleted file mode 100644 index e8041a26f..000000000 --- a/src/std/dev/devI64outSoftCallback.c +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Author: Marty Kraimer - * Date: 04NOV2003 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "int64outRecord.h" -#include "epicsExport.h" - -/* Create the dset for devI64outSoftCallback */ -static long write_int64out(int64outRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_int64out; -} devI64outSoftCallback = { - 5, - NULL, - NULL, - NULL, - NULL, - write_int64out -}; -epicsExportAddress(dset, devI64outSoftCallback); - -static long write_int64out(int64outRecord *prec) -{ - struct link *plink = &prec->out; - long status; - - if (prec->pact) - return 0; - - status = dbPutLinkAsync(plink, DBR_INT64, &prec->val, 1); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, DBR_INT64, &prec->val, 1); - - return status; -} diff --git a/src/std/dev/devLiSoft.c b/src/std/dev/devLiSoft.c deleted file mode 100644 index 6d7b7fda1..000000000 --- a/src/std/dev/devLiSoft.c +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Janet Anderson - * Date: 09-23-91 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "longinRecord.h" -#include "epicsExport.h" - -/* Create the dset for devLiSoft */ -static long init_record(longinRecord *prec); -static long read_longin(longinRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_longin; -} devLiSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_longin -}; -epicsExportAddress(dset, devLiSoft); - -static long init_record(longinRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_LONG, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - longinRecord *prec = (longinRecord *) pinp->precord; - long status = dbGetLink(pinp, DBR_LONG, &prec->val, 0, 0); - - if (status) return status; - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return status; -} - -static long read_longin(longinRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - return status; -} diff --git a/src/std/dev/devLiSoftCallback.c b/src/std/dev/devLiSoftCallback.c deleted file mode 100644 index caab523e5..000000000 --- a/src/std/dev/devLiSoftCallback.c +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLiSoftCallback.c */ -/* - * Authors: Marty Kraimer & Andrew Johnson - */ - -#include -#include - -#include "alarm.h" -#include "callback.h" -#include "cantProceed.h" -#include "dbCommon.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbChannel.h" -#include "dbNotify.h" -#include "epicsAssert.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "longinRecord.h" -#include "epicsExport.h" - - -#define GET_OPTIONS (DBR_STATUS | DBR_TIME) - -typedef struct devPvt { - processNotify pn; - CALLBACK callback; - long options; - int status; - struct { - DBRstatus - DBRtime - epicsInt32 value; - } buffer; -} devPvt; - - -static void getCallback(processNotify *ppn, notifyGetType type) -{ - longinRecord *prec = (longinRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - long no_elements = 1; - - if (ppn->status == notifyCanceled) { - printf("devLiSoftCallback::getCallback notifyCanceled\n"); - return; - } - - assert(type == getFieldType); - pdevPvt->status = dbChannelGetField(ppn->chan, DBR_LONG, - &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); -} - -static void doneCallback(processNotify *ppn) -{ - longinRecord *prec = (longinRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); -} - -static long add_record(dbCommon *pcommon) -{ - longinRecord *prec = (longinRecord *)pcommon; - DBLINK *plink = &prec->inp; - dbChannel *chan; - devPvt *pdevPvt; - processNotify *ppn; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - if (plink->type != PV_LINK) { - long status = S_db_badField; - - recGblRecordError(status, (void *)prec, - "devLiSoftCallback (add_record) Illegal INP field"); - return status; - } - - chan = dbChannelCreate(plink->value.pv_link.pvname); - if (!chan) { - long status = S_db_notFound; - - recGblRecordError(status, (void *)prec, - "devLiSoftCallback (init_record) linked record not found"); - return status; - } - - pdevPvt = calloc(1, sizeof(*pdevPvt)); - if (!pdevPvt) { - long status = S_db_noMemory; - - recGblRecordError(status, (void *)prec, - "devLiSoftCallback (add_record) out of memory, calloc() failed"); - return status; - } - ppn = &pdevPvt->pn; - - plink->type = PN_LINK; - plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - - ppn->usrPvt = prec; - ppn->chan = chan; - ppn->getCallback = getCallback; - ppn->doneCallback = doneCallback; - ppn->requestType = processGetRequest; - - pdevPvt->options = GET_OPTIONS; - - prec->dpvt = pdevPvt; - return 0; -} - -static long del_record(dbCommon *pcommon) { - longinRecord *prec = (longinRecord *)pcommon; - DBLINK *plink = &prec->inp; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - assert(plink->type == PN_LINK); - - dbNotifyCancel(&pdevPvt->pn); - dbChannelDelete(pdevPvt->pn.chan); - free(pdevPvt); - - plink->type = PV_LINK; - return 0; -} - -static struct dsxt dsxtSoftCallback = { - add_record, del_record -}; - -static long init(int pass) -{ - if (pass == 0) devExtend(&dsxtSoftCallback); - return 0; -} - -static long init_record(longinRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBR_LONG, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long read_li(longinRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (!prec->dpvt) - return 0; - - if (!prec->pact) { - dbProcessNotify(&pdevPvt->pn); - prec->pact = TRUE; - return 0; - } - - if (pdevPvt->status) { - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return pdevPvt->status; - } - - prec->val = pdevPvt->buffer.value; - prec->udf = FALSE; - - switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (pdevPvt->buffer.severity < INVALID_ALARM) - break; - /* else fall through */ - case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); - break; - case pvlOptMSS: - recGblSetSevr(prec, pdevPvt->buffer.status, - pdevPvt->buffer.severity); - break; - } - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - prec->time = pdevPvt->buffer.time; - - return 0; -} - -/* Create the dset for devLiSoftCallback */ -struct { - dset common; - DEVSUPFUN read_li; -} devLiSoftCallback = { - {5, NULL, init, init_record, NULL}, - read_li -}; -epicsExportAddress(dset, devLiSoftCallback); diff --git a/src/std/dev/devLoSoft.c b/src/std/dev/devLoSoft.c deleted file mode 100644 index af49c60ff..000000000 --- a/src/std/dev/devLoSoft.c +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devLoSoft.c */ -/* - * Author: Janet Anderson - * Date: 09-23-91 -*/ -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "longoutRecord.h" -#include "epicsExport.h" - -/* Create the dset for devLoSoft */ -static long init_record(longoutRecord *prec); -static long write_longout(longoutRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_longout; -}devLoSoft={ - 5, - NULL, - NULL, - init_record, - NULL, - write_longout -}; -epicsExportAddress(dset,devLoSoft); - -static long init_record(longoutRecord *prec) -{ - return 0; -} /* end init_record() */ - -static long write_longout(longoutRecord *prec) -{ - dbPutLink(&prec->out,DBR_LONG, &prec->val,1); - return 0; -} diff --git a/src/std/dev/devLoSoftCallback.c b/src/std/dev/devLoSoftCallback.c deleted file mode 100644 index f211957b5..000000000 --- a/src/std/dev/devLoSoftCallback.c +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* devLoSoftCallback.c */ -/* - * Author: Marty Kraimer - * Date: 04NOV2003 - */ - - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "longoutRecord.h" -#include "epicsExport.h" - -/* Create the dset for devLoSoftCallback */ -static long write_longout(longoutRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_longout; -}devLoSoftCallback={ - 5, - NULL, - NULL, - NULL, - NULL, - write_longout -}; -epicsExportAddress(dset,devLoSoftCallback); - -static long write_longout(longoutRecord *prec) -{ - struct link *plink = &prec->out; - long status; - - if (prec->pact) - return 0; - - status = dbPutLinkAsync(plink, DBR_LONG, &prec->val, 1); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, DBR_LONG, &prec->val, 1); - - return status; -} - diff --git a/src/std/dev/devLsiSoft.c b/src/std/dev/devLsiSoft.c deleted file mode 100644 index 3076c9900..000000000 --- a/src/std/dev/devLsiSoft.c +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Long String Input soft device support - * - * Author: Andrew Johnson - * Date: 2012-11-28 - */ - -#include "dbAccess.h" -#include "epicsTime.h" -#include "link.h" -#include "lsiRecord.h" -#include "epicsExport.h" - -static long init_record(lsiRecord *prec) -{ - dbLoadLinkLS(&prec->inp, prec->val, prec->sizv, &prec->len); - - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - lsiRecord *prec = (lsiRecord *) pinp->precord; - long status = dbGetLinkLS(pinp, prec->val, prec->sizv, &prec->len); - - if (status) return status; - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return status; -} - -static long read_string(lsiRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - return status; -} - -lsidset devLsiSoft = { - 5, NULL, NULL, init_record, NULL, read_string -}; -epicsExportAddress(dset, devLsiSoft); diff --git a/src/std/dev/devLsoSoft.c b/src/std/dev/devLsoSoft.c deleted file mode 100644 index 02079a053..000000000 --- a/src/std/dev/devLsoSoft.c +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Long String Output soft device support - * - * Author: Andrew Johnson - * Date: 2012-11-29 - */ - -#include "dbAccess.h" -#include "lsoRecord.h" -#include "epicsExport.h" - -static long write_string(lsoRecord *prec) -{ - return dbPutLinkLS(&prec->out, prec->val, prec->len); -} - -lsodset devLsoSoft = { - 5, NULL, NULL, NULL, NULL, write_string -}; -epicsExportAddress(dset, devLsoSoft); diff --git a/src/std/dev/devLsoSoftCallback.c b/src/std/dev/devLsoSoftCallback.c deleted file mode 100644 index 59579d558..000000000 --- a/src/std/dev/devLsoSoftCallback.c +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Andrew Johnson - * Date: 30 Nov 2012 - */ - -#include "alarm.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "lsoRecord.h" -#include "epicsExport.h" - -static long write_string(lsoRecord *prec) -{ - struct link *plink = &prec->out; - int dtyp = dbGetLinkDBFtype(plink); - long len = prec->len; - long status; - - if (prec->pact || dtyp < 0) - return 0; - - if (dtyp != DBR_CHAR && dtyp != DBF_UCHAR) { - dtyp = DBR_STRING; - len = 1; - } - - status = dbPutLinkAsync(plink, dtyp, prec->val, len); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, dtyp, prec->val, len); - - return status; -} - -lsodset devLsoSoftCallback = { - 5, NULL, NULL, NULL, NULL, write_string -}; -epicsExportAddress(dset, devLsoSoftCallback); - diff --git a/src/std/dev/devMbbiDirectSoft.c b/src/std/dev/devMbbiDirectSoft.c deleted file mode 100644 index 9c929b2b6..000000000 --- a/src/std/dev/devMbbiDirectSoft.c +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Matthew Needes - * Date: 10-08-93 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "mbbiDirectRecord.h" -#include "epicsExport.h" - -/* Create the dset for devMbbiDirectSoft */ -static long init_record(mbbiDirectRecord *prec); -static long read_mbbi(mbbiDirectRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbi; -} devMbbiDirectSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_mbbi -}; -epicsExportAddress(dset, devMbbiDirectSoft); - -static long init_record(mbbiDirectRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_ENUM, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - mbbiDirectRecord *prec = (mbbiDirectRecord *) pinp->precord; - long status = dbGetLink(pinp, DBR_USHORT, &prec->val, 0, 0); - - if (status) return status; - - prec->udf = FALSE; - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return 2; -} - -static long read_mbbi(mbbiDirectRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - return status; -} diff --git a/src/std/dev/devMbbiDirectSoftCallback.c b/src/std/dev/devMbbiDirectSoftCallback.c deleted file mode 100644 index 93016329f..000000000 --- a/src/std/dev/devMbbiDirectSoftCallback.c +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devMbbiDirectSoftCallback.c */ -/* - * Authors: Marty Kraimer & Andrew Johnson - */ - -#include -#include - -#include "alarm.h" -#include "callback.h" -#include "cantProceed.h" -#include "dbCommon.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbChannel.h" -#include "dbNotify.h" -#include "epicsAssert.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "mbbiDirectRecord.h" -#include "epicsExport.h" - - -#define GET_OPTIONS (DBR_STATUS | DBR_TIME) - -typedef struct devPvt { - processNotify pn; - CALLBACK callback; - long options; - int status; - struct { - DBRstatus - DBRtime - epicsUInt16 value; - } buffer; -} devPvt; - - -static void getCallback(processNotify *ppn, notifyGetType type) -{ - mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - long no_elements = 1; - - if (ppn->status == notifyCanceled) { - printf("devMbbiDirectSoftCallback::getCallback notifyCanceled\n"); - return; - } - - assert(type == getFieldType); - pdevPvt->status = dbChannelGetField(ppn->chan, DBR_USHORT, - &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); -} - -static void doneCallback(processNotify *ppn) -{ - mbbiDirectRecord *prec = (mbbiDirectRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); -} - -static long add_record(dbCommon *pcommon) -{ - mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon; - DBLINK *plink = &prec->inp; - dbChannel *chan; - devPvt *pdevPvt; - processNotify *ppn; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - if (plink->type != PV_LINK) { - long status = S_db_badField; - - recGblRecordError(status, (void *)prec, - "devMbbiDirectSoftCallback (add_record) Illegal INP field"); - return status; - } - - chan = dbChannelCreate(plink->value.pv_link.pvname); - if (!chan) { - long status = S_db_notFound; - - recGblRecordError(status,(void *)prec, - "devMbbiDirectSoftCallback (add_record) linked record not found"); - return status; - } - - pdevPvt = calloc(1, sizeof(*pdevPvt)); - if (!pdevPvt) { - long status = S_db_noMemory; - - recGblRecordError(status, (void *)prec, - "devMbbiDirectSoftCallback (add_record) out of memory, calloc() failed"); - return status; - } - ppn = &pdevPvt->pn; - - plink->type = PN_LINK; - plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - - ppn->usrPvt = prec; - ppn->chan = chan; - ppn->getCallback = getCallback; - ppn->doneCallback = doneCallback; - ppn->requestType = processGetRequest; - - pdevPvt->options = GET_OPTIONS; - - prec->dpvt = pdevPvt; - return 0; -} - -static long del_record(dbCommon *pcommon) { - mbbiDirectRecord *prec = (mbbiDirectRecord *)pcommon; - DBLINK *plink = &prec->inp; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - assert(plink->type == PN_LINK); - - dbNotifyCancel(&pdevPvt->pn); - dbChannelDelete(pdevPvt->pn.chan); - free(pdevPvt); - - plink->type = PV_LINK; - return 0; -} - -static struct dsxt dsxtSoftCallback = { - add_record, del_record -}; - -static long init(int pass) -{ - if (pass == 0) devExtend(&dsxtSoftCallback); - return 0; -} - -static long init_record(mbbiDirectRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long read_mbbiDirect(mbbiDirectRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (!prec->dpvt) - return 2; - - if (!prec->pact) { - dbProcessNotify(&pdevPvt->pn); - prec->pact = TRUE; - return 0; - } - - if (pdevPvt->status) { - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return 2; - } - - prec->val = pdevPvt->buffer.value; - prec->udf = FALSE; - - switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (pdevPvt->buffer.severity < INVALID_ALARM) - break; - /* else fall through */ - case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); - break; - case pvlOptMSS: - recGblSetSevr(prec, pdevPvt->buffer.status, - pdevPvt->buffer.severity); - break; - } - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - prec->time = pdevPvt->buffer.time; - - return 2; -} - -/* Create the dset for devMbbiDirectSoftCallback */ -struct { - dset common; - DEVSUPFUN read_mbbiDirect; -} devMbbiDirectSoftCallback = { - {5, NULL, init, init_record, NULL}, - read_mbbiDirect -}; -epicsExportAddress(dset, devMbbiDirectSoftCallback); diff --git a/src/std/dev/devMbbiDirectSoftRaw.c b/src/std/dev/devMbbiDirectSoftRaw.c deleted file mode 100644 index f6172cdec..000000000 --- a/src/std/dev/devMbbiDirectSoftRaw.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Matthew Needes - * Date: 10-08-93 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "mbbiDirectRecord.h" -#include "epicsExport.h" - -/* Create the dset for devMbbiDirectSoftRaw */ -static long init_record(mbbiDirectRecord *prec); -static long read_mbbi(mbbiDirectRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbi; -} devMbbiDirectSoftRaw = { - 5, - NULL, - NULL, - init_record, - NULL, - read_mbbi -}; -epicsExportAddress(dset, devMbbiDirectSoftRaw); - -static long init_record(mbbiDirectRecord *prec) -{ - recGblInitConstantLink(&prec->inp, DBF_ULONG, &prec->rval); - - /* Preserve old functionality */ - if (prec->nobt == 0) - prec->mask = 0xffffffff; - - prec->mask <<= prec->shft; - return 0; -} - -static long read_mbbi(mbbiDirectRecord *prec) -{ - if (!dbGetLink(&prec->inp, DBR_LONG, &prec->rval, 0, 0)) { - prec->rval &= prec->mask; - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(&prec->inp, &prec->time); - } - return 0; -} diff --git a/src/std/dev/devMbbiSoft.c b/src/std/dev/devMbbiSoft.c deleted file mode 100644 index b0b57144f..000000000 --- a/src/std/dev/devMbbiSoft.c +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Marty Kraimer - * Date: 6-1-90 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "mbbiRecord.h" -#include "epicsExport.h" - -/* Create the dset for devMbbiSoft */ -static long init_record(mbbiRecord *prec); -static long read_mbbi(mbbiRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbi; -} devMbbiSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_mbbi -}; -epicsExportAddress(dset, devMbbiSoft); - -static long init_record(mbbiRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_ENUM, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - mbbiRecord *prec = (mbbiRecord *) pinp->precord; - long status = dbGetLink(pinp, DBR_USHORT, &prec->val, 0, 0); - - if (status) return status; - - prec->udf = FALSE; - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return 2; -} - -static long read_mbbi(mbbiRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - return status; -} diff --git a/src/std/dev/devMbbiSoftCallback.c b/src/std/dev/devMbbiSoftCallback.c deleted file mode 100644 index 3796bcee6..000000000 --- a/src/std/dev/devMbbiSoftCallback.c +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devMbbiSoftCallback.c */ -/* - * Authors: Marty Kraimer & Andrew Johnson - */ - -#include -#include - -#include "alarm.h" -#include "callback.h" -#include "cantProceed.h" -#include "dbCommon.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbChannel.h" -#include "dbNotify.h" -#include "epicsAssert.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "mbbiRecord.h" -#include "epicsExport.h" - - -#define GET_OPTIONS (DBR_STATUS | DBR_TIME) - -typedef struct devPvt { - processNotify pn; - CALLBACK callback; - long options; - int status; - struct { - DBRstatus - DBRtime - epicsEnum16 value; - } buffer; -} devPvt; - - -static void getCallback(processNotify *ppn, notifyGetType type) -{ - mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - long no_elements = 1; - - if (ppn->status == notifyCanceled) { - printf("devMbbiSoftCallback::getCallback notifyCanceled\n"); - return; - } - - assert(type == getFieldType); - pdevPvt->status = dbChannelGetField(ppn->chan, DBR_ENUM, - &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); -} - -static void doneCallback(processNotify *ppn) -{ - mbbiRecord *prec = (mbbiRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); -} - -static long add_record(dbCommon *pcommon) -{ - mbbiRecord *prec = (mbbiRecord *)pcommon; - DBLINK *plink = &prec->inp; - dbChannel *chan; - devPvt *pdevPvt; - processNotify *ppn; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - if (plink->type != PV_LINK) { - long status = S_db_badField; - - recGblRecordError(status, (void *)prec, - "devMbbiSoftCallback (add_record) Illegal INP field"); - return status; - } - - chan = dbChannelCreate(plink->value.pv_link.pvname); - if (!chan) { - long status = S_db_notFound; - - recGblRecordError(status, (void *)prec, - "devMbbiSoftCallback (add_record) linked record not found"); - return status; - } - - pdevPvt = calloc(1, sizeof(*pdevPvt)); - if (!pdevPvt) { - long status = S_db_noMemory; - - recGblRecordError(status, (void *)prec, - "devMbbiSoftCallback (add_record) out of memory, calloc() failed"); - return status; - } - ppn = &pdevPvt->pn; - - plink->type = PN_LINK; - plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - - ppn->usrPvt = prec; - ppn->chan = chan; - ppn->getCallback = getCallback; - ppn->doneCallback = doneCallback; - ppn->requestType = processGetRequest; - - pdevPvt->options = GET_OPTIONS; - - prec->dpvt = pdevPvt; - return 0; -} - -static long del_record(dbCommon *pcommon) { - mbbiRecord *prec = (mbbiRecord *)pcommon; - DBLINK *plink = &prec->inp; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - assert(plink->type == PN_LINK); - - dbNotifyCancel(&pdevPvt->pn); - dbChannelDelete(pdevPvt->pn.chan); - free(pdevPvt); - - plink->type = PV_LINK; - return 0; -} - -static struct dsxt dsxtSoftCallback = { - add_record, del_record -}; - -static long init(int pass) -{ - if (pass == 0) devExtend(&dsxtSoftCallback); - return 0; -} - -static long init_record(mbbiRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBR_ENUM, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long read_mbbi(mbbiRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (!prec->dpvt) - return 2; - - if (!prec->pact) { - dbProcessNotify(&pdevPvt->pn); - prec->pact = TRUE; - return 0; - } - - if (pdevPvt->status) { - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return 2; - } - - prec->val = pdevPvt->buffer.value; - prec->udf = FALSE; - - switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (pdevPvt->buffer.severity < INVALID_ALARM) - break; - /* else fall through */ - case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); - break; - case pvlOptMSS: - recGblSetSevr(prec, pdevPvt->buffer.status, - pdevPvt->buffer.severity); - break; - } - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - prec->time = pdevPvt->buffer.time; - - return 2; -} - -/* Create the dset for devMbbiSoftCallback */ -struct { - dset common; - DEVSUPFUN read_mbbi; -} devMbbiSoftCallback = { - {5, NULL, init, init_record, NULL}, - read_mbbi -}; -epicsExportAddress(dset,devMbbiSoftCallback); diff --git a/src/std/dev/devMbbiSoftRaw.c b/src/std/dev/devMbbiSoftRaw.c deleted file mode 100644 index 3bd6b21da..000000000 --- a/src/std/dev/devMbbiSoftRaw.c +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Marty Kraimer - * Date: 6-1-90 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "mbbiRecord.h" -#include "epicsExport.h" - -/* Create the dset for devMbbiSoftRaw */ -static long init_record(mbbiRecord *prec); -static long read_mbbi(mbbiRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbi; -} devMbbiSoftRaw = { - 5, - NULL, - NULL, - init_record, - NULL, - read_mbbi -}; -epicsExportAddress(dset, devMbbiSoftRaw); - -static long init_record(mbbiRecord *prec) -{ - recGblInitConstantLink(&prec->inp, DBF_ULONG, &prec->rval); - - /* Preserve old functionality*/ - if (prec->nobt == 0) - prec->mask = 0xffffffff; - - prec->mask <<= prec->shft; - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - mbbiRecord *prec = (mbbiRecord *) pinp->precord; - long status = dbGetLink(pinp, DBR_LONG, &prec->rval, 0, 0); - - if (status) return status; - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return status; -} - -static long read_mbbi(mbbiRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - if (!status) - prec->rval &= prec->mask; - - return status; -} diff --git a/src/std/dev/devMbboDirectSoft.c b/src/std/dev/devMbboDirectSoft.c deleted file mode 100644 index 0c0851980..000000000 --- a/src/std/dev/devMbboDirectSoft.c +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devMbboDirectSoft.c */ -/* - * Original Author: Bob Dalesio - * Date: 10-08-93 - */ - -#include - -#include "dbAccess.h" -#include "devSup.h" -#include "mbboDirectRecord.h" -#include "epicsExport.h" - -static long write_mbbo(mbboDirectRecord *prec) -{ - dbPutLink(&prec->out, DBR_USHORT, &prec->val, 1); - return 0; -} - -/* Create the dset for devMbboDirectSoft */ -struct { - dset common; - DEVSUPFUN write; -} devMbboDirectSoft = { - {5, NULL, NULL, NULL, NULL}, - write_mbbo -}; -epicsExportAddress(dset, devMbboDirectSoft); diff --git a/src/std/dev/devMbboDirectSoftCallback.c b/src/std/dev/devMbboDirectSoftCallback.c deleted file mode 100644 index e64c3d41c..000000000 --- a/src/std/dev/devMbboDirectSoftCallback.c +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devMbboDirectSoftCallback.c */ -/* - * Original Author: Marty Kraimer - * Date: 04NOV2003 - */ - -#include - -#include "alarm.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "mbboDirectRecord.h" -#include "epicsExport.h" - -static long write_mbbo(mbboDirectRecord *prec) -{ - struct link *plink = &prec->out; - long status; - - if (prec->pact) - return 0; - - status = dbPutLinkAsync(plink, DBR_USHORT, &prec->val, 1); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, DBR_USHORT, &prec->val, 1); - - return status; -} - -/* Create the dset for devMbboSoft */ -struct { - dset common; - DEVSUPFUN write; -} devMbboDirectSoftCallback = { - {5, NULL, NULL, NULL, NULL}, - write_mbbo -}; -epicsExportAddress(dset, devMbboDirectSoftCallback); diff --git a/src/std/dev/devMbboDirectSoftRaw.c b/src/std/dev/devMbboDirectSoftRaw.c deleted file mode 100644 index c3bbdc898..000000000 --- a/src/std/dev/devMbboDirectSoftRaw.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devMbboDirectSoftRaw.c */ -/* - * Original Author: Janet Anderson - * Date: 10-08-93 - */ - -#include - -#include "dbAccess.h" -#include "epicsTypes.h" -#include "devSup.h" -#include "mbboDirectRecord.h" -#include "epicsExport.h" - -static long init_record(mbboDirectRecord *prec) -{ - if (prec->nobt == 0) - prec->mask = 0xffffffff; - - prec->mask <<= prec->shft; - - return 2; /* Don't convert */ -} - -static long write_mbbo(mbboDirectRecord *prec) -{ - epicsUInt32 data; - - data = prec->rval & prec->mask; - dbPutLink(&prec->out, DBR_ULONG, &data, 1); - return 0; -} - -/* Create the dset for devMbboDirectSoftRaw */ -struct { - dset common; - DEVSUPFUN write; -} devMbboDirectSoftRaw = { - {5, NULL, NULL, init_record, NULL}, - write_mbbo -}; -epicsExportAddress(dset, devMbboDirectSoftRaw); diff --git a/src/std/dev/devMbboSoft.c b/src/std/dev/devMbboSoft.c deleted file mode 100644 index b2fe6b094..000000000 --- a/src/std/dev/devMbboSoft.c +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devMbboSoft.c */ -/* - * Original Author: Bob Dalesio - * Current Author: Marty Kraimer - * Date: 6-1-90 - */ -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "mbboRecord.h" -#include "epicsExport.h" - -/* Create the dset for devMbboSoft */ -static long init_record(mbboRecord *prec); -static long write_mbbo(mbboRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_mbbo; -}devMbboSoft={ - 5, - NULL, - NULL, - init_record, - NULL, - write_mbbo -}; -epicsExportAddress(dset,devMbboSoft); - -static long init_record(mbboRecord *prec) -{ - /*dont convert*/ - return 2; - -} /* end init_record() */ - -static long write_mbbo(mbboRecord *prec) -{ - dbPutLink(&prec->out,DBR_USHORT, &prec->val,1); - return 0; -} diff --git a/src/std/dev/devMbboSoftCallback.c b/src/std/dev/devMbboSoftCallback.c deleted file mode 100644 index fd5fe405a..000000000 --- a/src/std/dev/devMbboSoftCallback.c +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* devMbboSoftCallback.c */ -/* - * Author: Marty Kraimer - * Date: 04NOV2003 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "mbboRecord.h" -#include "epicsExport.h" - -/* Create the dset for devMbboSoftCallback */ -static long write_mbbo(mbboRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_mbbo; -}devMbboSoftCallback={ - 5, - NULL, - NULL, - NULL, - NULL, - write_mbbo -}; -epicsExportAddress(dset,devMbboSoftCallback); - -static long write_mbbo(mbboRecord *prec) -{ - struct link *plink = &prec->out; - long status; - - if (prec->pact) - return 0; - - status = dbPutLinkAsync(plink, DBR_USHORT, &prec->val, 1); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, DBR_USHORT, &prec->val, 1); - - return status; -} - diff --git a/src/std/dev/devMbboSoftRaw.c b/src/std/dev/devMbboSoftRaw.c deleted file mode 100644 index 092b6a8a7..000000000 --- a/src/std/dev/devMbboSoftRaw.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devMbboSoftRaw.c */ -/* - * Original Author: Janet Anderson - * Date: 3-28-92 - */ - -#include - -#include "dbAccess.h" -#include "epicsTypes.h" -#include "devSup.h" -#include "mbboRecord.h" -#include "epicsExport.h" - -static long init_record(mbboRecord *prec) -{ - if (prec->nobt == 0) - prec->mask = 0xffffffff; - - prec->mask <<= prec->shft; - - return 2; /* Don't convert */ -} - -static long write_mbbo(mbboRecord *prec) -{ - epicsUInt32 data; - - data = prec->rval & prec->mask; - dbPutLink(&prec->out, DBR_ULONG, &data, 1); - return 0; -} - -/* Create the dset for devMbboSoftRaw */ -struct { - dset common; - DEVSUPFUN write; -} devMbboSoftRaw = { - {5, NULL, NULL, init_record, NULL}, - write_mbbo -}; -epicsExportAddress(dset, devMbboSoftRaw); diff --git a/src/std/dev/devPrintfSoft.c b/src/std/dev/devPrintfSoft.c deleted file mode 100644 index ca06f04be..000000000 --- a/src/std/dev/devPrintfSoft.c +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Andrew Johnson - * Date: 28 Sept 2012 - */ - -#include "dbAccess.h" -#include "printfRecord.h" -#include "epicsExport.h" - -static long write_string(printfRecord *prec) -{ - return dbPutLinkLS(&prec->out, prec->val, prec->len); -} - -printfdset devPrintfSoft = { - 5, NULL, NULL, NULL, NULL, write_string -}; -epicsExportAddress(dset, devPrintfSoft); - diff --git a/src/std/dev/devPrintfSoftCallback.c b/src/std/dev/devPrintfSoftCallback.c deleted file mode 100644 index e89afd53b..000000000 --- a/src/std/dev/devPrintfSoftCallback.c +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Andrew Johnson - * Date: 28 Sept 2012 - */ - -#include "alarm.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "printfRecord.h" -#include "epicsExport.h" - -static long write_string(printfRecord *prec) -{ - struct link *plink = &prec->out; - int dtyp = dbGetLinkDBFtype(plink); - long len = prec->len; - long status; - - if (prec->pact || dtyp < 0) - return 0; - - if (dtyp != DBR_CHAR && dtyp != DBF_UCHAR) { - dtyp = DBR_STRING; - len = 1; - } - - status = dbPutLinkAsync(plink, dtyp, prec->val, len); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, dtyp, prec->val, len); - - return status; -} - -printfdset devPrintfSoftCallback = { - 5, NULL, NULL, NULL, NULL, write_string -}; -epicsExportAddress(dset, devPrintfSoftCallback); diff --git a/src/std/dev/devSASoft.c b/src/std/dev/devSASoft.c deleted file mode 100644 index 01a076e6d..000000000 --- a/src/std/dev/devSASoft.c +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 Lawrence Berkeley Laboratory,The Control Systems -* Group, Systems Engineering Department -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Carl Lionberger - * Date: 9-2-93 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "devSup.h" -#include "subArrayRecord.h" -#include "epicsExport.h" - -/* Create the dset for devSASoft */ -static long init_record(subArrayRecord *prec); -static long read_sa(subArrayRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_sa; -} devSASoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_sa -}; -epicsExportAddress(dset, devSASoft); - -static void subset(subArrayRecord *prec, long nRequest) -{ - long ecount = nRequest - prec->indx; - - if (ecount > 0) { - int esize = dbValueSize(prec->ftvl); - - if (ecount > prec->nelm) - ecount = prec->nelm; - - memmove(prec->bptr, (char *)prec->bptr + prec->indx * esize, - ecount * esize); - } else - ecount = 0; - - prec->nord = ecount; - prec->udf = FALSE; -} - -static long init_record(subArrayRecord *prec) -{ - long nRequest = prec->indx + prec->nelm; - long status; - - if (nRequest > prec->malm) - nRequest = prec->malm; - - status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &nRequest); - - if (!status && nRequest > 0) - subset(prec, nRequest); - - return status; -} - -struct sart { - long nRequest; - epicsTimeStamp *ptime; -}; - -static long readLocked(struct link *pinp, void *vrt) -{ - subArrayRecord *prec = (subArrayRecord *) pinp->precord; - struct sart *prt = (struct sart *) vrt; - long status = dbGetLink(pinp, prec->ftvl, prec->bptr, 0, &prt->nRequest); - - if (!status && prt->ptime) - dbGetTimeStamp(pinp, prt->ptime); - - return status; -} - -static long read_sa(subArrayRecord *prec) -{ - long status; - struct sart rt; - - rt.nRequest = prec->indx + prec->nelm; - if (rt.nRequest > prec->malm) - rt.nRequest = prec->malm; - - rt.ptime = (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) ? &prec->time : NULL; - - if (dbLinkIsConstant(&prec->inp)) { - status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &rt.nRequest); - if (status == S_db_badField) { /* INP was empty */ - rt.nRequest = prec->nord; - status = 0; - } - } - else { - status = dbLinkDoLocked(&prec->inp, readLocked, &rt); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, &rt); - } - - if (!status && rt.nRequest > 0) - subset(prec, rt.nRequest); - - return status; -} diff --git a/src/std/dev/devSiSoft.c b/src/std/dev/devSiSoft.c deleted file mode 100644 index 5141c1038..000000000 --- a/src/std/dev/devSiSoft.c +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Janet Anderson - * Date: 04-21-91 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "epicsTime.h" -#include "recGbl.h" -#include "devSup.h" -#include "link.h" -#include "stringinRecord.h" -#include "epicsExport.h" - -/* Create the dset for devSiSoft */ -static long init_record(stringinRecord *prec); -static long read_stringin(stringinRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_stringin; -} devSiSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_stringin -}; -epicsExportAddress(dset, devSiSoft); - -static long init_record(stringinRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBF_STRING, prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long readLocked(struct link *pinp, void *dummy) -{ - stringinRecord *prec = (stringinRecord *) pinp->precord; - long status = dbGetLink(pinp, DBR_STRING, prec->val, 0, 0); - - if (status) return status; - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - dbGetTimeStamp(pinp, &prec->time); - - return status; -} - -static long read_stringin(stringinRecord *prec) -{ - long status = dbLinkDoLocked(&prec->inp, readLocked, NULL); - - if (status == S_db_noLSET) - status = readLocked(&prec->inp, NULL); - - if (!status && !dbLinkIsConstant(&prec->inp)) - prec->udf = FALSE; - - return status; -} diff --git a/src/std/dev/devSiSoftCallback.c b/src/std/dev/devSiSoftCallback.c deleted file mode 100644 index 8f679889e..000000000 --- a/src/std/dev/devSiSoftCallback.c +++ /dev/null @@ -1,217 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* devSiSoftCallback.c */ -/* - * Authors: Marty Kraimer & Andrew Johnson - */ - -#include -#include -#include - -#include "alarm.h" -#include "callback.h" -#include "cantProceed.h" -#include "dbCommon.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbChannel.h" -#include "dbNotify.h" -#include "epicsAssert.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "stringinRecord.h" -#include "epicsExport.h" - - -#define GET_OPTIONS (DBR_STATUS | DBR_TIME) - -typedef struct devPvt { - DBADDR dbaddr; - processNotify pn; - CALLBACK callback; - long options; - int status; - struct { - DBRstatus - DBRtime - char value[MAX_STRING_SIZE]; - } buffer; -} devPvt; - - -static void getCallback(processNotify *ppn, notifyGetType type) -{ - stringinRecord *prec = (stringinRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - long no_elements = 1; - - if (ppn->status==notifyCanceled) { - printf("devSiSoftCallback::getCallback notifyCanceled\n"); - return; - } - - assert(type == getFieldType); - pdevPvt->status = dbChannelGetField(ppn->chan, DBR_STRING, - &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0); -} - -static void doneCallback(processNotify *ppn) -{ - stringinRecord *prec = (stringinRecord *)ppn->usrPvt; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec); -} - -static long add_record(dbCommon *pcommon) -{ - stringinRecord *prec = (stringinRecord *)pcommon; - DBLINK *plink = &prec->inp; - dbChannel *chan; - devPvt *pdevPvt; - processNotify *ppn; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - if (plink->type != PV_LINK) { - long status = S_db_badField; - - recGblRecordError(status, (void *)prec, - "devSiSoftCallback (add_record) Illegal INP field"); - return status; - } - - pdevPvt = calloc(1, sizeof(*pdevPvt)); - if (!pdevPvt) { - long status = S_db_noMemory; - - recGblRecordError(status, (void *)prec, - "devSiSoftCallback (add_record) out of memory, calloc() failed"); - return status; - } - ppn = &pdevPvt->pn; - - chan = dbChannelCreate(plink->value.pv_link.pvname); - if (!chan) { - long status = S_db_notFound; - - recGblRecordError(status, (void *)prec, - "devSiSoftCallback (add_record) linked record not found"); - return status; - } - - plink->type = PN_LINK; - plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */ - - ppn->usrPvt = prec; - ppn->chan = chan; - ppn->getCallback = getCallback; - ppn->doneCallback = doneCallback; - ppn->requestType = processGetRequest; - - pdevPvt->options = GET_OPTIONS; - - prec->dpvt = pdevPvt; - return 0; -} - -static long del_record(dbCommon *pcommon) { - stringinRecord *prec = (stringinRecord *)pcommon; - DBLINK *plink = &prec->inp; - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (dbLinkIsDefined(plink) && dbLinkIsConstant(plink)) - return 0; - - assert(plink->type == PN_LINK); - - dbNotifyCancel(&pdevPvt->pn); - dbChannelDelete(pdevPvt->pn.chan); - free(pdevPvt); - - plink->type = PV_LINK; - return 0; -} - -static struct dsxt dsxtSoftCallback = { - add_record, del_record -}; - -static long init(int pass) -{ - if (pass == 0) devExtend(&dsxtSoftCallback); - return 0; -} - -static long init_record(stringinRecord *prec) -{ - if (recGblInitConstantLink(&prec->inp, DBR_STRING, &prec->val)) - prec->udf = FALSE; - - return 0; -} - -static long read_si(stringinRecord *prec) -{ - devPvt *pdevPvt = (devPvt *)prec->dpvt; - - if (!prec->dpvt) - return 0; - - if (!prec->pact) { - dbProcessNotify(&pdevPvt->pn); - prec->pact = TRUE; - return 0; - } - - if (pdevPvt->status) { - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - return pdevPvt->status; - } - - strncpy(prec->val, pdevPvt->buffer.value, MAX_STRING_SIZE); - prec->val[MAX_STRING_SIZE-1] = 0; - prec->udf = FALSE; - - switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) { - case pvlOptNMS: - break; - case pvlOptMSI: - if (pdevPvt->buffer.severity < INVALID_ALARM) - break; - /* else fall through */ - case pvlOptMS: - recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity); - break; - case pvlOptMSS: - recGblSetSevr(prec, pdevPvt->buffer.status, - pdevPvt->buffer.severity); - break; - } - - if (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) - prec->time = pdevPvt->buffer.time; - - return 0; -} - -/* Create the dset for devSiSoftCallback */ -struct { - dset common; - DEVSUPFUN read_li; -} devSiSoftCallback = { - {5, NULL, init, init_record, NULL}, - read_si -}; -epicsExportAddress(dset,devSiSoftCallback); diff --git a/src/std/dev/devSoSoft.c b/src/std/dev/devSoSoft.c deleted file mode 100644 index 6dda4a765..000000000 --- a/src/std/dev/devSoSoft.c +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Janet Anderson - * Date: 21APR1991 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "stringoutRecord.h" -#include "epicsExport.h" - -/* Create the dset for devSoSoft */ -static long write_stringout(stringoutRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_stringout; -} devSoSoft = { - 5, - NULL, - NULL, - NULL, - NULL, - write_stringout -}; -epicsExportAddress(dset, devSoSoft); - -static long write_stringout(stringoutRecord *prec) -{ - long status; - - status = dbPutLink(&prec->out, DBR_STRING, prec->val, 1); - return status; -} diff --git a/src/std/dev/devSoSoftCallback.c b/src/std/dev/devSoSoftCallback.c deleted file mode 100644 index df8c5d819..000000000 --- a/src/std/dev/devSoSoftCallback.c +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Marty Kraimer - * Date: 04NOV2003 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "stringoutRecord.h" -#include "epicsExport.h" - -/* Create the dset for devSoSoftCallback */ -static long write_stringout(stringoutRecord *prec); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_stringout; -} devSoSoftCallback = { - 5, - NULL, - NULL, - NULL, - NULL, - write_stringout -}; -epicsExportAddress(dset, devSoSoftCallback); - -static long write_stringout(stringoutRecord *prec) -{ - struct link *plink = &prec->out; - long status; - - if (prec->pact) - return 0; - - status = dbPutLinkAsync(plink, DBR_STRING, &prec->val, 1); - if (!status) - prec->pact = TRUE; - else if (status == S_db_noLSET) - status = dbPutLink(plink, DBR_STRING, &prec->val, 1); - - return status; -} - diff --git a/src/std/dev/devSoft.dbd b/src/std/dev/devSoft.dbd deleted file mode 100644 index 2d7a64be3..000000000 --- a/src/std/dev/devSoft.dbd +++ /dev/null @@ -1,71 +0,0 @@ -# devSoft.dbd - -device(aai,CONSTANT,devAaiSoft,"Soft Channel") -device(aao,CONSTANT,devAaoSoft,"Soft Channel") -device(ai,CONSTANT,devAiSoft,"Soft Channel") -device(ao,CONSTANT,devAoSoft,"Soft Channel") -device(bi,CONSTANT,devBiSoft,"Soft Channel") -device(bo,CONSTANT,devBoSoft,"Soft Channel") -device(calcout,CONSTANT,devCalcoutSoft,"Soft Channel") -device(event,CONSTANT,devEventSoft,"Soft Channel") -device(histogram,CONSTANT,devHistogramSoft,"Soft Channel") -device(int64in,CONSTANT,devI64inSoft,"Soft Channel") -device(int64out,CONSTANT,devI64outSoft,"Soft Channel") -device(longin,CONSTANT,devLiSoft,"Soft Channel") -device(longout,CONSTANT,devLoSoft,"Soft Channel") -device(lsi,CONSTANT,devLsiSoft,"Soft Channel") -device(lso,CONSTANT,devLsoSoft,"Soft Channel") -device(mbbi,CONSTANT,devMbbiSoft,"Soft Channel") -device(mbbiDirect,CONSTANT,devMbbiDirectSoft,"Soft Channel") -device(mbbo,CONSTANT,devMbboSoft,"Soft Channel") -device(mbboDirect,CONSTANT,devMbboDirectSoft,"Soft Channel") -device(printf,CONSTANT,devPrintfSoft,"Soft Channel") -device(stringin,CONSTANT,devSiSoft,"Soft Channel") -device(stringout,CONSTANT,devSoSoft,"Soft Channel") -device(subArray,CONSTANT,devSASoft,"Soft Channel") -device(waveform,CONSTANT,devWfSoft,"Soft Channel") - -device(ai,CONSTANT,devAiSoftRaw,"Raw Soft Channel") -device(ao,CONSTANT,devAoSoftRaw,"Raw Soft Channel") -device(bi,CONSTANT,devBiSoftRaw,"Raw Soft Channel") -device(bo,CONSTANT,devBoSoftRaw,"Raw Soft Channel") -device(mbbi,CONSTANT,devMbbiSoftRaw,"Raw Soft Channel") -device(mbbiDirect,CONSTANT,devMbbiDirectSoftRaw,"Raw Soft Channel") -device(mbbo,CONSTANT,devMbboSoftRaw,"Raw Soft Channel") -device(mbboDirect,CONSTANT,devMbboDirectSoftRaw,"Raw Soft Channel") - -device(ai,CONSTANT,devAiSoftCallback,"Async Soft Channel") -device(ao,CONSTANT,devAoSoftCallback,"Async Soft Channel") -device(bi,CONSTANT,devBiSoftCallback,"Async Soft Channel") -device(bo,CONSTANT,devBoSoftCallback,"Async Soft Channel") -device(calcout,CONSTANT,devCalcoutSoftCallback,"Async Soft Channel") -device(int64in,CONSTANT,devI64inSoftCallback,"Async Soft Channel") -device(int64out,CONSTANT,devI64outSoftCallback,"Async Soft Channel") -device(longin,CONSTANT,devLiSoftCallback,"Async Soft Channel") -device(longout,CONSTANT,devLoSoftCallback,"Async Soft Channel") -device(lso,CONSTANT,devLsoSoftCallback,"Async Soft Channel") -device(mbbi,CONSTANT,devMbbiSoftCallback,"Async Soft Channel") -device(mbbiDirect,CONSTANT,devMbbiDirectSoftCallback,"Async Soft Channel") -device(mbbo,CONSTANT,devMbboSoftCallback,"Async Soft Channel") -device(mbboDirect,CONSTANT,devMbboDirectSoftCallback,"Async Soft Channel") -device(printf,CONSTANT,devPrintfSoftCallback,"Async Soft Channel") -device(stringin,CONSTANT,devSiSoftCallback,"Async Soft Channel") -device(stringout,CONSTANT,devSoSoftCallback,"Async Soft Channel") - -device(ai, INST_IO,devTimestampAI,"Soft Timestamp") -device(stringin,INST_IO,devTimestampSI,"Soft Timestamp") - -device(ai, INST_IO,devAiGeneralTime,"General Time") -device(bo, INST_IO,devBoGeneralTime,"General Time") -device(longin, INST_IO,devLiGeneralTime,"General Time") -device(stringin,INST_IO,devSiGeneralTime,"General Time") - -device(lso,INST_IO,devLsoStdio,"stdio") -device(printf,INST_IO,devPrintfStdio,"stdio") -device(stringout,INST_IO,devSoStdio,"stdio") - -device(lsi,INST_IO,devLsiEnviron,"getenv") -device(stringin,INST_IO,devSiEnviron,"getenv") - -device(bi, INST_IO, devBiDbState, "Db State") -device(bo, INST_IO, devBoDbState, "Db State") diff --git a/src/std/dev/devStdio.c b/src/std/dev/devStdio.c deleted file mode 100644 index e957bfce0..000000000 --- a/src/std/dev/devStdio.c +++ /dev/null @@ -1,211 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include -#include - -#include "dbCommon.h" -#include "devSup.h" -#include "errlog.h" -#include "recGbl.h" -#include "recSup.h" - -#include "lsoRecord.h" -#include "printfRecord.h" -#include "stringoutRecord.h" -#include "epicsExport.h" - -typedef int (*PRINTFFUNC)(const char *fmt, ...); - -static int stderrPrintf(const char *fmt, ...); -static int logPrintf(const char *fmt, ...); - - -static struct outStream { - const char *name; - PRINTFFUNC print; -} outStreams[] = { - {"stdout", printf}, - {"stderr", stderrPrintf}, - {"errlog", logPrintf}, - {NULL, NULL} -}; - -static int stderrPrintf(const char *fmt, ...) { - va_list pvar; - int retval; - - va_start(pvar, fmt); - retval = vfprintf(stderr, fmt, pvar); - va_end (pvar); - - return retval; -} - -static int logPrintf(const char *fmt, ...) { - va_list pvar; - int retval; - - va_start(pvar, fmt); - retval = errlogVprintf(fmt, pvar); - va_end (pvar); - - return retval; -} - - -/* lso device support */ - -static long add_lso(dbCommon *pcommon) { - lsoRecord *prec = (lsoRecord *) pcommon; - struct outStream *pstream; - - if (prec->out.type != INST_IO) - return S_dev_badOutType; - - for (pstream = outStreams; pstream->name; ++pstream) { - if (strcmp(prec->out.value.instio.string, pstream->name) == 0) { - prec->dpvt = pstream; - return 0; - } - } - prec->dpvt = NULL; - return -1; -} - -static long del_lso(dbCommon *pcommon) { - lsoRecord *prec = (lsoRecord *) pcommon; - - prec->dpvt = NULL; - return 0; -} - -static struct dsxt dsxtLsoStdio = { - add_lso, del_lso -}; - -static long init_lso(int pass) -{ - if (pass == 0) devExtend(&dsxtLsoStdio); - return 0; -} - -static long write_lso(lsoRecord *prec) -{ - struct outStream *pstream = (struct outStream *)prec->dpvt; - if (pstream) - pstream->print("%s\n", prec->val); - return 0; -} - -lsodset devLsoStdio = { - 5, NULL, init_lso, NULL, NULL, write_lso -}; -epicsExportAddress(dset, devLsoStdio); - - -/* printf device support */ - -static long add_printf(dbCommon *pcommon) { - printfRecord *prec = (printfRecord *) pcommon; - struct outStream *pstream; - - if (prec->out.type != INST_IO) - return S_dev_badOutType; - - for (pstream = outStreams; pstream->name; ++pstream) { - if (strcmp(prec->out.value.instio.string, pstream->name) == 0) { - prec->dpvt = pstream; - return 0; - } - } - prec->dpvt = NULL; - return -1; -} - -static long del_printf(dbCommon *pcommon) { - printfRecord *prec = (printfRecord *) pcommon; - - prec->dpvt = NULL; - return 0; -} - -static struct dsxt dsxtPrintfStdio = { - add_printf, del_printf -}; - -static long init_printf(int pass) -{ - if (pass == 0) devExtend(&dsxtPrintfStdio); - return 0; -} - -static long write_printf(printfRecord *prec) -{ - struct outStream *pstream = (struct outStream *)prec->dpvt; - if (pstream) - pstream->print("%s\n", prec->val); - return 0; -} - -printfdset devPrintfStdio = { - 5, NULL, init_printf, NULL, NULL, write_printf -}; -epicsExportAddress(dset, devPrintfStdio); - - -/* stringout device support */ - -static long add_stringout(dbCommon *pcommon) { - stringoutRecord *prec = (stringoutRecord *) pcommon; - struct outStream *pstream; - - if (prec->out.type != INST_IO) - return S_dev_badOutType; - - for (pstream = outStreams; pstream->name; ++pstream) { - if (strcmp(prec->out.value.instio.string, pstream->name) == 0) { - prec->dpvt = pstream; - return 0; - } - } - prec->dpvt = NULL; - return -1; -} - -static long del_stringout(dbCommon *pcommon) { - stringoutRecord *prec = (stringoutRecord *) pcommon; - - prec->dpvt = NULL; - return 0; -} - -static struct dsxt dsxtSoStdio = { - add_stringout, del_stringout -}; - -static long init_stringout(int pass) -{ - if (pass == 0) devExtend(&dsxtSoStdio); - return 0; -} - -static long write_stringout(stringoutRecord *prec) -{ - struct outStream *pstream = (struct outStream *)prec->dpvt; - if (pstream) - pstream->print("%s\n", prec->val); - return 0; -} - -static struct { - dset common; - DEVSUPFUN write; -} devSoStdio = { - {5, NULL, init_stringout, NULL, NULL}, write_stringout -}; -epicsExportAddress(dset, devSoStdio); diff --git a/src/std/dev/devTimestamp.c b/src/std/dev/devTimestamp.c deleted file mode 100644 index 936d7767d..000000000 --- a/src/std/dev/devTimestamp.c +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in the file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Device support for EPICS time stamps - * - * Original Author: Eric Norum - */ - -#include "dbDefs.h" -#include "epicsTime.h" -#include "alarm.h" -#include "devSup.h" -#include "recGbl.h" - -#include "aiRecord.h" -#include "stringinRecord.h" -#include "epicsExport.h" - - -/* Extended device support to allow INP field changes */ - -static long initAllow(int pass) { - if (pass == 0) devExtend(&devSoft_DSXT); - return 0; -} - - -/* ai record */ - -static long read_ai(aiRecord *prec) -{ - recGblGetTimeStamp(prec); - prec->val = prec->time.secPastEpoch + (double)prec->time.nsec * 1e-9; - prec->udf = FALSE; - return 2; -} - -struct { - dset common; - DEVSUPFUN read_write; - DEVSUPFUN special_linconv; -} devTimestampAI = { - {6, NULL, initAllow, NULL, NULL}, read_ai, NULL -}; -epicsExportAddress(dset, devTimestampAI); - - -/* stringin record */ - -static long read_stringin (stringinRecord *prec) -{ - int len; - - recGblGetTimeStamp(prec); - len = epicsTimeToStrftime(prec->val, sizeof prec->val, - prec->inp.value.instio.string, &prec->time); - if (len >= sizeof prec->val) { - prec->udf = TRUE; - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - return -1; - } - prec->udf = FALSE; - return 0; -} - -struct { - dset common; - DEVSUPFUN read_stringin; -} devTimestampSI = { - {5, NULL, initAllow, NULL, NULL}, read_stringin -}; -epicsExportAddress(dset, devTimestampSI); diff --git a/src/std/dev/devWfSoft.c b/src/std/dev/devWfSoft.c deleted file mode 100644 index 8d8295696..000000000 --- a/src/std/dev/devWfSoft.c +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Authors: Bob Dalesio and Marty Kraimer - * Date: 6-1-90 - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "recGbl.h" -#include "devSup.h" -#include "waveformRecord.h" -#include "epicsExport.h" - -/* Create the dset for devWfSoft */ -static long init_record(waveformRecord *prec); -static long read_wf(waveformRecord *prec); - -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_wf; -} devWfSoft = { - 5, - NULL, - NULL, - init_record, - NULL, - read_wf -}; -epicsExportAddress(dset, devWfSoft); - -static long init_record(waveformRecord *prec) -{ - long nelm = prec->nelm; - long status = dbLoadLinkArray(&prec->inp, prec->ftvl, prec->bptr, &nelm); - - if (!status && nelm > 0) { - prec->nord = nelm; - prec->udf = FALSE; - } - else - prec->nord = 0; - return status; -} - -struct wfrt { - long nRequest; - epicsTimeStamp *ptime; -}; - -static long readLocked(struct link *pinp, void *vrt) -{ - waveformRecord *prec = (waveformRecord *) pinp->precord; - struct wfrt *prt = (struct wfrt *) vrt; - long status = dbGetLink(pinp, prec->ftvl, prec->bptr, 0, &prt->nRequest); - - if (!status && prt->ptime) - dbGetTimeStamp(pinp, prt->ptime); - - return status; -} - -static long read_wf(waveformRecord *prec) -{ - long status; - struct wfrt rt; - - rt.nRequest = prec->nelm; - rt.ptime = (dbLinkIsConstant(&prec->tsel) && - prec->tse == epicsTimeEventDeviceTime) ? &prec->time : NULL; - - status = dbLinkDoLocked(&prec->inp, readLocked, &rt); - if (status == S_db_noLSET) - status = readLocked(&prec->inp, &rt); - - if (!status && rt.nRequest > 0) { - prec->nord = rt.nRequest; - prec->udf = FALSE; - } - - return status; -} diff --git a/src/std/dev/softDevIoc.rc b/src/std/dev/softDevIoc.rc deleted file mode 100644 index 7e789bb2e..000000000 --- a/src/std/dev/softDevIoc.rc +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "epicsVersion.h" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - PRODUCTVERSION EPICS_VERSION,EPICS_REVISION,EPICS_MODIFICATION,EPICS_PATCH_LEVEL - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_UNKNOWN - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments","Soft Device Support Library for EPICS\0" - VALUE "CompanyName", "The EPICS collaboration\0" - VALUE "FileDescription", "Soft Device Support Library\0" - VALUE "FileVersion", EPICS_VERSION_STRING "\0" - VALUE "InternalName", "softDevIoc\0" - VALUE "LegalCopyright", "Copyright (C) Univ. of California, Univ. of Chicago\0" - VALUE "OriginalFilename", "softDevIoc.dll\0" - VALUE "ProductName", "Experimental Physics and Industrial Control System (EPICS)\0" - VALUE "ProductVersion", EPICS_VERSION_STRING "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/std/filters/Makefile b/src/std/filters/Makefile deleted file mode 100644 index d4539898f..000000000 --- a/src/std/filters/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/std/Makefile. - -SRC_DIRS += $(STDDIR)/filters - -DBD += filters.dbd - -dbRecStd_SRCS += ts.c -dbRecStd_SRCS += dbnd.c -dbRecStd_SRCS += arr.c -dbRecStd_SRCS += sync.c - -HTMLS += filters.html - diff --git a/src/std/filters/arr.c b/src/std/filters/arr.c deleted file mode 100644 index 0bd73e295..000000000 --- a/src/std/filters/arr.c +++ /dev/null @@ -1,232 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct myStruct { - epicsInt32 start; - epicsInt32 incr; - epicsInt32 end; - void *arrayFreeList; - long no_elements; -} myStruct; - -static void *myStructFreeList; - -static const chfPluginArgDef opts[] = { - chfInt32 (myStruct, start, "s", 0, 1), - chfInt32 (myStruct, incr, "i", 0, 1), - chfInt32 (myStruct, end, "e", 0, 1), - chfPluginArgEnd -}; - -static void * allocPvt(void) -{ - myStruct *my = (myStruct*) freeListCalloc(myStructFreeList); - if (!my) return NULL; - - my->incr = 1; - my->end = -1; - return (void *) my; -} - -static void freePvt(void *pvt) -{ - myStruct *my = (myStruct*) pvt; - - if (my->arrayFreeList) freeListCleanup(my->arrayFreeList); - freeListFree(myStructFreeList, pvt); -} - -static int parse_ok(void *pvt) -{ - myStruct *my = (myStruct*) pvt; - - if (my->incr <= 0) my->incr = 1; - return 0; -} - -static void freeArray(db_field_log *pfl) -{ - if (pfl->type == dbfl_type_ref) { - freeListFree(pfl->u.r.pvt, pfl->u.r.field); - } -} - -static long wrapArrayIndices(long *start, const long increment, long *end, - const long no_elements) -{ - long len = 0; - - if (*start < 0) *start = no_elements + *start; - if (*start < 0) *start = 0; - if (*start > no_elements) *start = no_elements; - - if (*end < 0) *end = no_elements + *end; - if (*end < 0) *end = 0; - if (*end >= no_elements) *end = no_elements - 1; - - if (*end - *start >= 0) len = 1 + (*end - *start) / increment; - return len; -} - -static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) -{ - myStruct *my = (myStruct*) pvt; - struct dbCommon *prec; - rset *prset; - long start = my->start; - long end = my->end; - long nTarget = 0; - long offset = 0; - long nSource = chan->addr.no_elements; - long capacity = nSource; - void *pdst; - - switch (pfl->type) { - case dbfl_type_val: - /* Only filter arrays */ - break; - - case dbfl_type_rec: - /* Extract from record */ - if (chan->addr.special == SPC_DBADDR && - nSource > 1 && - (prset = dbGetRset(&chan->addr)) && - prset->get_array_info) - { - void *pfieldsave = chan->addr.pfield; - prec = dbChannelRecord(chan); - dbScanLock(prec); - prset->get_array_info(&chan->addr, &nSource, &offset); - nTarget = wrapArrayIndices(&start, my->incr, &end, nSource); - pfl->type = dbfl_type_ref; - pfl->stat = prec->stat; - pfl->sevr = prec->sevr; - pfl->time = prec->time; - pfl->field_type = chan->addr.field_type; - pfl->field_size = chan->addr.field_size; - pfl->no_elements = nTarget; - if (nTarget) { - pdst = freeListCalloc(my->arrayFreeList); - if (pdst) { - pfl->u.r.dtor = freeArray; - pfl->u.r.pvt = my->arrayFreeList; - offset = (offset + start) % chan->addr.no_elements; - dbExtractArrayFromRec(&chan->addr, pdst, nTarget, capacity, - offset, my->incr); - pfl->u.r.field = pdst; - } - } - dbScanUnlock(prec); - chan->addr.pfield = pfieldsave; - } - break; - - /* Extract from buffer */ - case dbfl_type_ref: - pdst = NULL; - nSource = pfl->no_elements; - nTarget = wrapArrayIndices(&start, my->incr, &end, nSource); - pfl->no_elements = nTarget; - if (nTarget) { - /* Copy the data out */ - void *psrc = pfl->u.r.field; - - pdst = freeListCalloc(my->arrayFreeList); - if (!pdst) break; - offset = start; - dbExtractArrayFromBuf(psrc, pdst, pfl->field_size, pfl->field_type, - nTarget, nSource, offset, my->incr); - } - if (pfl->u.r.dtor) pfl->u.r.dtor(pfl); - if (nTarget) { - pfl->u.r.dtor = freeArray; - pfl->u.r.pvt = my->arrayFreeList; - pfl->u.r.field = pdst; - } - break; - } - return pfl; -} - -static void channelRegisterPost(dbChannel *chan, void *pvt, - chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - myStruct *my = (myStruct*) pvt; - long start = my->start; - long end = my->end; - long max = 0; - - if (probe->no_elements <= 1) return; /* array data only */ - - max = wrapArrayIndices(&start, my->incr, &end, probe->no_elements); - if (max) { - if (!my->arrayFreeList) - freeListInitPvt(&my->arrayFreeList, max * probe->field_size, 2); - if (!my->arrayFreeList) return; - } - probe->no_elements = my->no_elements = max; - *cb_out = filter; - *arg_out = pvt; -} - -static void channel_report(dbChannel *chan, void *pvt, int level, - const unsigned short indent) -{ - myStruct *my = (myStruct*) pvt; - printf("%*sArray (arr): start=%d, incr=%d, end=%d\n", indent, "", - my->start, my->incr, my->end); -} - -static chfPluginIf pif = { - allocPvt, - freePvt, - - NULL, /* parse_error, */ - parse_ok, - - NULL, /* channel_open, */ - NULL, /* channelRegisterPre, */ - channelRegisterPost, - channel_report, - NULL /* channel_close */ -}; - -static void arrShutdown(void* ignore) -{ - if(myStructFreeList) - freeListCleanup(myStructFreeList); - myStructFreeList = NULL; -} - -static void arrInitialize(void) -{ - if (!myStructFreeList) - freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64); - - chfPluginRegister("arr", &pif, opts); - epicsAtExit(arrShutdown, NULL); -} - -epicsExportRegistrar(arrInitialize); diff --git a/src/std/filters/dbnd.c b/src/std/filters/dbnd.c deleted file mode 100644 index e96c6b652..000000000 --- a/src/std/filters/dbnd.c +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* für Materialien und Energie GmbH. -* Copyright (c) 2014 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct myStruct { - int mode; - double cval; - double hyst; - double last; -} myStruct; - -static void *myStructFreeList; - -static const -chfPluginEnumType modeEnum[] = { {"abs", 0}, {"rel", 1}, {NULL,0} }; - -static const -chfPluginArgDef opts[] = { - chfDouble (myStruct, cval, "d", 0, 1), - chfEnum (myStruct, mode, "m", 0, 1, modeEnum), - chfTagDouble (myStruct, cval, "abs", mode, 0, 0, 1), - chfTagDouble (myStruct, cval, "rel", mode, 1, 0, 1), - chfPluginArgEnd -}; - -static void * allocPvt(void) -{ - return freeListCalloc(myStructFreeList); -} - -static void freePvt(void *pvt) -{ - freeListFree(myStructFreeList, pvt); -} - -static int parse_ok(void *pvt) -{ - myStruct *my = (myStruct*) pvt; - my->hyst = my->cval; - my->last = epicsNAN; - return 0; -} - -static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) { - myStruct *my = (myStruct*) pvt; - long status; - double val; - unsigned send = 1; - - /* - * Only scalar values supported - strings, arrays, and conversion errors - * are just passed on - */ - if (pfl->type == dbfl_type_val) { - DBADDR localAddr = chan->addr; /* Structure copy */ - localAddr.field_type = pfl->field_type; - localAddr.field_size = pfl->field_size; - localAddr.no_elements = pfl->no_elements; - localAddr.pfield = (char *) &pfl->u.v.field; - status = dbFastGetConvertRoutine[pfl->field_type][DBR_DOUBLE] - (localAddr.pfield, (void*) &val, &localAddr); - if (!status) { - send = 0; - recGblCheckDeadband(&my->last, val, my->hyst, &send, 1); - if (send && my->mode == 1) { - my->hyst = val * my->cval/100.; - } - } - } - if (!send) { - db_delete_field_log(pfl); - return NULL; - } else return pfl; -} - -static void channelRegisterPre(dbChannel *chan, void *pvt, - chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - *cb_out = filter; - *arg_out = pvt; -} - -static void channel_report(dbChannel *chan, void *pvt, int level, const unsigned short indent) -{ - myStruct *my = (myStruct*) pvt; - printf("%*sDeadband (dbnd): mode=%s, delta=%g%s\n", indent, "", - chfPluginEnumString(modeEnum, my->mode, "n/a"), my->cval, - my->mode == 1 ? "%" : ""); -} - -static chfPluginIf pif = { - allocPvt, - freePvt, - - NULL, /* parse_error, */ - parse_ok, - - NULL, /* channel_open, */ - channelRegisterPre, - NULL, /* channelRegisterPost, */ - channel_report, - NULL /* channel_close */ -}; - -static void dbndShutdown(void* ignore) -{ - if(myStructFreeList) - freeListCleanup(myStructFreeList); - myStructFreeList = NULL; -} - -static void dbndInitialize(void) -{ - if (!myStructFreeList) - freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64); - - chfPluginRegister("dbnd", &pif, opts); - epicsAtExit(dbndShutdown, NULL); -} - -epicsExportRegistrar(dbndInitialize); diff --git a/src/std/filters/filters.dbd.pod b/src/std/filters/filters.dbd.pod deleted file mode 100644 index db97907a5..000000000 --- a/src/std/filters/filters.dbd.pod +++ /dev/null @@ -1,247 +0,0 @@ -=head1 Channel Filters - -Channel Filters can be applied to Channel Access channels by a client, using -a JSON Field Modifier to select the filter and any parameters. -The following filters are available in this release: - -=over - -=item * L - -=item * L - -=item * L - -=item * L - -=back - -=head2 Using Filters - -Channel filters can be added to any Channel Access channel name. -There can be more than one filter applied to the same channel, in which case the -order that they are specified will control the order in which they are applied -to the resulting data-stream. -The filter specification must appear after the field name, or if the default -(VAL) field is used after a dot C<.> appended to the record name. -With the exception of the array short-hand which is described below, all filters -must appear inside a pair of braces C< {} > after the dot expressed as a JSON -(L) object, which allows filter -parameters to be included as needed. - -Each filter is given as a name/value pair. The filter name (given in parentheses -in the titles below) is a string, and must be enclosed inside double-quotes C<"> -characters as per the JSON specification. -Parameters to that filter are provided as the value part of the name/value pair, -and will normally appear as a child JSON object consisting of name/value pairs -inside a nested pair of braces C< {} >. - -=head4 Example Filter - -Given a record called C the following would apply a filter C to -the VAL field of that record, giving the filter two numeric parameters named -C and C: - - test:channel.{"f":{"lo":0,"hi":10}} - -Note that due to the required presence of the double-quote characters in the -JSON strings in the name string, it will usually be necessary to enclose a -filtered name within single-quotes C<< ' ... ' >> when typing it as an -argument to a Unix shell command. - -=head2 Filter Reference - -=cut - -registrar(tsInitialize) - -=head3 TimeStamp Filter C<"ts"> - -This filter is used to set the timestamp of the value fetched through -the channel to the time the value was fetched (or an update was sent), -rather than the time the record last -processed which could have been days or even weeks ago for some records, or set -to the EPICS epoch if the record has never processed. - -=head4 Parameters - -None, use an empty pair of braces. - -=head4 Example - - Hal$ caget -a 'test:channel.{"ts":{}}' - test:channel.{"ts":{}} 2012-08-28 22:10:31.192547 0 UDF INVALID - Hal$ caget -a 'test:channel' - test:channel 0 UDF INVALID - -=cut - -registrar(dbndInitialize) - -=head3 Deadband Filter C<"dbnd"> - -This filter implements a channel-specific monitor deadband, which is applied -after any deadbands implemented by the record itself (it can only drop updates -that the unfiltered channel generates, never add additional updates). - -The deadband can be specified as an absolute value change, or as a relative -percentage. - -=head4 Parameters - -=over - -=item Mode+Deadband C<"abs">/C<"rel"> (shorthand) - -Mode and deadband can be specified in one definition (shorthand). -The desired mode is given as parameter name (C<"abs"> or C<"rel">), with the -numeric size of the deadband (absolute value or numeric percentage) as value. - -=item Deadband C<"d"> - -The size of the deadband to use. -Relative deadband values are given as a numeric percentage, but without any -trailing percent character. - -=item Mode C<"m"> (optional) - -A string (enclosed in double-quotes C<">), which should contain either -C or C. -The default mode is C if no mode parameter is included. - -=back - -=head4 Example - - Hal$ camonitor 'test:channel' - test:channel 2012-09-01 22:10:19.600595 1 LOLO MAJOR - test:channel 2012-09-01 22:10:20.600661 2 LOLO MAJOR - test:channel 2012-09-01 22:10:21.600819 3 LOW MINOR - test:channel 2012-09-01 22:10:22.600905 4 LOW MINOR - test:channel 2012-09-01 22:10:23.601023 5 - test:channel 2012-09-01 22:10:24.601136 6 HIGH MINOR - ^C - Hal$ camonitor 'test:channel.{"dbnd":{"abs":1.5}}' - test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:49.613341 1 LOLO MAJOR - test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:51.613615 3 LOW MINOR - test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:53.613804 5 - test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:55.614074 7 HIGH MINOR - test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:57.614305 9 HIHI MAJOR - ^C - -=cut - -registrar(arrInitialize) - -=head3 Array Filter C<"arr"> - -This filter is used to retrieve parts of an array (subarrays and strided -subarrays). - -=head4 Parameters - -Note: Negative index numbers address from the end of the array, with C<-1> being the last element. - -=over - -=item Square bracket notation C<[start:increment:end]> (shorthand) - -The common square bracket notation with can be used in place of JSON. -Any parameter may be omitted (keeping the colons) to use the default value. -If only one colon is included, this means C<[start:end]> with a increment of 1. -If only a single parameter is used C<[index]> the filter returns one element. - -=item Start index C<"s"> - -Index of the first original array element to retrieve. - -=item Increment C<"i"> - -Index increment between retrieved elements of the original array; must be -a positive number. - -=item End index C<"e"> - -Index of the last original array element to retrieve. - -=back - -Defaults (when parameters are omitted) are: -C (first element), C (fetch all elements), C -(last element) - -=head4 Example - - Hal$ caget test:channel 'test:channel.{"arr":{"s":2,"i":2,"e":8}}' test:channel.[3:5] test:channel.[3:2:-3] - test:channel 10 0 1 2 3 4 5 6 7 8 9 - test:channel.{"arr":{"s":2,"i":2,"e":8}} 4 2 4 6 8 - test:channel.[3:5] 3 3 4 5 - test:channel.[3:2:-3] 3 3 5 7 - -=cut - -registrar(syncInitialize) - -=head3 Synchronize Filter C<"sync"> - -This filter is used to dynamically enable or disable monitors according -to a condition and a state variable declared by the IOC. - -State variables have a boolean value and can be set by a binary output -record, an iocsh command or by other software running in the IOC calling -C. - -=head4 Parameters - -=over - -=item Mode+State - -Mode and state can be specified in one definition (shorthand). -The desired mode is given as parameter name (C<"before"> / C<"first"> / -C<"while"> / C<"last"> / C<"after"> / C<"unless">), with the state name -(enclosed in double quotes C<">) as value. - -=item Mode C<"m"> - -A single word from the list below, enclosed in double quotes C<">. -This controls how the state value should affect the monitor stream. - -=over - -=item C<"before"> E only the last value received before the state -changes from false to true is forwarded to the client. - -=item C<"first"> E only the first value received after the state -changes from true to false is forwarded to the client. - -=item C<"while"> E values are forwarded to the client as long as -the state is true. - -=item C<"last"> E only the last value received before the state -changes from true to false is forwarded to the client. - -=item C<"after"> E only the first value received after the state -changes from true to false is forwarded to the client. - -=item C<"unless"> E values are forwarded to the client as long -as the state is false. - -=back - -=item State C<"s"> - -The name of a state variable, enclosed in double quotes C<">. - -=back - -=head4 Example - -Assuming there is a system state called "blue", that is being controlled by -some other facility such as a timing system, updates could be restricted to -periods only when "blue" is true by using - - Hal$ camonitor 'test:channel' 'test:channel.{"while":"blue"}' - ... - -=cut diff --git a/src/std/filters/sync.c b/src/std/filters/sync.c deleted file mode 100644 index d137dd7a9..000000000 --- a/src/std/filters/sync.c +++ /dev/null @@ -1,194 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include "freeList.h" -#include "db_field_log.h" -#include "chfPlugin.h" -#include "dbState.h" -#include "epicsExit.h" -#include "epicsAssert.h" -#include "epicsExport.h" - -#define STATE_NAME_LENGTH 20 - -typedef enum syncMode { - syncModeBefore=0, - syncModeFirst=1, - syncModeLast=2, - syncModeAfter=3, - syncModeWhile=4, - syncModeUnless=5 -} syncMode; - -static const -chfPluginEnumType modeEnum[] = { - {"before", syncModeBefore}, - {"first", syncModeFirst}, - {"last", syncModeLast}, - {"after", syncModeAfter}, - {"while", syncModeWhile}, - {"unless", syncModeUnless}, - {NULL, 0} -}; - -typedef struct myStruct { - syncMode mode; - char state[STATE_NAME_LENGTH]; - dbStateId id; - db_field_log *lastfl; - int laststate:1; -} myStruct; - -static void *myStructFreeList; - -static const -chfPluginArgDef opts[] = { - chfEnum (myStruct, mode, "m", 1, 1, modeEnum), - chfString (myStruct, state, "s", 1, 0), - chfTagString (myStruct, state, "before", mode, 0, 1, 0), - chfTagString (myStruct, state, "first", mode, 1, 1, 0), - chfTagString (myStruct, state, "last", mode, 2, 1, 0), - chfTagString (myStruct, state, "after", mode, 3, 1, 0), - chfTagString (myStruct, state, "while", mode, 4, 1, 0), - chfTagString (myStruct, state, "unless", mode, 5, 1, 0), - chfPluginArgEnd -}; - -static void * allocPvt(void) -{ - myStruct *my = (myStruct*) freeListCalloc(myStructFreeList); - return (void *) my; -} - -static void freePvt(void *pvt) -{ - myStruct *my = (myStruct*) pvt; - db_delete_field_log(my->lastfl); - freeListFree(myStructFreeList, pvt); -} - -static int parse_ok(void *pvt) -{ - myStruct *my = (myStruct*) pvt; - - if (!(my->id = dbStateFind(my->state))) - return -1; - - return 0; -} - -static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) { - db_field_log *passfl = NULL; - myStruct *my = (myStruct*) pvt; - int actstate; - - if (pfl->ctx == dbfl_context_read) - return pfl; - - actstate = dbStateGet(my->id); - - switch (my->mode) { - case syncModeBefore: - if (actstate && !my->laststate) { - passfl = my->lastfl; - my->lastfl = NULL; - } - break; - case syncModeFirst: - if (actstate && !my->laststate) { - passfl = pfl; - pfl = NULL; - } - break; - case syncModeLast: - if (!actstate && my->laststate) { - passfl = my->lastfl; - my->lastfl = NULL; - } - break; - case syncModeAfter: - if (!actstate && my->laststate) { - passfl = pfl; - pfl = NULL; - } - break; - case syncModeWhile: - if (actstate) { - passfl = pfl; - } - goto no_shift; - case syncModeUnless: - if (!actstate) { - passfl = pfl; - } - goto no_shift; - } - - if (my->lastfl) - db_delete_field_log(my->lastfl); - my->lastfl = pfl; - my->laststate = actstate; - - /* since no copy is made we can't keep a reference to the returned fl */ - assert(my->lastfl != passfl); - - no_shift: - return passfl; -} - -static void channelRegisterPre(dbChannel *chan, void *pvt, - chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - *cb_out = filter; - *arg_out = pvt; -} - -static void channel_report(dbChannel *chan, void *pvt, int level, const unsigned short indent) -{ - myStruct *my = (myStruct*) pvt; - printf("%*sSynchronize (sync): mode=%s, state=%s\n", indent, "", - chfPluginEnumString(modeEnum, my->mode, "n/a"), my->state); -} - -static chfPluginIf pif = { - allocPvt, - freePvt, - - NULL, /* parse_error, */ - parse_ok, - - NULL, /* channel_open, */ - channelRegisterPre, - NULL, /* channelRegisterPost, */ - channel_report, - NULL /* channel_close */ -}; - -static void syncShutdown(void* ignore) -{ - if(myStructFreeList) - freeListCleanup(myStructFreeList); - myStructFreeList = NULL; -} - -static void syncInitialize(void) -{ - if (!myStructFreeList) - freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64); - - chfPluginRegister("sync", &pif, opts); - epicsAtExit(syncShutdown, NULL); -} - -epicsExportRegistrar(syncInitialize); diff --git a/src/std/filters/test/Makefile b/src/std/filters/test/Makefile deleted file mode 100644 index 5c17d7fe6..000000000 --- a/src/std/filters/test/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -TESTLIBRARY = Recs - -Recs_SRCS += xRecord.c -Recs_SRCS += arrRecord.c -Recs_LIBS += dbCore Com - -PROD_LIBS = Recs dbRecStd dbCore ca Com - -DBDDEPENDS_FILES += filterTest.dbd$(DEP) -TARGETS += $(COMMON_DIR)/filterTest.dbd -filterTest_DBD += menuGlobal.dbd -filterTest_DBD += menuConvert.dbd -filterTest_DBD += menuScan.dbd -filterTest_DBD += filters.dbd -filterTest_DBD += xRecord.dbd -filterTest_DBD += arrRecord.dbd -TESTFILES += $(COMMON_DIR)/filterTest.dbd - -testHarness_SRCS += filterTest_registerRecordDeviceDriver.cpp - -TESTPROD_HOST += tsTest -tsTest_SRCS += tsTest.c -tsTest_SRCS += filterTest_registerRecordDeviceDriver.cpp -testHarness_SRCS += tsTest.c -TESTFILES += ../xRecord.db -TESTS += tsTest - -TESTPROD_HOST += dbndTest -dbndTest_SRCS += dbndTest.c -dbndTest_SRCS += filterTest_registerRecordDeviceDriver.cpp -testHarness_SRCS += dbndTest.c -TESTS += dbndTest - -TESTPROD_HOST += arrTest -arrTest_SRCS += arrTest.cpp -arrTest_SRCS += filterTest_registerRecordDeviceDriver.cpp -testHarness_SRCS += arrTest.cpp -TESTFILES += ../arrTest.db -TESTS += arrTest - -TESTPROD_HOST += syncTest -syncTest_SRCS += syncTest.c -syncTest_SRCS += filterTest_registerRecordDeviceDriver.cpp -testHarness_SRCS += syncTest.c -TESTS += syncTest - -# epicsRunFilterTests runs all the test programs in a known working order. -testHarness_SRCS += epicsRunFilterTests.c - -filterTestHarness_SRCS += $(testHarness_SRCS) -filterTestHarness_SRCS_RTEMS += rtemsTestHarness.c - -PROD_vxWorks = filterTestHarness -PROD_RTEMS = filterTestHarness - -TESTSPEC_vxWorks = filterTestHarness.munch; epicsRunFilterTests -TESTSPEC_RTEMS = filterTestHarness.boot; epicsRunFilterTests - -TESTSCRIPTS_HOST += $(TESTS:%=%.t) - -include $(TOP)/configure/RULES - -xRecord$(DEP): $(COMMON_DIR)/xRecord.h -tsTest$(DEP): $(COMMON_DIR)/xRecord.h -dbndTest$(DEP): $(COMMON_DIR)/xRecord.h -syncTest$(DEP): $(COMMON_DIR)/xRecord.h -arrRecord$(DEP): $(COMMON_DIR)/arrRecord.h -arrTest$(DEP): $(COMMON_DIR)/arrRecord.h diff --git a/src/std/filters/test/arrRecord.c b/src/std/filters/test/arrRecord.c deleted file mode 100644 index 8f1881f02..000000000 --- a/src/std/filters/test/arrRecord.c +++ /dev/null @@ -1,145 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* arrRecord.c - minimal array record for test purposes: no processing */ - -/* - * Author: Ralph Lange - * - * vaguely implemented like parts of recWaveform.c by Bob Dalesio - * - */ - -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "recSup.h" -#include "recGbl.h" -#include "cantProceed.h" -#define GEN_SIZE_OFFSET -#include "arrRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -static long get_array_info(DBADDR *, long *, long *); -static long put_array_info(DBADDR *, long); -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset arrRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, arrRSET); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct arrRecord *prec = (struct arrRecord *)pcommon; - - if (pass == 0) { - if (prec->nelm <= 0) - prec->nelm = 1; - if (prec->ftvl > DBF_ENUM) - prec->ftvl = DBF_UCHAR; - prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), - "arr calloc failed"); - - if (prec->nelm == 1) { - prec->nord = 1; - } else { - prec->nord = 0; - } - return 0; - } - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct arrRecord *prec = (struct arrRecord *)pcommon; - - if(prec->clbk) - (*prec->clbk)(prec); - prec->pact = TRUE; - recGblGetTimeStamp(prec); - recGblFwdLink(prec); - prec->pact = FALSE; - return 0; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - arrRecord *prec = (arrRecord *) paddr->precord; - - paddr->pfield = prec->bptr; - paddr->no_elements = prec->nelm; - paddr->field_type = prec->ftvl; - paddr->field_size = dbValueSize(prec->ftvl); - paddr->dbr_field_type = prec->ftvl; - - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - arrRecord *prec = (arrRecord *) paddr->precord; - - *no_elements = prec->nord; - *offset = prec->off; - - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - arrRecord *prec = (arrRecord *) paddr->precord; - - prec->nord = nNew; - if (prec->nord > prec->nelm) - prec->nord = prec->nelm; - - return 0; -} diff --git a/src/std/filters/test/arrRecord.dbd b/src/std/filters/test/arrRecord.dbd deleted file mode 100644 index b504be1cb..000000000 --- a/src/std/filters/test/arrRecord.dbd +++ /dev/null @@ -1,42 +0,0 @@ -include "menuGlobal.dbd" -include "menuConvert.dbd" -include "menuScan.dbd" -recordtype(arr) { - include "dbCommon.dbd" - field(VAL, DBF_NOACCESS) { - prompt("Value") - special(SPC_DBADDR) - pp(TRUE) - extra("void *val") - } - field(NELM, DBF_ULONG) { - prompt("Number of Elements") - special(SPC_NOMOD) - initial("1") - } - field(FTVL, DBF_MENU) { - prompt("Field Type of Value") - special(SPC_NOMOD) - menu(menuFtype) - } - field(NORD, DBF_ULONG) { - prompt("Number elements read") - special(SPC_NOMOD) - } - field(OFF, DBF_ULONG) { - prompt("Offset into array") - } - field(BPTR, DBF_NOACCESS) { - prompt("Buffer Pointer") - special(SPC_NOMOD) - extra("void *bptr") - } - field(INP, DBF_INLINK) { - prompt("Input Link") - } - field(CLBK, DBF_NOACCESS) { - prompt("Processing callback") - special(SPC_NOMOD) - extra("void (*clbk)(struct arrRecord*)") - } -} diff --git a/src/std/filters/test/arrTest.cpp b/src/std/filters/test/arrTest.cpp deleted file mode 100644 index 1ec16b32f..000000000 --- a/src/std/filters/test/arrTest.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2003 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to the Software License Agreement -* found in the file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -/* using stuff from softIoc.cpp by Andrew Johnson */ - -#include -#include -#include -#include -#include - -#include "registryFunction.h" -#include "epicsThread.h" -#include "epicsExit.h" -#include "epicsStdio.h" -#include "envDefs.h" -#include "dbStaticLib.h" -#include "dbmf.h" -#include "errlog.h" -#include "registry.h" -#include "dbAddr.h" -#include "dbAccess.h" -#include "asDbLib.h" -#include "iocInit.h" -#include "iocsh.h" -#include "dbChannel.h" -#include "epicsUnitTest.h" -#include "dbUnitTest.h" -#include "testMain.h" -#include "osiFileName.h" - -#include "arrRecord.h" - -extern "C" { - void filterTest_registerRecordDeviceDriver(struct dbBase *); -} - -#define CA_SERVER_PORT "65535" - -#define PATTERN 0x55 - -const char *server_port = CA_SERVER_PORT; - -static int fl_equals_array(short type, const db_field_log *pfl1, void *p2) { - for (int i = 0; i < pfl1->no_elements; i++) { - switch (type) { - case DBR_DOUBLE: - if (((epicsFloat64*)pfl1->u.r.field)[i] != ((epicsInt32*)p2)[i]) { - testDiag("at index=%d: field log has %g, should be %d", - i, ((epicsFloat64*)pfl1->u.r.field)[i], ((epicsInt32*)p2)[i]); - return 0; - } - break; - case DBR_LONG: - if (((epicsInt32*)pfl1->u.r.field)[i] != ((epicsInt32*)p2)[i]) { - testDiag("at index=%d: field log has %d, should be %d", - i, ((epicsInt32*)pfl1->u.r.field)[i], ((epicsInt32*)p2)[i]); - return 0; - } - break; - case DBR_STRING: - if (strtol(&((const char*)pfl1->u.r.field)[i*MAX_STRING_SIZE], NULL, 0) != ((epicsInt32*)p2)[i]) { - testDiag("at index=%d: field log has '%s', should be '%d'", - i, &((const char*)pfl1->u.r.field)[i*MAX_STRING_SIZE], ((epicsInt32*)p2)[i]); - return 0; - } - break; - default: - return 0; - } - } - return 1; -} - -static void createAndOpen(const char *chan, const char *json, const char *type, dbChannel**pch, short no) { - ELLNODE *node; - char name[80]; - - strncpy(name, chan, sizeof(name)-1); - strncat(name, json, sizeof(name)-strlen(name)-1); - - testOk(!!(*pch = dbChannelCreate(name)), "dbChannel with plugin arr %s created", type); - testOk((ellCount(&(*pch)->filters) == no), "channel has %d filter(s) in filter list", no); - - testOk(!(dbChannelOpen(*pch)), "dbChannel with plugin arr opened"); - - node = ellFirst(&(*pch)->pre_chain); - (void) CONTAINER(node, chFilter, pre_node); - testOk((ellCount(&(*pch)->pre_chain) == 0), "arr has no filter in pre chain"); - - node = ellFirst(&(*pch)->post_chain); - (void) CONTAINER(node, chFilter, post_node); - testOk((ellCount(&(*pch)->post_chain) == no), - "arr has %d filter(s) in post chain", no); -} - -static void testHead (const char *title, const char *typ = "") { - const char *line = "------------------------------------------------------------------------------"; - testDiag("%s", line); - testDiag(title, typ); - testDiag("%s", line); -} - -#define TEST1(Size, Offset, Incr, Text) \ - testDiag("Offset: %d (%s)", Offset, Text); \ - off = Offset; \ - (void) dbPutField(&offaddr, DBR_LONG, &off, 1); \ - pfl = db_create_read_log(pch); \ - testOk(pfl->type == dbfl_type_rec, "original field log has type rec"); \ - pfl2 = dbChannelRunPostChain(pch, pfl); \ - testOk(pfl2 == pfl, "call does not drop or replace field_log"); \ - testOk(pfl->type == dbfl_type_ref, "filtered field log has type ref"); \ - testOk(fl_equals_array(dbr_type, pfl2, ar##Size##_##Offset##_##Incr), "array data correct"); \ - db_delete_field_log(pfl); - -static void check(short dbr_type) { - dbChannel *pch; - db_field_log *pfl, *pfl2; - dbAddr valaddr; - dbAddr offaddr; - const char *offname = NULL, *valname = NULL, *typname = NULL; - epicsInt32 ar[10] = {10,11,12,13,14,15,16,17,18,19}; - epicsInt32 *ar10_0_1 = ar; - epicsInt32 ar10_4_1[10] = {14,15,16,17,18,19,10,11,12,13}; - epicsInt32 ar5_0_1[10] = {12,13,14,15,16}; - epicsInt32 ar5_3_1[10] = {15,16,17,18,19}; - epicsInt32 ar5_5_1[10] = {17,18,19,10,11}; - epicsInt32 ar5_9_1[10] = {11,12,13,14,15}; - epicsInt32 ar5_0_2[10] = {12,14,16}; - epicsInt32 ar5_3_2[10] = {15,17,19}; - epicsInt32 ar5_5_2[10] = {17,19,11}; - epicsInt32 ar5_9_2[10] = {11,13,15}; - epicsInt32 ar5_0_3[10] = {12,15}; - epicsInt32 ar5_3_3[10] = {15,18}; - epicsInt32 ar5_5_3[10] = {17,10}; - epicsInt32 ar5_9_3[10] = {11,14}; - epicsInt32 off = 0; - - switch (dbr_type) { - case DBR_LONG: - offname = "x.OFF"; - valname = "x.VAL"; - typname = "long"; - break; - case DBR_DOUBLE: - offname = "y.OFF"; - valname = "y.VAL"; - typname = "double"; - break; - case DBR_STRING: - offname = "z.OFF"; - valname = "z.VAL"; - typname = "string"; - break; - default: - testDiag("Invalid data type %d", dbr_type); - } - - (void) dbNameToAddr(offname, &offaddr); - - (void) dbNameToAddr(valname, &valaddr); - (void) dbPutField(&valaddr, DBR_LONG, ar, 10); - - /* Default: should not change anything */ - - testHead("Ten %s elements from rec, increment 1, full size (default)", typname); - createAndOpen(valname, "{\"arr\":{}}", "(default)", &pch, 1); - testOk(pch->final_type == valaddr.field_type, - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); - testOk(pch->final_no_elements == valaddr.no_elements, - "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); - TEST1(10, 0, 1, "no offset"); - TEST1(10, 4, 1, "wrapped"); - dbChannelDelete(pch); - - testHead("Ten %s elements from rec, increment 1, out-of-bound start parameter", typname); - createAndOpen(valname, "{\"arr\":{\"s\":-500}}", "out-of-bound start", &pch, 1); - testOk(pch->final_type == valaddr.field_type, - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); - testOk(pch->final_no_elements == valaddr.no_elements, - "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); - TEST1(10, 4, 1, "wrapped"); - dbChannelDelete(pch); - - testHead("Ten %s elements from rec, increment 1, out-of-bound end parameter", typname); - createAndOpen(valname, "{\"arr\":{\"e\":500}}", "out-of-bound end", &pch, 1); - testOk(pch->final_type == valaddr.field_type, - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); - testOk(pch->final_no_elements == valaddr.no_elements, - "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); - TEST1(10, 4, 1, "wrapped"); - dbChannelDelete(pch); - - testHead("Ten %s elements from rec, increment 1, zero increment parameter", typname); - createAndOpen(valname, "{\"arr\":{\"i\":0}}", "zero increment", &pch, 1); - testOk(pch->final_type == valaddr.field_type, - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); - testOk(pch->final_no_elements == valaddr.no_elements, - "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); - TEST1(10, 4, 1, "wrapped"); - dbChannelDelete(pch); - - testHead("Ten %s elements from rec, increment 1, invalid increment parameter", typname); - createAndOpen(valname, "{\"arr\":{\"i\":-30}}", "invalid increment", &pch, 1); - testOk(pch->final_type == valaddr.field_type, - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); - testOk(pch->final_no_elements == valaddr.no_elements, - "final no_elements unchanged (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); - TEST1(10, 4, 1, "wrapped"); - dbChannelDelete(pch); - -#define TEST5(Incr, Left, Right, Type) \ - testHead("Five %s elements from rec, increment " #Incr ", " Type " addressing", typname); \ - createAndOpen(valname, "{\"arr\":{\"s\":" #Left ",\"e\":" #Right ",\"i\":" #Incr "}}", \ - "(" #Left ":" #Incr ":" #Right ")", &pch, 1); \ - testOk(pch->final_type == valaddr.field_type, \ - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); \ - testOk(pch->final_no_elements == 4 / Incr + 1, \ - "final no_elements correct (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); \ - TEST1(5, 0, Incr, "no offset"); \ - TEST1(5, 3, Incr, "from upper block"); \ - TEST1(5, 5, Incr, "wrapped"); \ - TEST1(5, 9, Incr, "from lower block"); \ - dbChannelDelete(pch); - - /* Contiguous block of 5 */ - - TEST5(1, 2, 6, "regular"); - TEST5(1, -8, 6, "left side from-end"); - TEST5(1, 2, -4, "right side from-end"); - TEST5(1, -8, -4, "both sides from-end"); - - /* 5 elements with increment 2 */ - - TEST5(2, 2, 6, "regular"); - TEST5(2, -8, 6, "left side from-end"); - TEST5(2, 2, -4, "right side from-end"); - TEST5(2, -8, -4, "both sides from-end"); - - /* 5 elements with increment 3 */ - - TEST5(3, 2, 6, "regular"); - TEST5(3, -8, 6, "left side from-end"); - TEST5(3, 2, -4, "right side from-end"); - TEST5(3, -8, -4, "both sides from-end"); - - /* From buffer (plugin chain) */ - -#define TEST5B(Incr, Left, Right, Type) \ - testHead("Five %s elements from buffer, increment " #Incr ", " Type " addressing", typname); \ - createAndOpen(valname, "{\"arr\":{},\"arr\":{\"s\":" #Left ",\"e\":" #Right ",\"i\":" #Incr "}}", \ - "(" #Left ":" #Incr ":" #Right ")", &pch, 2); \ - testOk(pch->final_type == valaddr.field_type, \ - "final type unchanged (%d->%d)", valaddr.field_type, pch->final_type); \ - testOk(pch->final_no_elements == 4 / Incr + 1, \ - "final no_elements correct (%ld->%ld)", valaddr.no_elements, pch->final_no_elements); \ - TEST1(5, 0, Incr, "no offset"); \ - dbChannelDelete(pch); - - /* Contiguous block of 5 */ - - TEST5B(1, 2, 6, "regular"); - TEST5B(1, -8, 6, "left side from-end"); - TEST5B(1, 2, -4, "right side from-end"); - TEST5B(1, -8, -4, "both sides from-end"); - - /* 5 elements with increment 2 */ - - TEST5B(2, 2, 6, "regular"); - TEST5B(2, -8, 6, "left side from-end"); - TEST5B(2, 2, -4, "right side from-end"); - TEST5B(2, -8, -4, "both sides from-end"); - - /* 5 elements with increment 3 */ - - TEST5B(3, 2, 6, "regular"); - TEST5B(3, -8, 6, "left side from-end"); - TEST5B(3, 2, -4, "right side from-end"); - TEST5B(3, -8, -4, "both sides from-end"); -} - -MAIN(arrTest) -{ - dbEventCtx evtctx; - const chFilterPlugin *plug; - char arr[] = "arr"; - - testPlan(1402); - - /* Prepare the IOC */ - - epicsEnvSet("EPICS_CA_SERVER_PORT", server_port); - - testdbPrepare(); - - testdbReadDatabase("filterTest.dbd", NULL, NULL); - - filterTest_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("arrTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - /* Start the IOC */ - - evtctx = db_init_events(); - - testOk(!!(plug = dbFindFilter(arr, strlen(arr))), "plugin arr registered correctly"); - - check(DBR_LONG); - check(DBR_DOUBLE); - check(DBR_STRING); - - db_close_events(evtctx); - - testIocShutdownOk(); - - testdbCleanup(); - - return testDone(); -} diff --git a/src/std/filters/test/arrTest.db b/src/std/filters/test/arrTest.db deleted file mode 100644 index 467cf0d08..000000000 --- a/src/std/filters/test/arrTest.db +++ /dev/null @@ -1,15 +0,0 @@ -record(arr, "x") { - field(DESC, "test array record") - field(NELM, "10") - field(FTVL, "LONG") -} -record(arr, "y") { - field(DESC, "test array record") - field(NELM, "10") - field(FTVL, "DOUBLE") -} -record(arr, "z") { - field(DESC, "test array record") - field(NELM, "10") - field(FTVL, "STRING") -} diff --git a/src/std/filters/test/dbndTest.c b/src/std/filters/test/dbndTest.c deleted file mode 100644 index b35b9a6cc..000000000 --- a/src/std/filters/test/dbndTest.c +++ /dev/null @@ -1,285 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include "dbStaticLib.h" -#include "dbAccessDefs.h" -#include "db_field_log.h" -#include "dbCommon.h" -#include "registry.h" -#include "errlog.h" -#include "chfPlugin.h" -#include "epicsUnitTest.h" -#include "dbUnitTest.h" -#include "epicsTime.h" -#include "dbmf.h" -#include "testMain.h" -#include "osiFileName.h" - -#define PATTERN 0x55 - -void filterTest_registerRecordDeviceDriver(struct dbBase *); - -static db_field_log fl; - -static int fl_equal(const db_field_log *pfl1, const db_field_log *pfl2) { - return !(memcmp(pfl1, pfl2, sizeof(db_field_log))); -} - -static void fl_setup(dbChannel *chan, db_field_log *pfl) { - struct dbCommon *prec = dbChannelRecord(chan); - - pfl->ctx = dbfl_context_read; - pfl->type = dbfl_type_val; - pfl->stat = prec->stat; - pfl->sevr = prec->sevr; - pfl->time = prec->time; - pfl->field_type = dbChannelFieldType(chan); - pfl->no_elements = dbChannelElements(chan); - /* - * use memcpy to avoid a bus error on - * union copy of char in the db at an odd - * address - */ - memcpy(&pfl->u.v.field, - dbChannelField(chan), - dbChannelFieldSize(chan)); -} - -static void changeValue(db_field_log *pfl2, long val) { - pfl2->u.v.field.dbf_long = val; - testDiag("new value: %ld", val); -} - -static void mustPassOnce(dbChannel *pch, db_field_log *pfl2, char* m, double d, long val) { - db_field_log *pfl; - - changeValue(pfl2, val); - testDiag("mode=%s delta=%g filter must pass once", m, d); - pfl = dbChannelRunPreChain(pch, pfl2); - testOk(pfl2 == pfl, "call 1 does not drop or replace field_log"); - testOk(fl_equal(pfl, pfl2), "call 1 does not change field_log data"); - pfl = dbChannelRunPreChain(pch, pfl2); - testOk(NULL == pfl, "call 2 drops field_log"); -} - -static void mustDrop(dbChannel *pch, db_field_log *pfl2, char* m, double d, long val) { - db_field_log *pfl; - - changeValue(pfl2, val); - testDiag("mode=%s delta=%g filter must drop", m, d); - pfl = dbChannelRunPreChain(pch, pfl2); - testOk(NULL == pfl, "call 1 drops field_log"); -} - -static void mustPassTwice(dbChannel *pch, db_field_log *pfl2, char* m, double d, long val) { - db_field_log *pfl; - - changeValue(pfl2, val); - testDiag("mode=%s delta=%g filter must pass twice", m, d); - pfl = dbChannelRunPreChain(pch, pfl2); - testOk(pfl2 == pfl, "call 1 does not drop or replace field_log"); - testOk(fl_equal(pfl, pfl2), "call 1 does not change field_log data"); - pfl = dbChannelRunPreChain(pch, pfl2); - testOk(pfl2 == pfl, "call 2 does not drop or replace field_log"); - testOk(fl_equal(pfl, pfl2), "call 2 does not change field_log data"); -} - -static void testHead (char* title) { - testDiag("--------------------------------------------------------"); - testDiag("%s", title); - testDiag("--------------------------------------------------------"); -} - -MAIN(dbndTest) -{ - dbChannel *pch; - chFilter *filter; - const chFilterPlugin *plug; - char dbnd[] = "dbnd"; - ELLNODE *node; - chPostEventFunc *cb_out = NULL; - void *arg_out = NULL; - db_field_log *pfl2; - db_field_log fl1; - dbEventCtx evtctx; - - testPlan(59); - - testdbPrepare(); - - testdbReadDatabase("filterTest.dbd", NULL, NULL); - - filterTest_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("xRecord.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - evtctx = db_init_events(); - - testOk(!!(plug = dbFindFilter(dbnd, strlen(dbnd))), "plugin dbnd registered correctly"); - - testOk(!!(pch = dbChannelCreate("x.VAL{\"dbnd\":{}}")), "dbChannel with plugin dbnd (delta=0) created"); - testOk((ellCount(&pch->filters) == 1), "channel has one plugin"); - - memset(&fl, PATTERN, sizeof(fl)); - fl1 = fl; - node = ellFirst(&pch->filters); - filter = CONTAINER(node, chFilter, list_node); - plug->fif->channel_register_pre(filter, &cb_out, &arg_out, &fl1); - testOk(!!(cb_out) && !!(arg_out), "register_pre registers one filter with argument"); - testOk(fl_equal(&fl1, &fl), "register_pre does not change field_log data type"); - - testOk(!(dbChannelOpen(pch)), "dbChannel with plugin dbnd opened"); - node = ellFirst(&pch->pre_chain); - filter = CONTAINER(node, chFilter, pre_node); - testOk((ellCount(&pch->pre_chain) == 1 && filter->pre_arg != NULL), - "dbnd has one filter with argument in pre chain"); - testOk((ellCount(&pch->post_chain) == 0), "dbnd has no filter in post chain"); - - /* Field logs of type ref and rec: pass any update */ - - testHead("Field logs of type ref and rec"); - fl1.type = dbfl_type_rec; - mustPassTwice(pch, &fl1, "abs field_log=rec", 0., 0); - - fl1.type = dbfl_type_ref; - mustPassTwice(pch, &fl1, "abs field_log=ref", 0., 0); - - /* Delta = 0: pass any change */ - - testHead("Delta = 0: pass any change"); - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassOnce(pch, pfl2, "abs", 0., 0); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassOnce(pch, pfl2, "abs", 0., 1); - - dbChannelDelete(pch); - - /* Delta = -1: pass any update */ - - testHead("Delta = -1: pass any update"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"dbnd\":{\"d\":-1.0}}")), "dbChannel with plugin dbnd (delta=-1) created"); - testOk(!(dbChannelOpen(pch)), "dbChannel with plugin dbnd opened"); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassTwice(pch, pfl2, "abs", -1., 0); - mustPassTwice(pch, pfl2, "abs", -1., 1); - - db_delete_field_log(pfl2); - dbChannelDelete(pch); - - /* Delta = absolute */ - - testHead("Delta = absolute"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"dbnd\":{\"d\":3}}")), "dbChannel with plugin dbnd (delta=3) created"); - testOk(!(dbChannelOpen(pch)), "dbChannel with plugin dbnd opened"); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassOnce(pch, pfl2, "abs", 3., 1); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustDrop(pch, pfl2, "abs", 3., 3); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustDrop(pch, pfl2, "abs", 3., 4); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassOnce(pch, pfl2, "abs", 3., 5); - - dbChannelDelete(pch); - - /* Delta = relative */ - - testHead("Delta = relative"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"dbnd\":{\"m\":\"rel\",\"d\":50}}")), - "dbChannel with plugin dbnd (mode=rel, delta=50) created"); - testOk(!(dbChannelOpen(pch)), "dbChannel with plugin dbnd opened"); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassOnce(pch, pfl2, "rel", 50., 1); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassOnce(pch, pfl2, "rel", 50., 2); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustDrop(pch, pfl2, "rel", 50., 3); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassOnce(pch, pfl2, "rel", 50., 4); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustDrop(pch, pfl2, "rel", 50., 5); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustDrop(pch, pfl2, "rel", 50., 6); - - pfl2 = db_create_read_log(pch); - testDiag("new field_log from record"); - fl_setup(pch, pfl2); - - mustPassOnce(pch, pfl2, "rel", 50., 7); - - dbChannelDelete(pch); - - db_close_events(evtctx); - - testIocShutdownOk(); - - testdbCleanup(); - - return testDone(); -} diff --git a/src/std/filters/test/epicsRunFilterTests.c b/src/std/filters/test/epicsRunFilterTests.c deleted file mode 100644 index 236364391..000000000 --- a/src/std/filters/test/epicsRunFilterTests.c +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Run filter tests as a batch. - */ - -#include "epicsUnitTest.h" -#include "epicsExit.h" -#include "dbmf.h" - -int tsTest(void); -int dbndTest(void); -int syncTest(void); -int arrTest(void); - -void epicsRunFilterTests(void) -{ - testHarness(); - - runTest(tsTest); - runTest(dbndTest); - runTest(syncTest); - runTest(arrTest); - - dbmfFreeChunks(); - - epicsExit(0); /* Trigger test harness */ -} diff --git a/src/std/filters/test/rtemsTestHarness.c b/src/std/filters/test/rtemsTestHarness.c deleted file mode 100644 index 5215c7775..000000000 --- a/src/std/filters/test/rtemsTestHarness.c +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -extern void epicsRunFilterTests(void); - -int main(int argc, char **argv) -{ - epicsRunFilterTests(); /* calls epicsExit(0) */ - return 0; -} diff --git a/src/std/filters/test/syncTest.c b/src/std/filters/test/syncTest.c deleted file mode 100644 index 9af44afd7..000000000 --- a/src/std/filters/test/syncTest.c +++ /dev/null @@ -1,378 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include "dbStaticLib.h" -#include "dbAccessDefs.h" -#include "db_field_log.h" -#include "dbCommon.h" -#include "dbChannel.h" -#include "registry.h" -#include "chfPlugin.h" -#include "errlog.h" -#include "dbmf.h" -#include "epicsUnitTest.h" -#include "dbUnitTest.h" -#include "epicsTime.h" -#include "dbState.h" -#include "testMain.h" -#include "osiFileName.h" - -#define PATTERN 0x55 - -void filterTest_registerRecordDeviceDriver(struct dbBase *); - -static db_field_log fl; -static dbStateId red; - -static int fl_equal(const db_field_log *pfl1, const db_field_log *pfl2) { - return !(memcmp(pfl1, pfl2, sizeof(db_field_log))); -} - -static void fl_setup(dbChannel *chan, db_field_log *pfl, long val) { - struct dbCommon *prec = dbChannelRecord(chan); - - pfl->ctx = dbfl_context_event; - pfl->type = dbfl_type_val; - pfl->stat = prec->stat; - pfl->sevr = prec->sevr; - pfl->time = prec->time; - pfl->field_type = DBF_LONG; - pfl->no_elements = 1; - /* - * use memcpy to avoid a bus error on - * union copy of char in the db at an odd - * address - */ - memcpy(&pfl->u.v.field, - dbChannelField(chan), - dbChannelFieldSize(chan)); - pfl->u.v.field.dbf_long = val; -} - -static void testHead (char* title) { - testDiag("--------------------------------------------------------"); - testDiag("%s", title); - testDiag("--------------------------------------------------------"); -} - -static void mustDrop(dbChannel *pch, db_field_log *pfl2, char* m) { - db_field_log *pfl = dbChannelRunPreChain(pch, pfl2); - testOk(NULL == pfl, "filter drops field_log (%s)", m); -} - -static void mustPassTwice(dbChannel *pch, db_field_log *pfl2, char* m) { - db_field_log *pfl; - - testDiag("%s: filter must pass twice", m); - pfl = dbChannelRunPreChain(pch, pfl2); - testOk(pfl2 == pfl, "call 1 does not drop or replace field_log"); - pfl = dbChannelRunPreChain(pch, pfl2); - testOk(pfl2 == pfl, "call 2 does not drop or replace field_log"); -} - -static void mustPassOld(dbChannel *pch, db_field_log *old, db_field_log *cur, char* m) { - db_field_log *pfl = dbChannelRunPreChain(pch, cur); - - testOk(old == pfl, "filter passes previous field log (%s)", m); -} - -static void mustPass(dbChannel *pch, db_field_log *cur, char* m) { - db_field_log *pfl = dbChannelRunPreChain(pch, cur); - - testOk(cur == pfl, "filter passes field_log (%s)", m); -} - -static void checkCtxRead(dbChannel *pch, dbStateId id) { - fl.ctx = dbfl_context_read; - dbStateClear(id); - mustPassTwice(pch, &fl, "ctx='read', state=FALSE"); - dbStateSet(id); - mustPassTwice(pch, &fl, "ctx='read', state=TRUE"); - dbStateClear(id); - mustPassTwice(pch, &fl, "ctx='read', state=FALSE"); - fl.ctx = dbfl_context_event; -} - -static void checkAndOpenChannel(dbChannel *pch, const chFilterPlugin *plug) { - ELLNODE *node; - chFilter *filter; - chPostEventFunc *cb_out = NULL; - void *arg_out = NULL; - db_field_log fl1; - - testDiag("Test filter structure and open channel"); - - testOk((ellCount(&pch->filters) == 1), "channel has one plugin"); - - fl1 = fl; - node = ellFirst(&pch->filters); - filter = CONTAINER(node, chFilter, list_node); - plug->fif->channel_register_pre(filter, &cb_out, &arg_out, &fl1); - testOk(!!(cb_out) && !!(arg_out), "register_pre registers one filter with argument"); - testOk(fl_equal(&fl1, &fl), "register_pre does not change field_log data type"); - - testOk(!(dbChannelOpen(pch)), "dbChannel with plugin sync opened"); - node = ellFirst(&pch->pre_chain); - filter = CONTAINER(node, chFilter, pre_node); - testOk((ellCount(&pch->pre_chain) == 1 && filter->pre_arg != NULL), - "sync has one filter with argument in pre chain"); - testOk((ellCount(&pch->post_chain) == 0), "sync has no filter in post chain"); - - checkCtxRead(pch, red); -} - -MAIN(syncTest) -{ - dbChannel *pch; - const chFilterPlugin *plug; - char myname[] = "sync"; - db_field_log *pfl[10]; - int i; - dbEventCtx evtctx; - - testPlan(139); - - testdbPrepare(); - - testdbReadDatabase("filterTest.dbd", NULL, NULL); - - filterTest_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("xRecord.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - evtctx = db_init_events(); - - testOk(!!(plug = dbFindFilter(myname, strlen(myname))), "plugin %s registered correctly", myname); - testOk(!!(red = dbStateCreate("red")), "state 'red' created successfully"); - - /* nonexisting state */ - testOk(!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"while\",\"s\":\"blue\"}}")), - "dbChannel with sync (m='while' s='blue') (nonex state) failed"); - /* missing state */ - testOk(!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"while\"}}")), - "dbChannel with sync (m='while') (no state) failed"); - /* missing mode */ - testOk(!(pch = dbChannelCreate("x.VAL{\"sync\":{\"s\":\"red\"}}")), - "dbChannel with sync (s='red') (no mode) failed"); - - /* mode WHILE */ - - testHead("Mode WHILE (m='while', s='red')"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"while\",\"s\":\"red\"}}")), - "dbChannel with plugin sync (m='while' s='red') created"); - - checkAndOpenChannel(pch, plug); - - for (i = 0; i < 10; i++) { - pfl[i] = db_create_read_log(pch); - fl_setup(pch, pfl[i], 120 + i); - } - - testDiag("Test event stream"); - - dbStateClear(red); - mustDrop(pch, pfl[0], "state=FALSE, log0"); - mustDrop(pch, pfl[1], "state=FALSE, log1"); - mustDrop(pch, pfl[2], "state=FALSE, log2"); - dbStateSet(red); - mustPass(pch, pfl[3], "state=TRUE, log3"); - mustPass(pch, pfl[4], "state=TRUE, log4"); - mustPass(pch, pfl[5], "state=TRUE, log5"); - dbStateClear(red); - mustDrop(pch, pfl[6], "state=FALSE, log6"); - mustDrop(pch, pfl[7], "state=FALSE, log7"); - mustDrop(pch, pfl[8], "state=FALSE, log8"); - - for (i = 0; i < 10; i++) - db_delete_field_log(pfl[i]); - - dbChannelDelete(pch); - - /* mode UNLESS */ - - testHead("Mode UNLESS (m='unless', s='red')"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"unless\",\"s\":\"red\"}}")), - "dbChannel with plugin sync (m='unless' s='red') created"); - - checkAndOpenChannel(pch, plug); - - for (i = 0; i < 10; i++) { - pfl[i] = db_create_read_log(pch); - fl_setup(pch, pfl[i], 120 + i); - } - - testDiag("Test event stream"); - - dbStateClear(red); - mustPass(pch, pfl[0], "state=FALSE, log0"); - mustPass(pch, pfl[1], "state=FALSE, log1"); - mustPass(pch, pfl[2], "state=FALSE, log2"); - dbStateSet(red); - mustDrop(pch, pfl[3], "state=TRUE, log3"); - mustDrop(pch, pfl[4], "state=TRUE, log4"); - mustDrop(pch, pfl[5], "state=TRUE, log5"); - dbStateClear(red); - mustPass(pch, pfl[6], "state=FALSE, log6"); - mustPass(pch, pfl[7], "state=FALSE, log7"); - mustPass(pch, pfl[8], "state=FALSE, log8"); - - for (i = 0; i < 10; i++) - db_delete_field_log(pfl[i]); - - dbChannelDelete(pch); - - /* mode BEFORE */ - - testHead("Mode BEFORE (m='before', s='red')"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"before\",\"s\":\"red\"}}")), - "dbChannel with plugin sync (m='before' s='red') created"); - - checkAndOpenChannel(pch, plug); - - for (i = 0; i < 10; i++) { - pfl[i] = db_create_read_log(pch); - fl_setup(pch, pfl[i], 120 + i); - } - - testDiag("Test event stream"); - - dbStateClear(red); - mustDrop(pch, pfl[0], "state=FALSE, log0"); - mustDrop(pch, pfl[1], "state=FALSE, log1"); - mustDrop(pch, pfl[2], "state=FALSE, log2"); - dbStateSet(red); - mustPassOld(pch, pfl[2], pfl[3], "state=TRUE, log3, pass=log2"); - mustDrop(pch, pfl[4], "state=TRUE, log4"); - mustDrop(pch, pfl[5], "state=TRUE, log5"); - mustDrop(pch, pfl[6], "state=TRUE, log6"); - dbStateClear(red); - mustDrop(pch, pfl[7], "state=FALSE, log7"); - mustDrop(pch, pfl[8], "state=FALSE, log8"); - mustDrop(pch, pfl[9], "state=FALSE, log9"); - - db_delete_field_log(pfl[2]); - - dbChannelDelete(pch); - - /* mode FIRST */ - - testHead("Mode FIRST (m='first', s='red')"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"first\",\"s\":\"red\"}}")), - "dbChannel with plugin sync (m='first' s='red') created"); - - checkAndOpenChannel(pch, plug); - - for (i = 0; i < 10; i++) { - pfl[i] = db_create_read_log(pch); - fl_setup(pch, pfl[i], 120 + i); - } - - testDiag("Test event stream"); - - dbStateClear(red); - mustDrop(pch, pfl[0], "state=FALSE, log0"); - mustDrop(pch, pfl[1], "state=FALSE, log1"); - mustDrop(pch, pfl[2], "state=FALSE, log2"); - dbStateSet(red); - mustPass(pch, pfl[3], "state=TRUE, log3"); - mustDrop(pch, pfl[4], "state=TRUE, log4"); - mustDrop(pch, pfl[5], "state=TRUE, log5"); - dbStateClear(red); - mustDrop(pch, pfl[6], "state=FALSE, log6"); - mustDrop(pch, pfl[7], "state=FALSE, log7"); - mustDrop(pch, pfl[8], "state=FALSE, log8"); - - db_delete_field_log(pfl[3]); - db_delete_field_log(pfl[9]); - - dbChannelDelete(pch); - - /* mode LAST */ - - testHead("Mode LAST (m='last', s='red')"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"last\",\"s\":\"red\"}}")), - "dbChannel with plugin sync (m='last' s='red') created"); - - checkAndOpenChannel(pch, plug); - - for (i = 0; i < 10; i++) { - pfl[i] = db_create_read_log(pch); - fl_setup(pch, pfl[i], 120 + i); - } - - testDiag("Test event stream"); - - dbStateClear(red); - mustDrop(pch, pfl[0], "state=FALSE, log0"); - mustDrop(pch, pfl[1], "state=FALSE, log1"); - mustDrop(pch, pfl[2], "state=FALSE, log2"); - dbStateSet(red); - mustDrop(pch, pfl[3], "state=TRUE, log3"); - mustDrop(pch, pfl[4], "state=TRUE, log4"); - mustDrop(pch, pfl[5], "state=TRUE, log5"); - dbStateClear(red); - mustPassOld(pch, pfl[5], pfl[6], "state=TRUE, log6, pass=log5"); - mustDrop(pch, pfl[7], "state=FALSE, log7"); - mustDrop(pch, pfl[8], "state=FALSE, log8"); - mustDrop(pch, pfl[9], "state=FALSE, log9"); - - db_delete_field_log(pfl[5]); - - dbChannelDelete(pch); - - /* mode AFTER */ - - testHead("Mode AFTER (m='after', s='red')"); - testOk(!!(pch = dbChannelCreate("x.VAL{\"sync\":{\"m\":\"after\",\"s\":\"red\"}}")), - "dbChannel with plugin sync (m='after' s='red') created"); - - checkAndOpenChannel(pch, plug); - - for (i = 0; i < 10; i++) { - pfl[i] = db_create_read_log(pch); - fl_setup(pch, pfl[i], 120 + i); - } - - testDiag("Test event stream"); - - dbStateClear(red); - mustDrop(pch, pfl[0], "state=FALSE, log0"); - mustDrop(pch, pfl[1], "state=FALSE, log1"); - mustDrop(pch, pfl[2], "state=FALSE, log2"); - dbStateSet(red); - mustDrop(pch, pfl[3], "state=TRUE, log3"); - mustDrop(pch, pfl[4], "state=TRUE, log4"); - mustDrop(pch, pfl[5], "state=TRUE, log5"); - dbStateClear(red); - mustPass(pch, pfl[6], "state=FALSE, log6"); - mustDrop(pch, pfl[7], "state=FALSE, log7"); - mustDrop(pch, pfl[8], "state=FALSE, log8"); - - db_delete_field_log(pfl[6]); - db_delete_field_log(pfl[9]); - - dbChannelDelete(pch); - - db_close_events(evtctx); - - testIocShutdownOk(); - - testdbCleanup(); - - return testDone(); -} diff --git a/src/std/filters/test/tsTest.c b/src/std/filters/test/tsTest.c deleted file mode 100644 index 0315ab442..000000000 --- a/src/std/filters/test/tsTest.c +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include "dbStaticLib.h" -#include "dbAccessDefs.h" -#include "chfPlugin.h" -#include "errlog.h" -#include "epicsUnitTest.h" -#include "dbUnitTest.h" -#include "registry.h" -#include "dbmf.h" -#include "epicsTime.h" -#include "testMain.h" -#include "osiFileName.h" - -#define PATTERN 0x55 - -void filterTest_registerRecordDeviceDriver(struct dbBase *); - -static db_field_log fl; - -static int fl_equal(const db_field_log *pfl1, const db_field_log *pfl2) { - return !(memcmp(pfl1, pfl2, sizeof(db_field_log))); -} - -static int fl_equal_ex_ts(const db_field_log *pfl1, const db_field_log *pfl2) { - db_field_log fl1 = *pfl1; - - fl1.time = pfl2->time; - return fl_equal(&fl1, pfl2); -} - -MAIN(tsTest) -{ - dbChannel *pch; - chFilter *filter; - const chFilterPlugin *plug; - char ts[] = "ts"; - ELLNODE *node; - chPostEventFunc *cb_out = NULL; - void *arg_out = NULL; - db_field_log fl1; - db_field_log *pfl2; - epicsTimeStamp stamp, now; - dbEventCtx evtctx; - - testPlan(12); - - testdbPrepare(); - - testdbReadDatabase("filterTest.dbd", NULL, NULL); - - filterTest_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("xRecord.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - evtctx = db_init_events(); - - testOk(!!(plug = dbFindFilter(ts, strlen(ts))), "plugin ts registered correctly"); - - testOk(!!(pch = dbChannelCreate("x.VAL{\"ts\":{}}")), "dbChannel with plugin ts created"); - testOk((ellCount(&pch->filters) == 1), "channel has one plugin"); - - memset(&fl, PATTERN, sizeof(fl)); - fl1 = fl; - node = ellFirst(&pch->filters); - filter = CONTAINER(node, chFilter, list_node); - plug->fif->channel_register_pre(filter, &cb_out, &arg_out, &fl1); - testOk(!!(cb_out) && !(arg_out), "register_pre registers one filter w/o argument"); - testOk(fl_equal(&fl1, &fl), "register_pre does not change field_log data type"); - - testOk(!(dbChannelOpen(pch)), "dbChannel with plugin ts opened"); - node = ellFirst(&pch->pre_chain); - filter = CONTAINER(node, chFilter, pre_node); - testOk((ellCount(&pch->pre_chain) == 1 && filter->pre_arg == NULL), - "ts has one filter w/o argument in pre chain"); - testOk((ellCount(&pch->post_chain) == 0), "ts has no filter in post chain"); - - memset(&fl, PATTERN, sizeof(fl)); - fl1 = fl; - pfl2 = dbChannelRunPreChain(pch, &fl1); - testOk(pfl2 == &fl1, "ts filter does not drop or replace field_log"); - testOk(fl_equal_ex_ts(&fl1, pfl2), "ts filter does not change field_log data"); - - testOk(!!(pfl2 = db_create_read_log(pch)), "create field log from channel"); - stamp = pfl2->time; - db_delete_field_log(pfl2); - - pfl2 = dbChannelRunPreChain(pch, &fl1); - epicsTimeGetCurrent(&now); - testOk(epicsTimeDiffInSeconds(&pfl2->time, &stamp) >= 0 && - epicsTimeDiffInSeconds(&now, &pfl2->time) >= 0, - "ts filter sets time stamp to \"now\""); - - dbChannelDelete(pch); - - db_close_events(evtctx); - - testIocShutdownOk(); - - testdbCleanup(); - - return testDone(); -} diff --git a/src/std/filters/test/xRecord.c b/src/std/filters/test/xRecord.c deleted file mode 100644 index 568fbb838..000000000 --- a/src/std/filters/test/xRecord.c +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Andrew Johnson - * Ralph Lange - */ - -#include "dbAccessDefs.h" -#include - -#define GEN_SIZE_OFFSET -#include "xRecord.h" - -#include - -static rset xRSET; -epicsExportAddress(rset,xRSET); diff --git a/src/std/filters/test/xRecord.db b/src/std/filters/test/xRecord.db deleted file mode 100644 index a6fa08e40..000000000 --- a/src/std/filters/test/xRecord.db +++ /dev/null @@ -1,2 +0,0 @@ -record(x, x) {} - diff --git a/src/std/filters/test/xRecord.dbd b/src/std/filters/test/xRecord.dbd deleted file mode 100644 index fd59d1780..000000000 --- a/src/std/filters/test/xRecord.dbd +++ /dev/null @@ -1,8 +0,0 @@ -# This is a combined minimal DBD and DB file - -recordtype(x) { - include "dbCommon.dbd" - field(VAL, DBF_LONG) { - prompt("Value") - } -} diff --git a/src/std/filters/ts.c b/src/std/filters/ts.c deleted file mode 100644 index 5925b0bf2..000000000 --- a/src/std/filters/ts.c +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2010 Brookhaven National Laboratory. -* Copyright (c) 2010 Helmholtz-Zentrum Berlin -* fuer Materialien und Energie GmbH. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include -#include -#include -#include - -static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) { - epicsTimeStamp now; - epicsTimeGetCurrent(&now); - - /* If string or array, must make a copy (to ensure coherence between time and data) */ - if (pfl->type == dbfl_type_rec) { - dbScanLock(dbChannelRecord(chan)); - dbChannelMakeArrayCopy(pvt, pfl, chan); - dbScanUnlock(dbChannelRecord(chan)); - } - - pfl->time = now; - return pfl; -} - -static void channelRegisterPre(dbChannel *chan, void *pvt, - chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - *cb_out = filter; -} - -static void channel_report(dbChannel *chan, void *pvt, int level, const unsigned short indent) -{ - printf("%*sTimestamp (ts)\n", indent, ""); -} - -static chfPluginIf pif = { - NULL, /* allocPvt, */ - NULL, /* freePvt, */ - - NULL, /* parse_error, */ - NULL, /* parse_ok, */ - - NULL, /* channel_open, */ - channelRegisterPre, - NULL, /* channelRegisterPost, */ - channel_report, - NULL /* channel_close */ -}; - -static void tsInitialize(void) -{ - chfPluginRegister("ts", &pif, NULL); -} - -epicsExportRegistrar(tsInitialize); diff --git a/src/std/link/Makefile b/src/std/link/Makefile deleted file mode 100644 index 31d14b825..000000000 --- a/src/std/link/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -#************************************************************************* -# Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/std/Makefile. - -SRC_DIRS += $(STDDIR)/link - -DBD += links.dbd - -dbRecStd_SRCS += lnkConst.c -dbRecStd_SRCS += lnkCalc.c - -HTMLS += links.html - diff --git a/src/std/link/links.dbd.pod b/src/std/link/links.dbd.pod deleted file mode 100644 index ceb6ced77..000000000 --- a/src/std/link/links.dbd.pod +++ /dev/null @@ -1,123 +0,0 @@ -=head1 Extensible Links - -The extensible link mechanism allows new kinds of record links to be created, -using JSON for the link address syntax. -The IOC continues to support the older link types that do not use JSON to -specify their link addresses. - -The following additional link types are available in this release: - -=over - -=item * L - -=item * L - -=back - -=head2 Using JSON Links - -When setting a record link field to a JSON link address, the link specification -must appear inside a pair of braces C< {} > expressed as a JSON (L) object, which allows link parameters to -be defined as needed by the particular link type. When link fields are set from -an IOC database file at initialization time, the field definitions may take -advantage of a "relaxed JSON" syntax that reduces the number of double-quote -characters required and maintains backwards compatibility with the older -database file syntax. - - -=head2 Link Type Reference - -=cut - -link(const, lnkConstIf) - -=head3 Constant Link C<"const"> - -Constant links provide one or more values at link initalization time, but do not -return any data when their C routine is called. Most record types -support the use of constant links by calling C at -record initialization, which results in the constant value being loaded into the -target field at that time. - -Note that for most record types (the C and C records are the -main exceptions) it is pointless to set an input link to a constant link at -runtime since the link initialization that loads the field value usually only -happens when a record is initialized. A constant link that is embedded inside -another input link type such as a calculation link should be OK though since the -link initialization will take place when the record's field gets set. - -=head4 Parameters - -A const link takes a parameter which may be an integer, double or string, or an -array of those types. If an array contains both integers and double values the -integers will be promoted to doubles. Mixing strings and numbers in an array -results in an error. - -=head4 Examples - - {const: 3.14159265358979} - {const: "Pi"} - {const: [1, 2.718281828459, 3.14159265358979]} - {const: ["One", "e", "Pi"]} - -The JSON syntax does not support Infinity or NaN values when parsing numbers, -but (for scalars) it is possible to provide these in a string which will be -converted to the desired double value at initialization, for example: - - field(INP, {const:"Inf"}) - -=cut - -link(calc, lnkCalcIf) - -=head3 Calculation Link C<"calc"> - -Calculation links can perform simple mathematical expressions on scalar -(double-precision floating-point) values obtained from other link types and -return a single double-precision floating-point result. The expressions are -evaluated by the EPICS Calc engine, and up to 12 inputs can be provided. - -=head4 Parameters - -The link address is a JSON map with the following keys: - -=over - -=item expr - -The primary expression to be evaluated, given as a string. - -=item major - -An optional expression that returns non-zero to raise a major alarm. - -=item minor - -An optional expression that returns non-zero to raise a minor alarm. - -=item args - -A JSON list of up to 12 input arguments for the expression, which are assigned -to the inputs C, C, C, ... C. Each input argument may be either a -numeric literal or an embedded JSON link inside C<{}> braces. The same input -values are provided to the two alarm expressions as to the primary expression. - -=item units - -An optional string specifying the engineering units for the result of the -expression. Equivalent to the C field of a record. - -=item prec - -An optional integer specifying the numeric precision with which the calculation -result should be displayed. Equivalent to the C field of a record. - -=back - -=head4 Example - - {calc: {expr:"A*B", args:[{db:"record.VAL"}, 1.5], prec:3}} - -=cut diff --git a/src/std/link/lnkCalc.c b/src/std/link/lnkCalc.c deleted file mode 100644 index 286b61702..000000000 --- a/src/std/link/lnkCalc.c +++ /dev/null @@ -1,642 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* lnkCalc.c */ - -/* Current usage - * {calc:{expr:"A", args:[{...}, ...]}} - * First link in 'args' is 'A', second is 'B', and so forth. - * - * TODO: - * Support setting individual input links instead of the args list. - * {calc:{expr:"K", K:{...}}} - */ - -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "errlog.h" -#include "epicsAssert.h" -#include "epicsString.h" -#include "epicsTypes.h" -#include "dbAccessDefs.h" -#include "dbConvertFast.h" -#include "dbLink.h" -#include "dbJLink.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "postfix.h" -#include "recGbl.h" -#include "epicsExport.h" - - -typedef long (*FASTCONVERT)(); - -#define IFDEBUG(n) if(clink->jlink.debug) - -typedef struct calc_link { - jlink jlink; /* embedded object */ - int nArgs; - enum { - ps_init, - ps_expr, ps_major, ps_minor, - ps_args, - ps_prec, - ps_units, - ps_error - } pstate; - epicsEnum16 stat; - epicsEnum16 sevr; - short prec; - char *expr; - char *major; - char *minor; - char *post_expr; - char *post_major; - char *post_minor; - char *units; - struct link inp[CALCPERFORM_NARGS]; - double arg[CALCPERFORM_NARGS]; - double val; -} calc_link; - -static lset lnkCalc_lset; - - -/*************************** jlif Routines **************************/ - -static jlink* lnkCalc_alloc(short dbfType) -{ - calc_link *clink = calloc(1, sizeof(struct calc_link)); - - IFDEBUG(10) - printf("lnkCalc_alloc()\n"); - - clink->nArgs = 0; - clink->pstate = ps_init; - clink->prec = 15; /* standard value for a double */ - - IFDEBUG(10) - printf("lnkCalc_alloc -> calc@%p\n", clink); - - return &clink->jlink; -} - -static void lnkCalc_free(jlink *pjlink) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - int i; - - IFDEBUG(10) - printf("lnkCalc_free(calc@%p)\n", clink); - - for (i = 0; i < clink->nArgs; i++) - dbJLinkFree(clink->inp[i].value.json.jlink); - - free(clink->expr); - free(clink->major); - free(clink->minor); - free(clink->post_expr); - free(clink->post_major); - free(clink->post_minor); - free(clink->units); - free(clink); -} - -static jlif_result lnkCalc_integer(jlink *pjlink, long long num) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_integer(calc@%p, %lld)\n", clink, num); - - if (clink->pstate == ps_prec) { - clink->prec = num; - return jlif_continue; - } - - if (clink->pstate != ps_args) { - return jlif_stop; - errlogPrintf("lnkCalc: Unexpected integer %lld\n", num); - } - - if (clink->nArgs == CALCPERFORM_NARGS) { - errlogPrintf("lnkCalc: Too many input args, limit is %d\n", - CALCPERFORM_NARGS); - return jlif_stop; - } - - clink->arg[clink->nArgs++] = num; - - return jlif_continue; -} - -static jlif_result lnkCalc_double(jlink *pjlink, double num) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_double(calc@%p, %g)\n", clink, num); - - if (clink->pstate != ps_args) { - return jlif_stop; - errlogPrintf("lnkCalc: Unexpected double %g\n", num); - } - - if (clink->nArgs == CALCPERFORM_NARGS) { - errlogPrintf("lnkCalc: Too many input args, limit is %d\n", - CALCPERFORM_NARGS); - return jlif_stop; - } - - clink->arg[clink->nArgs++] = num; - - return jlif_continue; -} - -static jlif_result lnkCalc_string(jlink *pjlink, const char *val, size_t len) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - char *inbuf, *postbuf; - short err; - - IFDEBUG(10) - printf("lnkCalc_string(calc@%p, \"%.*s\")\n", clink, (int) len, val); - - if (clink->pstate == ps_units) { - clink->units = epicsStrnDup(val, len); - return jlif_continue; - } - - if (clink->pstate < ps_expr || clink->pstate > ps_minor) { - errlogPrintf("lnkCalc: Unexpected string \"%.*s\"\n", (int) len, val); - return jlif_stop; - } - - postbuf = malloc(INFIX_TO_POSTFIX_SIZE(len+1)); - if (!postbuf) { - errlogPrintf("lnkCalc: Out of memory\n"); - return jlif_stop; - } - - inbuf = malloc(len+1); - if(!inbuf) { - errlogPrintf("lnkCalc: Out of memory\n"); - return jlif_stop; - } - memcpy(inbuf, val, len); - inbuf[len] = '\0'; - - if (clink->pstate == ps_major) { - clink->major = inbuf; - clink->post_major = postbuf; - } - else if (clink->pstate == ps_minor) { - clink->minor = inbuf; - clink->post_minor = postbuf; - } - else { - clink->expr = inbuf; - clink->post_expr = postbuf; - } - - if (postfix(inbuf, postbuf, &err) < 0) { - errlogPrintf("lnkCalc: Error in calc expression, %s\n", - calcErrorStr(err)); - return jlif_stop; - } - - return jlif_continue; -} - -static jlif_key_result lnkCalc_start_map(jlink *pjlink) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_start_map(calc@%p)\n", clink); - - if (clink->pstate == ps_args) - return jlif_key_child_link; - - if (clink->pstate != ps_init) { - errlogPrintf("lnkCalc: Unexpected map\n"); - return jlif_key_stop; - } - - return jlif_key_continue; -} - -static jlif_result lnkCalc_map_key(jlink *pjlink, const char *key, size_t len) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_map_key(calc@%p, \"%.*s\")\n", pjlink, (int) len, key); - - if (len == 4) { - if (!strncmp(key, "expr", len) && !clink->post_expr) - clink->pstate = ps_expr; - else if (!strncmp(key, "args", len) && !clink->nArgs) - clink->pstate = ps_args; - else if (!strncmp(key, "prec", len)) - clink->pstate = ps_prec; - else { - errlogPrintf("lnkCalc: Unknown key \"%.4s\"\n", key); - return jlif_stop; - } - } - else if (len == 5) { - if (!strncmp(key, "major", len) && !clink->post_major) - clink->pstate = ps_major; - else if (!strncmp(key, "minor", len) && !clink->post_minor) - clink->pstate = ps_minor; - else if (!strncmp(key, "units", len) && !clink->units) - clink->pstate = ps_units; - else { - errlogPrintf("lnkCalc: Unknown key \"%.5s\"\n", key); - return jlif_stop; - } - } - else { - errlogPrintf("lnkCalc: Unknown key \"%.*s\"\n", (int) len, key); - return jlif_stop; - } - - return jlif_continue; -} - -static jlif_result lnkCalc_end_map(jlink *pjlink) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_end_map(calc@%p)\n", clink); - - if (clink->pstate == ps_error) - return jlif_stop; - else if (!clink->post_expr) { - errlogPrintf("lnkCalc: no expression ('expr' key)\n"); - return jlif_stop; - } - - return jlif_continue; -} - -static jlif_result lnkCalc_start_array(jlink *pjlink) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_start_array(calc@%p)\n", clink); - - if (clink->pstate != ps_args) { - errlogPrintf("lnkCalc: Unexpected array\n"); - return jlif_stop; - } - - return jlif_continue; -} - -static jlif_result lnkCalc_end_array(jlink *pjlink) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_end_array(calc@%p)\n", clink); - - if (clink->pstate == ps_error) - return jlif_stop; - - return jlif_continue; -} - -static void lnkCalc_end_child(jlink *parent, jlink *child) -{ - calc_link *clink = CONTAINER(parent, struct calc_link, jlink); - struct link *plink; - - if (clink->nArgs == CALCPERFORM_NARGS) { - dbJLinkFree(child); - errlogPrintf("lnkCalc: Too many input args, limit is %d\n", - CALCPERFORM_NARGS); - clink->pstate = ps_error; - return; - } - - plink = &clink->inp[clink->nArgs++]; - plink->type = JSON_LINK; - plink->value.json.string = NULL; - plink->value.json.jlink = child; -} - -static struct lset* lnkCalc_get_lset(const jlink *pjlink) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_get_lset(calc@%p)\n", pjlink); - - return &lnkCalc_lset; -} - -static void lnkCalc_report(const jlink *pjlink, int level, int indent) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - int i; - - IFDEBUG(10) - printf("lnkCalc_report(calc@%p)\n", clink); - - printf("%*s'calc': \"%s\" = %.*g %s\n", indent, "", - clink->expr, clink->prec, clink->val, - clink->units ? clink->units : ""); - - if (level > 0) { - if (clink->sevr) - printf("%*s Alarm: %s, %s\n", indent, "", - epicsAlarmSeverityStrings[clink->sevr], - epicsAlarmConditionStrings[clink->stat]); - - if (clink->post_major) - printf("%*s Major expression: \"%s\"\n", indent, "", - clink->major); - if (clink->post_minor) - printf("%*s Minor expression: \"%s\"\n", indent, "", - clink->minor); - - for (i = 0; i < clink->nArgs; i++) { - struct link *plink = &clink->inp[i]; - jlink *child = plink->type == JSON_LINK ? - plink->value.json.jlink : NULL; - - printf("%*s Input %c: %g\n", indent, "", - i + 'A', clink->arg[i]); - - if (child) - dbJLinkReport(child, level - 1, indent + 4); - } - } -} - -long lnkCalc_map_children(jlink *pjlink, jlink_map_fn rtn, void *ctx) -{ - calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink); - int i; - - IFDEBUG(10) - printf("lnkCalc_map_children(calc@%p)\n", clink); - - for (i = 0; i < clink->nArgs; i++) { - struct link *child = &clink->inp[i]; - long status = dbJLinkMapChildren(child, rtn, ctx); - - if (status) - return status; - } - return 0; -} - -/*************************** lset Routines **************************/ - -static void lnkCalc_open(struct link *plink) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - int i; - - IFDEBUG(10) - printf("lnkCalc_open(calc@%p)\n", clink); - - for (i = 0; i < clink->nArgs; i++) { - struct link *child = &clink->inp[i]; - - child->precord = plink->precord; - dbJLinkInit(child); - dbLoadLink(child, DBR_DOUBLE, &clink->arg[i]); - } -} - -static void lnkCalc_remove(struct dbLocker *locker, struct link *plink) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - int i; - - IFDEBUG(10) - printf("lnkCalc_remove(calc@%p)\n", clink); - - for (i = 0; i < clink->nArgs; i++) { - struct link *child = &clink->inp[i]; - - dbRemoveLink(locker, child); - } - - free(clink->expr); - free(clink->major); - free(clink->minor); - free(clink->post_expr); - free(clink->post_major); - free(clink->post_minor); - free(clink->units); - free(clink); - plink->value.json.jlink = NULL; -} - -static int lnkCalc_isConn(const struct link *plink) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - int connected = 1; - int i; - - IFDEBUG(10) - printf("lnkCalc_isConn(calc@%p)\n", clink); - - for (i = 0; i < clink->nArgs; i++) { - struct link *child = &clink->inp[i]; - - if (dbLinkIsVolatile(child) && - !dbIsLinkConnected(child)) - connected = 0; - } - - return connected; -} - -static int lnkCalc_getDBFtype(const struct link *plink) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - - IFDEBUG(10) { - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - - printf("lnkCalc_getDBFtype(calc@%p)\n", clink); - } - - return DBF_DOUBLE; -} - -static long lnkCalc_getElements(const struct link *plink, long *nelements) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - - IFDEBUG(10) { - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - - printf("lnkCalc_getElements(calc@%p, (%ld))\n", - clink, *nelements); - } - - *nelements = 1; - return 0; -} - -static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - int i; - long status; - FASTCONVERT conv = dbFastPutConvertRoutine[DBR_DOUBLE][dbrType]; - - IFDEBUG(10) - printf("lnkCalc_getValue(calc@%p, %d, ...)\n", - clink, dbrType); - - for (i = 0; i < clink->nArgs; i++) { - struct link *child = &clink->inp[i]; - long nReq = 1; - - dbGetLink(child, DBR_DOUBLE, &clink->arg[i], NULL, &nReq); - /* Any errors have already triggered a LINK/INVALID alarm */ - } - clink->stat = 0; - clink->sevr = 0; - - if (clink->post_expr) { - status = calcPerform(clink->arg, &clink->val, clink->post_expr); - if (!status) - status = conv(&clink->val, pbuffer, NULL); - if (!status && pnRequest) - *pnRequest = 1; - } - else { - status = 0; - if (pnRequest) - *pnRequest = 0; - } - - if (!status && clink->post_major) { - double alval = clink->val; - - status = calcPerform(clink->arg, &alval, clink->post_major); - if (!status && alval) { - clink->stat = LINK_ALARM; - clink->sevr = MAJOR_ALARM; - recGblSetSevr(plink->precord, clink->stat, clink->sevr); - } - } - - if (!status && clink->post_minor) { - double alval = clink->val; - - status = calcPerform(clink->arg, &alval, clink->post_minor); - if (!status && alval) { - clink->stat = LINK_ALARM; - clink->sevr = MINOR_ALARM; - recGblSetSevr(plink->precord, clink->stat, clink->sevr); - } - } - - return status; -} - -static long lnkCalc_getPrecision(const struct link *plink, short *precision) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_getPrecision(calc@%p)\n", clink); - - *precision = clink->prec; - return 0; -} - -static long lnkCalc_getUnits(const struct link *plink, char *units, int len) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_getUnits(calc@%p)\n", clink); - - if (clink->units) { - strncpy(units, clink->units, --len); - units[len] = '\0'; - } - else - units[0] = '\0'; - return 0; -} - -static long lnkCalc_getAlarm(const struct link *plink, epicsEnum16 *status, - epicsEnum16 *severity) -{ - calc_link *clink = CONTAINER(plink->value.json.jlink, - struct calc_link, jlink); - - IFDEBUG(10) - printf("lnkCalc_getAlarm(calc@%p)\n", clink); - - if (status) - *status = clink->stat; - if (severity) - *severity = clink->sevr; - - return 0; -} - -static long doLocked(struct link *plink, dbLinkUserCallback rtn, void *priv) -{ - return rtn(plink, priv); -} - - -/************************* Interface Tables *************************/ - -static lset lnkCalc_lset = { - 0, 1, /* not Constant, Volatile */ - lnkCalc_open, lnkCalc_remove, - NULL, NULL, NULL, - lnkCalc_isConn, lnkCalc_getDBFtype, lnkCalc_getElements, - lnkCalc_getValue, - NULL, NULL, NULL, - lnkCalc_getPrecision, lnkCalc_getUnits, - lnkCalc_getAlarm, NULL, - NULL, NULL, - NULL, doLocked -}; - -static jlif lnkCalcIf = { - "calc", lnkCalc_alloc, lnkCalc_free, - NULL, NULL, lnkCalc_integer, lnkCalc_double, lnkCalc_string, - lnkCalc_start_map, lnkCalc_map_key, lnkCalc_end_map, - lnkCalc_start_array, lnkCalc_end_array, - lnkCalc_end_child, lnkCalc_get_lset, - lnkCalc_report, lnkCalc_map_children -}; -epicsExportAddress(jlif, lnkCalcIf); - diff --git a/src/std/link/lnkConst.c b/src/std/link/lnkConst.c deleted file mode 100644 index db824abbc..000000000 --- a/src/std/link/lnkConst.c +++ /dev/null @@ -1,585 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* lnkConst.c */ - -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "epicsAssert.h" -#include "epicsString.h" -#include "epicsTypes.h" -#include "dbAccessDefs.h" -#include "dbConvertFast.h" -#include "dbLink.h" -#include "dbJLink.h" -#include "epicsExport.h" - - -#define IFDEBUG(n) if(clink->jlink.debug) - -typedef long (*FASTCONVERT)(); - -typedef struct const_link { - jlink jlink; /* embedded object */ - int nElems; - enum {s0, si32, sf64, sc40, a0, ai32, af64, ac40} type; - union { - epicsInt32 scalar_integer; /* si32 */ - epicsFloat64 scalar_double; /* sf64 */ - char *scalar_string; /* sc40 */ - void *pmem; - epicsInt32 *pintegers; /* ai32 */ - epicsFloat64 *pdoubles; /* af64 */ - char **pstrings; /* ac40 */ - } value; -} const_link; - -static lset lnkConst_lset; - - -/*************************** jlif Routines **************************/ - -static jlink* lnkConst_alloc(short dbfType) -{ - const_link *clink = calloc(1, sizeof(*clink)); - - IFDEBUG(10) - printf("lnkConst_alloc()\n"); - - clink->type = s0; - clink->nElems = 0; - clink->value.pmem = NULL; - - IFDEBUG(10) - printf("lnkConst_alloc -> const@%p\n", clink); - - return &clink->jlink; -} - -static void lnkConst_free(jlink *pjlink) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - - IFDEBUG(10) - printf("lnkConst_free(const@%p) type=%d\n", pjlink, clink->type); - - switch (clink->type) { - int i; - case ac40: - for (i=0; inElems; i++) - free(clink->value.pstrings[i]); - /* fall through */ - case sc40: - case ai32: - case af64: - free(clink->value.pmem); - break; - case s0: - case a0: - case si32: - case sf64: - break; - } - free(clink); -} - -static jlif_result lnkConst_integer(jlink *pjlink, long long num) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - int newElems = clink->nElems + 1; - - IFDEBUG(10) - printf("lnkConst_integer(const@%p, %lld)\n", pjlink, num); - - switch (clink->type) { - void *buf; - - case s0: - clink->type = si32; - clink->value.scalar_integer = num; - break; - - case a0: - clink->type = ai32; - /* fall through */ - case ai32: - buf = realloc(clink->value.pmem, newElems * sizeof(epicsInt32)); - if (!buf) - return jlif_stop; - - clink->value.pmem = buf; - clink->value.pintegers[clink->nElems] = num; - break; - - case af64: - buf = realloc(clink->value.pmem, newElems * sizeof(epicsFloat64)); - if (!buf) - return jlif_stop; - - clink->value.pmem = buf; - clink->value.pdoubles[clink->nElems] = num; - break; - - case ac40: - errlogPrintf("lnkConst: Mixed data types in array\n"); - /* fall through */ - default: - return jlif_stop; - } - - clink->nElems = newElems; - return jlif_continue; -} - -static jlif_result lnkConst_boolean(jlink *pjlink, int val) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - IFDEBUG(10) - printf("lnkConst_boolean(const@%p, %d)\n", pjlink, val); - - return lnkConst_integer(pjlink, val); -} - -static jlif_result lnkConst_double(jlink *pjlink, double num) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - int newElems = clink->nElems + 1; - - IFDEBUG(10) - printf("lnkConst_double(const@%p, %g)\n", pjlink, num); - - switch (clink->type) { - epicsFloat64 *f64buf; - int i; - - case s0: - clink->type = sf64; - clink->value.scalar_double = num; - break; - - case a0: - clink->type = af64; - /* fall through */ - case af64: - f64buf = realloc(clink->value.pmem, newElems * sizeof(epicsFloat64)); - if (!f64buf) - return jlif_stop; - - f64buf[clink->nElems] = num; - clink->value.pdoubles = f64buf; - break; - - case ai32: /* promote earlier ai32 values to af64 */ - f64buf = calloc(newElems, sizeof(epicsFloat64)); - if (!f64buf) - return jlif_stop; - - for (i = 0; i < clink->nElems; i++) { - f64buf[i] = clink->value.pintegers[i]; - } - free(clink->value.pmem); - f64buf[clink->nElems] = num; - clink->type = af64; - clink->value.pdoubles = f64buf; - break; - - case ac40: - errlogPrintf("lnkConst: Mixed data types in array\n"); - /* fall through */ - default: - return jlif_stop; - } - - clink->nElems = newElems; - return jlif_continue; -} - -static jlif_result lnkConst_string(jlink *pjlink, const char *val, size_t len) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - int newElems = clink->nElems + 1; - - IFDEBUG(10) - printf("lnkConst_string(const@%p, \"%.*s\")\n", clink, (int) len, val); - - switch (clink->type) { - char **vec, *str; - - case s0: - str = malloc(len+1); - if (!str) - return jlif_stop; - - strncpy(str, val, len); - str[len] = '\0'; - clink->type = sc40; - clink->value.scalar_string = str; - break; - - case a0: - clink->type = ac40; - /* fall thorough */ - case ac40: - vec = realloc(clink->value.pmem, newElems * sizeof(char *)); - if (!vec) - return jlif_stop; - str = malloc(len+1); - if (!str) - return jlif_stop; - - strncpy(str, val, len); - str[len] = '\0'; - vec[clink->nElems] = str; - clink->value.pstrings = vec; - break; - - case af64: - case ai32: - errlogPrintf("lnkConst: Mixed data types in array\n"); - /* fall thorough */ - default: - return jlif_stop; - } - - clink->nElems = newElems; - return jlif_continue; -} - -static jlif_result lnkConst_start_array(jlink *pjlink) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - - IFDEBUG(10) - printf("lnkConst_start_array(const@%p)\n", pjlink); - - if (clink->type != s0) { - errlogPrintf("lnkConst: Embedded array value\n"); - return jlif_stop; - } - - clink->type = a0; - return jlif_continue; -} - -static jlif_result lnkConst_end_array(jlink *pjlink) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - - IFDEBUG(10) - printf("lnkConst_end_array(const@%p)\n", pjlink); - - return jlif_continue; -} - -static struct lset* lnkConst_get_lset(const jlink *pjlink) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - - IFDEBUG(10) - printf("lnkConst_get_lset(const@%p)\n", pjlink); - - return &lnkConst_lset; -} - - -/* Report outputs: - * 'const': integer 21 - * 'const': double 5.23 - * 'const': string "something" - * 'const': array of 999 integers - * [1, 2, 3] - * 'const': array of 1 double - * [1.2345] - * 'const': array of 2 strings - * ["hello", "world"] - * - * Array values are only printed at level 2 - * because there might be quite a few of them. - */ - -static void lnkConst_report(const jlink *pjlink, int level, int indent) -{ - const_link *clink = CONTAINER(pjlink, const_link, jlink); - const char * const type_names[4] = { - "bug", "integer", "double", "string" - }; - const char * const dtype = type_names[clink->type & 3]; - - IFDEBUG(10) - printf("lnkConst_report(const@%p)\n", clink); - - if (clink->type > a0) { - const char * const plural = clink->nElems > 1 ? "s" : ""; - - printf("%*s'const': array of %d %s%s", indent, "", - clink->nElems, dtype, plural); - - if (level < 2) { - putchar('\n'); - } - else { - int i; - - switch (clink->type) { - case ai32: - printf("\n%*s[%d", indent+2, "", clink->value.pintegers[0]); - for (i = 1; i < clink->nElems; i++) { - printf(", %d", clink->value.pintegers[i]); - } - break; - case af64: - printf("\n%*s[%g", indent+2, "", clink->value.pdoubles[0]); - for (i = 1; i < clink->nElems; i++) { - printf(", %g", clink->value.pdoubles[i]); - } - break; - case ac40: - printf("\n%*s[\"%s\"", indent+2, "", clink->value.pstrings[0]); - for (i = 1; i < clink->nElems; i++) { - printf(", \"%s\"", clink->value.pstrings[i]); - } - break; - default: - break; - } - printf("]\n"); - } - return; - } - - printf("%*s'const': %s", indent, "", dtype); - - switch (clink->type) { - case si32: - printf(" %d\n", clink->value.scalar_integer); - return; - case sf64: - printf(" %g\n", clink->value.scalar_double); - return; - case sc40: - printf(" \"%s\"\n", clink->value.scalar_string); - return; - default: - printf(" -- type=%d\n", clink->type); - return; - } -} - -/*************************** lset Routines **************************/ - -static void lnkConst_remove(struct dbLocker *locker, struct link *plink) -{ - const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink); - - IFDEBUG(10) - printf("lnkConst_remove(const@%p)\n", clink); - - lnkConst_free(plink->value.json.jlink); -} - -static long lnkConst_loadScalar(struct link *plink, short dbrType, void *pbuffer) -{ - const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink); - long status; - - IFDEBUG(10) - printf("lnkConst_loadScalar(const@%p, %d, %p)\n", - clink, dbrType, pbuffer); - - switch (clink->type) { - case si32: - status = dbFastPutConvertRoutine[DBF_LONG][dbrType] - (&clink->value.scalar_integer, pbuffer, NULL); - break; - - case sf64: - status = dbFastPutConvertRoutine[DBF_DOUBLE][dbrType] - (&clink->value.scalar_double, pbuffer, NULL); - break; - - case sc40: - status = dbFastPutConvertRoutine[DBF_STRING][dbrType] - (clink->value.scalar_string, pbuffer, NULL); - break; - - case ai32: - status = dbFastPutConvertRoutine[DBF_LONG][dbrType] - (clink->value.pintegers, pbuffer, NULL); - break; - - case af64: - status = dbFastPutConvertRoutine[DBF_DOUBLE][dbrType] - (clink->value.pdoubles, pbuffer, NULL); - break; - - case ac40: - status = dbFastPutConvertRoutine[DBF_STRING][dbrType] - (clink->value.pstrings[0], pbuffer, NULL); - break; - - default: - status = S_db_badField; - break; - } - - return status; -} - -static long lnkConst_loadLS(struct link *plink, char *pbuffer, epicsUInt32 size, - epicsUInt32 *plen) -{ - const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink); - const char *pstr; - - IFDEBUG(10) - printf("lnkConst_loadLS(const@%p, %p, %d, %d)\n", - clink, pbuffer, size, *plen); - - if(!size) return 0; - - switch (clink->type) { - case sc40: - pstr = clink->value.scalar_string; - break; - - case ac40: - pstr = clink->value.pstrings[0]; - break; - - default: - return S_db_badField; - } - - strncpy(pbuffer, pstr, --size); - pbuffer[size] = 0; - *plen = (epicsUInt32) strlen(pbuffer) + 1; - return 0; -} - -static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer, - long *pnReq) -{ - const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink); - short dbrSize = dbValueSize(dbrType); - char *pdest = pbuffer; - int nElems = clink->nElems; - FASTCONVERT conv; - long status; - - IFDEBUG(10) - printf("lnkConst_loadArray(const@%p, %d, %p, (%ld))\n", - clink, dbrType, pbuffer, *pnReq); - - if (nElems > *pnReq) - nElems = *pnReq; - - switch (clink->type) { - int i; - - case si32: - status = dbFastPutConvertRoutine[DBF_LONG][dbrType] - (&clink->value.scalar_integer, pdest, NULL); - break; - - case sf64: - status = dbFastPutConvertRoutine[DBF_DOUBLE][dbrType] - (&clink->value.scalar_double, pdest, NULL); - break; - - case sc40: - status = dbFastPutConvertRoutine[DBF_STRING][dbrType] - (clink->value.scalar_string, pbuffer, NULL); - break; - - case ai32: - conv = dbFastPutConvertRoutine[DBF_LONG][dbrType]; - for (i = 0; i < nElems; i++) { - conv(&clink->value.pintegers[i], pdest, NULL); - pdest += dbrSize; - } - status = 0; - break; - - case af64: - conv = dbFastPutConvertRoutine[DBF_DOUBLE][dbrType]; - for (i = 0; i < nElems; i++) { - conv(&clink->value.pdoubles[i], pdest, NULL); - pdest += dbrSize; - } - status = 0; - break; - - case ac40: - conv = dbFastPutConvertRoutine[DBF_STRING][dbrType]; - for (i = 0; i < nElems; i++) { - conv(clink->value.pstrings[i], pdest, NULL); - pdest += dbrSize; - } - status = 0; - break; - - default: - status = S_db_badField; - } - *pnReq = nElems; - return status; -} - -static long lnkConst_getNelements(const struct link *plink, long *nelements) -{ - const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink); - - IFDEBUG(10) - printf("lnkConst_getNelements(const@%p, (%ld))\n", - plink->value.json.jlink, *nelements); - - *nelements = 0; - return 0; -} - -static long lnkConst_getValue(struct link *plink, short dbrType, void *pbuffer, - long *pnRequest) -{ - const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink); - - IFDEBUG(10) - printf("lnkConst_getValue(const@%p, %d, %p, ... (%ld))\n", - plink->value.json.jlink, dbrType, pbuffer, *pnRequest); - - if (pnRequest) - *pnRequest = 0; - return 0; -} - - -/************************* Interface Tables *************************/ - -static lset lnkConst_lset = { - 1, 0, /* Constant, not Volatile */ - NULL, lnkConst_remove, - lnkConst_loadScalar, lnkConst_loadLS, lnkConst_loadArray, NULL, - NULL, lnkConst_getNelements, lnkConst_getValue, - NULL, NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL, - NULL, NULL -}; - -static jlif lnkConstIf = { - "const", lnkConst_alloc, lnkConst_free, - NULL, lnkConst_boolean, lnkConst_integer, lnkConst_double, lnkConst_string, - NULL, NULL, NULL, - lnkConst_start_array, lnkConst_end_array, - NULL, lnkConst_get_lset, - lnkConst_report, NULL -}; -epicsExportAddress(jlif, lnkConstIf); - diff --git a/src/std/rec/Makefile b/src/std/rec/Makefile deleted file mode 100644 index 561058620..000000000 --- a/src/std/rec/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# This is a Makefile fragment, see src/std/Makefile. - -SRC_DIRS += $(STDDIR)/rec - -stdRecords += aaiRecord -stdRecords += aaoRecord -stdRecords += aiRecord -stdRecords += aoRecord -stdRecords += aSubRecord -stdRecords += biRecord -stdRecords += boRecord -stdRecords += calcRecord -stdRecords += calcoutRecord -stdRecords += compressRecord -stdRecords += dfanoutRecord -stdRecords += eventRecord -stdRecords += fanoutRecord -stdRecords += histogramRecord -stdRecords += int64inRecord -stdRecords += int64outRecord -stdRecords += longinRecord -stdRecords += longoutRecord -stdRecords += lsiRecord -stdRecords += lsoRecord -stdRecords += mbbiRecord -stdRecords += mbbiDirectRecord -stdRecords += mbboRecord -stdRecords += mbboDirectRecord -stdRecords += permissiveRecord -stdRecords += printfRecord -stdRecords += selRecord -stdRecords += seqRecord -stdRecords += stateRecord -stdRecords += stringinRecord -stdRecords += stringoutRecord -stdRecords += subRecord -stdRecords += subArrayRecord -stdRecords += waveformRecord - -DBDINC += $(stdRecords) - -# Generate stdRecords.dbd, not really by concatenation, see RULES -DBDCAT += stdRecords.dbd -stdRecords_DBD = $(patsubst %,%.dbd,$(stdRecords)) - -dbRecStd_SRCS += $(patsubst %,%.c,$(stdRecords)) - -HTMLS += $(patsubst %.dbd.pod,%.html,$(notdir $(wildcard ../rec/*Record.dbd.pod))) diff --git a/src/std/rec/RULES b/src/std/rec/RULES deleted file mode 100644 index 81e9a8c1d..000000000 --- a/src/std/rec/RULES +++ /dev/null @@ -1,18 +0,0 @@ -########################################################################## -# Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -########################################################################## - -# This is a Makefile fragment, see src/ioc/Makefile. - -stdRecords.dbd$(DEP): $(STDDIR)/rec/Makefile $(STDDIR)/rec/RULES - @$(RM) $@ - @echo "$(COMMON_DIR)/stdRecords.dbd:" > $@ - -$(COMMON_DIR)/stdRecords.dbd: $(STDDIR)/rec/Makefile $(STDDIR)/rec/RULES - -# This is a target-specific variable -$(COMMON_DIR)/stdRecords.dbd: DBDCAT_COMMAND = \ - $(PERL) $(TOOLS)/makeIncludeDbd.pl $(stdRecords_DBD) $(@F) diff --git a/src/std/rec/aSubRecord.c b/src/std/rec/aSubRecord.c deleted file mode 100644 index b513df17a..000000000 --- a/src/std/rec/aSubRecord.c +++ /dev/null @@ -1,566 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Record Support Routines for the Array Subroutine Record type, - * derived from Andy Foster's genSub record, with some features - * removed and asynchronous support added. - * - * Original Author: Andy Foster - * Revised by: Andrew Johnson - * - */ - -#include -#include -#include - -#include "alarm.h" -#include "cantProceed.h" -#include "dbDefs.h" -#include "dbEvent.h" -#include "dbAccess.h" -#include "dbFldTypes.h" -#include "dbStaticLib.h" -#include "errMdef.h" -#include "errlog.h" -#include "recSup.h" -#include "devSup.h" -#include "special.h" -#include "registryFunction.h" -#include "recGbl.h" -#define GEN_SIZE_OFFSET -#include "aSubRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - - -typedef long (*GENFUNCPTR)(struct aSubRecord *); - -/* Create RSET - Record Support Entry Table*/ - -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -static long get_array_info(DBADDR *, long *, long *); -static long put_array_info(DBADDR *, long ); -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset aSubRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, aSubRSET); - -static long initFields(epicsEnum16 *pft, epicsUInt32 *pno, epicsUInt32 *pne, - epicsUInt32 *pon, const char **fldnames, void **pval, void **povl); -static long fetch_values(aSubRecord *prec); -static void monitor(aSubRecord *); -static long do_sub(aSubRecord *); - -#define NUM_ARGS 21 - -/* These are the names of the Input fields */ -static const char *Ifldnames[] = { - "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", - "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U" -}; - -/* These are the names of the Output fields */ -static const char *Ofldnames[] = { - "VALA", "VALB", "VALC", "VALD", "VALE", "VALF", "VALG", - "VALH", "VALI", "VALJ", "VALK", "VALL", "VALM", "VALN", - "VALO", "VALP", "VALQ", "VALR", "VALS", "VALT", "VALU" -}; - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct aSubRecord *prec = (struct aSubRecord *)pcommon; - STATIC_ASSERT(sizeof(prec->onam)==sizeof(prec->snam)); - GENFUNCPTR pfunc; - int i; - - if (pass == 0) { - /* Allocate memory for arrays */ - initFields(&prec->fta, &prec->noa, &prec->nea, NULL, - Ifldnames, &prec->a, NULL); - initFields(&prec->ftva, &prec->nova, &prec->neva, &prec->onva, - Ofldnames, &prec->vala, &prec->ovla); - return 0; - } - - /* Initialize the Subroutine Name Link */ - recGblInitConstantLink(&prec->subl, DBF_STRING, prec->snam); - - /* Initialize Input Links */ - for (i = 0; i < NUM_ARGS; i++) { - struct link *plink = &(&prec->inpa)[i]; - short dbr = (&prec->fta)[i]; - long n = (&prec->noa)[i]; - - dbLoadLinkArray(plink, dbr, (&prec->a)[i], &n); - if (n > 0) - (&prec->nea)[i] = n; - } - - /* Call the user initialization routine if there is one */ - if (prec->inam[0] != 0) { - pfunc = (GENFUNCPTR)registryFunctionFind(prec->inam); - if (pfunc) { - pfunc(prec); - } else { - recGblRecordError(S_db_BadSub, (void *)prec, - "aSubRecord::init_record - INAM subr not found"); - return S_db_BadSub; - } - } - - if (prec->lflg == aSubLFLG_IGNORE && - prec->snam[0] != 0) { - pfunc = (GENFUNCPTR)registryFunctionFind(prec->snam); - if (pfunc) - prec->sadr = pfunc; - else { - recGblRecordError(S_db_BadSub, (void *)prec, - "aSubRecord::init_record - SNAM subr not found"); - return S_db_BadSub; - } - } - strcpy(prec->onam, prec->snam); - prec->oval = prec->val; - return 0; -} - - -static long initFields(epicsEnum16 *pft, epicsUInt32 *pno, epicsUInt32 *pne, - epicsUInt32 *pon, const char **fldnames, void **pval, void **povl) -{ - int i; - long status = 0; - - for (i = 0; i < NUM_ARGS; i++, pft++, pno++, pne++, pval++) { - epicsUInt32 num; - epicsUInt32 flen; - - if (*pft > DBF_ENUM) - *pft = DBF_CHAR; - - if (*pno == 0) - *pno = 1; - - flen = dbValueSize(*pft); - num = *pno * flen; - *pval = callocMustSucceed(*pno, flen, "aSubRecord::init_record"); - - *pne = *pno; - - if (povl) { - if (num) - *povl = callocMustSucceed(*pno, flen, - "aSubRecord::init_record"); - povl++; - *pon++ = *pne; - } - } - return status; -} - - -static long process(struct dbCommon *pcommon) -{ - struct aSubRecord *prec = (struct aSubRecord *)pcommon; - int pact = prec->pact; - long status = 0; - - if (!pact) { - prec->pact = TRUE; - status = fetch_values(prec); - prec->pact = FALSE; - } - - if (!status) { - status = do_sub(prec); - prec->val = status; - } - - if (!pact && prec->pact) - return 0; - - prec->pact = TRUE; - - /* Push the output link values */ - if (!status) { - int i; - - for (i = 0; i < NUM_ARGS; i++) - dbPutLink(&(&prec->outa)[i], (&prec->ftva)[i], (&prec->vala)[i], - (&prec->neva)[i]); - } - - recGblGetTimeStamp(prec); - monitor(prec); - recGblFwdLink(prec); - prec->pact = FALSE; - - return 0; -} - -static long fetch_values(aSubRecord *prec) -{ - long status; - int i; - - if (prec->lflg == aSubLFLG_READ) { - /* Get the Subroutine Name and look it up if changed */ - status = dbGetLink(&prec->subl, DBR_STRING, prec->snam, 0, 0); - if (status) - return status; - - if (prec->snam[0] != 0 && - strcmp(prec->snam, prec->onam)) { - GENFUNCPTR pfunc = (GENFUNCPTR)registryFunctionFind(prec->snam); - - if (!pfunc) - return S_db_BadSub; - - if (prec->sadr!=pfunc && prec->cadr) { - prec->cadr(prec); - prec->cadr = NULL; - } - - prec->sadr = pfunc; - strcpy(prec->onam, prec->snam); - } - } - - /* Get the input link values */ - for (i = 0; i < NUM_ARGS; i++) { - long nRequest = (&prec->noa)[i]; - status = dbGetLink(&(&prec->inpa)[i], (&prec->fta)[i], (&prec->a)[i], 0, - &nRequest); - if (nRequest > 0) - (&prec->nea)[i] = nRequest; - if (status) - return status; - } - return 0; -} - -#define indexof(field) aSubRecord##field - -static long get_inlinkNumber(int fieldIndex) { - if (fieldIndex >= indexof(A) && fieldIndex <= indexof(U)) - return fieldIndex - indexof(A); - return -1; -} - -static long get_outlinkNumber(int fieldIndex) { - if (fieldIndex >= indexof(VALA) && fieldIndex <= indexof(VALU)) - return fieldIndex - indexof(VALA); - return -1; -} - -static long get_units(DBADDR *paddr, char *units) -{ - aSubRecord *prec = (aSubRecord *)paddr->precord; - int linkNumber; - - linkNumber = get_inlinkNumber(dbGetFieldIndex(paddr)); - if (linkNumber >= 0) { - dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE); - return 0; - } - linkNumber = get_outlinkNumber(dbGetFieldIndex(paddr)); - if (linkNumber >= 0) { - dbGetUnits(&prec->outa + linkNumber, units, DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *pprecision) -{ - aSubRecord *prec = (aSubRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - *pprecision = prec->prec; - linkNumber = get_inlinkNumber(fieldIndex); - if (linkNumber >= 0) { - short precision; - - if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0) - *pprecision = precision; - return 0; - } - - linkNumber = get_outlinkNumber(fieldIndex); - if (linkNumber >= 0) { - short precision; - - if (dbGetPrecision(&prec->outa + linkNumber, &precision) == 0) - *pprecision = precision; - } else - recGblGetPrec(paddr, pprecision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - aSubRecord *prec = (aSubRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - linkNumber = get_inlinkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetGraphicLimits(&prec->inpa + linkNumber, - &pgd->lower_disp_limit, - &pgd->upper_disp_limit); - return 0; - } - linkNumber = get_outlinkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetGraphicLimits(&prec->outa + linkNumber, - &pgd->lower_disp_limit, - &pgd->upper_disp_limit); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - recGblGetControlDouble(paddr,pcd); - return 0; -} - -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - aSubRecord *prec = (aSubRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - linkNumber = get_inlinkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetAlarmLimits(&prec->inpa + linkNumber, - &pad->lower_alarm_limit, - &pad->lower_warning_limit, - &pad->upper_warning_limit, - &pad->upper_alarm_limit); - return 0; - } - linkNumber = get_outlinkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetAlarmLimits(&prec->outa + linkNumber, - &pad->lower_alarm_limit, - &pad->lower_warning_limit, - &pad->upper_warning_limit, - &pad->upper_alarm_limit); - return 0; - } - recGblGetAlarmDouble(paddr, pad); - return 0; -} - -static void monitor(aSubRecord *prec) -{ - int i; - unsigned short monitor_mask; - - monitor_mask = recGblResetAlarms(prec) | DBE_VALUE | DBE_LOG; - - /* Post events for VAL field */ - if (prec->val != prec->oval) { - db_post_events(prec, &prec->val, monitor_mask); - prec->oval = prec->val; - } - - /* Event posting on VAL arrays depends on the setting of prec->eflg */ - switch (prec->eflg) { - case aSubEFLG_NEVER: - break; - case aSubEFLG_ON_CHANGE: - for (i = 0; i < NUM_ARGS; i++) { - void *povl = (&prec->ovla)[i]; - void *pval = (&prec->vala)[i]; - epicsUInt32 *ponv = &(&prec->onva)[i]; - epicsUInt32 *pnev = &(&prec->neva)[i]; - epicsUInt32 onv = *ponv; /* Num Elements in OVLx */ - epicsUInt32 nev = *pnev; /* Num Elements in VALx */ - epicsUInt32 alen = dbValueSize((&prec->ftva)[i]) * nev; - - if (nev != onv || memcmp(povl, pval, alen)) { - memcpy(povl, pval, alen); - db_post_events(prec, pval, monitor_mask); - if (nev != onv) { - *ponv = nev; - db_post_events(prec, pnev, monitor_mask); - } - } - } - break; - case aSubEFLG_ALWAYS: - for (i = 0; i < NUM_ARGS; i++) { - db_post_events(prec, (&prec->vala)[i], monitor_mask); - db_post_events(prec, &(&prec->neva)[i], monitor_mask); - } - break; - } - return; -} - - -static long do_sub(aSubRecord *prec) -{ - GENFUNCPTR pfunc = prec->sadr; - long status; - - if (prec->snam[0] == 0) - return 0; - - if (pfunc == NULL) { - recGblSetSevr(prec, BAD_SUB_ALARM, INVALID_ALARM); - return S_db_BadSub; - } - status = pfunc(prec); - if (status < 0) - recGblSetSevr(prec, SOFT_ALARM, prec->brsv); - else - prec->udf = FALSE; - - return status; -} - - -static long cvt_dbaddr(DBADDR *paddr) -{ - aSubRecord *prec = (aSubRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (fieldIndex >= aSubRecordA && - fieldIndex <= aSubRecordU) { - int offset = fieldIndex - aSubRecordA; - - paddr->pfield = (&prec->a )[offset]; - paddr->no_elements = (&prec->noa)[offset]; - paddr->field_type = (&prec->fta)[offset]; - } - else if (fieldIndex >= aSubRecordVALA && - fieldIndex <= aSubRecordVALU) { - int offset = fieldIndex - aSubRecordVALA; - - paddr->pfield = (&prec->vala)[offset]; - paddr->no_elements = (&prec->nova)[offset]; - paddr->field_type = (&prec->ftva)[offset]; - } - else { - errlogPrintf("aSubRecord::cvt_dbaddr called for %s.%s\n", - prec->name, paddr->pfldDes->name); - return 0; - } - paddr->dbr_field_type = paddr->field_type; - paddr->field_size = dbValueSize(paddr->field_type); - return 0; -} - - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - aSubRecord *prec = (aSubRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (fieldIndex >= aSubRecordA && - fieldIndex <= aSubRecordU) { - *no_elements = (&prec->nea)[fieldIndex - aSubRecordA]; - } - else if (fieldIndex >= aSubRecordVALA && - fieldIndex <= aSubRecordVALU) { - *no_elements = (&prec->neva)[fieldIndex - aSubRecordVALA]; - } - else { - errlogPrintf("aSubRecord::get_array_info called for %s.%s\n", - prec->name, paddr->pfldDes->name); - } - *offset = 0; - - return 0; -} - - -static long put_array_info(DBADDR *paddr, long nNew) -{ - aSubRecord *prec = (aSubRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (fieldIndex >= aSubRecordA && - fieldIndex <= aSubRecordU) { - (&prec->nea)[fieldIndex - aSubRecordA] = nNew; - } - else if (fieldIndex >= aSubRecordVALA && - fieldIndex <= aSubRecordVALU) { - (&prec->neva)[fieldIndex - aSubRecordVALA] = nNew; - } - else { - errlogPrintf("aSubRecord::put_array_info called for %s.%s\n", - prec->name, paddr->pfldDes->name); - } - return 0; -} - - -static long special(DBADDR *paddr, int after) -{ - aSubRecord *prec = (aSubRecord *)paddr->precord; - long status = 0; - - if (after && - prec->lflg == aSubLFLG_IGNORE) { - GENFUNCPTR pfunc; - if (prec->snam[0] == 0) - pfunc = 0; - else { - pfunc = (GENFUNCPTR)registryFunctionFind(prec->snam); - if (!pfunc) { - status = S_db_BadSub; - recGblRecordError(status, (void *)prec, prec->snam); - } - } - - if (prec->sadr != pfunc && prec->cadr) { - prec->cadr(prec); - prec->cadr = NULL; - } - - prec->sadr = pfunc; - } - return status; -} diff --git a/src/std/rec/aSubRecord.dbd.pod b/src/std/rec/aSubRecord.dbd.pod deleted file mode 100644 index 73f734629..000000000 --- a/src/std/rec/aSubRecord.dbd.pod +++ /dev/null @@ -1,1931 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=title Array Subroutine Record (aSub) - -... - -=head2 Record-specific Menus - -=head3 Menu aSubLFLG - -The LFLG field uses this menu to ... - -=menu aSubLFLG - -=head3 Menu aSubEFLG - -The EFLG field uses this menu to ... - -=menu aSubEFLG - -... - -=head2 Parameter Fields - -The record-specific fields are described below. - -=recordtype aSub - -... - -=cut - -menu(aSubLFLG) { - choice(aSubLFLG_IGNORE,"IGNORE") - choice(aSubLFLG_READ,"READ") -} - -menu(aSubEFLG) { - choice(aSubEFLG_NEVER,"NEVER") - choice(aSubEFLG_ON_CHANGE,"ON CHANGE") - choice(aSubEFLG_ALWAYS,"ALWAYS") -} - -recordtype(aSub) { - include "dbCommon.dbd" - field(VAL,DBF_LONG) { - prompt("Subr. return value") - asl(ASL0) - } - field(OVAL,DBF_LONG) { - prompt("Old return value") - special(SPC_NOMOD) - interest(3) - } - field(INAM,DBF_STRING) { - prompt("Initialize Subr. Name") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - size(41) - } - field(LFLG,DBF_MENU) { - prompt("Subr. Input Enable") - promptgroup("30 - Action") - interest(1) - menu(aSubLFLG) - } - field(SUBL,DBF_INLINK) { - prompt("Subroutine Name Link") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - } - field(SNAM,DBF_STRING) { - prompt("Process Subr. Name") - promptgroup("30 - Action") - special(SPC_MOD) - interest(1) - size(41) - } - field(ONAM,DBF_STRING) { - prompt("Old Subr. Name") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(3) - size(41) - } - %struct aSubRecord; - field(SADR,DBF_NOACCESS) { - prompt("Subroutine Address") - special(SPC_NOMOD) - interest(2) - extra("long (*sadr)(struct aSubRecord *)") - } - field(CADR,DBF_NOACCESS) { - prompt("Subroutine Cleanup Address") - special(SPC_NOMOD) - interest(2) - extra("void (*cadr)(struct aSubRecord *)") - } - field(BRSV,DBF_MENU) { - prompt("Bad Return Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(EFLG,DBF_MENU) { - prompt("Output Event Flag") - promptgroup("50 - Output") - interest(1) - menu(aSubEFLG) - initial("1") - } - field(INPA,DBF_INLINK) { - prompt("Input Link A") - promptgroup("41 - Input A-G") - interest(1) - } - field(INPB,DBF_INLINK) { - prompt("Input Link B") - promptgroup("41 - Input A-G") - interest(1) - } - field(INPC,DBF_INLINK) { - prompt("Input Link C") - promptgroup("41 - Input A-G") - interest(1) - } - field(INPD,DBF_INLINK) { - prompt("Input Link D") - promptgroup("41 - Input A-G") - interest(1) - } - field(INPE,DBF_INLINK) { - prompt("Input Link E") - promptgroup("41 - Input A-G") - interest(1) - } - field(INPF,DBF_INLINK) { - prompt("Input Link F") - promptgroup("41 - Input A-G") - interest(1) - } - field(INPG,DBF_INLINK) { - prompt("Input Link G") - promptgroup("41 - Input A-G") - interest(1) - } - field(INPH,DBF_INLINK) { - prompt("Input Link H") - promptgroup("42 - Input H-N") - interest(1) - } - field(INPI,DBF_INLINK) { - prompt("Input Link I") - promptgroup("42 - Input H-N") - interest(1) - } - field(INPJ,DBF_INLINK) { - prompt("Input Link J") - promptgroup("42 - Input H-N") - interest(1) - } - field(INPK,DBF_INLINK) { - prompt("Input Link K") - promptgroup("42 - Input H-N") - interest(1) - } - field(INPL,DBF_INLINK) { - prompt("Input Link L") - promptgroup("42 - Input H-N") - interest(1) - } - field(INPM,DBF_INLINK) { - prompt("Input Link M") - promptgroup("42 - Input H-N") - interest(1) - } - field(INPN,DBF_INLINK) { - prompt("Input Link N") - promptgroup("42 - Input H-N") - interest(1) - } - field(INPO,DBF_INLINK) { - prompt("Input Link O") - promptgroup("43 - Input O-U") - interest(1) - } - field(INPP,DBF_INLINK) { - prompt("Input Link P") - promptgroup("43 - Input O-U") - interest(1) - } - field(INPQ,DBF_INLINK) { - prompt("Input Link Q") - promptgroup("43 - Input O-U") - interest(1) - } - field(INPR,DBF_INLINK) { - prompt("Input Link R") - promptgroup("43 - Input O-U") - interest(1) - } - field(INPS,DBF_INLINK) { - prompt("Input Link S") - promptgroup("43 - Input O-U") - interest(1) - } - field(INPT,DBF_INLINK) { - prompt("Input Link T") - promptgroup("43 - Input O-U") - interest(1) - } - field(INPU,DBF_INLINK) { - prompt("Input Link U") - promptgroup("43 - Input O-U") - interest(1) - } - -=head3 Input Fields - -... - -=fields A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U - -=cut - - field(A,DBF_NOACCESS) { - prompt("Input value A") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *a") - #=read Yes - #=write Yes - #=type Set by FTA - } - field(B,DBF_NOACCESS) { - prompt("Input value B") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *b") - #=read Yes - #=write Yes - #=type Set by FTB - } - field(C,DBF_NOACCESS) { - prompt("Input value C") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *c") - #=read Yes - #=write Yes - #=type Set by FTC - } - field(D,DBF_NOACCESS) { - prompt("Input value D") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *d") - #=read Yes - #=write Yes - #=type Set by FTD - } - field(E,DBF_NOACCESS) { - prompt("Input value E") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *e") - #=read Yes - #=write Yes - #=type Set by FTE - } - field(F,DBF_NOACCESS) { - prompt("Input value F") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *f") - #=read Yes - #=write Yes - #=type Set by FTF - } - field(G,DBF_NOACCESS) { - prompt("Input value G") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *g") - #=read Yes - #=write Yes - #=type Set by FTG - } - field(H,DBF_NOACCESS) { - prompt("Input value H") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *h") - #=read Yes - #=write Yes - #=type Set by FTH - } - field(I,DBF_NOACCESS) { - prompt("Input value I") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *i") - #=read Yes - #=write Yes - #=type Set by FTI - } - field(J,DBF_NOACCESS) { - prompt("Input value J") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *j") - #=read Yes - #=write Yes - #=type Set by FTJ - } - field(K,DBF_NOACCESS) { - prompt("Input value K") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *k") - #=read Yes - #=write Yes - #=type Set by FTK - } - field(L,DBF_NOACCESS) { - prompt("Input value L") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *l") - #=read Yes - #=write Yes - #=type Set by FTL - } - field(M,DBF_NOACCESS) { - prompt("Input value M") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *m") - #=read Yes - #=write Yes - #=type Set by FTM - } - field(N,DBF_NOACCESS) { - prompt("Input value N") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *n") - #=read Yes - #=write Yes - #=type Set by FTN - } - field(O,DBF_NOACCESS) { - prompt("Input value O") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *o") - #=read Yes - #=write Yes - #=type Set by FTO - } - field(P,DBF_NOACCESS) { - prompt("Input value P") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *p") - #=read Yes - #=write Yes - #=type Set by FTP - } - field(Q,DBF_NOACCESS) { - prompt("Input value Q") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *q") - #=read Yes - #=write Yes - #=type Set by FTQ - } - field(R,DBF_NOACCESS) { - prompt("Input value R") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *r") - #=read Yes - #=write Yes - #=type Set by FTR - } - field(S,DBF_NOACCESS) { - prompt("Input value S") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *s") - #=read Yes - #=write Yes - #=type Set by FTS - } - field(T,DBF_NOACCESS) { - prompt("Input value T") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *t") - #=read Yes - #=write Yes - #=type Set by FTT - } - field(U,DBF_NOACCESS) { - prompt("Input value U") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *u") - #=read Yes - #=write Yes - #=type Set by FTU - } - field(FTA,DBF_MENU) { - prompt("Type of A") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTB,DBF_MENU) { - prompt("Type of B") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTC,DBF_MENU) { - prompt("Type of C") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTD,DBF_MENU) { - prompt("Type of D") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTE,DBF_MENU) { - prompt("Type of E") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTF,DBF_MENU) { - prompt("Type of F") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTG,DBF_MENU) { - prompt("Type of G") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTH,DBF_MENU) { - prompt("Type of H") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTI,DBF_MENU) { - prompt("Type of I") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTJ,DBF_MENU) { - prompt("Type of J") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTK,DBF_MENU) { - prompt("Type of K") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTL,DBF_MENU) { - prompt("Type of L") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTM,DBF_MENU) { - prompt("Type of M") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTN,DBF_MENU) { - prompt("Type of N") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTO,DBF_MENU) { - prompt("Type of O") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTP,DBF_MENU) { - prompt("Type of P") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTQ,DBF_MENU) { - prompt("Type of Q") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTR,DBF_MENU) { - prompt("Type of R") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTS,DBF_MENU) { - prompt("Type of S") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTT,DBF_MENU) { - prompt("Type of T") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTU,DBF_MENU) { - prompt("Type of U") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(NOA,DBF_ULONG) { - prompt("Max. elements in A") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOB,DBF_ULONG) { - prompt("Max. elements in B") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOC,DBF_ULONG) { - prompt("Max. elements in C") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOD,DBF_ULONG) { - prompt("Max. elements in D") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOE,DBF_ULONG) { - prompt("Max. elements in E") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOF,DBF_ULONG) { - prompt("Max. elements in F") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOG,DBF_ULONG) { - prompt("Max. elements in G") - promptgroup("41 - Input A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOH,DBF_ULONG) { - prompt("Max. elements in H") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOI,DBF_ULONG) { - prompt("Max. elements in I") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOJ,DBF_ULONG) { - prompt("Max. elements in J") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOK,DBF_ULONG) { - prompt("Max. elements in K") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOL,DBF_ULONG) { - prompt("Max. elements in L") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOM,DBF_ULONG) { - prompt("Max. elements in M") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NON,DBF_ULONG) { - prompt("Max. elements in N") - promptgroup("42 - Input H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOO,DBF_ULONG) { - prompt("Max. elements in O") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOP,DBF_ULONG) { - prompt("Max. elements in P") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOQ,DBF_ULONG) { - prompt("Max. elements in Q") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOR,DBF_ULONG) { - prompt("Max. elements in R") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOS,DBF_ULONG) { - prompt("Max. elements in S") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOT,DBF_ULONG) { - prompt("Max. elements in T") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOU,DBF_ULONG) { - prompt("Max. elements in U") - promptgroup("43 - Input O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NEA,DBF_ULONG) { - prompt("Num. elements in A") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEB,DBF_ULONG) { - prompt("Num. elements in B") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEC,DBF_ULONG) { - prompt("Num. elements in C") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NED,DBF_ULONG) { - prompt("Num. elements in D") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEE,DBF_ULONG) { - prompt("Num. elements in E") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEF,DBF_ULONG) { - prompt("Num. elements in F") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEG,DBF_ULONG) { - prompt("Num. elements in G") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEH,DBF_ULONG) { - prompt("Num. elements in H") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEI,DBF_ULONG) { - prompt("Num. elements in I") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEJ,DBF_ULONG) { - prompt("Num. elements in J") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEK,DBF_ULONG) { - prompt("Num. elements in K") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEL,DBF_ULONG) { - prompt("Num. elements in L") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEM,DBF_ULONG) { - prompt("Num. elements in M") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEN,DBF_ULONG) { - prompt("Num. elements in N") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEO,DBF_ULONG) { - prompt("Num. elements in O") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEP,DBF_ULONG) { - prompt("Num. elements in P") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEQ,DBF_ULONG) { - prompt("Num. elements in Q") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NER,DBF_ULONG) { - prompt("Num. elements in R") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NES,DBF_ULONG) { - prompt("Num. elements in S") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NET,DBF_ULONG) { - prompt("Num. elements in T") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEU,DBF_ULONG) { - prompt("Num. elements in U") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(OUTA,DBF_OUTLINK) { - prompt("Output Link A") - promptgroup("51 - Output A-G") - interest(1) - } - field(OUTB,DBF_OUTLINK) { - prompt("Output Link B") - promptgroup("51 - Output A-G") - interest(1) - } - field(OUTC,DBF_OUTLINK) { - prompt("Output Link C") - promptgroup("51 - Output A-G") - interest(1) - } - field(OUTD,DBF_OUTLINK) { - prompt("Output Link D") - promptgroup("51 - Output A-G") - interest(1) - } - field(OUTE,DBF_OUTLINK) { - prompt("Output Link E") - promptgroup("51 - Output A-G") - interest(1) - } - field(OUTF,DBF_OUTLINK) { - prompt("Output Link F") - promptgroup("51 - Output A-G") - interest(1) - } - field(OUTG,DBF_OUTLINK) { - prompt("Output Link G") - promptgroup("51 - Output A-G") - interest(1) - } - field(OUTH,DBF_OUTLINK) { - prompt("Output Link H") - promptgroup("52 - Output H-N") - interest(1) - } - field(OUTI,DBF_OUTLINK) { - prompt("Output Link I") - promptgroup("52 - Output H-N") - interest(1) - } - field(OUTJ,DBF_OUTLINK) { - prompt("Output Link J") - promptgroup("52 - Output H-N") - interest(1) - } - field(OUTK,DBF_OUTLINK) { - prompt("Output Link K") - promptgroup("52 - Output H-N") - interest(1) - } - field(OUTL,DBF_OUTLINK) { - prompt("Output Link L") - promptgroup("52 - Output H-N") - interest(1) - } - field(OUTM,DBF_OUTLINK) { - prompt("Output Link M") - promptgroup("52 - Output H-N") - interest(1) - } - field(OUTN,DBF_OUTLINK) { - prompt("Output Link N") - promptgroup("52 - Output H-N") - interest(1) - } - field(OUTO,DBF_OUTLINK) { - prompt("Output Link O") - promptgroup("53 - Output O-U") - interest(1) - } - field(OUTP,DBF_OUTLINK) { - prompt("Output Link P") - promptgroup("53 - Output O-U") - interest(1) - } - field(OUTQ,DBF_OUTLINK) { - prompt("Output Link Q") - promptgroup("53 - Output O-U") - interest(1) - } - field(OUTR,DBF_OUTLINK) { - prompt("Output Link R") - promptgroup("53 - Output O-U") - interest(1) - } - field(OUTS,DBF_OUTLINK) { - prompt("Output Link S") - promptgroup("53 - Output O-U") - interest(1) - } - field(OUTT,DBF_OUTLINK) { - prompt("Output Link T") - promptgroup("53 - Output O-U") - interest(1) - } - field(OUTU,DBF_OUTLINK) { - prompt("Output Link U") - promptgroup("53 - Output O-U") - interest(1) - } - -=head3 Value Fields - -... - -=fields VALA, VALB, VALC, VALD, VALE, VALF, VALG, VALH, VALI, VALJ, VALK, VALL, VALM, VALN, VALO, VALP, VALQ, VALR, VALS, VALT, VALU - -=cut - - field(VALA,DBF_NOACCESS) { - prompt("Output value A") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *vala") - #=read Yes - #=write Yes - #=type Set by FTVA - } - field(VALB,DBF_NOACCESS) { - prompt("Output value B") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valb") - #=read Yes - #=write Yes - #=type Set by FTVB - } - field(VALC,DBF_NOACCESS) { - prompt("Output value C") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valc") - #=read Yes - #=write Yes - #=type Set by FTVC - } - field(VALD,DBF_NOACCESS) { - prompt("Output value D") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *vald") - #=read Yes - #=write Yes - #=type Set by FTVD - } - field(VALE,DBF_NOACCESS) { - prompt("Output value E") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *vale") - #=read Yes - #=write Yes - #=type Set by FTVE - } - field(VALF,DBF_NOACCESS) { - prompt("Output value F") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valf") - #=read Yes - #=write Yes - #=type Set by FTVF - } - field(VALG,DBF_NOACCESS) { - prompt("Output value G") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valg") - #=read Yes - #=write Yes - #=type Set by FTVG - } - field(VALH,DBF_NOACCESS) { - prompt("Output value H") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valh") - #=read Yes - #=write Yes - #=type Set by FTVH - } - field(VALI,DBF_NOACCESS) { - prompt("Output value I") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *vali") - #=read Yes - #=write Yes - #=type Set by FTVI - } - field(VALJ,DBF_NOACCESS) { - prompt("Output value J") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valj") - #=read Yes - #=write Yes - #=type Set by FTVJ - } - field(VALK,DBF_NOACCESS) { - prompt("Output value K") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valk") - #=read Yes - #=write Yes - #=type Set by FTVK - } - field(VALL,DBF_NOACCESS) { - prompt("Output value L") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *vall") - #=read Yes - #=write Yes - #=type Set by FTVL - } - field(VALM,DBF_NOACCESS) { - prompt("Output value M") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valm") - #=read Yes - #=write Yes - #=type Set by FTVM - } - field(VALN,DBF_NOACCESS) { - prompt("Output value N") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valn") - #=read Yes - #=write Yes - #=type Set by FTVN - } - field(VALO,DBF_NOACCESS) { - prompt("Output value O") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valo") - #=read Yes - #=write Yes - #=type Set by FTVO - } - field(VALP,DBF_NOACCESS) { - prompt("Output value P") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valp") - #=read Yes - #=write Yes - #=type Set by FTVP - } - field(VALQ,DBF_NOACCESS) { - prompt("Output value Q") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valq") - #=read Yes - #=write Yes - #=type Set by FTVQ - } - field(VALR,DBF_NOACCESS) { - prompt("Output value R") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valr") - #=read Yes - #=write Yes - #=type Set by FTVR - } - field(VALS,DBF_NOACCESS) { - prompt("Output value S") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *vals") - #=read Yes - #=write Yes - #=type Set by FTVS - } - field(VALT,DBF_NOACCESS) { - prompt("Output value T") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valt") - #=read Yes - #=write Yes - #=type Set by FTVT - } - field(VALU,DBF_NOACCESS) { - prompt("Output value U") - asl(ASL0) - special(SPC_DBADDR) - interest(2) - extra("void *valu") - #=read Yes - #=write Yes - #=type Set by FTVU - } - field(OVLA,DBF_NOACCESS) { - prompt("Old Output A") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovla") - } - field(OVLB,DBF_NOACCESS) { - prompt("Old Output B") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlb") - } - field(OVLC,DBF_NOACCESS) { - prompt("Old Output C") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlc") - } - field(OVLD,DBF_NOACCESS) { - prompt("Old Output D") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovld") - } - field(OVLE,DBF_NOACCESS) { - prompt("Old Output E") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovle") - } - field(OVLF,DBF_NOACCESS) { - prompt("Old Output F") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlf") - } - field(OVLG,DBF_NOACCESS) { - prompt("Old Output G") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlg") - } - field(OVLH,DBF_NOACCESS) { - prompt("Old Output H") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlh") - } - field(OVLI,DBF_NOACCESS) { - prompt("Old Output I") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovli") - } - field(OVLJ,DBF_NOACCESS) { - prompt("Old Output J") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlj") - } - field(OVLK,DBF_NOACCESS) { - prompt("Old Output K") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlk") - } - field(OVLL,DBF_NOACCESS) { - prompt("Old Output L") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovll") - } - field(OVLM,DBF_NOACCESS) { - prompt("Old Output M") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlm") - } - field(OVLN,DBF_NOACCESS) { - prompt("Old Output N") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovln") - } - field(OVLO,DBF_NOACCESS) { - prompt("Old Output O") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlo") - } - field(OVLP,DBF_NOACCESS) { - prompt("Old Output P") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlp") - } - field(OVLQ,DBF_NOACCESS) { - prompt("Old Output Q") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlq") - } - field(OVLR,DBF_NOACCESS) { - prompt("Old Output R") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlr") - } - field(OVLS,DBF_NOACCESS) { - prompt("Old Output S") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovls") - } - field(OVLT,DBF_NOACCESS) { - prompt("Old Output T") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlt") - } - field(OVLU,DBF_NOACCESS) { - prompt("Old Output U") - asl(ASL0) - special(SPC_NOMOD) - interest(4) - extra("void *ovlu") - } - field(FTVA,DBF_MENU) { - prompt("Type of VALA") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVB,DBF_MENU) { - prompt("Type of VALB") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVC,DBF_MENU) { - prompt("Type of VALC") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVD,DBF_MENU) { - prompt("Type of VALD") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVE,DBF_MENU) { - prompt("Type of VALE") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVF,DBF_MENU) { - prompt("Type of VALF") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVG,DBF_MENU) { - prompt("Type of VALG") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVH,DBF_MENU) { - prompt("Type of VALH") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVI,DBF_MENU) { - prompt("Type of VALI") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVJ,DBF_MENU) { - prompt("Type of VALJ") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVK,DBF_MENU) { - prompt("Type of VALK") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVL,DBF_MENU) { - prompt("Type of VALL") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVM,DBF_MENU) { - prompt("Type of VALM") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVN,DBF_MENU) { - prompt("Type of VALN") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVO,DBF_MENU) { - prompt("Type of VALO") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVP,DBF_MENU) { - prompt("Type of VALP") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVQ,DBF_MENU) { - prompt("Type of VALQ") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVR,DBF_MENU) { - prompt("Type of VALR") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVS,DBF_MENU) { - prompt("Type of VALS") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVT,DBF_MENU) { - prompt("Type of VALT") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(FTVU,DBF_MENU) { - prompt("Type of VALU") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("DOUBLE") - menu(menuFtype) - } - field(NOVA,DBF_ULONG) { - prompt("Max. elements in VALA") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVB,DBF_ULONG) { - prompt("Max. elements in VALB") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVC,DBF_ULONG) { - prompt("Max. elements in VALC") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVD,DBF_ULONG) { - prompt("Max. elements in VALD") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVE,DBF_ULONG) { - prompt("Max. elements in VALE") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVF,DBF_ULONG) { - prompt("Max. elements in VALF") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVG,DBF_ULONG) { - prompt("Max. elements in VALG") - promptgroup("51 - Output A-G") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVH,DBF_ULONG) { - prompt("Max. elements in VAlH") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVI,DBF_ULONG) { - prompt("Max. elements in VALI") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVJ,DBF_ULONG) { - prompt("Max. elements in VALJ") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVK,DBF_ULONG) { - prompt("Max. elements in VALK") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVL,DBF_ULONG) { - prompt("Max. elements in VALL") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVM,DBF_ULONG) { - prompt("Max. elements in VALM") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVN,DBF_ULONG) { - prompt("Max. elements in VALN") - promptgroup("52 - Output H-N") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVO,DBF_ULONG) { - prompt("Max. elements in VALO") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVP,DBF_ULONG) { - prompt("Max. elements in VALP") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVQ,DBF_ULONG) { - prompt("Max. elements in VALQ") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVR,DBF_ULONG) { - prompt("Max. elements in VALR") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVS,DBF_ULONG) { - prompt("Max. elements in VALS") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVT,DBF_ULONG) { - prompt("Max. elements in VALT") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NOVU,DBF_ULONG) { - prompt("Max. elements in VALU") - promptgroup("53 - Output O-U") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NEVA,DBF_ULONG) { - prompt("Num. elements in VALA") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVB,DBF_ULONG) { - prompt("Num. elements in VALB") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVC,DBF_ULONG) { - prompt("Num. elements in VALC") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVD,DBF_ULONG) { - prompt("Num. elements in VALD") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVE,DBF_ULONG) { - prompt("Num. elements in VALE") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVF,DBF_ULONG) { - prompt("Num. elements in VALF") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVG,DBF_ULONG) { - prompt("Num. elements in VALG") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVH,DBF_ULONG) { - prompt("Num. elements in VAlH") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVI,DBF_ULONG) { - prompt("Num. elements in VALI") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVJ,DBF_ULONG) { - prompt("Num. elements in VALJ") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVK,DBF_ULONG) { - prompt("Num. elements in VALK") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVL,DBF_ULONG) { - prompt("Num. elements in VALL") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVM,DBF_ULONG) { - prompt("Num. elements in VALM") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVN,DBF_ULONG) { - prompt("Num. elements in VALN") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVO,DBF_ULONG) { - prompt("Num. elements in VALO") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVP,DBF_ULONG) { - prompt("Num. elements in VALP") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVQ,DBF_ULONG) { - prompt("Num. elements in VALQ") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVR,DBF_ULONG) { - prompt("Num. elements in VALR") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVS,DBF_ULONG) { - prompt("Num. elements in VALS") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVT,DBF_ULONG) { - prompt("Num. elements in VALT") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(NEVU,DBF_ULONG) { - prompt("Num. elements in VALU") - special(SPC_NOMOD) - interest(3) - initial("1") - } - field(ONVA,DBF_ULONG) { - prompt("Num. elements in OVLA") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVB,DBF_ULONG) { - prompt("Num. elements in OVLB") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVC,DBF_ULONG) { - prompt("Num. elements in OVLC") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVD,DBF_ULONG) { - prompt("Num. elements in OVLD") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVE,DBF_ULONG) { - prompt("Num. elements in OVLE") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVF,DBF_ULONG) { - prompt("Num. elements in OVLF") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVG,DBF_ULONG) { - prompt("Num. elements in OVLG") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVH,DBF_ULONG) { - prompt("Num. elements in VAlH") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVI,DBF_ULONG) { - prompt("Num. elements in OVLI") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVJ,DBF_ULONG) { - prompt("Num. elements in OVLJ") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVK,DBF_ULONG) { - prompt("Num. elements in OVLK") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVL,DBF_ULONG) { - prompt("Num. elements in OVLL") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVM,DBF_ULONG) { - prompt("Num. elements in OVLM") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVN,DBF_ULONG) { - prompt("Num. elements in OVLN") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVO,DBF_ULONG) { - prompt("Num. elements in OVLO") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVP,DBF_ULONG) { - prompt("Num. elements in OVLP") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVQ,DBF_ULONG) { - prompt("Num. elements in OVLQ") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVR,DBF_ULONG) { - prompt("Num. elements in OVLR") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVS,DBF_ULONG) { - prompt("Num. elements in OVLS") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVT,DBF_ULONG) { - prompt("Num. elements in OVLT") - special(SPC_NOMOD) - interest(4) - initial("1") - } - field(ONVU,DBF_ULONG) { - prompt("Num. elements in OVLU") - special(SPC_NOMOD) - interest(4) - initial("1") - } -} diff --git a/src/std/rec/aaiRecord.c b/src/std/rec/aaiRecord.c deleted file mode 100644 index 0dfed346c..000000000 --- a/src/std/rec/aaiRecord.c +++ /dev/null @@ -1,347 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 Southeastern Universities Research Association, as -* Operator of Thomas Jefferson National Accelerator Facility. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* recAai.c */ - -/* recAai.c - Record Support Routines for Array Analog In records */ -/* - * Original Author: Dave Barker - * - * C E B A F - * - * Continuous Electron Beam Accelerator Facility - * Newport News, Virginia, USA. - * - * Copyright SURA CEBAF 1993. - * - * Current Author: Dirk Zimoch - * Date: 27-MAY-2010 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsString.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "dbScan.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "cantProceed.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "aaiRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -static long get_array_info(DBADDR *, long *, long *); -static long put_array_info(DBADDR *, long); -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -#define get_alarm_double NULL - -rset aaiRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,aaiRSET); - -struct aaidset { /* aai dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_aai; /*returns: (-1,0)=>(failure,success)*/ -}; - -static void monitor(aaiRecord *); -static long readValue(aaiRecord *); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct aaiRecord *prec = (struct aaiRecord *)pcommon; - struct aaidset *pdset = (struct aaidset *)(prec->dset); - long status; - - /* must have dset defined */ - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "aai: init_record"); - return S_dev_noDSET; - } - - if (pass == 0) { - if (prec->nelm <= 0) - prec->nelm = 1; - if (prec->ftvl > DBF_ENUM) - prec->ftvl = DBF_UCHAR; - if (prec->nelm == 1) { - prec->nord = 1; - } else { - prec->nord = 0; - } - - /* we must call pdset->init_record in pass 0 - because it may set prec->bptr which must - not change after links are established before pass 1 - */ - - if (pdset->init_record) { - /* init_record may set the bptr to point to the data */ - if ((status = pdset->init_record(prec))) - return status; - } - if (!prec->bptr) { - /* device support did not allocate memory so we must do it */ - prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), - "aai: buffer calloc failed"); - } - return 0; - } - - recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm); - - /* must have read_aai function defined */ - if (pdset->number < 5 || pdset->read_aai == NULL) { - recGblRecordError(S_dev_missingSup, prec, "aai: init_record"); - return S_dev_missingSup; - } - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct aaiRecord *prec = (struct aaiRecord *)pcommon; - struct aaidset *pdset = (struct aaidset *)(prec->dset); - long status; - unsigned char pact = prec->pact; - - if (pdset == NULL || pdset->read_aai == NULL) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "read_aai"); - return S_dev_missingSup; - } - - status = readValue(prec); /* read the new value */ - if (!pact && prec->pact) return 0; - prec->pact = TRUE; - - prec->udf = FALSE; - recGblGetTimeStamp(prec); - - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact = FALSE; - return status; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - aaiRecord *prec = (aaiRecord *)paddr->precord; - - paddr->no_elements = prec->nelm; - paddr->field_type = prec->ftvl; - paddr->field_size = dbValueSize(prec->ftvl); - paddr->dbr_field_type = prec->ftvl; - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - aaiRecord *prec = (aaiRecord *)paddr->precord; - - paddr->pfield = prec->bptr; - *no_elements = prec->nord; - *offset = 0; - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - aaiRecord *prec = (aaiRecord *)paddr->precord; - - prec->nord = nNew; - if (prec->nord > prec->nelm) - prec->nord = prec->nelm; - return 0; -} - -#define indexof(field) aaiRecord##field - -static long get_units(DBADDR *paddr, char *units) -{ - aaiRecord *prec = (aaiRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM) - break; - case indexof(HOPR): - case indexof(LOPR): - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - aaiRecord *prec = (aaiRecord *)paddr->precord; - - *precision = prec->prec; - if (dbGetFieldIndex(paddr) != indexof(VAL)) - recGblGetPrec(paddr, precision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - aaiRecord *prec = (aaiRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - case indexof(NORD): - pgd->upper_disp_limit = prec->nelm; - pgd->lower_disp_limit = 0; - break; - default: - recGblGetGraphicDouble(paddr, pgd); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - aaiRecord *prec = (aaiRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - case indexof(NORD): - pcd->upper_ctrl_limit = prec->nelm; - pcd->lower_ctrl_limit = 0; - break; - default: - recGblGetControlDouble(paddr, pcd); - } - return 0; -} - -static void monitor(aaiRecord *prec) -{ - unsigned short monitor_mask; - unsigned int hash = 0; - - monitor_mask = recGblResetAlarms(prec); - - if (prec->mpst == aaiPOST_Always) - monitor_mask |= DBE_VALUE; - if (prec->apst == aaiPOST_Always) - monitor_mask |= DBE_LOG; - - /* Calculate hash if we are interested in OnChange events. */ - if ((prec->mpst == aaiPOST_OnChange) || - (prec->apst == aaiPOST_OnChange)) { - hash = epicsMemHash(prec->bptr, - prec->nord * dbValueSize(prec->ftvl), 0); - - /* Only post OnChange values if the hash is different. */ - if (hash != prec->hash) { - if (prec->mpst == aaiPOST_OnChange) - monitor_mask |= DBE_VALUE; - if (prec->apst == aaiPOST_OnChange) - monitor_mask |= DBE_LOG; - - /* Store hash for next process. */ - prec->hash = hash; - /* Post HASH. */ - db_post_events(prec, &prec->hash, DBE_VALUE); - } - } - - if (monitor_mask) - db_post_events(prec, &prec->val, monitor_mask); -} - -static long readValue(aaiRecord *prec) -{ - long status; - struct aaidset *pdset = (struct aaidset *)prec->dset; - - if (prec->pact == TRUE){ - status = pdset->read_aai(prec); - return status; - } - - status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0); - if (status) - return status; - - if (prec->simm == menuYesNoNO){ - return pdset->read_aai(prec); - } - - if (prec->simm == menuYesNoYES){ - /* Device suport is responsible for buffer - which might be read-only so we may not be - allowed to call dbGetLink on it. - Maybe also device support has an advanced - simulation mode. - Thus call device now. - */ - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - return pdset->read_aai(prec); - } - - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return -1; -} - diff --git a/src/std/rec/aaiRecord.dbd b/src/std/rec/aaiRecord.dbd deleted file mode 100644 index 06ab7f7b8..000000000 --- a/src/std/rec/aaiRecord.dbd +++ /dev/null @@ -1,116 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(aaiPOST) { - choice(aaiPOST_Always,"Always") - choice(aaiPOST_OnChange,"On Change") -} -recordtype(aai) { - include "dbCommon.dbd" - field(VAL,DBF_NOACCESS) { - prompt("Value") - asl(ASL0) - special(SPC_DBADDR) - pp(TRUE) - extra("void * val") - #=type DOUBLE[] - #=read Yes - #=write Yes - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(NELM,DBF_ULONG) { - prompt("Number of Elements") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(FTVL,DBF_MENU) { - prompt("Field Type of Value") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - menu(menuFtype) - } - field(NORD,DBF_ULONG) { - prompt("Number elements read") - special(SPC_NOMOD) - } - field(BPTR,DBF_NOACCESS) { - prompt("Buffer Pointer") - special(SPC_NOMOD) - interest(4) - extra("void * bptr") - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(MPST,DBF_MENU) { - prompt("Post Value Monitors") - promptgroup("80 - Display") - interest(1) - menu(aaiPOST) - } - field(APST,DBF_MENU) { - prompt("Post Archive Monitors") - promptgroup("80 - Display") - interest(1) - menu(aaiPOST) - } - field(HASH,DBF_ULONG) { - prompt("Hash of OnChange data.") - interest(3) - } -} diff --git a/src/std/rec/aaoRecord.c b/src/std/rec/aaoRecord.c deleted file mode 100644 index 1cc2541eb..000000000 --- a/src/std/rec/aaoRecord.c +++ /dev/null @@ -1,345 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 Southeastern Universities Research Association, as -* Operator of Thomas Jefferson National Accelerator Facility. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* recAao.c */ - -/* recAao.c - Record Support Routines for Array Analog Out records */ -/* - * Original Author: Dave Barker - * - * C E B A F - * - * Continuous Electron Beam Accelerator Facility - * Newport News, Virginia, USA. - * - * Copyright SURA CEBAF 1993. - * - * Current Author: Dirk Zimoch - * Date: 27-MAY-2010 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsString.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "dbScan.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "cantProceed.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "aaoRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -static long get_array_info(DBADDR *, long *, long *); -static long put_array_info(DBADDR *, long); -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -#define get_alarm_double NULL - -rset aaoRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,aaoRSET); - -struct aaodset { /* aao dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_aao; /*returns: (-1,0)=>(failure,success)*/ -}; - -static void monitor(aaoRecord *); -static long writeValue(aaoRecord *); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct aaoRecord *prec = (struct aaoRecord *)pcommon; - struct aaodset *pdset = (struct aaodset *)(prec->dset); - long status; - - /* must have dset defined */ - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "aao: init_record"); - return S_dev_noDSET; - } - - if (pass == 0) { - if (prec->nelm <= 0) - prec->nelm = 1; - if (prec->ftvl > DBF_ENUM) - prec->ftvl = DBF_UCHAR; - if (prec->nelm == 1) { - prec->nord = 1; - } else { - prec->nord = 0; - } - - /* we must call pdset->init_record in pass 0 - because it may set prec->bptr which must - not change after links are established before pass 1 - */ - - if (pdset->init_record) { - /* init_record may set the bptr to point to the data */ - if ((status = pdset->init_record(prec))) - return status; - } - if (!prec->bptr) { - /* device support did not allocate memory so we must do it */ - prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), - "aao: buffer calloc failed"); - } - return 0; - } - - recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm); - - /* must have write_aao function defined */ - if (pdset->number < 5 || pdset->write_aao == NULL) { - recGblRecordError(S_dev_missingSup, prec, "aao: init_record"); - return S_dev_missingSup; - } - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct aaoRecord *prec = (struct aaoRecord *)pcommon; - struct aaodset *pdset = (struct aaodset *)(prec->dset); - long status; - unsigned char pact = prec->pact; - - if (pdset == NULL || pdset->write_aao == NULL) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "write_aao"); - return S_dev_missingSup; - } - - status = writeValue(prec); /* write the data */ - if (!pact && prec->pact) return 0; - prec->pact = TRUE; - - prec->udf = FALSE; - recGblGetTimeStamp(prec); - - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact = FALSE; - return status; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - aaoRecord *prec = (aaoRecord *)paddr->precord; - - paddr->no_elements = prec->nelm; - paddr->field_type = prec->ftvl; - paddr->field_size = dbValueSize(prec->ftvl); - paddr->dbr_field_type = prec->ftvl; - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - aaoRecord *prec = (aaoRecord *)paddr->precord; - - paddr->pfield = prec->bptr; - *no_elements = prec->nord; - *offset = 0; - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - aaoRecord *prec = (aaoRecord *)paddr->precord; - - prec->nord = nNew; - if (prec->nord > prec->nelm) - prec->nord = prec->nelm; - return 0; -} - -#define indexof(field) aaoRecord##field - -static long get_units(DBADDR *paddr, char *units) -{ - aaoRecord *prec = (aaoRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM) - break; - case indexof(HOPR): - case indexof(LOPR): - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - aaoRecord *prec = (aaoRecord *)paddr->precord; - - *precision = prec->prec; - if (dbGetFieldIndex(paddr) != indexof(VAL)) - recGblGetPrec(paddr, precision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - aaoRecord *prec = (aaoRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - case indexof(NORD): - pgd->upper_disp_limit = prec->nelm; - pgd->lower_disp_limit = 0; - break; - default: - recGblGetGraphicDouble(paddr, pgd); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - aaoRecord *prec = (aaoRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - case indexof(NORD): - pcd->upper_ctrl_limit = prec->nelm; - pcd->lower_ctrl_limit = 0; - break; - default: - recGblGetControlDouble(paddr, pcd); - } - return 0; -} - -static void monitor(aaoRecord *prec) -{ - unsigned short monitor_mask; - unsigned int hash = 0; - - monitor_mask = recGblResetAlarms(prec); - - if (prec->mpst == aaoPOST_Always) - monitor_mask |= DBE_VALUE; - if (prec->apst == aaoPOST_Always) - monitor_mask |= DBE_LOG; - - /* Calculate hash if we are interested in OnChange events. */ - if ((prec->mpst == aaoPOST_OnChange) || - (prec->apst == aaoPOST_OnChange)) { - hash = epicsMemHash(prec->bptr, - prec->nord * dbValueSize(prec->ftvl), 0); - - /* Only post OnChange values if the hash is different. */ - if (hash != prec->hash) { - if (prec->mpst == aaoPOST_OnChange) - monitor_mask |= DBE_VALUE; - if (prec->apst == aaoPOST_OnChange) - monitor_mask |= DBE_LOG; - - /* Store hash for next process. */ - prec->hash = hash; - /* Post HASH. */ - db_post_events(prec, &prec->hash, DBE_VALUE); - } - } - - if (monitor_mask) - db_post_events(prec, &prec->val, monitor_mask); -} - -static long writeValue(aaoRecord *prec) -{ - long status; - struct aaodset *pdset = (struct aaodset *)prec->dset; - - if (prec->pact == TRUE) { - /* no asyn allowed, pact true means do not process */ - return 0; - } - - status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0); - if (status) - return status; - - if (prec->simm == menuYesNoNO) { - return pdset->write_aao(prec); - } - if (prec->simm == menuYesNoYES) { - /* Device suport is responsible for buffer - which might be write-only so we may not be - allowed to call dbPutLink on it. - Maybe also device support has an advanced - simulation mode. - Thus call device now. - */ - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - return pdset->write_aao(prec); - } - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return -1; -} - diff --git a/src/std/rec/aaoRecord.dbd b/src/std/rec/aaoRecord.dbd deleted file mode 100644 index 57d842f4f..000000000 --- a/src/std/rec/aaoRecord.dbd +++ /dev/null @@ -1,116 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(aaoPOST) { - choice(aaoPOST_Always,"Always") - choice(aaoPOST_OnChange,"On Change") -} -recordtype(aao) { - include "dbCommon.dbd" - field(VAL,DBF_NOACCESS) { - prompt("Value") - asl(ASL0) - special(SPC_DBADDR) - pp(TRUE) - extra("void * val") - #=type DOUBLE[] - #=read Yes - #=write Yes - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(NELM,DBF_ULONG) { - prompt("Number of Elements") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(FTVL,DBF_MENU) { - prompt("Field Type of Value") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - menu(menuFtype) - } - field(NORD,DBF_ULONG) { - prompt("Number elements read") - special(SPC_NOMOD) - } - field(BPTR,DBF_NOACCESS) { - prompt("Buffer Pointer") - special(SPC_NOMOD) - interest(4) - extra("void * bptr") - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(MPST,DBF_MENU) { - prompt("Post Value Monitors") - promptgroup("80 - Display") - interest(1) - menu(aaoPOST) - } - field(APST,DBF_MENU) { - prompt("Post Archive Monitors") - promptgroup("80 - Display") - interest(1) - menu(aaoPOST) - } - field(HASH,DBF_ULONG) { - prompt("Hash of OnChange data.") - interest(3) - } -} diff --git a/src/std/rec/aiRecord.c b/src/std/rec/aiRecord.c deleted file mode 100644 index 81f730f6d..000000000 --- a/src/std/rec/aiRecord.c +++ /dev/null @@ -1,514 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* aiRecord.c - Record Support Routines for Analog Input records */ -/* - * Original Author: Bob Dalesio - * Date: 7-14-89 - * - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "epicsMath.h" -#include "alarm.h" -#include "cvtTable.h" -#include "dbAccess.h" -#include "dbScan.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "menuSimm.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#include "menuConvert.h" - -#define GEN_SIZE_OFFSET -#include "aiRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Hysterisis for alarm filtering: 1-1/e */ -#define THRESHOLD 0.6321 - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset aiRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,aiRSET); - -typedef struct aidset { /* analog input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai;/*(0,2)=> success and convert,don't convert)*/ - /* if convert then raw value stored in rval */ - DEVSUPFUN special_linconv; -}aidset; - - -static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime); -static void convert(aiRecord *prec); -static void monitor(aiRecord *prec); -static long readValue(aiRecord *prec); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct aiRecord *prec = (struct aiRecord *)pcommon; - aidset *pdset; - double eoff = prec->eoff, eslo = prec->eslo; - - if (pass==0) return(0); - - recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm); - recGblInitConstantLink(&prec->siol,DBF_DOUBLE,&prec->sval); - - if(!(pdset = (aidset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET,(void *)prec,"ai: init_record"); - return(S_dev_noDSET); - } - /* must have read_ai function defined */ - if( (pdset->number < 6) || (pdset->read_ai == NULL) ) { - recGblRecordError(S_dev_missingSup,(void *)prec,"ai: init_record"); - return(S_dev_missingSup); - } - prec->init = TRUE; - /*The following is for old device support that doesnt know about eoff*/ - if ((prec->eslo==1.0) && (prec->eoff==0.0)) { - prec->eoff = prec->egul; - } - - if( pdset->init_record ) { - long status=(*pdset->init_record)(prec); - if (prec->linr == menuConvertSLOPE) { - prec->eoff = eoff; - prec->eslo = eslo; - } - return (status); - } - prec->mlst = prec->val; - prec->alst = prec->val; - prec->lalm = prec->val; - prec->oraw = prec->rval; - return(0); -} - -static long process(struct dbCommon *pcommon) -{ - struct aiRecord *prec = (struct aiRecord *)pcommon; - aidset *pdset = (aidset *)(prec->dset); - long status; - unsigned char pact=prec->pact; - epicsTimeStamp timeLast; - - if( (pdset==NULL) || (pdset->read_ai==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"read_ai"); - return(S_dev_missingSup); - } - timeLast = prec->time; - - status=readValue(prec); /* read the new value */ - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - if (status==0) convert(prec); - else if (status==2) status=0; - - /* check for alarms */ - checkAlarms(prec,&timeLast); - /* check event list */ - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->init=FALSE; - prec->pact=FALSE; - return(status); -} - -static long special(DBADDR *paddr,int after) -{ - aiRecord *prec = (aiRecord *)(paddr->precord); - aidset *pdset = (aidset *) (prec->dset); - int special_type = paddr->special; - - switch(special_type) { - case(SPC_LINCONV): - if(pdset->number<6) { - recGblDbaddrError(S_db_noMod,paddr,"ai: special"); - return(S_db_noMod); - } - prec->init=TRUE; - if ((prec->linr == menuConvertLINEAR) && pdset->special_linconv) { - double eoff = prec->eoff; - double eslo = prec->eslo; - long status; - prec->eoff = prec->egul; - status = (*pdset->special_linconv)(prec,after); - if (eoff != prec->eoff) - db_post_events(prec, &prec->eoff, DBE_VALUE|DBE_LOG); - if (eslo != prec->eslo) - db_post_events(prec, &prec->eslo, DBE_VALUE|DBE_LOG); - return(status); - } - return(0); - default: - recGblDbaddrError(S_db_badChoice,paddr,"ai: special"); - return(S_db_badChoice); - } -} - -#define indexof(field) aiRecord##field - -static long get_units(DBADDR *paddr, char *units) -{ - aiRecord *prec=(aiRecord *)paddr->precord; - - if(paddr->pfldDes->field_type == DBF_DOUBLE) { - switch (dbGetFieldIndex(paddr)) { - case indexof(ASLO): - case indexof(AOFF): - case indexof(SMOO): - break; - default: - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - } - return(0); -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - aiRecord *prec=(aiRecord *)paddr->precord; - - *precision = prec->prec; - if (dbGetFieldIndex(paddr) == indexof(VAL)) return(0); - recGblGetPrec(paddr,precision); - return(0); -} - -static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd) -{ - aiRecord *prec=(aiRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - case indexof(SVAL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return(0); -} - -static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd) -{ - aiRecord *prec=(aiRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - case indexof(SVAL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return(0); -} - -static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad) -{ - aiRecord *prec=(aiRecord *)paddr->precord; - - if (dbGetFieldIndex(paddr) == indexof(VAL)) { - pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN; - pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN; - pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN; - pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(aiRecord *prec, epicsTimeStamp *lastTime) -{ - enum { - range_Lolo = 1, - range_Low, - range_Normal, - range_High, - range_Hihi - } alarmRange; - static const epicsEnum16 range_stat[] = { - SOFT_ALARM, LOLO_ALARM, LOW_ALARM, - NO_ALARM, HIGH_ALARM, HIHI_ALARM - }; - double val, hyst, lalm, alev, aftc, afvl; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - prec->afvl = 0; - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* check VAL against alarm limits */ - if ((asev = prec->hhsv) && - (val >= (alev = prec->hihi) || - ((lalm == alev) && (val >= alev - hyst)))) - alarmRange = range_Hihi; - else - if ((asev = prec->llsv) && - (val <= (alev = prec->lolo) || - ((lalm == alev) && (val <= alev + hyst)))) - alarmRange = range_Lolo; - else - if ((asev = prec->hsv) && - (val >= (alev = prec->high) || - ((lalm == alev) && (val >= alev - hyst)))) - alarmRange = range_High; - else - if ((asev = prec->lsv) && - (val <= (alev = prec->low) || - ((lalm == alev) && (val <= alev + hyst)))) - alarmRange = range_Low; - else { - alev = val; - asev = NO_ALARM; - alarmRange = range_Normal; - } - - aftc = prec->aftc; - afvl = 0; - - if (aftc > 0) { - /* Apply level filtering */ - afvl = prec->afvl; - if (afvl == 0) { - afvl = (double)alarmRange; - } else { - double t = epicsTimeDiffInSeconds(&prec->time, lastTime); - double alpha = aftc / (t + aftc); - - /* The sign of afvl indicates whether the result should be - * rounded up or down. This gives the filter hysteresis. - * If afvl > 0 the floor() function rounds to a lower alarm - * level, otherwise to a higher. - */ - afvl = alpha * afvl + - ((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange; - if (afvl - floor(afvl) > THRESHOLD) - afvl = -afvl; /* reverse rounding */ - - alarmRange = abs((int)floor(afvl)); - switch (alarmRange) { - case range_Hihi: - asev = prec->hhsv; - alev = prec->hihi; - break; - case range_High: - asev = prec->hsv; - alev = prec->high; - break; - case range_Normal: - asev = NO_ALARM; - break; - case range_Low: - asev = prec->lsv; - alev = prec->low; - break; - case range_Lolo: - asev = prec->llsv; - alev = prec->lolo; - break; - } - } - } - prec->afvl = afvl; - - if (asev) { - /* Report alarm condition, store LALM for future HYST calculations */ - if (recGblSetSevr(prec, range_stat[alarmRange], asev)) - prec->lalm = alev; - } else { - /* No alarm condition, reset LALM */ - prec->lalm = val; - } -} - -static void convert(aiRecord *prec) -{ - double val; - - - val = (double)prec->rval + (double)prec->roff; - /* adjust slope and offset */ - if(prec->aslo!=0.0) val*=prec->aslo; - val+=prec->aoff; - - /* convert raw to engineering units and signal units */ - switch (prec->linr) { - case menuConvertNO_CONVERSION: - break; /* do nothing*/ - - case menuConvertLINEAR: - case menuConvertSLOPE: - val = (val * prec->eslo) + prec->eoff; - break; - - default: /* must use breakpoint table */ - if (cvtRawToEngBpt(&val,prec->linr,prec->init,(void *)&prec->pbrk,&prec->lbrk)!=0) { - recGblSetSevr(prec,SOFT_ALARM,MAJOR_ALARM); - } - } - - /* apply smoothing algorithm */ - if (prec->smoo != 0.0 && finite(prec->val)){ - if (prec->init) prec->val = val; /* initial condition */ - prec->val = val * (1.00 - prec->smoo) + (prec->val * prec->smoo); - }else{ - prec->val = val; - } - prec->udf = isnan(prec->val); - return; -} - -static void monitor(aiRecord *prec) -{ - unsigned monitor_mask = recGblResetAlarms(prec); - - /* check for value change */ - recGblCheckDeadband(&prec->mlst, prec->val, prec->mdel, &monitor_mask, DBE_VALUE); - - /* check for archive change */ - recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask, DBE_ARCHIVE); - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(prec,&prec->val,monitor_mask); - if(prec->oraw != prec->rval) { - db_post_events(prec,&prec->rval,monitor_mask); - prec->oraw = prec->rval; - } - } - return; -} - -static long readValue(aiRecord *prec) -{ - long status; - aidset *pdset = (aidset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->read_ai)(prec); - return(status); - } - - status = dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0); - - if (status) - return(status); - - if (prec->simm == menuSimmNO){ - status=(*pdset->read_ai)(prec); - return(status); - } - if (prec->simm == menuSimmYES){ - status = dbGetLink(&(prec->siol),DBR_DOUBLE,&(prec->sval),0,0); - if (status==0){ - prec->val=prec->sval; - prec->udf=isnan(prec->val); - } - status=2; /* dont convert */ - } - else if (prec->simm == menuSimmRAW){ - status = dbGetLink(&(prec->siol),DBR_DOUBLE,&(prec->sval),0,0); - if (status==0) { - prec->udf=isnan(prec->sval); - if (!prec->udf) { - prec->rval=(long)floor(prec->sval); - } - } - status=0; /* convert since we've written RVAL */ - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/aiRecord.dbd.pod b/src/std/rec/aiRecord.dbd.pod deleted file mode 100644 index 2973ec831..000000000 --- a/src/std/rec/aiRecord.dbd.pod +++ /dev/null @@ -1,631 +0,0 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=title Analog Input Record (ai) - -This record type is normally used to obtain an analog value from a hardware -input and convert it to engineering units. -The record supports linear and break-point conversion to engineering units, -smoothing, alarm limits, alarm filtering, and graphics and control limits. - -=head2 Parameter Fields - -The record-specific fields are described below, grouped by functionality. - -=recordtype ai - -=cut - -recordtype(ai) { - -=head3 Input Specification - -These fields control where the record will read data from when it is processed: - -=fields DTYP, INP - -The DTYP field selects which device support layer should be responsible for -providing input data to the record. -The ai device support layers provided by EPICS Base are documented in the -L section. -External support modules may provide additional device support for this record -type. -If not set explicitly, the DTYP value defaults to the first device support that -is loaded for the record type, which will usually be the C support -that comes with Base. - -The INP link field contains a database or channel access link or provides -hardware address information that the device support uses to determine where the -input data should come from. -The format for the INP field value depends on the device support layer that is -selected by the DTYP field. -See L
for a description of the various hardware -address formats supported. - -=head3 Units Conversion - -These fields control if and how the raw input value gets converted into -engineering units: - -=fields RVAL, ROFF, ASLO, AOFF, LINR, ESLO, EOFF, EGUL, EGUF - -These fields are not used if the device support layer reads its value in -engineering units and puts it directly into the VAL field. -This applies to Soft Channel and Async Soft Channel device support, and is also -fairly common for GPIB and similar high-level device interfaces. - -If the device support sets the RVAL field, the LINR field controls how this gets -converted into engineering units and placed in the VAL field as follows: - -=over - -=item 1. -RVAL is converted to a double and ROFF is added to it. - -=item 2. -If ASLO is non-zero the value is multiplied by ASLO. - -=item 3. -AOFF is added. - -=item 4. -If LINR is C the units conversion is finished after the above -steps. - -=item 5. -If LINR is C or C, the value from step 3 above is multiplied by -ESLO and EOFF is added to complete the units conversion process. - -=item 6. -Any other value for LINR selects a particular breakpoint table to be used on the -value from step 3 above. - -=back - -The distinction between the C and C settings for the LINR field -are in how the conversion parameters are calculated: - -=over - -=item * -With C conversion the user must set EGUL and EGUF to the lowest and -highest possible engineering units values respectively that can be converted by -the hardware. -The device support knows the range of the raw data and calculates ESLO and EOFF -from them. - -=item * -C conversion requires the user to calculate the appropriate scaling and -offset factors and put them directly in ESLO and EOFF. - -=back - -=head3 Smoothing Filter - -This filter is usually only used if the device support sets the RVAL field and -the Units Conversion process is used. -Device support that directly sets the VAL field may implement the filter if -desired. - -The filter is controlled with a single parameter field: - -=fields SMOO - -The SMOO field should be set to a number between 0 and 1. -If set to zero the filter is not used (no smoothing), while if set to one the -result is infinite smoothing (the VAL field will never change). -The calculation performed is: - -=over - -VAL = VAL * SMOO + (1 - SMOO) * New Data - -=back - -where C was the result from the Units Conversion above. -This implements a first-order infinite impulse response (IIR) digital filter -with z-plane pole at SMOO. -The equivalent continuous-time filter time constant E is given by - -=over - -E = ET / ln(SMOO) - -=back - -where T is the time between record processing. - -=head3 Undefined Check - -If after applying the smoothing filter the VAL field contains a NaN -(Not-a-Number) value, the UDF field is set to a non-zero value, indicating that -the record value is undefined, which will trigger a C with severity -C. - -=fields UDF - -=head3 Operator Display Parameters - -These parameters are used to present meaningful data to the operator. -They do not affect the functioning of the record at all. - -=over - -=item * -DESC is a string that is usually used to briefly describe the record. - -=item * -EGU is a string of up to 16 characters naming the engineering units that the VAL -field represents. - -=item * -The HOPR and LOPR fields set the upper and lower display limits for the VAL, -HIHI, HIGH, LOW, and LOLO fields. - -=item * -The PREC field determines the floating point precision (i.e. the number of -digits to show after the decimal point) with which to display VAL and the other -DOUBLE fields. - -=back - -=fields DESC, EGU, HOPR, LOPR, PREC - -=head3 Alarm Limits - -The user configures limit alarms by putting numerical values into the HIHI, -HIGH, LOW and LOLO fields, and by setting the associated alarm severity in the -corresponding HHSV, HSV, LSV and LLSV menu fields. - -The HYST field controls hysteresis to prevent alarm chattering from an input -signal that is close to one of the limits and suffers from significant readout -noise. - -The AFTC field sets the time constant on a low-pass filter that delays the -reporting of limit alarms until the signal has been within the alarm range for -that number of seconds (the default AFTC value of zero retains the previous -behavior). - -=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, AFTC, LALM - -=head3 Monitor Parameters - -These parameters are used to determine when to send monitors placed on the VAL -field. -The monitors are sent when the current value exceeds the last transmitted value -by the appropriate deadband. -If these fields are set to zero, a monitor will be triggered every time the -value changes; if set to -1, a monitor will be sent every time the record is -processed. - -The ADEL field sets the deadband for archive monitors (C events), while -the MDEL field controls value monitors (C events). - -The remaining fields are used by the record at run-time to implement the record -monitoring functionality. - -=fields ADEL, MDEL, ALST, MLST, ORAW - -=cut - - include "dbCommon.dbd" - field(VAL,DBF_DOUBLE) { - prompt("Current EGU Value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LINR,DBF_MENU) { - prompt("Linearization") - promptgroup("60 - Convert") - special(SPC_LINCONV) - pp(TRUE) - interest(1) - menu(menuConvert) - } - field(EGUF,DBF_DOUBLE) { - prompt("Engineer Units Full") - promptgroup("60 - Convert") - special(SPC_LINCONV) - pp(TRUE) - interest(1) - } - field(EGUL,DBF_DOUBLE) { - prompt("Engineer Units Low") - promptgroup("60 - Convert") - special(SPC_LINCONV) - pp(TRUE) - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(AOFF,DBF_DOUBLE) { - prompt("Adjustment Offset") - promptgroup("60 - Convert") - pp(TRUE) - interest(1) - } - field(ASLO,DBF_DOUBLE) { - prompt("Adjustment Slope") - promptgroup("60 - Convert") - pp(TRUE) - interest(1) - initial("1") - } - field(SMOO,DBF_DOUBLE) { - prompt("Smoothing") - promptgroup("60 - Convert") - interest(1) - } - field(HIHI,DBF_DOUBLE) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_DOUBLE) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_DOUBLE) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_DOUBLE) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HYST,DBF_DOUBLE) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(AFTC,DBF_DOUBLE) { - prompt("Alarm Filter Time Constant") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_DOUBLE) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_DOUBLE) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(LALM,DBF_DOUBLE) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(AFVL,DBF_DOUBLE) { - prompt("Alarm Filter Value") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_DOUBLE) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_DOUBLE) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } - field(ESLO,DBF_DOUBLE) { - prompt("Raw to EGU Slope") - promptgroup("60 - Convert") - pp(TRUE) - interest(2) - initial("1") - } - field(EOFF,DBF_DOUBLE) { - prompt("Raw to EGU Offset") - promptgroup("60 - Convert") - pp(TRUE) - interest(2) - } - field(ROFF,DBF_ULONG) { - prompt("Raw Offset") - pp(TRUE) - interest(2) - } - field(PBRK,DBF_NOACCESS) { - prompt("Ptrto brkTable") - special(SPC_NOMOD) - interest(4) - extra("void * pbrk") - } - field(INIT,DBF_SHORT) { - prompt("Initialized?") - special(SPC_NOMOD) - interest(3) - } - field(LBRK,DBF_SHORT) { - prompt("LastBreak Point") - special(SPC_NOMOD) - interest(3) - } - field(RVAL,DBF_LONG) { - prompt("Current Raw Value") - pp(TRUE) - } - field(ORAW,DBF_LONG) { - prompt("Previous Raw Value") - special(SPC_NOMOD) - interest(3) - } - -=head3 Simulation Mode - -The record provides several fields to support simulation of absent hardware. -If the SIML field is set it is used to read a value into the SIMM field, which -controls whether simulation is used or not: - -=over - -=item * -SIMM must be zero (C) for the record to request a value from the device -support. - -=item * -If SIMM is C and the SIOL link field is set, a simlated value in -engineering units is read using the link into the SVAL field, from where it will -subsequently be copied into the VAL field. - -=item * -If SIMM is C the SIOL link is still read into SVAL, but is then truncated -and copied into the RVAL field. -The L process described above is then followed to transform -the simulated raw value into engineering units. - -=back - -The SIMS field can be set to give the record an alarm severity while it is in -simulation mode. - -=fields SIML, SIMM, SIOL, SVAL, SIMS - -=cut - - field(SIOL,DBF_INLINK) { - prompt("Sim. Input Specification") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_DOUBLE) { - prompt("Simulation Value") - } - field(SIML,DBF_INLINK) { - prompt("Sim. Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuSimm) - } - field(SIMS,DBF_MENU) { - prompt("Simulation Mode Severity") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } -} - -=head2 Device Support Interface - -The record requires device support to provide an entry table (dset) which -defines the following members: - - typedef struct { - long number; - long (*report)(int level); - long (*init)(int after); - long (*init_record)(aiRecord *prec); - long (*get_ioint_info)(int cmd, aiRecord *prec, IOSCANPVT *piosl); - long (*read_ai)(aiRecord *prec); - long (*special_linconv)(aiRecord *prec, int after); - } aidset; - -The module must set C to at least 6, and provide a pointer to its -C routine; the other function pointers may be C if their -associated functionality is not required for this support layer. -Most device supports also provide an C routine to configure the -record instance and connect it to the hardware or driver support layer, and if -using the record's L features they set C -as well. - -The individual routines are described below. - -=head3 Device Support Routines - -=head4 long report(int level) - -This optional routine is called by the IOC command C and is passed the -report level that was requested by the user. -It should print a report on the state of the device support to stdout. -The C parameter may be used to output increasingly more detailed -information at higher levels, or to select different types of information with -different levels. -Level zero should print no more than a small summary. - -=head4 long init(int after) - -This optional routine is called twice at IOC initialization time. -The first call happens before any of the C calls are made, with -the integer parameter C set to 0. -The second call happens after all of the C calls have been made, -with C set to 1. - -=head4 long init_record(aiRecord *prec) - -This optional routine is called by the record initialization code for each ai -record instance that has its DTYP field set to use this device support. -It is normally used to check that the INP address is the expected type and that -it points to a valid device; to allocate any record-specific buffer space and -other memory; and to connect any communication channels needed for the -C routine to work properly. - -If the record type's unit conversion features are used, the C -routine should calculate appropriate values for the ESLO and EOFF fields from -the EGUL and EGUF field values. -This calculation only has to be performed if the record's LINR field is set to -C, but it is not necessary to check that condition first. -This same calculation takes place in the C routine, so the -implementation can usually just call that routine to perform the task. - -=head4 long get_ioint_info(int cmd, aiRecord *prec, IOSCANPVT *piosl) - -This optional routine is called whenever the record's SCAN field is being -changed to or from the value C to find out which I/O Interrupt Scan -list the record should be added to or deleted from. -If this routine is not provided, it will not be possible to set the SCAN field -to the value C at all. - -The C parameter is zero when the record is being added to the scan list, -and one when it is being removed from the list. -The routine must determine which interrupt source the record should be connected -to, which it indicates by the scan list that it points the location at C<*piosl> -to before returning. -It can prevent the SCAN field from being changed at all by returning a non-zero -value to its caller. - -In most cases the device support will create the I/O Interrupt Scan lists that -it returns for itself, by calling C once for -each separate interrupt source. -That routine allocates memory and inializes the list, then passes back a pointer -to the new list in the location at C<*piosl>. - -When the device support receives notification that the interrupt has occurred, -it announces that to the IOC by calling C -which will arrange for the appropriate records to be processed in a suitable -thread. -The C routine is safe to call from an interrupt service routine -on embedded architectures (vxWorks and RTEMS). - -=head4 long read_ai(aiRecord *prec) - -This essential routine is called when the record wants a new value from the -addressed device. -It is responsible for performing (or at least initiating) a read operation, and -(eventually) returning its value to the record. - -... PACT and asynchronous processing ... - -... return value ... - -=head4 long special_linconv(aiRecord *prec, int after) - -This optional routine should be provided if the record type's unit conversion -features are used by the device support's C routine returning a -status value of zero. -It is called by the record code whenever any of the the fields LINR, EGUL or -EGUF are modified and LINR has the value C. -The routine must calculate and set the fields EOFF and ESLO appropriately based -on the new values of EGUL and EGUF. - -These calculations can be expressed in terms of the minimum and maximum raw -values that the C routine can put in the RVAL field. -When RVAL is set to I the VAL field will be set to EGUF, and when RVAL -is set to I the VAL field will become EGUL. - -The formulae to use are: - -=over - -EOFF = (I * EGUL E I * EGUF) / -(I E I) - -ESLO = (EGUF E EGUL) / (I E I) - -=back - -Note that the record support sets EOFF to EGUL before calling this routine, -which is a very common case (when I is zero). - -=head3 Extended Device Support - -... - -=cut diff --git a/src/std/rec/aoRecord.c b/src/std/rec/aoRecord.c deleted file mode 100644 index 0d923af5c..000000000 --- a/src/std/rec/aoRecord.c +++ /dev/null @@ -1,575 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* aoRecord.c - Record Support Routines for Analog Output records */ -/* - * Original Author: Bob Dalesio - * Date: 7-14-89 - * - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsMath.h" -#include "alarm.h" -#include "cvtTable.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "special.h" -#include "recSup.h" -#include "recGbl.h" -#include "menuConvert.h" -#include "menuOmsl.h" -#include "menuYesNo.h" -#include "menuIvoa.h" - -#define GEN_SIZE_OFFSET -#include "aoRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset aoRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double }; - -struct aodset { /* analog input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (0,2)=>(success,success no convert)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_ao;/*(0)=>(success ) */ - DEVSUPFUN special_linconv; -}; -epicsExportAddress(rset,aoRSET); - - - -static void checkAlarms(aoRecord *); -static long fetch_value(aoRecord *, double *); -static void convert(aoRecord *, double); -static void monitor(aoRecord *); -static long writeValue(aoRecord *); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct aoRecord *prec = (struct aoRecord *)pcommon; - struct aodset *pdset; - double eoff = prec->eoff, eslo = prec->eslo; - double value; - - if (pass==0) return(0); - - recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm); - - if(!(pdset = (struct aodset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET,(void *)prec,"ao: init_record"); - return(S_dev_noDSET); - } - /* get the initial value if dol is a constant*/ - if (recGblInitConstantLink(&prec->dol,DBF_DOUBLE,&prec->val)) - prec->udf = isnan(prec->val); - - /* must have write_ao function defined */ - if ((pdset->number < 6) || (pdset->write_ao ==NULL)) { - recGblRecordError(S_dev_missingSup,(void *)prec,"ao: init_record"); - return(S_dev_missingSup); - } - prec->init = TRUE; - /*The following is for old device support that doesnt know about eoff*/ - if ((prec->eslo==1.0) && (prec->eoff==0.0)) { - prec->eoff = prec->egul; - } - - if (pdset->init_record) { - long status=(*pdset->init_record)(prec); - if (prec->linr == menuConvertSLOPE) { - prec->eoff = eoff; - prec->eslo = eslo; - } - switch(status){ - case(0): /* convert */ - value = (double)prec->rval + (double)prec->roff; - if(prec->aslo!=0.0) value *= prec->aslo; - value += prec->aoff; - if (prec->linr == menuConvertNO_CONVERSION){ - ; /*do nothing*/ - } else if ((prec->linr == menuConvertLINEAR) || - (prec->linr == menuConvertSLOPE)) { - value = value*prec->eslo + prec->eoff; - }else{ - if(cvtRawToEngBpt(&value,prec->linr,prec->init, - (void *)&prec->pbrk,&prec->lbrk)!=0) break; - } - prec->val = value; - prec->udf = isnan(value); - break; - case(2): /* no convert */ - break; - default: - recGblRecordError(S_dev_badInitRet,(void *)prec,"ao: init_record"); - return(S_dev_badInitRet); - } - } - prec->oval = prec->pval = prec->val; - prec->mlst = prec->val; - prec->alst = prec->val; - prec->lalm = prec->val; - prec->oraw = prec->rval; - prec->orbv = prec->rbv; - return(0); -} - -static long process(struct dbCommon *pcommon) -{ - struct aoRecord *prec = (struct aoRecord *)pcommon; - struct aodset *pdset = (struct aodset *)(prec->dset); - long status=0; - unsigned char pact=prec->pact; - double value; - - if ((pdset==NULL) || (pdset->write_ao==NULL)) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"write_ao"); - return(S_dev_missingSup); - } - - /* fetch value and convert*/ - if (prec->pact == FALSE) { - if (!dbLinkIsConstant(&prec->dol) && - prec->omsl == menuOmslclosed_loop) { - status = fetch_value(prec, &value); - } - else { - value = prec->val; - } - if(!status) convert(prec, value); - prec->udf = isnan(prec->val); - } - - /* check for alarms */ - checkAlarms(prec); - - if (prec->nsev < INVALID_ALARM ) - status=writeValue(prec); /* write the new value */ - else { - switch (prec->ivoa) { - case (menuIvoaContinue_normally) : - status=writeValue(prec); /* write the new value */ - break; - case (menuIvoaDon_t_drive_outputs) : - break; - case (menuIvoaSet_output_to_IVOV) : - if(prec->pact == FALSE){ - prec->val=prec->ivov; - value=prec->ivov; - convert(prec,value); - } - status=writeValue(prec); /* write the new value */ - break; - default : - status=-1; - recGblRecordError(S_db_badField,(void *)prec, - "ao:process Illegal IVOA field"); - } - } - - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - - /* check event list */ - monitor(prec); - - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->init=FALSE; - prec->pact=FALSE; - return(status); -} - -static long special(DBADDR *paddr, int after) -{ - aoRecord *prec = (aoRecord *)(paddr->precord); - struct aodset *pdset = (struct aodset *) (prec->dset); - int special_type = paddr->special; - - switch(special_type) { - case(SPC_LINCONV): - if(pdset->number<6 ) { - recGblDbaddrError(S_db_noMod,paddr,"ao: special"); - return(S_db_noMod); - } - prec->init=TRUE; - if ((prec->linr == menuConvertLINEAR) && pdset->special_linconv) { - double eoff = prec->eoff; - double eslo = prec->eslo; - long status; - prec->eoff = prec->egul; - status = (*pdset->special_linconv)(prec,after); - if (eoff != prec->eoff) - db_post_events(prec, &prec->eoff, DBE_VALUE|DBE_LOG); - if (eslo != prec->eslo) - db_post_events(prec, &prec->eslo, DBE_VALUE|DBE_LOG); - return (status); - } - return (0); - default: - recGblDbaddrError(S_db_badChoice,paddr,"ao: special"); - return(S_db_badChoice); - } -} - -#define indexof(field) aoRecord##field - -static long get_units(DBADDR * paddr,char *units) -{ - aoRecord *prec=(aoRecord *)paddr->precord; - - if(paddr->pfldDes->field_type == DBF_DOUBLE) { - switch (dbGetFieldIndex(paddr)) { - case indexof(ASLO): - case indexof(AOFF): - break; - default: - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - } - return(0); -} - -static long get_precision(const DBADDR *paddr,long *precision) -{ - aoRecord *prec=(aoRecord *)paddr->precord; - - *precision = prec->prec; - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(OVAL): - case indexof(PVAL): - break; - default: - recGblGetPrec(paddr,precision); - } - return(0); -} - -static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd) -{ - aoRecord *prec=(aoRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(OVAL): - case indexof(PVAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - case indexof(IVOV): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return(0); -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - aoRecord *prec=(aoRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(OVAL): - case indexof(PVAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pcd->upper_ctrl_limit = prec->drvh; - pcd->lower_ctrl_limit = prec->drvl; - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return(0); -} -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - aoRecord *prec=(aoRecord *)paddr->precord; - - if(dbGetFieldIndex(paddr) == indexof(VAL)){ - pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN; - pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN; - pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN; - pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(aoRecord *prec) -{ - double val, hyst, lalm; - double alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* alarm condition hihi */ - asev = prec->hhsv; - alev = prec->hihi; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIHI_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition lolo */ - asev = prec->llsv; - alev = prec->lolo; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOLO_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition high */ - asev = prec->hsv; - alev = prec->high; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIGH_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition low */ - asev = prec->lsv; - alev = prec->low; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOW_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* we get here only if val is out of alarm by at least hyst */ - prec->lalm = val; - return; -} - -static long fetch_value(aoRecord *prec,double *pvalue) -{ - short save_pact; - long status; - - save_pact = prec->pact; - prec->pact = TRUE; - - /* don't allow dbputs to val field */ - prec->val=prec->pval; - - status = dbGetLink(&prec->dol,DBR_DOUBLE,pvalue,0,0); - prec->pact = save_pact; - - if (status) { - recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM); - return(status); - } - - if (prec->oif == aoOIF_Incremental) - *pvalue += prec->val; - - return(0); -} - -static void convert(aoRecord *prec, double value) -{ - /* check drive limits */ - if (prec->drvh > prec->drvl) { - if (value > prec->drvh) - value = prec->drvh; - else if (value < prec->drvl) - value = prec->drvl; - } - prec->val = value; - prec->pval = value; - - /* now set value equal to desired output value */ - /* apply the output rate of change */ - if (prec->oroc != 0){/*must be defined and >0*/ - double diff; - - diff = value - prec->oval; - if (diff < 0) { - if (prec->oroc < -diff) - value = prec->oval - prec->oroc; - } else if (prec->oroc < diff) - value = prec->oval + prec->oroc; - } - prec->omod = (prec->oval!=value); - prec->oval = value; - - /* convert */ - switch (prec->linr) { - case menuConvertNO_CONVERSION: - break; /* do nothing*/ - case menuConvertLINEAR: - case menuConvertSLOPE: - if (prec->eslo == 0.0) value = 0; - else value = (value - prec->eoff) / prec->eslo; - break; - default: - if (cvtEngToRawBpt(&value, prec->linr, prec->init, - (void *)&prec->pbrk, &prec->lbrk) != 0) { - recGblSetSevr(prec, SOFT_ALARM, MAJOR_ALARM); - return; - } - } - value -= prec->aoff; - if (prec->aslo != 0) value /= prec->aslo; - - /* Apply raw offset and limits, round to 32-bit integer */ - value -= prec->roff; - if (value >= 0.0) { - if (value >= (0x7fffffff - 0.5)) - prec->rval = 0x7fffffff; - else - prec->rval = (epicsInt32)(value + 0.5); - } else { - if (value > (0.5 - 0x80000000)) - prec->rval = (epicsInt32)(value - 0.5); - else - prec->rval = 0x80000000; - } -} - - -static void monitor(aoRecord *prec) -{ - unsigned monitor_mask = recGblResetAlarms(prec); - - /* check for value change */ - recGblCheckDeadband(&prec->mlst, prec->val, prec->mdel, &monitor_mask, DBE_VALUE); - - /* check for archive change */ - recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask, DBE_ARCHIVE); - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(prec,&prec->val,monitor_mask); - } - - if(prec->omod) monitor_mask |= (DBE_VALUE|DBE_LOG); - if(monitor_mask) { - prec->omod = FALSE; - db_post_events(prec,&prec->oval,monitor_mask); - if(prec->oraw != prec->rval) { - db_post_events(prec,&prec->rval, - monitor_mask|DBE_VALUE|DBE_LOG); - prec->oraw = prec->rval; - } - if(prec->orbv != prec->rbv) { - db_post_events(prec,&prec->rbv, - monitor_mask|DBE_VALUE|DBE_LOG); - prec->orbv = prec->rbv; - } - } - return; -} - -static long writeValue(aoRecord *prec) -{ - long status; - struct aodset *pdset = (struct aodset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->write_ao)(prec); - return(status); - } - - status = dbGetLink(&prec->siml,DBR_USHORT,&(prec->simm),0,0); - if (status) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->write_ao)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status = dbPutLink(&(prec->siol),DBR_DOUBLE,&(prec->oval),1); - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/aoRecord.dbd.pod b/src/std/rec/aoRecord.dbd.pod deleted file mode 100644 index 41467dcd3..000000000 --- a/src/std/rec/aoRecord.dbd.pod +++ /dev/null @@ -1,917 +0,0 @@ -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=title Analog Output Record (ao) - -This record type is normally used to send an analog value to an output device, -converting it from engineering units into an integer value if necessary. -The record supports alarm and drive limits, rate-of-change limiting, output -value integration, linear and break-point conversion from engineering units, and -graphics and control limits. - -=head2 Record-specific Menus - -=head3 Menu aoOIF - -The OIF field which uses this menu controls whether the record acts as an -integrator (C) or not (C). - -=menu aoOIF - -=head2 Parameter Fields - -The record-specific fields are described below. - -=recordtype ao - -=cut - -menu(aoOIF) { - choice(aoOIF_Full,"Full") - choice(aoOIF_Incremental,"Incremental") -} - -recordtype(ao) { - -=head3 Output Value Determination - -These fields control how the record determines the value to be output when it -gets processed: - -=fields OMSL, DOL, OIF, PVAL, DRVH, DRVL, VAL, OROC, OVAL - -The following steps are performed in order during record processing. - -=head4 Fetch Value, Integrate - -The OMSL menu field is used to determine whether the DOL link and OIF menu -fields should be used during processing or not: - -=over - -=item * -If OMSL is C the DOL and OIF fields are not used. -The new output value is taken from the VAL field, which may have been set from -elsewhere. - -=item * -If OMSL is C the DOL link field is read to obtain a value; if OIF -is C and the DOL link was read successfully, the record's previous -output value PVAL is added to it. - -=back - -=head4 Drive Limits - -The output value is now clipped to the range DRVL to DRVH inclusive, provided -that DRVH > DRVL. -The result is copied into both the VAL and PVAL fields. - -=head4 Limit Rate of Change - -If the OROC field is not zero, the VAL field is now adjusted so it is no more -than OROC different to the previous output value given in OVAL. -OROC thus determines the maximum change in the output value that can occur each -time the record gets processed. -The result is copied into the OVAL field, which is used as the input to the -following Units Conversion processing stage. - -=head3 Units Conversion - -... - - -For analog output records that do not use the Soft Channel device support -routine, the specified conversions (if any) are performed on the OVAL field and -the resulting value in the RVAL field is sent to the address contained in the -output link after it is adjusted by the values in the AOFF and ASLO fields. - -=fields LINR, RVAL, ROFF, EGUF, EGUL, AOFF, ASLO, ESLO, EOFF - -=head4 Conversion Related Fields and the Conversion Process - -Except for analog outputs that use Soft Channel device support, the LINR field -determines if a conversion is performed and which conversion algorithm is used -to convert OVAL to RVAL. - -The LINR field can specify C or C for linear conversions, -C for no conversions at all, or the name of a breakpoint table -such as C for breakpoint conversions. - -Note that the ESLO, EOFF, EGUF, and EGUL fields are only used for linear -conversions. -Also note that none of these fields have any significance for records that use -the Soft Channel device support module. - -=over - -=item EGUF, EGUF - -The user must calculate these fields when configuring the database for records -that use C conversions. -They are used to calculate the values for ESLO and EOFF. -See Conversion Specification for more information on how to calculate these -fields. - -=item AOFF, ASLO - -These fields are adjustment parameters for the raw output values. -They are applied to the raw output value after conversion from engineering -units. - -=item ESLO, EOFF - -Computed by device support using EGUF and EGUL when LINR specifies C. -These values must be supplied by the user when LINR specifies C. -Used only when LINR is C or C. - -=item ROFF - -This field can be used to offset the raw value generated by the conversion -process, which is needed for some kinds of hardware. - -=back - -Conversion proceeds as follows: - -=over - -=item 1. If LINR==LINEAR or LINR==SLOPE, then X = (VAL - EOFF) / ESLO, -else if LINR==NO_CONVERSION, then X = VAL, -else X is obtained via breakpoint table. - -=item 2. X = (X - AOFF) / ASLO - -=item 3. RVAL = round(X) - ROFF - -=back - -To see how the Raw Soft Channel device support routine uses these -fields, see L below for more -information. - -=head3 Output Specification - -The analog output record sends its desired output to the address in the -OUT field. For analog outputs that write their values to devices, the -OUT field must specify the address of the I/O card. In addition, the -DTYP field must contain the name of the device support module. Be aware -that the address format differs according to the I/O bus used. See -Address Specification for information on the format of hardware -addresses. The user can see a list of the device support modules -currently supported at the user's local site by using the dbst utility -in R3.13. - -For soft records the output link can be a database link, a channel -access link, or a constant value. If the link is a constant, no output -is sent. See Address Specification for information on the format of -database and channel access addresses. - -=fields DTYP, OUT - -=head3 Operator Display Parameters - -These parameters are used to present meaningful data to the operator. -They display the value and other parameters of the analog output either -textually or graphically. - -EGU is a string of up to 16 characters describing the units that the -analog output measures. It is retrieved by the get_units record support -routine. - -The HOPR and LOPR fields set the upper and lower display limits for the -VAL, OVAL, PVAL, HIHI, HIGH, LOW, and LOLO fields. Both the -get_graphic_double and get_control_double record support routines -retrieve these fields. If these values are defined, they must be in the -range: DRVL E= LOPR E= HOPR E= DRVH. - -The PREC field determines the floating point precision with which to -display VAL, OVAL and PVAL. It is used whenever the get_precision -record support routine is called. - -See Fields Common to All Record Types for more on the record name -(NAME) and description (DESC) fields. - -=fields EGU, HOPR, LOPR, PREC, NAME, DESC - -=head3 Alarm Parameters - -The possible alarm conditions for analog outputs are the SCAN, READ, -INVALID and limit alarms. The SCAN, READ, and INVALID alarms are called -by the record or device support routines. - -The limit alarms are configured by the user in the HIHI, LOLO, HIGH, -and LOW fields, which must be floating-point values. For each of these -fields, there is a corresponding severity field which can be either -NO_ALARM, MINOR, or MAJOR. - -See Alarm Specification for a complete explanation of alarms and these -fields. See Invalid Alarm Output Action for more information on the -IVOA and IVOV fields. Alarm Fields lists other fields related to a -alarms that are common to all record types. - -=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, IVOA, IVOV - -=head3 Monitor Parameters - -These parameters are used to specify deadbands for monitors on the VAL -field. The monitors are sent when the value field exceeds the last -monitored field by the specified deadband. If these fields have a value -of zero, everytime the value changes, a monitor will be triggered; if -they have a value of -1, everytime the record is processed, monitors -are triggered. ADEL is the deadband for archive monitors, and MDEL the -deadband for all other types of monitors. See Monitor Specification for -a complete explanation of monitors. - -=fields ADEL, MDEL - -=head3 Run-time and Simulation Mode Parameters - -These parameters are used by the run-time code for processing the -analog output. They are not configurable. They represent the current -state of the record. The record support routines use some of them for -more efficient processing. - -The ORAW field is used to decide if monitors should be triggered for -RVAL when monitors are triggered for VAL. The RBV field is the actual -read back value obtained from the hardware itself or from the -associated device driver. It is the responsibility of the device -support routine to give this field a value. - -ORBV is used to decide if monitors should be triggered for RBV at the -same time monitors are triggered for changes in VAL. - -The LALM, MLST, and ALST fields are used to implement the hysteresis -factors for monitor callbacks. - -The INIT field is used to initialize the LBRK field and for smoothing. - -The PBRK field contains a pointer to the current breakpoint table (if -any), and LBRK contains a pointer to the last breakpoint table used. - -The OMOD field indicates whether OVAL differs from VAL. It will be -different if VAL or OVAL have changed since the last time the record -was processed, or if VAL has been adjusted by OROC during the current -processing. - -=fields ORAW, RBV, ORBV, LALM, ALST, MLST, INIT, PBRK, LBRK, PVAL, OMOD - -The following fields are used to operate the analog output in the -simulation mode. See Fields Common to Many Record Types for more -information on these fields. - -=fields SIOL, SIML, SIMM, SIMS - -=cut - - include "dbCommon.dbd" - field(VAL,DBF_DOUBLE) { - prompt("Desired Output") - promptgroup("50 - Output") - asl(ASL0) - pp(TRUE) - } - field(OVAL,DBF_DOUBLE) { - prompt("Output Value") - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(OROC,DBF_DOUBLE) { - prompt("Output Rate of Change") - promptgroup("50 - Output") - interest(1) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup("40 - Input") - interest(1) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - interest(1) - menu(menuOmsl) - } - field(OIF,DBF_MENU) { - prompt("Out Full/Incremental") - promptgroup("50 - Output") - interest(1) - menu(aoOIF) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LINR,DBF_MENU) { - prompt("Linearization") - promptgroup("60 - Convert") - special(SPC_LINCONV) - pp(TRUE) - interest(1) - menu(menuConvert) - } - field(EGUF,DBF_DOUBLE) { - prompt("Eng Units Full") - promptgroup("60 - Convert") - special(SPC_LINCONV) - pp(TRUE) - interest(1) - } - field(EGUL,DBF_DOUBLE) { - prompt("Eng Units Low") - promptgroup("60 - Convert") - special(SPC_LINCONV) - pp(TRUE) - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(ROFF,DBF_ULONG) { - prompt("Raw Offset") - pp(TRUE) - interest(2) - } - field(EOFF,DBF_DOUBLE) { - prompt("EGU to Raw Offset") - promptgroup("60 - Convert") - pp(TRUE) - interest(2) - } - field(ESLO,DBF_DOUBLE) { - prompt("EGU to Raw Slope") - promptgroup("60 - Convert") - pp(TRUE) - interest(2) - initial("1") - } - field(DRVH,DBF_DOUBLE) { - prompt("Drive High Limit") - promptgroup("30 - Action") - pp(TRUE) - interest(1) - prop(YES) - } - field(DRVL,DBF_DOUBLE) { - prompt("Drive Low Limit") - promptgroup("30 - Action") - pp(TRUE) - interest(1) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(AOFF,DBF_DOUBLE) { - prompt("Adjustment Offset") - promptgroup("60 - Convert") - pp(TRUE) - interest(1) - } - field(ASLO,DBF_DOUBLE) { - prompt("Adjustment Slope") - promptgroup("60 - Convert") - pp(TRUE) - interest(1) - } - field(HIHI,DBF_DOUBLE) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_DOUBLE) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_DOUBLE) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_DOUBLE) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HYST,DBF_DOUBLE) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_DOUBLE) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_DOUBLE) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(RVAL,DBF_LONG) { - prompt("Current Raw Value") - pp(TRUE) - } - field(ORAW,DBF_LONG) { - prompt("Previous Raw Value") - special(SPC_NOMOD) - interest(3) - } - field(RBV,DBF_LONG) { - prompt("Readback Value") - special(SPC_NOMOD) - } - field(ORBV,DBF_LONG) { - prompt("Prev Readback Value") - special(SPC_NOMOD) - interest(3) - } - field(PVAL,DBF_DOUBLE) { - prompt("Previous value") - special(SPC_NOMOD) - interest(3) - } - field(LALM,DBF_DOUBLE) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_DOUBLE) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_DOUBLE) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } - field(PBRK,DBF_NOACCESS) { - prompt("Ptrto brkTable") - special(SPC_NOMOD) - interest(4) - extra("void * pbrk") - } - field(INIT,DBF_SHORT) { - prompt("Initialized?") - special(SPC_NOMOD) - interest(3) - } - field(LBRK,DBF_SHORT) { - prompt("LastBreak Point") - special(SPC_NOMOD) - interest(3) - } - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(IVOA,DBF_MENU) { - prompt("INVALID output action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_DOUBLE) { - prompt("INVALID output value") - promptgroup("50 - Output") - interest(2) - } - field(OMOD,DBF_UCHAR) { - prompt("Was OVAL modified?") - special(SPC_NOMOD) - } -} - -=head2 Record Support - -=head3 Record Support Routines - -The following are the record support routines that would be of interest -to an application developer. Other routines are the get_units, -get_precision, get_graphic_double, and get_control_double routines. - -=over - -=item init_record - -This routine initializes SIMM if SIML is a constant or creates a -channel access link if SIML is PV_LINK. If SIOL is PV_LINK a channel -access link is created. - -This routine next checks to see that device support is available. If -DOL is a constant, then VAL is initialized with its value and UDF is -set to FALSE. - -The routine next checks to see if the device support write routine is -defined. If either device support or the device support write routine -does not exist, an error message is issued and processing is -terminated. - -For compatibility with old device supports that don't know EOFF, if -both EOFF and ESLO have their default value, EOFF is set to EGUL. - -If device support includes init_record, it is called. - -INIT is set TRUE. This causes PBRK, LBRK, and smoothing to be -re-initialized. If "backwards" linear conversion is requested, then VAL -is computed from RVAL using the algorithm: - - VAL = ((RVAL+ROFF) * ASLO + AOFF) * ESLO + EOFF - -and UDF is set to FALSE. - -For breakpoint conversion, a call is made to cvtEngToRawBpt and UDF is -then set to FALSE. PVAL is set to VAL. - -=item process - -See next section. - -=item special - -The only special processing for analog output records is SPC_LINCONV -which is invoked whenever either of the fields LINR, EGUF, EGUL or ROFF -is changed If the device support routine special_linconv exists it is -called. - -INIT is set TRUE. This causes PBRK, LBRK, and smoothing to be -re-initialized. - -=item get_value - -Fills in the values of struct valueDes so that they refer to VAL. - -=item get_alarm_double - -Sets the following values: - - upper_alarm_limit = HIHI - upper_warning_limit = HIGH - lower_warning_limit = LOW - lower_alarm_limit = LOLO - -=back - -=head3 Record Processing - -Routine process implements the following algorithm: - -=over - -=item 1. Check to see that the appropriate device support module -exists. If it doesn't, an error message is issued and processing is -terminated with the PACT field set to TRUE. This ensures that processes -will no longer be called for this record. Thus error storms will not -occur. - -=item 2. Check PACT: If PACT is FALSE call fetch_values and convert -which perform the following steps: - -=over - -=item * fetch_values: - -=over - -=item * if DOL is DB_LINK and OMSL is CLOSED_LOOP then get value from -DOL - -=item * if OIF is INCREMENTAL then set value = value + VAL else value = -VAL - -=back - -=item * convert: - -=over - -=item * If Drive limits are defined force value to be within limits - -=item * Set VAL equal to value - -=item * Set UDF to FALSE. - -=item * If OVAL is undefined set it equal to value - -=item * If OROC is defined and not 0 make |value-OVAL| E=OROC - -=item * Set OVAL equal to value - -=item * Compute RVAL from OVAL. using linear or break point table -conversion. For linear conversions the algorithm is RVAL = -(OVAL-EOFF)/ESLO. - -=item * For break point table conversion a call is made to -cvtEngToRawBpt. - -=item * After that, for all conversion types AOFF, ASLO, and ROFF are -calculated in, using the formula RVAL = (RVAL -AOFF) / ASLO - ROFF. - -=back - -=back - -=item 3. Check alarms: This routine checks to see if the new VAL causes -the alarm status and severity to change. If so, NSEV, NSTA and y are -set. It also honors the alarm hysteresis factor (HYST). Thus the value -must change by at least HYST before the alarm status and severity is -reduced. - -=item 4. Check severity and write the new value. See Invalid Alarm -Output Action for details on how invalid alarms affect output records. - -=item 5. If PACT has been changed to TRUE, the device support write -output routine has started but has not completed writing the new value. -In this case, the processing routine merely returns, leaving PACT TRUE. - -=item 6. Check to see if monitors should be invoked: - -=over - -=item * Alarm monitors are invoked if the alarm status or severity has -changed. - -=item * Archive and value change monitors are invoked if ADEL and MDEL -conditions are met. - -=item * Monitors for RVAL and for RBV are checked whenever other -monitors are invoked. - -=item * NSEV and NSTA are reset to 0. - -=back - -=item 7. Scan forward link if necessary, set PACT and INIT FALSE, and -return. - -=back - -=head2 Device Support - -=head3 Fields Of Interest To Device Support - -Each analog output record must have an associated set of device support -routines. The primary responsibility of the device support routines is -to output a new value whenever write_ao is called. The device support -routines are primarily interested in the following fields: - -=over - -=item * -PACT E Process Active, used to indicate asynchronous completion - -=item * -DPVT E Device Private, reserved for device support to use - -=item * -OUT E Output Link, provides addressing information - -=item * -EGUF E Engineering Units Full - -=item * -EGUL E Engineering Units Low - -=item * -ESLO E Engineering Unit Slope - -=item * -EOFF E Engineering Unit Offset - -=item * -OVAL E Output Value, in Engineering units - -=item * -RVAL E Raw Output Value, after conversion - -=back - -=head3 Device Support routines - -Device support consists of the following routines: - -=over - -=item C - -This optional routine is called by the IOC command C and is passed the -report level that was requested by the user. -It should print a report on the state of the device support to stdout. -The C parameter may be used to output increasingly more detailed -information at higher levels, or to select different types of information with -different levels. -Level zero should print no more than a small summary. - -=item C - -This optional routine is called twice at IOC initialization time. -The first call happens before any of the C calls are made, with -the integer parameter C set to 0. -The second call happens after all of the C calls have been made, -with C set to 1. - -=item C - -This optional routine is called by the record initialization code for each ao -record instance that has its DTYP field set to use this device support. -It is normally used to check that the OUT address has the expected type and -points to a valid device; to allocate any record-specific buffer space and -other memory; and to connect any communication channels needed for the -C routine to work properly. - -If the record type's unit conversion features are used, the C -routine should calculate appropriate values for the ESLO and EOFF fields from -the EGUL and EGUF field values. -This calculation only has to be performed if the record's LINR field is set to -C, but it is not necessary to check that condition first. -This same calculation takes place in the C routine, so the -implementation can usually just call that routine to perform the task. - -If the the last output value can be read back from the hardware, this routine -should also fetch that value and put it into the record's RVAL or VAL field. The -return value should be zero if the RVAL field has been set, or 2 if either the -VAL field has been set or if the last output value cannot be retrieved. - -=item C - -This optional routine is called whenever the record's SCAN field is being -changed to or from the value C to find out which I/O Interrupt Scan -list the record should be added to or deleted from. -If this routine is not provided, it will not be possible to set the SCAN field -to the value C at all. - -The C parameter is zero when the record is being added to the scan list, -and one when it is being removed from the list. -The routine must determine which interrupt source the record should be connected -to, which it indicates by the scan list that it points the location at C<*piosl> -to before returning. -It can prevent the SCAN field from being changed at all by returning a non-zero -value to its caller. - -In most cases the device support will create the I/O Interrupt Scan lists that -it returns for itself, by calling C once for -each separate interrupt source. -That API allocates memory and inializes the list, then passes back a pointer to -the new list in the location at C<*piosl>. -When the device support receives notification that the interrupt has occurred, -it announces that to the IOC by calling C -which will arrange for the appropriate records to be processed in a suitable -thread. -The C routine is safe to call from an interrupt service routine -on embedded architectures (vxWorks and RTEMS). - -=item C - -This essential routine is called whenever the record has a new output value to -send to the device. It is responsible for performing the write operation, using -either the engineering units value found in the record's OVAL field, or the raw -value from the record's RVAL field if the record type's unit conversion -facilities are used. A return value of zero indicates success, any other value -indicates that an error occurred. - -This routine must not block (busy-wait) if the device takes more than a few -microseconds to accept the new value. In that case the routine must use -asynchronous completion to tell the record when the write operation eventually -completes. It signals that this is an asynchronous operation by setting the -record's PACT field to TRUE before it returns, having arranged for the record's -C routine to be called later once the write operation is over. When -that happens the C routine will be called again with PACT still set -to TRUE; it should then set it to FALSE to indicate the write has completed, and -return. - -=item C - -This optional routine should be provided if the record type's unit conversion -features are used by the device support's C routine utilizing the -RVAL field rather than OVAL or VAL. -It is called by the record code whenever any of the the fields LINR, EGUL or -EGUF are modified and LINR has the value C. -The routine must calculate and set the fields EOFF and ESLO appropriately based -on the new values of EGUL and EGUF. - -These calculations can be expressed in terms of the minimum and maximum raw -values that the C routine can accept in the RVAL field. -When VAL is EGUF the RVAL field will be set to I, and when VAL is -EGUL the RVAL field will become I. -The fomulae to use are: - -=over - -EOFF = (I * EGUL E I * EGUF) / -(I E I) - -ESLO = (EGUF E EGUL) / (I E I) - -=back - -Note that the record support sets EOFF to EGUL before calling this routine, -which is a very common case (I is zero). - -=back - -=head2 Device Support For Soft Records - -Two soft device support modules Soft Channel and Raw Soft Channel are -provided for output records not related to actual hardware devices. The -OUT link type must be either a CONSTANT, DB_LINK, or CA_LINK. - -=head3 Soft Channel - -This module writes the current value of OVAL. - -If the OUT link type is PV_LINK, then dbCaAddInlink is called by -init_record. init_record always returns a value of 2, which means that -no conversion will ever be attempted. - -write_ao calls recGblPutLinkValue to write the current value of VAL. -See Soft Output for details. - -=head3 Raw Soft Channel - -This module is like the previous except that it writes the current -value of RVAL. - -=cut diff --git a/src/std/rec/biRecord.c b/src/std/rec/biRecord.c deleted file mode 100644 index 7afea3d9d..000000000 --- a/src/std/rec/biRecord.c +++ /dev/null @@ -1,294 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recBi.c - Record Support Routines for Binary Input records */ -/* - * Original Author: Bob Dalesio - * Date: 7-14-89 - * - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbFldTypes.h" -#include "dbEvent.h" -#include "devSup.h" -#include "errMdef.h" -#include "menuSimm.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" - -#define GEN_SIZE_OFFSET -#include "biRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -static long get_enum_str(const DBADDR *, char *); -static long get_enum_strs(const DBADDR *, struct dbr_enumStrs *); -static long put_enum_str(const DBADDR *, const char *); -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL -rset biRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double }; -struct bidset { /* binary input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bi;/*(0,2)=> success and convert, don't convert)*/ - /* if convert then raw value stored in rval */ -}; -epicsExportAddress(rset,biRSET); -static void checkAlarms(biRecord *); -static void monitor(biRecord *); -static long readValue(biRecord *); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct biRecord *prec = (struct biRecord *)pcommon; - struct bidset *pdset; - long status; - - if (pass==0) return(0); - - recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm); - recGblInitConstantLink(&prec->siol,DBF_USHORT,&prec->sval); - if(!(pdset = (struct bidset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET,(void *)prec,"bi: init_record"); - return(S_dev_noDSET); - } - /* must have read_bi function defined */ - if( (pdset->number < 5) || (pdset->read_bi == NULL) ) { - recGblRecordError(S_dev_missingSup,(void *)prec,"bi: init_record"); - return(S_dev_missingSup); - } - if( pdset->init_record ) { - if((status=(*pdset->init_record)(prec))) return(status); - } - prec->mlst = prec->val; - prec->lalm = prec->val; - prec->oraw = prec->rval; - return(0); -} - -static long process(struct dbCommon *pcommon) -{ - struct biRecord *prec = (struct biRecord *)pcommon; - struct bidset *pdset = (struct bidset *)(prec->dset); - long status; - unsigned char pact=prec->pact; - - if( (pdset==NULL) || (pdset->read_bi==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"read_bi"); - return(S_dev_missingSup); - } - - status=readValue(prec); /* read the new value */ - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - if(status==0) { /* convert rval to val */ - if(prec->rval==0) prec->val =0; - else prec->val = 1; - prec->udf = FALSE; - } - else if(status==2) status=0; - /* check for alarms */ - checkAlarms(prec); - /* check event list */ - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - -static long get_enum_str(const DBADDR *paddr, char *pstring) -{ - biRecord *prec=(biRecord *)paddr->precord; - int index; - unsigned short *pfield = (unsigned short *)paddr->pfield; - - - index = dbGetFieldIndex(paddr); - if(index!=biRecordVAL) { - strcpy(pstring,"Illegal_Value"); - } else if(*pfield==0) { - strncpy(pstring,prec->znam,sizeof(prec->znam)); - pstring[sizeof(prec->znam)] = 0; - } else if(*pfield==1) { - strncpy(pstring,prec->onam,sizeof(prec->onam)); - pstring[sizeof(prec->onam)] = 0; - } else { - strcpy(pstring,"Illegal_Value"); - } - return(0); -} - -static long get_enum_strs(const DBADDR *paddr,struct dbr_enumStrs *pes) -{ - biRecord *prec=(biRecord *)paddr->precord; - - pes->no_str = 2; - memset(pes->strs,'\0',sizeof(pes->strs)); - strncpy(pes->strs[0],prec->znam,sizeof(prec->znam)); - if(*prec->znam!=0) pes->no_str=1; - strncpy(pes->strs[1],prec->onam,sizeof(prec->onam)); - if(*prec->onam!=0) pes->no_str=2; - return(0); -} - -static long put_enum_str(const DBADDR *paddr, const char *pstring) -{ - biRecord *prec=(biRecord *)paddr->precord; - - if(strncmp(pstring,prec->znam,sizeof(prec->znam))==0) prec->val = 0; - else if(strncmp(pstring,prec->onam,sizeof(prec->onam))==0) prec->val = 1; - else return(S_db_badChoice); - prec->udf=FALSE; - return(0); -} - - -static void checkAlarms(biRecord *prec) -{ - unsigned short val = prec->val; - - - if(prec->udf == TRUE){ - recGblSetSevr(prec,UDF_ALARM,prec->udfs); - return; - } - - if(val>1)return; - /* check for state alarm */ - if (val == 0){ - recGblSetSevr(prec,STATE_ALARM,prec->zsv); - }else{ - recGblSetSevr(prec,STATE_ALARM,prec->osv); - } - - /* check for cos alarm */ - if(val == prec->lalm) return; - recGblSetSevr(prec,COS_ALARM,prec->cosv); - prec->lalm = val; - return; -} - -static void monitor(biRecord *prec) -{ - unsigned short monitor_mask; - - monitor_mask = recGblResetAlarms(prec); - /* check for value change */ - if (prec->mlst != prec->val){ - /* post events for value change and archive change */ - monitor_mask |= (DBE_VALUE | DBE_LOG); - /* update last value monitored */ - prec->mlst = prec->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(prec,&prec->val,monitor_mask); - } - if(prec->oraw!=prec->rval) { - db_post_events(prec,&prec->rval, - monitor_mask|DBE_VALUE|DBE_LOG); - prec->oraw = prec->rval; - } - return; -} - -static long readValue(biRecord *prec) -{ - long status; - struct bidset *pdset = (struct bidset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->read_bi)(prec); - return(status); - } - - status = dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0); - if (status) - return(status); - - if (prec->simm == menuSimmNO){ - status=(*pdset->read_bi)(prec); - return(status); - } - if (prec->simm == menuSimmYES){ - status=dbGetLink(&(prec->siol),DBR_ULONG,&(prec->sval),0,0); - if (status==0){ - prec->val=(unsigned short)prec->sval; - prec->udf=FALSE; - } - status=2; /* dont convert */ - } - else if (prec->simm == menuSimmRAW){ - status=dbGetLink(&(prec->siol),DBR_ULONG,&(prec->sval),0,0); - if (status==0){ - prec->rval=prec->sval; - prec->udf=FALSE; - } - status=0; /* convert since we've written RVAL */ - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/biRecord.dbd b/src/std/rec/biRecord.dbd deleted file mode 100644 index fb3588fb1..000000000 --- a/src/std/rec/biRecord.dbd +++ /dev/null @@ -1,107 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(bi) { - include "dbCommon.dbd" - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(VAL,DBF_ENUM) { - prompt("Current Value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(ZSV,DBF_MENU) { - prompt("Zero Error Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(OSV,DBF_MENU) { - prompt("One Error Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(COSV,DBF_MENU) { - prompt("Change of State Svr") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(ZNAM,DBF_STRING) { - prompt("Zero Name") - promptgroup("80 - Display") - pp(TRUE) - interest(1) - size(26) - prop(YES) - } - field(ONAM,DBF_STRING) { - prompt("One Name") - promptgroup("80 - Display") - pp(TRUE) - interest(1) - size(26) - prop(YES) - } - field(RVAL,DBF_ULONG) { - prompt("Raw Value") - pp(TRUE) - } - field(ORAW,DBF_ULONG) { - prompt("prev Raw Value") - special(SPC_NOMOD) - interest(3) - } - field(MASK,DBF_ULONG) { - prompt("Hardware Mask") - special(SPC_NOMOD) - interest(1) - } - field(LALM,DBF_USHORT) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_USHORT) { - prompt("Last Value Monitored") - special(SPC_NOMOD) - interest(3) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_ULONG) { - prompt("Simulation Value") - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuSimm) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } -} diff --git a/src/std/rec/boRecord.c b/src/std/rec/boRecord.c deleted file mode 100644 index 8f60a0be5..000000000 --- a/src/std/rec/boRecord.c +++ /dev/null @@ -1,429 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recBo.c - Record Support Routines for Binary Output records */ -/* - * Original Author: Bob Dalesio - * Date: 7-14-89 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "callback.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#include "menuIvoa.h" -#include "menuOmsl.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "boRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -static long get_enum_str(const DBADDR *, char *); -static long get_enum_strs(const DBADDR *, struct dbr_enumStrs *); -static long put_enum_str(const DBADDR *, const char *); -#define get_graphic_double NULL -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -#define get_alarm_double NULL - -rset boRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,boRSET); - -int boHIGHprecision = 2; -epicsExportAddress(int, boHIGHprecision); -double boHIGHlimit = 100000; -epicsExportAddress(double, boHIGHlimit); - -struct bodset { /* binary output dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns:(0,2)=>(success,success no convert*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_bo;/*returns: (-1,0)=>(failure,success)*/ -}; - - -/* control block for callback*/ -typedef struct myCallback { - CALLBACK callback; - struct dbCommon *precord; -}myCallback; - -static void checkAlarms(boRecord *); -static void monitor(boRecord *); -static long writeValue(boRecord *); - -static void myCallbackFunc(CALLBACK *arg) -{ - myCallback *pcallback; - boRecord *prec; - - callbackGetUser(pcallback,arg); - prec=(boRecord *)pcallback->precord; - dbScanLock((struct dbCommon *)prec); - if(prec->pact) { - if((prec->val==1) && (prec->high>0)){ - myCallback *pcallback; - pcallback = (myCallback *)(prec->rpvt); - callbackSetPriority(prec->prio, &pcallback->callback); - callbackRequestDelayed(&pcallback->callback,(double)prec->high); - } - } else { - prec->val = 0; - dbProcess((struct dbCommon *)prec); - } - dbScanUnlock((struct dbCommon *)prec); -} - -static long init_record(struct dbCommon *pcommon,int pass) -{ - struct boRecord *prec = (struct boRecord *)pcommon; - struct bodset *pdset = (struct bodset *) prec->dset; - unsigned short ival = 0; - long status = 0; - myCallback *pcallback; - - if (pass == 0) - return 0; - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "bo: init_record"); - return S_dev_noDSET; - } - - /* must have write_bo functions defined */ - if ((pdset->number < 5) || (pdset->write_bo == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "bo: init_record"); - return S_dev_missingSup; - } - - /* get the initial value */ - if (recGblInitConstantLink(&prec->dol, DBF_USHORT, &ival)) { - prec->val = !!ival; - prec->udf = FALSE; - } - - pcallback = (myCallback *) calloc(1, sizeof(myCallback)); - prec->rpvt = pcallback; - callbackSetCallback(myCallbackFunc, &pcallback->callback); - callbackSetUser(pcallback, &pcallback->callback); - pcallback->precord = (struct dbCommon *) prec; - - if (pdset->init_record) { - status=(*pdset->init_record)(prec); - if(status==0) { - if(prec->rval==0) prec->val = 0; - else prec->val = 1; - prec->udf = FALSE; - } else if (status==2) status=0; - } - prec->mlst = prec->val; - /* convert val to rval */ - if ( prec->mask != 0 ) { - if(prec->val==0) prec->rval = 0; - else prec->rval = prec->mask; - } else prec->rval = (epicsUInt32)prec->val; - - prec->mlst = prec->val; - prec->lalm = prec->val; - prec->oraw = prec->rval; - prec->orbv = prec->rbv; - return(status); -} - -static long process(struct dbCommon *pcommon) -{ - struct boRecord *prec = (struct boRecord *)pcommon; - struct bodset *pdset = (struct bodset *)(prec->dset); - long status=0; - unsigned char pact=prec->pact; - - if( (pdset==NULL) || (pdset->write_bo==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"write_bo"); - return(S_dev_missingSup); - } - if (!prec->pact) { - if (!dbLinkIsConstant(&prec->dol) && - prec->omsl == menuOmslclosed_loop) { - unsigned short val; - - prec->pact = TRUE; - status=dbGetLink(&prec->dol,DBR_USHORT, &val,0,0); - prec->pact = FALSE; - if(status==0){ - prec->val = val; - prec->udf = FALSE; - }else { - recGblSetSevr(prec,LINK_ALARM,INVALID_ALARM); - } - } - - /* convert val to rval */ - if ( prec->mask != 0 ) { - if(prec->val==0) prec->rval = 0; - else prec->rval = prec->mask; - } else prec->rval = (epicsUInt32)prec->val; - } - - /* check for alarms */ - checkAlarms(prec); - - if (prec->nsev < INVALID_ALARM ) - status=writeValue(prec); /* write the new value */ - else { - switch (prec->ivoa) { - case (menuIvoaContinue_normally) : - status=writeValue(prec); /* write the new value */ - break; - case (menuIvoaDon_t_drive_outputs) : - break; - case (menuIvoaSet_output_to_IVOV) : - if(prec->pact == FALSE){ - /* convert val to rval */ - prec->val=prec->ivov; - if ( prec->mask != 0 ) { - if(prec->val==0) prec->rval = 0; - else prec->rval = prec->mask; - } else prec->rval = (epicsUInt32)prec->val; - } - status=writeValue(prec); /* write the new value */ - break; - default : - status=-1; - recGblRecordError(S_db_badField,(void *)prec, - "bo:process Illegal IVOA field"); - } - } - - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - if((prec->val==1) && (prec->high>0)){ - myCallback *pcallback; - pcallback = (myCallback *)(prec->rpvt); - callbackSetPriority(prec->prio, &pcallback->callback); - callbackRequestDelayed(&pcallback->callback,(double)prec->high); - } - /* check event list */ - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - -#define indexof(field) boRecord##field - -static long get_units(DBADDR *paddr, char *units) -{ - if(dbGetFieldIndex(paddr) == indexof(HIGH)) - strcpy(units, "s"); - return(0); -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - if(dbGetFieldIndex(paddr) == indexof(HIGH)) - *precision = boHIGHprecision; - else - recGblGetPrec(paddr,precision); - return(0); -} - -static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd) -{ - if(dbGetFieldIndex(paddr) == indexof(HIGH)) { - pcd->lower_ctrl_limit = 0.0; - pcd->upper_ctrl_limit = boHIGHlimit; - } else - recGblGetControlDouble(paddr,pcd); - return(0); -} - -static long get_enum_str(const DBADDR *paddr, char *pstring) -{ - boRecord *prec=(boRecord *)paddr->precord; - int index; - unsigned short *pfield = (unsigned short *)paddr->pfield; - - - index = dbGetFieldIndex(paddr); - if(index!=indexof(VAL)) { - strcpy(pstring,"Illegal_Value"); - } else if(*pfield==0) { - strncpy(pstring,prec->znam,sizeof(prec->znam)); - pstring[sizeof(prec->znam)] = 0; - } else if(*pfield==1) { - strncpy(pstring,prec->onam,sizeof(prec->onam)); - pstring[sizeof(prec->onam)] = 0; - } else { - strcpy(pstring,"Illegal_Value"); - } - return(0); -} - -static long get_enum_strs(const DBADDR *paddr,struct dbr_enumStrs *pes) -{ - boRecord *prec=(boRecord *)paddr->precord; - - /*SETTING no_str=0 breaks channel access clients*/ - pes->no_str = 2; - memset(pes->strs,'\0',sizeof(pes->strs)); - strncpy(pes->strs[0],prec->znam,sizeof(prec->znam)); - if(*prec->znam!=0) pes->no_str=1; - strncpy(pes->strs[1],prec->onam,sizeof(prec->onam)); - if(*prec->onam!=0) pes->no_str=2; - return(0); -} -static long put_enum_str(const DBADDR *paddr, const char *pstring) -{ - boRecord *prec=(boRecord *)paddr->precord; - - if(strncmp(pstring,prec->znam,sizeof(prec->znam))==0) prec->val = 0; - else if(strncmp(pstring,prec->onam,sizeof(prec->onam))==0) prec->val = 1; - else return(S_db_badChoice); - return(0); -} - - -static void checkAlarms(boRecord *prec) -{ - unsigned short val = prec->val; - - /* check for udf alarm */ - if(prec->udf == TRUE ){ - recGblSetSevr(prec,UDF_ALARM,prec->udfs); - } - - /* check for state alarm */ - if (val == 0){ - recGblSetSevr(prec,STATE_ALARM,prec->zsv); - }else{ - recGblSetSevr(prec,STATE_ALARM,prec->osv); - } - - /* check for cos alarm */ - if(val == prec->lalm) return; - recGblSetSevr(prec,COS_ALARM,prec->cosv); - prec->lalm = val; - return; -} - -static void monitor(boRecord *prec) -{ - unsigned short monitor_mask; - - monitor_mask = recGblResetAlarms(prec); - /* check for value change */ - if (prec->mlst != prec->val){ - /* post events for value change and archive change */ - monitor_mask |= (DBE_VALUE | DBE_LOG); - /* update last value monitored */ - prec->mlst = prec->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(prec,&prec->val,monitor_mask); - } - if(prec->oraw!=prec->rval) { - db_post_events(prec,&prec->rval, - monitor_mask|DBE_VALUE|DBE_LOG); - prec->oraw = prec->rval; - } - if(prec->orbv!=prec->rbv) { - db_post_events(prec,&prec->rbv, - monitor_mask|DBE_VALUE|DBE_LOG); - prec->orbv = prec->rbv; - } - return; -} - -static long writeValue(boRecord *prec) -{ - long status; - struct bodset *pdset = (struct bodset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->write_bo)(prec); - return(status); - } - - status=dbGetLink(&prec->siml,DBR_USHORT, &prec->simm,0,0); - if (status) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->write_bo)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status=dbPutLink(&(prec->siol),DBR_USHORT, &(prec->val),1); - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/boRecord.dbd b/src/std/rec/boRecord.dbd deleted file mode 100644 index fd002c368..000000000 --- a/src/std/rec/boRecord.dbd +++ /dev/null @@ -1,155 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(bo) { - include "dbCommon.dbd" - field(VAL,DBF_ENUM) { - prompt("Current Value") - promptgroup("50 - Output") - asl(ASL0) - pp(TRUE) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - interest(1) - menu(menuOmsl) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup("40 - Input") - interest(1) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(HIGH,DBF_DOUBLE) { - prompt("Seconds to Hold High") - promptgroup("30 - Action") - interest(1) - } - field(ZNAM,DBF_STRING) { - prompt("Zero Name") - promptgroup("80 - Display") - pp(TRUE) - interest(1) - size(26) - prop(YES) - } - field(ONAM,DBF_STRING) { - prompt("One Name") - promptgroup("80 - Display") - pp(TRUE) - interest(1) - size(26) - prop(YES) - } - field(RVAL,DBF_ULONG) { - prompt("Raw Value") - pp(TRUE) - } - field(ORAW,DBF_ULONG) { - prompt("prev Raw Value") - special(SPC_NOMOD) - interest(3) - } - field(MASK,DBF_ULONG) { - prompt("Hardware Mask") - special(SPC_NOMOD) - interest(1) - } - field(RPVT,DBF_NOACCESS) { - prompt("Record Private") - special(SPC_NOMOD) - interest(4) - extra("void * rpvt") - } - field(WDPT,DBF_NOACCESS) { - prompt("Watch Dog Timer ID") - special(SPC_NOMOD) - interest(4) - extra("void * wdpt") - } - field(ZSV,DBF_MENU) { - prompt("Zero Error Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(OSV,DBF_MENU) { - prompt("One Error Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(COSV,DBF_MENU) { - prompt("Change of State Sevr") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(RBV,DBF_ULONG) { - prompt("Readback Value") - special(SPC_NOMOD) - } - field(ORBV,DBF_ULONG) { - prompt("Prev Readback Value") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_USHORT) { - prompt("Last Value Monitored") - special(SPC_NOMOD) - interest(3) - } - field(LALM,DBF_USHORT) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(IVOA,DBF_MENU) { - prompt("INVALID outpt action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_USHORT) { - prompt("INVALID output value") - promptgroup("50 - Output") - interest(2) - } -} - -variable(boHIGHprecision, int) -variable(boHIGHlimit, double) diff --git a/src/std/rec/calcRecord.c b/src/std/rec/calcRecord.c deleted file mode 100644 index 12a58d1c8..000000000 --- a/src/std/rec/calcRecord.c +++ /dev/null @@ -1,442 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Record Support Routines for Calculation records */ -/* - * Original Author: Julie Sander and Bob Dalesio - * Date: 7-27-87 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "epicsMath.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" - -#define GEN_SIZE_OFFSET -#include "calcRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Hysterisis for alarm filtering: 1-1/e */ -#define THRESHOLD 0.6321 - -/* Create RSET - Record Support Entry Table */ - -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *prec, int pass); -static long process(struct dbCommon *prec); -static long special(DBADDR *paddr, int after); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *paddr, char *units); -static long get_precision(const DBADDR *paddr, long *precision); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd); -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd); -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad); - -rset calcRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, calcRSET); - -static void checkAlarms(calcRecord *prec, epicsTimeStamp *timeLast); -static void monitor(calcRecord *prec); -static int fetch_values(calcRecord *prec); - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct calcRecord *prec = (struct calcRecord *)pcommon; - struct link *plink; - double *pvalue; - int i; - short error_number; - - if (pass==0) return(0); - - plink = &prec->inpa; - pvalue = &prec->a; - for (i = 0; i < CALCPERFORM_NARGS; i++, plink++, pvalue++) { - recGblInitConstantLink(plink, DBF_DOUBLE, pvalue); - } - if (postfix(prec->calc, prec->rpcl, &error_number)) { - recGblRecordError(S_db_badField, (void *)prec, - "calc: init_record: Illegal CALC field"); - errlogPrintf("%s.CALC: %s in expression \"%s\"\n", - prec->name, calcErrorStr(error_number), prec->calc); - } - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct calcRecord *prec = (struct calcRecord *)pcommon; - epicsTimeStamp timeLast; - - prec->pact = TRUE; - if (fetch_values(prec) == 0) { - if (calcPerform(&prec->a, &prec->val, prec->rpcl)) { - recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM); - } else - prec->udf = isnan(prec->val); - } - - timeLast = prec->time; - recGblGetTimeStamp(prec); - /* check for alarms */ - checkAlarms(prec, &timeLast); - /* check event list */ - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - prec->pact = FALSE; - return 0; -} - -static long special(DBADDR *paddr, int after) -{ - calcRecord *prec = (calcRecord *)paddr->precord; - short error_number; - - if (!after) return 0; - if (paddr->special == SPC_CALC) { - if (postfix(prec->calc, prec->rpcl, &error_number)) { - recGblRecordError(S_db_badField, (void *)prec, - "calc: Illegal CALC field"); - errlogPrintf("%s.CALC: %s in expression \"%s\"\n", - prec->name, calcErrorStr(error_number), prec->calc); - return S_db_badField; - } - return 0; - } - recGblDbaddrError(S_db_badChoice, paddr, "calc::special - bad special value!"); - return S_db_badChoice; -} - -#define indexof(field) calcRecord##field - -static long get_linkNumber(int fieldIndex) { - if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L)) - return fieldIndex - indexof(A); - if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL)) - return fieldIndex - indexof(LA); - return -1; -} - -static long get_units(DBADDR *paddr, char *units) -{ - calcRecord *prec = (calcRecord *)paddr->precord; - int linkNumber; - - if(paddr->pfldDes->field_type == DBF_DOUBLE) { - linkNumber = get_linkNumber(dbGetFieldIndex(paddr)); - if (linkNumber >= 0) - dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE); - else - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *pprecision) -{ - calcRecord *prec = (calcRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - *pprecision = prec->prec; - if (fieldIndex == indexof(VAL)) - return 0; - - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - short precision; - - if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0) - *pprecision = precision; - } else - recGblGetPrec(paddr, pprecision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - calcRecord *prec = (calcRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - switch (fieldIndex) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pgd->lower_disp_limit = prec->lopr; - pgd->upper_disp_limit = prec->hopr; - break; - default: - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetGraphicLimits(&prec->inpa + linkNumber, - &pgd->lower_disp_limit, - &pgd->upper_disp_limit); - } else - recGblGetGraphicDouble(paddr,pgd); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - calcRecord *prec = (calcRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pcd->lower_ctrl_limit = prec->lopr; - pcd->upper_ctrl_limit = prec->hopr; - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return 0; -} - -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - calcRecord *prec = (calcRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - if (fieldIndex == indexof(VAL)) { - pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN; - pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN; - pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN; - pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN; - } else { - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetAlarmLimits(&prec->inpa + linkNumber, - &pad->lower_alarm_limit, - &pad->lower_warning_limit, - &pad->upper_warning_limit, - &pad->upper_alarm_limit); - } else - recGblGetAlarmDouble(paddr, pad); - } - return 0; -} - -static void checkAlarms(calcRecord *prec, epicsTimeStamp *timeLast) -{ - - enum { - range_Lolo = 1, - range_Low, - range_Normal, - range_High, - range_Hihi - } alarmRange; - static const epicsEnum16 range_stat[] = { - SOFT_ALARM, LOLO_ALARM, LOW_ALARM, - NO_ALARM, HIGH_ALARM, HIHI_ALARM - }; - - double val, hyst, lalm, alev, aftc, afvl; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - prec->afvl = 0; - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* check VAL against alarm limits */ - if ((asev = prec->hhsv) && - (val >= (alev = prec->hihi) || - ((lalm == alev) && (val >= alev - hyst)))) - alarmRange = range_Hihi; - else - if ((asev = prec->llsv) && - (val <= (alev = prec->lolo) || - ((lalm == alev) && (val <= alev + hyst)))) - alarmRange = range_Lolo; - else - if ((asev = prec->hsv) && - (val >= (alev = prec->high) || - ((lalm == alev) && (val >= alev - hyst)))) - alarmRange = range_High; - else - if ((asev = prec->lsv) && - (val <= (alev = prec->low) || - ((lalm == alev) && (val <= alev + hyst)))) - alarmRange = range_Low; - else { - alev = val; - asev = NO_ALARM; - alarmRange = range_Normal; - } - - aftc = prec->aftc; - afvl = 0; - - if (aftc > 0) { - /* Apply level filtering */ - afvl = prec->afvl; - if (afvl == 0) { - afvl = (double)alarmRange; - } else { - double t = epicsTimeDiffInSeconds(&prec->time, timeLast); - double alpha = aftc / (t + aftc); - - /* The sign of afvl indicates whether the result should be - * rounded up or down. This gives the filter hysteresis. - * If afvl > 0 the floor() function rounds to a lower alarm - * level, otherwise to a higher. - */ - afvl = alpha * afvl + - ((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange; - if (afvl - floor(afvl) > THRESHOLD) - afvl = -afvl; /* reverse rounding */ - - alarmRange = abs((int)floor(afvl)); - switch (alarmRange) { - case range_Hihi: - asev = prec->hhsv; - alev = prec->hihi; - break; - case range_High: - asev = prec->hsv; - alev = prec->high; - break; - case range_Normal: - asev = NO_ALARM; - break; - case range_Low: - asev = prec->lsv; - alev = prec->low; - break; - case range_Lolo: - asev = prec->llsv; - alev = prec->lolo; - break; - } - } - } - prec->afvl = afvl; - - if (asev) { - /* Report alarm condition, store LALM for future HYST calculations */ - if (recGblSetSevr(prec, range_stat[alarmRange], asev)) - prec->lalm = alev; - } else { - /* No alarm condition, reset LALM */ - prec->lalm = val; - } - -} - -static void monitor(calcRecord *prec) -{ - unsigned monitor_mask; - double *pnew, *pprev; - int i; - - monitor_mask = recGblResetAlarms(prec); - - /* check for value change */ - recGblCheckDeadband(&prec->mlst, prec->val, prec->mdel, &monitor_mask, DBE_VALUE); - - /* check for archive change */ - recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask, DBE_ARCHIVE); - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(prec, &prec->val, monitor_mask); - } - - /* check all input fields for changes*/ - pnew = &prec->a; - pprev = &prec->la; - for (i = 0; i < CALCPERFORM_NARGS; i++, pnew++, pprev++) { - if (*pnew != *pprev || - monitor_mask & DBE_ALARM) { - db_post_events(prec, pnew, monitor_mask | DBE_VALUE | DBE_LOG); - *pprev = *pnew; - } - } - return; -} - -static int fetch_values(calcRecord *prec) -{ - struct link *plink; - double *pvalue; - long status = 0; - int i; - - plink = &prec->inpa; - pvalue = &prec->a; - for(i = 0; i < CALCPERFORM_NARGS; i++, plink++, pvalue++) { - int newStatus; - - newStatus = dbGetLink(plink, DBR_DOUBLE, pvalue, 0, 0); - if (status == 0) status = newStatus; - } - return status; -} diff --git a/src/std/rec/calcRecord.dbd b/src/std/rec/calcRecord.dbd deleted file mode 100644 index e7eb0eee3..000000000 --- a/src/std/rec/calcRecord.dbd +++ /dev/null @@ -1,324 +0,0 @@ -#************************************************************************* -# Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(calc) { - include "dbCommon.dbd" - field(VAL,DBF_DOUBLE) { - prompt("Result") - promptgroup("50 - Output") - asl(ASL0) - } - field(CALC,DBF_STRING) { - prompt("Calculation") - promptgroup("30 - Action") - special(SPC_CALC) - pp(TRUE) - size(80) - initial("0") - } - field(INPA,DBF_INLINK) { - prompt("Input A") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPB,DBF_INLINK) { - prompt("Input B") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPC,DBF_INLINK) { - prompt("Input C") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPD,DBF_INLINK) { - prompt("Input D") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPE,DBF_INLINK) { - prompt("Input E") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPF,DBF_INLINK) { - prompt("Input F") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPG,DBF_INLINK) { - prompt("Input G") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPH,DBF_INLINK) { - prompt("Input H") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPI,DBF_INLINK) { - prompt("Input I") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPJ,DBF_INLINK) { - prompt("Input J") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPK,DBF_INLINK) { - prompt("Input K") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPL,DBF_INLINK) { - prompt("Input L") - promptgroup("42 - Input G-L") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Rng") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HIHI,DBF_DOUBLE) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_DOUBLE) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_DOUBLE) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_DOUBLE) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(AFTC, DBF_DOUBLE) { - prompt("Alarm Filter Time Constant") - promptgroup("70 - Alarm") - interest(1) - } - field(AFVL, DBF_DOUBLE) { - prompt("Alarm Filter Value") - special(SPC_NOMOD) - interest(3) - } - field(HYST,DBF_DOUBLE) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_DOUBLE) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_DOUBLE) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(A,DBF_DOUBLE) { - prompt("Value of Input A") - pp(TRUE) - } - field(B,DBF_DOUBLE) { - prompt("Value of Input B") - pp(TRUE) - } - field(C,DBF_DOUBLE) { - prompt("Value of Input C") - pp(TRUE) - } - field(D,DBF_DOUBLE) { - prompt("Value of Input D") - pp(TRUE) - } - field(E,DBF_DOUBLE) { - prompt("Value of Input E") - pp(TRUE) - } - field(F,DBF_DOUBLE) { - prompt("Value of Input F") - pp(TRUE) - } - field(G,DBF_DOUBLE) { - prompt("Value of Input G") - pp(TRUE) - } - field(H,DBF_DOUBLE) { - prompt("Value of Input H") - pp(TRUE) - } - field(I,DBF_DOUBLE) { - prompt("Value of Input I") - pp(TRUE) - } - field(J,DBF_DOUBLE) { - prompt("Value of Input J") - pp(TRUE) - } - field(K,DBF_DOUBLE) { - prompt("Value of Input K") - pp(TRUE) - } - field(L,DBF_DOUBLE) { - prompt("Value of Input L") - pp(TRUE) - } - field(LA,DBF_DOUBLE) { - prompt("Prev Value of A") - special(SPC_NOMOD) - interest(3) - } - field(LB,DBF_DOUBLE) { - prompt("Prev Value of B") - special(SPC_NOMOD) - interest(3) - } - field(LC,DBF_DOUBLE) { - prompt("Prev Value of C") - special(SPC_NOMOD) - interest(3) - } - field(LD,DBF_DOUBLE) { - prompt("Prev Value of D") - special(SPC_NOMOD) - interest(3) - } - field(LE,DBF_DOUBLE) { - prompt("Prev Value of E") - special(SPC_NOMOD) - interest(3) - } - field(LF,DBF_DOUBLE) { - prompt("Prev Value of F") - special(SPC_NOMOD) - interest(3) - } - field(LG,DBF_DOUBLE) { - prompt("Prev Value of G") - special(SPC_NOMOD) - interest(3) - } - field(LH,DBF_DOUBLE) { - prompt("Prev Value of H") - special(SPC_NOMOD) - interest(3) - } - field(LI,DBF_DOUBLE) { - prompt("Prev Value of I") - special(SPC_NOMOD) - interest(3) - } - field(LJ,DBF_DOUBLE) { - prompt("Prev Value of J") - special(SPC_NOMOD) - interest(3) - } - field(LK,DBF_DOUBLE) { - prompt("Prev Value of K") - special(SPC_NOMOD) - interest(3) - } - field(LL,DBF_DOUBLE) { - prompt("Prev Value of L") - special(SPC_NOMOD) - interest(3) - } - field(LALM,DBF_DOUBLE) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_DOUBLE) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_DOUBLE) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } - %#include "postfix.h" - field(RPCL,DBF_NOACCESS) { - prompt("Reverse Polish Calc") - special(SPC_NOMOD) - interest(4) - extra("char rpcl[INFIX_TO_POSTFIX_SIZE(80)]") - } -} diff --git a/src/std/rec/calcoutRecord.c b/src/std/rec/calcoutRecord.c deleted file mode 100644 index 8b5525527..000000000 --- a/src/std/rec/calcoutRecord.c +++ /dev/null @@ -1,781 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* calcout.c - Record Support Routines for calc with output records */ -/* - * Author : Ned Arnold - * Based on recCalc.c by Julie Sander and Bob Dalesio - * Date: 7-27-87 - */ - -#include -#include -#include -#include -#include -#include - -#include "alarm.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbLink.h" -#include "dbScan.h" -#include "cantProceed.h" -#include "epicsMath.h" -#include "errMdef.h" -#include "errlog.h" -#include "recSup.h" -#include "devSup.h" -#include "recGbl.h" -#include "special.h" -#include "callback.h" -#include "taskwd.h" -#include "menuIvoa.h" - -#define GEN_SIZE_OFFSET -#include "calcoutRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset calcoutRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, calcoutRSET); - -int calcoutODLYprecision = 2; -epicsExportAddress(int, calcoutODLYprecision); -double calcoutODLYlimit = 100000; -epicsExportAddress(double, calcoutODLYlimit); - -typedef struct calcoutDSET { - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN write; -}calcoutDSET; - - -/* To provide feedback to the user as to the connection status of the - * links (.INxV and .OUTV), the following algorithm has been implemented ... - * - * A new PV_LINK is checked [in both init() and special()] to see if the - * target is local -- if so it is marked as such. If not, a checkLinkCb - * callback is scheduled to check the connection status later by calling - * dbIsLinkConnected(). Anytime there are unconnected CA_LINKs, another - * callback is scheduled. Once all connections are established, the CA_LINKs - * are checked whenever the record processes. - * - */ - -#define NO_CA_LINKS 0 -#define CA_LINKS_ALL_OK 1 -#define CA_LINKS_NOT_OK 2 - -typedef struct rpvtStruct { - CALLBACK doOutCb; - CALLBACK checkLinkCb; - short cbScheduled; - short caLinkStat; /* NO_CA_LINKS, CA_LINKS_ALL_OK, CA_LINKS_NOT_OK */ -} rpvtStruct; - -static void checkAlarms(calcoutRecord *prec); -static void monitor(calcoutRecord *prec); -static int fetch_values(calcoutRecord *prec); -static void execOutput(calcoutRecord *prec); -static void checkLinks(calcoutRecord *prec); -static void checkLinksCallback(CALLBACK *arg); -static long writeValue(calcoutRecord *prec); - -int calcoutRecDebug; - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct calcoutRecord *prec = (struct calcoutRecord *)pcommon; - DBLINK *plink; - int i; - double *pvalue; - epicsEnum16 *plinkValid; - short error_number; - calcoutDSET *pcalcoutDSET; - rpvtStruct *prpvt; - - if (pass == 0) { - prec->rpvt = (rpvtStruct *) callocMustSucceed(1, sizeof(rpvtStruct), "calcoutRecord"); - return 0; - } - - if (!(pcalcoutDSET = (calcoutDSET *)prec->dset)) { - recGblRecordError(S_dev_noDSET, (void *)prec, "calcout:init_record"); - return S_dev_noDSET; - } - - /* must have write defined */ - if ((pcalcoutDSET->number < 5) || (pcalcoutDSET->write ==NULL)) { - recGblRecordError(S_dev_missingSup, (void *)prec, "calcout:init_record"); - return S_dev_missingSup; - } - - prpvt = prec->rpvt; - plink = &prec->inpa; - pvalue = &prec->a; - plinkValid = &prec->inav; - - for (i = 0; i <= CALCPERFORM_NARGS; i++, plink++, pvalue++, plinkValid++) { - /* Don't InitConstantLink the .OUT link */ - if (i < CALCPERFORM_NARGS) { - recGblInitConstantLink(plink, DBF_DOUBLE, pvalue); - } - - if (dbLinkIsConstant(plink)) { - *plinkValid = calcoutINAV_CON; - } - else if (dbLinkIsVolatile(plink)) { - int conn = dbIsLinkConnected(plink); - - if (conn) - *plinkValid = calcoutINAV_EXT; - else { - /* Monitor for connection */ - *plinkValid = calcoutINAV_EXT_NC; - prpvt->caLinkStat = CA_LINKS_NOT_OK; - } - } - else { - /* PV must reside on this ioc */ - *plinkValid = calcoutINAV_LOC; - - if (!dbIsLinkConnected(plink)) { - errlogPrintf("calcout: %s.INP%c in no-vo disco state\n", - prec->name, i+'A'); - } - } - } - - prec->clcv = postfix(prec->calc, prec->rpcl, &error_number); - if (prec->clcv){ - recGblRecordError(S_db_badField, (void *)prec, - "calcout: init_record: Illegal CALC field"); - errlogPrintf("%s.CALC: %s in expression \"%s\"\n", - prec->name, calcErrorStr(error_number), prec->calc); - } - - prec->oclv = postfix(prec->ocal, prec->orpc, &error_number); - if (prec->dopt == calcoutDOPT_Use_OVAL && prec->oclv){ - recGblRecordError(S_db_badField, (void *)prec, - "calcout: init_record: Illegal OCAL field"); - errlogPrintf("%s.OCAL: %s in expression \"%s\"\n", - prec->name, calcErrorStr(error_number), prec->ocal); - } - - prpvt = prec->rpvt; - callbackSetCallback(checkLinksCallback, &prpvt->checkLinkCb); - callbackSetPriority(0, &prpvt->checkLinkCb); - callbackSetUser(prec, &prpvt->checkLinkCb); - prpvt->cbScheduled = 0; - - prec->epvt = eventNameToHandle(prec->oevt); - - if (pcalcoutDSET->init_record) pcalcoutDSET->init_record(prec); - prec->pval = prec->val; - prec->mlst = prec->val; - prec->alst = prec->val; - prec->lalm = prec->val; - prec->povl = prec->oval; - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct calcoutRecord *prec = (struct calcoutRecord *)pcommon; - rpvtStruct *prpvt = prec->rpvt; - int doOutput; - - if (!prec->pact) { - prec->pact = TRUE; - /* if some links are CA, check connections */ - if (prpvt->caLinkStat != NO_CA_LINKS) { - checkLinks(prec); - } - if (fetch_values(prec) == 0) { - if (calcPerform(&prec->a, &prec->val, prec->rpcl)) { - recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM); - } else { - prec->udf = isnan(prec->val); - } - } - checkAlarms(prec); - /* check for output link execution */ - switch (prec->oopt) { - case calcoutOOPT_Every_Time: - doOutput = 1; - break; - case calcoutOOPT_On_Change: - doOutput = ! (fabs(prec->pval - prec->val) <= prec->mdel); - break; - case calcoutOOPT_Transition_To_Zero: - doOutput = ((prec->pval != 0.0) && (prec->val == 0.0)); - break; - case calcoutOOPT_Transition_To_Non_zero: - doOutput = ((prec->pval == 0.0) && (prec->val != 0.0)); - break; - case calcoutOOPT_When_Zero: - doOutput = (prec->val == 0.0); - break; - case calcoutOOPT_When_Non_zero: - doOutput = (prec->val != 0.0); - break; - default: - doOutput = 0; - break; - } - prec->pval = prec->val; - if (doOutput) { - if (prec->odly > 0.0) { - prec->dlya = 1; - recGblGetTimeStamp(prec); - db_post_events(prec, &prec->dlya, DBE_VALUE); - callbackRequestProcessCallbackDelayed(&prpvt->doOutCb, - prec->prio, prec, (double)prec->odly); - return 0; - } else { - prec->pact = FALSE; - execOutput(prec); - if (prec->pact) return 0; - prec->pact = TRUE; - } - } - recGblGetTimeStamp(prec); - } else { /* pact == TRUE */ - if (prec->dlya) { - prec->dlya = 0; - recGblGetTimeStamp(prec); - db_post_events(prec, &prec->dlya, DBE_VALUE); - /* Make pact FALSE for asynchronous device support*/ - prec->pact = FALSE; - execOutput(prec); - if (prec->pact) return 0; - prec->pact = TRUE; - } else {/*Device Support is asynchronous*/ - writeValue(prec); - recGblGetTimeStamp(prec); - } - } - monitor(prec); - recGblFwdLink(prec); - prec->pact = FALSE; - return 0; -} - -static long special(DBADDR *paddr, int after) -{ - calcoutRecord *prec = (calcoutRecord *)paddr->precord; - rpvtStruct *prpvt = prec->rpvt; - short error_number; - int fieldIndex = dbGetFieldIndex(paddr); - int lnkIndex; - DBLINK *plink; - double *pvalue; - epicsEnum16 *plinkValid; - - if (!after) return 0; - switch(fieldIndex) { - case(calcoutRecordCALC): - prec->clcv = postfix(prec->calc, prec->rpcl, &error_number); - if (prec->clcv){ - recGblRecordError(S_db_badField, (void *)prec, - "calcout: special(): Illegal CALC field"); - errlogPrintf("%s.CALC: %s in expression \"%s\"\n", - prec->name, calcErrorStr(error_number), prec->calc); - } - db_post_events(prec, &prec->clcv, DBE_VALUE); - return 0; - - case(calcoutRecordOCAL): - prec->oclv = postfix(prec->ocal, prec->orpc, &error_number); - if (prec->dopt == calcoutDOPT_Use_OVAL && prec->oclv){ - recGblRecordError(S_db_badField, (void *)prec, - "calcout: special(): Illegal OCAL field"); - errlogPrintf("%s.OCAL: %s in expression \"%s\"\n", - prec->name, calcErrorStr(error_number), prec->ocal); - } - db_post_events(prec, &prec->oclv, DBE_VALUE); - return 0; - case(calcoutRecordINPA): - case(calcoutRecordINPB): - case(calcoutRecordINPC): - case(calcoutRecordINPD): - case(calcoutRecordINPE): - case(calcoutRecordINPF): - case(calcoutRecordINPG): - case(calcoutRecordINPH): - case(calcoutRecordINPI): - case(calcoutRecordINPJ): - case(calcoutRecordINPK): - case(calcoutRecordINPL): - case(calcoutRecordOUT): - lnkIndex = fieldIndex - calcoutRecordINPA; - plink = &prec->inpa + lnkIndex; - pvalue = &prec->a + lnkIndex; - plinkValid = &prec->inav + lnkIndex; - - if (fieldIndex != calcoutRecordOUT) - recGblInitConstantLink(plink, DBF_DOUBLE, pvalue); - - if (dbLinkIsConstant(plink)) { - db_post_events(prec, pvalue, DBE_VALUE); - *plinkValid = calcoutINAV_CON; - } else if (dbLinkIsVolatile(plink)) { - int conn = dbIsLinkConnected(plink); - - if (conn) - *plinkValid = calcoutINAV_EXT; - else { - /* Monitor for connection */ - *plinkValid = calcoutINAV_EXT_NC; - /* DO_CALLBACK, if not already scheduled */ - if (!prpvt->cbScheduled) { - callbackRequestDelayed(&prpvt->checkLinkCb, .5); - prpvt->cbScheduled = 1; - prpvt->caLinkStat = CA_LINKS_NOT_OK; - } - } - } - else { - /* PV must reside on this ioc */ - *plinkValid = calcoutINAV_LOC; - - if (!dbIsLinkConnected(plink)) { - errlogPrintf("calcout: %s.INP%c in no-vo diso state\n", - prec->name, lnkIndex); - } - } - db_post_events(prec, plinkValid, DBE_VALUE); - return 0; - case(calcoutRecordOEVT): - prec->epvt = eventNameToHandle(prec->oevt); - return 0; - default: - recGblDbaddrError(S_db_badChoice, paddr, "calc: special"); - return(S_db_badChoice); - } -} - -#define indexof(field) calcoutRecord##field - -static long get_linkNumber(int fieldIndex) { - if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L)) - return fieldIndex - indexof(A); - if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL)) - return fieldIndex - indexof(LA); - return -1; -} - -static long get_units(DBADDR *paddr, char *units) -{ - calcoutRecord *prec = (calcoutRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - if(fieldIndex == indexof(ODLY)) { - strcpy(units, "s"); - return 0; - } - - if(paddr->pfldDes->field_type == DBF_DOUBLE) { - linkNumber = get_linkNumber(dbGetFieldIndex(paddr)); - if (linkNumber >= 0) - dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE); - else - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *pprecision) -{ - calcoutRecord *prec = (calcoutRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - if (fieldIndex == indexof(ODLY)) { - *pprecision = calcoutODLYprecision; - return 0; - } - - *pprecision = prec->prec; - if (fieldIndex == indexof(VAL)) - return 0; - - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - short precision; - - if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0) - *pprecision = precision; - } else - recGblGetPrec(paddr, pprecision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - calcoutRecord *prec = (calcoutRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - switch (fieldIndex) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pgd->lower_disp_limit = prec->lopr; - pgd->upper_disp_limit = prec->hopr; - break; - case indexof(ODLY): - recGblGetGraphicDouble(paddr,pgd); - pgd->lower_disp_limit = 0.0; - break; - default: - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetGraphicLimits(&prec->inpa + linkNumber, - &pgd->lower_disp_limit, - &pgd->upper_disp_limit); - } else - recGblGetGraphicDouble(paddr,pgd); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - calcoutRecord *prec = (calcoutRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pcd->lower_ctrl_limit = prec->lopr; - pcd->upper_ctrl_limit = prec->hopr; - break; - case indexof(ODLY): - pcd->lower_ctrl_limit = 0.0; - pcd->upper_ctrl_limit = calcoutODLYlimit; - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return 0; -} - -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - calcoutRecord *prec = (calcoutRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - if (fieldIndex == indexof(VAL)) { - pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN; - pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN; - pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN; - pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN; - } else { - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetAlarmLimits(&prec->inpa + linkNumber, - &pad->lower_alarm_limit, - &pad->lower_warning_limit, - &pad->upper_warning_limit, - &pad->upper_alarm_limit); - } else - recGblGetAlarmDouble(paddr, pad); - } - return 0; -} - -static void checkAlarms(calcoutRecord *prec) -{ - double val, hyst, lalm; - double alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* alarm condition hihi */ - asev = prec->hhsv; - alev = prec->hihi; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIHI_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition lolo */ - asev = prec->llsv; - alev = prec->lolo; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOLO_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition high */ - asev = prec->hsv; - alev = prec->high; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIGH_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition low */ - asev = prec->lsv; - alev = prec->low; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOW_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* we get here only if val is out of alarm by at least hyst */ - prec->lalm = val; - return; -} - -static void execOutput(calcoutRecord *prec) -{ - /* Determine output data */ - switch(prec->dopt) { - case calcoutDOPT_Use_VAL: - prec->oval = prec->val; - break; - case calcoutDOPT_Use_OVAL: - if (calcPerform(&prec->a, &prec->oval, prec->orpc)) { - recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM); - } else { - prec->udf = isnan(prec->oval); - } - break; - } - if (prec->udf){ - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - } - - /* Check to see what to do if INVALID */ - if (prec->nsev < INVALID_ALARM ) { - /* Output the value */ - writeValue(prec); - /* post output event if set */ - if (prec->epvt) postEvent(prec->epvt); - } else switch (prec->ivoa) { - case menuIvoaContinue_normally: - writeValue(prec); - /* post output event if set */ - if (prec->epvt) postEvent(prec->epvt); - break; - case menuIvoaDon_t_drive_outputs: - break; - case menuIvoaSet_output_to_IVOV: - prec->oval = prec->ivov; - writeValue(prec); - /* post output event if set */ - if (prec->epvt) postEvent(prec->epvt); - break; - default: - recGblRecordError(S_db_badField, (void *)prec, - "calcout:process Illegal IVOA field"); - } -} - -static void monitor(calcoutRecord *prec) -{ - unsigned monitor_mask; - double *pnew; - double *pprev; - int i; - - monitor_mask = recGblResetAlarms(prec); - - /* check for value change */ - recGblCheckDeadband(&prec->mlst, prec->val, prec->mdel, &monitor_mask, DBE_VALUE); - - /* check for archive change */ - recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask, DBE_ARCHIVE); - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(prec, &prec->val, monitor_mask); - } - - /* check all input fields for changes*/ - for (i = 0, pnew = &prec->a, pprev = &prec->la; ipovl != prec->oval) { - db_post_events(prec, &prec->oval, monitor_mask|DBE_VALUE|DBE_LOG); - prec->povl = prec->oval; - } - return; -} - -static int fetch_values(calcoutRecord *prec) -{ - DBLINK *plink; /* structure of the link field */ - double *pvalue; - long status = 0; - int i; - - for (i = 0, plink = &prec->inpa, pvalue = &prec->a; irpvt; - - dbScanLock((dbCommon *)prec); - prpvt->cbScheduled = 0; - checkLinks(prec); - dbScanUnlock((dbCommon *)prec); - -} - -static void checkLinks(calcoutRecord *prec) -{ - - DBLINK *plink; - rpvtStruct *prpvt = prec->rpvt; - int i; - int stat; - int caLink = 0; - int caLinkNc = 0; - epicsEnum16 *plinkValid; - - if (calcoutRecDebug) printf("checkLinks() for %p\n", prec); - - plink = &prec->inpa; - plinkValid = &prec->inav; - - for (i = 0; icaLinkStat = CA_LINKS_NOT_OK; - else if (caLink) - prpvt->caLinkStat = CA_LINKS_ALL_OK; - else - prpvt->caLinkStat = NO_CA_LINKS; - - if (!prpvt->cbScheduled && caLinkNc) { - /* Schedule another CALLBACK */ - prpvt->cbScheduled = 1; - callbackRequestDelayed(&prpvt->checkLinkCb, .5); - } -} - -static long writeValue(calcoutRecord *prec) -{ - calcoutDSET *pcalcoutDSET = (calcoutDSET *)prec->dset; - - - if (!pcalcoutDSET || !pcalcoutDSET->write) { - errlogPrintf("%s DSET write does not exist\n", prec->name); - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - prec->pact = TRUE; - return(-1); - } - return pcalcoutDSET->write(prec); -} diff --git a/src/std/rec/calcoutRecord.dbd b/src/std/rec/calcoutRecord.dbd deleted file mode 100644 index 5bf2e54de..000000000 --- a/src/std/rec/calcoutRecord.dbd +++ /dev/null @@ -1,530 +0,0 @@ -#************************************************************************* -# Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(calcoutOOPT) { - choice(calcoutOOPT_Every_Time,"Every Time") - choice(calcoutOOPT_On_Change,"On Change") - choice(calcoutOOPT_When_Zero,"When Zero") - choice(calcoutOOPT_When_Non_zero,"When Non-zero") - choice(calcoutOOPT_Transition_To_Zero,"Transition To Zero") - choice(calcoutOOPT_Transition_To_Non_zero,"Transition To Non-zero") -} -menu(calcoutDOPT) { - choice(calcoutDOPT_Use_VAL,"Use CALC") - choice(calcoutDOPT_Use_OVAL,"Use OCAL") -} -menu(calcoutINAV) { - choice(calcoutINAV_EXT_NC,"Ext PV NC") - choice(calcoutINAV_EXT,"Ext PV OK") - choice(calcoutINAV_LOC,"Local PV") - choice(calcoutINAV_CON,"Constant") -} -recordtype(calcout) { - include "dbCommon.dbd" - field(RPVT,DBF_NOACCESS) { - prompt("Record Private") - special(SPC_NOMOD) - interest(4) - extra("struct rpvtStruct *rpvt") - } - field(VAL,DBF_DOUBLE) { - prompt("Result") - promptgroup("50 - Output") - asl(ASL0) - } - field(PVAL,DBF_DOUBLE) { - prompt("Previous Value") - } - field(CALC,DBF_STRING) { - prompt("Calculation") - promptgroup("30 - Action") - special(SPC_CALC) - pp(TRUE) - size(80) - initial("0") - } - field(CLCV,DBF_LONG) { - prompt("CALC Valid") - interest(1) - } - field(INPA,DBF_INLINK) { - prompt("Input A") - special(SPC_MOD) - promptgroup("41 - Input A-F") - interest(1) - } - field(INPB,DBF_INLINK) { - prompt("Input B") - special(SPC_MOD) - promptgroup("41 - Input A-F") - interest(1) - } - field(INPC,DBF_INLINK) { - prompt("Input C") - special(SPC_MOD) - promptgroup("41 - Input A-F") - interest(1) - } - field(INPD,DBF_INLINK) { - prompt("Input D") - special(SPC_MOD) - promptgroup("41 - Input A-F") - interest(1) - } - field(INPE,DBF_INLINK) { - prompt("Input E") - special(SPC_MOD) - promptgroup("41 - Input A-F") - interest(1) - } - field(INPF,DBF_INLINK) { - prompt("Input F") - special(SPC_MOD) - promptgroup("41 - Input A-F") - interest(1) - } - field(INPG,DBF_INLINK) { - prompt("Input G") - special(SPC_MOD) - promptgroup("42 - Input G-L") - interest(1) - } - field(INPH,DBF_INLINK) { - prompt("Input H") - special(SPC_MOD) - promptgroup("42 - Input G-L") - interest(1) - } - field(INPI,DBF_INLINK) { - prompt("Input I") - special(SPC_MOD) - promptgroup("42 - Input G-L") - interest(1) - } - field(INPJ,DBF_INLINK) { - prompt("Input J") - special(SPC_MOD) - promptgroup("42 - Input G-L") - interest(1) - } - field(INPK,DBF_INLINK) { - prompt("Input K") - special(SPC_MOD) - promptgroup("42 - Input G-L") - interest(1) - } - field(INPL,DBF_INLINK) { - prompt("Input L") - special(SPC_MOD) - promptgroup("42 - Input G-L") - interest(1) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - special(SPC_MOD) - promptgroup("50 - Output") - interest(1) - } - field(INAV,DBF_MENU) { - prompt("INPA PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INBV,DBF_MENU) { - prompt("INPB PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INCV,DBF_MENU) { - prompt("INPC PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INDV,DBF_MENU) { - prompt("INPD PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INEV,DBF_MENU) { - prompt("INPE PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INFV,DBF_MENU) { - prompt("INPF PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INGV,DBF_MENU) { - prompt("INPG PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INHV,DBF_MENU) { - prompt("INPH PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INIV,DBF_MENU) { - prompt("INPI PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INJV,DBF_MENU) { - prompt("INPJ PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INKV,DBF_MENU) { - prompt("INPK PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(INLV,DBF_MENU) { - prompt("INPL PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - initial("1") - } - field(OUTV,DBF_MENU) { - prompt("OUT PV Status") - special(SPC_NOMOD) - interest(1) - menu(calcoutINAV) - } - field(OOPT,DBF_MENU) { - prompt("Output Execute Opt") - promptgroup("50 - Output") - interest(1) - menu(calcoutOOPT) - } - field(ODLY,DBF_DOUBLE) { - prompt("Output Execute Delay") - promptgroup("50 - Output") - asl(ASL0) - interest(1) - } - field(DLYA,DBF_USHORT) { - prompt("Output Delay Active") - special(SPC_NOMOD) - asl(ASL0) - } - field(DOPT,DBF_MENU) { - prompt("Output Data Opt") - promptgroup("30 - Action") - interest(1) - menu(calcoutDOPT) - } - field(OCAL,DBF_STRING) { - prompt("Output Calculation") - promptgroup("30 - Action") - special(SPC_CALC) - pp(TRUE) - size(80) - initial("0") - } - field(OCLV,DBF_LONG) { - prompt("OCAL Valid") - interest(1) - } - field(OEVT,DBF_STRING) { - prompt("Event To Issue") - promptgroup("30 - Action") - special(SPC_MOD) - asl(ASL0) - size(40) - } - %#include "dbScan.h" - field(EPVT, DBF_NOACCESS) { - prompt("Event private") - special(SPC_NOMOD) - interest(4) - extra("EVENTPVT epvt") - } - field(IVOA,DBF_MENU) { - prompt("INVALID output action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_DOUBLE) { - prompt("INVALID output value") - promptgroup("50 - Output") - interest(2) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Rng") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HIHI,DBF_DOUBLE) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_DOUBLE) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_DOUBLE) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_DOUBLE) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HYST,DBF_DOUBLE) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_DOUBLE) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_DOUBLE) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(A,DBF_DOUBLE) { - prompt("Value of Input A") - pp(TRUE) - } - field(B,DBF_DOUBLE) { - prompt("Value of Input B") - pp(TRUE) - } - field(C,DBF_DOUBLE) { - prompt("Value of Input C") - pp(TRUE) - } - field(D,DBF_DOUBLE) { - prompt("Value of Input D") - pp(TRUE) - } - field(E,DBF_DOUBLE) { - prompt("Value of Input E") - pp(TRUE) - } - field(F,DBF_DOUBLE) { - prompt("Value of Input F") - pp(TRUE) - } - field(G,DBF_DOUBLE) { - prompt("Value of Input G") - pp(TRUE) - } - field(H,DBF_DOUBLE) { - prompt("Value of Input H") - pp(TRUE) - } - field(I,DBF_DOUBLE) { - prompt("Value of Input I") - pp(TRUE) - } - field(J,DBF_DOUBLE) { - prompt("Value of Input J") - pp(TRUE) - } - field(K,DBF_DOUBLE) { - prompt("Value of Input K") - pp(TRUE) - } - field(L,DBF_DOUBLE) { - prompt("Value of Input L") - pp(TRUE) - } - field(OVAL,DBF_DOUBLE) { - prompt("Output Value") - asl(ASL0) - } - field(LA,DBF_DOUBLE) { - prompt("Prev Value of A") - special(SPC_NOMOD) - interest(3) - } - field(LB,DBF_DOUBLE) { - prompt("Prev Value of B") - special(SPC_NOMOD) - interest(3) - } - field(LC,DBF_DOUBLE) { - prompt("Prev Value of C") - special(SPC_NOMOD) - interest(3) - } - field(LD,DBF_DOUBLE) { - prompt("Prev Value of D") - special(SPC_NOMOD) - interest(3) - } - field(LE,DBF_DOUBLE) { - prompt("Prev Value of E") - special(SPC_NOMOD) - interest(3) - } - field(LF,DBF_DOUBLE) { - prompt("Prev Value of F") - special(SPC_NOMOD) - interest(3) - } - field(LG,DBF_DOUBLE) { - prompt("Prev Value of G") - special(SPC_NOMOD) - interest(3) - } - field(LH,DBF_DOUBLE) { - prompt("Prev Value of H") - special(SPC_NOMOD) - interest(3) - } - field(LI,DBF_DOUBLE) { - prompt("Prev Value of I") - special(SPC_NOMOD) - interest(3) - } - field(LJ,DBF_DOUBLE) { - prompt("Prev Value of J") - special(SPC_NOMOD) - interest(3) - } - field(LK,DBF_DOUBLE) { - prompt("Prev Value of K") - special(SPC_NOMOD) - interest(3) - } - field(LL,DBF_DOUBLE) { - prompt("Prev Value of L") - special(SPC_NOMOD) - interest(3) - } - field(POVL,DBF_DOUBLE) { - prompt("Prev Value of OVAL") - asl(ASL0) - } - field(LALM,DBF_DOUBLE) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_DOUBLE) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_DOUBLE) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } - %#include "postfix.h" - field(RPCL,DBF_NOACCESS) { - prompt("Reverse Polish Calc") - special(SPC_NOMOD) - interest(4) - extra("char rpcl[INFIX_TO_POSTFIX_SIZE(80)]") - } - field(ORPC,DBF_NOACCESS) { - prompt("Reverse Polish OCalc") - special(SPC_NOMOD) - interest(4) - extra("char orpc[INFIX_TO_POSTFIX_SIZE(80)]") - } -} - -variable(calcoutODLYprecision, int) -variable(calcoutODLYlimit, double) diff --git a/src/std/rec/compressRecord.c b/src/std/rec/compressRecord.c deleted file mode 100644 index 4b4de5f15..000000000 --- a/src/std/rec/compressRecord.c +++ /dev/null @@ -1,504 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Author: Bob Dalesio - * Date: 7-14-89 - */ - -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbStaticLib.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "errMdef.h" -#include "special.h" -#include "recSup.h" -#include "recGbl.h" - -#define GEN_SIZE_OFFSET -#include "compressRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -#define indexof(field) compressRecord##field - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -static long get_array_info(DBADDR *, long *, long *); -static long put_array_info(DBADDR *, long); -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -#define get_alarm_double NULL - -rset compressRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,compressRSET); - - -static void reset(compressRecord *prec) -{ - prec->nuse = 0; - prec->off = 0; - prec->inx = 0; - prec->cvb = 0.0; - prec->res = 0; - /* allocate memory for the summing buffer for conversions requiring it */ - if (prec->alg == compressALG_Average && prec->sptr == NULL) { - prec->sptr = calloc(prec->nsam, sizeof(double)); - } - - if (prec->bptr && prec->nsam) - memset(prec->bptr, 0, prec->nsam * sizeof(double)); -} - -static void monitor(compressRecord *prec) -{ - unsigned short alarm_mask = recGblResetAlarms(prec); - unsigned short monitor_mask = alarm_mask | DBE_LOG | DBE_VALUE; - - if (alarm_mask || prec->nuse != prec->ouse) { - db_post_events(prec, &prec->nuse, monitor_mask); - prec->ouse = prec->nuse; - } - db_post_events(prec, prec->bptr, monitor_mask); -} - -static void put_value(compressRecord *prec, double *psource, int n) -{ - int fifo = (prec->balg == bufferingALG_FIFO); - epicsUInt32 offset = prec->off; - epicsUInt32 nuse = prec->nuse; - epicsUInt32 nsam = prec->nsam; - - nuse += n; - if (nuse > nsam) - nuse = nsam; - - while (n--) { - /* for LIFO, decrement before */ - if (!fifo) - offset = (offset - 1) % nsam; - - prec->bptr[offset] = *psource++; - - /* for FIFO, increment after */ - if (fifo) - offset = (offset + 1) % nsam; - } - - prec->off = offset; - prec->nuse = nuse; -} - - -/* qsort comparison function (for median calculation) */ -static int compare(const void *arg1, const void *arg2) -{ - double a = *(double *)arg1; - double b = *(double *)arg2; - - if ( a < b ) return -1; - else if ( a == b ) return 0; - else return 1; -} - -static int compress_array(compressRecord *prec, - double *psource, int no_elements) -{ - epicsInt32 i,j; - epicsInt32 n, nnew; - epicsInt32 nsam = prec->nsam; - double value; - - /* skip out of limit data */ - if (prec->ilil < prec->ihil) { - while (((*psource < prec->ilil) || (*psource > prec->ihil)) - && (no_elements > 0)) { - no_elements--; - psource++; - } - } - if (prec->n <= 0) - prec->n = 1; - n = prec->n; - if (no_elements < n) - return 1; /*dont do anything*/ - - /* determine number of samples to take */ - if (no_elements < nsam * n) - nnew = (no_elements / n); - else nnew = nsam; - - /* compress according to specified algorithm */ - switch (prec->alg){ - case compressALG_N_to_1_Low_Value: - /* compress N to 1 keeping the lowest value */ - for (i = 0; i < nnew; i++) { - value = *psource++; - for (j = 1; j < n; j++, psource++) { - if (value > *psource) - value = *psource; - } - put_value(prec, &value, 1); - } - break; - case compressALG_N_to_1_High_Value: - /* compress N to 1 keeping the highest value */ - for (i = 0; i < nnew; i++){ - value = *psource++; - for (j = 1; j < n; j++, psource++) { - if (value < *psource) - value = *psource; - } - put_value(prec, &value, 1); - } - break; - case compressALG_N_to_1_Average: - /* compress N to 1 keeping the average value */ - for (i = 0; i < nnew; i++) { - value = 0; - for (j = 0; j < n; j++, psource++) - value += *psource; - value /= n; - put_value(prec, &value, 1); - } - break; - - case compressALG_N_to_1_Median: - /* compress N to 1 keeping the median value */ - /* note: sorts source array (OK; it's a work pointer) */ - for (i = 0; i < nnew; i++, psource += nnew) { - qsort(psource, n, sizeof(double), compare); - value = psource[n / 2]; - put_value(prec, &value, 1); - } - break; - } - return 0; -} - -static int array_average(compressRecord *prec, - double *psource, epicsInt32 no_elements) -{ - epicsInt32 i; - epicsInt32 nnow; - epicsInt32 nsam=prec->nsam; - double *psum; - double multiplier; - epicsInt32 inx = prec->inx; - epicsInt32 nuse, n; - - nuse = nsam; - if (nuse > no_elements) - nuse = no_elements; - nnow = nuse; - if (nnow > no_elements) - nnow=no_elements; - psum = (double *)prec->sptr; - - /* add in the new waveform */ - if (inx == 0) { - for (i = 0; i < nnow; i++) - *psum++ = *psource++; - for (i = nnow; i < nuse; i++) - *psum++ = 0; - } else { - for (i = 0; i < nnow; i++) - *psum++ += *psource++; - } - - /* do we need to calculate the result */ - inx++; - if (prec->n <= 0) - prec->n = 1; - n = prec->n; - if (inx < n) { - prec->inx = inx; - return 1; - } - if (n > 1) { - psum = (double *)prec->sptr; - multiplier = 1.0 / n; - for (i = 0; i < nuse; i++, psum++) - *psum = *psum * multiplier; - } - put_value(prec, prec->sptr, nuse); - prec->inx = 0; - return 0; -} - -static int compress_scalar(struct compressRecord *prec,double *psource) -{ - double value = *psource; - double *pdest=&prec->cvb; - epicsInt32 inx = prec->inx; - - /* compress according to specified algorithm */ - switch (prec->alg) { - case (compressALG_N_to_1_Low_Value): - if ((value < *pdest) || (inx == 0)) - *pdest = value; - break; - case (compressALG_N_to_1_High_Value): - if ((value > *pdest) || (inx == 0)) - *pdest = value; - break; - /* for scalars, Median not implemented => use average */ - case (compressALG_N_to_1_Average): - case (compressALG_N_to_1_Median): - if (inx == 0) - *pdest = value; - else { - *pdest += value; - if (inx + 1 >= prec->n) - *pdest = *pdest / (inx + 1); - } - break; - } - inx++; - if (inx >= prec->n) { - put_value(prec,pdest,1); - prec->inx = 0; - return 0; - } else { - prec->inx = inx; - return 1; - } -} - -/*Beginning of record support routines*/ -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct compressRecord *prec = (struct compressRecord *)pcommon; - if (pass == 0) { - if (prec->nsam < 1) - prec->nsam = 1; - prec->bptr = calloc(prec->nsam, sizeof(double)); - reset(prec); - } - - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct compressRecord *prec = (struct compressRecord *)pcommon; - long status = 0; - long nelements = 0; - int alg = prec->alg; - - prec->pact = TRUE; - if (!dbIsLinkConnected(&prec->inp) || - dbGetNelements(&prec->inp, &nelements) || - nelements <= 0) { - recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM); - } - else { - if (!prec->wptr || nelements != prec->inpn) { - if (prec->wptr) { - free(prec->wptr); - reset(prec); - } - prec->wptr = dbCalloc(nelements, sizeof(double)); - prec->inpn = nelements; - } - status = dbGetLink(&prec->inp, DBF_DOUBLE, prec->wptr, 0, &nelements); - if (status || nelements <= 0) { - recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM); - status = 0; - } - else if (alg == compressALG_Average) { - status = array_average(prec, prec->wptr, nelements); - } - else if (alg == compressALG_Circular_Buffer) { - put_value(prec, prec->wptr, nelements); - status = 0; - } - else if (nelements > 1) { - status = compress_array(prec, prec->wptr, nelements); - } - else if (nelements == 1){ - status = compress_scalar(prec, prec->wptr); - } - else - status = 1; - } - - /* check event list */ - if (status != 1) { - prec->udf = FALSE; - recGblGetTimeStamp(prec); - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - } - - prec->pact = FALSE; - return 0; -} - -static long special(DBADDR *paddr, int after) -{ - compressRecord *prec = (compressRecord *) paddr->precord; - int special_type = paddr->special; - - if (!after) - return 0; - - if (special_type == SPC_RESET) { - reset(prec); - return 0; - } - - recGblDbaddrError(S_db_badChoice, paddr, "compress: special"); - return S_db_badChoice; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - compressRecord *prec = (compressRecord *) paddr->precord; - - paddr->pfield = prec->bptr; - paddr->no_elements = prec->nsam; - paddr->field_type = DBF_DOUBLE; - paddr->field_size = sizeof(double); - paddr->dbr_field_type = DBF_DOUBLE; - - if (prec->balg == bufferingALG_LIFO) - paddr->special = SPC_NOMOD; - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - /* offset indicates the next element which would be written. - * In FIFO mode offset-1 is the last valid element - * In LIFO mode offset is the first valid element - * (*offset) should be set to the index of the first valid element - */ - compressRecord *prec = (compressRecord *) paddr->precord; - epicsUInt32 off = prec->off; - epicsUInt32 nuse = prec->nuse; - epicsUInt32 nsam = prec->nsam; - - *no_elements = nuse; - if (prec->balg == bufferingALG_FIFO) { - *offset = (off - nuse) % nsam; - } else { - *offset = off; - } - - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - compressRecord *prec = (compressRecord *) paddr->precord; - - if (prec->balg == bufferingALG_FIFO) - prec->off = (prec->off + nNew) % prec->nsam; - prec->nuse += nNew; - if (prec->nuse > prec->nsam) - prec->nuse = prec->nsam; - return 0; -} - -static long get_units(DBADDR *paddr, char *units) -{ - compressRecord *prec = (compressRecord *) paddr->precord; - - if (paddr->pfldDes->field_type == DBF_DOUBLE || - dbGetFieldIndex(paddr) == indexof(VAL)) { - strncpy(units, prec->egu, DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - compressRecord *prec = (compressRecord *) paddr->precord; - - *precision = prec->prec; - if (dbGetFieldIndex(paddr) != indexof(VAL)) - recGblGetPrec(paddr,precision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - compressRecord *prec = (compressRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(IHIL): - case indexof(ILIL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - compressRecord *prec = (compressRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(IHIL): - case indexof(ILIL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - default: - recGblGetControlDouble(paddr, pcd); - } - return 0; -} diff --git a/src/std/rec/compressRecord.dbd.pod b/src/std/rec/compressRecord.dbd.pod deleted file mode 100644 index 265cdfe8a..000000000 --- a/src/std/rec/compressRecord.dbd.pod +++ /dev/null @@ -1,199 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=title Compress Record (compress) - -The data compression record is used to collect and compress data from arrays. -When the INP field references a data array field, it immediately compresses the -entire array into an element of an array using one of several algorithms, -overwriting the previous element. If the INP field obtains its value from a -scalar-value field, the compression record will collect a new sample each time -the record is processed and add it to the compressed data array as a circular -buffer. - -The INP link can also specify a constant; however, if this is the case, the -compression algorithms are ignored, and the record support routines merely -return after checking the FLNK field. - -=head2 Record-specific Menus - -=head3 Menu compressALG - -The ALG field which uses this menu controls the compression algorithm used by -the record. - -=menu compressALG - -=head3 Menu bufferingALG - -The BALG field which uses this menu controls whether new values are inserted at -the beginning or the end of the VAL array. - -=menu bufferingALG - - -=head2 Parameter Fields - -The record-specific fields are described below. - -=recordtype compress - -... - -=cut - -menu(compressALG) { - choice(compressALG_N_to_1_Low_Value,"N to 1 Low Value") - choice(compressALG_N_to_1_High_Value,"N to 1 High Value") - choice(compressALG_N_to_1_Average,"N to 1 Average") - choice(compressALG_Average,"Average") - choice(compressALG_Circular_Buffer,"Circular Buffer") - choice(compressALG_N_to_1_Median,"N to 1 Median") -} -menu(bufferingALG) { - choice(bufferingALG_FIFO, "FIFO Buffer") - choice(bufferingALG_LIFO, "LIFO Buffer") -} -recordtype(compress) { - -=fields VAL - -=cut - - include "dbCommon.dbd" - field(VAL,DBF_NOACCESS) { - prompt("Value") - asl(ASL0) - special(SPC_DBADDR) - pp(TRUE) - extra("void * val") - #=type DOUBLE[] - #=read Yes - #=write Yes - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(RES,DBF_SHORT) { - prompt("Reset") - asl(ASL0) - special(SPC_RESET) - interest(3) - } - field(ALG,DBF_MENU) { - prompt("Compression Algorithm") - promptgroup("30 - Action") - special(SPC_RESET) - interest(1) - menu(compressALG) - } - field(BALG,DBF_MENU) { - prompt("Buffering Algorithm") - promptgroup("30 - Action") - special(SPC_RESET) - interest(1) - menu(bufferingALG) - } - field(NSAM,DBF_ULONG) { - prompt("Number of Values") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(N,DBF_ULONG) { - prompt("N to 1 Compression") - promptgroup("30 - Action") - special(SPC_RESET) - interest(1) - initial("1") - } - field(IHIL,DBF_DOUBLE) { - prompt("Init High Interest Lim") - promptgroup("30 - Action") - interest(1) - } - field(ILIL,DBF_DOUBLE) { - prompt("Init Low Interest Lim") - promptgroup("30 - Action") - interest(1) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(OFF,DBF_ULONG) { - prompt("Offset") - special(SPC_NOMOD) - } - field(NUSE,DBF_ULONG) { - prompt("Number Used") - special(SPC_NOMOD) - } - field(OUSE,DBF_ULONG) { - prompt("Old Number Used") - special(SPC_NOMOD) - } - field(BPTR,DBF_NOACCESS) { - prompt("Buffer Pointer") - special(SPC_NOMOD) - interest(4) - extra("double *bptr") - } - field(SPTR,DBF_NOACCESS) { - prompt("Summing Buffer Ptr") - special(SPC_NOMOD) - interest(4) - extra("double *sptr") - } - field(WPTR,DBF_NOACCESS) { - prompt("Working Buffer Ptr") - special(SPC_NOMOD) - interest(4) - extra("double *wptr") - } - field(INPN,DBF_LONG) { - prompt("Number of elements in Working Buffer") - special(SPC_NOMOD) - interest(4) - } - field(CVB,DBF_DOUBLE) { - prompt("Compress Value Buffer") - special(SPC_NOMOD) - interest(3) - } - field(INX,DBF_ULONG) { - prompt("Compressed Array Inx") - special(SPC_NOMOD) - interest(3) - } -} diff --git a/src/std/rec/dfanoutRecord.c b/src/std/rec/dfanoutRecord.c deleted file mode 100644 index 4672fc413..000000000 --- a/src/std/rec/dfanoutRecord.c +++ /dev/null @@ -1,321 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 Southeastern Universities Research Association, as -* Operator of Thomas Jefferson National Accelerator Facility. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recDfanout.c - Record Support Routines for Dfanout records */ -/* - * Original Author: Matt Bickley (Sometime in 1994) - * - * Modification Log: - * ----------------- - * .01 1994 mhb Started with longout record to make the data fanout - * .02 May 10, 96 jt Bug Fix - * .03 11SEP2000 mrk LONG=>DOUBLE, add SELL,SELN,SELM - */ - - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsMath.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#include "menuOmsl.h" - -#define GEN_SIZE_OFFSET -#include "dfanoutRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *,struct dbr_grDouble *); -static long get_control_double(DBADDR *,struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *,struct dbr_alDouble *); - -rset dfanoutRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,dfanoutRSET); - - -static void checkAlarms(dfanoutRecord *); -static void monitor(dfanoutRecord *); -static void push_values(dfanoutRecord *); - -#define OUT_ARG_MAX 8 - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct dfanoutRecord *prec = (struct dfanoutRecord *)pcommon; - if (pass==0) - return 0; - - recGblInitConstantLink(&prec->sell, DBF_USHORT, &prec->seln); - - /* get the initial value dol is a constant*/ - if (recGblInitConstantLink(&prec->dol, DBF_DOUBLE, &prec->val)) - prec->udf = isnan(prec->val); - - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct dfanoutRecord *prec = (struct dfanoutRecord *)pcommon; - long status=0; - - if (!prec->pact && - !dbLinkIsConstant(&prec->dol) && - prec->omsl == menuOmslclosed_loop) { - status = dbGetLink(&prec->dol, DBR_DOUBLE, &prec->val, 0, 0); - if (!dbLinkIsConstant(&prec->dol) && !status) - prec->udf = isnan(prec->val); - } - prec->pact = TRUE; - recGblGetTimeStamp(prec); - /* Push out the data to all the forward links */ - dbGetLink(&(prec->sell),DBR_USHORT,&(prec->seln),0,0); - checkAlarms(prec); - push_values(prec); - monitor(prec); - recGblFwdLink(prec); - prec->pact=FALSE; - return(status); -} - -#define indexof(field) dfanoutRecord##field - -static long get_units(DBADDR *paddr,char *units) -{ - dfanoutRecord *prec=(dfanoutRecord *)paddr->precord; - - if(paddr->pfldDes->field_type == DBF_DOUBLE) { - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return(0); -} - -static long get_precision(const DBADDR *paddr,long *precision) -{ - dfanoutRecord *prec=(dfanoutRecord *)paddr->precord; - - *precision = prec->prec; - if (dbGetFieldIndex(paddr) == indexof(VAL)) return(0); - recGblGetPrec(paddr,precision); - return(0); -} - -static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd) -{ - dfanoutRecord *prec=(dfanoutRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return(0); -} - -static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd) -{ - dfanoutRecord *prec=(dfanoutRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return(0); -} -static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad) -{ - dfanoutRecord *prec=(dfanoutRecord *)paddr->precord; - - if(dbGetFieldIndex(paddr) == indexof(VAL)) { - pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN; - pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN; - pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN; - pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(dfanoutRecord *prec) -{ - double val, hyst, lalm; - double alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* alarm condition hihi */ - asev = prec->hhsv; - alev = prec->hihi; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIHI_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition lolo */ - asev = prec->llsv; - alev = prec->lolo; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOLO_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition high */ - asev = prec->hsv; - alev = prec->high; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIGH_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition low */ - asev = prec->lsv; - alev = prec->low; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOW_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* we get here only if val is out of alarm by at least hyst */ - prec->lalm = val; - return; -} - -static void monitor(dfanoutRecord *prec) -{ - unsigned monitor_mask = recGblResetAlarms(prec); - - /* check for value change */ - recGblCheckDeadband(&prec->mlst, prec->val, prec->mdel, &monitor_mask, DBE_VALUE); - - /* check for archive change */ - recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask, DBE_ARCHIVE); - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(prec,&prec->val,monitor_mask); - } - - return; -} - -static void push_values(dfanoutRecord *prec) -{ - struct link *plink; /* structure of the link field */ - int i; - long status; - unsigned short state; - - switch (prec->selm){ - case (dfanoutSELM_All): - for(i=0, plink=&(prec->outa); ival),1); - if(status) recGblSetSevr(prec,LINK_ALARM,MAJOR_ALARM); - } - break; - case (dfanoutSELM_Specified): - if(prec->seln>OUT_ARG_MAX) { - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - break; - } - if(prec->seln==0) break; - plink=&(prec->outa); - plink += (prec->seln -1); - status=dbPutLink(plink,DBR_DOUBLE,&(prec->val),1); - if(status) recGblSetSevr(prec,LINK_ALARM,MAJOR_ALARM); - break; - case (dfanoutSELM_Mask): - if(prec->seln==0) break; - for(i=0, plink=&(prec->outa), state=prec->seln; - i>=1) { - if(state&1) { - status=dbPutLink(plink,DBR_DOUBLE,&(prec->val),1); - if(status) recGblSetSevr(prec,LINK_ALARM,MAJOR_ALARM); - } - } - break; - default: - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - } - -} diff --git a/src/std/rec/dfanoutRecord.dbd b/src/std/rec/dfanoutRecord.dbd deleted file mode 100644 index c2eb42a75..000000000 --- a/src/std/rec/dfanoutRecord.dbd +++ /dev/null @@ -1,204 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(dfanoutSELM) { - choice(dfanoutSELM_All,"All") - choice(dfanoutSELM_Specified,"Specified") - choice(dfanoutSELM_Mask,"Mask") -} -recordtype(dfanout) { - include "dbCommon.dbd" - field(VAL,DBF_DOUBLE) { - prompt("Desired Output") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(SELM,DBF_MENU) { - prompt("Select Mechanism") - promptgroup("30 - Action") - interest(1) - menu(dfanoutSELM) - } - field(SELN,DBF_USHORT) { - prompt("Link Selection") - interest(1) - initial("1") - } - field(SELL,DBF_INLINK) { - prompt("Link Selection Loc") - promptgroup("30 - Action") - interest(1) - } - field(OUTA,DBF_OUTLINK) { - prompt("Output Spec A") - promptgroup("50 - Output") - interest(1) - } - field(OUTB,DBF_OUTLINK) { - prompt("Output Spec B") - promptgroup("50 - Output") - interest(1) - } - field(OUTC,DBF_OUTLINK) { - prompt("Output Spec C") - promptgroup("50 - Output") - interest(1) - } - field(OUTD,DBF_OUTLINK) { - prompt("Output Spec D") - promptgroup("50 - Output") - interest(1) - } - field(OUTE,DBF_OUTLINK) { - prompt("Output Spec E") - promptgroup("50 - Output") - interest(1) - } - field(OUTF,DBF_OUTLINK) { - prompt("Output Spec F") - promptgroup("50 - Output") - interest(1) - } - field(OUTG,DBF_OUTLINK) { - prompt("Output Spec G") - promptgroup("50 - Output") - interest(1) - } - field(OUTH,DBF_OUTLINK) { - prompt("Output Spec H") - promptgroup("50 - Output") - interest(1) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup("40 - Input") - interest(1) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - interest(1) - menu(menuOmsl) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HIHI,DBF_DOUBLE) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_DOUBLE) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_DOUBLE) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_DOUBLE) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HYST,DBF_DOUBLE) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_DOUBLE) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_DOUBLE) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(LALM,DBF_DOUBLE) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_DOUBLE) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_DOUBLE) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } -} diff --git a/src/std/rec/eventRecord.c b/src/std/rec/eventRecord.c deleted file mode 100644 index 38a4ad62f..000000000 --- a/src/std/rec/eventRecord.c +++ /dev/null @@ -1,200 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recEvent.c - Record Support Routines for Event records */ -/* - * Author: Janet Anderson - * Date: 12-13-91 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbScan.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "eventRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset eventRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,eventRSET); - -struct eventdset { /* event input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_event;/*(0)=> success */ -}; -static void monitor(eventRecord *); -static long readValue(eventRecord *); - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct eventRecord *prec = (struct eventRecord *)pcommon; - struct eventdset *pdset; - long status=0; - - if (pass==0) return(0); - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - recGblInitConstantLink(&prec->siol, DBF_STRING, &prec->sval); - - if( (pdset=(struct eventdset *)(prec->dset)) && (pdset->init_record) ) - status=(*pdset->init_record)(prec); - - prec->epvt = eventNameToHandle(prec->val); - - return(status); -} - -static long process(struct dbCommon *pcommon) -{ - struct eventRecord *prec = (struct eventRecord *)pcommon; - struct eventdset *pdset = (struct eventdset *)(prec->dset); - long status=0; - unsigned char pact=prec->pact; - - if((pdset!=NULL) && (pdset->number >= 5) && pdset->read_event ) - status=readValue(prec); /* read the new value */ - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - postEvent(prec->epvt); - - recGblGetTimeStamp(prec); - - /* check event list */ - monitor(prec); - - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - - -static long special(DBADDR *paddr, int after) -{ - eventRecord *prec = (eventRecord *)paddr->precord; - - if (!after) return 0; - if (dbGetFieldIndex(paddr) == eventRecordVAL) { - prec->epvt = eventNameToHandle(prec->val); - } - return 0; -} - - -static void monitor(eventRecord *prec) -{ - unsigned short monitor_mask; - - /* get previous stat and sevr and new stat and sevr*/ - monitor_mask = recGblResetAlarms(prec); - db_post_events(prec,&prec->val,monitor_mask|DBE_VALUE); - return; -} - -static long readValue(eventRecord *prec) -{ - long status; - struct eventdset *pdset = (struct eventdset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->read_event)(prec); - return(status); - } - - status=dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0); - - if (status) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->read_event)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status=dbGetLink(&(prec->siol),DBR_STRING, - &(prec->sval),0,0); - if (status==0) { - if (strcmp(prec->sval, prec->val) != 0) { - strcpy(prec->val, prec->sval); - prec->epvt = eventNameToHandle(prec->val); - } - prec->udf=FALSE; - } - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/eventRecord.dbd b/src/std/rec/eventRecord.dbd deleted file mode 100644 index 348902e4b..000000000 --- a/src/std/rec/eventRecord.dbd +++ /dev/null @@ -1,55 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(event) { - include "dbCommon.dbd" - field(VAL,DBF_STRING) { - prompt("Event Name To Post") - promptgroup("40 - Input") - special(SPC_MOD) - asl(ASL0) - size(40) - } - %#include "dbScan.h" - field(EPVT, DBF_NOACCESS) { - prompt("Event private") - special(SPC_NOMOD) - interest(4) - extra("EVENTPVT epvt") - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_STRING) { - prompt("Simulation Value") - size(40) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } -} diff --git a/src/std/rec/fanoutRecord.c b/src/std/rec/fanoutRecord.c deleted file mode 100644 index 3ac6b66c6..000000000 --- a/src/std/rec/fanoutRecord.c +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Author: Bob Dalesio - * Date: 12-20-88 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "errMdef.h" -#include "epicsTypes.h" -#include "recSup.h" -#include "recGbl.h" -#include "dbCommon.h" - -#define GEN_SIZE_OFFSET -#include "fanoutRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -#define NLINKS 16 - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset fanoutRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,fanoutRSET); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct fanoutRecord *prec = (struct fanoutRecord *)pcommon; - if (pass == 0) - return 0; - - recGblInitConstantLink(&prec->sell, DBF_USHORT, &prec->seln); - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct fanoutRecord *prec = (struct fanoutRecord *)pcommon; - struct link *plink; - epicsUInt16 seln, events; - int i; - epicsUInt16 oldn = prec->seln; - - prec->pact = TRUE; - - /* fetch link selection */ - dbGetLink(&prec->sell, DBR_USHORT, &prec->seln, 0, 0); - seln = prec->seln; - - switch (prec->selm) { - case fanoutSELM_All: - plink = &prec->lnk0; - for (i = 0; i < NLINKS; i++, plink++) { - dbScanFwdLink(plink); - } - break; - - case fanoutSELM_Specified: - i = seln + prec->offs; - if (i < 0 || i >= NLINKS) { - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - break; - } - plink = &prec->lnk0 + i; - dbScanFwdLink(plink); - break; - - case fanoutSELM_Mask: - i = prec->shft; - if (i < -15 || i > 15) { - /* Shifting by more than the number of bits in the - * value produces undefined behavior in C */ - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - break; - } - seln = (i >= 0) ? seln >> i : seln << -i; - if (seln == 0) - break; - plink = &prec->lnk0; - for (i = 0; i < NLINKS; i++, seln >>= 1, plink++) { - if (seln & 1) - dbScanFwdLink(plink); - } - break; - default: - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - } - prec->udf = FALSE; - recGblGetTimeStamp(prec); - - /* post monitors */ - events = recGblResetAlarms(prec); - if (events) - db_post_events(prec, &prec->val, events); - if (prec->seln != oldn) - db_post_events(prec, &prec->seln, events | DBE_VALUE | DBE_LOG); - - /* finish off */ - recGblFwdLink(prec); - prec->pact = FALSE; - return 0; -} diff --git a/src/std/rec/fanoutRecord.dbd b/src/std/rec/fanoutRecord.dbd deleted file mode 100644 index 251d63a11..000000000 --- a/src/std/rec/fanoutRecord.dbd +++ /dev/null @@ -1,129 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(fanoutSELM) { - choice(fanoutSELM_All,"All") - choice(fanoutSELM_Specified,"Specified") - choice(fanoutSELM_Mask,"Mask") -} -recordtype(fanout) { - include "dbCommon.dbd" - field(VAL,DBF_LONG) { - prompt("Used to trigger") - asl(ASL0) - pp(TRUE) - } - field(SELM,DBF_MENU) { - prompt("Select Mechanism") - promptgroup("30 - Action") - interest(1) - menu(fanoutSELM) - } - field(SELN,DBF_USHORT) { - prompt("Link Selection") - interest(1) - initial("1") - } - field(SELL,DBF_INLINK) { - prompt("Link Selection Loc") - promptgroup("30 - Action") - interest(1) - } - field(OFFS,DBF_SHORT) { - prompt("Offset for Specified") - promptgroup("30 - Action") - interest(1) - initial("0") - } - field(SHFT,DBF_SHORT) { - prompt("Shift for Mask mode") - promptgroup("30 - Action") - interest(1) - initial("-1") - } - field(LNK0,DBF_FWDLINK) { - prompt("Forward Link 0") - promptgroup("51 - Output 0-7") - interest(1) - } - field(LNK1,DBF_FWDLINK) { - prompt("Forward Link 1") - promptgroup("51 - Output 0-7") - interest(1) - } - field(LNK2,DBF_FWDLINK) { - prompt("Forward Link 2") - promptgroup("51 - Output 0-7") - interest(1) - } - field(LNK3,DBF_FWDLINK) { - prompt("Forward Link 3") - promptgroup("51 - Output 0-7") - interest(1) - } - field(LNK4,DBF_FWDLINK) { - prompt("Forward Link 4") - promptgroup("51 - Output 0-7") - interest(1) - } - field(LNK5,DBF_FWDLINK) { - prompt("Forward Link 5") - promptgroup("51 - Output 0-7") - interest(1) - } - field(LNK6,DBF_FWDLINK) { - prompt("Forward Link 6") - promptgroup("51 - Output 0-7") - interest(1) - } - field(LNK7,DBF_FWDLINK) { - prompt("Forward Link 7") - promptgroup("51 - Output 0-7") - interest(1) - } - field(LNK8,DBF_FWDLINK) { - prompt("Forward Link 8") - promptgroup("52 - Output 8-F") - interest(1) - } - field(LNK9,DBF_FWDLINK) { - prompt("Forward Link 9") - promptgroup("52 - Output 8-F") - interest(1) - } - field(LNKA,DBF_FWDLINK) { - prompt("Forward Link 10") - promptgroup("52 - Output 8-F") - interest(1) - } - field(LNKB,DBF_FWDLINK) { - prompt("Forward Link 11") - promptgroup("52 - Output 8-F") - interest(1) - } - field(LNKC,DBF_FWDLINK) { - prompt("Forward Link 12") - promptgroup("52 - Output 8-F") - interest(1) - } - field(LNKD,DBF_FWDLINK) { - prompt("Forward Link 13") - promptgroup("52 - Output 8-F") - interest(1) - } - field(LNKE,DBF_FWDLINK) { - prompt("Forward Link 14") - promptgroup("52 - Output 8-F") - interest(1) - } - field(LNKF,DBF_FWDLINK) { - prompt("Forward Link 15") - promptgroup("52 - Output 8-F") - interest(1) - } -} diff --git a/src/std/rec/histogramRecord.c b/src/std/rec/histogramRecord.c deleted file mode 100644 index a9563500f..000000000 --- a/src/std/rec/histogramRecord.c +++ /dev/null @@ -1,471 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* histogramRecord.c - Record Support Routines for Histogram records */ -/* - * Author: Janet Anderson - * Date: 5/20/91 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "callback.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "epicsPrint.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "special.h" -#include "recSup.h" -#include "recGbl.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "histogramRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -#define indexof(field) histogramRecord##field - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -static long get_array_info(DBADDR *, long *, long *); -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *paddr,long *precision); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_alarm_double NULL -static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd); -static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd); - -rset histogramRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,histogramRSET); - -int histogramSDELprecision = 2; -epicsExportAddress(int, histogramSDELprecision); - -struct histogramdset { /* histogram input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_histogram;/*(0,2)=> success and add_count, don't add_count)*/ - /* if add_count then sgnl added to array */ - DEVSUPFUN special_linconv; -}; - -/* control block for callback*/ -typedef struct myCallback { - CALLBACK callback; - histogramRecord *prec; -} myCallback; - -static long add_count(histogramRecord *); -static long clear_histogram(histogramRecord *); -static void monitor(histogramRecord *); -static long readValue(histogramRecord *); - - -static void wdogCallback(CALLBACK *arg) -{ - myCallback *pcallback; - histogramRecord *prec; - - callbackGetUser(pcallback, arg); - prec = pcallback->prec; - /* force post events for any count change */ - if (prec->mcnt > 0){ - dbScanLock((struct dbCommon *)prec); - recGblGetTimeStamp(prec); - db_post_events(prec, prec->bptr, DBE_VALUE | DBE_LOG); - prec->mcnt = 0; - dbScanUnlock((struct dbCommon *)prec); - } - - if (prec->sdel > 0) { - /* restart timer */ - callbackRequestDelayed(&pcallback->callback, prec->sdel); - } - - return; -} -static long wdogInit(histogramRecord *prec) -{ - myCallback *pcallback; - - if (!prec->wdog && prec->sdel > 0) { - /* initialize a callback object */ - pcallback = calloc(1, sizeof(myCallback)); - pcallback->prec = prec; - if (!pcallback) - return -1; - - callbackSetCallback(wdogCallback, &pcallback->callback); - callbackSetUser(pcallback, &pcallback->callback); - callbackSetPriority(priorityLow, &pcallback->callback); - prec->wdog = pcallback; - } - - if (!prec->wdog) - return -1; - pcallback = prec->wdog; - if (!pcallback) - return -1; - if (prec->sdel > 0) { - /* start new timer on monitor */ - callbackRequestDelayed(&pcallback->callback, prec->sdel); - } - return 0; -} - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct histogramRecord *prec = (struct histogramRecord *)pcommon; - struct histogramdset *pdset; - - if (pass == 0) { - /* allocate space for histogram array */ - if (!prec->bptr) { - if (prec->nelm <= 0) - prec->nelm = 1; - prec->bptr = calloc(prec->nelm, sizeof(epicsUInt32)); - } - - /* calulate width of array element */ - prec->wdth = (prec->ulim - prec->llim) / prec->nelm; - return 0; - } - - wdogInit(prec); - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - recGblInitConstantLink(&prec->siol, DBF_DOUBLE, &prec->sval); - - /* must have device support defined */ - pdset = (struct histogramdset *) prec->dset; - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "histogram: init_record"); - return S_dev_noDSET; - } - - /* must have read_histogram function defined */ - if (pdset->number < 6 || !pdset->read_histogram) { - recGblRecordError(S_dev_missingSup, prec, "histogram: init_record"); - return S_dev_missingSup; - } - - /* call device support init_record */ - if (pdset->init_record) { - long status = pdset->init_record(prec); - - if (status) - return status; - } - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct histogramRecord *prec = (struct histogramRecord *)pcommon; - struct histogramdset *pdset = (struct histogramdset *) prec->dset; - int pact = prec->pact; - long status; - - if (!pdset || !pdset->read_histogram) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "read_histogram"); - return S_dev_missingSup; - } - - status = readValue(prec); /* read the new value */ - - /* check if device support set pact */ - if (!pact && prec->pact) - return 0; - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - - if (status == 0) - add_count(prec); - else if (status == 2) - status = 0; - - monitor(prec); - recGblFwdLink(prec); - - prec->pact=FALSE; - return status; -} - -static long special(DBADDR *paddr, int after) -{ - histogramRecord *prec = (histogramRecord *) paddr->precord; - - if (!after) - return 0; - - switch (paddr->special) { - case SPC_CALC: - if (prec->cmd <= 1) { - clear_histogram(prec); - prec->cmd = 0; - } - else if (prec->cmd == 2) { - prec->csta = TRUE; - prec->cmd = 0; - } - else if (prec->cmd == 3) { - prec->csta = FALSE; - prec->cmd = 0; - } - return 0; - - case SPC_MOD: - /* increment frequency in histogram array */ - add_count(prec); - return 0; - - case SPC_RESET: - if (dbGetFieldIndex(paddr) == histogramRecordSDEL) { - wdogInit(prec); - } - else { - prec->wdth = (prec->ulim - prec->llim) / prec->nelm; - clear_histogram(prec); - } - return 0; - - default: - recGblDbaddrError(S_db_badChoice, paddr, "histogram: special"); - return S_db_badChoice; - } -} - -static void monitor(histogramRecord *prec) -{ - unsigned short monitor_mask = recGblResetAlarms(prec); - - /* post events for count change */ - if (prec->mcnt > prec->mdel){ - monitor_mask |= DBE_VALUE | DBE_LOG; - /* reset counts since monitor */ - prec->mcnt = 0; - } - /* send out monitors connected to the value field */ - if (monitor_mask) - db_post_events(prec, prec->bptr, monitor_mask); - - return; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - histogramRecord *prec = (histogramRecord *) paddr->precord; - - paddr->pfield = prec->bptr; - paddr->no_elements = prec->nelm; - paddr->field_type = DBF_ULONG; - paddr->field_size = sizeof(epicsUInt32); - paddr->dbr_field_type = DBF_ULONG; - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - histogramRecord *prec = (histogramRecord *) paddr->precord; - - *no_elements = prec->nelm; - *offset = 0; - return 0; -} - -static long add_count(histogramRecord *prec) -{ - double temp; - epicsUInt32 *pdest; - int i; - - if (prec->csta == FALSE) - return 0; - - if (prec->llim >= prec->ulim) { - if (prec->nsev < INVALID_ALARM) { - prec->stat = SOFT_ALARM; - prec->sevr = INVALID_ALARM; - return -1; - } - } - if (prec->sgnl < prec->llim || - prec->sgnl >= prec->ulim) - return 0; - - temp = prec->sgnl - prec->llim; - for (i = 1; i <= prec->nelm; i++){ - if (temp <= (double) i * prec->wdth) - break; - } - pdest = prec->bptr + i - 1; - if (*pdest == (epicsUInt32) UINT_MAX) - *pdest = 0; - (*pdest)++; - prec->mcnt++; - - return 0; -} - -static long clear_histogram(histogramRecord *prec) -{ - int i; - - for (i = 0; i < prec->nelm; i++) - prec->bptr[i] = 0; - prec->mcnt = prec->mdel + 1; - prec->udf = FALSE; - - return 0; -} - -static long readValue(histogramRecord *prec) -{ - struct histogramdset *pdset = (struct histogramdset *) prec->dset; - long status; - - if (prec->pact) { - status = pdset->read_histogram(prec); - return status; - } - - status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0); - if (status) - return(status); - - if (prec->simm == menuYesNoNO) { - status = pdset->read_histogram(prec); - return status; - } - if (prec->simm == menuYesNoYES) { - status = dbGetLink(&prec->siol,DBR_DOUBLE, &prec->sval, 0, 0); - if (status == 0) - prec->sgnl = prec->sval; - } - else { - status = -1; - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return status; - } - - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - return status; -} - -static long get_units(DBADDR *paddr, char *units) -{ - if (dbGetFieldIndex(paddr) == indexof(SDEL)) { - strcpy(units,"s"); - } - /* We should have EGU for other DOUBLE values or probably get it from input link SVL */ - return 0; -} - -static long get_precision(const DBADDR *paddr,long *precision) -{ - histogramRecord *prec = (histogramRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(ULIM): - case indexof(LLIM): - case indexof(SGNL): - case indexof(SVAL): - case indexof(WDTH): - *precision = prec->prec; - break; - case indexof(SDEL): - *precision = histogramSDELprecision; - break; - default: - recGblGetPrec(paddr,precision); - } - return 0; -} - -static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd) -{ - histogramRecord *prec = (histogramRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - case indexof(WDTH): - pgd->upper_disp_limit = prec->ulim - prec->llim; - pgd->lower_disp_limit = 0.0; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return 0; -} -static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd) -{ - histogramRecord *prec = (histogramRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - case indexof(WDTH): - pcd->upper_ctrl_limit = prec->ulim - prec->llim; - pcd->lower_ctrl_limit = 0.0; - break; - default: - recGblGetControlDouble(paddr, pcd); - } - return 0; -} diff --git a/src/std/rec/histogramRecord.dbd b/src/std/rec/histogramRecord.dbd deleted file mode 100644 index 075400fc6..000000000 --- a/src/std/rec/histogramRecord.dbd +++ /dev/null @@ -1,146 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(histogramCMD) { - choice(histogramCMD_Read,"Read") - choice(histogramCMD_Clear,"Clear") - choice(histogramCMD_Start,"Start") - choice(histogramCMD_Stop,"Stop") -} -recordtype(histogram) { - include "dbCommon.dbd" - field(VAL,DBF_NOACCESS) { - prompt("Value") - asl(ASL0) - special(SPC_DBADDR) - extra("void * val") - #=type ULONG[] - #=read Yes - #=write Yes - } - field(NELM,DBF_USHORT) { - prompt("Num of Array Elements") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(CSTA,DBF_SHORT) { - prompt("Collection Status") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(CMD,DBF_MENU) { - prompt("Collection Control") - asl(ASL0) - special(SPC_CALC) - interest(1) - menu(histogramCMD) - } - field(ULIM,DBF_DOUBLE) { - prompt("Upper Signal Limit") - promptgroup("30 - Action") - special(SPC_RESET) - interest(1) - prop(YES) - } - field(LLIM,DBF_DOUBLE) { - prompt("Lower Signal Limit ") - promptgroup("30 - Action") - special(SPC_RESET) - interest(1) - prop(YES) - } - field(WDTH,DBF_DOUBLE) { - prompt("Element Width") - special(SPC_NOMOD) - interest(3) - } - field(SGNL,DBF_DOUBLE) { - prompt("Signal Value") - special(SPC_MOD) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(SVL,DBF_INLINK) { - prompt("Signal Value Location") - promptgroup("40 - Input") - interest(1) - } - field(BPTR,DBF_NOACCESS) { - prompt("Buffer Pointer") - special(SPC_NOMOD) - interest(4) - extra("epicsUInt32 *bptr") - } - field(WDOG,DBF_NOACCESS) { - prompt("Watchdog callback") - special(SPC_NOMOD) - interest(4) - extra("void * wdog") - } - field(MDEL,DBF_SHORT) { - prompt("Monitor Count Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MCNT,DBF_SHORT) { - prompt("Counts Since Monitor") - special(SPC_NOMOD) - interest(3) - } - field(SDEL,DBF_DOUBLE) { - prompt("Monitor Seconds Dband") - promptgroup("80 - Display") - special(SPC_RESET) - interest(1) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_DOUBLE) { - prompt("Simulation Value") - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(HOPR,DBF_ULONG) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_ULONG) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } -} - -variable(histogramSDELprecision, int) diff --git a/src/std/rec/int64inRecord.c b/src/std/rec/int64inRecord.c deleted file mode 100644 index 85063028d..000000000 --- a/src/std/rec/int64inRecord.c +++ /dev/null @@ -1,416 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* int64inRecord.c - Record Support Routines for int64in records */ -/* - * Original Author: Janet Anderson - * Date: 9/23/91 - */ - -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "int64inRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - - /* Hysterisis for alarm filtering: 1-1/e */ -#define THRESHOLD 0.6321 -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(dbCommon *, int); -static long process(dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset int64inRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,int64inRSET); - - -struct int64indset { /* int64in input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_int64in; /*returns: (-1,0)=>(failure,success)*/ -}; -static void checkAlarms(int64inRecord *prec, epicsTimeStamp *timeLast); -static void monitor(int64inRecord *prec); -static long readValue(int64inRecord *prec); - - -static long init_record(dbCommon *pcommon, int pass) -{ - int64inRecord *prec = (int64inRecord*)pcommon; - struct int64indset *pdset; - long status; - - if (pass==0) return(0); - - /* int64in.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ - if (prec->siml.type == CONSTANT) { - recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm); - } - - /* int64in.siol must be a CONSTANT or a PV_LINK or a DB_LINK */ - if (prec->siol.type == CONSTANT) { - recGblInitConstantLink(&prec->siol,DBF_LONG,&prec->sval); - } - - if(!(pdset = (struct int64indset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET,(void *)prec,"int64in: init_record"); - return(S_dev_noDSET); - } - /* must have read_int64in function defined */ - if( (pdset->number < 5) || (pdset->read_int64in == NULL) ) { - recGblRecordError(S_dev_missingSup,(void *)prec,"int64in: init_record"); - return(S_dev_missingSup); - } - if( pdset->init_record ) { - if((status=(*pdset->init_record)(prec))) return(status); - } - prec->mlst = prec->val; - prec->alst = prec->val; - prec->lalm = prec->val; - return(0); -} - -static long process(dbCommon *pcommon) -{ - int64inRecord *prec = (int64inRecord*)pcommon; - struct int64indset *pdset = (struct int64indset *)(prec->dset); - long status; - unsigned char pact=prec->pact; - epicsTimeStamp timeLast; - - if( (pdset==NULL) || (pdset->read_int64in==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"read_int64in"); - return(S_dev_missingSup); - } - timeLast = prec->time; - - status=readValue(prec); /* read the new value */ - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - if (status==0) prec->udf = FALSE; - - /* check for alarms */ - checkAlarms(prec, &timeLast); - /* check event list */ - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - -#define indexof(field) int64inRecord##field - -static long get_units(DBADDR *paddr,char *units) -{ - int64inRecord *prec=(int64inRecord *)paddr->precord; - - if(paddr->pfldDes->field_type == DBF_LONG) { - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return(0); -} - - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - int64inRecord *prec=(int64inRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - case indexof(SVAL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return(0); -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - int64inRecord *prec=(int64inRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - case indexof(SVAL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return(0); -} - -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - int64inRecord *prec=(int64inRecord *)paddr->precord; - - if(dbGetFieldIndex(paddr) == indexof(VAL)){ - pad->upper_alarm_limit = prec->hihi; - pad->upper_warning_limit = prec->high; - pad->lower_warning_limit = prec->low; - pad->lower_alarm_limit = prec->lolo; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(int64inRecord *prec, epicsTimeStamp *timeLast) -{ - enum { - range_Lolo = 1, - range_Low, - range_Normal, - range_High, - range_Hihi - } alarmRange; - static const epicsEnum16 range_stat[] = { - SOFT_ALARM, LOLO_ALARM, LOW_ALARM, - NO_ALARM, HIGH_ALARM, HIHI_ALARM - }; - - double aftc, afvl; - epicsInt64 val, hyst, lalm; - epicsInt64 alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - prec->afvl = 0; - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* check VAL against alarm limits */ - if ((asev = prec->hhsv) && - (val >= (alev = prec->hihi) || - ((lalm == alev) && (val >= alev - hyst)))) - alarmRange = range_Hihi; - else - if ((asev = prec->llsv) && - (val <= (alev = prec->lolo) || - ((lalm == alev) && (val <= alev + hyst)))) - alarmRange = range_Lolo; - else - if ((asev = prec->hsv) && - (val >= (alev = prec->high) || - ((lalm == alev) && (val >= alev - hyst)))) - alarmRange = range_High; - else - if ((asev = prec->lsv) && - (val <= (alev = prec->low) || - ((lalm == alev) && (val <= alev + hyst)))) - alarmRange = range_Low; - else { - alev = val; - asev = NO_ALARM; - alarmRange = range_Normal; - } - - aftc = prec->aftc; - afvl = 0; - - if (aftc > 0) { - /* Apply level filtering */ - afvl = prec->afvl; - if (afvl == 0) { - afvl = (double)alarmRange; - } else { - double t = epicsTimeDiffInSeconds(&prec->time, timeLast); - double alpha = aftc / (t + aftc); - - /* The sign of afvl indicates whether the result should be - * rounded up or down. This gives the filter hysteresis. - * If afvl > 0 the floor() function rounds to a lower alarm - * level, otherwise to a higher. - */ - afvl = alpha * afvl + - ((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange; - if (afvl - floor(afvl) > THRESHOLD) - afvl = -afvl; /* reverse rounding */ - - alarmRange = abs((int)floor(afvl)); - switch (alarmRange) { - case range_Hihi: - asev = prec->hhsv; - alev = prec->hihi; - break; - case range_High: - asev = prec->hsv; - alev = prec->high; - break; - case range_Normal: - asev = NO_ALARM; - break; - case range_Low: - asev = prec->lsv; - alev = prec->low; - break; - case range_Lolo: - asev = prec->llsv; - alev = prec->lolo; - break; - } - } - } - prec->afvl = afvl; - - if (asev) { - /* Report alarm condition, store LALM for future HYST calculations */ - if (recGblSetSevr(prec, range_stat[alarmRange], asev)) - prec->lalm = alev; - } else { - /* No alarm condition, reset LALM */ - prec->lalm = val; - } -} - -/* DELTA calculates the absolute difference between its arguments - * expressed as an unsigned 32-bit integer */ -#define DELTA(last, val) \ - ((epicsUInt32) ((last) > (val) ? (last) - (val) : (val) - (last))) - -static void monitor(int64inRecord *prec) -{ - unsigned short monitor_mask = recGblResetAlarms(prec); - - if (prec->mdel < 0 || - DELTA(prec->mlst, prec->val) > (epicsUInt32) prec->mdel) { - /* post events for value change */ - monitor_mask |= DBE_VALUE; - /* update last value monitored */ - prec->mlst = prec->val; - } - - if (prec->adel < 0 || - DELTA(prec->alst, prec->val) > (epicsUInt32) prec->adel) { - /* post events for archive value change */ - monitor_mask |= DBE_LOG; - /* update last archive value monitored */ - prec->alst = prec->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask) - db_post_events(prec, &prec->val, monitor_mask); -} - -static long readValue(int64inRecord *prec) -{ - long status; - struct int64indset *pdset = (struct int64indset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->read_int64in)(prec); - return(status); - } - - status=dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0); - if (status) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->read_int64in)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status=dbGetLink(&(prec->siol),DBR_LONG, - &(prec->sval),0,0); - - if (status==0) { - prec->val=prec->sval; - prec->udf=FALSE; - } - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/int64inRecord.dbd.pod b/src/std/rec/int64inRecord.dbd.pod deleted file mode 100644 index b85c68ae0..000000000 --- a/src/std/rec/int64inRecord.dbd.pod +++ /dev/null @@ -1,528 +0,0 @@ -#************************************************************************* -# Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=title 64bit Integer Input Record (int64in) - -This record type is normally used to obtain an integer value of up to 64 bits -from a hardware input. -The record supports alarm limits, alarm filtering, graphics and control -limits. - -=head2 Parameter Fields - -The record-specific fields are described below. - -=recordtype int64in - -=cut - -recordtype(int64in) { - -=head3 Input Specification - -These fields control where the record will read data from when it is processed: - -=fields DTYP, INP - -The DTYP field selects which device support layer should be responsible for -providing input data to the record. -The int64in device support layers provided by EPICS Base are documented in the -L section. -External support modules may provide additional device support for this record -type. -If not set explicitly, the DTYP value defaults to the first device support that -is loaded for the record type, which will usually be the C support -that comes with Base. - -The INP link field contains a database or channel access link or provides -hardware address information that the device support uses to determine where the -input data should come from. -The format for the INP field value depends on the device support layer that is -selected by the DTYP field. -See L
for a description of the various hardware -address formats supported. - -=head3 Operator Display Parameters - -These parameters are used to present meaningful data to the operator. -They do not affect the functioning of the record. - -=over - -=item * -DESC is a string that is usually used to briefly describe the record. - -=item * -EGU is a string of up to 16 characters naming the engineering units -that the VAL field represents. - -=item * -The HOPR and LOPR fields set the upper and lower display limits for the VAL, -HIHI, HIGH, LOW, and LOLO fields. - -=back - -=fields DESC, EGU, HOPR, LOPR - -=head3 Alarm Limits - -The user configures limit alarms by putting numerical values into the HIHI, -HIGH, LOW and LOLO fields, and by setting the associated alarm severity in the -corresponding HHSV, HSV, LSV and LLSV menu fields. - -The HYST field controls hysteresis to prevent alarm chattering from an input -signal that is close to one of the limits and suffers from significant readout -noise. - -The AFTC field sets the time constant on a low-pass filter that delays the -reporting of limit alarms until the signal has been within the alarm range for -that number of seconds (the default AFTC value of zero retains the previous -behavior). - -The LALM field is used by the record at run-time to implement the alarm limit -functionality. - -=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, AFTC, LALM - -=head3 Monitor Parameters - -These parameters are used to determine when to send monitors placed on the VAL -field. -The monitors are sent when the current value exceeds the last transmitted value -by the appropriate deadband. -If these fields are set to zero, a monitor will be triggered every time the -value changes; if set to -1, a monitor will be sent every time the record is -processed. - -The ADEL field sets the deadband for archive monitors (C events), while -the MDEL field controls value monitors (C events). - -The remaining fields are used by the record at run-time to implement the record -monitoring deadband functionality. - -=fields ADEL, MDEL, ALST, MLST - -=cut - - include "dbCommon.dbd" - field(VAL,DBF_INT64) { - prompt("Current value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Units name") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(HOPR,DBF_INT64) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_INT64) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HIHI,DBF_INT64) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_INT64) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_INT64) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_INT64) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HYST,DBF_INT64) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(AFTC, DBF_DOUBLE) { - prompt("Alarm Filter Time Constant") - promptgroup("70 - Alarm") - interest(1) - } - field(AFVL, DBF_DOUBLE) { - prompt("Alarm Filter Value") - special(SPC_NOMOD) - interest(3) - } - field(ADEL,DBF_INT64) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_INT64) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(LALM,DBF_INT64) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_INT64) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_INT64) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } - -=head3 Simulation Mode - -The record provides several fields to support simulation of absent hardware. -If the SIML field is set it is used to read a value into the SIMM field, which -controls whether simulation is used or not: - -=over - -=item * -SIMM must be zero (C) for the record to request a value from the device -support. - -=item * -If SIMM is C and the SIOL link field is set, a simulated value in -engineering units is read using the link into the SVAL field, from where it will -subsequently be copied into the VAL field. - -=back - -The SIMS field can be set to give the record an alarm severity while it is in -simulation mode. - -=fields SIML, SIMM, SIOL, SVAL, SIMS - -=cut - - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_INT64) { - prompt("Simulation Value") - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } -} - -=head2 Record Support - -=head3 Record Support Routines - -The following are the record support routines that would be of interest -to an application developer. -Other routines are the C, C, -C and C routines, which are used to -collect properties from the record for the complex DBR data structures. - -=head4 init_record - -This routine first initializes the simulation mode mechanism by setting SIMM -if SIML is a constant, and setting SVAL if SIOL is a constant. - -It then checks if the device support and the device support's -C routine are defined. -If either one does not exist, an error message is issued -and processing is terminated. - -If device support includes C, it is called. - -Finally, the deadband mechanisms for monitors and level alarms are -initialized. - -=head4 process - -See next section. - -=head3 Record Processing - -Routine C implements the following algorithm: - -=over - -=item 1. - -Check to see that the appropriate device support module and its -C routine are defined. -If either one does not exist, an error message is issued and processing is -terminated with the PACT field set to TRUE, effectively blocking the record -to avoid error storms. - -=item 2. - -Determine the value: - -If PACT is TRUE, call the device support C routine and return. - -If PACT is FALSE, read the value, honoring simulation mode: - -=over - -=item * Get SIMM by reading the SIML link. - -=item * If SIMM is C, -call the device support C routine and return. - -=item * If SIMM is C, -read the simulated value into SVAL using the SIOL link, -then copy the value into VAL and set UDF to 0 on success. - -=item * Raise an alarm for other values of SIMM. - -=item * Set the record to the severity configured in SIMS. - -=back - -=item 3. - -If PACT has been changed to TRUE, the device support signals asynchronous -processing: its C output routine has started, but not -completed reading the new value. -In this case, the processing routine merely returns, leaving PACT TRUE. - -=item 4. - -Set PACT to TRUE. Get the processing time stamp. Set UDF to 0 if reading -the value was successful. - -=item 5. - -Check UDF and level alarms: This routine checks to see if the record is -undefined (UDF is TRUE) or if the new VAL causes the alarm status -and severity to change. In the latter case, NSEV, NSTA and LALM are set. -It also honors the alarm hysteresis factor (HYST): the value must change -by at least HYST between level alarm status and severity changes. -If AFTC is set, alarm level filtering is applied. - -=item 6. - -Check to see if monitors should be invoked: - -=over - -=item * Alarm monitors are posted if the alarm status or severity have -changed. - -=item * Archive and value change monitors are posted if ADEL and MDEL -conditions (see L) are met. - -=back - -=item 7. - -Scan (process) forward link if necessary, set PACT to FALSE, and return. - -=back - -=head2 Device Support - -=head3 Device Support Interface - -The record requires device support to provide an entry table (dset) which -defines the following members: - - typedef struct { - long number; - long (*report)(int level); - long (*init)(int after); - long (*init_record)(int64inRecord *prec); - long (*get_ioint_info)(int cmd, int64inRecord *prec, IOSCANPVT *piosl); - long (*read_int64in)(int64inRecord *prec); - } int64indset; - -The module must set C to at least 5, and provide a pointer to its -C routine; the other function pointers may be C if their -associated functionality is not required for this support layer. -Most device supports also provide an C routine to configure the -record instance and connect it to the hardware or driver support layer. - -The individual routines are described below. - -=head3 Device Support Routines - -=head4 long report(int level) - -This optional routine is called by the IOC command C and is passed the -report level that was requested by the user. -It should print a report on the state of the device support to stdout. -The C parameter may be used to output increasingly more detailed -information at higher levels, or to select different types of information with -different levels. -Level zero should print no more than a small summary. - -=head4 long init(int after) - -This optional routine is called twice at IOC initialization time. -The first call happens before any of the C calls are made, with -the integer parameter C set to 0. -The second call happens after all of the C calls have been made, -with C set to 1. - -=head4 long init_record(int64inRecord *prec) - -This optional routine is called by the record initialization code for each -int64in record instance that has its DTYP field set to use this device support. -It is normally used to check that the INP address is the expected type and that -it points to a valid device; to allocate any record-specific buffer space and -other memory; and to connect any communication channels needed for the -C routine to work properly. - -=head4 long get_ioint_info(int cmd, int64inRecord *prec, IOSCANPVT *piosl) - -This optional routine is called whenever the record's SCAN field is being -changed to or from the value C to find out which I/O Interrupt Scan -list the record should be added to or deleted from. -If this routine is not provided, it will not be possible to set the SCAN field -to the value C at all. - -The C parameter is zero when the record is being added to the scan list, -and one when it is being removed from the list. -The routine must determine which interrupt source the record should be connected -to, which it indicates by the scan list that it points the location at C<*piosl> -to before returning. -It can prevent the SCAN field from being changed at all by returning a non-zero -value to its caller. - -In most cases the device support will create the I/O Interrupt Scan lists that -it returns for itself, by calling C once for -each separate interrupt source. -That routine allocates memory and inializes the list, then passes back a pointer -to the new list in the location at C<*piosl>. - -When the device support receives notification that the interrupt has occurred, -it announces that to the IOC by calling C -which will arrange for the appropriate records to be processed in a suitable -thread. -The C routine is safe to call from an interrupt service routine -on embedded architectures (vxWorks and RTEMS). - -=head4 long read_int64in(int64inRecord *prec) - -This essential routine is called when the record wants a new value from the -addressed device. -It is responsible for performing (or at least initiating) a read operation, and -(eventually) returning its value to the record. - -If the device may take more than a few microseconds to return the new value, -this routine must never block (busy-wait), but use the asynchronous -processing mechanism. -In that case it signals the asynchronous operation by setting the record's -PACT field to TRUE before it returns, having arranged for the record's -C routine to be called later once the read operation is finished. -When that happens, the C routine will be called again with -PACT still set to TRUE; it should then set it to FALSE to indicate the read -has completed, and return. - -A return value of zero indicates success, any other value indicates that an -error occurred. - -=head3 Extended Device Support - -... - -=cut - -=head2 Device Support For Soft Records - -Two soft device support modules, Soft Channel and Soft Callback Channel, are -provided for input records not related to actual hardware devices. The -INP link type must be either a CONSTANT, DB_LINK, or CA_LINK. - -=head3 Soft Channel - -This module reads the value using the record's INP link. - -C calls C to read the value. - -=head3 Soft Callback Channel - -This module is like the previous except that it reads the value -using asynchronous processing that will not complete until an asynchronous -processing of the INP target record has completed. - -=cut diff --git a/src/std/rec/int64outRecord.c b/src/std/rec/int64outRecord.c deleted file mode 100644 index ecbe52ce8..000000000 --- a/src/std/rec/int64outRecord.c +++ /dev/null @@ -1,394 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Author: Janet Anderson - * Date: 9/23/91 - */ -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "menuYesNo.h" -#include "menuIvoa.h" -#include "menuOmsl.h" - -#define GEN_SIZE_OFFSET -#include "int64outRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(dbCommon *, int); -static long process(dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset int64outRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,int64outRSET); - - -struct int64outdset { /* int64out input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_int64out;/*(-1,0)=>(failure,success*/ -}; -static void checkAlarms(int64outRecord *prec); -static void monitor(int64outRecord *prec); -static long writeValue(int64outRecord *prec); -static void convert(int64outRecord *prec, epicsInt64 value); - - -static long init_record(dbCommon *pcommon, int pass) -{ - int64outRecord *prec = (int64outRecord*)pcommon; - struct int64outdset *pdset; - long status=0; - - if (pass==0) return(0); - if (prec->siml.type == CONSTANT) { - recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm); - } - if(!(pdset = (struct int64outdset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET,(void *)prec,"int64out: init_record"); - return(S_dev_noDSET); - } - /* must have write_int64out functions defined */ - if( (pdset->number < 5) || (pdset->write_int64out == NULL) ) { - recGblRecordError(S_dev_missingSup,(void *)prec,"int64out: init_record"); - return(S_dev_missingSup); - } - if (prec->dol.type == CONSTANT) { - if(recGblInitConstantLink(&prec->dol,DBF_INT64,&prec->val)) - prec->udf=FALSE; - } - if( pdset->init_record ) { - if((status=(*pdset->init_record)(prec))) return(status); - } - prec->mlst = prec->val; - prec->alst = prec->val; - prec->lalm = prec->val; - return(0); -} - -static long process(dbCommon *pcommon) -{ - int64outRecord *prec = (int64outRecord*)pcommon; - struct int64outdset *pdset = (struct int64outdset *)(prec->dset); - long status=0; - epicsInt64 value; - unsigned char pact=prec->pact; - - if( (pdset==NULL) || (pdset->write_int64out==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"write_int64out"); - return(S_dev_missingSup); - } - if (!prec->pact) { - if((prec->dol.type != CONSTANT) - && (prec->omsl == menuOmslclosed_loop)) { - status = dbGetLink(&(prec->dol),DBR_INT64, - &value,0,0); - if (prec->dol.type!=CONSTANT && RTN_SUCCESS(status)) - prec->udf=FALSE; - } - else { - value = prec->val; - } - if (!status) convert(prec,value); - } - - /* check for alarms */ - checkAlarms(prec); - - if (prec->nsev < INVALID_ALARM ) - status=writeValue(prec); /* write the new value */ - else { - switch (prec->ivoa) { - case (menuIvoaContinue_normally) : - status=writeValue(prec); /* write the new value */ - break; - case (menuIvoaDon_t_drive_outputs) : - break; - case (menuIvoaSet_output_to_IVOV) : - if(prec->pact == FALSE){ - prec->val=prec->ivov; - } - status=writeValue(prec); /* write the new value */ - break; - default : - status=-1; - recGblRecordError(S_db_badField,(void *)prec, - "int64out:process Illegal IVOA field"); - } - } - - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - - /* check event list */ - monitor(prec); - - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - -#define indexof(field) int64outRecord##field - -static long get_units(DBADDR *paddr,char *units) -{ - int64outRecord *prec=(int64outRecord *)paddr->precord; - - if(paddr->pfldDes->field_type == DBF_INT64) { - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return(0); -} - -static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd) -{ - int64outRecord *prec=(int64outRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return(0); -} - -static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd) -{ - int64outRecord *prec=(int64outRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - /* do not change pre drvh/drvl behavior */ - if(prec->drvh > prec->drvl) { - pcd->upper_ctrl_limit = prec->drvh; - pcd->lower_ctrl_limit = prec->drvl; - } else { - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - } - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return(0); -} - -static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad) -{ - int64outRecord *prec=(int64outRecord *)paddr->precord; - - if(dbGetFieldIndex(paddr) == indexof(VAL)) { - pad->upper_alarm_limit = prec->hihi; - pad->upper_warning_limit = prec->high; - pad->lower_warning_limit = prec->low; - pad->lower_alarm_limit = prec->lolo; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(int64outRecord *prec) -{ - epicsInt64 val, hyst, lalm; - epicsInt64 alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* alarm condition hihi */ - asev = prec->hhsv; - alev = prec->hihi; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIHI_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition lolo */ - asev = prec->llsv; - alev = prec->lolo; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOLO_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition high */ - asev = prec->hsv; - alev = prec->high; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIGH_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition low */ - asev = prec->lsv; - alev = prec->low; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOW_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* we get here only if val is out of alarm by at least hyst */ - prec->lalm = val; - return; -} - -/* DELTA calculates the absolute difference between its arguments - * expressed as an unsigned 64-bit integer */ -#define DELTA(last, val) \ - ((epicsUInt64) ((last) > (val) ? (last) - (val) : (val) - (last))) - -static void monitor(int64outRecord *prec) -{ - unsigned short monitor_mask = recGblResetAlarms(prec); - - if (prec->mdel < 0 || - DELTA(prec->mlst, prec->val) > (epicsUInt64) prec->mdel) { - /* post events for value change */ - monitor_mask |= DBE_VALUE; - /* update last value monitored */ - prec->mlst = prec->val; - } - - if (prec->adel < 0 || - DELTA(prec->alst, prec->val) > (epicsUInt64) prec->adel) { - /* post events for archive value change */ - monitor_mask |= DBE_LOG; - /* update last archive value monitored */ - prec->alst = prec->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask) - db_post_events(prec, &prec->val, monitor_mask); -} - -static long writeValue(int64outRecord *prec) -{ - long status; - struct int64outdset *pdset = (struct int64outdset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->write_int64out)(prec); - return(status); - } - - status=dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0); - if (!RTN_SUCCESS(status)) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->write_int64out)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status=dbPutLink(&prec->siol,DBR_INT64,&prec->val,1); - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} - -static void convert(int64outRecord *prec, epicsInt64 value) -{ - /* check drive limits */ - if(prec->drvh > prec->drvl) { - if (value > prec->drvh) value = prec->drvh; - else if (value < prec->drvl) value = prec->drvl; - } - prec->val = value; -} diff --git a/src/std/rec/int64outRecord.dbd.pod b/src/std/rec/int64outRecord.dbd.pod deleted file mode 100644 index b489ada97..000000000 --- a/src/std/rec/int64outRecord.dbd.pod +++ /dev/null @@ -1,596 +0,0 @@ -#************************************************************************* -# Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=title 64bit Integer Output Record (int64out) - -This record type is normally used to send an integer value of up to 64 bits -to an output device. -The record supports alarm, drive, graphics and control limits. - -=head2 Parameter Fields - -The record-specific fields are described below. - -=recordtype int64out - -=cut - -recordtype(int64out) { - -=head3 Output Value Determination - -These fields control how the record determines the value to be output when it -gets processed: - -=fields OMSL, DOL, DRVH, DRVL, VAL - -The following steps are performed in order during record processing. - -=head4 Fetch Value - -The OMSL menu field is used to determine whether the DOL link field -should be used during processing or not: - -=over - -=item * -If OMSL is C the DOL link field is not used. -The new output value is taken from the VAL field, which may have been set from -elsewhere. - -=item * -If OMSL is C the DOL link field is used to obtain a value. - -=back - -=head4 Drive Limits - -The output value is clipped to the range DRVL to DRVH inclusive, provided -that DRVH > DRVL. -The result is copied into the VAL field. - -=head3 Output Specification - -These fields control where the record will read data from when it is processed: - -=fields DTYP, OUT - -The DTYP field selects which device support layer should be responsible for -writing output data. -The int64out device support layers provided by EPICS Base are documented in the -L section. -External support modules may provide additional device support for this record -type. -If not set explicitly, the DTYP value defaults to the first device support that -is loaded for the record type, which will usually be the C support -that comes with Base. - -The OUT link field contains a database or channel access link or provides -hardware address information that the device support uses to determine where the -output data should be sent to. -The format for the OUT field value depends on the device support layer that is -selected by the DTYP field. -See L
for a description of the various hardware -address formats supported. - -=head3 Operator Display Parameters - -These parameters are used to present meaningful data to the operator. -They do not affect the functioning of the record. - -=over - -=item * -DESC is a string that is usually used to briefly describe the record. - -=item * -EGU is a string of up to 16 characters naming the engineering units -that the VAL field represents. - -=item * -The HOPR and LOPR fields set the upper and lower display limits for the VAL, -HIHI, HIGH, LOW, and LOLO fields. - -=back - -=fields DESC, EGU, HOPR, LOPR - -=head3 Alarm Limits - -The user configures limit alarms by putting numerical values into the HIHI, -HIGH, LOW and LOLO fields, and by setting the associated alarm severities -in the corresponding HHSV, HSV, LSV and LLSV menu fields. - -The HYST field controls hysteresis to prevent alarm chattering from an input -signal that is close to one of the limits and suffers from significant readout -noise. - -The LALM field is used by the record at run-time to implement the alarm limit -hysteresis functionality. - -=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, LALM - -=head3 Monitor Parameters - -These parameters are used to determine when to send monitors placed on the VAL -field. -The monitors are sent when the current value exceeds the last transmitted value -by the appropriate deadband. -If these fields are set to zero, a monitor will be triggered every time the -value changes; if set to -1, a monitor will be sent every time the record is -processed. - -The ADEL field sets the deadband for archive monitors (C events), while -the MDEL field controls value monitors (C events). - -The remaining fields are used by the record at run-time to implement the record -monitoring deadband functionality. - -=fields ADEL, MDEL, ALST, MLST - -=cut - - include "dbCommon.dbd" - field(VAL,DBF_INT64) { - prompt("Desired Output") - promptgroup("50 - Output") - asl(ASL0) - pp(TRUE) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup("40 - Input") - interest(1) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - interest(1) - menu(menuOmsl) - } - field(EGU,DBF_STRING) { - prompt("Units name") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(DRVH,DBF_INT64) { - prompt("Drive High Limit") - promptgroup("30 - Action") - pp(TRUE) - interest(1) - prop(YES) - } - field(DRVL,DBF_INT64) { - prompt("Drive Low Limit") - promptgroup("30 - Action") - pp(TRUE) - interest(1) - prop(YES) - } - field(HOPR,DBF_INT64) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_INT64) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HIHI,DBF_INT64) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_INT64) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_INT64) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_INT64) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HYST,DBF_INT64) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_INT64) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_INT64) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(LALM,DBF_INT64) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_INT64) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_INT64) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } - -=head3 Simulation Mode - -The record provides several fields to support simulation of absent hardware. -If the SIML field is set it is used to read a value into the SIMM field, -which controls whether simulation is used or not: - -=over - -=item * -SIMM must be zero (C) for the record to write a value to the device -support. - -=item * -If SIMM is C and the SIOL link field is set, the value in engineering -units is written using the link. - -=back - -The SIMS field can be set to give the record an alarm severity while it is in -simulation mode. - -=fields SIML, SIMM, SIOL, SIMS - -=cut - - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - -=head3 Invalid Alarm Output Action - -Whenever an output record is put into INVALID alarm severity, IVOA specifies -the action to take. - -=over - -=item C (default) - -Write the value. Same as if severity is lower than INVALID. - -=item C - -Do not write value. - -=item C - -Set VAL to IVOV, then write the value. - -=back - -=fields IVOA, IVOV - -=cut - - field(IVOA,DBF_MENU) { - prompt("INVALID output action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_INT64) { - prompt("INVALID output value") - promptgroup("50 - Output") - interest(2) - } -} - -=head2 Record Support - -=head3 Record Support Routines - -The following are the record support routines that would be of interest -to an application developer. -Other routines are the C, C, -C and C routines, which are used to -collect properties from the record for the complex DBR data structures. - -=head4 init_record - -This routine first initializes the simulation mode mechanism by setting SIMM -if SIML is a constant. - -It then checks if the device support and the device support's -C routine are defined. -If either one does not exist, an error message is issued -and processing is terminated. - -If DOL is a constant, then VAL is initialized with its value and UDF is -set to FALSE. - -If device support includes C, it is called. - -Finally, the deadband mechanisms for monitors and level alarms are -initialized. - -=head4 process - -See next section. - -=head3 Record Processing - -Routine C implements the following algorithm: - -=over - -=item 1. - -Check to see that the appropriate device support module and its -C routine are defined. -If either one does not exist, an error message is issued and processing is -terminated with the PACT field set to TRUE, effectively blocking the record -to avoid error storms. - -=item 2. - -Check PACT. If PACT is FALSE, do the following: - -=over - -=item * Determine value, honoring closed loop mode: -if DOL is not a CONSTANT and OMSL is CLOSED_LOOP then get value from DOL -setting UDF to FALSE in case of success, else use the VAL field. - -=item * Call C: -if drive limits are defined then force value to be within those limits. - -=back - -=item 3. - -Check UDF and level alarms: This routine checks to see if the record is -undefined (UDF is TRUE) or if the new VAL causes the alarm status -and severity to change. In the latter case, NSEV, NSTA and LALM are set. -It also honors the alarm hysteresis factor (HYST): the value must change -by at least HYST between level alarm status and severity changes. - -=item 4. - -Check severity and write the new value. See L -for details on how invalid alarms affect output records. - -=item 5. - -If PACT has been changed to TRUE, the device support signals asynchronous -processing: its C output routine has started, but not -completed writing the new value. -In this case, the processing routine merely returns, leaving PACT TRUE. - -=item 6. - -Check to see if monitors should be invoked: - -=over - -=item * Alarm monitors are posted if the alarm status or severity have -changed. - -=item * Archive and value change monitors are posted if ADEL and MDEL -conditions (see L) are met. - -=item * NSEV and NSTA are reset to 0. - -=back - -=item 7. - -Scan (process) forward link if necessary, set PACT to FALSE, and return. - -=back - -=head2 Device Support - -=head3 Device Support Interface - -The record requires device support to provide an entry table (dset) which -defines the following members: - - typedef struct { - long number; - long (*report)(int level); - long (*init)(int after); - long (*init_record)(int64outRecord *prec); - long (*get_ioint_info)(int cmd, int64outRecord *prec, IOSCANPVT *piosl); - long (*write_int64out)(int64outRecord *prec); - } int64outdset; - -The module must set C to at least 5, and provide a pointer to its -C routine; the other function pointers may be C if their -associated functionality is not required for this support layer. -Most device supports also provide an C routine to configure the -record instance and connect it to the hardware or driver support layer. - -The individual routines are described below. - -=head3 Device Support Routines - -=head4 long report(int level) - -This optional routine is called by the IOC command C and is passed the -report level that was requested by the user. -It should print a report on the state of the device support to stdout. -The C parameter may be used to output increasingly more detailed -information at higher levels, or to select different types of information with -different levels. -Level zero should print no more than a small summary. - -=head4 long init(int after) - -This optional routine is called twice at IOC initialization time. -The first call happens before any of the C calls are made, with -the integer parameter C set to 0. -The second call happens after all of the C calls have been made, -with C set to 1. - -=head4 long init_record(int64outRecord *prec) - -This optional routine is called by the record initialization code for each -int64out record instance that has its DTYP field set to use this device support. -It is normally used to check that the OUT address is the expected type and that -it points to a valid device, to allocate any record-specific buffer space and -other memory, and to connect any communication channels needed for the -C routine to work properly. - -=head4 long get_ioint_info(int cmd, int64outRecord *prec, IOSCANPVT *piosl) - -This optional routine is called whenever the record's SCAN field is being -changed to or from the value C to find out which I/O Interrupt Scan -list the record should be added to or deleted from. -If this routine is not provided, it will not be possible to set the SCAN field -to the value C at all. - -The C parameter is zero when the record is being added to the scan list, -and one when it is being removed from the list. -The routine must determine which interrupt source the record should be connected -to, which it indicates by the scan list that it points the location at C<*piosl> -to before returning. -It can prevent the SCAN field from being changed at all by returning a non-zero -value to its caller. - -In most cases the device support will create the I/O Interrupt Scan lists that -it returns for itself, by calling C once for -each separate interrupt source. -That routine allocates memory and inializes the list, then passes back a pointer -to the new list in the location at C<*piosl>. - -When the device support receives notification that the interrupt has occurred, -it announces that to the IOC by calling C -which will arrange for the appropriate records to be processed in a suitable -thread. -The C routine is safe to call from an interrupt service routine -on embedded architectures (vxWorks and RTEMS). - -=head4 long write_int64out(int64outRecord *prec) - -This essential routine is called when the record wants to write a new value -to the addressed device. -It is responsible for performing (or at least initiating) a write operation, -using the value from the record's VAL field. - -If the device may take more than a few microseconds to accept the new value, -this routine must never block (busy-wait), but use the asynchronous -processing mechanism. -In that case it signals the asynchronous operation by setting the record's -PACT field to TRUE before it returns, having arranged for the record's -C routine to be called later once the write operation is over. -When that happens, the C routine will be called again with -PACT still set to TRUE; it should then set it to FALSE to indicate the write -has completed, and return. - -A return value of zero indicates success, any other value indicates that an -error occurred. - -=head3 Extended Device Support - -... - -=cut - -=head2 Device Support For Soft Records - -Two soft device support modules, Soft Channel and Soft Callback Channel, are -provided for output records not related to actual hardware devices. The -OUT link type must be either a CONSTANT, DB_LINK, or CA_LINK. - -=head3 Soft Channel - -This module writes the current value using the record's VAL field. - -C calls C to write the current value. - -=head3 Soft Callback Channel - -This module is like the previous except that it writes the current value -using asynchronous processing that will not complete until an asynchronous -processing of the target record has completed. - -=cut diff --git a/src/std/rec/longinRecord.c b/src/std/rec/longinRecord.c deleted file mode 100644 index bd3c24ab9..000000000 --- a/src/std/rec/longinRecord.c +++ /dev/null @@ -1,415 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recLongin.c - Record Support Routines for Longin records */ -/* - * Author: Janet Anderson - * Date: 9/23/91 - */ - -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "longinRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - - /* Hysterisis for alarm filtering: 1-1/e */ -#define THRESHOLD 0.6321 -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset longinRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,longinRSET); - - -struct longindset { /* longin input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_longin; /*returns: (-1,0)=>(failure,success)*/ -}; -static void checkAlarms(longinRecord *prec, epicsTimeStamp *timeLast); -static void monitor(longinRecord *prec); -static long readValue(longinRecord *prec); - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct longinRecord *prec = (struct longinRecord *)pcommon; - struct longindset *pdset = (struct longindset *) prec->dset; - - if (pass==0) - return(0); - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - recGblInitConstantLink(&prec->siol, DBF_LONG, &prec->sval); - - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "longin: init_record"); - return S_dev_noDSET; - } - - /* must have read_longin function defined */ - if ((pdset->number < 5) || (pdset->read_longin == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "longin: init_record"); - return S_dev_missingSup; - } - - if (pdset->init_record) { - long status = pdset->init_record(prec); - - if (status) - return status; - } - - prec->mlst = prec->val; - prec->alst = prec->val; - prec->lalm = prec->val; - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct longinRecord *prec = (struct longinRecord *)pcommon; - struct longindset *pdset = (struct longindset *)(prec->dset); - long status; - unsigned char pact=prec->pact; - epicsTimeStamp timeLast; - - if( (pdset==NULL) || (pdset->read_longin==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"read_longin"); - return(S_dev_missingSup); - } - timeLast = prec->time; - - status=readValue(prec); /* read the new value */ - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - if (status==0) prec->udf = FALSE; - - /* check for alarms */ - checkAlarms(prec, &timeLast); - /* check event list */ - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - -#define indexof(field) longinRecord##field - -static long get_units(DBADDR *paddr,char *units) -{ - longinRecord *prec=(longinRecord *)paddr->precord; - - if(paddr->pfldDes->field_type == DBF_LONG) { - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return(0); -} - - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - longinRecord *prec=(longinRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - case indexof(SVAL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return(0); -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - longinRecord *prec=(longinRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - case indexof(SVAL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return(0); -} - -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - longinRecord *prec=(longinRecord *)paddr->precord; - - if(dbGetFieldIndex(paddr) == indexof(VAL)){ - pad->upper_alarm_limit = prec->hihi; - pad->upper_warning_limit = prec->high; - pad->lower_warning_limit = prec->low; - pad->lower_alarm_limit = prec->lolo; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(longinRecord *prec, epicsTimeStamp *timeLast) -{ - enum { - range_Lolo = 1, - range_Low, - range_Normal, - range_High, - range_Hihi - } alarmRange; - static const epicsEnum16 range_stat[] = { - SOFT_ALARM, LOLO_ALARM, LOW_ALARM, - NO_ALARM, HIGH_ALARM, HIHI_ALARM - }; - - double aftc, afvl; - epicsInt32 val, hyst, lalm; - epicsInt32 alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - prec->afvl = 0; - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* check VAL against alarm limits */ - if ((asev = prec->hhsv) && - (val >= (alev = prec->hihi) || - ((lalm == alev) && (val >= alev - hyst)))) - alarmRange = range_Hihi; - else - if ((asev = prec->llsv) && - (val <= (alev = prec->lolo) || - ((lalm == alev) && (val <= alev + hyst)))) - alarmRange = range_Lolo; - else - if ((asev = prec->hsv) && - (val >= (alev = prec->high) || - ((lalm == alev) && (val >= alev - hyst)))) - alarmRange = range_High; - else - if ((asev = prec->lsv) && - (val <= (alev = prec->low) || - ((lalm == alev) && (val <= alev + hyst)))) - alarmRange = range_Low; - else { - alev = val; - asev = NO_ALARM; - alarmRange = range_Normal; - } - - aftc = prec->aftc; - afvl = 0; - - if (aftc > 0) { - /* Apply level filtering */ - afvl = prec->afvl; - if (afvl == 0) { - afvl = (double)alarmRange; - } else { - double t = epicsTimeDiffInSeconds(&prec->time, timeLast); - double alpha = aftc / (t + aftc); - - /* The sign of afvl indicates whether the result should be - * rounded up or down. This gives the filter hysteresis. - * If afvl > 0 the floor() function rounds to a lower alarm - * level, otherwise to a higher. - */ - afvl = alpha * afvl + - ((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange; - if (afvl - floor(afvl) > THRESHOLD) - afvl = -afvl; /* reverse rounding */ - - alarmRange = abs((int)floor(afvl)); - switch (alarmRange) { - case range_Hihi: - asev = prec->hhsv; - alev = prec->hihi; - break; - case range_High: - asev = prec->hsv; - alev = prec->high; - break; - case range_Normal: - asev = NO_ALARM; - break; - case range_Low: - asev = prec->lsv; - alev = prec->low; - break; - case range_Lolo: - asev = prec->llsv; - alev = prec->lolo; - break; - } - } - } - prec->afvl = afvl; - - if (asev) { - /* Report alarm condition, store LALM for future HYST calculations */ - if (recGblSetSevr(prec, range_stat[alarmRange], asev)) - prec->lalm = alev; - } else { - /* No alarm condition, reset LALM */ - prec->lalm = val; - } -} - -/* DELTA calculates the absolute difference between its arguments - * expressed as an unsigned 32-bit integer */ -#define DELTA(last, val) \ - ((epicsUInt32) ((last) > (val) ? (last) - (val) : (val) - (last))) - -static void monitor(longinRecord *prec) -{ - unsigned short monitor_mask = recGblResetAlarms(prec); - - if (prec->mdel < 0 || - DELTA(prec->mlst, prec->val) > (epicsUInt32) prec->mdel) { - /* post events for value change */ - monitor_mask |= DBE_VALUE; - /* update last value monitored */ - prec->mlst = prec->val; - } - - if (prec->adel < 0 || - DELTA(prec->alst, prec->val) > (epicsUInt32) prec->adel) { - /* post events for archive value change */ - monitor_mask |= DBE_LOG; - /* update last archive value monitored */ - prec->alst = prec->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask) - db_post_events(prec, &prec->val, monitor_mask); -} - -static long readValue(longinRecord *prec) -{ - long status; - struct longindset *pdset = (struct longindset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->read_longin)(prec); - return(status); - } - - status=dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0); - if (status) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->read_longin)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status=dbGetLink(&(prec->siol),DBR_LONG, - &(prec->sval),0,0); - - if (status==0) { - prec->val=prec->sval; - prec->udf=FALSE; - } - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/longinRecord.dbd b/src/std/rec/longinRecord.dbd deleted file mode 100644 index 60eee5000..000000000 --- a/src/std/rec/longinRecord.dbd +++ /dev/null @@ -1,161 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(longin) { - include "dbCommon.dbd" - field(VAL,DBF_LONG) { - prompt("Current value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(HOPR,DBF_LONG) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_LONG) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HIHI,DBF_LONG) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_LONG) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_LONG) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_LONG) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HYST,DBF_LONG) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(AFTC, DBF_DOUBLE) { - prompt("Alarm Filter Time Constant") - promptgroup("70 - Alarm") - interest(1) - } - field(AFVL, DBF_DOUBLE) { - prompt("Alarm Filter Value") - special(SPC_NOMOD) - interest(3) - } - field(ADEL,DBF_LONG) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_LONG) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(LALM,DBF_LONG) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_LONG) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_LONG) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_LONG) { - prompt("Simulation Value") - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } -} diff --git a/src/std/rec/longoutRecord.c b/src/std/rec/longoutRecord.c deleted file mode 100644 index 6062ad741..000000000 --- a/src/std/rec/longoutRecord.c +++ /dev/null @@ -1,397 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Janet Anderson - * Date: 9/23/91 - */ -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "menuYesNo.h" -#include "menuIvoa.h" -#include "menuOmsl.h" - -#define GEN_SIZE_OFFSET -#include "longoutRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset longoutRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,longoutRSET); - - -struct longoutdset { /* longout input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_longout;/*(-1,0)=>(failure,success*/ -}; -static void checkAlarms(longoutRecord *prec); -static void monitor(longoutRecord *prec); -static long writeValue(longoutRecord *prec); -static void convert(longoutRecord *prec, epicsInt32 value); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct longoutRecord *prec = (struct longoutRecord *)pcommon; - struct longoutdset *pdset = (struct longoutdset *) prec->dset; - - if (pass==0) - return 0; - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "longout: init_record"); - return S_dev_noDSET; - } - - /* must have write_longout functions defined */ - if ((pdset->number < 5) || (pdset->write_longout == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "longout: init_record"); - return S_dev_missingSup; - } - - if (recGblInitConstantLink(&prec->dol, DBF_LONG, &prec->val)) - prec->udf=FALSE; - - if (pdset->init_record) { - long status = pdset->init_record(prec); - - if (status) - return status; - } - - prec->mlst = prec->val; - prec->alst = prec->val; - prec->lalm = prec->val; - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct longoutRecord *prec = (struct longoutRecord *)pcommon; - struct longoutdset *pdset = (struct longoutdset *)(prec->dset); - long status=0; - epicsInt32 value; - unsigned char pact=prec->pact; - - if( (pdset==NULL) || (pdset->write_longout==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"write_longout"); - return(S_dev_missingSup); - } - if (!prec->pact) { - if (!dbLinkIsConstant(&prec->dol) && - prec->omsl == menuOmslclosed_loop) { - status = dbGetLink(&prec->dol, DBR_LONG, &value, 0, 0); - if (!dbLinkIsConstant(&prec->dol) && !status) - prec->udf=FALSE; - } - else { - value = prec->val; - } - if (!status) convert(prec,value); - } - - /* check for alarms */ - checkAlarms(prec); - - if (prec->nsev < INVALID_ALARM ) - status=writeValue(prec); /* write the new value */ - else { - switch (prec->ivoa) { - case (menuIvoaContinue_normally) : - status=writeValue(prec); /* write the new value */ - break; - case (menuIvoaDon_t_drive_outputs) : - break; - case (menuIvoaSet_output_to_IVOV) : - if(prec->pact == FALSE){ - prec->val=prec->ivov; - } - status=writeValue(prec); /* write the new value */ - break; - default : - status=-1; - recGblRecordError(S_db_badField,(void *)prec, - "longout:process Illegal IVOA field"); - } - } - - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - - /* check event list */ - monitor(prec); - - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - -#define indexof(field) longoutRecord##field - -static long get_units(DBADDR *paddr,char *units) -{ - longoutRecord *prec=(longoutRecord *)paddr->precord; - - if(paddr->pfldDes->field_type == DBF_LONG) { - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return(0); -} - -static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd) -{ - longoutRecord *prec=(longoutRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - default: - recGblGetGraphicDouble(paddr,pgd); - } - return(0); -} - -static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd) -{ - longoutRecord *prec=(longoutRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - /* do not change pre drvh/drvl behavior */ - if(prec->drvh > prec->drvl) { - pcd->upper_ctrl_limit = prec->drvh; - pcd->lower_ctrl_limit = prec->drvl; - } else { - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - } - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return(0); -} - -static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad) -{ - longoutRecord *prec=(longoutRecord *)paddr->precord; - - if(dbGetFieldIndex(paddr) == indexof(VAL)) { - pad->upper_alarm_limit = prec->hihi; - pad->upper_warning_limit = prec->high; - pad->lower_warning_limit = prec->low; - pad->lower_alarm_limit = prec->lolo; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(longoutRecord *prec) -{ - epicsInt32 val, hyst, lalm; - epicsInt32 alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* alarm condition hihi */ - asev = prec->hhsv; - alev = prec->hihi; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIHI_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition lolo */ - asev = prec->llsv; - alev = prec->lolo; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOLO_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition high */ - asev = prec->hsv; - alev = prec->high; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIGH_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition low */ - asev = prec->lsv; - alev = prec->low; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOW_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* we get here only if val is out of alarm by at least hyst */ - prec->lalm = val; - return; -} - -/* DELTA calculates the absolute difference between its arguments - * expressed as an unsigned 32-bit integer */ -#define DELTA(last, val) \ - ((epicsUInt32) ((last) > (val) ? (last) - (val) : (val) - (last))) - -static void monitor(longoutRecord *prec) -{ - unsigned short monitor_mask = recGblResetAlarms(prec); - - if (prec->mdel < 0 || - DELTA(prec->mlst, prec->val) > (epicsUInt32) prec->mdel) { - /* post events for value change */ - monitor_mask |= DBE_VALUE; - /* update last value monitored */ - prec->mlst = prec->val; - } - - if (prec->adel < 0 || - DELTA(prec->alst, prec->val) > (epicsUInt32) prec->adel) { - /* post events for archive value change */ - monitor_mask |= DBE_LOG; - /* update last archive value monitored */ - prec->alst = prec->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask) - db_post_events(prec, &prec->val, monitor_mask); -} - -static long writeValue(longoutRecord *prec) -{ - long status; - struct longoutdset *pdset = (struct longoutdset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->write_longout)(prec); - return(status); - } - - status=dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0); - if (!RTN_SUCCESS(status)) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->write_longout)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status=dbPutLink(&prec->siol,DBR_LONG,&prec->val,1); - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} - -static void convert(longoutRecord *prec, epicsInt32 value) -{ - /* check drive limits */ - if(prec->drvh > prec->drvl) { - if (value > prec->drvh) value = prec->drvh; - else if (value < prec->drvl) value = prec->drvl; - } - prec->val = value; -} diff --git a/src/std/rec/longoutRecord.dbd b/src/std/rec/longoutRecord.dbd deleted file mode 100644 index c3ba0b977..000000000 --- a/src/std/rec/longoutRecord.dbd +++ /dev/null @@ -1,184 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(longout) { - include "dbCommon.dbd" - field(VAL,DBF_LONG) { - prompt("Desired Output") - promptgroup("50 - Output") - asl(ASL0) - pp(TRUE) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup("40 - Input") - interest(1) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - interest(1) - menu(menuOmsl) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(DRVH,DBF_LONG) { - prompt("Drive High Limit") - promptgroup("30 - Action") - pp(TRUE) - interest(1) - prop(YES) - } - field(DRVL,DBF_LONG) { - prompt("Drive Low Limit") - promptgroup("30 - Action") - pp(TRUE) - interest(1) - prop(YES) - } - field(HOPR,DBF_LONG) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_LONG) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HIHI,DBF_LONG) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_LONG) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_LONG) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_LONG) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HYST,DBF_LONG) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_LONG) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_LONG) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(LALM,DBF_LONG) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_LONG) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_LONG) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(IVOA,DBF_MENU) { - prompt("INVALID output action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_LONG) { - prompt("INVALID output value") - promptgroup("50 - Output") - interest(2) - } -} diff --git a/src/std/rec/lsiRecord.c b/src/std/rec/lsiRecord.c deleted file mode 100644 index 81b6785ab..000000000 --- a/src/std/rec/lsiRecord.c +++ /dev/null @@ -1,287 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Long String Input record type */ -/* - * Author: Andrew Johnson - * Date: 2012-11-27 - */ - -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "alarm.h" -#include "cantProceed.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "errMdef.h" -#include "menuPost.h" -#include "menuYesNo.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#define GEN_SIZE_OFFSET -#include "lsiRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -static void monitor(lsiRecord *); -static long readValue(lsiRecord *); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct lsiRecord *prec = (struct lsiRecord *)pcommon; - lsidset *pdset; - - if (pass == 0) { - size_t sizv = prec->sizv; - - if (sizv < 16) { - sizv = 16; /* Enforce a minimum size for the VAL field */ - prec->sizv = sizv; - } - - prec->val = callocMustSucceed(1, sizv, "lsi::init_record"); - prec->len = 0; - prec->oval = callocMustSucceed(1, sizv, "lsi::init_record"); - prec->olen = 0; - return 0; - } - - dbLoadLink(&prec->siml, DBF_USHORT, &prec->simm); - - pdset = (lsidset *) prec->dset; - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "lsi: init_record"); - return S_dev_noDSET; - } - - /* must have a read_string function */ - if (pdset->number < 5 || !pdset->read_string) { - recGblRecordError(S_dev_missingSup, prec, "lsi: init_record"); - return S_dev_missingSup; - } - - if (pdset->init_record) { - long status = pdset->init_record(prec); - - if (status) - return status; - } - - if (prec->len) { - strcpy(prec->oval, prec->val); - prec->olen = prec->len; - prec->udf = FALSE; - } - - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct lsiRecord *prec = (struct lsiRecord *)pcommon; - int pact = prec->pact; - lsidset *pdset = (lsidset *) prec->dset; - long status = 0; - - if (!pdset || !pdset->read_string) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "lsi: read_string"); - return S_dev_missingSup; - } - - status = readValue(prec); /* read the new value */ - if (!pact && prec->pact) - return 0; - - prec->pact = TRUE; - recGblGetTimeStamp(prec); - - monitor(prec); - - /* Wrap up */ - recGblFwdLink(prec); - prec->pact = FALSE; - return status; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - lsiRecord *prec = (lsiRecord *) paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (fieldIndex == lsiRecordVAL) { - paddr->pfield = prec->val; - paddr->special = SPC_MOD; - } - else if (fieldIndex == lsiRecordOVAL) { - paddr->pfield = prec->oval; - paddr->special = SPC_NOMOD; - } - else { - errlogPrintf("lsiRecord::cvt_dbaddr called for %s.%s\n", - prec->name, paddr->pfldDes->name); - return -1; - } - - paddr->no_elements = 1; - paddr->field_type = DBF_STRING; - paddr->dbr_field_type = DBF_STRING; - paddr->field_size = prec->sizv; - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - lsiRecord *prec = (lsiRecord *) paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (fieldIndex == lsiRecordVAL) - *no_elements = prec->len; - else if (fieldIndex == lsiRecordOVAL) - *no_elements = prec->olen; - else - return -1; - - *offset = 0; - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - lsiRecord *prec = (lsiRecord *) paddr->precord; - - if (nNew >= prec->sizv) - nNew = prec->sizv - 1; /* truncated string */ - if (paddr->field_type == DBF_CHAR) - prec->val[nNew] = 0; /* ensure data is terminated */ - - return 0; -} - -static long special(DBADDR *paddr, int after) -{ - lsiRecord *prec = (lsiRecord *) paddr->precord; - - if (!after) - return 0; - - /* We set prec->len here and not in put_array_info() - * because that does not get called if the put was - * done using a DBR_STRING type. - */ - prec->len = strlen(prec->val) + 1; - db_post_events(prec, &prec->len, DBE_VALUE | DBE_LOG); - - return 0; -} - -static void monitor(lsiRecord *prec) -{ - epicsUInt16 events = recGblResetAlarms(prec); - - if (prec->len != prec->olen || - memcmp(prec->oval, prec->val, prec->len)) { - events |= DBE_VALUE | DBE_LOG; - memcpy(prec->oval, prec->val, prec->len); - } - - if (prec->len != prec->olen) { - prec->olen = prec->len; - db_post_events(prec, &prec->len, DBE_VALUE | DBE_LOG); - } - - if (prec->mpst == menuPost_Always) - events |= DBE_VALUE; - if (prec->apst == menuPost_Always) - events |= DBE_LOG; - - if (events) - db_post_events(prec, prec->val, events); -} - -static long readValue(lsiRecord *prec) -{ - long status; - lsidset *pdset = (lsidset *) prec->dset; - - if (prec->pact) - goto read; - - status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0); - if (status) - return status; - - switch (prec->simm) { - case menuYesNoNO: -read: - status = pdset->read_string(prec); - break; - - case menuYesNoYES: - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - status = dbGetLinkLS(&prec->siol, prec->val, prec->sizv, &prec->len); - break; - - default: - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - status = -1; - } - - if (!status) - prec->udf = FALSE; - - return status; -} - - -/* Create Record Support Entry Table*/ - -#define report NULL -#define initialize NULL -/* init_record */ -/* process */ -/* special */ -#define get_value NULL -/* cvt_dbaddr */ -/* get_array_info */ -/* put_array_info */ -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset lsiRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, lsiRSET); diff --git a/src/std/rec/lsiRecord.dbd b/src/std/rec/lsiRecord.dbd deleted file mode 100644 index c50d905d8..000000000 --- a/src/std/rec/lsiRecord.dbd +++ /dev/null @@ -1,88 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -recordtype(lsi) { - include "dbCommon.dbd" - %#include "devSup.h" - % - %/* Declare Device Support Entry Table */ - %typedef struct lsidset { - % long number; - % DEVSUPFUN report; - % DEVSUPFUN init; - % DEVSUPFUN init_record; - % DEVSUPFUN get_ioint_info; - % DEVSUPFUN read_string; - %} lsidset; - % - field(VAL,DBF_NOACCESS) { - prompt("Current Value") - asl(ASL0) - pp(TRUE) - special(SPC_DBADDR) - extra("char *val") - } - field(OVAL,DBF_NOACCESS) { - prompt("Old Value") - special(SPC_DBADDR) - interest(3) - extra("char *oval") - } - field(SIZV,DBF_USHORT) { - prompt("Size of buffers") - promptgroup("40 - Input") - special(SPC_NOMOD) - interest(1) - initial("41") - } - field(LEN,DBF_ULONG) { - prompt("Length of VAL") - special(SPC_NOMOD) - } - field(OLEN,DBF_ULONG) { - prompt("Length of OVAL") - special(SPC_NOMOD) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(MPST,DBF_MENU) { - prompt("Post Value Monitors") - promptgroup("80 - Display") - interest(1) - menu(menuPost) - } - field(APST,DBF_MENU) { - prompt("Post Archive Monitors") - promptgroup("80 - Display") - interest(1) - menu(menuPost) - } - field(SIML,DBF_INLINK) { - prompt("Simulation Mode Link") - promptgroup("90 - Simulate") - interest(2) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(2) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Simulation Mode Severity") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(2) - } -} diff --git a/src/std/rec/lsoRecord.c b/src/std/rec/lsoRecord.c deleted file mode 100644 index 625f5d77c..000000000 --- a/src/std/rec/lsoRecord.c +++ /dev/null @@ -1,325 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Long String Output record type */ -/* - * Author: Andrew Johnson - * Date: 2012-11-28 - */ - - -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "alarm.h" -#include "cantProceed.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "menuIvoa.h" -#include "menuOmsl.h" -#include "menuPost.h" -#include "menuYesNo.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#define GEN_SIZE_OFFSET -#include "lsoRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -static void monitor(lsoRecord *); -static long writeValue(lsoRecord *); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct lsoRecord *prec = (struct lsoRecord *)pcommon; - lsodset *pdset; - - if (pass == 0) { - size_t sizv = prec->sizv; - - if (sizv < 16) { - sizv = 16; /* Enforce a minimum size for the VAL field */ - prec->sizv = sizv; - } - - prec->val = callocMustSucceed(1, sizv, "lso::init_record"); - prec->len = 0; - prec->oval = callocMustSucceed(1, sizv, "lso::init_record"); - prec->olen = 0; - return 0; - } - - dbLoadLink(&prec->siml, DBF_USHORT, &prec->simm); - - pdset = (lsodset *) prec->dset; - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "lso: init_record"); - return S_dev_noDSET; - } - - /* must have a write_string function defined */ - if (pdset->number < 5 || !pdset->write_string) { - recGblRecordError(S_dev_missingSup, prec, "lso: init_record"); - return S_dev_missingSup; - } - - dbLoadLinkLS(&prec->dol, prec->val, prec->sizv, &prec->len); - - if (pdset->init_record) { - long status = pdset->init_record(prec); - - if (status) - return status; - } - - if (prec->len) { - strcpy(prec->oval, prec->val); - prec->olen = prec->len; - prec->udf = FALSE; - } - - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct lsoRecord *prec = (struct lsoRecord *)pcommon; - int pact = prec->pact; - lsodset *pdset = (lsodset *) prec->dset; - long status = 0; - - if (!pdset || !pdset->write_string) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "lso: write_string"); - return S_dev_missingSup; - } - - if (!pact && prec->omsl == menuOmslclosed_loop) - if (!dbGetLinkLS(&prec->dol, prec->val, prec->sizv, &prec->len)) - prec->udf = FALSE; - - if (prec->udf) - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - - if (prec->nsev < INVALID_ALARM ) - status = writeValue(prec); /* write the new value */ - else { - switch (prec->ivoa) { - case menuIvoaContinue_normally: - status = writeValue(prec); /* write the new value */ - break; - - case menuIvoaDon_t_drive_outputs: - break; - - case menuIvoaSet_output_to_IVOV: - if (!prec->pact) { - size_t size = prec->sizv - 1; - - strncpy(prec->val, prec->ivov, size); - prec->val[size] = 0; - prec->len = strlen(prec->val) + 1; - } - status = writeValue(prec); /* write the new value */ - break; - - default: - status = -1; - recGblRecordError(S_db_badField, prec, - "lso:process Bad IVOA choice"); - } - } - - /* Asynchronous if device support set pact */ - if (!pact && prec->pact) - return status; - - prec->pact = TRUE; - recGblGetTimeStamp(prec); - - monitor(prec); - - /* Wrap up */ - recGblFwdLink(prec); - prec->pact = FALSE; - return status; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - lsoRecord *prec = (lsoRecord *) paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (fieldIndex == lsoRecordVAL) { - paddr->pfield = prec->val; - paddr->special = SPC_MOD; - } - else if (fieldIndex == lsoRecordOVAL) { - paddr->pfield = prec->oval; - paddr->special = SPC_NOMOD; - } - else { - errlogPrintf("lsoRecord::cvt_dbaddr called for %s.%s\n", - prec->name, paddr->pfldDes->name); - return -1; - } - - paddr->no_elements = 1; - paddr->field_type = DBF_STRING; - paddr->dbr_field_type = DBF_STRING; - paddr->field_size = prec->sizv; - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - lsoRecord *prec = (lsoRecord *) paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (fieldIndex == lsoRecordVAL) - *no_elements = prec->len; - else if (fieldIndex == lsoRecordOVAL) - *no_elements = prec->olen; - else - return -1; - - *offset = 0; - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - lsoRecord *prec = (lsoRecord *) paddr->precord; - - if (nNew >= prec->sizv) - nNew = prec->sizv - 1; /* truncated string */ - if (paddr->field_type == DBF_CHAR) - prec->val[nNew] = 0; /* ensure data is terminated */ - - return 0; -} - -static long special(DBADDR *paddr, int after) -{ - lsoRecord *prec = (lsoRecord *) paddr->precord; - - if (!after) - return 0; - - /* We set prec->len here and not in put_array_info() - * because that does not get called if the put was - * done using a DBR_STRING type. - */ - prec->len = strlen(prec->val) + 1; - db_post_events(prec, &prec->len, DBE_VALUE | DBE_LOG); - - return 0; -} - -static void monitor(lsoRecord *prec) -{ - epicsUInt16 events = recGblResetAlarms(prec); - - if (prec->len != prec->olen || - memcmp(prec->oval, prec->val, prec->len)) { - events |= DBE_VALUE | DBE_LOG; - memcpy(prec->oval, prec->val, prec->len); - } - - if (prec->len != prec->olen) { - prec->olen = prec->len; - db_post_events(prec, &prec->len, DBE_VALUE | DBE_LOG); - } - - if (prec->mpst == menuPost_Always) - events |= DBE_VALUE; - if (prec->apst == menuPost_Always) - events |= DBE_LOG; - - if (events) - db_post_events(prec, prec->val, events); -} - -static long writeValue(lsoRecord *prec) -{ - long status; - lsodset *pdset = (lsodset *) prec->dset; - - if (prec->pact) - goto write; - - status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0); - if (status) - return(status); - - switch (prec->simm) { - case menuYesNoNO: -write: - status = pdset->write_string(prec); - break; - - case menuYesNoYES: - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - status = dbPutLink(&prec->siol,DBR_STRING, prec->val,1); - break; - - default: - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - status = -1; - } - - return status; -} - -/* Create Record Support Entry Table*/ - -#define report NULL -#define initialize NULL -/* init_record */ -/* process */ -/* special */ -#define get_value NULL -/* cvt_dbaddr */ -/* get_array_info */ -/* put_array_info */ -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset lsoRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, lsoRSET); diff --git a/src/std/rec/lsoRecord.dbd b/src/std/rec/lsoRecord.dbd deleted file mode 100644 index 69203f2d0..000000000 --- a/src/std/rec/lsoRecord.dbd +++ /dev/null @@ -1,112 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -recordtype(lso) { - include "dbCommon.dbd" - %#include "devSup.h" - % - %/* Declare Device Support Entry Table */ - %typedef struct lsodset { - % long number; - % DEVSUPFUN report; - % DEVSUPFUN init; - % DEVSUPFUN init_record; - % DEVSUPFUN get_ioint_info; - % DEVSUPFUN write_string; - %} lsodset; - % - field(VAL,DBF_NOACCESS) { - prompt("Current Value") - asl(ASL0) - pp(TRUE) - special(SPC_DBADDR) - extra("char *val") - } - field(OVAL,DBF_NOACCESS) { - prompt("Previous Value") - special(SPC_DBADDR) - interest(3) - extra("char *oval") - } - field(SIZV,DBF_USHORT) { - prompt("Size of buffers") - promptgroup("50 - Output") - special(SPC_NOMOD) - interest(1) - initial("41") - } - field(LEN,DBF_ULONG) { - prompt("Length of VAL") - special(SPC_NOMOD) - } - field(OLEN,DBF_ULONG) { - prompt("Length of OVAL") - special(SPC_NOMOD) - interest(3) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Link") - promptgroup("40 - Input") - interest(1) - } - field(IVOA,DBF_MENU) { - prompt("INVALID Output Action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_STRING) { - prompt("INVALID Output Value") - promptgroup("50 - Output") - interest(2) - size(40) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - interest(1) - menu(menuOmsl) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(MPST,DBF_MENU) { - prompt("Post Value Monitors") - promptgroup("80 - Display") - interest(1) - menu(menuPost) - } - field(APST,DBF_MENU) { - prompt("Post Archive Monitors") - promptgroup("80 - Display") - interest(1) - menu(menuPost) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode link") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } -} diff --git a/src/std/rec/mbbiDirectRecord.c b/src/std/rec/mbbiDirectRecord.c deleted file mode 100644 index 112272925..000000000 --- a/src/std/rec/mbbiDirectRecord.c +++ /dev/null @@ -1,260 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Copyright (c) 2002 Southeastern Universities Research Association, as -* Operator of Thomas Jefferson National Accelerator Facility. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* mbbiDirectRecord.c - Record Support routines for mbboDirect records */ -/* - * Original Authors: Bob Dalesio and Matthew Needes - * Date: 10-07-93 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "menuSimm.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" - -#define GEN_SIZE_OFFSET -#include "mbbiDirectRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset mbbiDirectRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,mbbiDirectRSET); - -struct mbbidset { /* multi bit binary input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure, success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbi; /*returns: (0,2)=>(success, success no convert)*/ -}; - -static void monitor(mbbiDirectRecord *); -static long readValue(mbbiDirectRecord *); - -#define NUM_BITS 16 - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)pcommon; - struct mbbidset *pdset = (struct mbbidset *) prec->dset; - long status = 0; - - if (pass == 0) - return status; - - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "mbbiDirect: init_record"); - return S_dev_noDSET; - } - - if ((pdset->number < 5) || (pdset->read_mbbi == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "mbbiDirect: init_record"); - return S_dev_missingSup; - } - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval); - - /* Initialize MASK if the user set NOBT instead */ - if (prec->mask == 0 && prec->nobt <= 32) - prec->mask = ((epicsUInt64) 1u << prec->nobt) - 1; - - if (pdset->init_record) { - status = pdset->init_record(prec); - if (status == 0) { - epicsUInt16 val = prec->val; - epicsUInt8 *pBn = &prec->b0; - int i; - - /* Initialize B0 - BF from VAL */ - for (i = 0; i < NUM_BITS; i++, pBn++, val >>= 1) - *pBn = !! (val & 1); - } - } - - prec->mlst = prec->val; - prec->oraw = prec->rval; - return status; -} - -static long process(struct dbCommon *pcommon) -{ - struct mbbiDirectRecord *prec = (struct mbbiDirectRecord *)pcommon; - struct mbbidset *pdset = (struct mbbidset *) prec->dset; - long status; - int pact = prec->pact; - - if ((pdset == NULL) || (pdset->read_mbbi == NULL)) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "read_mbbi"); - return S_dev_missingSup; - } - - status = readValue(prec); - - /* Done if device support set PACT */ - if (!pact && prec->pact) - return 0; - - prec->pact = TRUE; - recGblGetTimeStamp(prec); - - if (status == 0) { - /* Convert RVAL to VAL */ - epicsUInt32 rval = prec->rval; - - if (prec->shft > 0) - rval >>= prec->shft; - - prec->val = rval; - prec->udf = FALSE; - } - else if (status == 2) - status = 0; - - if (prec->udf) - recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM); - - monitor(prec); - - /* Wrap up */ - recGblFwdLink(prec); - prec->pact = FALSE; - return status; -} - -static void monitor(mbbiDirectRecord *prec) -{ - epicsUInt16 events = recGblResetAlarms(prec); - epicsUInt16 vl_events = events | DBE_VALUE | DBE_LOG; - epicsUInt16 val = prec->val; - epicsUInt8 *pBn = &prec->b0; - int i; - - /* Update B0 - BF from VAL and post monitors */ - for (i = 0; i < NUM_BITS; i++, pBn++, val >>= 1) { - epicsUInt8 oBn = *pBn; - - *pBn = !! (val & 1); - if (oBn != *pBn) - db_post_events(prec, pBn, vl_events); - else if (events) - db_post_events(prec, pBn, events); - } - - if (prec->mlst != prec->val) { - events = vl_events; - prec->mlst = prec->val; - } - if (events) - db_post_events(prec, &prec->val, events); - - if (prec->oraw != prec->rval) { - db_post_events(prec, &prec->rval, vl_events); - prec->oraw = prec->rval; - } -} - -static long readValue(mbbiDirectRecord *prec) -{ - struct mbbidset *pdset = (struct mbbidset *) prec->dset; - long status; - - if (prec->pact) - return pdset->read_mbbi(prec); - - status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0); - if (status) - return status; - - switch (prec->simm) { - case menuSimmNO: - return pdset->read_mbbi(prec); - - case menuSimmYES: - status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0); - if (status == 0) { - prec->val = prec->sval; - prec->udf = FALSE; - } - status = 2; /* Don't convert */ - break; - - case menuSimmRAW: - status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0); - if (status == 0) { - prec->rval = prec->sval; - prec->udf = FALSE; - } - status = 0; /* Convert RVAL */ - break; - - default: - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return -1; - } - - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - return status; -} diff --git a/src/std/rec/mbbiDirectRecord.dbd b/src/std/rec/mbbiDirectRecord.dbd deleted file mode 100644 index 3fa3d8823..000000000 --- a/src/std/rec/mbbiDirectRecord.dbd +++ /dev/null @@ -1,156 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(mbbiDirect) { - include "dbCommon.dbd" - field(VAL,DBF_USHORT) { - prompt("Current Value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(NOBT,DBF_SHORT) { - prompt("Number of Bits") - promptgroup("40 - Input") - special(SPC_NOMOD) - interest(1) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(RVAL,DBF_ULONG) { - prompt("Raw Value") - pp(TRUE) - } - field(ORAW,DBF_ULONG) { - prompt("Prev Raw Value") - special(SPC_NOMOD) - interest(3) - } - field(MASK,DBF_ULONG) { - prompt("Hardware Mask") - special(SPC_NOMOD) - interest(1) - } - field(MLST,DBF_USHORT) { - prompt("Last Value Monitored") - special(SPC_NOMOD) - interest(3) - } - field(SHFT,DBF_USHORT) { - prompt("Shift") - promptgroup("40 - Input") - interest(1) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_ULONG) { - prompt("Simulation Value") - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuSimm) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(B0,DBF_UCHAR) { - prompt("Bit 0") - pp(TRUE) - interest(1) - } - field(B1,DBF_UCHAR) { - prompt("Bit 1") - pp(TRUE) - interest(1) - } - field(B2,DBF_UCHAR) { - prompt("Bit 2") - pp(TRUE) - interest(1) - } - field(B3,DBF_UCHAR) { - prompt("Bit 3") - pp(TRUE) - interest(1) - } - field(B4,DBF_UCHAR) { - prompt("Bit 4") - pp(TRUE) - interest(1) - } - field(B5,DBF_UCHAR) { - prompt("Bit 5") - pp(TRUE) - interest(1) - } - field(B6,DBF_UCHAR) { - prompt("Bit 6") - pp(TRUE) - interest(1) - } - field(B7,DBF_UCHAR) { - prompt("Bit 7") - pp(TRUE) - interest(1) - } - field(B8,DBF_UCHAR) { - prompt("Bit 8") - pp(TRUE) - interest(1) - } - field(B9,DBF_UCHAR) { - prompt("Bit 9") - pp(TRUE) - interest(1) - } - field(BA,DBF_UCHAR) { - prompt("Bit A") - pp(TRUE) - interest(1) - } - field(BB,DBF_UCHAR) { - prompt("Bit B") - pp(TRUE) - interest(1) - } - field(BC,DBF_UCHAR) { - prompt("Bit C") - pp(TRUE) - interest(1) - } - field(BD,DBF_UCHAR) { - prompt("Bit D") - pp(TRUE) - interest(1) - } - field(BE,DBF_UCHAR) { - prompt("Bit E") - pp(TRUE) - interest(1) - } - field(BF,DBF_UCHAR) { - prompt("Bit F") - pp(TRUE) - interest(1) - } -} diff --git a/src/std/rec/mbbiRecord.c b/src/std/rec/mbbiRecord.c deleted file mode 100644 index ad5a8ce06..000000000 --- a/src/std/rec/mbbiRecord.c +++ /dev/null @@ -1,413 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Original Author: Bob Dalesio - * Date: 5-9-88 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "epicsMath.h" -#include "errMdef.h" -#include "menuSimm.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" - -#define GEN_SIZE_OFFSET -#include "mbbiRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Hysterisis for alarm filtering: 1-1/e */ -#define THRESHOLD 0.6321 - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -static long get_enum_str(const DBADDR *, char *); -static long get_enum_strs(const DBADDR *, struct dbr_enumStrs *); -static long put_enum_str(const DBADDR *, const char *); -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset mbbiRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,mbbiRSET); - -struct mbbidset { /* multi bit binary input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /* returns: (-1,0) => (failure, success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_mbbi;/* (0, 2) => (success, success no convert)*/ -}; - -static void checkAlarms(mbbiRecord *, epicsTimeStamp *); -static void monitor(mbbiRecord *); -static long readValue(mbbiRecord *); - -static void init_common(mbbiRecord *prec) -{ - epicsUInt32 *pstate_values = &prec->zrvl; - char *pstate_string = prec->zrst; - int i; - - /* Check if any states are defined */ - for (i = 0; i < 16; i++, pstate_string += sizeof(prec->zrst)) { - if ((pstate_values[i] != 0) || (*pstate_string != '\0')) { - prec->sdef = TRUE; - return; - } - } - prec->sdef = FALSE; -} - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct mbbiRecord *prec = (struct mbbiRecord *)pcommon; - struct mbbidset *pdset = (struct mbbidset *) prec->dset; - long status = 0; - - if (pass == 0) - return 0; - - pdset = (struct mbbidset *) prec->dset; - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "mbbi: init_record"); - return S_dev_noDSET; - } - - if ((pdset->number < 5) || (pdset->read_mbbi == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "mbbi: init_record"); - return S_dev_missingSup; - } - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - recGblInitConstantLink(&prec->siol, DBF_USHORT, &prec->sval); - - /* Initialize MASK if the user set NOBT instead */ - if (prec->mask == 0 && prec->nobt <= 32) - prec->mask = ((epicsUInt64) 1u << prec->nobt) - 1; - - if (pdset->init_record) - status = pdset->init_record(prec); - - init_common(prec); - - prec->mlst = prec->val; - prec->lalm = prec->val; - prec->oraw = prec->rval; - return status; -} - -static long process(struct dbCommon *pcommon) -{ - struct mbbiRecord *prec = (struct mbbiRecord *)pcommon; - struct mbbidset *pdset = (struct mbbidset *) prec->dset; - long status; - int pact = prec->pact; - epicsTimeStamp timeLast; - - if ((pdset == NULL) || (pdset->read_mbbi == NULL)) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "read_mbbi"); - return S_dev_missingSup; - } - - timeLast = prec->time; - - status = readValue(prec); - - /* Done if device support set PACT */ - if (!pact && prec->pact) - return 0; - - prec->pact = TRUE; - recGblGetTimeStamp(prec); - - if (status == 0) { - /* Convert RVAL to VAL */ - epicsUInt32 *pstate_values; - short i; - epicsUInt32 rval = prec->rval; - - prec->udf = FALSE; - if (prec->shft > 0) - rval >>= prec->shft; - - if (prec->sdef) { - pstate_values = &(prec->zrvl); - prec->val = 65535; /* Initalize to unknown state*/ - for (i = 0; i < 16; i++) { - if (*pstate_values == rval) { - prec->val = i; - break; - } - pstate_values++; - } - } - else /* No states defined, set VAL = RVAL */ - prec->val = rval; - } - else if (status == 2) - status = 0; - - checkAlarms(prec, &timeLast); - monitor(prec); - - /* Wrap up */ - recGblFwdLink(prec); - prec->pact=FALSE; - return status; -} - -static long special(DBADDR *paddr, int after) -{ - mbbiRecord *prec = (mbbiRecord *) paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (!after) - return 0; - - switch (paddr->special) { - case SPC_MOD: - init_common(prec); - if (fieldIndex >= mbbiRecordZRST && fieldIndex <= mbbiRecordFFST) { - int event = DBE_PROPERTY; - - if (prec->val == fieldIndex - mbbiRecordZRST) - event |= DBE_VALUE | DBE_LOG; - db_post_events(prec, &prec->val, event); - } - return 0; - default: - recGblDbaddrError(S_db_badChoice, paddr, "mbbi: special"); - return S_db_badChoice; - } -} - -static long get_enum_str(const DBADDR *paddr, char *pstring) -{ - mbbiRecord *prec = (mbbiRecord *) paddr->precord; - int index; - unsigned short *pfield = paddr->pfield; - epicsEnum16 val = *pfield; - - index = dbGetFieldIndex(paddr); - if (index != mbbiRecordVAL) { - strcpy(pstring, "Illegal_Value"); - } - else if (val <= 15) { - char *pstate = prec->zrst + val * sizeof(prec->zrst); - - strncpy(pstring, pstate, sizeof(prec->zrst)); - } - else { - strcpy(pstring, "Illegal Value"); - } - return 0; -} - -static long get_enum_strs(const DBADDR *paddr, struct dbr_enumStrs *pes) -{ - mbbiRecord *prec = (mbbiRecord *) paddr->precord; - char *pstate = prec->zrst; - int i; - short states = 0; - - memset(pes->strs, '\0', sizeof(pes->strs)); - for (i = 0; i < 16; i++, pstate += sizeof(prec->zrst) ) { - strncpy(pes->strs[i], pstate, sizeof(prec->zrst)); - if (*pstate!=0) states = i+1; - } - pes->no_str = states; - return 0; -} - -static long put_enum_str(const DBADDR *paddr, const char *pstring) -{ - mbbiRecord *prec = (mbbiRecord *) paddr->precord; - char *pstate; - short i; - - if (prec->sdef) { - pstate = prec->zrst; - for (i = 0; i < 16; i++) { - if (strncmp(pstate, pstring, sizeof(prec->zrst)) == 0) { - prec->val = i; - prec->udf = FALSE; - return 0; - } - pstate += sizeof(prec->zrst); - } - } - return S_db_badChoice; -} - -static void checkAlarms(mbbiRecord *prec, epicsTimeStamp *timeLast) -{ - double aftc, afvl; - unsigned short alarm; - epicsEnum16 asev; - epicsEnum16 val = prec->val; - - /* Check for UDF alarm */ - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - prec->afvl = 0; - return; - } - - /* Check for STATE alarm */ - if (val > 15) { - /* Unknown state */ - alarm = prec->unsv; - } - else { - /* State has a severity field */ - epicsEnum16 *severities = &prec->zrsv; - - alarm = severities[prec->val]; - } - - aftc = prec->aftc; - afvl = 0; - - if (aftc > 0) { - afvl = prec->afvl; - if (afvl == 0) { - afvl = (double) alarm; - } - else { - double t = epicsTimeDiffInSeconds(&prec->time, timeLast); - double alpha = aftc / (t + aftc); - - afvl = alpha * afvl + - ((afvl > 0) ? (1.0 - alpha) : (alpha - 1.0)) * alarm; - if (afvl - floor(afvl) > THRESHOLD) - afvl = -afvl; - - alarm = abs((int)floor(afvl)); - } - } - - asev = alarm; - recGblSetSevr(prec, STATE_ALARM, asev); - - /* Check for COS alarm */ - if (val == prec->lalm || - recGblSetSevr(prec, COS_ALARM, prec->cosv)) - return; - - prec->lalm = val; -} - -static void monitor(mbbiRecord *prec) -{ - epicsUInt16 events = recGblResetAlarms(prec); - - if (prec->mlst != prec->val) { - events |= DBE_VALUE | DBE_LOG; - prec->mlst = prec->val; - } - - if (events) - db_post_events(prec, &prec->val, events); - - if (prec->oraw != prec->rval) { - db_post_events(prec, &prec->rval, events | DBE_VALUE | DBE_LOG); - prec->oraw = prec->rval; - } -} - -static long readValue(mbbiRecord *prec) -{ - struct mbbidset *pdset = (struct mbbidset *) prec->dset; - long status; - - if (prec->pact) - return pdset->read_mbbi(prec); - - status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0); - if (status) - return status; - - switch (prec->simm) { - case menuSimmNO: - return pdset->read_mbbi(prec); - - case menuSimmYES: - status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0); - if (status == 0) { - prec->val = prec->sval; - prec->udf = FALSE; - } - status = 2; /* Don't convert */ - break; - - case menuSimmRAW: - status = dbGetLink(&prec->siol, DBR_ULONG, &prec->sval, 0, 0); - if (status == 0) { - prec->rval = prec->sval; - prec->udf = FALSE; - } - status = 0; /* Convert RVAL */ - break; - - default: - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return -1; - } - - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - return status; -} diff --git a/src/std/rec/mbbiRecord.dbd b/src/std/rec/mbbiRecord.dbd deleted file mode 100644 index 1f5724c92..000000000 --- a/src/std/rec/mbbiRecord.dbd +++ /dev/null @@ -1,478 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(mbbi) { - include "dbCommon.dbd" - field(VAL,DBF_ENUM) { - prompt("Current Value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(NOBT,DBF_USHORT) { - prompt("Number of Bits") - promptgroup("40 - Input") - special(SPC_NOMOD) - interest(1) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(ZRVL,DBF_ULONG) { - prompt("Zero Value") - promptgroup("41 - Input 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(ONVL,DBF_ULONG) { - prompt("One Value") - promptgroup("41 - Input 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(TWVL,DBF_ULONG) { - prompt("Two Value") - promptgroup("41 - Input 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(THVL,DBF_ULONG) { - prompt("Three Value") - promptgroup("41 - Input 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(FRVL,DBF_ULONG) { - prompt("Four Value") - promptgroup("41 - Input 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(FVVL,DBF_ULONG) { - prompt("Five Value") - promptgroup("41 - Input 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(SXVL,DBF_ULONG) { - prompt("Six Value") - promptgroup("41 - Input 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(SVVL,DBF_ULONG) { - prompt("Seven Value") - promptgroup("41 - Input 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(EIVL,DBF_ULONG) { - prompt("Eight Value") - promptgroup("42 - Input 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(NIVL,DBF_ULONG) { - prompt("Nine Value") - promptgroup("42 - Input 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(TEVL,DBF_ULONG) { - prompt("Ten Value") - promptgroup("42 - Input 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(ELVL,DBF_ULONG) { - prompt("Eleven Value") - promptgroup("42 - Input 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(TVVL,DBF_ULONG) { - prompt("Twelve Value") - promptgroup("42 - Input 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(TTVL,DBF_ULONG) { - prompt("Thirteen Value") - promptgroup("42 - Input 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(FTVL,DBF_ULONG) { - prompt("Fourteen Value") - promptgroup("42 - Input 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(FFVL,DBF_ULONG) { - prompt("Fifteen Value") - promptgroup("42 - Input 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(ZRST,DBF_STRING) { - prompt("Zero String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(ONST,DBF_STRING) { - prompt("One String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(TWST,DBF_STRING) { - prompt("Two String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(THST,DBF_STRING) { - prompt("Three String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(FRST,DBF_STRING) { - prompt("Four String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(FVST,DBF_STRING) { - prompt("Five String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(SXST,DBF_STRING) { - prompt("Six String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(SVST,DBF_STRING) { - prompt("Seven String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(EIST,DBF_STRING) { - prompt("Eight String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(NIST,DBF_STRING) { - prompt("Nine String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(TEST,DBF_STRING) { - prompt("Ten String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(ELST,DBF_STRING) { - prompt("Eleven String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(TVST,DBF_STRING) { - prompt("Twelve String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(TTST,DBF_STRING) { - prompt("Thirteen String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(FTST,DBF_STRING) { - prompt("Fourteen String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(FFST,DBF_STRING) { - prompt("Fifteen String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(ZRSV,DBF_MENU) { - prompt("State Zero Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(ONSV,DBF_MENU) { - prompt("State One Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(TWSV,DBF_MENU) { - prompt("State Two Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(THSV,DBF_MENU) { - prompt("State Three Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(FRSV,DBF_MENU) { - prompt("State Four Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(FVSV,DBF_MENU) { - prompt("State Five Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(SXSV,DBF_MENU) { - prompt("State Six Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(SVSV,DBF_MENU) { - prompt("State Seven Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(EISV,DBF_MENU) { - prompt("State Eight Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(NISV,DBF_MENU) { - prompt("State Nine Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(TESV,DBF_MENU) { - prompt("State Ten Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(ELSV,DBF_MENU) { - prompt("State Eleven Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(TVSV,DBF_MENU) { - prompt("State Twelve Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(TTSV,DBF_MENU) { - prompt("State Thirteen Sevr") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(FTSV,DBF_MENU) { - prompt("State Fourteen Sevr") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(FFSV,DBF_MENU) { - prompt("State Fifteen Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(AFTC, DBF_DOUBLE) { - prompt("Alarm Filter Time Constant") - promptgroup("70 - Alarm") - interest(1) - } - field(AFVL, DBF_DOUBLE) { - prompt("Alarm Filter Value") - special(SPC_NOMOD) - interest(3) - } - field(UNSV,DBF_MENU) { - prompt("Unknown State Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(COSV,DBF_MENU) { - prompt("Change of State Svr") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(RVAL,DBF_ULONG) { - prompt("Raw Value") - pp(TRUE) - } - field(ORAW,DBF_ULONG) { - prompt("Prev Raw Value") - special(SPC_NOMOD) - interest(3) - } - field(MASK,DBF_ULONG) { - prompt("Hardware Mask") - special(SPC_NOMOD) - interest(1) - } - field(MLST,DBF_USHORT) { - prompt("Last Value Monitored") - special(SPC_NOMOD) - interest(3) - } - field(LALM,DBF_USHORT) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(SDEF,DBF_SHORT) { - prompt("States Defined") - special(SPC_NOMOD) - interest(3) - } - field(SHFT,DBF_USHORT) { - prompt("Shift") - promptgroup("40 - Input") - interest(1) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_ULONG) { - prompt("Simulation Value") - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuSimm) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } -} diff --git a/src/std/rec/mbboDirectRecord.c b/src/std/rec/mbboDirectRecord.c deleted file mode 100644 index 0a6e3391e..000000000 --- a/src/std/rec/mbboDirectRecord.c +++ /dev/null @@ -1,360 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* mbboDirectRecord.c - Record Support for mbboDirect records */ -/* - * Original Author: Bob Dalesio - * Date: 10-06-93 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#include "menuOmsl.h" -#include "menuIvoa.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "mbboDirectRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset mbboDirectRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, mbboDirectRSET); - -struct mbbodset { /* multi bit binary output dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (0, 2)=>(success, success no convert)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_mbbo; /*returns: (0, 2)=>(success, success no convert)*/ -}; - - -static void convert(mbboDirectRecord *); -static void monitor(mbboDirectRecord *); -static long writeValue(mbboDirectRecord *); - -#define NUM_BITS 16 - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct mbboDirectRecord *prec = (struct mbboDirectRecord *)pcommon; - struct mbbodset *pdset = (struct mbbodset *) prec->dset; - long status = 0; - - if (pass == 0) - return 0; - - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "mbboDirect: init_record"); - return S_dev_noDSET; - } - - if ((pdset->number < 5) || (pdset->write_mbbo == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "mbboDirect: init_record"); - return S_dev_missingSup; - } - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - if (recGblInitConstantLink(&prec->dol, DBF_USHORT, &prec->val)) - prec->udf = FALSE; - - /* Initialize MASK if the user set NOBT instead */ - if (prec->mask == 0 && prec->nobt <= 32) - prec->mask = ((epicsUInt64) 1u << prec->nobt) - 1; - - if (pdset->init_record) { - status = pdset->init_record(prec); - if (status == 0) { - /* Convert initial read-back */ - epicsUInt32 rval = prec->rval; - - if (prec->shft > 0) - rval >>= prec->shft; - - prec->val = rval; - prec->udf = FALSE; - } - else if (status == 2) - status = 0; - } - - if (!prec->udf && - prec->omsl == menuOmslsupervisory) { - /* Set initial B0 - BF from VAL */ - epicsUInt16 val = prec->val; - epicsUInt8 *pBn = &prec->b0; - int i; - - for (i = 0; i < NUM_BITS; i++) { - *pBn++ = !! (val & 1); - val >>= 1; - } - } - - prec->mlst = prec->val; - prec->oraw = prec->rval; - prec->orbv = prec->rbv; - return status; -} - -static long process(struct dbCommon *pcommon) -{ - struct mbboDirectRecord *prec = (struct mbboDirectRecord *)pcommon; - struct mbbodset *pdset = (struct mbbodset *)(prec->dset); - long status = 0; - int pact = prec->pact; - - if ((pdset == NULL) || (pdset->write_mbbo == NULL)) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "write_mbbo"); - return S_dev_missingSup; - } - - if (!pact) { - if (!dbLinkIsConstant(&prec->dol) && - prec->omsl == menuOmslclosed_loop) { - epicsUInt16 val; - - if (dbGetLink(&prec->dol, DBR_USHORT, &val, 0, 0)) { - recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM); - goto CONTINUE; - } - prec->val = val; - } - else if (prec->omsl == menuOmslsupervisory) { - epicsUInt8 *pBn = &prec->b0; - epicsUInt16 val = 0; - epicsUInt16 bit = 1; - int i; - - /* Construct VAL from B0 - BF */ - for (i = 0; i < NUM_BITS; i++, bit <<= 1) - if (*pBn++) - val |= bit; - prec->val = val; - } - else if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - goto CONTINUE; - } - - prec->udf = FALSE; - /* Convert VAL to RVAL */ - convert(prec); - } - -CONTINUE: - if (prec->nsev < INVALID_ALARM) - status = writeValue(prec); - else { - switch (prec->ivoa) { - case menuIvoaSet_output_to_IVOV: - if (!prec->pact) { - prec->val = prec->ivov; - convert(prec); - } - /* No break, fall through... */ - case menuIvoaContinue_normally: - status = writeValue(prec); - break; - case menuIvoaDon_t_drive_outputs: - break; - default: - status = -1; - recGblRecordError(S_db_badField, prec, - "mbboDirect: process Illegal IVOA field"); - } - } - - /* Done if device support set PACT */ - if (!pact && prec->pact) - return 0; - - prec->pact = TRUE; - recGblGetTimeStamp(prec); - monitor(prec); - - /* Wrap up */ - recGblFwdLink(prec); - prec->pact = FALSE; - return status; -} - -static long special(DBADDR *paddr, int after) -{ - mbboDirectRecord *prec = (mbboDirectRecord *) paddr->precord; - - if (!after) - return 0; - - switch (paddr->special) { - case SPC_MOD: /* Bn field modified */ - if (prec->omsl == menuOmslsupervisory) { - /* Adjust VAL corresponding to the bit changed */ - epicsUInt8 *pBn = (epicsUInt8 *) paddr->pfield; - int bit = 1 << (pBn - &prec->b0); - - if (*pBn) - prec->val |= bit; - else - prec->val &= ~bit; - - prec->udf = FALSE; - convert(prec); - } - break; - - case SPC_RESET: /* OMSL field modified */ - if (prec->omsl == menuOmslclosed_loop) { - /* Construct VAL from B0 - BF */ - epicsUInt8 *pBn = &prec->b0; - epicsUInt16 val = 0, bit = 1; - int i; - - for (i = 0; i < NUM_BITS; i++, bit <<= 1) - if (*pBn++) - val |= bit; - prec->val = val; - } - else if (prec->omsl == menuOmslsupervisory) { - /* Set B0 - BF from VAL and post monitors */ - epicsUInt16 val = prec->val; - epicsUInt8 *pBn = &prec->b0; - int i; - - for (i = 0; i < NUM_BITS; i++, pBn++, val >>= 1) { - epicsUInt8 oBn = *pBn; - - *pBn = !! (val & 1); - if (oBn != *pBn) - db_post_events(prec, pBn, DBE_VALUE | DBE_LOG); - } - } - break; - - default: - recGblDbaddrError(S_db_badChoice, paddr, "mbboDirect: special"); - return S_db_badChoice; - } - - prec->udf = FALSE; - return 0; -} - -static void monitor(mbboDirectRecord *prec) -{ - epicsUInt16 events = recGblResetAlarms(prec); - - if (prec->mlst != prec->val) { - events |= DBE_VALUE | DBE_LOG; - prec->mlst = prec->val; - } - if (events) - db_post_events(prec, &prec->val, events); - - events |= DBE_VALUE | DBE_LOG; - if (prec->oraw != prec->rval) { - db_post_events(prec, &prec->rval, events); - prec->oraw = prec->rval; - } - if (prec->orbv != prec->rbv) { - db_post_events(prec, &prec->rbv, events); - prec->orbv = prec->rbv; - } -} - -static void convert(mbboDirectRecord *prec) -{ - /* Convert VAL to RVAL */ - prec->rval = prec->val; - - if (prec->shft > 0) - prec->rval <<= prec->shft; -} - -static long writeValue(mbboDirectRecord *prec) -{ - long status; - struct mbbodset *pdset = (struct mbbodset *) prec->dset; - - if (prec->pact) - return pdset->write_mbbo(prec); - - status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0); - if (status) - return status; - - switch (prec->simm) { - case menuYesNoNO: - return pdset->write_mbbo(prec); - - case menuYesNoYES: - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - return dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1); - - default: - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return -1; - } -} diff --git a/src/std/rec/mbboDirectRecord.dbd b/src/std/rec/mbboDirectRecord.dbd deleted file mode 100644 index 0b4285e32..000000000 --- a/src/std/rec/mbboDirectRecord.dbd +++ /dev/null @@ -1,219 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(mbboDirect) { - include "dbCommon.dbd" - field(VAL,DBF_USHORT) { - prompt("Word") - promptgroup("50 - Output") - asl(ASL0) - pp(TRUE) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - special(SPC_RESET) - pp(TRUE) - interest(1) - menu(menuOmsl) - } - field(NOBT,DBF_SHORT) { - prompt("Number of Bits") - promptgroup("50 - Output") - special(SPC_NOMOD) - interest(1) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup("40 - Input") - interest(1) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(B0,DBF_UCHAR) { - prompt("Bit 0") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B1,DBF_UCHAR) { - prompt("Bit 1") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B2,DBF_UCHAR) { - prompt("Bit 2") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B3,DBF_UCHAR) { - prompt("Bit 3") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B4,DBF_UCHAR) { - prompt("Bit 4") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B5,DBF_UCHAR) { - prompt("Bit 5") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B6,DBF_UCHAR) { - prompt("Bit 6") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B7,DBF_UCHAR) { - prompt("Bit 7") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B8,DBF_UCHAR) { - prompt("Bit 8") - promptgroup("52 - Output 9-F") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(B9,DBF_UCHAR) { - prompt("Bit 9") - promptgroup("52 - Output 9-F") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(BA,DBF_UCHAR) { - prompt("Bit 10") - promptgroup("52 - Output 9-F") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(BB,DBF_UCHAR) { - prompt("Bit 11") - promptgroup("52 - Output 9-F") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(BC,DBF_UCHAR) { - prompt("Bit 12") - promptgroup("52 - Output 9-F") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(BD,DBF_UCHAR) { - prompt("Bit 13") - promptgroup("52 - Output 9-F") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(BE,DBF_UCHAR) { - prompt("Bit 14") - promptgroup("52 - Output 9-F") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(BF,DBF_UCHAR) { - prompt("Bit 15") - promptgroup("52 - Output 9-F") - special(SPC_MOD) - pp(TRUE) - interest(1) - } - field(RVAL,DBF_ULONG) { - prompt("Raw Value") - special(SPC_NOMOD) - pp(TRUE) - } - field(ORAW,DBF_ULONG) { - prompt("Prev Raw Value") - special(SPC_NOMOD) - interest(3) - } - field(RBV,DBF_ULONG) { - prompt("Readback Value") - special(SPC_NOMOD) - } - field(ORBV,DBF_ULONG) { - prompt("Prev Readback Value") - special(SPC_NOMOD) - interest(3) - } - field(MASK,DBF_ULONG) { - prompt("Hardware Mask") - special(SPC_NOMOD) - interest(1) - } - field(MLST,DBF_ULONG) { - prompt("Last Value Monitored") - special(SPC_NOMOD) - interest(3) - } - field(SHFT,DBF_ULONG) { - prompt("Shift") - promptgroup("50 - Output") - interest(1) - } - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(IVOA,DBF_MENU) { - prompt("INVALID outpt action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_USHORT) { - prompt("INVALID output value") - promptgroup("50 - Output") - interest(2) - } -} diff --git a/src/std/rec/mbboRecord.c b/src/std/rec/mbboRecord.c deleted file mode 100644 index 0ae6a815a..000000000 --- a/src/std/rec/mbboRecord.c +++ /dev/null @@ -1,452 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie. -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* mbboRecord.c - Record Support Routines for multi bit binary Output records */ -/* - * Original Author: Bob Dalesio - * Date: 7-17-87 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#include "menuOmsl.h" -#include "menuIvoa.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "mbboRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -static long get_enum_str(const DBADDR *, char *); -static long get_enum_strs(const DBADDR *, struct dbr_enumStrs *); -static long put_enum_str(const DBADDR *, const char *); -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset mbboRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,mbboRSET); - -struct mbbodset { /* multi bit binary output dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (0, 2) => (success, success no convert)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_mbbo; /*returns: (0, 2) => (success, success no convert)*/ -}; - - -static void checkAlarms(mbboRecord *); -static void convert(mbboRecord *); -static void monitor(mbboRecord *); -static long writeValue(mbboRecord *); - - -static void init_common(mbboRecord *prec) -{ - epicsUInt32 *pstate_values = &prec->zrvl; - char *pstate_string = prec->zrst; - int i; - - /* Check if any states are defined */ - for (i = 0; i < 16; i++, pstate_string += sizeof(prec->zrst)) { - if ((pstate_values[i] != 0) || (*pstate_string != '\0')) { - prec->sdef = TRUE; - return; - } - } - prec->sdef = FALSE; -} - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct mbboRecord *prec = (struct mbboRecord *)pcommon; - struct mbbodset *pdset; - long status; - - if (pass == 0) { - init_common(prec); - return 0; - } - - pdset = (struct mbbodset *) prec->dset; - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "mbbo: init_record"); - return S_dev_noDSET; - } - - if ((pdset->number < 5) || (pdset->write_mbbo == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "mbbo: init_record"); - return S_dev_missingSup; - } - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - if (recGblInitConstantLink(&prec->dol, DBF_USHORT, &prec->val)) - prec->udf = FALSE; - - /* Initialize MASK if the user set NOBT instead */ - if (prec->mask == 0 && prec->nobt <= 32) - prec->mask = ((epicsUInt64) 1u << prec->nobt) - 1; - - if (pdset->init_record) { - status = pdset->init_record(prec); - init_common(prec); - if (status == 0) { - /* Convert initial read-back */ - epicsUInt32 rval = prec->rval; - - if (prec->shft > 0) - rval >>= prec->shft; - - if (prec->sdef) { - epicsUInt32 *pstate_values = &prec->zrvl; - int i; - - prec->val = 65535; /* initalize to unknown state */ - for (i = 0; i < 16; i++) { - if (*pstate_values == rval) { - prec->val = i; - break; - } - pstate_values++; - } - } - else { - /* No defined states, punt */ - prec->val = rval; - } - prec->udf = FALSE; - } - else if (status == 2) - status = 0; - } - else { - init_common(prec); - status = 0; - } - /* Convert VAL to RVAL */ - convert(prec); - - prec->mlst = prec->val; - prec->lalm = prec->val; - prec->oraw = prec->rval; - prec->orbv = prec->rbv; - return status; -} - -static long process(struct dbCommon *pcommon) -{ - struct mbboRecord *prec = (struct mbboRecord *)pcommon; - struct mbbodset *pdset = (struct mbbodset *) prec->dset; - long status = 0; - int pact = prec->pact; - - if ((pdset == NULL) || (pdset->write_mbbo == NULL)) { - prec->pact = TRUE; - recGblRecordError(S_dev_missingSup, prec, "write_mbbo"); - return S_dev_missingSup; - } - - if (!pact) { - if (!dbLinkIsConstant(&prec->dol) && - prec->omsl == menuOmslclosed_loop) { - epicsUInt16 val; - - if (dbGetLink(&prec->dol, DBR_USHORT, &val, 0, 0)) { - recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM); - goto CONTINUE; - } - prec->val = val; - } - else if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - goto CONTINUE; - } - - prec->udf = FALSE; - /* Convert VAL to RVAL */ - convert(prec); - } - -CONTINUE: - /* Check for alarms */ - checkAlarms(prec); - - if (prec->nsev < INVALID_ALARM) - status = writeValue(prec); - else { - switch (prec->ivoa) { - case menuIvoaSet_output_to_IVOV: - if (!prec->pact) { - prec->val = prec->ivov; - convert(prec); - } - /* No break, fall through... */ - case menuIvoaContinue_normally: - status = writeValue(prec); - break; - case menuIvoaDon_t_drive_outputs: - break; - default : - status = -1; - recGblRecordError(S_db_badField, prec, - "mbbo::process Illegal IVOA field"); - } - } - - /* Done if device support set pact */ - if (!pact && prec->pact) - return 0; - - prec->pact = TRUE; - recGblGetTimeStamp(prec); - monitor(prec); - - /* Wrap up */ - recGblFwdLink(prec); - prec->pact = FALSE; - return status; -} - -static long special(DBADDR *paddr, int after) -{ - mbboRecord *prec = (mbboRecord *) paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (!after) - return 0; - - switch (paddr->special) { - case SPC_MOD: - init_common(prec); - if (fieldIndex >= mbboRecordZRST && fieldIndex <= mbboRecordFFST) { - int event = DBE_PROPERTY; - - if (prec->val == fieldIndex - mbboRecordZRST) - event |= DBE_VALUE | DBE_LOG; - db_post_events(prec, &prec->val, event); - } - return 0; - default: - recGblDbaddrError(S_db_badChoice, paddr, "mbbo: special"); - return S_db_badChoice; - } -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - mbboRecord *prec = (mbboRecord *) paddr->precord; - - if (dbGetFieldIndex(paddr) != mbboRecordVAL) { - recGblDbaddrError(S_db_badField, paddr, "mbbo: cvt_dbaddr"); - return 0; - } - if (!prec->sdef) { - paddr->field_type = DBF_USHORT; - paddr->dbr_field_type = DBF_USHORT; - } - return 0; -} - -static long get_enum_str(const DBADDR *paddr, char *pstring) -{ - mbboRecord *prec = (mbboRecord *) paddr->precord; - epicsEnum16 *pfield = paddr->pfield; - epicsEnum16 val = *pfield; - - if (dbGetFieldIndex(paddr) != mbboRecordVAL) { - strcpy(pstring, "Bad Field"); - } - else if (val <= 15) { - const char *pstate = prec->zrst + val * sizeof(prec->zrst); - - strncpy(pstring, pstate, sizeof(prec->zrst)); - } - else { - strcpy(pstring, "Illegal Value"); - } - return 0; -} - -static long get_enum_strs(const DBADDR *paddr, struct dbr_enumStrs *pes) -{ - mbboRecord *prec = (mbboRecord *) paddr->precord; - const char *pstate; - int i, states = 0; - - memset(pes->strs, '\0', sizeof(pes->strs)); - pstate = prec->zrst; - for (i = 0; i < 16; i++) { - strncpy(pes->strs[i], pstate, sizeof(prec->zrst)); - if (*pstate) - states = i + 1; - pstate += sizeof(prec->zrst); - } - pes->no_str = states; - - return 0; -} - -static long put_enum_str(const DBADDR *paddr, const char *pstring) -{ - mbboRecord *prec = (mbboRecord *) paddr->precord; - const char *pstate; - int i; - - if (prec->sdef) { - pstate = prec->zrst; - for (i = 0; i < 16; i++) { - if (strncmp(pstate, pstring, sizeof(prec->zrst)) == 0) { - prec->val = i; - return 0; - } - pstate += sizeof(prec->zrst); - } - } - return S_db_badChoice; -} - -static void checkAlarms(mbboRecord *prec) -{ - epicsEnum16 val = prec->val; - - /* Check for STATE alarm */ - if (val > 15) { - /* Unknown state */ - recGblSetSevr(prec, STATE_ALARM, prec->unsv); - } - else { - /* State has a severity field */ - epicsEnum16 *severities = &prec->zrsv; - recGblSetSevr(prec, STATE_ALARM, severities[prec->val]); - } - - /* Check for COS alarm */ - if (val == prec->lalm || - recGblSetSevr(prec, COS_ALARM, prec->cosv)) - return; - - prec->lalm = val; -} - -static void monitor(mbboRecord *prec) -{ - epicsUInt16 events = recGblResetAlarms(prec); - - if (prec->mlst != prec->val) { - events |= DBE_VALUE | DBE_LOG; - prec->mlst = prec->val; - } - if (events) - db_post_events(prec, &prec->val, events); - - events |= DBE_VALUE | DBE_LOG; - if (prec->oraw != prec->rval) { - db_post_events(prec, &prec->rval, events); - prec->oraw = prec->rval; - } - if (prec->orbv != prec->rbv) { - db_post_events(prec, &prec->rbv, events); - prec->orbv = prec->rbv; - } -} - -static void convert(mbboRecord *prec) -{ - /* Convert VAL to RVAL */ - if (prec->sdef) { - epicsUInt32 *pvalues = &prec->zrvl; - - if (prec->val > 15) { - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return; - } - prec->rval = pvalues[prec->val]; - } - else - prec->rval = prec->val; - - if (prec->shft > 0) - prec->rval <<= prec->shft; -} - -static long writeValue(mbboRecord *prec) -{ - long status; - struct mbbodset *pdset = (struct mbbodset *) prec->dset; - - if (prec->pact) - return pdset->write_mbbo(prec); - - status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0); - if (status) - return status; - - switch (prec->simm) { - case menuYesNoNO: - return pdset->write_mbbo(prec); - - case menuYesNoYES: - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - return dbPutLink(&prec->siol, DBR_USHORT, &prec->val, 1); - - default: - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return -1; - } -} diff --git a/src/std/rec/mbboRecord.dbd b/src/std/rec/mbboRecord.dbd deleted file mode 100644 index f841ba018..000000000 --- a/src/std/rec/mbboRecord.dbd +++ /dev/null @@ -1,499 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(mbbo) { - include "dbCommon.dbd" - field(VAL,DBF_ENUM) { - prompt("Desired Value") - promptgroup("50 - Output") - special(SPC_DBADDR) - asl(ASL0) - pp(TRUE) - #=read Yes - #=write Yes - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup("40 - Input") - interest(1) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - interest(1) - menu(menuOmsl) - } - field(NOBT,DBF_USHORT) { - prompt("Number of Bits") - promptgroup("50 - Output") - special(SPC_NOMOD) - interest(1) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(ZRVL,DBF_ULONG) { - prompt("Zero Value") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(ONVL,DBF_ULONG) { - prompt("One Value") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(TWVL,DBF_ULONG) { - prompt("Two Value") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(THVL,DBF_ULONG) { - prompt("Three Value") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(FRVL,DBF_ULONG) { - prompt("Four Value") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(FVVL,DBF_ULONG) { - prompt("Five Value") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(SXVL,DBF_ULONG) { - prompt("Six Value") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(SVVL,DBF_ULONG) { - prompt("Seven Value") - promptgroup("51 - Output 0-7") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(EIVL,DBF_ULONG) { - prompt("Eight Value") - promptgroup("52 - Output 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(NIVL,DBF_ULONG) { - prompt("Nine Value") - promptgroup("52 - Output 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(TEVL,DBF_ULONG) { - prompt("Ten Value") - promptgroup("52 - Output 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(ELVL,DBF_ULONG) { - prompt("Eleven Value") - promptgroup("52 - Output 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(TVVL,DBF_ULONG) { - prompt("Twelve Value") - promptgroup("52 - Output 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(TTVL,DBF_ULONG) { - prompt("Thirteen Value") - promptgroup("52 - Output 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(FTVL,DBF_ULONG) { - prompt("Fourteen Value") - promptgroup("52 - Output 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(FFVL,DBF_ULONG) { - prompt("Fifteen Value") - promptgroup("52 - Output 8-15") - special(SPC_MOD) - pp(TRUE) - base(HEX) - interest(1) - } - field(ZRST,DBF_STRING) { - prompt("Zero String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(ONST,DBF_STRING) { - prompt("One String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(TWST,DBF_STRING) { - prompt("Two String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(THST,DBF_STRING) { - prompt("Three String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(FRST,DBF_STRING) { - prompt("Four String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(FVST,DBF_STRING) { - prompt("Five String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(SXST,DBF_STRING) { - prompt("Six String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(SVST,DBF_STRING) { - prompt("Seven String") - promptgroup("81 - Display 0-7") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(EIST,DBF_STRING) { - prompt("Eight String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(NIST,DBF_STRING) { - prompt("Nine String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(TEST,DBF_STRING) { - prompt("Ten String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(ELST,DBF_STRING) { - prompt("Eleven String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(TVST,DBF_STRING) { - prompt("Twelve String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(TTST,DBF_STRING) { - prompt("Thirteen String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(FTST,DBF_STRING) { - prompt("Fourteen String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(FFST,DBF_STRING) { - prompt("Fifteen String") - promptgroup("82 - Display 8-15") - special(SPC_MOD) - pp(TRUE) - interest(1) - size(26) - } - field(ZRSV,DBF_MENU) { - prompt("State Zero Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(ONSV,DBF_MENU) { - prompt("State One Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(TWSV,DBF_MENU) { - prompt("State Two Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(THSV,DBF_MENU) { - prompt("State Three Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(FRSV,DBF_MENU) { - prompt("State Four Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(FVSV,DBF_MENU) { - prompt("State Five Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(SXSV,DBF_MENU) { - prompt("State Six Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(SVSV,DBF_MENU) { - prompt("State Seven Severity") - promptgroup("71 - Alarm 0-7") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(EISV,DBF_MENU) { - prompt("State Eight Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(NISV,DBF_MENU) { - prompt("State Nine Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(TESV,DBF_MENU) { - prompt("State Ten Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(ELSV,DBF_MENU) { - prompt("State Eleven Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(TVSV,DBF_MENU) { - prompt("State Twelve Severity") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(TTSV,DBF_MENU) { - prompt("State Thirteen Sevr") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(FTSV,DBF_MENU) { - prompt("State Fourteen Sevr") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(FFSV,DBF_MENU) { - prompt("State Fifteen Sevr") - promptgroup("72 - Alarm 8-15") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(UNSV,DBF_MENU) { - prompt("Unknown State Sevr") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(COSV,DBF_MENU) { - prompt("Change of State Sevr") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(RVAL,DBF_ULONG) { - prompt("Raw Value") - pp(TRUE) - } - field(ORAW,DBF_ULONG) { - prompt("Prev Raw Value") - special(SPC_NOMOD) - interest(3) - } - field(RBV,DBF_ULONG) { - prompt("Readback Value") - special(SPC_NOMOD) - } - field(ORBV,DBF_ULONG) { - prompt("Prev Readback Value") - special(SPC_NOMOD) - interest(3) - } - field(MASK,DBF_ULONG) { - prompt("Hardware Mask") - special(SPC_NOMOD) - interest(1) - } - field(MLST,DBF_USHORT) { - prompt("Last Value Monitored") - special(SPC_NOMOD) - interest(3) - } - field(LALM,DBF_USHORT) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(SDEF,DBF_SHORT) { - prompt("States Defined") - special(SPC_NOMOD) - interest(3) - } - field(SHFT,DBF_USHORT) { - prompt("Shift") - promptgroup("50 - Output") - interest(1) - } - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(IVOA,DBF_MENU) { - prompt("INVALID outpt action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_USHORT) { - prompt("INVALID output value") - promptgroup("50 - Output") - interest(2) - } -} diff --git a/src/std/rec/permissiveRecord.c b/src/std/rec/permissiveRecord.c deleted file mode 100644 index e553931bc..000000000 --- a/src/std/rec/permissiveRecord.c +++ /dev/null @@ -1,115 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recPermissive.c - Record Support Routines for Permissive records */ -/* - * Original Author: Bob Dalesio - * Date: 10-10-90 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" - -#define GEN_SIZE_OFFSET -#include "permissiveRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -#define init_record NULL -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset permissiveRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,permissiveRSET); - -static void monitor(permissiveRecord *); - -static long process(struct dbCommon *pcommon) -{ - struct permissiveRecord *prec = (struct permissiveRecord *)pcommon; - - prec->pact=TRUE; - prec->udf=FALSE; - recGblGetTimeStamp(prec); - monitor(prec); - recGblFwdLink(prec); - prec->pact=FALSE; - return(0); -} - -static void monitor(permissiveRecord *prec) -{ - unsigned short monitor_mask; - unsigned short val,oval,wflg,oflg; - - monitor_mask = recGblResetAlarms(prec); - /* get val,oval,wflg,oflg*/ - val=prec->val; - oval=prec->oval; - wflg=prec->wflg; - oflg=prec->oflg; - /*set oval and oflg*/ - prec->oval = val; - prec->oflg = wflg; - if(oval != val) { - db_post_events(prec,&prec->val, - monitor_mask|DBE_VALUE|DBE_LOG); - } - if(oflg != wflg) { - db_post_events(prec,&prec->wflg, - monitor_mask|DBE_VALUE|DBE_LOG); - } - return; -} diff --git a/src/std/rec/permissiveRecord.dbd b/src/std/rec/permissiveRecord.dbd deleted file mode 100644 index 7eb04bf95..000000000 --- a/src/std/rec/permissiveRecord.dbd +++ /dev/null @@ -1,38 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(permissive) { - include "dbCommon.dbd" - field(LABL,DBF_STRING) { - prompt("Button Label") - promptgroup("80 - Display") - pp(TRUE) - interest(1) - size(20) - } - field(VAL,DBF_USHORT) { - prompt("Status") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(OVAL,DBF_USHORT) { - prompt("Old Status") - special(SPC_NOMOD) - interest(3) - } - field(WFLG,DBF_USHORT) { - prompt("Wait Flag") - pp(TRUE) - } - field(OFLG,DBF_USHORT) { - prompt("Old Flag") - special(SPC_NOMOD) - interest(3) - } -} diff --git a/src/std/rec/printfRecord.c b/src/std/rec/printfRecord.c deleted file mode 100644 index 7011453d4..000000000 --- a/src/std/rec/printfRecord.c +++ /dev/null @@ -1,448 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Printf record type */ -/* - * Author: Andrew Johnson - * Date: 2012-09-18 - */ - -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "alarm.h" -#include "cantProceed.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "epicsMath.h" -#include "epicsStdio.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#define GEN_SIZE_OFFSET -#include "printfRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - - -/* Flag bits */ -#define F_CHAR 1 -#define F_SHORT 2 -#define F_LONG 4 -#define F_LEFT 8 -#define F_BADFMT 0x10 -#define F_BADLNK 0x20 -#define F_BAD (F_BADFMT | F_BADLNK) - -#define GET_PRINT(VALTYPE, DBRTYPE) \ - VALTYPE val; \ - int ok; \ -\ - if (dbLinkIsConstant(plink)) \ - ok = recGblInitConstantLink(plink++, DBRTYPE, &val); \ - else \ - ok = ! dbGetLink(plink++, DBRTYPE, &val, 0, 0); \ - if (ok) \ - added = epicsSnprintf(pval, vspace + 1, format, val); \ - else \ - flags |= F_BADLNK - -static void doPrintf(printfRecord *prec) -{ - const char *pfmt = prec->fmt; - DBLINK *plink = &prec->inp0; - int linkn = 0; - char *pval = prec->val; - int vspace = prec->sizv - 1; - int ch; - - while (vspace > 0 && (ch = *pfmt++)) { - if (ch != '%') { - /* Copy literal strings directly into prec->val */ - *pval++ = ch; - --vspace; - } - else { - char format[20]; - char *pformat = format; - int width = 0; - int precision = 0; - int *pnum = &width; - int flags = 0; - int added = 0; - int cont = 1; - - /* The format directive parsing here is not comprehensive, - * in most cases we just copy each directive into format[] - * and get epicsSnprintf() do all the work. We do replace - * all variable-length field width or precision '*' chars - * with an integer read from the next input link, and we - * also convert %ls (long string) directives ourself, so - * we need to know the width, precision and justification. - */ - - *pformat++ = ch; /* '%' */ - while (cont && (ch = *pfmt++)) { - *pformat++ = ch; - switch (ch) { - case '+': case ' ': case '#': - break; - case '-': - flags |= F_LEFT; - break; - case '.': - pnum = &precision; - break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - *pnum = *pnum * 10 + ch - '0'; - break; - case '*': - if (*pnum) { - flags |= F_BADFMT; - } - else if (linkn++ < PRINTF_NLINKS) { - epicsInt16 i; - int ok; - - if (dbLinkIsConstant(plink)) - ok = recGblInitConstantLink(plink++, DBR_SHORT, &i); - else - ok = ! dbGetLink(plink++, DBR_SHORT, &i, 0, 0); - if (ok) { - *pnum = i; - added = epicsSnprintf(--pformat, 6, "%d", i); - pformat += added; - } - else /* No more LNKn fields */ - flags |= F_BADLNK; - } - else - flags |= F_BADLNK; - break; - case 'h': - if (flags & F_SHORT) - flags = (flags & ~F_SHORT) | F_CHAR; - else - flags |= F_SHORT; - break; - case 'l': - flags |= F_LONG; - break; - default: - if (strchr("diouxXeEfFgGcs%", ch) == NULL) - flags |= F_BADFMT; - cont = 0; - break; - } - } - if (!ch) /* End of format string */ - break; - - if (flags & F_BAD) - goto bad_format; - - *pformat = 0; /* Terminate our format string */ - - if (width < 0) { - width = -width; - flags |= F_LEFT; - } - if (precision < 0) - precision = 0; - - if (ch == '%') { - added = epicsSnprintf(pval, vspace + 1, "%s", format); - } - else if (linkn++ >= PRINTF_NLINKS) { - /* No more LNKn fields */ - flags |= F_BADLNK; - } - else - switch (ch) { /* Conversion character */ - case 'c': case 'd': case 'i': - if (ch == 'c' || flags & F_CHAR) { - GET_PRINT(epicsInt8, DBR_CHAR); - } - else if (flags & F_SHORT) { - GET_PRINT(epicsInt16, DBR_SHORT); - } - else { /* F_LONG has no real effect */ - GET_PRINT(epicsInt32, DBR_LONG); - } - break; - - case 'o': case 'x': case 'X': case 'u': - if (flags & F_CHAR) { - GET_PRINT(epicsUInt8, DBR_UCHAR); - } - else if (flags & F_SHORT) { - GET_PRINT(epicsUInt16, DBR_USHORT); - } - else { /* F_LONG has no real effect */ - GET_PRINT(epicsUInt32, DBR_ULONG); - } - break; - - case 'e': case 'E': - case 'f': case 'F': - case 'g': case 'G': - if (flags & F_SHORT) { - GET_PRINT(epicsFloat32, DBR_FLOAT); - } - else { - GET_PRINT(epicsFloat64, DBR_DOUBLE); - } - break; - - case 's': - if (flags & F_LONG) { - long n = vspace + 1; - long status; - - if (precision && n > precision) - n = precision + 1; - /* If set, precision is the maximum number of - * characters to be printed from the string. - * It does not limit the field width however. - */ - if (dbLinkIsConstant(plink)) { - epicsUInt32 len = n; - status = dbLoadLinkLS(plink++, pval, n, &len); - n = len; - } - else - status = dbGetLink(plink++, DBR_CHAR, pval, 0, &n); - if (status) - flags |= F_BADLNK; - else { - int padding; - - /* Terminate string and measure its length */ - pval[n] = 0; - added = strlen(pval); - padding = width - added; - - if (padding > 0) { - if (flags & F_LEFT) { - /* add spaces on RHS */ - if (width > vspace) - padding = vspace - added; - memset(pval + added, ' ', padding); - } - else { - /* insert spaces on LHS */ - int trunc = width - vspace; - - if (trunc < added) { - added -= trunc; - memmove(pval + padding, pval, added); - } - else { - padding = vspace; - added = 0; - } - memset(pval, ' ', padding); - } - added += padding; - } - } - } - else { - char val[MAX_STRING_SIZE]; - int ok; - - if (dbLinkIsConstant(plink)) - ok = recGblInitConstantLink(plink++, DBR_STRING, val); - else - ok = ! dbGetLink(plink++, DBR_STRING, val, 0, 0); - if (ok) - added = epicsSnprintf(pval, vspace + 1, format, val); - else - flags |= F_BADLNK; - } - break; - - default: - errlogPrintf("printfRecord: Unexpected conversion '%s'\n", - format); - flags |= F_BADFMT; - break; - } - - if (flags & F_BAD) { - bad_format: - added = epicsSnprintf(pval, vspace + 1, "%s", - flags & F_BADLNK ? prec->ivls : format); - } - - if (added <= vspace) { - pval += added; - vspace -= added; - } - else { - /* Output was truncated */ - pval += vspace; - vspace = 0; - } - } - } - *pval++ = 0; /* Terminate the VAL string */ - prec->len = pval - prec->val; -} - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct printfRecord *prec = (struct printfRecord *)pcommon; - printfdset *pdset; - - if (pass == 0) { - size_t sizv = prec->sizv; - - if (sizv < 16) { - sizv = 16; /* Enforce a minimum size for the VAL field */ - prec->sizv = sizv; - } - - prec->val = callocMustSucceed(1, sizv, "printf::init_record"); - prec->len = 0; - return 0; - } - - pdset = (printfdset *) prec->dset; - if (!pdset) - return 0; /* Device support is optional */ - - if (pdset->number < 5) { - recGblRecordError(S_dev_missingSup, prec, "printf::init_record"); - return S_dev_missingSup; - } - - if (pdset->init_record) { - long status = pdset->init_record(prec); - if (status) - return status; - } - - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct printfRecord *prec = (struct printfRecord *)pcommon; - int pact = prec->pact; - printfdset *pdset; - long status = 0; - epicsUInt16 events; - - if (!pact) { - doPrintf(prec); - - prec->udf = FALSE; - recGblGetTimeStamp(prec); - } - - /* Call device support */ - pdset = (printfdset *) prec->dset; - if (pdset && - pdset->number >= 5 && - pdset->write_string) { - status = pdset->write_string(prec); - - /* Asynchronous if device support set pact */ - if (!pact && prec->pact) - return status; - } - - prec->pact = TRUE; - - /* Post monitor */ - events = recGblResetAlarms(prec); - db_post_events(prec, prec->val, events | DBE_VALUE | DBE_LOG); - db_post_events(prec, &prec->len, events | DBE_VALUE | DBE_LOG); - - /* Wrap up */ - recGblFwdLink(prec); - prec->pact = FALSE; - return status; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - printfRecord *prec = (printfRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if (fieldIndex == printfRecordVAL) { - paddr->pfield = prec->val; - paddr->no_elements = 1; - paddr->field_type = DBF_STRING; - paddr->dbr_field_type = DBF_STRING; - paddr->field_size = prec->sizv; - } - else - errlogPrintf("printfRecord::cvt_dbaddr called for %s.%s\n", - prec->name, paddr->pfldDes->name); - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - printfRecord *prec = (printfRecord *) paddr->precord; - - *no_elements = prec->len; - *offset = 0; - return 0; -} - - -/* Create Record Support Entry Table */ - -#define report NULL -#define initialize NULL -/* init_record */ -/* process */ -#define special NULL -#define get_value NULL -/* cvt_dbaddr */ -/* get_array_info */ -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset printfRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, printfRSET); - diff --git a/src/std/rec/printfRecord.dbd b/src/std/rec/printfRecord.dbd deleted file mode 100644 index 4fd63ef3c..000000000 --- a/src/std/rec/printfRecord.dbd +++ /dev/null @@ -1,109 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -recordtype(printf) { - include "dbCommon.dbd" - %#include "devSup.h" - % - %/* Declare Device Support Entry Table */ - %typedef struct printfdset { - % long number; - % DEVSUPFUN report; - % DEVSUPFUN init; - % DEVSUPFUN init_record; - % DEVSUPFUN get_ioint_info; - % DEVSUPFUN write_string; - %} printfdset; - % - field(VAL,DBF_NOACCESS) { - prompt("Result") - asl(ASL0) - pp(TRUE) - special(SPC_DBADDR) - extra("char *val") - } - field(SIZV,DBF_USHORT) { - prompt("Size of VAL buffer") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - initial("41") - } - field(LEN,DBF_ULONG) { - prompt("Length of VAL") - special(SPC_NOMOD) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(FMT,DBF_STRING) { - prompt("Format String") - promptgroup("30 - Action") - pp(TRUE) - size(81) - } - field(IVLS,DBF_STRING) { - prompt("Invalid Link String") - promptgroup("30 - Action") - size(16) - initial("LNK") - } - field(INP0,DBF_INLINK) { - prompt("Input 0") - promptgroup("40 - Input") - interest(1) - } - field(INP1,DBF_INLINK) { - prompt("Input 1") - promptgroup("40 - Input") - interest(1) - } - field(INP2,DBF_INLINK) { - prompt("Input 2") - promptgroup("40 - Input") - interest(1) - } - field(INP3,DBF_INLINK) { - prompt("Input 3") - promptgroup("40 - Input") - interest(1) - } - field(INP4,DBF_INLINK) { - prompt("Input 4") - promptgroup("40 - Input") - interest(1) - } - field(INP5,DBF_INLINK) { - prompt("Input 5") - promptgroup("40 - Input") - interest(1) - } - field(INP6,DBF_INLINK) { - prompt("Input 6") - promptgroup("40 - Input") - interest(1) - } - field(INP7,DBF_INLINK) { - prompt("Input 7") - promptgroup("40 - Input") - interest(1) - } - field(INP8,DBF_INLINK) { - prompt("Input 8") - promptgroup("40 - Input") - interest(1) - } - field(INP9,DBF_INLINK) { - prompt("Input 9") - promptgroup("40 - Input") - interest(1) - } - %/* Number of INPx fields defined */ - %#define PRINTF_NLINKS 10 -} diff --git a/src/std/rec/selRecord.c b/src/std/rec/selRecord.c deleted file mode 100644 index 56a995c8f..000000000 --- a/src/std/rec/selRecord.c +++ /dev/null @@ -1,437 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* selRecord.c - Record Support Routines for Select records */ -/* - * Original Author: Bob Dalesio - * Date: 6-2-89 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsMath.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" - -#define GEN_SIZE_OFFSET -#include "selRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset selRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,selRSET); - -#define SEL_MAX 12 - -static void checkAlarms(selRecord *); -static void do_sel(selRecord *); -static int fetch_values(selRecord *); -static void monitor(selRecord *); - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct selRecord *prec = (struct selRecord *)pcommon; - struct link *plink; - int i; - double *pvalue; - - if (pass==0) - return 0; - - /* get seln initial value if nvl is a constant*/ - recGblInitConstantLink(&prec->nvl, DBF_USHORT, &prec->seln); - - plink = &prec->inpa; - pvalue = &prec->a; - for (i=0; ipact = TRUE; - if ( RTN_SUCCESS(fetch_values(prec)) ) { - do_sel(prec); - } - - recGblGetTimeStamp(prec); - /* check for alarms */ - checkAlarms(prec); - - - /* check event list */ - monitor(prec); - - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(0); -} - - -#define indexof(field) selRecord##field - -static long get_units(DBADDR *paddr, char *units) -{ - selRecord *prec=(selRecord *)paddr->precord; - - if(paddr->pfldDes->field_type == DBF_DOUBLE) { - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return(0); -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - selRecord *prec=(selRecord *)paddr->precord; - double *pvalue,*plvalue; - int i; - - *precision = prec->prec; - if(paddr->pfield==(void *)&prec->val){ - return(0); - } - pvalue = &prec->a; - plvalue = &prec->la; - for(i=0; ipfield==(void *)&pvalue - || paddr->pfield==(void *)&plvalue){ - return(0); - } - } - recGblGetPrec(paddr,precision); - return(0); -} - - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - selRecord *prec=(selRecord *)paddr->precord; - int index = dbGetFieldIndex(paddr); - - switch (index) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): -#ifdef __GNUC__ - case indexof(A) ... indexof(L): - case indexof(LA) ... indexof(LL): - break; - default: -#else - break; - default: - if((index >= indexof(A) && index <= indexof(L)) - || (index >= indexof(LA) && index <= indexof(LL))) - break; -#endif - recGblGetGraphicDouble(paddr,pgd); - return(0); - } - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - return(0); -} - -static long get_control_double(struct dbAddr *paddr, struct dbr_ctrlDouble *pcd) -{ - selRecord *prec=(selRecord *)paddr->precord; - int index = dbGetFieldIndex(paddr); - - switch (index) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): -#ifdef __GNUC__ - case indexof(A) ... indexof(L): - case indexof(LA) ... indexof(LL): - break; - default: -#else - break; - default: - if((index >= indexof(A) && index <= indexof(L)) - || (index >= indexof(LA) && index <= indexof(LL))) - break; -#endif - recGblGetControlDouble(paddr,pcd); - return(0); - } - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - return(0); -} - -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - selRecord *prec=(selRecord *)paddr->precord; - - if(dbGetFieldIndex(paddr) == indexof(VAL)) { - pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN; - pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN; - pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN; - pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(selRecord *prec) -{ - double val, hyst, lalm; - double alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* alarm condition hihi */ - asev = prec->hhsv; - alev = prec->hihi; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIHI_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition lolo */ - asev = prec->llsv; - alev = prec->lolo; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOLO_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition high */ - asev = prec->hsv; - alev = prec->high; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIGH_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition low */ - asev = prec->lsv; - alev = prec->low; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOW_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* we get here only if val is out of alarm by at least hyst */ - prec->lalm = val; - return; -} - -static void monitor(selRecord *prec) -{ - unsigned monitor_mask; - double *pnew; - double *pprev; - int i; - - monitor_mask = recGblResetAlarms(prec); - - /* check for value change */ - recGblCheckDeadband(&prec->mlst, prec->val, prec->mdel, &monitor_mask, DBE_VALUE); - - /* check for archive change */ - recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask, DBE_ARCHIVE); - - /* send out monitors connected to the value field */ - if (monitor_mask) - db_post_events(prec, &prec->val, monitor_mask); - - monitor_mask |= DBE_VALUE|DBE_LOG; - - /* trigger monitors of the SELN field */ - if (prec->nlst != prec->seln) { - prec->nlst = prec->seln; - db_post_events(prec, &prec->seln, monitor_mask); - } - - /* check all input fields for changes, even if VAL hasn't changed */ - for(i=0, pnew=&prec->a, pprev=&prec->la; ia; - switch (prec->selm){ - case (selSELM_Specified): - if (prec->seln >= SEL_MAX) { - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return; - } - val = *(pvalue+prec->seln); - break; - case (selSELM_High_Signal): - val = -epicsINF; - for (i = 0; i < SEL_MAX; i++,pvalue++){ - if (!isnan(*pvalue) && val < *pvalue) { - val = *pvalue; - prec->seln = i; - } - } - break; - case (selSELM_Low_Signal): - val = epicsINF; - for (i = 0; i < SEL_MAX; i++,pvalue++){ - if (!isnan(*pvalue) && val > *pvalue) { - val = *pvalue; - prec->seln = i; - } - } - break; - case (selSELM_Median_Signal): - count = 0; - order[0] = epicsNAN; - for (i = 0; i < SEL_MAX; i++,pvalue++){ - if (!isnan(*pvalue)){ - /* Insertion sort */ - j = count; - while ((j > 0) && (order[j-1] > *pvalue)){ - order[j] = order[j-1]; - j--; - } - order[j] = *pvalue; - count++; - } - } - prec->seln = count; - val = order[count / 2]; - break; - default: - recGblSetSevr(prec,CALC_ALARM,INVALID_ALARM); - return; - } - prec->val = val; - prec->udf = isnan(prec->val); - return; -} - -/* - * FETCH_VALUES - * - * fetch the values for the variables from which to select - */ -static int fetch_values(selRecord *prec) -{ - struct link *plink; - double *pvalue; - int i; - long status; - - plink = &prec->inpa; - pvalue = &prec->a; - /* If mechanism is selSELM_Specified, only get the selected input*/ - if(prec->selm == selSELM_Specified) { - /* fetch the select index */ - status=dbGetLink(&(prec->nvl),DBR_USHORT,&(prec->seln),0,0); - if (!RTN_SUCCESS(status) || (prec->seln >= SEL_MAX)) - return(status); - - plink += prec->seln; - pvalue += prec->seln; - - status=dbGetLink(plink,DBR_DOUBLE, pvalue,0,0); - return(status); - } - /* fetch all inputs*/ - for(i=0; i -#include -#include - -#include "alarm.h" -#include "callback.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "epicsTypes.h" -#include "link.h" -#include "recSup.h" -#include "recGbl.h" - -#define GEN_SIZE_OFFSET -#include "seqRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -static void processNextLink(seqRecord *prec); -static long asyncFinish(seqRecord *prec); -static void processCallback(CALLBACK *arg); - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *prec, int pass); -static long process(struct dbCommon *prec); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *paddr, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset seqRSET = { - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, seqRSET); - -int seqDLYprecision = 2; -epicsExportAddress(int, seqDLYprecision); - -double seqDLYlimit = 100000; -epicsExportAddress(double, seqDLYlimit); - - -/* Total number of link-groups */ -#define NUM_LINKS 16 - -/* Each link-group looks like this */ -typedef struct linkGrp { - double dly; /* Delay in seconds */ - DBLINK dol; /* Input link */ - double dov; /* Value storage */ - DBLINK lnk; /* Output link */ -} linkGrp; - -/* The list of link-groups for processing */ -typedef struct seqRecPvt { - CALLBACK callback; - seqRecord *prec; - linkGrp *grps[NUM_LINKS + 1]; /* List of link-groups */ - int index; /* Where we are now */ -} seqRecPvt; - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct seqRecord *prec = (struct seqRecord *)pcommon; - int index; - linkGrp *grp; - seqRecPvt *pseqRecPvt; - - if (pass == 0) - return 0; - - pseqRecPvt = (seqRecPvt *)calloc(1, sizeof(seqRecPvt)); - pseqRecPvt->prec = prec; - callbackSetCallback(processCallback, &pseqRecPvt->callback); - callbackSetUser(pseqRecPvt, &pseqRecPvt->callback); - prec->dpvt = pseqRecPvt; - - recGblInitConstantLink(&prec->sell, DBF_USHORT, &prec->seln); - - grp = (linkGrp *) &prec->dly0; - for (index = 0; index < NUM_LINKS; index++, grp++) { - recGblInitConstantLink(&grp->dol, DBF_DOUBLE, &grp->dov); - } - - prec->oldn = prec->seln; - - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct seqRecord *prec = (struct seqRecord *)pcommon; - seqRecPvt *pcb = (seqRecPvt *) prec->dpvt; - linkGrp *pgrp; - epicsUInt16 lmask; - int i; - - if (prec->pact) - return asyncFinish(prec); - prec->pact = TRUE; - - /* Set callback from PRIO */ - callbackSetPriority(prec->prio, &pcb->callback); - - if (prec->selm == seqSELM_All) - lmask = (1 << NUM_LINKS) - 1; - else { - /* Get SELN value */ - dbGetLink(&prec->sell, DBR_USHORT, &prec->seln, 0, 0); - - if (prec->selm == seqSELM_Specified) { - int grpn = prec->seln + prec->offs; - if (grpn < 0 || grpn >= NUM_LINKS) { - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return asyncFinish(prec); - } - if (grpn == 0) - return asyncFinish(prec); - - lmask = 1 << grpn; - } - else if (prec->selm == seqSELM_Mask) { - int shft = prec->shft; - if (shft < -15 || shft > 15) { - /* Shifting by more than the number of bits in the - * value produces undefined behavior in C */ - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return asyncFinish(prec); - } - lmask = (shft >= 0) ? prec->seln >> shft : prec->seln << -shft; - } - else { - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return asyncFinish(prec); - } - } - - /* Figure out which groups are to be processed */ - pcb->index = 0; - pgrp = (linkGrp *) &prec->dly0; - for (i = 0; lmask; lmask >>= 1) { - if ((lmask & 1) && - (!dbLinkIsConstant(&pgrp->lnk) || - !dbLinkIsConstant(&pgrp->dol))) { - pcb->grps[i++] = pgrp; - } - pgrp++; - } - pcb->grps[i] = NULL; /* mark the end of the list */ - - if (!i) - return asyncFinish(prec); - - /* Start processing link groups (we have at least one) */ - processNextLink(prec); - - return 0; -} - -static void processNextLink(seqRecord *prec) -{ - seqRecPvt *pcb = (seqRecPvt *) prec->dpvt; - linkGrp *pgrp = pcb->grps[pcb->index]; - - if (pgrp == NULL) { - /* None left, finish up. */ - prec->rset->process((dbCommon *)prec); - return; - } - - /* Always use the callback task to avoid recursion */ - if (pgrp->dly > 0.0) - callbackRequestDelayed(&pcb->callback, pgrp->dly); - else - callbackRequest(&pcb->callback); -} - -static long asyncFinish(seqRecord *prec) -{ - epicsUInt16 events; - - prec->udf = FALSE; - recGblGetTimeStamp(prec); - - /* post monitors */ - events = recGblResetAlarms(prec); - if (events) - db_post_events(prec, &prec->val, events); - if (prec->seln != prec->oldn) { - db_post_events(prec, &prec->seln, events | DBE_VALUE | DBE_LOG); - prec->oldn = prec->seln; - } - - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact = FALSE; - return 0; -} - - -static void processCallback(CALLBACK *arg) -{ - seqRecPvt *pcb; - seqRecord *prec; - linkGrp *pgrp; - double odov; - - callbackGetUser(pcb, arg); - prec = pcb->prec; - dbScanLock((struct dbCommon *)prec); - - pgrp = pcb->grps[pcb->index]; - - /* Save the old value */ - odov = pgrp->dov; - - dbGetLink(&pgrp->dol, DBR_DOUBLE, &pgrp->dov, 0, 0); - - recGblGetTimeStamp(prec); - - /* Dump the value to the destination field */ - dbPutLink(&pgrp->lnk, DBR_DOUBLE, &pgrp->dov, 1); - - if (odov != pgrp->dov) { - db_post_events(prec, &pgrp->dov, DBE_VALUE | DBE_LOG); - } - - /* Start the next link-group */ - pcb->index++; - processNextLink(prec); - - dbScanUnlock((struct dbCommon *)prec); -} - - -#define indexof(field) seqRecord##field -#define get_dol(prec, fieldOffset) \ - &((linkGrp *) &prec->dly0)[fieldOffset >> 2].dol - -static long get_units(DBADDR *paddr, char *units) -{ - seqRecord *prec = (seqRecord *) paddr->precord; - int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1); - - if (fieldOffset >= 0) - switch (fieldOffset & 2) { - case 0: /* DLYn */ - strcpy(units, "s"); - break; - case 2: /* DOn */ - dbGetUnits(get_dol(prec, fieldOffset), - units, DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *pprecision) -{ - seqRecord *prec = (seqRecord *) paddr->precord; - int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1); - short precision; - - if (fieldOffset >= 0) - switch (fieldOffset & 2) { - case 0: /* DLYn */ - *pprecision = seqDLYprecision; - return 0; - case 2: /* DOn */ - if (dbGetPrecision(get_dol(prec, fieldOffset), &precision) == 0) { - *pprecision = precision; - return 0; - } - } - *pprecision = prec->prec; - recGblGetPrec(paddr, pprecision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - seqRecord *prec = (seqRecord *) paddr->precord; - int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1); - - if (fieldOffset >= 0) - switch (fieldOffset & 2) { - case 0: /* DLYn */ - pgd->lower_disp_limit = 0.0; - pgd->lower_disp_limit = 10.0; - return 0; - case 2: /* DOn */ - dbGetGraphicLimits(get_dol(prec, fieldOffset), - &pgd->lower_disp_limit, - &pgd->upper_disp_limit); - return 0; - } - recGblGetGraphicDouble(paddr, pgd); - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1); - - if (fieldOffset >= 0 && (fieldOffset & 2) == 0) { /* DLYn */ - pcd->lower_ctrl_limit = 0.0; - pcd->upper_ctrl_limit = seqDLYlimit; - } - else - recGblGetControlDouble(paddr, pcd); - return 0; -} - -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - seqRecord *prec = (seqRecord *) paddr->precord; - int fieldOffset = dbGetFieldIndex(paddr) - indexof(DLY1); - - if (fieldOffset >= 0 && (fieldOffset & 2) == 2) /* DOn */ - dbGetAlarmLimits(get_dol(prec, fieldOffset), - &pad->lower_alarm_limit, &pad->lower_warning_limit, - &pad->upper_warning_limit, &pad->upper_alarm_limit); - else - recGblGetAlarmDouble(paddr, pad); - return 0; -} diff --git a/src/std/rec/seqRecord.dbd b/src/std/rec/seqRecord.dbd deleted file mode 100644 index 826f3ecf6..000000000 --- a/src/std/rec/seqRecord.dbd +++ /dev/null @@ -1,365 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(seqSELM) { - choice(seqSELM_All,"All") - choice(seqSELM_Specified,"Specified") - choice(seqSELM_Mask,"Mask") -} -recordtype(seq) { - include "dbCommon.dbd" - field(VAL,DBF_LONG) { - prompt("Used to trigger") - asl(ASL0) - pp(TRUE) - } - field(SELM,DBF_MENU) { - prompt("Select Mechanism") - promptgroup("30 - Action") - interest(1) - menu(seqSELM) - } - field(SELN,DBF_USHORT) { - prompt("Link Selection") - interest(1) - initial("1") - } - field(SELL,DBF_INLINK) { - prompt("Link Selection Loc") - promptgroup("30 - Action") - interest(1) - } - field(OFFS,DBF_SHORT) { - prompt("Offset for Specified") - promptgroup("30 - Action") - interest(1) - initial("0") - } - field(SHFT,DBF_SHORT) { - prompt("Shift for Mask mode") - promptgroup("30 - Action") - interest(1) - initial("-1") - } - field(OLDN,DBF_USHORT) { - prompt("Old Selection") - interest(4) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - } - field(DLY0,DBF_DOUBLE) { - prompt("Delay 0") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DOL0,DBF_INLINK) { - prompt("Input link 0") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DO0,DBF_DOUBLE) { - prompt("Value 0") - interest(1) - } - field(LNK0,DBF_OUTLINK) { - prompt("Output Link 0") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DLY1,DBF_DOUBLE) { - prompt("Delay 1") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DOL1,DBF_INLINK) { - prompt("Input link1") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DO1,DBF_DOUBLE) { - prompt("Value 1") - interest(1) - } - field(LNK1,DBF_OUTLINK) { - prompt("Output Link 1") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DLY2,DBF_DOUBLE) { - prompt("Delay 2") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DOL2,DBF_INLINK) { - prompt("Input link 2") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DO2,DBF_DOUBLE) { - prompt("Value 2") - interest(1) - } - field(LNK2,DBF_OUTLINK) { - prompt("Output Link 2") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DLY3,DBF_DOUBLE) { - prompt("Delay 3") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DOL3,DBF_INLINK) { - prompt("Input link 3") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DO3,DBF_DOUBLE) { - prompt("Value 3") - interest(1) - } - field(LNK3,DBF_OUTLINK) { - prompt("Output Link 3") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DLY4,DBF_DOUBLE) { - prompt("Delay 4") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DOL4,DBF_INLINK) { - prompt("Input link 4") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DO4,DBF_DOUBLE) { - prompt("Value 4") - interest(1) - } - field(LNK4,DBF_OUTLINK) { - prompt("Output Link 4") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DLY5,DBF_DOUBLE) { - prompt("Delay 5") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DOL5,DBF_INLINK) { - prompt("Input link 5") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DO5,DBF_DOUBLE) { - prompt("Value 5") - interest(1) - } - field(LNK5,DBF_OUTLINK) { - prompt("Output Link 5") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DLY6,DBF_DOUBLE) { - prompt("Delay 6") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DOL6,DBF_INLINK) { - prompt("Input link 6") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DO6,DBF_DOUBLE) { - prompt("Value 6") - interest(1) - } - field(LNK6,DBF_OUTLINK) { - prompt("Output Link 6") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DLY7,DBF_DOUBLE) { - prompt("Delay 7") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DOL7,DBF_INLINK) { - prompt("Input link 7") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DO7,DBF_DOUBLE) { - prompt("Value 7") - interest(1) - } - field(LNK7,DBF_OUTLINK) { - prompt("Output Link 7") - promptgroup("41 - Link 0-7") - interest(1) - } - field(DLY8,DBF_DOUBLE) { - prompt("Delay 8") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOL8,DBF_INLINK) { - prompt("Input link 8") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DO8,DBF_DOUBLE) { - prompt("Value 8") - interest(1) - } - field(LNK8,DBF_OUTLINK) { - prompt("Output Link 8") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DLY9,DBF_DOUBLE) { - prompt("Delay 9") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOL9,DBF_INLINK) { - prompt("Input link 9") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DO9,DBF_DOUBLE) { - prompt("Value 9") - interest(1) - } - field(LNK9,DBF_OUTLINK) { - prompt("Output Link 9") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DLYA,DBF_DOUBLE) { - prompt("Delay 10") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOLA,DBF_INLINK) { - prompt("Input link 10") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOA,DBF_DOUBLE) { - prompt("Value 10") - interest(1) - } - field(LNKA,DBF_OUTLINK) { - prompt("Output Link 10") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DLYB,DBF_DOUBLE) { - prompt("Delay 11") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOLB,DBF_INLINK) { - prompt("Input link 11") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOB,DBF_DOUBLE) { - prompt("Value 11") - interest(1) - } - field(LNKB,DBF_OUTLINK) { - prompt("Output Link 11") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DLYC,DBF_DOUBLE) { - prompt("Delay 12") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOLC,DBF_INLINK) { - prompt("Input link 12") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOC,DBF_DOUBLE) { - prompt("Value 12") - interest(1) - } - field(LNKC,DBF_OUTLINK) { - prompt("Output Link 12") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DLYD,DBF_DOUBLE) { - prompt("Delay 13") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOLD,DBF_INLINK) { - prompt("Input link 13") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOD,DBF_DOUBLE) { - prompt("Value 13") - interest(1) - } - field(LNKD,DBF_OUTLINK) { - prompt("Output Link 13") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DLYE,DBF_DOUBLE) { - prompt("Delay 14") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOLE,DBF_INLINK) { - prompt("Input link 14") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOE,DBF_DOUBLE) { - prompt("Value 14") - interest(1) - } - field(LNKE,DBF_OUTLINK) { - prompt("Output Link 14") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DLYF,DBF_DOUBLE) { - prompt("Delay 15") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOLF,DBF_INLINK) { - prompt("Input link 15") - promptgroup("42 - Link 8-F") - interest(1) - } - field(DOF,DBF_DOUBLE) { - prompt("Value 15") - interest(1) - } - field(LNKF,DBF_OUTLINK) { - prompt("Output Link 15") - promptgroup("42 - Link 8-F") - interest(1) - } -} - -variable(seqDLYprecision, int) -variable(seqDLYlimit, double) diff --git a/src/std/rec/stateRecord.c b/src/std/rec/stateRecord.c deleted file mode 100644 index ca5df0295..000000000 --- a/src/std/rec/stateRecord.c +++ /dev/null @@ -1,105 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recState.c - Record Support Routines for State records */ -/* - * Original Author: Bob Dalesio - * Date: 10-10-90 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" - -#define GEN_SIZE_OFFSET -#include "stateRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -#define init_record NULL -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset stateRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,stateRSET); - -static void monitor(stateRecord *); - -static long process(struct dbCommon *pcommon) -{ - struct stateRecord *prec = (struct stateRecord *)pcommon; - - prec->udf = FALSE; - prec->pact=TRUE; - recGblGetTimeStamp(prec); - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - prec->pact=FALSE; - return(0); -} - -static void monitor(stateRecord *prec) -{ - unsigned short monitor_mask; - - /* get previous stat and sevr and new stat and sevr*/ - monitor_mask = recGblResetAlarms(prec); - if(strncmp(prec->oval,prec->val,sizeof(prec->val))) { - db_post_events(prec,&(prec->val[0]),monitor_mask|DBE_VALUE|DBE_LOG); - strncpy(prec->oval,prec->val,sizeof(prec->val)); - } - return; -} diff --git a/src/std/rec/stateRecord.dbd b/src/std/rec/stateRecord.dbd deleted file mode 100644 index 6e43ddbba..000000000 --- a/src/std/rec/stateRecord.dbd +++ /dev/null @@ -1,24 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(state) { - include "dbCommon.dbd" - field(VAL,DBF_STRING) { - prompt("Value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - size(20) - } - field(OVAL,DBF_STRING) { - prompt("Prev Value") - special(SPC_NOMOD) - interest(3) - size(20) - } -} diff --git a/src/std/rec/stringinRecord.c b/src/std/rec/stringinRecord.c deleted file mode 100644 index 163b23a49..000000000 --- a/src/std/rec/stringinRecord.c +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recStringin.c - Record Support Routines for Stringin records */ -/* - * Author: Janet Anderson - * Date: 4/23/91 - */ - - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "stringinRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset stringinRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,stringinRSET); - -struct stringindset { /* stringin input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_stringin; /*returns: (-1,0)=>(failure,success)*/ -}; -static void monitor(stringinRecord *); -static long readValue(stringinRecord *); - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct stringinRecord *prec = (struct stringinRecord *)pcommon; - STATIC_ASSERT(sizeof(prec->oval)==sizeof(prec->val)); - struct stringindset *pdset = (struct stringindset *) prec->dset; - - if (pass==0) - return 0; - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - recGblInitConstantLink(&prec->siol, DBF_STRING, prec->sval); - - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "stringin: init_record"); - return S_dev_noDSET; - } - - /* must have read_stringin function defined */ - if ((pdset->number < 5) || (pdset->read_stringin == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "stringin: init_record"); - return S_dev_missingSup; - } - - if (pdset->init_record) { - long status = pdset->init_record(prec); - - if (status) - return status; - } - strcpy(prec->oval, prec->val); - return 0; -} - -/* - */ -static long process(struct dbCommon *pcommon) -{ - struct stringinRecord *prec = (struct stringinRecord *)pcommon; - struct stringindset *pdset = (struct stringindset *)(prec->dset); - long status; - unsigned char pact=prec->pact; - - if( (pdset==NULL) || (pdset->read_stringin==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"read_stringin"); - return(S_dev_missingSup); - } - - status=readValue(prec); /* read the new value */ - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - - /* check event list */ - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - -static void monitor(stringinRecord *prec) -{ - int monitor_mask = recGblResetAlarms(prec); - - if (strncmp(prec->oval, prec->val, sizeof(prec->val))) { - monitor_mask |= DBE_VALUE | DBE_LOG; - strncpy(prec->oval, prec->val, sizeof(prec->val)); - } - - if (prec->mpst == stringinPOST_Always) - monitor_mask |= DBE_VALUE; - if (prec->apst == stringinPOST_Always) - monitor_mask |= DBE_LOG; - - if (monitor_mask) - db_post_events(prec, prec->val, monitor_mask); -} - -static long readValue(stringinRecord *prec) -{ - long status; - struct stringindset *pdset = (struct stringindset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->read_stringin)(prec); - return(status); - } - - status=dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0); - if (status) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->read_stringin)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status=dbGetLink(&(prec->siol),DBR_STRING, - prec->sval,0,0); - if (status==0) { - strcpy(prec->val,prec->sval); - prec->udf=FALSE; - } - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/stringinRecord.dbd b/src/std/rec/stringinRecord.dbd deleted file mode 100644 index 5b0b76813..000000000 --- a/src/std/rec/stringinRecord.dbd +++ /dev/null @@ -1,71 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(stringinPOST) { - choice(stringinPOST_OnChange,"On Change") - choice(stringinPOST_Always,"Always") -} -recordtype(stringin) { - include "dbCommon.dbd" - field(VAL,DBF_STRING) { - prompt("Current Value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - size(40) - } - field(OVAL,DBF_STRING) { - prompt("Previous Value") - special(SPC_NOMOD) - interest(3) - size(40) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(MPST,DBF_MENU) { - prompt("Post Value Monitors") - promptgroup("80 - Display") - interest(1) - menu(stringinPOST) - } - field(APST,DBF_MENU) { - prompt("Post Archive Monitors") - promptgroup("80 - Display") - interest(1) - menu(stringinPOST) - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SVAL,DBF_STRING) { - prompt("Simulation Value") - pp(TRUE) - size(40) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } -} diff --git a/src/std/rec/stringoutRecord.c b/src/std/rec/stringoutRecord.c deleted file mode 100644 index 416a6db5e..000000000 --- a/src/std/rec/stringoutRecord.c +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recStringout.c - Record Support Routines for Stringout records */ -/* - * Author: Janet Anderson - * Date: 4/23/91 - */ - - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "menuOmsl.h" -#include "menuIvoa.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "stringoutRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -#define get_units NULL -#define get_precision NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_graphic_double NULL -#define get_control_double NULL -#define get_alarm_double NULL - -rset stringoutRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,stringoutRSET); - -struct stringoutdset { /* stringout input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN write_stringout;/*(-1,0)=>(failure,success)*/ -}; -static void monitor(stringoutRecord *); -static long writeValue(stringoutRecord *); - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct stringoutRecord *prec = (struct stringoutRecord *)pcommon; - STATIC_ASSERT(sizeof(prec->oval)==sizeof(prec->val)); - struct stringoutdset *pdset = (struct stringoutdset *) prec->dset; - - if (pass==0) - return 0; - - recGblInitConstantLink(&prec->siml, DBF_USHORT, &prec->simm); - - if (!pdset) { - recGblRecordError(S_dev_noDSET, prec, "stringout: init_record"); - return S_dev_noDSET; - } - - /* must have write_stringout functions defined */ - if ((pdset->number < 5) || (pdset->write_stringout == NULL)) { - recGblRecordError(S_dev_missingSup, prec, "stringout: init_record"); - return S_dev_missingSup; - } - - /* get the initial value dol is a constant*/ - if (recGblInitConstantLink(&prec->dol, DBF_STRING, prec->val)) - prec->udf = FALSE; - - if (pdset->init_record) { - long status = pdset->init_record(prec); - - if(status) - return status; - } - - strcpy(prec->oval, prec->val); - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct stringoutRecord *prec = (struct stringoutRecord *)pcommon; - struct stringoutdset *pdset = (struct stringoutdset *)(prec->dset); - long status=0; - unsigned char pact=prec->pact; - - if( (pdset==NULL) || (pdset->write_stringout==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"write_stringout"); - return(S_dev_missingSup); - } - if (!prec->pact && - !dbLinkIsConstant(&prec->dol) && - prec->omsl == menuOmslclosed_loop) { - status = dbGetLink(&prec->dol, DBR_STRING, prec->val, 0, 0); - if (!dbLinkIsConstant(&prec->dol) && !status) - prec->udf=FALSE; - } - - if(prec->udf == TRUE ){ - recGblSetSevr(prec,UDF_ALARM,prec->udfs); - } - - if (prec->nsev < INVALID_ALARM ) - status=writeValue(prec); /* write the new value */ - else { - switch (prec->ivoa) { - case (menuIvoaContinue_normally) : - status=writeValue(prec); /* write the new value */ - break; - case (menuIvoaDon_t_drive_outputs) : - break; - case (menuIvoaSet_output_to_IVOV) : - if(prec->pact == FALSE){ - strcpy(prec->val,prec->ivov); - } - status=writeValue(prec); /* write the new value */ - break; - default : - status=-1; - recGblRecordError(S_db_badField,(void *)prec, - "stringout:process Illegal IVOA field"); - } - } - - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - - prec->pact = TRUE; - recGblGetTimeStamp(prec); - monitor(prec); - recGblFwdLink(prec); - prec->pact=FALSE; - return(status); -} - -static void monitor(stringoutRecord *prec) -{ - int monitor_mask = recGblResetAlarms(prec); - - if (strncmp(prec->oval, prec->val, sizeof(prec->val))) { - monitor_mask |= DBE_VALUE | DBE_LOG; - strncpy(prec->oval, prec->val, sizeof(prec->val)); - } - - if (prec->mpst == stringoutPOST_Always) - monitor_mask |= DBE_VALUE; - if (prec->apst == stringoutPOST_Always) - monitor_mask |= DBE_LOG; - - if (monitor_mask) - db_post_events(prec, prec->val, monitor_mask); -} - -static long writeValue(stringoutRecord *prec) -{ - long status; - struct stringoutdset *pdset = (struct stringoutdset *) (prec->dset); - - if (prec->pact == TRUE){ - status=(*pdset->write_stringout)(prec); - return(status); - } - - status=dbGetLink(&(prec->siml),DBR_USHORT, - &(prec->simm),0,0); - if (status) - return(status); - - if (prec->simm == menuYesNoNO){ - status=(*pdset->write_stringout)(prec); - return(status); - } - if (prec->simm == menuYesNoYES){ - status=dbPutLink(&prec->siol,DBR_STRING, - prec->val,1); - } else { - status=-1; - recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM); - return(status); - } - recGblSetSevr(prec,SIMM_ALARM,prec->sims); - - return(status); -} diff --git a/src/std/rec/stringoutRecord.dbd b/src/std/rec/stringoutRecord.dbd deleted file mode 100644 index fe0bae5d0..000000000 --- a/src/std/rec/stringoutRecord.dbd +++ /dev/null @@ -1,89 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -menu(stringoutPOST) { - choice(stringoutPOST_OnChange,"On Change") - choice(stringoutPOST_Always,"Always") -} -recordtype(stringout) { - include "dbCommon.dbd" - field(VAL,DBF_STRING) { - prompt("Current Value") - promptgroup("50 - Output") - asl(ASL0) - pp(TRUE) - size(40) - } - field(OVAL,DBF_STRING) { - prompt("Previous Value") - special(SPC_NOMOD) - interest(3) - size(40) - } - field(DOL,DBF_INLINK) { - prompt("Desired Output Loc") - promptgroup("40 - Input") - interest(1) - } - field(OMSL,DBF_MENU) { - prompt("Output Mode Select") - promptgroup("50 - Output") - interest(1) - menu(menuOmsl) - } - field(OUT,DBF_OUTLINK) { - prompt("Output Specification") - promptgroup("50 - Output") - interest(1) - } - field(MPST,DBF_MENU) { - prompt("Post Value Monitors") - promptgroup("80 - Display") - interest(1) - menu(stringoutPOST) - } - field(APST,DBF_MENU) { - prompt("Post Archive Monitors") - promptgroup("80 - Display") - interest(1) - menu(stringoutPOST) - } - field(SIOL,DBF_OUTLINK) { - prompt("Sim Output Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(IVOA,DBF_MENU) { - prompt("INVALID output action") - promptgroup("50 - Output") - interest(2) - menu(menuIvoa) - } - field(IVOV,DBF_STRING) { - prompt("INVALID output value") - promptgroup("50 - Output") - interest(2) - size(40) - } -} diff --git a/src/std/rec/subArrayRecord.c b/src/std/rec/subArrayRecord.c deleted file mode 100644 index d9d1c33e1..000000000 --- a/src/std/rec/subArrayRecord.c +++ /dev/null @@ -1,324 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 Lawrence Berkeley Laboratory,The Control Systems -* Group, Systems Engineering Department -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recSubArray.c - Record Support Routines for SubArray records - * - * - * Author: Carl Lionberger - * Date: 090293 - * - * NOTES: - * Derived from waveform record. - * Modification Log: - * ----------------- - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "dbScan.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "cantProceed.h" - -#define GEN_SIZE_OFFSET -#include "subArrayRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *prec, int pass); -static long process(struct dbCommon *prec); -#define special NULL -#define get_value NULL -static long cvt_dbaddr(DBADDR *paddr); -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset); -static long put_array_info(DBADDR *paddr, long nNew); -static long get_units(DBADDR *paddr, char *units); -static long get_precision(const DBADDR *paddr, long *precision); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd); -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd); -#define get_alarm_double NULL - -rset subArrayRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,subArrayRSET); - -struct sadset { /* subArray dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_sa; /*returns: (-1,0)=>(failure,success)*/ -}; - -static void monitor(subArrayRecord *prec); -static long readValue(subArrayRecord *prec); - - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct subArrayRecord *prec = (struct subArrayRecord *)pcommon; - struct sadset *pdset; - - if (pass==0){ - if (prec->malm <= 0) - prec->malm = 1; - if (prec->ftvl > DBF_ENUM) - prec->ftvl = DBF_UCHAR; - prec->bptr = callocMustSucceed(prec->malm, dbValueSize(prec->ftvl), - "subArrayRecord calloc failed"); - prec->nord = 0; - if (prec->nelm > prec->malm) - prec->nelm = prec->malm; - return 0; - } - - /* must have dset defined */ - if (!(pdset = (struct sadset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET,(void *)prec,"sa: init_record"); - return S_dev_noDSET; - } - - /* must have read_sa function defined */ - if ( (pdset->number < 5) || (pdset->read_sa == NULL) ) { - recGblRecordError(S_dev_missingSup,(void *)prec,"sa: init_record"); - return S_dev_missingSup; - } - - if (pdset->init_record) - return (*pdset->init_record)(prec); - - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct subArrayRecord *prec = (struct subArrayRecord *)pcommon; - struct sadset *pdset = (struct sadset *)(prec->dset); - long status; - unsigned char pact=prec->pact; - - if ((pdset==NULL) || (pdset->read_sa==NULL)) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup, (void *)prec, "read_sa"); - return S_dev_missingSup; - } - - if (pact && prec->busy) return 0; - - status=readValue(prec); /* read the new value */ - if (!pact && prec->pact) return 0; - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - - prec->udf = !!status; /* 0 or 1 */ - if (status) - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - - monitor(prec); - - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return 0; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - subArrayRecord *prec = (subArrayRecord *) paddr->precord; - - paddr->pfield = prec->bptr; - paddr->no_elements = prec->malm; - paddr->field_type = prec->ftvl; - paddr->field_size = dbValueSize(prec->ftvl); - paddr->dbr_field_type = prec->ftvl; - - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - subArrayRecord *prec = (subArrayRecord *) paddr->precord; - - if (prec->udf) - *no_elements = 0; - else - *no_elements = prec->nord; - *offset = 0; - - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - subArrayRecord *prec = (subArrayRecord *) paddr->precord; - - if (nNew > prec->malm) - nNew = prec->malm; - prec->nord = nNew; - - return 0; -} - -#define indexof(field) subArrayRecord##field - -static long get_units(DBADDR *paddr, char *units) -{ - subArrayRecord *prec = (subArrayRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM) - break; - case indexof(HOPR): - case indexof(LOPR): - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - subArrayRecord *prec = (subArrayRecord *) paddr->precord; - - *precision = prec->prec; - if (dbGetFieldIndex(paddr) != indexof(VAL)) - recGblGetPrec(paddr, precision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - subArrayRecord *prec = (subArrayRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - case indexof(INDX): - pgd->upper_disp_limit = prec->malm - 1; - pgd->lower_disp_limit = 0; - break; - case indexof(NELM): - pgd->upper_disp_limit = prec->malm; - pgd->lower_disp_limit = 0; - break; - case indexof(NORD): - pgd->upper_disp_limit = prec->malm; - pgd->lower_disp_limit = 0; - break; - case indexof(BUSY): - pgd->upper_disp_limit = 1; - pgd->lower_disp_limit = 0; - break; - default: - recGblGetGraphicDouble(paddr, pgd); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - subArrayRecord *prec = (subArrayRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - case indexof(INDX): - pcd->upper_ctrl_limit = prec->malm - 1; - pcd->lower_ctrl_limit = 0; - break; - case indexof(NELM): - pcd->upper_ctrl_limit = prec->malm; - pcd->lower_ctrl_limit = 1; - break; - case indexof(NORD): - pcd->upper_ctrl_limit = prec->malm; - pcd->lower_ctrl_limit = 0; - break; - case indexof(BUSY): - pcd->upper_ctrl_limit = 1; - pcd->lower_ctrl_limit = 0; - break; - default: - recGblGetControlDouble(paddr, pcd); - } - return 0; -} - -static void monitor(subArrayRecord *prec) -{ - unsigned short monitor_mask; - - monitor_mask = recGblResetAlarms(prec); - monitor_mask |= (DBE_LOG|DBE_VALUE); - - db_post_events(prec, prec->bptr, monitor_mask); - - return; -} - -static long readValue(subArrayRecord *prec) -{ - long status; - struct sadset *pdset = (struct sadset *) (prec->dset); - - if (prec->nelm > prec->malm) - prec->nelm = prec->malm; - - if (prec->indx >= prec->malm) - prec->indx = prec->malm - 1; - - status = (*pdset->read_sa)(prec); - - if (prec->nord <= 0) - status = -1; - - return status; -} - diff --git a/src/std/rec/subArrayRecord.dbd b/src/std/rec/subArrayRecord.dbd deleted file mode 100644 index 7814a2e48..000000000 --- a/src/std/rec/subArrayRecord.dbd +++ /dev/null @@ -1,90 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(subArray) { - include "dbCommon.dbd" - field(VAL,DBF_NOACCESS) { - prompt("Value") - asl(ASL0) - special(SPC_DBADDR) - pp(TRUE) - extra("void * val") - #=type Set by FTVL - #=read Yes - #=write Yes - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(FTVL,DBF_MENU) { - prompt("Field Type of Value") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - menu(menuFtype) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(MALM,DBF_ULONG) { - prompt("Maximum Elements") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(NELM,DBF_ULONG) { - prompt("Number of Elements") - promptgroup("30 - Action") - pp(TRUE) - initial("1") - } - field(INDX,DBF_ULONG) { - prompt("Substring Index") - promptgroup("30 - Action") - pp(TRUE) - } - field(BUSY,DBF_SHORT) { - prompt("Busy Indicator") - special(SPC_NOMOD) - } - field(NORD,DBF_LONG) { - prompt("Number elements read") - special(SPC_NOMOD) - } - field(BPTR,DBF_NOACCESS) { - prompt("Buffer Pointer") - special(SPC_NOMOD) - interest(4) - extra("void * bptr") - } -} diff --git a/src/std/rec/subRecord.c b/src/std/rec/subRecord.c deleted file mode 100644 index 1fc007034..000000000 --- a/src/std/rec/subRecord.c +++ /dev/null @@ -1,434 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Record Support Routines for Subroutine records */ -/* - * Original Author: Bob Dalesio - * Date: 01-25-90 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsMath.h" -#include "registryFunction.h" -#include "alarm.h" -#include "cantProceed.h" -#include "dbAccess.h" -#include "epicsPrint.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" - -#define GEN_SIZE_OFFSET -#include "subRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -static long special(DBADDR *, int); -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset subRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset, subRSET); - -static void checkAlarms(subRecord *); -static long do_sub(subRecord *); -static long fetch_values(subRecord *); -static void monitor(subRecord *); - -#define INP_ARG_MAX 12 - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct subRecord *prec = (struct subRecord *)pcommon; - SUBFUNCPTR psubroutine; - struct link *plink; - int i; - double *pvalue; - - if (pass==0) return(0); - - plink = &prec->inpa; - pvalue = &prec->a; - for (i = 0; i < INP_ARG_MAX; i++, plink++, pvalue++) { - recGblInitConstantLink(plink, DBF_DOUBLE, pvalue); - } - - if (prec->inam[0]) { - /* convert the initialization subroutine name */ - psubroutine = (SUBFUNCPTR)registryFunctionFind(prec->inam); - if (psubroutine == 0) { - recGblRecordError(S_db_BadSub, (void *)prec, "Init subroutine (INAM)"); - return S_db_BadSub; - } - /* invoke the initialization subroutine */ - (*psubroutine)(prec); - } - - if (prec->snam[0] == 0) { - epicsPrintf("%s.SNAM is empty\n", prec->name); - prec->pact = TRUE; - return 0; - } - prec->sadr = (SUBFUNCPTR)registryFunctionFind(prec->snam); - if (prec->sadr == NULL) { - recGblRecordError(S_db_BadSub, (void *)prec, "Proc subroutine (SNAM)"); - return S_db_BadSub; - } - prec->mlst = prec->val; - prec->alst = prec->val; - prec->lalm = prec->val; - return 0; -} - -static long process(struct dbCommon *pcommon) -{ - struct subRecord *prec = (struct subRecord *)pcommon; - long status = 0; - int pact = prec->pact; - - if (!pact) { - prec->pact = TRUE; - status = fetch_values(prec); - prec->pact = FALSE; - } - if (status == 0) status = do_sub(prec); - - /* Is subroutine asynchronous? */ - if (!pact && prec->pact) return 0; - prec->pact = TRUE; - - /* Asynchronous function (documented API!) */ - if (status == 1) return 0; - - recGblGetTimeStamp(prec); - - /* check for alarms */ - checkAlarms(prec); - - /* publish changes */ - monitor(prec); - - recGblFwdLink(prec); - prec->pact = FALSE; - - return 0; -} - -static long special(DBADDR *paddr, int after) -{ - subRecord *prec = (subRecord *)paddr->precord; - - if (!after) { - if (prec->snam[0] == 0 && prec->pact) { - prec->pact = FALSE; - prec->rpro = FALSE; - } - return 0; - } - - if (prec->snam[0] == 0) { - epicsPrintf("%s.SNAM is empty\n", prec->name); - prec->pact = TRUE; - return 0; - } - - prec->sadr = (SUBFUNCPTR)registryFunctionFind(prec->snam); - if (prec->sadr) return 0; - - recGblRecordError(S_db_BadSub, (void *)prec, - "subRecord(special) registryFunctionFind failed"); - return S_db_BadSub; -} - -#define indexof(field) subRecord##field - -static long get_linkNumber(int fieldIndex) { - if (fieldIndex >= indexof(A) && fieldIndex <= indexof(L)) - return fieldIndex - indexof(A); - if (fieldIndex >= indexof(LA) && fieldIndex <= indexof(LL)) - return fieldIndex - indexof(LA); - return -1; -} - -static long get_units(DBADDR *paddr, char *units) -{ - subRecord *prec = (subRecord *)paddr->precord; - int linkNumber; - - if(paddr->pfldDes->field_type == DBF_DOUBLE) { - linkNumber = get_linkNumber(dbGetFieldIndex(paddr)); - if (linkNumber >= 0) - dbGetUnits(&prec->inpa + linkNumber, units, DB_UNITS_SIZE); - else - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *pprecision) -{ - subRecord *prec = (subRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - *pprecision = prec->prec; - if (fieldIndex == indexof(VAL)) - return 0; - - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - short precision; - - if (dbGetPrecision(&prec->inpa + linkNumber, &precision) == 0) - *pprecision = precision; - } else - recGblGetPrec(paddr, pprecision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - subRecord *prec = (subRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - switch (fieldIndex) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pgd->lower_disp_limit = prec->lopr; - pgd->upper_disp_limit = prec->hopr; - break; - default: - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetGraphicLimits(&prec->inpa + linkNumber, - &pgd->lower_disp_limit, - &pgd->upper_disp_limit); - } else - recGblGetGraphicDouble(paddr,pgd); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - subRecord *prec = (subRecord *)paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - case indexof(HIHI): - case indexof(HIGH): - case indexof(LOW): - case indexof(LOLO): - case indexof(LALM): - case indexof(ALST): - case indexof(MLST): - pcd->lower_ctrl_limit = prec->lopr; - pcd->upper_ctrl_limit = prec->hopr; - break; - default: - recGblGetControlDouble(paddr,pcd); - } - return 0; -} - -static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad) -{ - subRecord *prec = (subRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - int linkNumber; - - if (fieldIndex == subRecordVAL) { - pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN; - pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN; - pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN; - pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN; - } else { - linkNumber = get_linkNumber(fieldIndex); - if (linkNumber >= 0) { - dbGetAlarmLimits(&prec->inpa + linkNumber, - &pad->lower_alarm_limit, - &pad->lower_warning_limit, - &pad->upper_warning_limit, - &pad->upper_alarm_limit); - } else - recGblGetAlarmDouble(paddr, pad); - } - return 0; -} - -static void checkAlarms(subRecord *prec) -{ - double val, hyst, lalm; - double alev; - epicsEnum16 asev; - - if (prec->udf) { - recGblSetSevr(prec, UDF_ALARM, prec->udfs); - return; - } - - val = prec->val; - hyst = prec->hyst; - lalm = prec->lalm; - - /* alarm condition hihi */ - asev = prec->hhsv; - alev = prec->hihi; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIHI_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition lolo */ - asev = prec->llsv; - alev = prec->lolo; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOLO_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition high */ - asev = prec->hsv; - alev = prec->high; - if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) { - if (recGblSetSevr(prec, HIGH_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* alarm condition low */ - asev = prec->lsv; - alev = prec->low; - if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) { - if (recGblSetSevr(prec, LOW_ALARM, asev)) - prec->lalm = alev; - return; - } - - /* we get here only if val is out of alarm by at least hyst */ - prec->lalm = val; - return; -} - -static void monitor(subRecord *prec) -{ - unsigned monitor_mask; - double *pnew; - double *pold; - int i; - - /* get alarm mask */ - monitor_mask = recGblResetAlarms(prec); - - /* check for value change */ - recGblCheckDeadband(&prec->mlst, prec->val, prec->mdel, &monitor_mask, DBE_VALUE); - - /* check for archive change */ - recGblCheckDeadband(&prec->alst, prec->val, prec->adel, &monitor_mask, DBE_ARCHIVE); - - /* send out monitors connected to the value field */ - if (monitor_mask) { - db_post_events(prec, &prec->val, monitor_mask); - } - - /* check all input fields for changes */ - for (i = 0, pnew = &prec->a, pold = &prec->la; - i < INP_ARG_MAX; i++, pnew++, pold++) { - if (*pnew != *pold) { - db_post_events(prec, pnew, monitor_mask | DBE_VALUE | DBE_LOG); - *pold = *pnew; - } - } - return; -} - -static long fetch_values(subRecord *prec) -{ - struct link *plink = &prec->inpa; - double *pvalue = &prec->a; - int i; - - for (i = 0; i < INP_ARG_MAX; i++, plink++, pvalue++) { - if (dbGetLink(plink, DBR_DOUBLE, pvalue, 0, 0)) - return -1; - } - return 0; -} - -static long do_sub(subRecord *prec) -{ - SUBFUNCPTR psubroutine = prec->sadr; - long status; - - if (psubroutine == NULL) { - recGblSetSevr(prec, BAD_SUB_ALARM, INVALID_ALARM); - return 0; - } - - status = (*psubroutine)(prec); - if (status < 0) { - recGblSetSevr(prec, SOFT_ALARM, prec->brsv); - } else { - prec->udf = isnan(prec->val); - } - return status; -} diff --git a/src/std/rec/subRecord.dbd b/src/std/rec/subRecord.dbd deleted file mode 100644 index 48cfc1385..000000000 --- a/src/std/rec/subRecord.dbd +++ /dev/null @@ -1,328 +0,0 @@ -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(sub) { - include "dbCommon.dbd" - field(VAL,DBF_DOUBLE) { - prompt("Result") - asl(ASL0) - pp(TRUE) - } - field(INAM,DBF_STRING) { - prompt("Init Routine Name") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - size(40) - } - field(SNAM,DBF_STRING) { - prompt("Subroutine Name") - promptgroup("30 - Action") - special(SPC_MOD) - interest(1) - size(40) - } - %struct subRecord; - %typedef long (*SUBFUNCPTR)(struct subRecord *); - field(SADR,DBF_NOACCESS) { - prompt("Subroutine Address") - special(SPC_NOMOD) - interest(4) - extra("SUBFUNCPTR sadr") - } - field(INPA,DBF_INLINK) { - prompt("Input A") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPB,DBF_INLINK) { - prompt("Input B") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPC,DBF_INLINK) { - prompt("Input C") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPD,DBF_INLINK) { - prompt("Input D") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPE,DBF_INLINK) { - prompt("Input E") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPF,DBF_INLINK) { - prompt("Input F") - promptgroup("41 - Input A-F") - interest(1) - } - field(INPG,DBF_INLINK) { - prompt("Input G") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPH,DBF_INLINK) { - prompt("Input H") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPI,DBF_INLINK) { - prompt("Input I") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPJ,DBF_INLINK) { - prompt("Input J") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPK,DBF_INLINK) { - prompt("Input K") - promptgroup("42 - Input G-L") - interest(1) - } - field(INPL,DBF_INLINK) { - prompt("Input L") - promptgroup("42 - Input G-L") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(HIHI,DBF_DOUBLE) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOLO,DBF_DOUBLE) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(HIGH,DBF_DOUBLE) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(LOW,DBF_DOUBLE) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(BRSV,DBF_MENU) { - prompt("Bad Return Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - prop(YES) - menu(menuAlarmSevr) - } - field(HYST,DBF_DOUBLE) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_DOUBLE) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_DOUBLE) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(A,DBF_DOUBLE) { - prompt("Value of Input A") - pp(TRUE) - } - field(B,DBF_DOUBLE) { - prompt("Value of Input B") - pp(TRUE) - } - field(C,DBF_DOUBLE) { - prompt("Value of Input C") - pp(TRUE) - } - field(D,DBF_DOUBLE) { - prompt("Value of Input D") - pp(TRUE) - } - field(E,DBF_DOUBLE) { - prompt("Value of Input E") - pp(TRUE) - } - field(F,DBF_DOUBLE) { - prompt("Value of Input F") - pp(TRUE) - } - field(G,DBF_DOUBLE) { - prompt("Value of Input G") - pp(TRUE) - } - field(H,DBF_DOUBLE) { - prompt("Value of Input H") - pp(TRUE) - } - field(I,DBF_DOUBLE) { - prompt("Value of Input I") - pp(TRUE) - } - field(J,DBF_DOUBLE) { - prompt("Value of Input J") - pp(TRUE) - } - field(K,DBF_DOUBLE) { - prompt("Value of Input K") - pp(TRUE) - } - field(L,DBF_DOUBLE) { - prompt("Value of Input L") - pp(TRUE) - } - field(LA,DBF_DOUBLE) { - prompt("Prev Value of A") - special(SPC_NOMOD) - interest(3) - } - field(LB,DBF_DOUBLE) { - prompt("Prev Value of B") - special(SPC_NOMOD) - interest(3) - } - field(LC,DBF_DOUBLE) { - prompt("Prev Value of C") - special(SPC_NOMOD) - interest(3) - } - field(LD,DBF_DOUBLE) { - prompt("Prev Value of D") - special(SPC_NOMOD) - interest(3) - } - field(LE,DBF_DOUBLE) { - prompt("Prev Value of E") - special(SPC_NOMOD) - interest(3) - } - field(LF,DBF_DOUBLE) { - prompt("Prev Value of F") - special(SPC_NOMOD) - interest(3) - } - field(LG,DBF_DOUBLE) { - prompt("Prev Value of G") - special(SPC_NOMOD) - interest(3) - } - field(LH,DBF_DOUBLE) { - prompt("Prev Value of H") - special(SPC_NOMOD) - interest(3) - } - field(LI,DBF_DOUBLE) { - prompt("Prev Value of I") - special(SPC_NOMOD) - interest(3) - } - field(LJ,DBF_DOUBLE) { - prompt("Prev Value of J") - special(SPC_NOMOD) - interest(3) - } - field(LK,DBF_DOUBLE) { - prompt("Prev Value of K") - special(SPC_NOMOD) - interest(3) - } - field(LL,DBF_DOUBLE) { - prompt("Prev Value of L") - special(SPC_NOMOD) - interest(3) - } - field(LALM,DBF_DOUBLE) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_DOUBLE) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_DOUBLE) { - prompt("Last Value Monitored") - special(SPC_NOMOD) - interest(3) - } -} diff --git a/src/std/rec/test/Makefile b/src/std/rec/test/Makefile deleted file mode 100644 index f200e54e6..000000000 --- a/src/std/rec/test/Makefile +++ /dev/null @@ -1,114 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -TESTLIBRARY = dbRecStdTest - -dbRecStdTest_SRCS += asTestLib.c -dbRecStdTest_LIBS += dbRecStd dbCore ca Com - -PROD_LIBS = dbRecStdTest dbRecStd dbCore ca Com - -TARGETS += $(COMMON_DIR)/recTestIoc.dbd -DBDDEPENDS_FILES += recTestIoc.dbd$(DEP) -recTestIoc_DBD = base.dbd -TESTFILES += $(COMMON_DIR)/recTestIoc.dbd - -testHarness_SRCS += recTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += asTestIoc_registerRecordDeviceDriver.cpp - -TESTPROD_HOST += arrayOpTest -arrayOpTest_SRCS += arrayOpTest.c -arrayOpTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += arrayOpTest.c -TESTFILES += ../arrayOpTest.db -TESTS += arrayOpTest - -TESTPROD_HOST += recMiscTest -recMiscTest_SRCS += recMiscTest.c -recMiscTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += recMiscTest.c -TESTFILES += ../recMiscTest.db -TESTS += recMiscTest - -TESTPROD_HOST += linkRetargetLinkTest -linkRetargetLinkTest_SRCS += linkRetargetLinkTest.c -linkRetargetLinkTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += linkRetargetLinkTest.c -TESTFILES += ../linkRetargetLink.db -TESTS += linkRetargetLinkTest - -TESTPROD_HOST += linkInitTest -linkInitTest_SRCS += linkInitTest.c -linkInitTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += linkInitTest.c -TESTFILES += ../linkInitTest.db -TESTS += linkInitTest - -TESTPROD_HOST += compressTest -compressTest_SRCS += compressTest.c -compressTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += compressTest.c -TESTFILES += ../compressTest.db -TESTS += compressTest - -TESTPROD_HOST += asyncSoftTest -asyncSoftTest_SRCS += asyncSoftTest.c -asyncSoftTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += asyncSoftTest.c -TESTFILES += ../asyncSoftTest.db -TESTS += asyncSoftTest - -TARGETS += $(COMMON_DIR)/asTestIoc.dbd -DBDDEPENDS_FILES += asTestIoc.dbd$(DEP) -asTestIoc_DBD += base.dbd -asTestIoc_DBD += asTest.dbd -TESTPROD_HOST += asTest -asTest_SRCS += asTest.c -asTest_SRCS += asTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += asTest.c -TESTFILES += $(COMMON_DIR)/asTestIoc.dbd ../asTest.db -TESTS += asTest - -TARGETS += $(COMMON_DIR)/analogMonitorTest.dbd -DBDDEPENDS_FILES += analogMonitorTest.dbd$(DEP) -analogMonitorTest_DBD += base.dbd -TESTPROD_HOST += analogMonitorTest -analogMonitorTest_SRCS += analogMonitorTest.c -analogMonitorTest_SRCS += analogMonitorTest_registerRecordDeviceDriver.cpp -testHarness_SRCS += analogMonitorTest.c -testHarness_SRCS += analogMonitorTest_registerRecordDeviceDriver.cpp -TESTFILES += $(COMMON_DIR)/analogMonitorTest.dbd ../analogMonitorTest.db -TESTS += analogMonitorTest - -TARGETS += $(COMMON_DIR)/regressTest.dbd -regressTest_DBD += base.dbd -TESTPROD_HOST += regressTest -regressTest_SRCS += regressTest.c -regressTest_SRCS += regressTest_registerRecordDeviceDriver.cpp -TESTFILES += $(COMMON_DIR)/regressTest.dbd ../regressArray1.db -TESTS += regressTest - -# epicsRunRecordTests runs all the test programs in a known working order. -testHarness_SRCS += epicsRunRecordTests.c - -recordTestHarness_SRCS += $(testHarness_SRCS) -recordTestHarness_SRCS_RTEMS += rtemsTestHarness.c - -PROD_vxWorks = recordTestHarness -PROD_RTEMS = recordTestHarness - -TESTSPEC_vxWorks = recordTestHarness.munch; epicsRunRecordTests -TESTSPEC_RTEMS = recordTestHarness.boot; epicsRunRecordTests - -TESTSCRIPTS_HOST += $(TESTS:%=%.t) - -include $(TOP)/configure/RULES diff --git a/src/std/rec/test/analogMonitorTest.c b/src/std/rec/test/analogMonitorTest.c deleted file mode 100644 index fb7f61e39..000000000 --- a/src/std/rec/test/analogMonitorTest.c +++ /dev/null @@ -1,240 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 ITER Organization. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Ralph Lange - */ - -#include - -#include "registryFunction.h" -#include "osiFileName.h" -#include "epicsThread.h" -#include "epicsMath.h" -#include "epicsUnitTest.h" -#include "dbAccessDefs.h" -#include "dbStaticLib.h" -#include "dbEvent.h" -#include "caeventmask.h" -#include "db_field_log.h" -#include "chfPlugin.h" -#include "iocInit.h" -#include "testMain.h" -#include "epicsExport.h" - -/* Test parameters */ - -#define NO_OF_RECORD_TYPES 7 -#define NO_OF_DEADBANDS 3 -#define NO_OF_PATTERNS 16 -#define NO_OF_VALUES_PER_SEQUENCE 2 - -void analogMonitorTest_registerRecordDeviceDriver(struct dbBase *); - -/* Indices for record type, deadband type, deadband value, test number, val in sequence */ -static int irec, ityp, idbnd, itest, iseq; - -/* Records to test with */ -static const char t_Record[NO_OF_RECORD_TYPES][10] = { - {"ai"}, {"ao"}, {"calc"}, {"calcout"}, {"dfanout"}, {"sel"}, {"sub"}, -}; -/* Deadband types to test */ -static const char t_DbndType[2][6] = { {".MDEL"}, {".ADEL"} }; -/* Different deadbands to test with */ -static double t_Deadband[NO_OF_DEADBANDS] = { -1, 0, 1.5 }; -/* Value sequences for each of the 16 tests */ -static double t_SetValues[NO_OF_PATTERNS][NO_OF_VALUES_PER_SEQUENCE]; -/* Expected updates (1=yes) for each sequence of each test of each deadband */ -static int t_ExpectedUpdates[NO_OF_DEADBANDS][NO_OF_PATTERNS][NO_OF_VALUES_PER_SEQUENCE] = { - { /* deadband = -1 */ - {1, 1}, {1, 1}, {1, 1}, {1, 1}, - {1, 1}, {1, 1}, {1, 1}, {1, 1}, - {1, 1}, {1, 1}, {1, 1}, {1, 1}, - {1, 1}, {1, 1}, {1, 1}, {1, 1}, - }, - { /* deadband = 0 */ - {1, 1}, {0, 1}, {0, 0}, {0, 0}, - {1, 1}, {1, 0}, {1, 1}, {1, 1}, - {1, 1}, {1, 1}, {1, 0}, {1, 1}, - {1, 1}, {1, 1}, {1, 1}, {1, 0}, - }, - { /* deadband = 1.5 */ - {0, 1}, {0, 1}, {0, 0}, {0, 0}, - {1, 1}, {1, 0}, {1, 1}, {1, 1}, - {1, 1}, {1, 1}, {1, 0}, {1, 1}, - {1, 1}, {1, 1}, {1, 1}, {1, 0}, - }, -}; -static int t_ReceivedUpdates[NO_OF_PATTERNS][NO_OF_VALUES_PER_SEQUENCE]; - -/* Dummy subroutine needed for sub record */ - -static long myTestSub(void *p) { - return 0; -} - - -/* Minimal pre-chain plugin to divert all monitors back into the test (before they hit the queue) */ - -static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) { - double val = *((double*)chan->addr.pfield); - - /* iseq == -1 is the value reset before the test pattern -> do not count */ - if (iseq >= 0) { - t_ReceivedUpdates[itest][iseq] = 1; - testOk((val == t_SetValues[itest][iseq]) || (isnan(val) && isnan(t_SetValues[itest][iseq])), - "update %d pattern %2d with %s = %2.1f (expected %f, got %f)", - iseq, itest, (ityp==0?"MDEL":"ADEL"), t_Deadband[idbnd], t_SetValues[itest][iseq], val); - } - db_delete_field_log(pfl); - return NULL; -} - -static void channelRegisterPre(dbChannel *chan, void *pvt, - chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) -{ - *cb_out = filter; -} - -static chfPluginIf pif = { - NULL, /* allocPvt, */ - NULL, /* freePvt, */ - NULL, /* parse_error, */ - NULL, /* parse_ok, */ - NULL, /* channel_open, */ - channelRegisterPre, - NULL, /* channelRegisterPost, */ - NULL, /* channel_report, */ - NULL /* channel_close */ -}; - - -MAIN(analogMonitorTest) -{ - dbChannel *pch; - const chFilterPlugin *plug; - const char test[] = "test"; - dbEventCtx evtctx; - dbEventSubscription subscr; - unsigned mask; - struct dbAddr vaddr, daddr; - double val; - char chan[50]; /* Channel name */ - char cval[50]; /* Name for test values */ - char cdel[50]; /* Name for deadband values */ - - /* Test patterns: - * 0: step less than deadband (of 1.5) - * 1: step larger than deadband (of 1.5) - * 2: no change - * 3: -0.0 -> +0.0 - * ... all possible combinations of steps - * between: finite / NaN / -inf / +inf - */ - t_SetValues[ 0][0] = 1.0; t_SetValues[ 0][1] = 2.0; - t_SetValues[ 1][0] = 0.0; t_SetValues[ 1][1] = 2.0; - t_SetValues[ 2][0] = 0.0; t_SetValues[ 2][1] = 0.0; - t_SetValues[ 3][0] = -0.0; t_SetValues[ 3][1] = 0.0; - t_SetValues[ 4][0] = epicsNAN; t_SetValues[ 4][1] = 1.0; - t_SetValues[ 5][0] = epicsNAN; t_SetValues[ 5][1] = epicsNAN; - t_SetValues[ 6][0] = epicsNAN; t_SetValues[ 6][1] = epicsINF; - t_SetValues[ 7][0] = epicsNAN; t_SetValues[ 7][1] = -epicsINF; - t_SetValues[ 8][0] = epicsINF; t_SetValues[ 8][1] = 1.0; - t_SetValues[ 9][0] = epicsINF; t_SetValues[ 9][1] = epicsNAN; - t_SetValues[10][0] = epicsINF; t_SetValues[10][1] = epicsINF; - t_SetValues[11][0] = epicsINF; t_SetValues[11][1] = -epicsINF; - t_SetValues[12][0] = -epicsINF; t_SetValues[12][1] = 1.0; - t_SetValues[13][0] = -epicsINF; t_SetValues[13][1] = epicsNAN; - t_SetValues[14][0] = -epicsINF; t_SetValues[14][1] = epicsINF; - t_SetValues[15][0] = -epicsINF; t_SetValues[15][1] = -epicsINF; - - registryFunctionAdd("myTestSub", (REGISTRYFUNCTION) myTestSub); - - testPlan(1793); - - if (dbReadDatabase(&pdbbase, "analogMonitorTest.dbd", - "." OSI_PATH_LIST_SEPARATOR ".." OSI_PATH_LIST_SEPARATOR - "../O.Common" OSI_PATH_LIST_SEPARATOR "O.Common", NULL)) - testAbort("Error reading database description 'analogMonitorTest.dbd'"); - - analogMonitorTest_registerRecordDeviceDriver(pdbbase); - - if (dbReadDatabase(&pdbbase, "analogMonitorTest.db", - "." OSI_PATH_LIST_SEPARATOR "..", NULL)) - testAbort("Error reading test database 'analogMonitorTest.db'"); - - /* Start the core IOC (no CA) */ - iocBuildIsolated(); - - evtctx = db_init_events(); - chfPluginRegister(test, &pif, NULL); - - plug = dbFindFilter(test, strlen(test)); - testOk(!!plug, "interceptor plugin registered"); - - /* Loop over all analog record types (one instance each) */ - for (irec = 0; irec < NO_OF_RECORD_TYPES; irec++) { - strcpy(cval, t_Record[irec]); - strcpy(chan, cval); - strcat(chan, ".VAL{\"test\":{}}"); - if ((strcmp(t_Record[irec], "sel") == 0) - || (strcmp(t_Record[irec], "calc") == 0) - || (strcmp(t_Record[irec], "calcout") == 0)) { - strcat(cval, ".A"); - } else { - strcat(cval, ".VAL"); - } - - testDiag("--------------------------------------------------------"); - testDiag("Testing the %s record", t_Record[irec]); - testDiag("--------------------------------------------------------"); - - pch = dbChannelCreate(chan); - testOk(!!pch, "dbChannel with test plugin created"); - testOk(!dbChannelOpen(pch), "dbChannel opened"); - - dbNameToAddr(cval, &vaddr); - - /* Loop over both tested deadband types */ - for (ityp = 0; ityp < 2; ityp++) { - strcpy(cdel, t_Record[irec]); - strcat(cdel, t_DbndType[ityp]); - dbNameToAddr(cdel, &daddr); - mask = (ityp==0?DBE_VALUE:DBE_ARCHIVE); - subscr = db_add_event(evtctx, pch, NULL, NULL, mask); - db_event_enable(subscr); - - /* Loop over all tested deadband values */ - for (idbnd = 0; idbnd < NO_OF_DEADBANDS; idbnd++) { - testDiag("Test %s%s = %g", t_Record[irec], t_DbndType[ityp], t_Deadband[idbnd]); - dbPutField(&daddr, DBR_DOUBLE, (void*) &t_Deadband[idbnd], 1); - memset(t_ReceivedUpdates, 0, sizeof(t_ReceivedUpdates)); - - /* Loop over all test patterns */ - for (itest = 0; itest < NO_OF_PATTERNS; itest++) { - iseq = -1; - val = 0.0; - dbPutField(&vaddr, DBR_DOUBLE, (void*) &val, 1); - - /* Loop over the test sequence */ - for (iseq = 0; iseq < NO_OF_VALUES_PER_SEQUENCE; iseq++) { - dbPutField(&vaddr, DBR_DOUBLE, (void*) &t_SetValues[itest][iseq], 1); - } - /* Check expected vs. actual monitors */ - testOk( (t_ExpectedUpdates[idbnd][itest][0] == t_ReceivedUpdates[itest][0]) && - (t_ExpectedUpdates[idbnd][itest][1] == t_ReceivedUpdates[itest][1]), - "pattern %2d with %s = %2.1f (expected %d-%d, got %d-%d)", - itest, (ityp==0?"MDEL":"ADEL"), t_Deadband[idbnd], - t_ExpectedUpdates[idbnd][itest][0], t_ExpectedUpdates[idbnd][itest][1], - t_ReceivedUpdates[itest][0], t_ReceivedUpdates[itest][1]); - } - } - db_cancel_event(subscr); - } - } - iocShutdown(); - return testDone(); -} diff --git a/src/std/rec/test/analogMonitorTest.db b/src/std/rec/test/analogMonitorTest.db deleted file mode 100644 index 5b3f4a2d7..000000000 --- a/src/std/rec/test/analogMonitorTest.db +++ /dev/null @@ -1,13 +0,0 @@ -record(ai, "ai") {} -record(ao, "ao") {} -record(calc, "calc") { - field(CALC, "A") -} -record(calcout, "calcout") { - field(CALC, "A") -} -record(dfanout, "dfanout") {} -record(sel, "sel") {} -record(sub, "sub") { - field(SNAM, "myTestSub") -} diff --git a/src/std/rec/test/arrayOpTest.c b/src/std/rec/test/arrayOpTest.c deleted file mode 100644 index b37c725e2..000000000 --- a/src/std/rec/test/arrayOpTest.c +++ /dev/null @@ -1,166 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2014 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -#include - -#include "dbAccess.h" -#include "dbTest.h" - -#include "dbUnitTest.h" -#include "errlog.h" - -#include "waveformRecord.h" - -#include "testMain.h" - -void recTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static void testGetPutArray(void) -{ - double data[4] = {11, 12, 13, 14}; - DBADDR addr, save; - long nreq; - epicsInt32 *pbtr; - waveformRecord *prec; - - testdbPrepare(); - - testdbReadDatabase("recTestIoc.dbd", NULL, NULL); - - recTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("arrayOpTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - testDiag("Test dbGet() and dbPut() from/to an array"); - - prec = (waveformRecord*)testdbRecordPtr("wfrec"); - if(!prec || dbNameToAddr("wfrec", &addr)) - testAbort("Failed to find record wfrec"); - memcpy(&save, &addr, sizeof(save)); - - testDiag("Fetch initial value of %s", prec->name); - - dbScanLock(addr.precord); - testOk(prec->nord==3, "prec->nord==3 (got %d)", prec->nord); - - nreq = NELEMENTS(data); - if(dbGet(&addr, DBF_DOUBLE, &data, NULL, &nreq, NULL)) { - testFail("dbGet fails"); - testSkip(1, "failed get"); - } else { - testOk(nreq==3, "nreq==3 (got %ld)", nreq); - testOk1(data[0]==1.0 && data[1]==2.0 && data[2]==3.0); - } - dbScanUnlock(addr.precord); - - testOk1(memcmp(&addr, &save, sizeof(save))==0); - addr=save; - - testDiag("Write a new value"); - - data[0] = 4.0; - data[1] = 5.0; - data[2] = 6.0; - data[3] = 7.0; - - dbScanLock(addr.precord); - testOk1(dbPut(&addr, DBF_DOUBLE, &data, NELEMENTS(data))==0); - pbtr = prec->bptr; - testOk(prec->nord==4, "prec->nord==4 (got %u)", prec->nord); - testOk1(pbtr[0]==4 && pbtr[1]==5 && pbtr[2]==6 && pbtr[3]==7); - dbScanUnlock(addr.precord); - - testOk1(memcmp(&addr, &save, sizeof(save))==0); - addr=save; - - memset(&data, 0, sizeof(data)); - - testDiag("Reread the value"); - - dbScanLock(addr.precord); - nreq = NELEMENTS(data); - if(dbGet(&addr, DBF_DOUBLE, &data, NULL, &nreq, NULL)) - testFail("dbGet fails"); - else { - testOk1(nreq==NELEMENTS(data)); - testOk1(data[0]==4.0 && data[1]==5.0 && data[2]==6.0 && data[3]==7.0); - } - dbScanUnlock(addr.precord); - - testOk1(memcmp(&addr, &save, sizeof(save))==0); - - testDiag("Test dbGet() and dbPut() from/to an array of size 1"); - - prec = (waveformRecord*)testdbRecordPtr("wfrec1"); - if(!prec || dbNameToAddr("wfrec1", &addr)) - testAbort("Failed to find record wfrec1"); - memcpy(&save, &addr, sizeof(save)); - - testDiag("Fetch initial value of %s", prec->name); - - dbScanLock(addr.precord); - testOk(prec->nord==0, "prec->nord==0 (got %d)", prec->nord); - - nreq = NELEMENTS(data); - if(dbGet(&addr, DBF_DOUBLE, &data, NULL, &nreq, NULL)) - testFail("dbGet fails"); - else { - testOk(nreq==0, "nreq==0 (got %ld)", nreq); - } - dbScanUnlock(addr.precord); - - testOk1(memcmp(&addr, &save, sizeof(save))==0); - addr=save; - - testDiag("Write a new value"); - - data[0] = 4.0; - data[1] = 5.0; - data[2] = 6.0; - data[3] = 7.0; - - dbScanLock(addr.precord); - testOk1(dbPut(&addr, DBF_DOUBLE, &data, 1)==0); - pbtr = prec->bptr; - testOk(prec->nord==1, "prec->nord==1 (got %u)", prec->nord); - testOk1(pbtr[0]==4); - dbScanUnlock(addr.precord); - - testOk1(memcmp(&addr, &save, sizeof(save))==0); - addr=save; - - memset(&data, 0, sizeof(data)); - - testDiag("Reread the value"); - - dbScanLock(addr.precord); - nreq = NELEMENTS(data); - if(dbGet(&addr, DBF_DOUBLE, &data, NULL, &nreq, NULL)) - testFail("dbGet fails"); - else { - testOk1(nreq==1); - testOk1(data[0]==4.0); - } - dbScanUnlock(addr.precord); - - testOk1(memcmp(&addr, &save, sizeof(save))==0); - - testIocShutdownOk(); - - testdbCleanup(); -} - -MAIN(arrayOpTest) -{ - testPlan(21); - testGetPutArray(); - return testDone(); -} diff --git a/src/std/rec/test/arrayOpTest.db b/src/std/rec/test/arrayOpTest.db deleted file mode 100644 index 1c011e755..000000000 --- a/src/std/rec/test/arrayOpTest.db +++ /dev/null @@ -1,9 +0,0 @@ -record(waveform, "wfrec") { - field(NELM, "10") - field(FTVL, "LONG") - field(INP, [1, 2, 3]) -} -record(waveform, "wfrec1") { - field(NELM, "1") - field(FTVL, "LONG") -} diff --git a/src/std/rec/test/asTest.c b/src/std/rec/test/asTest.c deleted file mode 100644 index 44ef66fd2..000000000 --- a/src/std/rec/test/asTest.c +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - * - * Test the hooks that autosave uses during initialization - */ - -#include "string.h" - -#include "epicsString.h" -#include "dbUnitTest.h" -#include "epicsThread.h" -#include "iocInit.h" -#include "dbBase.h" -#include "link.h" -#include "recSup.h" -#include "dbAccess.h" -#include "dbConvert.h" -#include "dbStaticLib.h" -#include "registry.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "osiFileName.h" -#include "initHooks.h" -#include "devSup.h" -#include "errlog.h" - -#include "aoRecord.h" -#include "waveformRecord.h" - -#include "testMain.h" - -epicsShareFunc void testRestore(void); - -#include "epicsExport.h" - -MAIN(asTest) -{ - testPlan(42); - testRestore(); - return testDone(); -} diff --git a/src/std/rec/test/asTest.db b/src/std/rec/test/asTest.db deleted file mode 100644 index 6a4eea4bd..000000000 --- a/src/std/rec/test/asTest.db +++ /dev/null @@ -1,12 +0,0 @@ -record(ao, "rec0") { - field(DESC, "foobar") - field(DTYP, "asTest") - field(VAL, "1") - field(OUT, "rec0.DISV") -} - -record(waveform, "rec1") { - field(DTYP, "asTest") - field(FTVL, "DOUBLE") - field(NELM, "5") -} diff --git a/src/std/rec/test/asTest.dbd b/src/std/rec/test/asTest.dbd deleted file mode 100644 index c53b52a8b..000000000 --- a/src/std/rec/test/asTest.dbd +++ /dev/null @@ -1,2 +0,0 @@ -device(ao, CONSTANT, devAOasTest, "asTest") -device(waveform, CONSTANT, devWFasTest, "asTest") diff --git a/src/std/rec/test/asTestLib.c b/src/std/rec/test/asTestLib.c deleted file mode 100644 index 18139233f..000000000 --- a/src/std/rec/test/asTestLib.c +++ /dev/null @@ -1,295 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Brookhaven Science Assoc. as operator of Brookhaven -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - * - * Test the hooks that autosave uses during initialization - */ - -#include "string.h" - -#include "epicsString.h" -#include "dbUnitTest.h" -#include "epicsThread.h" -#include "iocInit.h" -#include "dbBase.h" -#include "link.h" -#include "recSup.h" -#include "iocsh.h" -#include "dbAccess.h" -#include "dbConvert.h" -#include "dbStaticLib.h" -#include "registry.h" -#include "dbStaticLib.h" -#include "dbStaticPvt.h" -#include "osiFileName.h" -#include "initHooks.h" -#include "devSup.h" -#include "errlog.h" - -#include "aoRecord.h" -#include "waveformRecord.h" - -#include "epicsExport.h" - -static unsigned iran; - -static -int checkGetString(DBENTRY *pent, const char *expect) -{ - dbCommon *prec = pent->precnode->precord; - const char *actual = dbGetString(pent); - int ret = strcmp(actual, expect); - testOk(ret==0, "dbGetString(\"%s.%s\") -> '%s' == '%s'", prec->name, - pent->pflddes->name, actual, expect); - return ret; -} - -static void hookPass0(initHookState state) -{ - DBENTRY entry; - if(state!=initHookAfterInitDevSup) - return; - testDiag("initHookAfterInitDevSup"); - - dbInitEntry(pdbbase, &entry); - - testDiag("restore integer pass0"); - /* rec0.VAL is initially 1, set it to 2 */ - if(dbFindRecord(&entry, "rec0.VAL")==0) { - aoRecord *prec = entry.precnode->precord; - testOk(prec->val==1, "VAL %d==1 (initial value from .db)", (int)prec->val); - checkGetString(&entry, "1"); - testOk1(dbPutString(&entry, "2")==0); - testOk(prec->val==2, "VAL %d==2", (int)prec->val); - checkGetString(&entry, "2"); - } else { - testFail("Missing rec0"); - testSkip(4, "missing record"); - } - - testDiag("restore string pass0"); - if(dbFindRecord(&entry, "rec0.DESC")==0) { - aoRecord *prec = entry.precnode->precord; - testOk1(strcmp(prec->desc, "foobar")==0); - checkGetString(&entry, "foobar"); - testOk1(dbPutString(&entry, "hello")==0); - testOk1(strcmp(prec->desc, "hello")==0); - checkGetString(&entry, "hello"); - } else { - testFail("Missing rec0"); - testSkip(4, "missing record"); - } - - if(dbFindRecord(&entry, "rec1.DESC")==0) { - aoRecord *prec = entry.precnode->precord; - testOk1(strcmp(prec->desc, "")==0); - checkGetString(&entry, ""); - testOk1(dbPutString(&entry, "world")==0); - testOk1(strcmp(prec->desc, "world")==0); - checkGetString(&entry, "world"); - } else { - testFail("Missing rec1"); - testSkip(4, "missing record"); - } - - testDiag("restore link pass0"); - /* rec0.OUT is initially "rec0.DISV", set it to "rec0.SEVR" */ - if(dbFindRecord(&entry, "rec0.OUT")==0) { - aoRecord *prec = entry.precnode->precord; - if(prec->out.type==CONSTANT) - testOk(strcmp(prec->out.text,"rec0.DISV")==0, - "%s==rec0.DISV (initial value from .db)", - prec->out.text); - else - testFail("Wrong link type: %d", (int)prec->out.type); - - /* note that dbGetString() reads an empty string before links are initialized - * should probably be considered a bug, but has been the case for so long - * we call it a 'feature'. - */ - checkGetString(&entry, ""); - - testOk1(dbPutString(&entry, "rec0.SEVR")==0); - } else{ - testFail("Missing rec0"); - testSkip(1, "missing record"); - } - - /* rec0.SDIS is initially NULL, set it to "rec0.STAT" */ - if(dbFindRecord(&entry, "rec0.SDIS")==0) { - aoRecord *prec = entry.precnode->precord; - if(prec->sdis.type==CONSTANT) - testOk1(prec->sdis.value.constantStr==NULL); - else - testFail("Wrong link type: %d", (int)prec->sdis.type); - - testOk1(dbPutString(&entry, "rec0.STAT")==0); - } else{ - testFail("Missing rec0"); - testSkip(1, "missing record"); - } - - /* can't restore array field in pass0 */ - - dbFinishEntry(&entry); -} - -static long initRec0(aoRecord *prec) -{ - DBLINK *plink = &prec->out; - testDiag("init_record(%s)", prec->name); - testOk(prec->val==2, "VAL %d==2 (pass0 value)", (int)prec->val); - prec->val = 3; - testOk(prec->val==3, "VAL %d==3", (int)prec->val); - - testOk1(plink->type==DB_LINK); - if(plink->type==DB_LINK) - testOk(strcmp(plink->value.pv_link.pvname,"rec0.SEVR")==0, - "%s==rec0.SEVR (pass0 value)", plink->value.pv_link.pvname); - else - testFail("Wrong link type"); - - plink = &prec->sdis; - - testOk1(plink->type==DB_LINK); - if(plink->type==DB_LINK) - testOk(strcmp(plink->value.pv_link.pvname,"rec0.STAT")==0, - "%s==rec0.STAT (pass0 value)", plink->value.pv_link.pvname); - else - testFail("Wrong link type"); - - iran |= 1; - return 2; /* we set .VAL, so don't use RVAL */ -} - -static long initRec1(waveformRecord *prec) -{ - testDiag("init_record(%s)", prec->name); - testOk(prec->nord==0, "NORD %d==0", (int)prec->nord); - iran |= 2; - return 0; -} - -static double values[] = {1,2,3,4,5}; - -static void hookPass1(initHookState state) -{ - DBENTRY entry; - DBADDR addr; - if(state!=initHookAfterInitDatabase) - return; - testDiag("initHookAfterInitDatabase"); - - dbInitEntry(pdbbase, &entry); - - if(dbFindRecord(&entry, "rec0.VAL")==0) { - aoRecord *prec = entry.precnode->precord; - testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val); - testOk1(dbPutString(&entry, "4")==0); - testOk(prec->val==4, "VAL %d==4", (int)prec->val); - } else{ - testFail("Missing rec0"); - testSkip(1, "missing record"); - } - - /* Can't restore links in pass 1 */ - - if(dbNameToAddr("rec1.VAL", &addr)) { - testFail("missing rec1"); - testSkip(3, "missing record"); - } else { - rset *prset = dbGetRset(&addr); - dbfType ftype = addr.field_type; - long count=-1, offset=-1, maxcount = addr.no_elements; - testOk1(prset && prset->get_array_info && prset->put_array_info); - testOk1((*prset->get_array_info)(&addr, &count, &offset)==0); - /* count is ignored */ - testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0); - testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0); - } - - dbFinishEntry(&entry); -} - -#if defined(__rtems__) || defined(vxWorks) -void asTestIoc_registerRecordDeviceDriver(struct dbBase *); -#endif - -epicsShareFunc -void testRestore(void) -{ - aoRecord *rec0; - waveformRecord *rec1; - testDiag("test Restore"); - - initHookRegister(hookPass0); - initHookRegister(hookPass1); - - testdbPrepare(); - - testdbReadDatabase("asTestIoc.dbd", NULL, NULL); - - /* since this test has device support it must appear in a - * DLL for windows dynamic builds. - * However, the rRDD function is in the executable, - * and not accessible here. So use iocsh. - * For rtems/vxworks the test harness clears - * iocsh registrations, so iocsh can't work here. - */ -#if defined(__rtems__) || defined(vxWorks) - asTestIoc_registerRecordDeviceDriver(pdbbase); -#else - iocshCmd("asTestIoc_registerRecordDeviceDriver(pdbbase)"); -#endif - - testdbReadDatabase("asTest.db", NULL, NULL); - - rec0 = (aoRecord*)testdbRecordPtr("rec0"); - rec1 = (waveformRecord*)testdbRecordPtr("rec1"); - - eltc(0); - testIocInitOk(); - eltc(1); - - testDiag("Post initialization"); - - testOk1(iran==3); - - testOk1(rec0->val==4); - testOk1(rec1->nord==5); - { - double *buf = rec1->bptr; - testOk(buf[0]==1, "buf[0] %f==1", buf[0]); - testOk1(buf[1]==2); - testOk1(buf[2]==3); - testOk1(buf[3]==4); - testOk1(buf[4]==5); - } - - testIocShutdownOk(); - - /* recSup doesn't cleanup after itself */ - free(rec1->bptr); - - testdbCleanup(); -} - -struct dset6 { - dset common; - DEVSUPFUN proc; - DEVSUPFUN linconv; -}; - -static long noop() {return 0;} - -static struct dset6 devAOasTest = { {6, NULL, NULL, (DEVSUPFUN)initRec0, NULL}, (DEVSUPFUN)noop, NULL}; -static struct dset6 devWFasTest = { {6, NULL, NULL, (DEVSUPFUN)initRec1, NULL}, (DEVSUPFUN)noop, NULL}; - -epicsExportAddress(dset, devAOasTest); -epicsExportAddress(dset, devWFasTest); diff --git a/src/std/rec/test/asyncSoftTest.c b/src/std/rec/test/asyncSoftTest.c deleted file mode 100644 index 7b494a349..000000000 --- a/src/std/rec/test/asyncSoftTest.c +++ /dev/null @@ -1,189 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2017 UChicago Argonne LLC, as operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "dbAccess.h" -#include "dbStaticLib.h" -#include "dbTest.h" -#include "dbUnitTest.h" -#include "epicsEvent.h" -#include "errlog.h" -#include "registryFunction.h" -#include "subRecord.h" -#include "testMain.h" - -static int startCounter, doneCounter; -static epicsEventId asyncEvent, doneEvent; - -static -long asyncSubr(subRecord *prec) -{ - testDiag("Processing %s, pact=%d", prec->name, prec->pact); - - if (!prec->pact) { - epicsEventTrigger(asyncEvent); - prec->pact = 1; /* Make asynchronous */ - } - - return 0; -} - -static -long doneSubr(subRecord *prec) -{ - epicsEventTrigger(doneEvent); - return 0; -} - -static -void checkAsyncInput(const char *rec, int init, dbCommon *async) -{ - char inp[16], proc[16]; - - testDiag("Checking record '%s'", rec); - - strcpy(inp, rec); - strcat(inp, ".INP"); - strcpy(proc, rec); - strcat(proc, ".PROC"); - - if (init) { - testdbGetFieldEqual(rec, DBF_LONG, init); - - testdbPutFieldOk(inp, DBF_STRING, "async"); - } - - testdbPutFieldOk(proc, DBF_CHAR, 1); - - epicsEventWait(asyncEvent); - testdbGetFieldEqual("startCounter", DBF_LONG, ++startCounter); - testdbGetFieldEqual("doneCounter", DBF_LONG, doneCounter); - - dbScanLock(async); - async->rset->process(async); - dbScanUnlock(async); - - epicsEventWait(doneEvent); - testdbGetFieldEqual("startCounter", DBF_LONG, startCounter); - testdbGetFieldEqual("doneCounter", DBF_LONG, ++doneCounter); -} - -static -void testAsynInputs(dbCommon *async) -{ - const char * records[] = { - "ai0", "bi0", "di0", "ii0", "li0", "mi0", "si0", NULL, - "bi1", /* bi1 must be first in this group */ - "ai1", "di1", "ii1", "li1", "mi1", "si1", NULL, - }; - const char ** rec = &records[0]; - int init = 1; /* bi1 initializes to 1 */ - - testDiag("============ Starting %s ============", EPICS_FUNCTION); - - startCounter = doneCounter = 0; - testdbPutFieldOk("startCounter", DBF_LONG, startCounter); - testdbPutFieldOk("doneCounter", DBF_LONG, doneCounter); - - epicsEventTryWait(asyncEvent); - epicsEventTryWait(doneEvent); - - while (*rec) { /* 1st group don't need initializing */ - checkAsyncInput(*rec++, 0, async); - } - rec++; - while (*rec) { - checkAsyncInput(*rec++, init, async); - init = 9; /* remainder initialize to 9 */ - } - - testDiag("============= Ending %s =============", EPICS_FUNCTION); -} - -static -void checkAsyncOutput(const char *rec, dbCommon *async) -{ - char proc[16]; - - testDiag("Checking record '%s'", rec); - - strcpy(proc, rec); - strcat(proc, ".PROC"); - - testdbPutFieldOk(proc, DBF_CHAR, 1); - - epicsEventWait(asyncEvent); - testdbGetFieldEqual("startCounter", DBF_LONG, ++startCounter); - testdbGetFieldEqual("doneCounter", DBF_LONG, doneCounter); - - dbScanLock(async); - async->rset->process(async); - dbScanUnlock(async); - - epicsEventWait(doneEvent); - testdbGetFieldEqual("startCounter", DBF_LONG, startCounter); - testdbGetFieldEqual("doneCounter", DBF_LONG, ++doneCounter); -} - -static -void testAsyncOutputs(dbCommon *async) -{ - const char * records[] = { - "ao1", "bo1", "do1", "io1", "lo1", "lso1", "mo1", "so1", NULL, - }; - const char ** rec = &records[0]; - - testDiag("============ Starting %s ============", EPICS_FUNCTION); - - startCounter = doneCounter = 0; - testdbPutFieldOk("startCounter", DBF_LONG, startCounter); - testdbPutFieldOk("doneCounter", DBF_LONG, doneCounter); - - epicsEventTryWait(asyncEvent); - epicsEventTryWait(doneEvent); - - while (*rec) { - checkAsyncOutput(*rec++, async); - } - - testDiag("============= Ending %s =============", EPICS_FUNCTION); -} - -void recTestIoc_registerRecordDeviceDriver(struct dbBase *); - -MAIN(asyncSoftTest) -{ - dbCommon *async; - - testPlan(128); - - testdbPrepare(); - testdbReadDatabase("recTestIoc.dbd", NULL, NULL); - - recTestIoc_registerRecordDeviceDriver(pdbbase); - registryFunctionAdd("asyncSubr", (REGISTRYFUNCTION) asyncSubr); - registryFunctionAdd("doneSubr", (REGISTRYFUNCTION) doneSubr); - - testdbReadDatabase("asyncSoftTest.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - - async = testdbRecordPtr("async"); - asyncEvent = epicsEventCreate(epicsEventEmpty); - doneEvent = epicsEventCreate(epicsEventEmpty); - - testAsynInputs(async); - testAsyncOutputs(async); - - testIocShutdownOk(); - testdbCleanup(); - - return testDone(); -} diff --git a/src/std/rec/test/asyncSoftTest.db b/src/std/rec/test/asyncSoftTest.db deleted file mode 100644 index 6cb51422b..000000000 --- a/src/std/rec/test/asyncSoftTest.db +++ /dev/null @@ -1,188 +0,0 @@ -record(ai, "ai0") { - field(DTYP, "Async Soft Channel") - field(INP, "async") - field(FLNK, "done") -} -record(bi, "bi0") { - field(DTYP, "Async Soft Channel") - field(INP, "async") - field(FLNK, "done") - field(ZNAM, "Zero") - field(ONAM, "One") -} -record(int64in, "ii0") { - field(DTYP, "Async Soft Channel") - field(INP, "async") - field(FLNK, "done") -} -record(longin, "li0") { - field(DTYP, "Async Soft Channel") - field(INP, "async") - field(FLNK, "done") -} -record(mbbiDirect, "di0") { - field(DTYP, "Async Soft Channel") - field(NOBT, 4) - field(INP, "async") - field(FLNK, "done") -} -record(mbbi, "mi0") { - field(DTYP, "Async Soft Channel") - field(NOBT, 4) - field(INP, "async") - field(FLNK, "done") - field(ZRST, "Zero") - field(ONST, "One") - field(TWST, "Two") - field(THST, "Three") - field(FRST, "Four") - field(FVST, "Five") - field(SXST, "Six") - field(SVST, "Seven") - field(EIST, "Eight") - field(NIST, "Nine") - field(TEST, "Ten") - field(ELST, "Eleven") - field(TWST, "Twelve") - field(TTST, "Thirteen") - field(FTST, "Fourteen") - field(FFST, "Fifteen") -} -record(stringin, "si0") { - field(DTYP, "Async Soft Channel") - field(INP, "async") - field(FLNK, "done") -} - -record(ai, "ai1") { - field(DTYP, "Async Soft Channel") - field(INP, {const:9}) - field(FLNK, "done") -} -record(bi, "bi1") { - field(DTYP, "Async Soft Channel") - field(INP, {const:1}) - field(FLNK, "done") - field(ZNAM, "Zero") - field(ONAM, "One") -} -record(int64in, "ii1") { - field(DTYP, "Async Soft Channel") - field(INP, {const:9}) - field(FLNK, "done") -} -record(longin, "li1") { - field(DTYP, "Async Soft Channel") - field(INP, {const:9}) - field(FLNK, "done") -} -record(mbbiDirect, "di1") { - field(DTYP, "Async Soft Channel") - field(NOBT, 4) - field(INP, {const:9}) - field(FLNK, "done") -} -record(mbbi, "mi1") { - field(DTYP, "Async Soft Channel") - field(NOBT, 4) - field(INP, {const:9}) - field(FLNK, "done") - field(ZRST, "Zero") - field(ONST, "One") - field(TWST, "Two") - field(THST, "Three") - field(FRST, "Four") - field(FVST, "Five") - field(SXST, "Six") - field(SVST, "Seven") - field(EIST, "Eight") - field(NIST, "Nine") - field(TEST, "Ten") - field(ELST, "Eleven") - field(TWST, "Twelve") - field(TTST, "Thirteen") - field(FTST, "Fourteen") - field(FFST, "Fifteen") -} -record(stringin, "si1") { - field(DTYP, "Async Soft Channel") - field(INP, {const:"9"}) - field(FLNK, "done") -} - -record(sub, "async") { - field(INPA, "startCounter PP") - field(SNAM, "asyncSubr") -} -record(calc, "startCounter") { - field(CALC, "VAL+1") -} -record(sub, "done") { - field(INPA, "doneCounter PP") - field(SNAM, "doneSubr") -} -record(calc, "doneCounter") { - field(CALC, "VAL+1") -} - -record(ao, "ao1") { - field(DTYP, "Async Soft Channel") - field(OUT, "async.PROC CA") - field(FLNK, "done") -} -record(bo, "bo1") { - field(DTYP, "Async Soft Channel") - field(OUT, "async.PROC CA") - field(FLNK, "done") - field(ZNAM, "Zero") - field(ONAM, "One") -} -record(int64out, "io1") { - field(DTYP, "Async Soft Channel") - field(OUT, "async.PROC CA") - field(FLNK, "done") -} -record(longout, "lo1") { - field(DTYP, "Async Soft Channel") - field(OUT, "async.PROC CA") - field(FLNK, "done") -} -record(mbboDirect, "do1") { - field(DTYP, "Async Soft Channel") - field(NOBT, 4) - field(OUT, "async.PROC CA") - field(FLNK, "done") -} -record(mbbo, "mo1") { - field(DTYP, "Async Soft Channel") - field(NOBT, 4) - field(OUT, "async.PROC CA") - field(FLNK, "done") - field(ZRST, "Zero") - field(ONST, "One") - field(TWST, "Two") - field(THST, "Three") - field(FRST, "Four") - field(FVST, "Five") - field(SXST, "Six") - field(SVST, "Seven") - field(EIST, "Eight") - field(NIST, "Nine") - field(TEST, "Ten") - field(ELST, "Eleven") - field(TWST, "Twelve") - field(TTST, "Thirteen") - field(FTST, "Fourteen") - field(FFST, "Fifteen") -} -record(lso, "lso1") { - field(DTYP, "Async Soft Channel") - field(OUT, "async.PROC CA") - field(FLNK, "done") - field(SIZV, 40) -} -record(stringout, "so1") { - field(DTYP, "Async Soft Channel") - field(OUT, "async.PROC CA") - field(FLNK, "done") -} diff --git a/src/std/rec/test/compressTest.c b/src/std/rec/test/compressTest.c deleted file mode 100644 index 99a937115..000000000 --- a/src/std/rec/test/compressTest.c +++ /dev/null @@ -1,354 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include "dbUnitTest.h" -#include "testMain.h" -#include "dbLock.h" -#include "errlog.h" -#include "dbAccess.h" -#include "epicsMath.h" - -#include "aiRecord.h" -#include "compressRecord.h" - -#define testDEq(A,B,D) testOk(fabs((A)-(B))<(D), #A " (%f) ~= " #B " (%f)", A, B) - -void recTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static -void checkArrD(const char *pv, long elen, double a, double b, double c, double d) -{ - double buf[4]; - double expect[4]; - long nReq = NELEMENTS(buf), i; - unsigned match; - DBADDR addr; - - expect[0] = a; - expect[1] = b; - expect[2] = c; - expect[3] = d; - - if (dbNameToAddr(pv, &addr)) - testAbort("Unknown PV '%s'", pv); - - if (dbGet(&addr, DBR_DOUBLE, buf, NULL, &nReq, NULL)) - testAbort("Failed to get '%s'", pv); - - match = elen==nReq; - for (i=0; i=0.01) - testDiag("[%ld] -> %f != %f", i, expect[i], buf[i]); - } -} - -static -void checkArrI(const char *pv, long elen, epicsInt32 a, epicsInt32 b, epicsInt32 c, epicsInt32 d) -{ - epicsInt32 buf[4]; - epicsInt32 expect[4]; - long nReq = NELEMENTS(buf), i; - unsigned match; - DBADDR addr; - - expect[0] = a; - expect[1] = b; - expect[2] = c; - expect[3] = d; - - if (dbNameToAddr(pv, &addr)) - testAbort("Unknown PV '%s'", pv); - - if (dbGet(&addr, DBR_LONG, buf, NULL, &nReq, NULL)) - testAbort("Failed to get '%s'", pv); - - match = elen==nReq; - for (i=0; i %d != %d", i, (int)expect[i], (int)buf[i]); - } -} - -static -void testFIFOCirc(void) -{ - aiRecord *vrec; - compressRecord *crec; - double *cbuf; - - testDiag("Test FIFO"); - - testdbPrepare(); - - testdbReadDatabase("recTestIoc.dbd", NULL, NULL); - - recTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("compressTest.db", NULL, "ALG=Circular Buffer,BALG=FIFO Buffer,NSAM=4"); - - vrec = (aiRecord*)testdbRecordPtr("val"); - crec = (compressRecord*)testdbRecordPtr("comp"); - - eltc(0); - testIocInitOk(); - eltc(1); - - dbScanLock((dbCommon*)crec); - cbuf = crec->bptr; - - testOk1(crec->off==0); - testOk1(crec->inx==0); - testOk1(crec->nuse==0); - - testDiag("Push 1.1"); - vrec->val = 1.1; - dbProcess((dbCommon*)crec); - - /* In FIFO mode the valid elements are - * cbuf[(off-nuse-1) % size] through cbuf[(off-1) % size] - */ - testOk1(crec->off==1); - testOk1(crec->inx==0); - testOk1(crec->nuse==1); - testDEq(cbuf[0], 1.1, 0.1); - testDEq(cbuf[1], 0.0, 0.1); - testDEq(cbuf[2], 0.0, 0.1); - testDEq(cbuf[3], 0.0, 0.1); - checkArrD("comp", 1, 1.1, 0, 0, 0); - - testDiag("Push 2.1"); - vrec->val = 2.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==2); - testOk1(crec->inx==0); - testOk1(crec->nuse==2); - testDEq(cbuf[0], 1.1, 0.1); - testDEq(cbuf[1], 2.1, 0.1); - testDEq(cbuf[2], 0.0, 0.1); - testDEq(cbuf[3], 0.0, 0.1); - checkArrD("comp", 2, 1.1, 2.1, 0, 0); - - testDiag("Push 3.1"); - vrec->val = 3.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==3); - testOk1(crec->inx==0); - testOk1(crec->nuse==3); - testDEq(cbuf[0], 1.1, 0.1); - testDEq(cbuf[1], 2.1, 0.1); - testDEq(cbuf[2], 3.1, 0.1); - testDEq(cbuf[3], 0.0, 0.1); - checkArrD("comp", 3, 1.1, 2.1, 3.1, 0); - - testDiag("Push 4.1"); - vrec->val = 4.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==0); - testOk1(crec->inx==0); - testOk1(crec->nuse==4); - testDEq(cbuf[0], 1.1, 0.1); - testDEq(cbuf[1], 2.1, 0.1); - testDEq(cbuf[2], 3.1, 0.1); - testDEq(cbuf[3], 4.1, 0.1); - checkArrD("comp", 4, 1.1, 2.1, 3.1, 4.1); - - testDiag("Push 5.1"); - vrec->val = 5.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==1); - testOk1(crec->inx==0); - testOk1(crec->nuse==4); - testDEq(cbuf[0], 5.1, 0.1); - testDEq(cbuf[1], 2.1, 0.1); - testDEq(cbuf[2], 3.1, 0.1); - testDEq(cbuf[3], 4.1, 0.1); - checkArrD("comp", 4, 2.1, 3.1, 4.1, 5.1); - - testDiag("Push 6.1"); - vrec->val = 6.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==2); - testOk1(crec->inx==0); - testOk1(crec->nuse==4); - testDEq(cbuf[0], 5.1, 0.1); - testDEq(cbuf[1], 6.1, 0.1); - testDEq(cbuf[2], 3.1, 0.1); - testDEq(cbuf[3], 4.1, 0.1); - checkArrD("comp", 4, 3.1, 4.1, 5.1, 6.1); - - dbScanUnlock((dbCommon*)crec); - - testDiag("Reset"); - testdbPutFieldOk("comp.RES", DBF_LONG, 0); - - dbScanLock((dbCommon*)crec); - testOk1(crec->off==0); - testOk1(crec->inx==0); - testOk1(crec->nuse==0); - checkArrD("comp", 0, 0, 0, 0, 0); - dbScanUnlock((dbCommon*)crec); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static -void testLIFOCirc(void) -{ - aiRecord *vrec; - compressRecord *crec; - double *cbuf; - - testDiag("Test LIFO"); - - testdbPrepare(); - - testdbReadDatabase("recTestIoc.dbd", NULL, NULL); - - recTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("compressTest.db", NULL, - "ALG=Circular Buffer,BALG=LIFO Buffer,NSAM=4"); - - vrec = (aiRecord*)testdbRecordPtr("val"); - crec = (compressRecord*)testdbRecordPtr("comp"); - - eltc(0); - testIocInitOk(); - eltc(1); - - dbScanLock((dbCommon*)crec); - cbuf = crec->bptr; - - testOk1(crec->off==0); - testOk1(crec->inx==0); - testOk1(crec->nuse==0); - - testDiag("Push 1.1"); - vrec->val = 1.1; - dbProcess((dbCommon*)crec); - - testDiag("off %u", crec->off); - testOk1(crec->off==3); - testOk1(crec->inx==0); - testOk1(crec->nuse==1); - testDEq(cbuf[0], 0.0, 0.1); - testDEq(cbuf[1], 0.0, 0.1); - testDEq(cbuf[2], 0.0, 0.1); - testDEq(cbuf[3], 1.1, 0.1); - checkArrD("comp", 1, 1.1, 0, 0, 0); - - testDiag("Push 2.1"); - vrec->val = 2.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==2); - testOk1(crec->inx==0); - testOk1(crec->nuse==2); - testDEq(cbuf[0], 0.0, 0.1); - testDEq(cbuf[1], 0.0, 0.1); - testDEq(cbuf[2], 2.1, 0.1); - testDEq(cbuf[3], 1.1, 0.1); - checkArrD("comp", 2, 2.1, 1.1, 0, 0); - checkArrI("comp", 2, 2, 1, 0, 0); - - testDiag("Push 3.1"); - vrec->val = 3.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==1); - testOk1(crec->inx==0); - testOk1(crec->nuse==3); - testDEq(cbuf[0], 0.0, 0.1); - testDEq(cbuf[1], 3.1, 0.1); - testDEq(cbuf[2], 2.1, 0.1); - testDEq(cbuf[3], 1.1, 0.1); - checkArrD("comp", 3, 3.1, 2.1, 1.1, 0); - checkArrI("comp", 3, 3, 2, 1, 0); - - testDiag("Push 4.1"); - vrec->val = 4.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==0); - testOk1(crec->inx==0); - testOk1(crec->nuse==4); - testDEq(cbuf[0], 4.1, 0.1); - testDEq(cbuf[1], 3.1, 0.1); - testDEq(cbuf[2], 2.1, 0.1); - testDEq(cbuf[3], 1.1, 0.1); - checkArrD("comp", 4, 4.1, 3.1, 2.1, 1.1); - checkArrI("comp", 4, 4, 3, 2, 1); - - testDiag("Push 5.1"); - vrec->val = 5.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==3); - testOk1(crec->inx==0); - testOk1(crec->nuse==4); - testDEq(cbuf[0], 4.1, 0.1); - testDEq(cbuf[1], 3.1, 0.1); - testDEq(cbuf[2], 2.1, 0.1); - testDEq(cbuf[3], 5.1, 0.1); - checkArrD("comp", 4, 5.1, 4.1, 3.1, 2.1); - checkArrI("comp", 4, 5, 4, 3, 2); - - testDiag("Push 6.1"); - vrec->val = 6.1; - dbProcess((dbCommon*)crec); - - testOk1(crec->off==2); - testOk1(crec->inx==0); - testOk1(crec->nuse==4); - testDEq(cbuf[0], 4.1, 0.1); - testDEq(cbuf[1], 3.1, 0.1); - testDEq(cbuf[2], 6.1, 0.1); - testDEq(cbuf[3], 5.1, 0.1); - checkArrD("comp", 4, 6.1, 5.1, 4.1, 3.1); - - dbScanUnlock((dbCommon*)crec); - - testDiag("Reset"); - testdbPutFieldOk("comp.RES", DBF_LONG, 0); - - dbScanLock((dbCommon*)crec); - testOk1(crec->off==0); - testOk1(crec->inx==0); - testOk1(crec->nuse==0); - checkArrD("comp", 0, 0, 0, 0, 0); - dbScanUnlock((dbCommon*)crec); - - testIocShutdownOk(); - - testdbCleanup(); -} - -MAIN(compressTest) -{ - testPlan(116); - testFIFOCirc(); - testLIFOCirc(); - return testDone(); -} diff --git a/src/std/rec/test/compressTest.db b/src/std/rec/test/compressTest.db deleted file mode 100644 index 59fc620ba..000000000 --- a/src/std/rec/test/compressTest.db +++ /dev/null @@ -1,7 +0,0 @@ -record(ai, "val") {} -record(compress, "comp") { - field(INP, "val NPP") - field(ALG, "$(ALG)") - field(BALG,"$(BALG)") - field(NSAM,"$(NSAM)") -} diff --git a/src/std/rec/test/epicsRunRecordTests.c b/src/std/rec/test/epicsRunRecordTests.c deleted file mode 100644 index 8c551c1ab..000000000 --- a/src/std/rec/test/epicsRunRecordTests.c +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Run tests as a batch. - */ - -#include "epicsUnitTest.h" -#include "epicsExit.h" - -int analogMonitorTest(void); -int compressTest(void); -int recMiscTest(void); -int arrayOpTest(void); -int asTest(void); -int linkRetargetLinkTest(void); -int linkInitTest(void); -int asyncSoftTest(void); - -void epicsRunRecordTests(void) -{ - testHarness(); - - runTest(analogMonitorTest); - - runTest(compressTest); - - runTest(recMiscTest); - - runTest(arrayOpTest); - - runTest(asTest); - - runTest(linkRetargetLinkTest); - - runTest(linkInitTest); - - runTest(asyncSoftTest); - - epicsExit(0); /* Trigger test harness */ -} diff --git a/src/std/rec/test/linkInitTest.c b/src/std/rec/test/linkInitTest.c deleted file mode 100644 index cf279b5aa..000000000 --- a/src/std/rec/test/linkInitTest.c +++ /dev/null @@ -1,225 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "dbAccess.h" -#include "alarm.h" -#include "dbUnitTest.h" -#include "errlog.h" -#include "epicsThread.h" - -#include "testMain.h" - -void recTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static void startTestIoc(const char *dbfile) -{ - testdbPrepare(); - testdbReadDatabase("recTestIoc.dbd", NULL, NULL); - recTestIoc_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase(dbfile, NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); -} - -static void testLongStringInit() -{ - testDiag("testLongStringInit"); - - startTestIoc("linkInitTest.db"); - - { - const char buf[] = "!----------------------------------------------!"; - testdbGetArrFieldEqual("longstr1.VAL$", DBF_CHAR, NELEMENTS(buf)+2, NELEMENTS(buf), buf); - testdbGetFieldEqual("longstr1.VAL", DBR_STRING, "!--------------------------------------"); - } - - { - const char buf[] = "!----------------------------------------------!"; - testdbGetArrFieldEqual("longstr2.VAL$", DBF_CHAR, NELEMENTS(buf)+2, NELEMENTS(buf), buf); - testdbGetFieldEqual("longstr2.VAL", DBR_STRING, "!--------------------------------------"); - } - - { - const char buf[] = "!----------------------------------------------!"; - testdbGetArrFieldEqual("longstr3.VAL$", DBF_CHAR, NELEMENTS(buf)+2, NELEMENTS(buf), buf); - testdbGetFieldEqual("longstr3.VAL", DBR_STRING, "!--------------------------------------"); - } - - testdbGetFieldEqual("longstr4.VAL", DBR_STRING, "One"); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testCalcInit() -{ - testDiag("testCalcInit"); - - startTestIoc("linkInitTest.db"); - - testdbGetFieldEqual("emptylink.VAL", DBR_DOUBLE, 0.0); - testdbGetFieldEqual("emptylink.SEVR", DBR_LONG, INVALID_ALARM); - - testdbPutFieldOk("emptylink.PROC", DBF_LONG, 1); - - testdbGetFieldEqual("emptylink.VAL", DBR_DOUBLE, 0.0); - testdbGetFieldEqual("emptylink.SEVR", DBR_LONG, 0); - - testdbGetFieldEqual("emptylink1.VAL", DBR_DOUBLE, 0.0); - testdbGetFieldEqual("emptylink1.SEVR", DBR_LONG, INVALID_ALARM); - - testdbPutFieldOk("emptylink1.PROC", DBF_LONG, 1); - - testdbGetFieldEqual("emptylink1.VAL", DBR_DOUBLE, 1.0); - testdbGetFieldEqual("emptylink1.SEVR", DBR_LONG, 0); - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testPrintfStrings() -{ - testDiag("testPrintfStrings"); - - startTestIoc("linkInitTest.db"); - - { - const char buf1[] = "Test string, exactly 40 characters long"; - const char buf2[] = "Longer test string, more that 40 characters long"; - const char buf2t[] = "Longer test string, more that 40 charac"; - - /* The FMT field is pp(TRUE), so this put triggers processing */ - testdbPutFieldOk("printf1.FMT", DBF_STRING, "%s"); - testdbGetArrFieldEqual("printf1.VAL$", DBF_CHAR, NELEMENTS(buf1)+2, - NELEMENTS(buf1), buf1); - testdbGetFieldEqual("printf1.VAL", DBR_STRING, buf1); - - testdbPutFieldOk("printf1.FMT", DBF_STRING, "%ls"); - testdbGetArrFieldEqual("printf1.VAL$", DBF_CHAR, NELEMENTS(buf1)+2, - NELEMENTS(buf1), buf1); - testdbGetFieldEqual("printf1.VAL", DBR_STRING, buf1); - - testdbPutFieldOk("printf2.FMT", DBF_STRING, "%s"); - testdbGetArrFieldEqual("printf2.VAL$", DBF_CHAR, NELEMENTS(buf2)+2, - NELEMENTS(buf2t), buf2t); - testdbGetFieldEqual("printf2.VAL", DBR_STRING, buf2t); - - testdbPutFieldOk("printf2.FMT", DBF_STRING, "%ls"); - testdbGetArrFieldEqual("printf2.VAL$", DBF_CHAR, NELEMENTS(buf2)+2, - NELEMENTS(buf2), buf2); - testdbGetFieldEqual("printf2.VAL", DBR_STRING, buf2t); - - testdbPutFieldOk("printf2.FMT", DBF_STRING, "%.39ls"); - testdbGetArrFieldEqual("printf2.VAL$", DBF_CHAR, NELEMENTS(buf2)+2, - NELEMENTS(buf2t), buf2t); - } - - testIocShutdownOk(); - - testdbCleanup(); -} - -static void testArrayInputs() -{ - epicsInt32 oneToTwelve[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - - testDiag("testArrayInputs"); - - startTestIoc("linkInitTest.db"); - - testdbGetFieldEqual("aai1.NORD", DBR_LONG, 10); - testdbGetFieldEqual("aai1.UDF", DBR_UCHAR, 0); - testdbGetFieldEqual("aai2.NORD", DBR_LONG, 10); - testdbGetFieldEqual("aai2.UDF", DBR_UCHAR, 0); - testdbGetFieldEqual("sa1.NORD", DBR_LONG, 10); - testdbGetFieldEqual("sa1.UDF", DBR_UCHAR, 0); - testdbGetFieldEqual("sa2.NORD", DBR_LONG, 0); - testdbGetFieldEqual("sa2.UDF", DBR_UCHAR, 1); - testdbGetFieldEqual("wf1.NORD", DBR_LONG, 10); - testdbGetFieldEqual("wf1.UDF", DBR_UCHAR, 0); - testdbGetFieldEqual("wf2.NORD", DBR_LONG, 10); - testdbGetFieldEqual("wf2.UDF", DBR_UCHAR, 0); - - testdbGetArrFieldEqual("aai1.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]); - testdbGetArrFieldEqual("aai2.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]); - testdbGetArrFieldEqual("sa1.VAL", DBF_LONG, 12, 10, &oneToTwelve[2]); - testdbGetArrFieldEqual("sa2.VAL", DBF_LONG, 10, 0, NULL); - testdbGetArrFieldEqual("wf1.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]); - testdbGetArrFieldEqual("wf2.VAL", DBF_LONG, 12, 10, &oneToTwelve[0]); - - testdbPutFieldOk("sa1.INDX", DBF_LONG, 3); - testdbGetArrFieldEqual("sa1.VAL", DBF_LONG, 12, 9, &oneToTwelve[3]); - - testdbPutFieldOk("sa1.NELM", DBF_LONG, 3); - testdbGetArrFieldEqual("sa1.VAL", DBF_LONG, 12, 3, &oneToTwelve[3]); - - testdbPutFieldOk("sa2.VAL", DBF_LONG, 1); - testdbGetArrFieldEqual("sa2.VAL", DBF_LONG, 10, 1, &oneToTwelve[0]); - - testDiag("testScalarInputs"); - - testdbGetFieldEqual("li1", DBR_LONG, 1); - testdbGetFieldEqual("i64i1", DBR_INT64, 1LL); - testdbGetFieldEqual("li2", DBR_LONG, 1); - testdbGetFieldEqual("i64i2", DBR_INT64, 1LL); - - testIocShutdownOk(); - testdbCleanup(); -} - -static void testEventRecord() -{ - testMonitor *countmon; - - testDiag("testEventRecord"); - - startTestIoc("linkInitTest.db"); - countmon = testMonitorCreate("count1.VAL", DBR_LONG, 0); - - testdbGetFieldEqual("ev1.VAL", DBR_STRING, "soft event 1"); - testdbGetFieldEqual("ev1.UDF", DBR_UCHAR, 0); - testdbGetFieldEqual("ev2.VAL", DBR_STRING, ""); - testdbGetFieldEqual("ev2.UDF", DBR_UCHAR, 1); - testdbGetFieldEqual("count1.VAL", DBR_LONG, 0); - - testdbPutFieldOk("ev1.PROC", DBF_UCHAR, 1); - testMonitorWait(countmon); - testdbGetFieldEqual("count1.VAL", DBR_LONG, 1); - - testdbPutFieldOk("ev2.PROC", DBF_UCHAR, 1); - testMonitorWait(countmon); - testdbGetFieldEqual("ev2.UDF", DBR_UCHAR, 0); - testdbGetFieldEqual("count1.VAL", DBR_LONG, 2); - - testdbPutFieldOk("count1.EVNT", DBF_STRING, "Tock"); - testdbPutFieldOk("ev2.PROC", DBF_UCHAR, 1); - testMonitorWait(countmon); - testdbGetFieldEqual("count1.VAL", DBR_LONG, 3); - - testMonitorDestroy(countmon); - testIocShutdownOk(); - testdbCleanup(); -} - - -MAIN(linkInitTest) -{ - testPlan(72); - - testLongStringInit(); - testCalcInit(); - testPrintfStrings(); - testArrayInputs(); - testEventRecord(); - - return testDone(); -} diff --git a/src/std/rec/test/linkInitTest.db b/src/std/rec/test/linkInitTest.db deleted file mode 100644 index 701490073..000000000 --- a/src/std/rec/test/linkInitTest.db +++ /dev/null @@ -1,90 +0,0 @@ -record(lsi, "longstr1") { - field(SIZV, "100") - field(INP, ["!----------------------------------------------!"]) -} -record(lsi, "longstr2") { - field(SIZV, "100") - field(INP, {const: ["!----------------------------------------------!"]}) -} -record(lsi, "longstr3") { - field(SIZV, "100") - field(INP, {const: "!----------------------------------------------!"}) -} -record(lsi, "longstr4") { - field(SIZV, "100") - field(INP, ["One","Two","Three","Four"]) -} - -record(ai, "emptylink" ) { - field(INP, {calc: {expr:"0"}}) -} -record(ai, "emptylink1" ) { - field(INP, {calc: {expr:"1"}}) -} - -record(printf, "printf1") { - field(SIZV, "100") - field(INP0, ["Test string, exactly 40 characters long"]) -} -record(printf, "printf2") { - field(SIZV, "100") - field(INP0, ["Longer test string, more that 40 characters long"]) -} - -record(aai, "aai1") { - field(NELM, 10) - field(FTVL, "LONG") - field(INP, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) -} -record(aai, "aai2") { - field(NELM, 10) - field(FTVL, "LONG") - field(INP, {const:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}) -} -record(subArray, "sa1") { - field(FTVL, "LONG") - field(MALM, 12) - field(INP, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) - field(INDX, 2) - field(NELM, 10) -} -record(subArray, "sa2") { - field(FTVL, "LONG") - field(MALM, 10) - field(NELM, 1) -} -record(waveform, "wf1") { - field(NELM, 10) - field(FTVL, "LONG") - field(INP, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]) -} -record(waveform, "wf2") { - field(NELM, 10) - field(FTVL, "LONG") - field(INP, {const:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}) -} - -record(longin, "li1") { - field(INP, 1) -} -record(int64in, "i64i1") { - field(INP, 1) -} -record(longin, "li2") { - field(INP, {const:1}) -} -record(int64in, "i64i2") { - field(INP, {const:1}) -} - -record(longin, "count1" ) { - field(INP, {calc: {expr:"VAL+1"}}) - field(SCAN, "Event") - field(EVNT, "soft event 1") -} -record(event, "ev1") { - field(INP, ["soft event 1"]) -} -record(event, "ev2") { - field(INP, "count1.EVNT") -} diff --git a/src/std/rec/test/linkRetargetLink.db b/src/std/rec/test/linkRetargetLink.db deleted file mode 100644 index 148e2d50b..000000000 --- a/src/std/rec/test/linkRetargetLink.db +++ /dev/null @@ -1,25 +0,0 @@ -record(ai, "rec:ai") { - field(INP, "0") -} -record(ai, "rec:src1") { - field(VAL, "1") -} -record(ai, "rec:src2") { - field(VAL, "2") -} -record(stringout, "rec:link1") { - field(VAL, "rec:src1") - field(OUT, "rec:ai.INP CA") -} -record(stringout, "rec:link2") { - field(VAL, "rec:src2 CP") - field(OUT, "rec:ai.INP CA") -} - -record(ai, "rec:j1") { - field(INP, {calc:{ - expr:"A+5", - args:5 - }}) - field(PINI, "YES") -} diff --git a/src/std/rec/test/linkRetargetLinkTest.c b/src/std/rec/test/linkRetargetLinkTest.c deleted file mode 100644 index 2a37696aa..000000000 --- a/src/std/rec/test/linkRetargetLinkTest.c +++ /dev/null @@ -1,122 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2015 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -/* - * Author: Michael Davidsaver - * - * Test using several stringout records to retarget the link of another record - */ -#define EPICS_DBCA_PRIVATE_API - -#include - -#include "dbAccess.h" - -#include "dbUnitTest.h" -#include "errlog.h" -#include "epicsThread.h" - -#include "testMain.h" - -void recTestIoc_registerRecordDeviceDriver(struct dbBase *); - -static void testRetarget(void) -{ - testMonitor *lnkmon, *valmon; - - testDiag("In testRetarget"); - - lnkmon = testMonitorCreate("rec:ai.INP", DBE_VALUE, 0); - valmon = testMonitorCreate("rec:ai", DBE_VALUE, 0); - - /* initially rec:ai.INP is CONSTANT */ - - testdbGetFieldEqual("rec:ai", DBR_DOUBLE, 0.0); - testdbGetFieldEqual("rec:ai.INP", DBR_STRING, "0"); - - /* rec:ai.INP becomes DB_LINK, but no processing is triggered */ - testdbPutFieldOk("rec:link1.PROC", DBF_LONG, 0); - - testMonitorWait(lnkmon); - - testdbGetFieldEqual("rec:ai", DBR_DOUBLE, 0.0); - testdbGetFieldEqual("rec:ai.INP", DBR_STRING, "rec:src1 NPP NMS"); - - /* trigger a read from rec:ai.INP */ - testdbPutFieldOk("rec:ai.PROC", DBF_LONG, 0); - - testMonitorWait(valmon); - - testdbGetFieldEqual("rec:ai", DBR_DOUBLE, 1.0); - - /* rec:ai.INP becomes CA_LINK w/ CP, processing is triggered */ - testdbPutFieldOk("rec:link2.PROC", DBF_LONG, 0); - - testMonitorWait(lnkmon); - testMonitorWait(valmon); - - testdbGetFieldEqual("rec:ai", DBR_DOUBLE, 2.0); - testdbGetFieldEqual("rec:ai.INP", DBR_STRING, "rec:src2 CP NMS"); - - testMonitorDestroy(lnkmon); - testMonitorDestroy(valmon); -} - -#define testLongStrEq(PV, VAL) testdbGetArrFieldEqual(PV, DBF_CHAR, sizeof(VAL)+2, sizeof(VAL), VAL) -#define testPutLongStr(PV, VAL) testdbPutArrFieldOk(PV, DBF_CHAR, sizeof(VAL), VAL); - -static void testRetargetJLink(void) -{ - testDiag("In testRetargetJLink"); - - testdbGetFieldEqual("rec:j1", DBF_DOUBLE, 10.0); - /* minimal args */ - testLongStrEq("rec:j1.INP$", "{\"calc\":{\"expr\":\"A+5\",\"args\":5}}"); - - /* with [] */ - testPutLongStr("rec:j1.INP$", "{\"calc\":{\"expr\":\"A+5\",\"args\":[7]}}"); - testdbPutFieldOk("rec:j1.PROC", DBF_LONG, 1); - - /* with const */ - testPutLongStr("rec:j1.INP$", "{\"calc\":{\"expr\":\"A+5\",\"args\":[{\"const\":7}]}}"); - testdbPutFieldOk("rec:j1.PROC", DBF_LONG, 1); - - testdbGetFieldEqual("rec:j1", DBF_DOUBLE, 12.0); - testLongStrEq("rec:j1.INP$", "{\"calc\":{\"expr\":\"A+5\",\"args\":[{\"const\":7}]}}"); -} - -MAIN(linkRetargetLinkTest) -{ - testPlan(18); - - testdbPrepare(); - - testdbReadDatabase("recTestIoc.dbd", NULL, NULL); - - recTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("linkRetargetLink.db", NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); - /* wait for local CA links to be connected or dbPutField() will fail */ - /* wait for initial CA_CONNECT actions to be processed. - * Assume that local CA links deliver callbacks synchronously - * eg. that ca_create_channel() will invoke the connection callback - * before returning. - */ - dbCaSync(); - - testRetarget(); - testRetargetJLink(); - - testIocShutdownOk(); - - testdbCleanup(); - - return testDone(); -} diff --git a/src/std/rec/test/recMiscTest.c b/src/std/rec/test/recMiscTest.c deleted file mode 100644 index 567638b78..000000000 --- a/src/std/rec/test/recMiscTest.c +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2017 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -#include - -#include "dbAccess.h" -#include "errlog.h" -#include "dbStaticLib.h" -#include "dbUnitTest.h" -#include "testMain.h" - -static -void testint64BeforeInit(void) -{ - const char *S; - DBENTRY dbent; - - /* check dbGet/PutString */ - - testDiag("In %s", EPICS_FUNCTION); - - dbInitEntryFromRecord(testdbRecordPtr("out64"), &dbent); - if(dbFindField(&dbent, "VAL")) - testAbort("Failed to find out64.VAL"); - - S = dbGetString(&dbent); - testOk(S && strcmp(S, "0")==0, "initial value \"%s\"", S); - - testOk1(dbPutString(&dbent, "0x12345678abcdef00")==0); - - S = dbGetString(&dbent); - testOk(S && strcmp(S, "1311768467750121216")==0, "1311768467750121216 \"%s\"", S); - - dbFinishEntry(&dbent); -} - -static -void testint64AfterInit(void) -{ - testDiag("In %s", EPICS_FUNCTION); - - /* check dbGet/PutField and DB links */ - - testdbGetFieldEqual("in64", DBF_UINT64, 0ULL); - testdbGetFieldEqual("out64", DBF_UINT64, 0x12345678abcdef00ULL); - - testdbPutFieldOk("out64.PROC", DBF_LONG, 1); - - testdbGetFieldEqual("in64", DBF_UINT64, 0x12345678abcdef00ULL); - - testdbPutFieldOk("out64.VAL", DBF_UINT64, 0x22345678abcdef00ULL); - - testdbPutFieldOk("in64.PROC", DBF_LONG, 1); - - testdbGetFieldEqual("in64", DBF_UINT64, 0x22345678abcdef00ULL); -} - -void recTestIoc_registerRecordDeviceDriver(struct dbBase *); - -MAIN(recMiscTest) -{ - testPlan(10); - - testdbPrepare(); - - testdbReadDatabase("recTestIoc.dbd", NULL, NULL); - - recTestIoc_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("recMiscTest.db", NULL, NULL); - - testint64BeforeInit(); - - eltc(0); - testIocInitOk(); - eltc(1); - - testint64AfterInit(); - - testIocShutdownOk(); - - testdbCleanup(); - - return testDone(); -} diff --git a/src/std/rec/test/recMiscTest.db b/src/std/rec/test/recMiscTest.db deleted file mode 100644 index 46fc8ae11..000000000 --- a/src/std/rec/test/recMiscTest.db +++ /dev/null @@ -1,10 +0,0 @@ - -# check int64in/out - -record(int64in, "in64") { - field(INP , "out64 NPP") -} - -record(int64out, "out64") { - field(OUT , "in64 NPP") -} diff --git a/src/std/rec/test/regressArray1.db b/src/std/rec/test/regressArray1.db deleted file mode 100644 index a09f3bfba..000000000 --- a/src/std/rec/test/regressArray1.db +++ /dev/null @@ -1,9 +0,0 @@ -record(waveform, "wf") { - field(FTVL, "DOUBLE") - field(NELM, "1") - field(FLNK, "co") -} -record(calcout, "co") { - field(CALC, "A") - field(INPA, "wf") -} diff --git a/src/std/rec/test/regressTest.c b/src/std/rec/test/regressTest.c deleted file mode 100644 index ccbe53189..000000000 --- a/src/std/rec/test/regressTest.c +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2016 Michael Davidsaver -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. - \*************************************************************************/ - -#include -#include -#include -#include - -#include -#include - -/* - * Test the some identified regressions - */ - -void regressTest_registerRecordDeviceDriver(struct dbBase *); - -/* - * https://bugs.launchpad.net/epics-base/+bug/1577108 - */ -static -void testArrayLength1(void) -{ - waveformRecord *precwf; - calcoutRecord *precco; - double *pbuf; - - testdbPrepare(); - - testdbReadDatabase("regressTest.dbd", NULL, NULL); - - regressTest_registerRecordDeviceDriver(pdbbase); - - testdbReadDatabase("regressArray1.db", NULL, NULL); - - precwf = (waveformRecord*)testdbRecordPtr("wf"); - precco = (calcoutRecord*)testdbRecordPtr("co"); - - eltc(0); - testIocInitOk(); - eltc(1); - - dbScanLock((dbCommon*)precwf); - pbuf = (double*)precwf->bptr; - dbScanUnlock((dbCommon*)precwf); - - testdbPutFieldOk("wf", DBF_DOUBLE, 2.0); - - dbScanLock((dbCommon*)precwf); - testOk(precwf->nord==1, "wf.NORD = %u == 1", (unsigned)precwf->nord); - testOk(pbuf[0]==2.0, "wf.VAL[0] = %f == 2.0", pbuf[0]); - dbScanUnlock((dbCommon*)precwf); - - dbScanLock((dbCommon*)precco); - testOk(precco->a==2.0, "co.A = %f == 2.0", precco->a); - dbScanUnlock((dbCommon*)precco); - - testdbGetFieldEqual("co", DBF_DOUBLE, 2.0); - - testIocShutdownOk(); - - testdbCleanup(); -} - -MAIN(regressTest) -{ - testPlan(5); - testArrayLength1(); - return testDone(); -} diff --git a/src/std/rec/test/rtemsTestHarness.c b/src/std/rec/test/rtemsTestHarness.c deleted file mode 100644 index 772d5394e..000000000 --- a/src/std/rec/test/rtemsTestHarness.c +++ /dev/null @@ -1,14 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -extern void epicsRunRecordTests(void); - -int main(int argc, char **argv) -{ - epicsRunRecordTests(); /* calls epicsExit(0) */ - return 0; -} diff --git a/src/std/rec/waveformRecord.c b/src/std/rec/waveformRecord.c deleted file mode 100644 index c06c48001..000000000 --- a/src/std/rec/waveformRecord.c +++ /dev/null @@ -1,346 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* recWaveform.c - Record Support Routines for Waveform records */ -/* - * Original Author: Bob Dalesio - * Date: 7-14-89 - */ - -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "epicsString.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "dbScan.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "cantProceed.h" -#include "menuYesNo.h" - -#define GEN_SIZE_OFFSET -#include "waveformRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -static long cvt_dbaddr(DBADDR *); -static long get_array_info(DBADDR *, long *, long *); -static long put_array_info(DBADDR *, long); -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -#define get_alarm_double NULL -rset waveformRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,waveformRSET); -struct wfdset { /* waveform dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_wf; /*returns: (-1,0)=>(failure,success)*/ -}; - -static void monitor(waveformRecord *); -static long readValue(waveformRecord *); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - struct waveformRecord *prec = (struct waveformRecord *)pcommon; - struct wfdset *pdset; - - if (pass==0){ - if (prec->nelm <= 0) - prec->nelm = 1; - if (prec->ftvl > DBF_ENUM) - prec->ftvl = DBF_UCHAR; - prec->bptr = callocMustSucceed(prec->nelm, dbValueSize(prec->ftvl), - "waveform calloc failed"); - if (prec->nelm == 1) { - prec->nord = 1; - } else { - prec->nord = 0; - } - return 0; - } - - recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm); - - /* must have dset defined */ - if (!(pdset = (struct wfdset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET,(void *)prec,"wf: init_record"); - return S_dev_noDSET; - } - /* must have read_wf function defined */ - if ((pdset->number < 5) || (pdset->read_wf == NULL)) { - recGblRecordError(S_dev_missingSup,(void *)prec,"wf: init_record"); - return S_dev_missingSup; - } - if (! pdset->init_record) return 0; - - return (*pdset->init_record)(prec); -} - -static long process(struct dbCommon *pcommon) -{ - struct waveformRecord *prec = (struct waveformRecord *)pcommon; - struct wfdset *pdset = (struct wfdset *)(prec->dset); - unsigned char pact=prec->pact; - - if ((pdset==NULL) || (pdset->read_wf==NULL)) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup, (void *)prec, "read_wf"); - return S_dev_missingSup; - } - - if (pact && prec->busy) return 0; - - readValue(prec); /* read the new value */ - if (!pact && prec->pact) return 0; - - prec->pact = TRUE; - prec->udf = FALSE; - recGblGetTimeStamp(prec); - - monitor(prec); - - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return 0; -} - -static long cvt_dbaddr(DBADDR *paddr) -{ - waveformRecord *prec = (waveformRecord *) paddr->precord; - - paddr->no_elements = prec->nelm; - paddr->field_type = prec->ftvl; - paddr->field_size = dbValueSize(prec->ftvl); - paddr->dbr_field_type = prec->ftvl; - - return 0; -} - -static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) -{ - waveformRecord *prec = (waveformRecord *) paddr->precord; - - paddr->pfield = prec->bptr; - *no_elements = prec->nord; - *offset = 0; - - return 0; -} - -static long put_array_info(DBADDR *paddr, long nNew) -{ - waveformRecord *prec = (waveformRecord *) paddr->precord; - - prec->nord = nNew; - if (prec->nord > prec->nelm) - prec->nord = prec->nelm; - - db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG); - return 0; -} - -#define indexof(field) waveformRecord##field - -static long get_units(DBADDR *paddr, char *units) -{ - waveformRecord *prec = (waveformRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM) - break; - case indexof(HOPR): - case indexof(LOPR): - strncpy(units,prec->egu,DB_UNITS_SIZE); - } - return 0; -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - waveformRecord *prec = (waveformRecord *) paddr->precord; - - *precision = prec->prec; - if (dbGetFieldIndex(paddr) != indexof(VAL)) - recGblGetPrec(paddr, precision); - return 0; -} - -static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) -{ - waveformRecord *prec = (waveformRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - break; - case indexof(BUSY): - pgd->upper_disp_limit = 1; - pgd->lower_disp_limit = 0; - break; - case indexof(NORD): - pgd->upper_disp_limit = prec->nelm; - pgd->lower_disp_limit = 0; - break; - default: - recGblGetGraphicDouble(paddr, pgd); - } - return 0; -} - -static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd) -{ - waveformRecord *prec = (waveformRecord *) paddr->precord; - - switch (dbGetFieldIndex(paddr)) { - case indexof(VAL): - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - break; - case indexof(BUSY): - pcd->upper_ctrl_limit = 1; - pcd->lower_ctrl_limit = 0; - break; - case indexof(NORD): - pcd->upper_ctrl_limit = prec->nelm; - pcd->lower_ctrl_limit = 0; - break; - default: - recGblGetControlDouble(paddr, pcd); - } - return 0; -} - -static void monitor(waveformRecord *prec) -{ - unsigned short monitor_mask = 0; - unsigned int hash = 0; - - monitor_mask = recGblResetAlarms(prec); - - if (prec->mpst == waveformPOST_Always) - monitor_mask |= DBE_VALUE; - if (prec->apst == waveformPOST_Always) - monitor_mask |= DBE_LOG; - - /* Calculate hash if we are interested in OnChange events. */ - if ((prec->mpst == waveformPOST_OnChange) || - (prec->apst == waveformPOST_OnChange)) { - hash = epicsMemHash((char *)prec->bptr, - prec->nord * dbValueSize(prec->ftvl), 0); - - /* Only post OnChange values if the hash is different. */ - if (hash != prec->hash) { - if (prec->mpst == waveformPOST_OnChange) - monitor_mask |= DBE_VALUE; - if (prec->apst == waveformPOST_OnChange) - monitor_mask |= DBE_LOG; - - /* Store hash for next process. */ - prec->hash = hash; - /* Post HASH. */ - db_post_events(prec, &prec->hash, DBE_VALUE); - } - } - - if (monitor_mask) { - db_post_events(prec, &prec->val, monitor_mask); - } -} - -static long readValue(waveformRecord *prec) -{ - long status; - struct wfdset *pdset = (struct wfdset *) prec->dset; - - if (prec->pact == TRUE){ - return (*pdset->read_wf)(prec); - } - - status = dbGetLink(&prec->siml, DBR_ENUM, &prec->simm, 0, 0); - if (status) - return status; - - if (prec->simm == menuYesNoNO){ - epicsUInt32 nord = prec->nord; - - status = (*pdset->read_wf)(prec); - if (nord != prec->nord) - db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG); - return status; - } - - if (prec->simm == menuYesNoYES){ - long nRequest = prec->nelm; - - status = dbGetLink(&prec->siol, prec->ftvl, prec->bptr, 0, &nRequest); - /* nord set only for db links: needed for old db_access */ - if (!dbLinkIsConstant(&prec->siol)) { - prec->nord = nRequest; - db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG); - if (status == 0) - prec->udf=FALSE; - } - } else { - recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM); - return -1; - } - recGblSetSevr(prec, SIMM_ALARM, prec->sims); - - return status; -} - diff --git a/src/std/rec/waveformRecord.dbd.pod b/src/std/rec/waveformRecord.dbd.pod deleted file mode 100644 index db2fa05fb..000000000 --- a/src/std/rec/waveformRecord.dbd.pod +++ /dev/null @@ -1,158 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -=title Waveform Record (waveform) - -... - -=head2 Record-specific Menus - -=head3 Menu waveformPOST - -The MPST and APST fields use this menu to determine when to post new value -and archive monitors respectively. - -=menu waveformPOST - -... - -=head2 Parameter Fields - -The record-specific fields are described below. - -=recordtype waveform - -... - -=cut - -menu(waveformPOST) { - choice(waveformPOST_Always,"Always") - choice(waveformPOST_OnChange,"On Change") -} - -recordtype(waveform) { - -=fields VAL, FTVL, MPST, APST - -=cut - - include "dbCommon.dbd" - field(VAL,DBF_NOACCESS) { - prompt("Value") - asl(ASL0) - special(SPC_DBADDR) - pp(TRUE) - extra("void * val") - #=type Set by FTVL - #=read Yes - #=write Yes - } - field(RARM,DBF_SHORT) { - prompt("Rearm the waveform") - promptgroup("30 - Action") - pp(TRUE) - interest(1) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - prop(YES) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - prop(YES) - } - field(NELM,DBF_ULONG) { - prompt("Number of Elements") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - initial("1") - } - field(FTVL,DBF_MENU) { - prompt("Field Type of Value") - promptgroup("30 - Action") - special(SPC_NOMOD) - interest(1) - menu(menuFtype) - } - field(BUSY,DBF_SHORT) { - prompt("Busy Indicator") - special(SPC_NOMOD) - } - field(NORD,DBF_ULONG) { - prompt("Number elements read") - special(SPC_NOMOD) - } - field(BPTR,DBF_NOACCESS) { - prompt("Buffer Pointer") - special(SPC_NOMOD) - interest(4) - extra("void * bptr") - } - field(SIOL,DBF_INLINK) { - prompt("Sim Input Specifctn") - promptgroup("90 - Simulate") - interest(1) - } - field(SIML,DBF_INLINK) { - prompt("Sim Mode Location") - promptgroup("90 - Simulate") - interest(1) - } - field(SIMM,DBF_MENU) { - prompt("Simulation Mode") - interest(1) - menu(menuYesNo) - } - field(SIMS,DBF_MENU) { - prompt("Sim mode Alarm Svrty") - promptgroup("90 - Simulate") - interest(2) - menu(menuAlarmSevr) - } - field(MPST,DBF_MENU) { - prompt("Post Value Monitors") - promptgroup("80 - Display") - interest(1) - menu(waveformPOST) - } - field(APST,DBF_MENU) { - prompt("Post Archive Monitors") - promptgroup("80 - Display") - interest(1) - menu(waveformPOST) - } - field(HASH,DBF_ULONG) { - prompt("Hash of OnChange data.") - interest(3) - } -} diff --git a/src/std/softIoc/Makefile b/src/std/softIoc/Makefile deleted file mode 100644 index a432d358d..000000000 --- a/src/std/softIoc/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -########################################################################## -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -########################################################################## - -# This is a Makefile fragment, see src/ioc/Makefile. - -SRC_DIRS += $(STDDIR)/softIoc - -PROD_IOC_DEFAULT = softIoc -PROD_IOC_iOS = -nil- - -DBD += base.dbd -DBD += asSub.dbd -DBD += softIoc.dbd - -softIoc_DBD += base.dbd -softIoc_DBD += dlload.dbd -softIoc_DBD += system.dbd - -softIoc_SRCS += softIoc_registerRecordDeviceDriver.cpp -softIoc_SRCS_DEFAULT += softMain.cpp -softIoc_SRCS_vxWorks = -nil- - -softIoc_LIBS = $(EPICS_BASE_IOC_LIBS) - -DB += softIocExit.db - -FINAL_LOCATION ?= $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION)) - -CLEANS += epicsInstallDir.h - diff --git a/src/std/softIoc/RULES b/src/std/softIoc/RULES deleted file mode 100644 index fc1c6236e..000000000 --- a/src/std/softIoc/RULES +++ /dev/null @@ -1,23 +0,0 @@ -########################################################################## -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -########################################################################## - -# This is a Makefile fragment, see src/ioc/Makefile. - -softIoc.dbd$(DEP): $(COMMON_DIR)/stdRecords.dbd -softIoc.dbd$(DEP): $(COMMON_DIR)/filters.dbd -softIoc.dbd$(DEP): $(COMMON_DIR)/links.dbd -$(COMMON_DIR)/softIoc.dbd: $(COMMON_DIR)/stdRecords.dbd -$(COMMON_DIR)/softIoc.dbd: $(COMMON_DIR)/filters.dbd -$(COMMON_DIR)/softIoc.dbd: $(COMMON_DIR)/links.dbd -$(COMMON_DIR)/softIoc.dbd: $(STDDIR)/softIoc/Makefile - -softMain$(DEP): epicsInstallDir.h - -epicsInstallDir.h: - $(ECHO) "FINAL_LOCATION=$(FINAL_LOCATION)" - $(PERL) $(STDDIR)/softIoc/makeInstallDir.pl "$(FINAL_LOCATION)" > $@ - diff --git a/src/std/softIoc/asSub.dbd b/src/std/softIoc/asSub.dbd deleted file mode 100644 index d02852fae..000000000 --- a/src/std/softIoc/asSub.dbd +++ /dev/null @@ -1,3 +0,0 @@ -# Register access security subroutines -registrar(asSub) - diff --git a/src/std/softIoc/base.dbd b/src/std/softIoc/base.dbd deleted file mode 100644 index 58f4884ea..000000000 --- a/src/std/softIoc/base.dbd +++ /dev/null @@ -1,28 +0,0 @@ -# This file includes the standard record types and device support -# provided by Base and (usually) loaded into all IOCs. - -# Fixed menus -include "menuGlobal.dbd" - -# Modifyable menus -include "menuConvert.dbd" -include "menuScan.dbd" - -# Record types -include "stdRecords.dbd" - -# Channel filters & plugins -include "filters.dbd" - -# Link types -include "links.dbd" - -# Standard device support -include "devSoft.dbd" - -# Access security subroutines -include "asSub.dbd" - -# IOC Core variables -include "dbCore.dbd" - diff --git a/src/std/softIoc/makeInstallDir.pl b/src/std/softIoc/makeInstallDir.pl deleted file mode 100644 index 61f271f15..000000000 --- a/src/std/softIoc/makeInstallDir.pl +++ /dev/null @@ -1,28 +0,0 @@ -eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*- - if $running_under_some_shell; -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; - -die "$0: Argument missing, INSTALL_LOCATION\n" if @ARGV == 0; -die "$0: Too many arguments, expecting one\n" unless @ARGV == 1; - -my $path = shift; - -$path =~ s/\\/\\\\/gx; -$path =~ s/^'//; -$path =~ s/'$//; - -print "/* THIS IS A GENERATED FILE. DO NOT EDIT! */\n", - "\n", - "#ifndef INC_epicsInstallDir_H\n", - "#define INC_epicsInstallDir_H\n", - "\n", - "#define EPICS_BASE \"$path\"\n", - "\n", - "#endif /* INC_epicsInstallDir_H */\n"; diff --git a/src/std/softIoc/softIocExit.db b/src/std/softIoc/softIocExit.db deleted file mode 100644 index c530f778a..000000000 --- a/src/std/softIoc/softIocExit.db +++ /dev/null @@ -1,15 +0,0 @@ -# softIocExit.db - -record(sub,"$(IOC):exit") { - field(DESC,"Exit subroutine") - field(SCAN,"Passive") - field(SNAM,"exit") -} - -record(stringin,"$(IOC):BaseVersion") { - field(DESC,"EPICS Base Version") - field(DTYP,"getenv") - field(INP,"@EPICS_VERSION_FULL") - field(PINI,"YES") - field(DISP,1) -} diff --git a/src/std/softIoc/softMain.cpp b/src/std/softIoc/softMain.cpp deleted file mode 100644 index 8400a6554..000000000 --- a/src/std/softIoc/softMain.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2003 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to the Software License Agreement -* found in the file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* Author: Andrew Johnson Date: 2003-04-08 */ - -/* Usage: - * softIoc [-D softIoc.dbd] [-h] [-S] [-s] [-a ascf] - * [-m macro=value,macro2=value2] [-d file.db] - * [-x prefix] [st.cmd] - * - * If used the -D option must come first, and specify the - * path to the softIoc.dbd file. The compile-time install - * location is saved in the binary as a default. - * - * Usage information will be printed if -h is given, then - * the program will exit normally. - * - * The -S option prevents an interactive shell being started - * after all arguments have been processed. - * - * Previous versions accepted a -s option to cause a shell - * to be started; this option is still accepted but ignored - * since a command shell is now started by default. - * - * Access Security can be enabled with the -a option giving - * the name of the configuration file; if any macros were - * set with -m before the -a option was given, they will be - * used as access security substitution macros. - * - * Any number of -m and -d arguments can be interspersed; - * the macros are applied to the following .db files. Each - * later -m option causes earlier macros to be discarded. - * - * The -x option loads the softIocExit.db with the macro - * IOC set to the string provided. This database contains - * a subroutine record named $(IOC):exit which has its field - * SNAM set to "exit". When this record is processed, the - * subroutine that runs will call epicsExit() with the value - * of the field A determining whether the exit status is - * EXIT_SUCCESS if (A == 0.0) or EXIT_FAILURE (A != 0.0). - * - * A st.cmd file is optional. If any databases were loaded - * the st.cmd file will be run *after* iocInit. To perform - * iocsh commands before iocInit, all database loading must - * be performed by the script itself, or by the user from - * the interactive IOC shell. - */ - -#include -#include -#include -#include -#include - -#include "registryFunction.h" -#include "epicsThread.h" -#include "epicsExit.h" -#include "epicsStdio.h" -#include "dbStaticLib.h" -#include "subRecord.h" -#include "dbAccess.h" -#include "asDbLib.h" -#include "iocInit.h" -#include "iocsh.h" -#include "epicsInstallDir.h" - -extern "C" int softIoc_registerRecordDeviceDriver(struct dbBase *pdbbase); - -#define DBD_FILE EPICS_BASE "/dbd/softIoc.dbd" -#define EXIT_FILE EPICS_BASE "/db/softIocExit.db" - -const char *arg0; -const char *base_dbd = DBD_FILE; -const char *exit_db = EXIT_FILE; - - -static void exitSubroutine(subRecord *precord) { - epicsExitLater((precord->a == 0.0) ? EXIT_SUCCESS : EXIT_FAILURE); -} - -static void usage(int status) { - printf("Usage: %s [-D softIoc.dbd] [-h] [-S] [-a ascf]\n", arg0); - puts("\t[-m macro=value,macro2=value2] [-d file.db]"); - puts("\t[-x prefix] [st.cmd]"); - puts("Compiled-in path to softIoc.dbd is:"); - printf("\t%s\n", base_dbd); - epicsExit(status); -} - - -int main(int argc, char *argv[]) -{ - char *dbd_file = const_cast(base_dbd); - char *macros = NULL; - char xmacro[PVNAME_STRINGSZ + 4]; - int startIocsh = 1; /* default = start shell */ - int loadedDb = 0; - - arg0 = strrchr(*argv, '/'); - if (!arg0) { - arg0 = *argv; - } else { - ++arg0; /* skip the '/' */ - } - - --argc, ++argv; - - /* Do this here in case the dbd file not available */ - if (argc>0 && **argv=='-' && (*argv)[1]=='h') { - usage(EXIT_SUCCESS); - } - - if (argc>1 && **argv=='-' && (*argv)[1]=='D') { - dbd_file = *++argv; - argc -= 2; - ++argv; - } - - if (dbLoadDatabase(dbd_file, NULL, NULL)) { - epicsExit(EXIT_FAILURE); - } - - softIoc_registerRecordDeviceDriver(pdbbase); - registryFunctionAdd("exit", (REGISTRYFUNCTION) exitSubroutine); - - while (argc>1 && **argv == '-') { - switch ((*argv)[1]) { - case 'a': - if (macros) asSetSubstitutions(macros); - asSetFilename(*++argv); - --argc; - break; - - case 'd': - if (dbLoadRecords(*++argv, macros)) { - epicsExit(EXIT_FAILURE); - } - loadedDb = 1; - --argc; - break; - - case 'h': - usage(EXIT_SUCCESS); - - case 'm': - macros = *++argv; - --argc; - break; - - case 'S': - startIocsh = 0; - break; - - case 's': - break; - - case 'x': - epicsSnprintf(xmacro, sizeof xmacro, "IOC=%s", *++argv); - if (dbLoadRecords(exit_db, xmacro)) { - epicsExit(EXIT_FAILURE); - } - loadedDb = 1; - --argc; - break; - - default: - printf("%s: option '%s' not recognized\n", arg0, *argv); - usage(EXIT_FAILURE); - } - --argc; - ++argv; - } - - if (argc>0 && **argv=='-') { - switch((*argv)[1]) { - case 'a': - case 'd': - case 'm': - case 'x': - printf("%s: missing argument to option '%s'\n", arg0, *argv); - usage(EXIT_FAILURE); - - case 'h': - usage(EXIT_SUCCESS); - - case 'S': - startIocsh = 0; - break; - - case 's': - break; - - default: - printf("%s: option '%s' not recognized\n", arg0, *argv); - usage(EXIT_FAILURE); - } - --argc; - ++argv; - } - - if (loadedDb) { - iocInit(); - epicsThreadSleep(0.2); - } - - /* run user's startup script */ - if (argc>0) { - if (iocsh(*argv)) epicsExit(EXIT_FAILURE); - epicsThreadSleep(0.2); - loadedDb = 1; /* Give it the benefit of the doubt... */ - } - - /* start an interactive shell if it was requested */ - if (startIocsh) { - iocsh(NULL); - } else { - if (loadedDb) { - epicsThreadExitMain(); - } else { - printf("%s: Nothing to do!\n", arg0); - usage(EXIT_FAILURE); - } - } - epicsExit(EXIT_SUCCESS); - /*Note that the following statement will never be executed*/ - return 0; -} diff --git a/src/template/Makefile b/src/template/Makefile new file mode 100644 index 000000000..1b2ccbd0e --- /dev/null +++ b/src/template/Makefile @@ -0,0 +1,20 @@ +TOP=../.. + +include $(TOP)/configure/CONFIG + +TEMPLATES_DIR = makeBaseApp + +TEMPLATES += top/caServerApp/Makefile +TEMPLATES += top/caServerApp/README +TEMPLATES += top/caServerApp/exAsyncPV.cc +TEMPLATES += top/caServerApp/exChannel.cc +TEMPLATES += top/caServerApp/exPV.cc +TEMPLATES += top/caServerApp/exScalarPV.cc +TEMPLATES += top/caServerApp/exServer.cc +TEMPLATES += top/caServerApp/exServer.h +TEMPLATES += top/caServerApp/exVectorPV.cc +TEMPLATES += top/caServerApp/main.cc +TEMPLATES += top/caServerApp/test.adl +TEMPLATES += top/caServerApp/vxEntry.cc + +include $(TOP)/configure/RULES diff --git a/src/template/base/Makefile b/src/template/base/Makefile deleted file mode 100644 index bfc6de244..000000000 --- a/src/template/base/Makefile +++ /dev/null @@ -1,99 +0,0 @@ -TOP=../../.. - -include $(TOP)/configure/CONFIG - -TEMPLATES_DIR = makeBaseApp - -TEMPLATES += top/Makefile -TEMPLATES += top/configure/CONFIG -TEMPLATES += top/configure/CONFIG_SITE -TEMPLATES += top/configure/Makefile -TEMPLATES += top/configure/RELEASE -TEMPLATES += top/configure/RULES -TEMPLATES += top/configure/RULES.ioc -TEMPLATES += top/configure/RULES_DIRS -TEMPLATES += top/configure/RULES_TOP - -TEMPLATES += top/supportApp/Makefile -TEMPLATES += top/supportApp/Db/Makefile -TEMPLATES += top/supportApp/src/Makefile -TEMPLATES += top/supportApp/src/_APPNAME_.dbd - -TEMPLATES += top/iocApp/Makefile -TEMPLATES += top/iocApp/Db/Makefile -TEMPLATES += top/iocApp/src/Makefile -TEMPLATES += top/iocApp/src/_APPNAME_Main.cpp - -TEMPLATES += top/exampleApp/Makefile -TEMPLATES += top/exampleApp/Db/Makefile -TEMPLATES += top/exampleApp/Db/dbExample1.db -TEMPLATES += top/exampleApp/Db/dbExample2.db -TEMPLATES += top/exampleApp/Db/_APPNAME_Version.db -TEMPLATES += top/exampleApp/Db/dbSubExample.db -TEMPLATES += top/exampleApp/Db/user.substitutions -TEMPLATES += top/exampleApp/src/Makefile -TEMPLATES += top/exampleApp/src/dev_APPNAME_Version.c -TEMPLATES += top/exampleApp/src/dev_APPNAME_Version.dbd -TEMPLATES += top/exampleApp/src/xxxRecord.dbd -TEMPLATES += top/exampleApp/src/xxxRecord.c -TEMPLATES += top/exampleApp/src/devXxxSoft.c -TEMPLATES += top/exampleApp/src/xxxSupport.dbd -TEMPLATES += top/exampleApp/src/sncExample.stt -TEMPLATES += top/exampleApp/src/sncProgram.st -TEMPLATES += top/exampleApp/src/sncExample.dbd -TEMPLATES += top/exampleApp/src/dbSubExample.c -TEMPLATES += top/exampleApp/src/dbSubExample.dbd -TEMPLATES += top/exampleApp/src/_APPNAME_Main.cpp -TEMPLATES += top/exampleApp/src/_APPNAME_Hello.c -TEMPLATES += top/exampleApp/src/_APPNAME_Hello.dbd -TEMPLATES += top/exampleApp/src/initTrace.c -TEMPLATES += top/exampleApp/src/initTrace.dbd - -TEMPLATES += top/exampleBoot/Makefile -TEMPLATES += top/exampleBoot/nfsCommands@vxWorks -TEMPLATES += top/exampleBoot/nfsCommands@RTEMS -TEMPLATES += top/exampleBoot/ioc/Makefile@Common -TEMPLATES += top/exampleBoot/ioc/Makefile@vxWorks -TEMPLATES += top/exampleBoot/ioc/Makefile@win32 -TEMPLATES += top/exampleBoot/ioc/Makefile@windows -TEMPLATES += top/exampleBoot/ioc/Makefile@cygwin -TEMPLATES += top/exampleBoot/ioc/st.cmd@Common -TEMPLATES += top/exampleBoot/ioc/st.cmd@vxWorks -TEMPLATES += top/exampleBoot/ioc/st.cmd@RTEMS -TEMPLATES += top/exampleBoot/ioc/README@Common -TEMPLATES += top/exampleBoot/ioc/README@vxWorks - -TEMPLATES += top/caClientApp/Makefile -TEMPLATES += top/caClientApp/caExample.c -TEMPLATES += top/caClientApp/caMonitor.c - -TEMPLATES += top/caServerApp/Makefile -TEMPLATES += top/caServerApp/README -TEMPLATES += top/caServerApp/exAsyncPV.cc -TEMPLATES += top/caServerApp/exChannel.cc -TEMPLATES += top/caServerApp/exPV.cc -TEMPLATES += top/caServerApp/exScalarPV.cc -TEMPLATES += top/caServerApp/exServer.cc -TEMPLATES += top/caServerApp/exServer.h -TEMPLATES += top/caServerApp/exVectorPV.cc -TEMPLATES += top/caServerApp/main.cc -TEMPLATES += top/caServerApp/test.adl -TEMPLATES += top/caServerApp/vxEntry.cc - -TEMPLATES += top/iocBoot/Makefile -TEMPLATES += top/iocBoot/nfsCommands@vxWorks -TEMPLATES += top/iocBoot/nfsCommands@RTEMS -TEMPLATES += top/iocBoot/ioc/Makefile@Common -TEMPLATES += top/iocBoot/ioc/Makefile@vxWorks -TEMPLATES += top/iocBoot/ioc/Makefile@win32 -TEMPLATES += top/iocBoot/ioc/Makefile@windows -TEMPLATES += top/iocBoot/ioc/Makefile@cygwin -TEMPLATES += top/iocBoot/ioc/st.cmd@Common -TEMPLATES += top/iocBoot/ioc/st.cmd@Cross -TEMPLATES += top/iocBoot/ioc/st.cmd@vxWorks -TEMPLATES += top/iocBoot/ioc/st.cmd@RTEMS - -SCRIPTS_HOST += makeBaseApp.pl - -include $(TOP)/configure/RULES - diff --git a/src/template/base/makeBaseApp.pl b/src/template/base/makeBaseApp.pl deleted file mode 100644 index d6da8adf8..000000000 --- a/src/template/base/makeBaseApp.pl +++ /dev/null @@ -1,432 +0,0 @@ -#!/usr/bin/env perl - -# Authors: Ralph Lange, Marty Kraimer, Andrew Johnson and Janet Anderson - -use FindBin qw($Bin); -use lib ("$Bin/../../lib/perl", $Bin); - -use Cwd; -use Getopt::Std; -use File::Find; -use File::Path 'mkpath'; -use EPICS::Path; -use EPICS::Release; - -$app_top = cwd(); - -%release = (TOP => $app_top); -@apps = (TOP); - -$bad_ident_chars = '[^0-9A-Za-z_]'; - -readReleaseFiles("configure/RELEASE", \%release, \@apps); -expandRelease(\%release); -get_commandline_opts(); # Check command-line options -GetUser(); # Ensure we know who's in charge - -# -# Declare two default callback routines for file copy plus two -# hook routines to add conversions -# These may be overriden within $top/$apptypename/Replace.pl - -# First: the hooks -sub ReplaceFilenameHook { return $_[0]; } -sub ReplaceLineHook { return $_[0]; } - -# ReplaceFilename -# called with the source (template) file or directory name, returns -# the target file/dir name (current directory is the application top). - -# Inside iocBoot, templates can install different files for different -# IOC architectures or OSs: 'name@', 'name@' & 'name@Common' -# The best match is installed as 'name', but if the best matching file -# is empty then no file is created, allowing a file 'name@Common' to -# be omitted by providing an empty 'name@' or 'name@'. - -# Returning an empty string means don't copy this file. -sub ReplaceFilename { # (filename) - my($file) = $_[0]; - $file =~ s|.*/CVS/?.*||; # Ignore CVS files and Replace.pl scripts - $file =~ s|.*/$apptypename/Replace\.pl$||; - - if($opt_i) { - # Handle name@arch stuff, copy only the closest matching file - # NB: Won't work with directories, don't use '@' in a directory name! - my($base,$filearch) = split /@/, $file; - if ($base ne $file) { # This file is arch-specific - my($os,$cpu,$toolset) = split /-/, $arch, 3; - if (-r "$base\@$arch") { # A version exists for this arch - $base = '' unless ($filearch eq $arch && -s $file); - } elsif (-r "$base\@$os") { # A version exists for this os - $base = '' unless ($filearch eq $os && -s $file); - } elsif ( $ENV{EPICS_HOST_ARCH} !~ "$os-$cpu" && - -r "$base\@Cross" ) { # Cross version exists - $base = '' unless ($filearch eq "Cross" && -s $file); - } elsif (-r "$base\@Common") { # Default version exists - $base = '' unless ($filearch eq "Common" && -s $file); - } else { # No default version - $base = ''; - } - $file = $base; # Strip the @... part from the target name - } - $file =~ s|/$apptypename|/iocBoot|; # templateBoot => iocBoot - } - if ($ioc) { - $file =~ s|/iocBoot/ioc|/iocBoot/$ioc|; # name the ioc subdirectory - $file =~ s|_IOC_|$ioc|; - } else { - $file =~ s|.*/iocBoot/ioc/?.*||; # Not doing IOCs here - } - if ($app) { - $file =~ s|/$apptypename|/$appdir|; # templateApp => namedApp - $file =~ s|/$appdir/configure|/configure/$apptype|; - } - $file =~ s|_APPNAME_|$appname|; - $file =~ s|_APPTYPE_|$apptype|; - my $qmtop = quotemeta($top); - $file =~ s|$qmtop/||; # Change to the target location - $file = ReplaceFilenameHook($file); # Call the apptype's hook - return $file; -} - -# ReplaceLine -# called with one line of a file, returns the line after replacing -# this and that -sub ReplaceLine { # (line) - my($line) = $_[0]; - $line =~ s/_IOC_/$ioc/g if ($ioc); - $line =~ s/_USER_/$user/go; - $line =~ s/_EPICS_BASE_/$app_epics_base/go; - $line =~ s/_TEMPLATE_TOP_/$app_template_top/go; - $line =~ s/_TOP_/$app_top/go; - $line =~ s/_APPNAME_/$appname/g; - $line =~ s/_CSAFEAPPNAME_/$csafeappname/g; - $line =~ s/_APPTYPE_/$apptype/go; - $line =~ s/_ARCH_/$arch/go if ($opt_i); - $line = ReplaceLineHook($line); # Call the apptype's hook - return $line; -} - -# Source replace overrides for file copy -if (-r "$top/$apptypename/Replace.pl") { - require "$top/$apptypename/Replace.pl"; -} - -# -# Copy files and dirs from (other than App & Boot) if not present -# -opendir TOPDIR, "$top" or die "Can't open $top: $!"; -foreach $f ( grep !/^\.\.?$|^[^\/]*(App|Boot)/, readdir TOPDIR ) { - find({wanted => \&FCopyTree, follow => 1}, "$top/$f") unless (-e "$f"); -} -closedir TOPDIR; - -# -# Create ioc directories -# -if ($opt_i) { - find({wanted => \&FCopyTree, follow => 1}, "$top/$apptypename"); - - $appname=$appnameIn if $appnameIn; - foreach $ioc ( @names ) { - ($appname = $ioc) =~ s/App$// if !$appnameIn; - ($csafeappname = $appname) =~ s/$bad_ident_chars/_/og; - $ioc = "ioc" . $ioc unless ($ioc =~ m/ioc/); - if (-d "iocBoot/$ioc") { - print "iocBoot/$ioc exists, not modified.\n"; - next; - } - find({wanted => \&FCopyTree, follow => 1}, "$top/$apptypename/ioc"); - } - exit 0; # finished here for -i (no xxxApps) -} - -# -# Create app directories (if any names given) -# -foreach $app ( @names ) { - ($appname = $app) =~ s/App$//; - ($csafeappname = $appname) =~ s/$bad_ident_chars/_/og; - $appdir = $appname . "App"; - if (-d "$appdir") { - print "$appname exists, not modified.\n"; - next; - } - print "Creating $appname from template type $apptypename\n" if $opt_d; - find({wanted => \&FCopyTree, follow => 1}, "$top/$apptypename/"); -} - -exit 0; # END OF SCRIPT - -# -# Get commandline options and check for validity -# -sub get_commandline_opts { #no args - getopts("a:b:dhilp:T:t:u:") or Cleanup(1); - - # Options help - Cleanup(0) if $opt_h; - - # Locate epics_base - my ($command) = UnixPath($0); - if ($opt_b) { # first choice is -b base - $epics_base = UnixPath($opt_b); - } elsif ($release{"EPICS_BASE"}) { # second choice is configure/RELEASE - $epics_base = UnixPath($release{"EPICS_BASE"}); - $epics_base =~s|^\$\(TOP\)/||; - } elsif ($ENV{EPICS_MBA_BASE}) { # third choice is env var EPICS_MBA_BASE - $epics_base = UnixPath($ENV{EPICS_MBA_BASE}); - } elsif ($command =~ m|/bin/|) { # assume script was run with full path to base - $epics_base = $command; - $epics_base =~ s|^(.*)/bin/.*makeBaseApp.*|$1|; - } - $epics_base and -d "$epics_base" or Cleanup(1, "Can't find EPICS base"); - $app_epics_base = LocalPath($epics_base); - $app_epics_base =~ s|^\.\.|\$(TOP)/..|; - - # Locate template top directory - if ($opt_T) { # first choice is -T templ-top - $top = UnixPath($opt_T); - } elsif ($release{"TEMPLATE_TOP"}) { # second choice is configure/RELEASE - $top = UnixPath($release{"TEMPLATE_TOP"}); - $top =~s|^\$\(EPICS_BASE\)|$epics_base|; - $top =~s|^\$\(TOP\)/||; - } - $top = $ENV{EPICS_MBA_TEMPLATE_TOP} unless $top && -d $top; # third choice is env var - $top = $epics_base . "/templates/makeBaseApp/top" unless $top && -d $top; # final - $top and -d "$top" or Cleanup(1, "Can't find template top directory"); - $app_template_top = LocalPath($top); - $app_template_top =~s|^\.\.|\$(TOP)/..|; - $app_template_top =~s|^$epics_base/|\$\(EPICS_BASE\)/|; - - # Print application type list? - if ($opt_l) { - ListAppTypes(); - exit 0; # finished for -l command - } - - if (!@ARGV){ - if ($opt_t) { - if ($opt_i) { - my @iocs = map {s/iocBoot\///; $_} glob 'iocBoot/ioc*'; - if (@iocs) { - print "The following IOCs already exist here:\n", - map {" $_\n"} @iocs; - } - print "Name the IOC(s) to be created.\n", - "Names given will have \"ioc\" prepended to them.\n", - "IOC names? "; - } else { - print "Name the application(s) to be created.\n", - "Names given will have \"App\" appended to them.\n", - "Application names? "; - } - $namelist = ; - chomp($namelist); - @names = split /[\s,]/, $namelist; - } else { - Cleanup(1); - } - } else { - @names = @ARGV; - } - - # ioc architecture and application name - if ($opt_i && @names) { - - # ioc architecture - opendir BINDIR, "$epics_base/bin" or die "Can't open $epics_base/bin: $!"; - my @archs = grep !/^\./, readdir BINDIR; # exclude .files - closedir BINDIR; - if ($opt_a) { - $arch = $opt_a; - } elsif (@archs == 1) { - $arch = $archs[0]; - print "Using target architecture $arch (only one available)\n"; - } else { - print "The following target architectures are available in base:\n"; - foreach $arch (@archs) { - print " $arch\n"; - } - print "What architecture do you want to use? "; - $arch = ; - chomp($arch); - } - grep /^$arch$/, @archs or Cleanup(1, "Target architecture $arch not available"); - - # Application name - if ($opt_p){ - $appnameIn = $opt_p if ($opt_p); - } else { - my @apps = glob '*App'; - if (@apps) { - print "The following applications are available:\n", - map {s/App$//; " $_\n"} @apps; - } - print "What application should the IOC(s) boot?\n", - "The default uses the IOC's name, even if not listed above.\n", - "Application name? "; - $appnameIn = ; - chomp($appnameIn); - } - } - - # Application type - $appext = $opt_i ? "Boot" : "App"; - if ($opt_t) { # first choice is -t type - $apptype = $opt_t; - $apptype =~ s/$appext$//; - } elsif ($ENV{EPICS_MBA_DEF_APP_TYPE}) { # second choice is environment var - $apptype = $ENV{EPICS_MBA_DEF_APP_TYPE}; - $apptype =~ s/(App)|(Boot)$//; - } elsif (-d "$top/default$appext") { # third choice is default - $apptype = "default"; - } elsif (-d "$top/example$appext") { # fourth choice is example - $apptype = "example"; - } - $apptype or Cleanup(1, "No application type set"); - $apptypename = $apptype . $appext; - (-r "$top/$apptypename") or - Cleanup(1, "Can't access template directory '$top/$apptypename'.\n"); - - print "\nCommand line / environment options validated:\n" - . " Templ-Top: $top\n" - . "Templ-Type: $apptype\n" - . "Templ-Name: $apptypename\n" - . " opt_i: $opt_i\n" - . " arch: $arch\n" - . "EPICS-Base: $epics_base\n\n" if $opt_d; -} - -# -# List application types -# -sub ListAppTypes { # no args - opendir TYPES, "$top" or die "Can't open $top: $!"; - my @allfiles = readdir TYPES; - closedir TYPES; - my @apps = grep /.*App$/, @allfiles; - my @boots = grep /.*Boot$/, @allfiles; - print "Valid application types are:\n"; - foreach $name (@apps) { - $name =~ s|App||; - printf "\t$name\n" if ($name && -r "$top/$name" . "App"); - } - print "Valid iocBoot types are:\n"; - foreach $name (@boots) { - $name =~ s|Boot||; - printf "\t$name\n" if ($name && -r "$top/$name" . "Boot");; - } -} - -# -# Copy a file with replacements -# -sub CopyFile { # (source) - $source = $_[0]; - $target = ReplaceFilename($source); - - if ($target and !-e $target) { - open(INP, "<$source") and open(OUT, ">$target") - or die "$! Copying $source -> $target"; - - print "Copying file $source -> $target\n" if $opt_d; - while () { - print OUT ReplaceLine($_); - } - close INP; close OUT; - } -} - -# -# Find() callback for file or structure copy -# -sub FCopyTree { - chdir $app_top; # Sigh - if (-d "$File::Find::name" - and ($dir = ReplaceFilename($File::Find::name))) { - print "Creating directory $dir\n" if $opt_d; - mkpath($dir) unless (-d "$dir"); - } else { - CopyFile($File::Find::name); - } - chdir $File::Find::dir; -} - -# -# Cleanup and exit -# -sub Cleanup { # (return-code [ messsage-line1, line 2, ... ]) - my ($rtncode, @message) = @_; - - if (@message) { - print join("\n", @message), "\n"; - } else { - Usage(); - } - exit $rtncode; -} - -sub Usage { - print </bin//makeBaseApp.pl -h - display help on command options -/bin//makeBaseApp.pl -l [options] - list application types -/bin//makeBaseApp.pl -t type [options] [app ...] - create application directories -/bin//makeBaseApp.pl -i -t type [options] [ioc ...] - create ioc boot directories -where - app Application name (the created directory will have \"App\" appended) - ioc IOC name (the created directory will have \"ioc\" prepended) -EOF - print </bin//makeBaseApp.pl -t example example -/bin//makeBaseApp.pl -i -t example example -EOF -} - -sub GetUser { - $user = $opt_u || $ENV{USER} || $ENV{USERNAME} || getlogin(); - $user = Win32::LoginName() if !$user && $^ eq 'MSWin32'; - - unless ($user) { - print "Strange, I cannot figure out your user name!\n"; - print "What should you be called ? "; - $user = ; - chomp $user; - } - $user =~ tr/-a-zA-Z0-9_:;[]<>//cd; # Sanitize; these are the legal chars - die "No user name" unless $user; -} diff --git a/src/template/base/top/Makefile b/src/template/base/top/Makefile deleted file mode 100644 index 19c9068d1..000000000 --- a/src/template/base/top/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# Makefile at top of application tree -TOP = . -include $(TOP)/configure/CONFIG - -# Directories to build, any order -DIRS += configure -DIRS += $(wildcard *Sup) -DIRS += $(wildcard *App) -DIRS += $(wildcard *Top) -DIRS += $(wildcard iocBoot) - -# The build order is controlled by these dependency rules: - -# All dirs except configure depend on configure -$(foreach dir, $(filter-out configure, $(DIRS)), \ - $(eval $(dir)_DEPEND_DIRS += configure)) - -# Any *App dirs depend on all *Sup dirs -$(foreach dir, $(filter %App, $(DIRS)), \ - $(eval $(dir)_DEPEND_DIRS += $(filter %Sup, $(DIRS)))) - -# Any *Top dirs depend on all *Sup and *App dirs -$(foreach dir, $(filter %Top, $(DIRS)), \ - $(eval $(dir)_DEPEND_DIRS += $(filter %Sup %App, $(DIRS)))) - -# iocBoot depends on all *App dirs -iocBoot_DEPEND_DIRS += $(filter %App,$(DIRS)) - -# Add any additional dependency rules here: - -include $(TOP)/configure/RULES_TOP diff --git a/src/template/base/top/caClientApp/Makefile b/src/template/base/top/caClientApp/Makefile deleted file mode 100644 index 47011375c..000000000 --- a/src/template/base/top/caClientApp/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -TOP=.. - -include $(TOP)/configure/CONFIG -#---------------------------------------- -# ADD MACRO DEFINITIONS AFTER THIS LINE -#============================= - -PROD_HOST += caExample -caExample_SRCS += caExample.c -caExample_LIBS += $(EPICS_BASE_HOST_LIBS) - -PROD_HOST += caMonitor -caMonitor_SRCS += caMonitor.c -caMonitor_LIBS += $(EPICS_BASE_HOST_LIBS) - -include $(TOP)/configure/RULES -#---------------------------------------- -# ADD RULES AFTER THIS LINE - diff --git a/src/template/base/top/caClientApp/caExample.c b/src/template/base/top/caClientApp/caExample.c deleted file mode 100644 index cc342e237..000000000 --- a/src/template/base/top/caClientApp/caExample.c +++ /dev/null @@ -1,25 +0,0 @@ -/*caExample.c*/ -#include -#include -#include -#include - -#include "cadef.h" - -int main(int argc,char **argv) -{ - double data; - chid mychid; - - if(argc != 2) { - fprintf(stderr,"usage: caExample pvname\n"); - exit(1); - } - SEVCHK(ca_context_create(ca_disable_preemptive_callback),"ca_context_create"); - SEVCHK(ca_create_channel(argv[1],NULL,NULL,10,&mychid),"ca_create_channel failure"); - SEVCHK(ca_pend_io(5.0),"ca_pend_io failure"); - SEVCHK(ca_get(DBR_DOUBLE,mychid,(void *)&data),"ca_get failure"); - SEVCHK(ca_pend_io(5.0),"ca_pend_io failure"); - printf("%s %f\n",argv[1],data); - return(0); -} diff --git a/src/template/base/top/caClientApp/caMonitor.c b/src/template/base/top/caClientApp/caMonitor.c deleted file mode 100644 index 9554cc744..000000000 --- a/src/template/base/top/caClientApp/caMonitor.c +++ /dev/null @@ -1,130 +0,0 @@ -/*caMonitor.c*/ - -/* This example accepts the name of a file containing a list of pvs to monitor. - * It prints a message for all ca events: connection, access rights and monitor. - */ - -#include -#include -#include -#include - -#include "cadef.h" -#include "dbDefs.h" -#include "epicsString.h" -#include "cantProceed.h" - -#define MAX_PV 1000 -#define MAX_PV_NAME_LEN 40 - -typedef struct{ - char value[20]; - chid mychid; - evid myevid; -} MYNODE; - - -static void printChidInfo(chid chid, char *message) -{ - printf("\n%s\n",message); - printf("pv: %s type(%d) nelements(%ld) host(%s)", - ca_name(chid),ca_field_type(chid),ca_element_count(chid), - ca_host_name(chid)); - printf(" read(%d) write(%d) state(%d)\n", - ca_read_access(chid),ca_write_access(chid),ca_state(chid)); -} - -static void exceptionCallback(struct exception_handler_args args) -{ - chid chid = args.chid; - long stat = args.stat; /* Channel access status code*/ - const char *channel; - static char *noname = "unknown"; - - channel = (chid ? ca_name(chid) : noname); - - - if(chid) printChidInfo(chid,"exceptionCallback"); - printf("exceptionCallback stat %s channel %s\n", - ca_message(stat),channel); -} - -static void connectionCallback(struct connection_handler_args args) -{ - chid chid = args.chid; - - printChidInfo(chid,"connectionCallback"); -} - -static void accessRightsCallback(struct access_rights_handler_args args) -{ - chid chid = args.chid; - - printChidInfo(chid,"accessRightsCallback"); -} -static void eventCallback(struct event_handler_args eha) -{ - chid chid = eha.chid; - - if(eha.status!=ECA_NORMAL) { - printChidInfo(chid,"eventCallback"); - } else { - char *pdata = (char *)eha.dbr; - printf("Event Callback: %s = %s\n",ca_name(eha.chid),pdata); - } -} - -int main(int argc,char **argv) -{ - char *filename; - int npv = 0; - MYNODE *pmynode[MAX_PV]; - char *pname[MAX_PV]; - int i; - char tempStr[MAX_PV_NAME_LEN]; - char *pstr; - FILE *fp; - - if (argc != 2) { - fprintf(stderr,"usage: caMonitor filename\n"); - exit(1); - } - filename = argv[1]; - fp = fopen(filename,"r"); - if (!fp) { - perror("fopen failed"); - return(1); - } - while (npv < MAX_PV) { - size_t len; - - pstr = fgets(tempStr, MAX_PV_NAME_LEN, fp); - if (!pstr) break; - - len = strlen(pstr); - if (len <= 1) continue; - - pstr[len - 1] = '\0'; /* Strip newline */ - pname[npv] = epicsStrDup(pstr); - pmynode[npv] = callocMustSucceed(1, sizeof(MYNODE), "caMonitor"); - npv++; - } - fclose(fp); - SEVCHK(ca_context_create(ca_disable_preemptive_callback),"ca_context_create"); - SEVCHK(ca_add_exception_event(exceptionCallback,NULL), - "ca_add_exception_event"); - for (i=0; imychid), - "ca_create_channel"); - SEVCHK(ca_replace_access_rights_event(pmynode[i]->mychid, - accessRightsCallback), - "ca_replace_access_rights_event"); - SEVCHK(ca_create_subscription(DBR_STRING,1,pmynode[i]->mychid, - DBE_VALUE,eventCallback,pmynode[i],&pmynode[i]->myevid), - "ca_create_subscription"); - } - /*Should never return from following call*/ - SEVCHK(ca_pend_event(0.0),"ca_pend_event"); - return 0; -} diff --git a/src/template/base/top/configure/CONFIG b/src/template/base/top/configure/CONFIG deleted file mode 100644 index c1a470322..000000000 --- a/src/template/base/top/configure/CONFIG +++ /dev/null @@ -1,29 +0,0 @@ -# CONFIG - Load build configuration data -# -# Do not make changes to this file! - -# Allow user to override where the build rules come from -RULES = $(EPICS_BASE) - -# RELEASE files point to other application tops -include $(TOP)/configure/RELEASE --include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common -ifdef T_A --include $(TOP)/configure/RELEASE.Common.$(T_A) --include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A) -endif - -CONFIG = $(RULES)/configure -include $(CONFIG)/CONFIG - -# Override the Base definition: -INSTALL_LOCATION = $(TOP) - -# CONFIG_SITE files contain other build configuration settings -include $(TOP)/configure/CONFIG_SITE --include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).Common -ifdef T_A - -include $(TOP)/configure/CONFIG_SITE.Common.$(T_A) - -include $(TOP)/configure/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) -endif - diff --git a/src/template/base/top/configure/CONFIG_SITE b/src/template/base/top/configure/CONFIG_SITE deleted file mode 100644 index 212485ebe..000000000 --- a/src/template/base/top/configure/CONFIG_SITE +++ /dev/null @@ -1,43 +0,0 @@ -# CONFIG_SITE - -# Make any application-specific changes to the EPICS build -# configuration variables in this file. -# -# Host/target specific settings can be specified in files named -# CONFIG_SITE.$(EPICS_HOST_ARCH).Common -# CONFIG_SITE.Common.$(T_A) -# CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) - -# CHECK_RELEASE controls the consistency checking of the support -# applications pointed to by the RELEASE* files. -# Normally CHECK_RELEASE should be set to YES. -# Set CHECK_RELEASE to NO to disable checking completely. -# Set CHECK_RELEASE to WARN to perform consistency checking but -# continue building even if conflicts are found. -CHECK_RELEASE = YES - -# Set this when you only want to compile this application -# for a subset of the cross-compiled target architectures -# that Base is built for. -#CROSS_COMPILER_TARGET_ARCHS = vxWorks-ppc32 - -# To install files into a location other than $(TOP) define -# INSTALL_LOCATION here. -#INSTALL_LOCATION= - -# Set this when the IOC and build host use different paths -# to the install location. This may be needed to boot from -# a Microsoft FTP server say, or on some NFS configurations. -#IOCS_APPL_TOP = - -# For application debugging purposes, override the HOST_OPT and/ -# or CROSS_OPT settings from base/configure/CONFIG_SITE -#HOST_OPT = NO -#CROSS_OPT = NO - -# These allow developers to override the CONFIG_SITE variable -# settings without having to modify the configure/CONFIG_SITE -# file itself. --include $(TOP)/../CONFIG_SITE.local --include $(TOP)/configure/CONFIG_SITE.local - diff --git a/src/template/base/top/configure/Makefile b/src/template/base/top/configure/Makefile deleted file mode 100644 index 925430940..000000000 --- a/src/template/base/top/configure/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -TOP=.. - -include $(TOP)/configure/CONFIG - -TARGETS = $(CONFIG_TARGETS) -CONFIGS += $(subst ../,,$(wildcard $(CONFIG_INSTALLS))) - -include $(TOP)/configure/RULES diff --git a/src/template/base/top/configure/RELEASE b/src/template/base/top/configure/RELEASE deleted file mode 100644 index dbd742b45..000000000 --- a/src/template/base/top/configure/RELEASE +++ /dev/null @@ -1,43 +0,0 @@ -# RELEASE - Location of external support modules -# -# IF YOU MAKE ANY CHANGES to this file you must subsequently -# do a "gnumake rebuild" in this application's top level -# directory. -# -# The build process does not check dependencies against files -# that are outside this application, thus you should do a -# "gnumake rebuild" in the top level directory after EPICS_BASE -# or any other external module pointed to below is rebuilt. -# -# Host- or target-specific settings can be given in files named -# RELEASE.$(EPICS_HOST_ARCH).Common -# RELEASE.Common.$(T_A) -# RELEASE.$(EPICS_HOST_ARCH).$(T_A) -# -# This file is parsed by both GNUmake and an EPICS Perl script, -# so it can ONLY contain definititions of paths to other support -# modules, variable definitions that are used in module paths, -# and include statements that pull in other RELEASE files. -# Variables may be used before their values have been set. -# Build variables that are NOT used in paths should be set in -# the CONFIG_SITE file. - -# Variables and paths to dependent modules: -#MODULES = /path/to/modules -#MYMODULE = $(MODULES)/my-module - -# If using the sequencer, point SNCSEQ at its top directory: -#SNCSEQ = $(MODULES)/seq-ver - -# EPICS_BASE should appear last so earlier modules can override stuff: -EPICS_BASE = _EPICS_BASE_ - -# Set RULES here if you want to use build rules from somewhere -# other than EPICS_BASE: -#RULES = $(MODULES)/build-rules - -# These allow developers to override the RELEASE variable settings -# without having to modify the configure/RELEASE file itself. --include $(TOP)/../RELEASE.local --include $(TOP)/configure/RELEASE.local - diff --git a/src/template/base/top/configure/RULES b/src/template/base/top/configure/RULES deleted file mode 100644 index 6d56e14e8..000000000 --- a/src/template/base/top/configure/RULES +++ /dev/null @@ -1,6 +0,0 @@ -# RULES - -include $(CONFIG)/RULES - -# Library should be rebuilt because LIBOBJS may have changed. -$(LIBNAME): ../Makefile diff --git a/src/template/base/top/configure/RULES.ioc b/src/template/base/top/configure/RULES.ioc deleted file mode 100644 index 901987c6c..000000000 --- a/src/template/base/top/configure/RULES.ioc +++ /dev/null @@ -1,2 +0,0 @@ -#RULES.ioc -include $(CONFIG)/RULES.ioc diff --git a/src/template/base/top/configure/RULES_DIRS b/src/template/base/top/configure/RULES_DIRS deleted file mode 100644 index 3ba269dcc..000000000 --- a/src/template/base/top/configure/RULES_DIRS +++ /dev/null @@ -1,2 +0,0 @@ -#RULES_DIRS -include $(CONFIG)/RULES_DIRS diff --git a/src/template/base/top/configure/RULES_TOP b/src/template/base/top/configure/RULES_TOP deleted file mode 100644 index d09d668d5..000000000 --- a/src/template/base/top/configure/RULES_TOP +++ /dev/null @@ -1,3 +0,0 @@ -#RULES_TOP -include $(CONFIG)/RULES_TOP - diff --git a/src/template/base/top/exampleApp/Db/Makefile b/src/template/base/top/exampleApp/Db/Makefile deleted file mode 100644 index 679bba60c..000000000 --- a/src/template/base/top/exampleApp/Db/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -TOP=../.. -include $(TOP)/configure/CONFIG -#---------------------------------------- -# ADD MACRO DEFINITIONS BELOW HERE - -# Install databases, templates & substitutions like this -DB += dbExample1.db -DB += dbExample2.db -DB += _APPNAME_Version.db -DB += dbSubExample.db -DB += user.substitutions - -# If .db template is not named *.template add -# _TEMPLATE = - -include $(TOP)/configure/RULES -#---------------------------------------- -# ADD EXTRA GNUMAKE RULES BELOW HERE - diff --git a/src/template/base/top/exampleApp/Db/_APPNAME_Version.db b/src/template/base/top/exampleApp/Db/_APPNAME_Version.db deleted file mode 100644 index 1b03f08ba..000000000 --- a/src/template/base/top/exampleApp/Db/_APPNAME_Version.db +++ /dev/null @@ -1,6 +0,0 @@ -record(lsi, "$(user):_APPNAME_:version") { - field(DTYP, "_APPNAME_ version") - field(DESC, "Version string") - field(SIZV, "$(SIZV=200)") - field(PINI, "YES") -} diff --git a/src/template/base/top/exampleApp/Db/dbExample1.db b/src/template/base/top/exampleApp/Db/dbExample1.db deleted file mode 100644 index 4f16adac9..000000000 --- a/src/template/base/top/exampleApp/Db/dbExample1.db +++ /dev/null @@ -1,62 +0,0 @@ -record(ai, "$(user):aiExample") -{ - field(DESC, "Analog input") - field(INP, "$(user):calcExample.VAL NPP NMS") - field(EGUF, "10") - field(EGU, "Counts") - field(HOPR, "10") - field(LOPR, "0") - field(HIHI, "8") - field(HIGH, "6") - field(LOW, "4") - field(LOLO, "2") - field(HHSV, "MAJOR") - field(HSV, "MINOR") - field(LSV, "MINOR") - field(LLSV, "MAJOR") -} -record(calc, "$(user):calcExample") -{ - field(DESC, "Counter") - field(SCAN,"1 second") - field(FLNK, "$(user):aiExample") - field(CALC, "(A/dbd -DBD += xxxSupport.dbd - -# Build an IOC support library -LIBRARY_IOC += _APPNAME_Support - -# Compile and add code to the support library -_APPNAME_Support_SRCS += xxxRecord.c -_APPNAME_Support_SRCS += devXxxSoft.c - -# Link locally-provided code into the support library, -# rather than directly into the IOC application, that -# causes problems on Windows DLL builds -_APPNAME_Support_SRCS += dbSubExample.c -_APPNAME_Support_SRCS += dev_APPNAME_Version.c -_APPNAME_Support_SRCS += _APPNAME_Hello.c -_APPNAME_Support_SRCS += initTrace.c - -_APPNAME_Support_LIBS += $(EPICS_BASE_IOC_LIBS) - -# Auto-generate a header file containing a version string. -# Version comes from the VCS if available, else date+time. -GENVERSION = _APPNAME_Version.h -# Macro name -GENVERSIONMACRO = _APPNAME_VERSION - -# Build the IOC application -PROD_IOC = _APPNAME_ - -# _APPNAME_.dbd will be created and installed -DBD += _APPNAME_.dbd - -# _APPNAME_.dbd will include these files: -_APPNAME__DBD += base.dbd -_APPNAME__DBD += xxxSupport.dbd -_APPNAME__DBD += dbSubExample.dbd -_APPNAME__DBD += dev_APPNAME_Version.dbd -_APPNAME__DBD += _APPNAME_Hello.dbd -_APPNAME__DBD += initTrace.dbd - -# _APPNAME__registerRecordDeviceDriver.cpp derives from _APPNAME_.dbd -_APPNAME__SRCS += _APPNAME__registerRecordDeviceDriver.cpp - -# Build the main IOC entry point where needed -_APPNAME__SRCS_DEFAULT += _APPNAME_Main.cpp -_APPNAME__SRCS_vxWorks += -nil- - -# Link in the code from our support library -_APPNAME__LIBS += _APPNAME_Support - -# To build SNL programs, SNCSEQ must be defined -# in the /configure/RELEASE file -ifneq ($(SNCSEQ),) - # Build sncExample into _APPNAME_Support - sncExample_SNCFLAGS += +r - _APPNAME__DBD += sncExample.dbd - # A .stt sequence program is *not* pre-processed: - _APPNAME_Support_SRCS += sncExample.stt - _APPNAME_Support_LIBS += seq pv - _APPNAME__LIBS += seq pv - - # Build sncProgram as a standalone program - PROD_HOST += sncProgram - sncProgram_SNCFLAGS += +m - # A .st sequence program *is* pre-processed: - sncProgram_SRCS += sncProgram.st - sncProgram_LIBS += seq pv - sncProgram_LIBS += $(EPICS_BASE_HOST_LIBS) -endif - -# Finally link IOC to the EPICS Base libraries -_APPNAME__LIBS += $(EPICS_BASE_IOC_LIBS) - -include $(TOP)/configure/RULES -#---------------------------------------- -# ADD EXTRA GNUMAKE RULES BELOW HERE - -# Explicit dependency needed for generated header file -dev_APPNAME_Version$(DEP): $(COMMON_DIR)/$(GENVERSION) diff --git a/src/template/base/top/exampleApp/src/_APPNAME_Hello.c b/src/template/base/top/exampleApp/src/_APPNAME_Hello.c deleted file mode 100644 index 6582b84a4..000000000 --- a/src/template/base/top/exampleApp/src/_APPNAME_Hello.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Example showing how to register a new command with iocsh */ - -#include - -#include -#include - -/* This is the command, which the vxWorks shell will call directly */ -void hello(const char *name) { - if (name) { - printf("Hello %s, from _APPNAME_\n", name); - } else { - puts("Hello from _APPNAME_"); - } -} - -/* Information needed by iocsh */ -static const iocshArg helloArg0 = {"name", iocshArgString}; -static const iocshArg *helloArgs[] = {&helloArg0}; -static const iocshFuncDef helloFuncDef = {"hello", 1, helloArgs}; - -/* Wrapper called by iocsh, selects the argument types that hello needs */ -static void helloCallFunc(const iocshArgBuf *args) { - hello(args[0].sval); -} - -/* Registration routine, runs at startup */ -static void helloRegister(void) { - iocshRegister(&helloFuncDef, helloCallFunc); -} -epicsExportRegistrar(helloRegister); diff --git a/src/template/base/top/exampleApp/src/_APPNAME_Hello.dbd b/src/template/base/top/exampleApp/src/_APPNAME_Hello.dbd deleted file mode 100644 index 64eb0389a..000000000 --- a/src/template/base/top/exampleApp/src/_APPNAME_Hello.dbd +++ /dev/null @@ -1 +0,0 @@ -registrar(helloRegister) diff --git a/src/template/base/top/exampleApp/src/_APPNAME_Main.cpp b/src/template/base/top/exampleApp/src/_APPNAME_Main.cpp deleted file mode 100644 index ae0ecb68a..000000000 --- a/src/template/base/top/exampleApp/src/_APPNAME_Main.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* _APPNAME_Main.cpp */ -/* Author: Marty Kraimer Date: 17MAR2000 */ - -#include -#include -#include -#include -#include - -#include "epicsExit.h" -#include "epicsThread.h" -#include "iocsh.h" - -int main(int argc,char *argv[]) -{ - if(argc>=2) { - iocsh(argv[1]); - epicsThreadSleep(.2); - } - iocsh(NULL); - epicsExit(0); - return(0); -} diff --git a/src/template/base/top/exampleApp/src/dbSubExample.c b/src/template/base/top/exampleApp/src/dbSubExample.c deleted file mode 100644 index 1cc748b12..000000000 --- a/src/template/base/top/exampleApp/src/dbSubExample.c +++ /dev/null @@ -1,49 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -int mySubDebug; - -static long mySubInit(subRecord *precord) -{ - if (mySubDebug) - printf("Record %s called mySubInit(%p)\n", - precord->name, (void*) precord); - return 0; -} - -static long mySubProcess(subRecord *precord) -{ - if (mySubDebug) - printf("Record %s called mySubProcess(%p)\n", - precord->name, (void*) precord); - return 0; -} - -static long myAsubInit(aSubRecord *precord) -{ - if (mySubDebug) - printf("Record %s called myAsubInit(%p)\n", - precord->name, (void*) precord); - return 0; -} - -static long myAsubProcess(aSubRecord *precord) -{ - if (mySubDebug) - printf("Record %s called myAsubProcess(%p)\n", - precord->name, (void*) precord); - return 0; -} - -/* Register these symbols for use by IOC code: */ - -epicsExportAddress(int, mySubDebug); -epicsRegisterFunction(mySubInit); -epicsRegisterFunction(mySubProcess); -epicsRegisterFunction(myAsubInit); -epicsRegisterFunction(myAsubProcess); diff --git a/src/template/base/top/exampleApp/src/dbSubExample.dbd b/src/template/base/top/exampleApp/src/dbSubExample.dbd deleted file mode 100644 index 5f6e40ac7..000000000 --- a/src/template/base/top/exampleApp/src/dbSubExample.dbd +++ /dev/null @@ -1,5 +0,0 @@ -variable(mySubDebug) -function(mySubInit) -function(mySubProcess) -function(myAsubInit) -function(myAsubProcess) diff --git a/src/template/base/top/exampleApp/src/devXxxSoft.c b/src/template/base/top/exampleApp/src/devXxxSoft.c deleted file mode 100644 index 0507fdfd0..000000000 --- a/src/template/base/top/exampleApp/src/devXxxSoft.c +++ /dev/null @@ -1,58 +0,0 @@ -/* devXxxSoft.c */ -/* Example device support module */ - -#include -#include -#include -#include - -#include "alarm.h" -#include "cvtTable.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "recSup.h" -#include "devSup.h" -#include "link.h" -#include "xxxRecord.h" -#include "epicsExport.h" - -/*Create the dset for devXxxSoft */ -static long init_record(); -static long read_xxx(); -struct { - long number; - DEVSUPFUN report; - DEVSUPFUN init; - DEVSUPFUN init_record; - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_xxx; -}devXxxSoft={ - 5, - NULL, - NULL, - init_record, - NULL, - read_xxx, -}; -epicsExportAddress(dset,devXxxSoft); - - -static long init_record(pxxx) - struct xxxRecord *pxxx; -{ - if(recGblInitConstantLink(&pxxx->inp,DBF_DOUBLE,&pxxx->val)) - pxxx->udf = FALSE; - return(0); -} - -static long read_xxx(pxxx) - struct xxxRecord *pxxx; -{ - long status; - - status = dbGetLink(&(pxxx->inp),DBF_DOUBLE, &(pxxx->val),0,0); - /*If return was succesful then set undefined false*/ - if(!status) pxxx->udf = FALSE; - return(0); -} diff --git a/src/template/base/top/exampleApp/src/dev_APPNAME_Version.c b/src/template/base/top/exampleApp/src/dev_APPNAME_Version.c deleted file mode 100644 index 4f2c28f67..000000000 --- a/src/template/base/top/exampleApp/src/dev_APPNAME_Version.c +++ /dev/null @@ -1,38 +0,0 @@ -/* dev_APPNAME_Version.c */ -/* Example device support for the lsi (long string input) record - * providing the module version string as the value - */ - -#include -#include -#include - -#include "devSup.h" -#include "lsiRecord.h" - -#include "_APPNAME_Version.h" - -/* must be last include */ -#include "epicsExport.h" - -const char const version[] = _APPNAME_VERSION; - -static long read_string(lsiRecord *prec) -{ - size_t N = sizeof version; - char *buf = prec->val; - - if (N > prec->sizv) - N = prec->sizv; - prec->len = N; - - memcpy(buf, version, N); - buf[N - 1] = '\0'; - - return 0; -} - -static lsidset dev_CSAFEAPPNAME_Version = { - 5, NULL, NULL, NULL, NULL, read_string -}; -epicsExportAddress(dset,dev_CSAFEAPPNAME_Version); diff --git a/src/template/base/top/exampleApp/src/dev_APPNAME_Version.dbd b/src/template/base/top/exampleApp/src/dev_APPNAME_Version.dbd deleted file mode 100644 index 67295f3f0..000000000 --- a/src/template/base/top/exampleApp/src/dev_APPNAME_Version.dbd +++ /dev/null @@ -1 +0,0 @@ -device(lsi,INST_IO,dev_CSAFEAPPNAME_Version,"_APPNAME_ version") diff --git a/src/template/base/top/exampleApp/src/initTrace.c b/src/template/base/top/exampleApp/src/initTrace.c deleted file mode 100644 index 50bc8e8c7..000000000 --- a/src/template/base/top/exampleApp/src/initTrace.c +++ /dev/null @@ -1,39 +0,0 @@ -/* initTrace.c */ - -/* - * An initHook routine to trace the iocInit() process. - * Prints out the name of each state as it is reached. - */ - -#include - -#include "initHooks.h" -#include "epicsExport.h" -#include "iocsh.h" - - -static void trace(initHookState state) { - printf("iocInit: Reached %s\n", initHookName(state)); -} - -int traceIocInit(void) { - static int done = 0; - if (done) - return -1; - done = 1; - - initHookRegister(trace); - puts("iocInit will be traced"); - return 0; -} - - -static const iocshFuncDef traceInitFuncDef = {"traceIocInit", 0, NULL}; -static void traceInitFunc(const iocshArgBuf *args) { - traceIocInit(); -} - -static void initTraceRegister(void) { - iocshRegister(&traceInitFuncDef, traceInitFunc); -} -epicsExportRegistrar(initTraceRegister); diff --git a/src/template/base/top/exampleApp/src/initTrace.dbd b/src/template/base/top/exampleApp/src/initTrace.dbd deleted file mode 100644 index 8083c0a50..000000000 --- a/src/template/base/top/exampleApp/src/initTrace.dbd +++ /dev/null @@ -1 +0,0 @@ -registrar(initTraceRegister) diff --git a/src/template/base/top/exampleApp/src/sncExample.dbd b/src/template/base/top/exampleApp/src/sncExample.dbd deleted file mode 100644 index df61066c3..000000000 --- a/src/template/base/top/exampleApp/src/sncExample.dbd +++ /dev/null @@ -1 +0,0 @@ -registrar(sncExampleRegistrar) diff --git a/src/template/base/top/exampleApp/src/sncExample.stt b/src/template/base/top/exampleApp/src/sncExample.stt deleted file mode 100644 index 235f3f45c..000000000 --- a/src/template/base/top/exampleApp/src/sncExample.stt +++ /dev/null @@ -1,22 +0,0 @@ -program sncExample -double v; -assign v to "{user}:aiExample"; -monitor v; - -ss ss1 { - state init { - when (delay(10)) { - printf("sncExample: Startup delay over\n"); - } state low - } - state low { - when (v > 5.0) { - printf("sncExample: Changing to high\n"); - } state high - } - state high { - when (v <= 5.0) { - printf("sncExample: Changing to low\n"); - } state low - } -} diff --git a/src/template/base/top/exampleApp/src/sncProgram.st b/src/template/base/top/exampleApp/src/sncProgram.st deleted file mode 100644 index 1ba29893e..000000000 --- a/src/template/base/top/exampleApp/src/sncProgram.st +++ /dev/null @@ -1 +0,0 @@ -#include "../sncExample.stt" diff --git a/src/template/base/top/exampleApp/src/xxxRecord.c b/src/template/base/top/exampleApp/src/xxxRecord.c deleted file mode 100644 index c2693c48e..000000000 --- a/src/template/base/top/exampleApp/src/xxxRecord.c +++ /dev/null @@ -1,273 +0,0 @@ -/* xxxRecord.c */ -/* Example record support module */ - -#include -#include -#include -#include - -#include "epicsMath.h" -#include "alarm.h" -#include "dbAccess.h" -#include "recGbl.h" -#include "dbEvent.h" -#include "dbDefs.h" -#include "dbAccess.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "special.h" -#define GEN_SIZE_OFFSET -#include "xxxRecord.h" -#undef GEN_SIZE_OFFSET -#include "epicsExport.h" - -/* Create RSET - Record Support Entry Table */ -#define report NULL -#define initialize NULL -static long init_record(struct dbCommon *, int); -static long process(struct dbCommon *); -#define special NULL -#define get_value NULL -#define cvt_dbaddr NULL -#define get_array_info NULL -#define put_array_info NULL -static long get_units(DBADDR *, char *); -static long get_precision(const DBADDR *, long *); -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -static long get_graphic_double(DBADDR *, struct dbr_grDouble *); -static long get_control_double(DBADDR *, struct dbr_ctrlDouble *); -static long get_alarm_double(DBADDR *, struct dbr_alDouble *); - -rset xxxRSET={ - RSETNUMBER, - report, - initialize, - init_record, - process, - special, - get_value, - cvt_dbaddr, - get_array_info, - put_array_info, - get_units, - get_precision, - get_enum_str, - get_enum_strs, - put_enum_str, - get_graphic_double, - get_control_double, - get_alarm_double -}; -epicsExportAddress(rset,xxxRSET); - -typedef struct xxxset { /* xxx input dset */ - long number; - DEVSUPFUN dev_report; - DEVSUPFUN init; - DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ - DEVSUPFUN get_ioint_info; - DEVSUPFUN read_xxx; -}xxxdset; - -static void checkAlarms(xxxRecord *prec); -static void monitor(xxxRecord *prec); - -static long init_record(struct dbCommon *pcommon, int pass) -{ - xxxRecord *prec = (xxxRecord *)pcommon; - xxxdset *pdset; - long status; - - if (pass==0) return(0); - - if(!(pdset = (xxxdset *)(prec->dset))) { - recGblRecordError(S_dev_noDSET,(void *)prec,"xxx: init_record"); - return(S_dev_noDSET); - } - /* must have read_xxx function defined */ - if( (pdset->number < 5) || (pdset->read_xxx == NULL) ) { - recGblRecordError(S_dev_missingSup,(void *)prec,"xxx: init_record"); - return(S_dev_missingSup); - } - - if( pdset->init_record ) { - if((status=(*pdset->init_record)(prec))) return(status); - } - return(0); -} - -static long process(struct dbCommon *pcommon) -{ - xxxRecord *prec = (xxxRecord *)pcommon; - xxxdset *pdset = (xxxdset *)(prec->dset); - long status; - unsigned char pact=prec->pact; - - if( (pdset==NULL) || (pdset->read_xxx==NULL) ) { - prec->pact=TRUE; - recGblRecordError(S_dev_missingSup,(void *)prec,"read_xxx"); - return(S_dev_missingSup); - } - - /* pact must not be set until after calling device support */ - status=(*pdset->read_xxx)(prec); - /* check if device support set pact */ - if ( !pact && prec->pact ) return(0); - prec->pact = TRUE; - - recGblGetTimeStamp(prec); - /* check for alarms */ - checkAlarms(prec); - /* check event list */ - monitor(prec); - /* process the forward scan link record */ - recGblFwdLink(prec); - - prec->pact=FALSE; - return(status); -} - -static long get_units(DBADDR *paddr, char *units) -{ - xxxRecord *prec=(xxxRecord *)paddr->precord; - - strncpy(units,prec->egu,DB_UNITS_SIZE); - return(0); -} - -static long get_precision(const DBADDR *paddr, long *precision) -{ - xxxRecord *prec=(xxxRecord *)paddr->precord; - - *precision = prec->prec; - if(paddr->pfield == (void *)&prec->val) return(0); - recGblGetPrec(paddr,precision); - return(0); -} - -static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd) -{ - xxxRecord *prec=(xxxRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if(fieldIndex == xxxRecordVAL - || fieldIndex == xxxRecordHIHI - || fieldIndex == xxxRecordHIGH - || fieldIndex == xxxRecordLOW - || fieldIndex == xxxRecordLOLO - || fieldIndex == xxxRecordHOPR - || fieldIndex == xxxRecordLOPR) { - pgd->upper_disp_limit = prec->hopr; - pgd->lower_disp_limit = prec->lopr; - } else recGblGetGraphicDouble(paddr,pgd); - return(0); -} - -static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd) -{ - xxxRecord *prec=(xxxRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if(fieldIndex == xxxRecordVAL - || fieldIndex == xxxRecordHIHI - || fieldIndex == xxxRecordHIGH - || fieldIndex == xxxRecordLOW - || fieldIndex == xxxRecordLOLO) { - pcd->upper_ctrl_limit = prec->hopr; - pcd->lower_ctrl_limit = prec->lopr; - } else recGblGetControlDouble(paddr,pcd); - return(0); -} - -static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad) -{ - xxxRecord *prec=(xxxRecord *)paddr->precord; - int fieldIndex = dbGetFieldIndex(paddr); - - if(fieldIndex == xxxRecordVAL) { - pad->upper_alarm_limit = prec->hhsv ? prec->hihi : epicsNAN; - pad->upper_warning_limit = prec->hsv ? prec->high : epicsNAN; - pad->lower_warning_limit = prec->lsv ? prec->low : epicsNAN; - pad->lower_alarm_limit = prec->llsv ? prec->lolo : epicsNAN; - } else recGblGetAlarmDouble(paddr,pad); - return(0); -} - -static void checkAlarms(xxxRecord *prec) -{ - double val; - float hyst, lalm, hihi, high, low, lolo; - unsigned short hhsv, llsv, hsv, lsv; - - if(prec->udf == TRUE ){ - recGblSetSevr(prec,UDF_ALARM,prec->udfs); - return; - } - hihi = prec->hihi; lolo = prec->lolo; high = prec->high; low = prec->low; - hhsv = prec->hhsv; llsv = prec->llsv; hsv = prec->hsv; lsv = prec->lsv; - val = prec->val; hyst = prec->hyst; lalm = prec->lalm; - - /* alarm condition hihi */ - if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ - if (recGblSetSevr(prec,HIHI_ALARM,prec->hhsv)) prec->lalm = hihi; - return; - } - - /* alarm condition lolo */ - if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ - if (recGblSetSevr(prec,LOLO_ALARM,prec->llsv)) prec->lalm = lolo; - return; - } - - /* alarm condition high */ - if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ - if (recGblSetSevr(prec,HIGH_ALARM,prec->hsv)) prec->lalm = high; - return; - } - - /* alarm condition low */ - if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ - if (recGblSetSevr(prec,LOW_ALARM,prec->lsv)) prec->lalm = low; - return; - } - - /* we get here only if val is out of alarm by at least hyst */ - prec->lalm = val; - return; -} - -static void monitor(xxxRecord *prec) -{ - unsigned short monitor_mask; - double delta; - - monitor_mask = recGblResetAlarms(prec); - /* check for value change */ - delta = prec->mlst - prec->val; - if(delta<0.0) delta = -delta; - if (delta > prec->mdel) { - /* post events for value change */ - monitor_mask |= DBE_VALUE; - /* update last value monitored */ - prec->mlst = prec->val; - } - - /* check for archive change */ - delta = prec->alst - prec->val; - if(delta<0.0) delta = -delta; - if (delta > prec->adel) { - /* post events on value field for archive change */ - monitor_mask |= DBE_LOG; - /* update last archive value monitored */ - prec->alst = prec->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(prec,&prec->val,monitor_mask); - } - return; -} diff --git a/src/template/base/top/exampleApp/src/xxxRecord.dbd b/src/template/base/top/exampleApp/src/xxxRecord.dbd deleted file mode 100644 index 12c1d6202..000000000 --- a/src/template/base/top/exampleApp/src/xxxRecord.dbd +++ /dev/null @@ -1,118 +0,0 @@ -recordtype(xxx) { - include "dbCommon.dbd" - field(VAL,DBF_DOUBLE) { - prompt("Current EGU Value") - promptgroup("40 - Input") - asl(ASL0) - pp(TRUE) - } - field(INP,DBF_INLINK) { - prompt("Input Specification") - promptgroup("40 - Input") - special(SPC_NOMOD) - interest(1) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup("80 - Display") - interest(1) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units") - promptgroup("80 - Display") - interest(1) - size(16) - } - field(HOPR,DBF_FLOAT) { - prompt("High Operating Range") - promptgroup("80 - Display") - interest(1) - } - field(LOPR,DBF_FLOAT) { - prompt("Low Operating Range") - promptgroup("80 - Display") - interest(1) - } - field(HIHI,DBF_FLOAT) { - prompt("Hihi Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - } - field(LOLO,DBF_FLOAT) { - prompt("Lolo Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - } - field(HIGH,DBF_FLOAT) { - prompt("High Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - } - field(LOW,DBF_FLOAT) { - prompt("Low Alarm Limit") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - } - field(HHSV,DBF_MENU) { - prompt("Hihi Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LLSV,DBF_MENU) { - prompt("Lolo Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HSV,DBF_MENU) { - prompt("High Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(LSV,DBF_MENU) { - prompt("Low Severity") - promptgroup("70 - Alarm") - pp(TRUE) - interest(1) - menu(menuAlarmSevr) - } - field(HYST,DBF_DOUBLE) { - prompt("Alarm Deadband") - promptgroup("70 - Alarm") - interest(1) - } - field(ADEL,DBF_DOUBLE) { - prompt("Archive Deadband") - promptgroup("80 - Display") - interest(1) - } - field(MDEL,DBF_DOUBLE) { - prompt("Monitor Deadband") - promptgroup("80 - Display") - interest(1) - } - field(LALM,DBF_DOUBLE) { - prompt("Last Value Alarmed") - special(SPC_NOMOD) - interest(3) - } - field(ALST,DBF_DOUBLE) { - prompt("Last Value Archived") - special(SPC_NOMOD) - interest(3) - } - field(MLST,DBF_DOUBLE) { - prompt("Last Val Monitored") - special(SPC_NOMOD) - interest(3) - } -} diff --git a/src/template/base/top/exampleApp/src/xxxSupport.dbd b/src/template/base/top/exampleApp/src/xxxSupport.dbd deleted file mode 100644 index 8094bdda6..000000000 --- a/src/template/base/top/exampleApp/src/xxxSupport.dbd +++ /dev/null @@ -1,2 +0,0 @@ -include "xxxRecord.dbd" -device(xxx,CONSTANT,devXxxSoft,"SoftChannel") diff --git a/src/template/base/top/exampleBoot/Makefile b/src/template/base/top/exampleBoot/Makefile deleted file mode 100644 index 91e47d0b5..000000000 --- a/src/template/base/top/exampleBoot/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -TOP = .. -include $(TOP)/configure/CONFIG -DIRS += $(wildcard *ioc*) -DIRS += $(wildcard as*) -include $(CONFIG)/RULES_DIRS - diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@Common b/src/template/base/top/exampleBoot/ioc/Makefile@Common deleted file mode 100644 index e064d7344..000000000 --- a/src/template/base/top/exampleBoot/ioc/Makefile@Common +++ /dev/null @@ -1,4 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -TARGETS = envPaths -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@cygwin b/src/template/base/top/exampleBoot/ioc/Makefile@cygwin deleted file mode 100644 index 77c3215d7..000000000 --- a/src/template/base/top/exampleBoot/ioc/Makefile@cygwin +++ /dev/null @@ -1,5 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -ARCH = _ARCH_ -TARGETS = envPaths relPaths.sh -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@vxWorks b/src/template/base/top/exampleBoot/ioc/Makefile@vxWorks deleted file mode 100644 index 12ff7f494..000000000 --- a/src/template/base/top/exampleBoot/ioc/Makefile@vxWorks +++ /dev/null @@ -1,5 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -ARCH = _ARCH_ -TARGETS = cdCommands -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@win32 b/src/template/base/top/exampleBoot/ioc/Makefile@win32 deleted file mode 100644 index 59b32d734..000000000 --- a/src/template/base/top/exampleBoot/ioc/Makefile@win32 +++ /dev/null @@ -1,5 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -ARCH = _ARCH_ -TARGETS = envPaths dllPath.bat -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/exampleBoot/ioc/Makefile@windows b/src/template/base/top/exampleBoot/ioc/Makefile@windows deleted file mode 100644 index 59b32d734..000000000 --- a/src/template/base/top/exampleBoot/ioc/Makefile@windows +++ /dev/null @@ -1,5 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -ARCH = _ARCH_ -TARGETS = envPaths dllPath.bat -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/exampleBoot/ioc/README@Common b/src/template/base/top/exampleBoot/ioc/README@Common deleted file mode 100644 index f6dc23be8..000000000 --- a/src/template/base/top/exampleBoot/ioc/README@Common +++ /dev/null @@ -1,9 +0,0 @@ -To start the ioc from this directory execute the command - ../../bin/_ARCH_/ st.cmd - -Alternatively make the st.cmd file directly executable with - chmod +x st.cmd -and check the executable name on the first line of the st.cmd file - -You may need to change the name of the .dbd file given in the -st.cmd's dbLoadDatabase() command before starting the ioc. diff --git a/src/template/base/top/exampleBoot/ioc/README@RTEMS b/src/template/base/top/exampleBoot/ioc/README@RTEMS deleted file mode 100644 index b040e848c..000000000 --- a/src/template/base/top/exampleBoot/ioc/README@RTEMS +++ /dev/null @@ -1,6 +0,0 @@ -Copy the startup script (st.cmd) and top level db and dbd directories and -contents to -<>/epics/<>/ - -Then load the executable into the IOC (floppy disk, network boot, debugger, -etc.) and start it. diff --git a/src/template/base/top/exampleBoot/ioc/README@vxWorks b/src/template/base/top/exampleBoot/ioc/README@vxWorks deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/template/base/top/exampleBoot/ioc/st.cmd@Common b/src/template/base/top/exampleBoot/ioc/st.cmd@Common deleted file mode 100644 index b2dfb4ae4..000000000 --- a/src/template/base/top/exampleBoot/ioc/st.cmd@Common +++ /dev/null @@ -1,29 +0,0 @@ -#!../../bin/_ARCH_/_APPNAME_ - -#- You may have to change _APPNAME_ to something else -#- everywhere it appears in this file - -< envPaths - -cd "${TOP}" - -## Register all support components -dbLoadDatabase "dbd/_APPNAME_.dbd" -_CSAFEAPPNAME__registerRecordDeviceDriver pdbbase - -## Load record instances -dbLoadTemplate "db/user.substitutions" -dbLoadRecords "db/_APPNAME_Version.db", "user=_USER_" -dbLoadRecords "db/dbSubExample.db", "user=_USER_" - -#- Set this to see messages from mySub -#var mySubDebug 1 - -#- Run this to trace the stages of iocInit -#traceIocInit - -cd "${TOP}/iocBoot/${IOC}" -iocInit - -## Start any sequence programs -#seq sncExample, "user=_USER_" diff --git a/src/template/base/top/exampleBoot/ioc/st.cmd@RTEMS b/src/template/base/top/exampleBoot/ioc/st.cmd@RTEMS deleted file mode 100644 index 87e9e3b13..000000000 --- a/src/template/base/top/exampleBoot/ioc/st.cmd@RTEMS +++ /dev/null @@ -1,26 +0,0 @@ -#- Example RTEMS startup script - -#- You may have to change _APPNAME_ to something else -#- everywhere it appears in this file - -#< envPaths - -## Register all support components -dbLoadDatabase("dbd/_APPNAME_.dbd") -_CSAFEAPPNAME__registerRecordDeviceDriver(pdbbase) - -## Load record instances -dbLoadTemplate("db/user.substitutions") -dbLoadRecords("db/_APPNAME_Version.db", "user=_USER_") -dbLoadRecords("db/dbSubExample.db", "user=_USER_") - -#- Set this to see messages from mySub -#var mySubDebug 1 - -#- Run this to trace the stages of iocInit -#traceIocInit - -iocInit - -## Start any sequence programs -#seq(sncExample, "user=_USER_") diff --git a/src/template/base/top/exampleBoot/ioc/st.cmd@vxWorks b/src/template/base/top/exampleBoot/ioc/st.cmd@vxWorks deleted file mode 100644 index 617ba6111..000000000 --- a/src/template/base/top/exampleBoot/ioc/st.cmd@vxWorks +++ /dev/null @@ -1,36 +0,0 @@ -#- Example vxWorks startup file - -#- The following is needed if your board support package doesn't at boot time -#- automatically cd to the directory containing its startup script -#cd "_TOP_/iocBoot/_IOC_" - -< cdCommands -#< ../nfsCommands - -cd topbin - -#- You may have to change _APPNAME_ to something else -#- everywhere it appears in this file -ld 0,0, "_APPNAME_.munch" - -## Register all support components -cd top -dbLoadDatabase "dbd/_APPNAME_.dbd" -_CSAFEAPPNAME__registerRecordDeviceDriver pdbbase - -## Load record instances -dbLoadTemplate "db/user.substitutions" -dbLoadRecords "db/_APPNAME_Version.db", "user=_USER_" -dbLoadRecords "db/dbSubExample.db", "user=_USER_" - -#- Set this to see messages from mySub -#mySubDebug = 1 - -#- Run this to trace the stages of iocInit -#traceIocInit - -cd startup -iocInit - -## Start any sequence programs -#seq &sncExample, "user=_USER_" diff --git a/src/template/base/top/exampleBoot/nfsCommands@RTEMS b/src/template/base/top/exampleBoot/nfsCommands@RTEMS deleted file mode 100644 index 18ae461fa..000000000 --- a/src/template/base/top/exampleBoot/nfsCommands@RTEMS +++ /dev/null @@ -1,26 +0,0 @@ -#- Instructions for creating and using a real nfsCommands file -#- -#- in order to use nfs do the following: -#- 1) Create hostAdd and nfsMount commands for each nfs server -#- 2) In each st.cmd file add the following two commands BEFORE any load commands -#- ../nfs.cmd -#- cd " -#- -#- The hostAdd command has the form: -#- hostAdd("","xxx.xxx.xxx.xxx") -#- -#- You can also mount subdirectories as follows: -#- nfsMount("", "/xxx/xxx/xxx", "/xxx") -#- -#- For example assume -#- -#- host is mercury with inet address 155.77.2.56 -#- You want to mount the directory (which is a file system of mercury) -#- /home/mercury5/iocinfo -#- as -#- /iocinfo -#- -#- The commands would be -#- -#- hostAdd("mercury","155.77.2.56") -#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo") diff --git a/src/template/base/top/exampleBoot/nfsCommands@vxWorks b/src/template/base/top/exampleBoot/nfsCommands@vxWorks deleted file mode 100644 index eb302c569..000000000 --- a/src/template/base/top/exampleBoot/nfsCommands@vxWorks +++ /dev/null @@ -1,29 +0,0 @@ -#- Instructions for creating and using a real nfsCommands file -#- -#- in order to use nfs do the following: -#- 1) Create hostAdd and nfsMount commands for each nfs server -#- 2) In each st.cmd file add the following two commands BEFORE any load commands -#- ../nfs.cmd -#- cd " -#- -#- The hostAdd command has the form: -#- hostAdd("","xxx.xxx.xxx.xxx") -#- -#- The nfsMount command has the form: -#- nfsMount("", "/xxx/xxx/xxx", "/xxx") -#- -#- You can also mount subdirectories as follows: -#- nfsMountAll("") -#- -#- For example assume -#- -#- host is mercury with inet address 155.77.2.56 -#- You want to mount the directory (which is a file system of mercury) -#- /home/mercury5/iocinfo -#- as -#- /iocinfo -#- -#- The commands would be -#- -#- hostAdd("mercury","155.77.2.56") -#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo") diff --git a/src/template/base/top/iocApp/Db/Makefile b/src/template/base/top/iocApp/Db/Makefile deleted file mode 100644 index 8eb97279d..000000000 --- a/src/template/base/top/iocApp/Db/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -TOP=../.. -include $(TOP)/configure/CONFIG -#---------------------------------------- -# ADD MACRO DEFINITIONS AFTER THIS LINE - -#---------------------------------------------------- -# Create and install (or just install) into /db -# databases, templates, substitutions like this -#DB += xxx.db - -#---------------------------------------------------- -# If .db template is not named *.template add -# _template = - -include $(TOP)/configure/RULES -#---------------------------------------- -# ADD RULES AFTER THIS LINE - diff --git a/src/template/base/top/iocApp/Makefile b/src/template/base/top/iocApp/Makefile deleted file mode 100644 index 10e0126aa..000000000 --- a/src/template/base/top/iocApp/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -TOP = .. -include $(TOP)/configure/CONFIG -DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *src*)) -DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Src*)) -DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *db*)) -DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Db*)) -include $(TOP)/configure/RULES_DIRS - diff --git a/src/template/base/top/iocApp/src/Makefile b/src/template/base/top/iocApp/src/Makefile deleted file mode 100644 index de6b93a5b..000000000 --- a/src/template/base/top/iocApp/src/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -TOP=../.. - -include $(TOP)/configure/CONFIG -#---------------------------------------- -# ADD MACRO DEFINITIONS AFTER THIS LINE -#============================= - -#============================= -# Build the IOC application - -PROD_IOC = _APPNAME_ -# _APPNAME_.dbd will be created and installed -DBD += _APPNAME_.dbd - -# _APPNAME_.dbd will be made up from these files: -_APPNAME__DBD += base.dbd - -# Include dbd files from all support applications: -#_APPNAME__DBD += xxx.dbd - -# Add all the support libraries needed by this IOC -#_APPNAME__LIBS += xxx - -# _APPNAME__registerRecordDeviceDriver.cpp derives from _APPNAME_.dbd -_APPNAME__SRCS += _APPNAME__registerRecordDeviceDriver.cpp - -# Build the main IOC entry point on workstation OSs. -_APPNAME__SRCS_DEFAULT += _APPNAME_Main.cpp -_APPNAME__SRCS_vxWorks += -nil- - -# Add support from base/src/vxWorks if needed -#_APPNAME__OBJS_vxWorks += $(EPICS_BASE_BIN)/vxComLibrary - -# Finally link to the EPICS Base libraries -_APPNAME__LIBS += $(EPICS_BASE_IOC_LIBS) - -#=========================== - -include $(TOP)/configure/RULES -#---------------------------------------- -# ADD RULES AFTER THIS LINE - diff --git a/src/template/base/top/iocApp/src/_APPNAME_Main.cpp b/src/template/base/top/iocApp/src/_APPNAME_Main.cpp deleted file mode 100644 index ae0ecb68a..000000000 --- a/src/template/base/top/iocApp/src/_APPNAME_Main.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* _APPNAME_Main.cpp */ -/* Author: Marty Kraimer Date: 17MAR2000 */ - -#include -#include -#include -#include -#include - -#include "epicsExit.h" -#include "epicsThread.h" -#include "iocsh.h" - -int main(int argc,char *argv[]) -{ - if(argc>=2) { - iocsh(argv[1]); - epicsThreadSleep(.2); - } - iocsh(NULL); - epicsExit(0); - return(0); -} diff --git a/src/template/base/top/iocBoot/Makefile b/src/template/base/top/iocBoot/Makefile deleted file mode 100644 index 91e47d0b5..000000000 --- a/src/template/base/top/iocBoot/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -TOP = .. -include $(TOP)/configure/CONFIG -DIRS += $(wildcard *ioc*) -DIRS += $(wildcard as*) -include $(CONFIG)/RULES_DIRS - diff --git a/src/template/base/top/iocBoot/ioc/Makefile@Common b/src/template/base/top/iocBoot/ioc/Makefile@Common deleted file mode 100644 index e064d7344..000000000 --- a/src/template/base/top/iocBoot/ioc/Makefile@Common +++ /dev/null @@ -1,4 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -TARGETS = envPaths -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/iocBoot/ioc/Makefile@cygwin b/src/template/base/top/iocBoot/ioc/Makefile@cygwin deleted file mode 100644 index 77c3215d7..000000000 --- a/src/template/base/top/iocBoot/ioc/Makefile@cygwin +++ /dev/null @@ -1,5 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -ARCH = _ARCH_ -TARGETS = envPaths relPaths.sh -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/iocBoot/ioc/Makefile@vxWorks b/src/template/base/top/iocBoot/ioc/Makefile@vxWorks deleted file mode 100644 index 12ff7f494..000000000 --- a/src/template/base/top/iocBoot/ioc/Makefile@vxWorks +++ /dev/null @@ -1,5 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -ARCH = _ARCH_ -TARGETS = cdCommands -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/iocBoot/ioc/Makefile@win32 b/src/template/base/top/iocBoot/ioc/Makefile@win32 deleted file mode 100644 index 59b32d734..000000000 --- a/src/template/base/top/iocBoot/ioc/Makefile@win32 +++ /dev/null @@ -1,5 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -ARCH = _ARCH_ -TARGETS = envPaths dllPath.bat -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/iocBoot/ioc/Makefile@windows b/src/template/base/top/iocBoot/ioc/Makefile@windows deleted file mode 100644 index 59b32d734..000000000 --- a/src/template/base/top/iocBoot/ioc/Makefile@windows +++ /dev/null @@ -1,5 +0,0 @@ -TOP = ../.. -include $(TOP)/configure/CONFIG -ARCH = _ARCH_ -TARGETS = envPaths dllPath.bat -include $(TOP)/configure/RULES.ioc diff --git a/src/template/base/top/iocBoot/ioc/st.cmd@Common b/src/template/base/top/iocBoot/ioc/st.cmd@Common deleted file mode 100644 index dd0811dfb..000000000 --- a/src/template/base/top/iocBoot/ioc/st.cmd@Common +++ /dev/null @@ -1,21 +0,0 @@ -#!../../bin/_ARCH_/_APPNAME_ - -#- You may have to change _APPNAME_ to something else -#- everywhere it appears in this file - -< envPaths - -cd "${TOP}" - -## Register all support components -dbLoadDatabase "dbd/_APPNAME_.dbd" -_CSAFEAPPNAME__registerRecordDeviceDriver pdbbase - -## Load record instances -#dbLoadRecords("db/xxx.db","user=_USER_") - -cd "${TOP}/iocBoot/${IOC}" -iocInit - -## Start any sequence programs -#seq sncxxx,"user=_USER_" diff --git a/src/template/base/top/iocBoot/ioc/st.cmd@Cross b/src/template/base/top/iocBoot/ioc/st.cmd@Cross deleted file mode 100644 index f42a26c1b..000000000 --- a/src/template/base/top/iocBoot/ioc/st.cmd@Cross +++ /dev/null @@ -1,18 +0,0 @@ -#!../../bin/_ARCH_/_APPNAME_ - -#- You may have to change _APPNAME_ to something else -#- everywhere it appears in this file - -#< envPaths - -## Register all support components -dbLoadDatabase("../../dbd/_APPNAME_.dbd",0,0) -_CSAFEAPPNAME__registerRecordDeviceDriver(pdbbase) - -## Load record instances -dbLoadRecords("../../db/_APPNAME_.db","user=_USER_") - -iocInit() - -## Start any sequence programs -#seq snc_APPNAME_,"user=_USER_" diff --git a/src/template/base/top/iocBoot/ioc/st.cmd@RTEMS b/src/template/base/top/iocBoot/ioc/st.cmd@RTEMS deleted file mode 100644 index a7d08fbcf..000000000 --- a/src/template/base/top/iocBoot/ioc/st.cmd@RTEMS +++ /dev/null @@ -1,19 +0,0 @@ -#- Example RTEMS startup script - -#- You may have to change _APPNAME_ to something else -#- everywhere it appears in this file - -#< envPaths - -## Register all support components -dbLoadDatabase("dbd/_APPNAME_.dbd") -_CSAFEAPPNAME__registerRecordDeviceDriver(pdbbase) - -## Load record instances -#dbLoadTemplate("db/_APPNAME_.substitutions") -#dbLoadRecords("db/_APPNAME_.db", "user=_USER_") - -iocInit - -## Start any sequence programs -#seq(sncxxx, "user=_USER_") diff --git a/src/template/base/top/iocBoot/ioc/st.cmd@vxWorks b/src/template/base/top/iocBoot/ioc/st.cmd@vxWorks deleted file mode 100644 index 43287d68b..000000000 --- a/src/template/base/top/iocBoot/ioc/st.cmd@vxWorks +++ /dev/null @@ -1,29 +0,0 @@ -#- Example vxWorks startup file - -#- The following is needed if your board support package doesn't at boot time -#- automatically cd to the directory containing its startup script -#cd "_TOP_/iocBoot/_IOC_" - -< cdCommands -#< ../nfsCommands - -cd topbin - -## You may have to change _APPNAME_ to something else -## everywhere it appears in this file -ld 0,0, "_APPNAME_.munch" - -## Register all support components -cd top -dbLoadDatabase "dbd/_APPNAME_.dbd" -_CSAFEAPPNAME__registerRecordDeviceDriver pdbbase - -## Load record instances -#dbLoadTemplate "db/_APPNAME_.substitutions" -#dbLoadRecords "db/_APPNAME_.db", "user=_USER_" - -cd startup -iocInit - -## Start any sequence programs -#seq &sncxxx, "user=_USER_" diff --git a/src/template/base/top/iocBoot/nfsCommands@RTEMS b/src/template/base/top/iocBoot/nfsCommands@RTEMS deleted file mode 100644 index dd8811319..000000000 --- a/src/template/base/top/iocBoot/nfsCommands@RTEMS +++ /dev/null @@ -1,29 +0,0 @@ -#- Instructions for creating and using a real nfsCommands file -#- -#- in order to use nfs do the following: -#- 1) Create hostAdd and nfsMount commands for each nfs server -#- 2) In each st.cmd file add the following two commands BEFORE any load commands -#- ../nfs.cmd -#- cd " -#- -#- The hostAdd command has the form: -#- hostAdd("","xxx.xxx.xxx.xxx") -#- -#- The vxWorks nfsMount command has the form: -#- nfsMount("") -#- -#- You can also mount subdirectories as follows: -#- nfsMount("", "/xxx/xxx/xxx", "/xxx") -#- -#- For example assume -#- -#- host is mercury with inet address 155.77.2.56 -#- You want to mount the directory (which is a file system of mercury) -#- /home/mercury5/iocinfo -#- as -#- /iocinfo -#- -#- The commands would be -#- -#- hostAdd("mercury","155.77.2.56") -#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo") diff --git a/src/template/base/top/iocBoot/nfsCommands@vxWorks b/src/template/base/top/iocBoot/nfsCommands@vxWorks deleted file mode 100644 index dd8811319..000000000 --- a/src/template/base/top/iocBoot/nfsCommands@vxWorks +++ /dev/null @@ -1,29 +0,0 @@ -#- Instructions for creating and using a real nfsCommands file -#- -#- in order to use nfs do the following: -#- 1) Create hostAdd and nfsMount commands for each nfs server -#- 2) In each st.cmd file add the following two commands BEFORE any load commands -#- ../nfs.cmd -#- cd " -#- -#- The hostAdd command has the form: -#- hostAdd("","xxx.xxx.xxx.xxx") -#- -#- The vxWorks nfsMount command has the form: -#- nfsMount("") -#- -#- You can also mount subdirectories as follows: -#- nfsMount("", "/xxx/xxx/xxx", "/xxx") -#- -#- For example assume -#- -#- host is mercury with inet address 155.77.2.56 -#- You want to mount the directory (which is a file system of mercury) -#- /home/mercury5/iocinfo -#- as -#- /iocinfo -#- -#- The commands would be -#- -#- hostAdd("mercury","155.77.2.56") -#- nfsMount("mercury","/home/mercury5/iocinfo","/iocinfo") diff --git a/src/template/base/top/supportApp/Db/Makefile b/src/template/base/top/supportApp/Db/Makefile deleted file mode 100644 index 8eb97279d..000000000 --- a/src/template/base/top/supportApp/Db/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -TOP=../.. -include $(TOP)/configure/CONFIG -#---------------------------------------- -# ADD MACRO DEFINITIONS AFTER THIS LINE - -#---------------------------------------------------- -# Create and install (or just install) into /db -# databases, templates, substitutions like this -#DB += xxx.db - -#---------------------------------------------------- -# If .db template is not named *.template add -# _template = - -include $(TOP)/configure/RULES -#---------------------------------------- -# ADD RULES AFTER THIS LINE - diff --git a/src/template/base/top/supportApp/Makefile b/src/template/base/top/supportApp/Makefile deleted file mode 100644 index ab15bfb1c..000000000 --- a/src/template/base/top/supportApp/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -TOP = .. -include $(TOP)/configure/CONFIG -DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *src*)) -DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Src*)) -DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *db*)) -DIRS := $(DIRS) $(filter-out $(DIRS), $(wildcard *Db*)) -include $(TOP)/configure/RULES_DIRS diff --git a/src/template/base/top/supportApp/src/Makefile b/src/template/base/top/supportApp/src/Makefile deleted file mode 100644 index 941d94f8b..000000000 --- a/src/template/base/top/supportApp/src/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -TOP=../.. - -include $(TOP)/configure/CONFIG -#---------------------------------------- -# ADD MACRO DEFINITIONS AFTER THIS LINE -#============================= - -#================================================== -# build a support library - -LIBRARY_IOC += _APPNAME_ - -# xxxRecord.h will be created from xxxRecord.dbd -#DBDINC += xxxRecord -# install _APPNAME_.dbd into /dbd -DBD += _APPNAME_.dbd - -# specify all source files to be compiled and added to the library -#_APPNAME__SRCS += xxx - -_APPNAME__LIBS += $(EPICS_BASE_IOC_LIBS) - -#=========================== - -include $(TOP)/configure/RULES -#---------------------------------------- -# ADD RULES AFTER THIS LINE - diff --git a/src/template/base/top/supportApp/src/_APPNAME_.dbd b/src/template/base/top/supportApp/src/_APPNAME_.dbd deleted file mode 100644 index e70223b19..000000000 --- a/src/template/base/top/supportApp/src/_APPNAME_.dbd +++ /dev/null @@ -1,6 +0,0 @@ -# provide definitions such as -#include "xxxRecord.dbd" -#device(xxx,CONSTANT,devXxxSoft,"SoftChannel") -#driver(myDriver) -#registrar(myRegistrar) -#variable(myVariable) diff --git a/src/template/ext/Makefile b/src/template/ext/Makefile deleted file mode 100644 index 06c529aa1..000000000 --- a/src/template/ext/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -TOP=../../.. - -include $(TOP)/configure/CONFIG - -TEMPLATES_DIR = makeBaseExt - -TEMPLATES += top/Makefile -TEMPLATES += top/README -TEMPLATES += top/configure/CONFIG -TEMPLATES += top/configure/CONFIG_SITE -TEMPLATES += top/configure/Makefile -TEMPLATES += top/configure/RELEASE -TEMPLATES += top/configure/RULES -TEMPLATES += top/configure/RULES_DIRS -TEMPLATES += top/configure/RULES_TOP -TEMPLATES += top/configure/RULES_PYTHON -TEMPLATES += top/configure/RULES_IDL - -TEMPLATES += $(subst ../,,$(wildcard ../top/configure/os/CONFIG*)) - -TEMPLATES += top/src/Makefile - -TEMPLATES += top/exampleExt/Makefile -TEMPLATES += top/exampleExt/caExample.c -TEMPLATES += top/exampleExt/RELEASE_NOTES.HTM - -TEMPLATES += top/simpleExt/Makefile - -SCRIPTS_HOST += makeBaseExt.pl - -include $(TOP)/configure/RULES - diff --git a/src/template/ext/makeBaseExt.pl b/src/template/ext/makeBaseExt.pl deleted file mode 100644 index a3bf895d8..000000000 --- a/src/template/ext/makeBaseExt.pl +++ /dev/null @@ -1,307 +0,0 @@ -#!/usr/bin/env perl - -# Authors: Ralph Lange, Marty Kraimer, Andrew Johnson and Janet Anderson - -use Cwd; -use Getopt::Std; -use File::Copy; -use File::Find; -use File::Path; - -$user = GetUser(); -$cwd = cwd(); -$eEXTTYPE = $ENV{EPICS_MBE_DEF_EXT_TYPE}; -$eTOP = $ENV{EPICS_MBE_TEMPLATE_TOP}; -$eBASE = $ENV{EPICS_MBE_BASE}; - -get_commandline_opts(); # Read and check options - -$extname = "@ARGV"; - -# -# Declare two default callback routines for file copy plus two -# hook routines to add conversions -# These may be overriden within $top/$exttypename/Replace.pl - -# First: the hooks -sub ReplaceFilenameHook { return $_[0]; } -sub ReplaceLineHook { return $_[0]; } - -# ReplaceFilename -# called with the source (template) file or directory name, returns -# the "real" name (which gets the target after $top is removed) -# Empty string: Don't copy this file -sub ReplaceFilename { # (filename) - my($file) = $_[0]; - $file =~ s|.*/CVS/?.*||; # Ignore CVS files - if ($ext) { # exttypenameExt itself is dynamic, too - $file =~ s|/$exttypename|/$extdir|; - $file =~ s|/$extdir/configure|/configure/$exttype|; - } - $file =~ s|_EXTNAME_|$extname|; - $file =~ s|_EXTTYPE_|$exttype|; - # We don't want the Replace overrides - $file =~ s|.*/$extdir/Replace.pl$||; - $file = ReplaceFilenameHook($file); # Call the user-defineable hook - return $file; -} - -# ReplaceLine -# called with one line of a file, returns the line after replacing -# this and that -sub ReplaceLine { # (line) - my($line) = $_[0]; - $line =~ s/_USER_/$user/o; - $line =~ s/_EPICS_BASE_/$epics_base/o; - $line =~ s/_ARCH_/$arch/o; - $line =~ s/_EXTNAME_/$extname/o; - $line =~ s/_EXTTYPE_/$exttype/o; - $line =~ s/_TEMPLATE_TOP_/$top/o; - $line = ReplaceLineHook($line); # Call the user-defineable hook - return $line; -} - -# Source replace overrides for file copy -if (-r "$top/$exttypename/Replace.pl") { - require "$top/$exttypename/Replace.pl"; -} - -# -# Copy files and trees from (non-Ext) if not present -# -opendir TOPDIR, "$top" or die "Can't open $top: $!"; -foreach $f ( grep !/^\.\.?$|^[^\/]*(Ext)/, readdir TOPDIR ) { - if (-f "$f") { - CopyFile("$top/$f") unless (-e "$f"); - } else { - $note = yes if ("$f" eq "src" && -e "$f"); - find(\&FCopyTree, "$top/$f") unless (-e "$f"); - } -} -closedir TOPDIR; - -# -# Create ext directories (if any names given) -# -$cwdsave = $cwd; -$cwd = "$cwd/src"; -foreach $ext ( @ARGV ) { - ($extname = $ext) =~ s/Ext$//; - $extdir = $extname; - if (-d "src/$extdir") { - print "Extention $extname is already there!\n"; - next; - } - print "Creating template structure " - . "for $extname (of type $exttypename)\n" if $Debug; - find(\&FCopyTree, "$top/$exttypename/"); - if ($note) { - print "\nNOTE: You must add the line \"DIRS += $extname\" to src/Makefile.\n\n"; - } -} -$cwd = $cwdsave; - -exit 0; # END OF SCRIPT - -# -# Get commandline options and check for validity -# -sub get_commandline_opts { #no args - ($len = @ARGV) and getopts("ldit:T:b:a:") or Cleanup(1); - -# Debug option - $Debug = 1 if $opt_d; - -# Locate epics_base - my ($command) = UnixPath($0); - if ($opt_b) { # first choice is -b base - $epics_base = UnixPath($opt_b); - } elsif (-r "configure/RELEASE") { # second choice is configure/RELEASE - open(IN, "configure/RELEASE") or die "Cannot open configure/RELEASE"; - while () { - chomp; - s/EPICS_BASE\s*=\s*// and $epics_base = UnixPath($_), break; - } - close IN; - } elsif ($eBASE) { # third choice is env var EPICS_MBE_BASE - $epics_base = UnixPath($eBASE); - } elsif ($command =~ m|/bin/|) { # assume script was called with full path to base - $epics_base = $command; - $epics_base =~ s|(/.*)/bin/.*makeBaseExt.*|$1|; - } - "$epics_base" or Cleanup(1, "Cannot find EPICS base"); - -# Locate template top directory - if ($opt_T) { # first choice is -T templ-top - $top = UnixPath($opt_T); - } elsif (-r "configure/RELEASE") { # second choice is configure/RELEASE - open(IN, "configure/RELEASE") or die "Cannot open configure/RELEASE"; - while () { - chomp; - s/TEMPLATE_TOP\s*=\s*// and $top = UnixPath($_), break; - } - close IN; - } - if("$top" eq "") { - if ($eTOP) { # third choice is $ENV{EPICS_MBE_TEMPL_TOP} - $top = UnixPath($eTOP); - } else { # use templates from EPICS base - $top = $epics_base . "/templates/makeBaseExt/top"; - } - } - "$top" or Cleanup(1, "Cannot find template top directory"); - -# Print extension type list? - if ($opt_l) { - ListExtTypes(); - exit 0; # finished for -l command - } - -# Extention template type - if ($opt_t) { # first choice is -t type - $exttype = $opt_t; - } elsif ($eEXTTYPE) { # second choice is $ENV{EPICS_DEFAULT_EXT_TYPE} - $exttype = $eEXTTYPE; - } elsif (-r "$top/defaultExt") {# third choice is (a link) in the $top dir - $exttype = "default"; - } elsif (-r "$top/exampleExt") {# fourth choice is (a link) in the $top dir - $exttype = "example"; - } - $exttype =~ s/Ext$//; - "$exttype" or Cleanup(1, "Cannot find default extension type"); - $exttypename = $exttype . "Ext"; - -# Valid $exttypename? - unless (-r "$top/$exttypename") { - print "Template for extension type '$exttype' is unreadable or does not exist.\n"; - ListExtTypes(); - exit 1; - } - - print "\nCommand line / environment options validated:\n" - . " Templ-Top: $top\n" - . "Templ-Type: $exttype\n" - . "Templ-Name: $exttypename\n" - . "EPICS-Base: $epics_base\n\n" if $Debug; - -} - -# -# List extension types -# -sub ListExtTypes { # no args - print "Valid extension types are:\n"; - foreach $name (<$top/*Ext>) { - $name =~ s|$top/||; - $name =~ s|Ext||; - printf "\t$name\n" if ($name && -r "$top/$name" . "Ext"); - } -} - -# -# Copy a file with replacements -# -sub CopyFile { # (source) - $source = $_[0]; - $target = ReplaceFilename($source); - - if ($target) { - $target =~ s|$top/||; - open(INP, "<$source") and open(OUT, ">$target") - or die "$! Copying $source -> $target"; - - print "Copying file $source -> $target\n" if $Debug; - while () { - print OUT ReplaceLine($_); - } - close INP; close OUT; - } -} - -# -# Find() callback for file or structure copy -# -sub FCopyTree { - chdir $cwd; # Sigh - if (-d $File::Find::name - and ($dir = ReplaceFilename($File::Find::name))) { - $dir =~ s|$top/||; - print "Creating directory $dir\n" if $Debug; - mkpath($dir); - } else { - CopyFile($File::Find::name); - } - chdir $File::Find::dir; -} - -# -# Cleanup and exit -# -sub Cleanup { # (return-code [ messsage-line1, line 2, ... ]) - my ($rtncode, @message) = @_; - - foreach $line ( @message ) { - print "$line\n"; - } - - print </bin//makeBaseExt.pl -t example example - -EOF - - exit $rtncode; -} - -sub GetUser { # no args - my ($user); - - # add to this list if new possibilities arise, - # currently it's UNIX and WIN32: - $user = $ENV{USER} || $ENV{USERNAME} || Win32::LoginName(); - - unless ($user) { - print "I cannot figure out your user name.\n"; - print "What shall you be called ?\n"; - print ">"; - $user = ; - chomp $user; - } - die "No user name" unless $user; - return $user; -} - -# replace "\" by "/" (for WINxx) -sub UnixPath { # path - my($newpath) = $_[0]; - $newpath =~ s|\\|/|go; - return $newpath; -} diff --git a/src/template/ext/top/Makefile b/src/template/ext/top/Makefile deleted file mode 100644 index 91e678167..000000000 --- a/src/template/ext/top/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile at the top of an extensions tree - -TOP = . -include $(TOP)/configure/CONFIG -DIRS += configure -DIRS += src -include $(TOP)/configure/RULES_TOP - - diff --git a/src/template/ext/top/README b/src/template/ext/top/README deleted file mode 100644 index c0e91eb9c..000000000 --- a/src/template/ext/top/README +++ /dev/null @@ -1,5 +0,0 @@ -Notes: - -Each time you add a new extension in the src directory you -must add the extension directory name to src/Makefile. - diff --git a/src/template/ext/top/configure/CONFIG b/src/template/ext/top/configure/CONFIG deleted file mode 100644 index 321f6cea2..000000000 --- a/src/template/ext/top/configure/CONFIG +++ /dev/null @@ -1,43 +0,0 @@ -# CONFIG - Load build configuration data -# -# Do not make changes in this file, any site-specific -# overrides should be given in a CONFIG_SITE file. - -# Where the build rules come from -RULES = $(EPICS_BASE) - -INSTALL_IDLFILE = $(INSTALL) - -include $(TOP)/configure/RELEASE --include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH) --include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).Common - -ifdef T_A - -include $(TOP)/configure/RELEASE.Common.$(T_A) - -include $(TOP)/configure/RELEASE.$(EPICS_HOST_ARCH).$(T_A) -endif - -CONFIG = $(RULES)/configure -include $(CONFIG)/CONFIG - -# Override some Base definitions -INSTALL_LOCATION = $(TOP) - -# CONFIG_SITE files contain build configuration overrides -include $(TOP)/configure/CONFIG_SITE - -# Host-arch specific settings --include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common - -ifdef INSTALL_LOCATION_EXTENSIONS - INSTALL_LOCATION = $(INSTALL_LOCATION_EXTENSIONS) -endif - -ifdef T_A - # Target-arch specific settings - -include $(TOP)/configure/os/CONFIG_SITE.Common.$(T_A) - - # Host & target specific combination settings - -include $(TOP)/configure/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) -endif - diff --git a/src/template/ext/top/configure/CONFIG_SITE b/src/template/ext/top/configure/CONFIG_SITE deleted file mode 100644 index 4ef88cedf..000000000 --- a/src/template/ext/top/configure/CONFIG_SITE +++ /dev/null @@ -1,20 +0,0 @@ -# CONFIG_SITE -# -# Make any extensions-specific changes to the EPICS build -# configuration variables in this file. -# -# Host/target specific settings are in os subdirectory files named -# os/CONFIG_SITE.$(EPICS_HOST_ARCH).Common -# os/CONFIG_SITE.Common.$(T_A) -# os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) - -# Extensions are not normally built for cross targets -CROSS_COMPILER_TARGET_ARCHS = - -# If you don't want to install into $(TOP) then -# define INSTALL_LOCATION here -#INSTALL_LOCATION= - -# Extensions don't normally build shared libraries -SHARED_LIBRARIES = NO - diff --git a/src/template/ext/top/configure/Makefile b/src/template/ext/top/configure/Makefile deleted file mode 100644 index 6e6609842..000000000 --- a/src/template/ext/top/configure/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# Makefile in extensions/configure directory - -TOP=.. - -include $(TOP)/configure/CONFIG - -TARGETS = $(CONFIG_TARGETS) - -include $(TOP)/configure/RULES - diff --git a/src/template/ext/top/configure/RELEASE b/src/template/ext/top/configure/RELEASE deleted file mode 100644 index 2a7ad2714..000000000 --- a/src/template/ext/top/configure/RELEASE +++ /dev/null @@ -1,23 +0,0 @@ -# RELEASE Locations of external modules -# -# NOTE: The build does not check dependancies on files -# external to this application. Thus you should run -# "gnumake clean uninstall install" in the top directory -# each time EPICS_BASE or any other external module that -# is defined in a RELEASE* file gets rebuilt. -# -# Host/target specific paths can be specified in files named -# RELEASE.$(EPICS_HOST_ARCH).Common -# RELEASE.Common.$(T_A) -# RELEASE.$(EPICS_HOST_ARCH).$(T_A) - -# Define INSTALL_LOCATION in CONFIG_SITE - -EPICS_EXTENSIONS = $(TOP) - -# Locations of external modules - -# OAG_APPS may be needed by the SDDS extension -#OAG_APPS = $(TOP)/../../oag/apps - -EPICS_BASE = _EPICS_BASE_ diff --git a/src/template/ext/top/configure/RULES b/src/template/ext/top/configure/RULES deleted file mode 100644 index 7592a37c6..000000000 --- a/src/template/ext/top/configure/RULES +++ /dev/null @@ -1,9 +0,0 @@ -# extensions/configure/RULES - -include $(CONFIG)/RULES --include $(TOP)/configure/RULES_PYTHON --include $(TOP)/configure/RULES_IDL - -ifdef BASE_3_15 - -include $(TOP)/configure/RULES_JAVA -endif diff --git a/src/template/ext/top/configure/RULES_DIRS b/src/template/ext/top/configure/RULES_DIRS deleted file mode 100644 index dd6904367..000000000 --- a/src/template/ext/top/configure/RULES_DIRS +++ /dev/null @@ -1,3 +0,0 @@ -# extensions/configure/RULES_DIRS - -include $(CONFIG)/RULES_DIRS diff --git a/src/template/ext/top/configure/RULES_IDL b/src/template/ext/top/configure/RULES_IDL deleted file mode 100644 index 3610bcc21..000000000 --- a/src/template/ext/top/configure/RULES_IDL +++ /dev/null @@ -1,30 +0,0 @@ -# extensions/configure/RULES_IDL - -ifdef T_A -ifeq ($(findstring Host,$(VALID_BUILDS)),Host) - -INSTALL_IDL = $(INSTALL_LOCATION)/idllib -DIRECTORY_TARGETS += $(INSTALL_IDL) - -ifneq ($(strip $(IDLS_$(OS_CLASS))),) -IDLS += $(subst -nil-,,$(IDLS_$(OS_CLASS))) -else -ifdef IDLS_DEFAULT -IDLS += $(IDLS_DEFAULT) -endif -endif - -INSTALL_IDLS =$(IDLS:%=$(INSTALL_IDL)/%) - -buildInstall : $(INSTALL_IDLS) - -$(INSTALL_IDL)/%: % - @echo "Installing idl program $@" - @$(INSTALL_IDLFILE) -d -m 644 $< $(INSTALL_IDL) - -$(INSTALL_IDL)/%: ../% - @echo "Installing idl program $@" - @$(INSTALL_IDLFILE) -d -m 644 $< $(INSTALL_IDL) - -endif -endif diff --git a/src/template/ext/top/configure/RULES_JAVA b/src/template/ext/top/configure/RULES_JAVA deleted file mode 100644 index b6ffa3f0f..000000000 --- a/src/template/ext/top/configure/RULES_JAVA +++ /dev/null @@ -1,158 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - - -ifeq ($(BUILD_CLASS),HOST) - -#------------------------------------------------------- -# java jdk1.1.5 definitions - -INSTALL_JAVA = $(INSTALL_LOCATION)/javalib -UNINSTALL_DIRS += $(INSTALL_JAVA) - -JAVA_INC = $(JAVA_DIR)/include -JAVA_BIN = $(JAVA_DIR)/bin -JAVA_INCLUDES += -I$(JAVA_INC) -I$(JAVA_INC)/$(word 1, $(subst -, ,$(T_A))) -I$(COMMON_DIR) - -JAVACCMD = $(subst \,/,$(JAVA_BIN)/javac$(EXE) $(CLASSPATH) $(SOURCEPATH) $(JAVACFLAGS)) -JAVAHCMD = $(subst \,/,$(JAVA_BIN)/javah$(EXE) -d $(COMMON_DIR) -force $(CLASSPATH) $(JAVAHFLAGS)) -JARCMD = $(subst \,/,$(JAVA_BIN)/jar$(EXE) $(JAR_OPTIONS) $@ $(JARINPUT) $(JARPACKAGES)) - -#------------------------------------------------------- -vpath %.java .. -vpath %.jar .. $(COMMON_DIR) - -empty:= -space:= $(empty) $(empty) -CLASSPATH = -classpath $(subst $(space),:,$(strip $(USR_PRECLASSPATH) $(INSTALL_JAVA) $(USR_CLASSPATH))) -SOURCEPATH = -sourcepath .:..:../.. - -#------------------------------------------------------- -# Java directory - -ifdef JAVA -JAVA_DIRECTORY_TARGETS += $(INSTALL_JAVA) -endif - -#------------------------------------------------------- -# Java native method C header files - -JAVAHFLAGS += $(USR_JAVAHFLAGS) -JAVAINC_CLASSFILES += $(addprefix $(INSTALL_JAVA)/,$(subst _,/,$(subst .h,.class,$(JAVAINC)))) -JAVAINC_CLASSNAMES += $(subst _,.,$(subst .h,,$(JAVAINC))) -COMMON_JAVAINC += $(addprefix $(COMMON_DIR)/,$(JAVAINC)) - -#------------------------------------------------------- -# Java class files - -JAVACFLAGS += $(USR_JAVACFLAGS) -CLASSES += $(subst .java,.class,$(JAVA)) -INSTALL_CLASSES = $(addprefix $(INSTALL_JAVA)/,$(CLASSES)) - -TESTCLASSES += $(subst .java,.class,$(notdir $(TESTJAVA))) -COMMON_TESTCLASSES += $(addprefix $(COMMON_DIR)/,$(TESTCLASSES)) -DEPTESTJAVA += $(subst .class,.java,$(TESTCLASSES)) - -#------------------------------------------------------- -# Java jar file - -INSTALL_JAR =$(addprefix $(INSTALL_JAVA)/,$(JAR)) -JARMANIFEST += $(firstword $(MANIFEST) $(JAR_MANIFEST)) -JARDEPFILES += $(addprefix $(INSTALL_JAVA)/,$(subst .java,.class,$(JAVA)) $(JAR_INPUT)) -JARINPUT += $(foreach inp,$(JAR_INPUT),-C $(INSTALL_JAVA) $(subst .java,.class,$(inp))) -JARPACKAGES += $(foreach pkg,$(JAR_PACKAGES),-C $(INSTALL_JAVA) $(subst .,/,$(pkg))) -PACKAGEDIRS += $(foreach pkg,$(JAR_PACKAGES),$(addprefix $(INSTALL_JAVA)/,$(subst .,/,$(pkg)))) - -ifneq ($(JARMANIFEST),) -JAR_OPTIONS = cvmf $(JARMANIFEST) -else -JAR_OPTIONS = cvf -endif - -#------------------------------------------------------- -# Java doc definitions -ifdef JAVADOC -JAVADOCFLAGS += $(USR_JAVADOCFLAGS) -JAVADOCCMD = $(subst \,/,$(JAVA_BIN)/javadoc$(EXE) $(CLASSPATH) $(SOURCEPATH) $(JAVADOCFLAGS)) -INSTALL_JAVADOC = $(addprefix $(INSTALL_HTML)/,$(JAVADOC))/index.html -endif - -#------------------------------------------------------- -# Java rules - -all: install - -install: buildInstall - -buildInstall : build - -rebuild: clean install - -inc: $(JAVA_DIRECTORY_TARGETS) $(INSTALL_CLASSES) $(COMMON_JAVAINC) - -build: inc - -build: $(COMMON_TESTCLASSES) - -buildInstall : $(INSTALL_JAR) $(INSTALL_JAVADOC) - -#This clean works only from O.* dirs. -buildclean: - @$(RMDIR) $(INSTALL_CLASSES) $(PACKAGEDIRS) - @$(RM) $(INSTALL_JAR) $(INSTALL_JAVADOC) - @$(RM) $(COMMON_TESTCLASSES) $(COMMON_JAVAINC) - -ifdef JAVA_DIRECTORY_TARGETS -$(JAVA_DIRECTORY_TARGETS): - $(MKDIR) $@ -endif - -$(COMMON_JAVAINC):$(JAVAINC_CLASSFILES) - $(ECHO) Creating header files $(COMMON_JAVAINC) - @$(RM) $@ - $(JAVAHCMD) $(JAVAINC_CLASSNAMES) - -$(COMMON_TESTCLASSES): $(addprefix ../,$(DEPTESTJAVA)) - $(ECHO) Creating test java class files $(COMMON_TESTCLASSES) - @$(RM) $@ - $(JAVACCMD) -d $(COMMON_DIR) $^ - -$(INSTALL_CLASSES): $(addprefix ../,$(JAVA)) - $(ECHO) Creating java class files - @$(RM) $@ - $(JAVACCMD) -d $(INSTALL_JAVA) $^ - -$(INSTALL_JAVADOC): $(addprefix ../,$(JAVA)) - $(ECHO) Creating java doc files - @$(RM) $@ - $(JAVADOCCMD) -d $(addprefix $(INSTALL_HTML)/,$(JAVADOC)) $^ - -$(COMMON_DIR)/%.jar: $(JARDEPFILES) - $(ECHO) Creating java jar file $@ - @$(RM) $@ - $(JARCMD) - -$(INSTALL_JAVA)/%.jar: $(COMMON_DIR)/%.jar - $(ECHO) "Installing java jar file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(INSTALL_JAVA)/%.jar: %.jar - $(ECHO) "Installing java jar file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -$(addprefix $(INSTALL_JAVA)/, $(JARINPUT)): $(INSTALL_JAVA)/%: ../% - $(ECHO) "Installing jar input file $@" - @$(INSTALL) -d -m $(INSTALL_PERMISSIONS) $< $(@D) - -.PHONY: all install buildInstall rebuild clean build inc - -.PRECIOUS: $(COMMON_JAVAINC) - -endif diff --git a/src/template/ext/top/configure/RULES_PYTHON b/src/template/ext/top/configure/RULES_PYTHON deleted file mode 100644 index 49dffa02b..000000000 --- a/src/template/ext/top/configure/RULES_PYTHON +++ /dev/null @@ -1,54 +0,0 @@ -# extensions/configure/RULES_PYTHON - -ifdef T_A -ifeq ($(findstring Host,$(VALID_BUILDS)),Host) - -SWIG ?= swig - -vpath %.py $(USR_VPATH) $(ALL_SRC_DIRS) - -# The optional PYTHON_INSTALL_LOCATION environment variable -# should be set to /site-packages -PYTHON_INSTALL_LOCATION ?= $(INSTALL_LOCATION)/lang/python - -INSTALL_PYTHON = $(PYTHON_INSTALL_LOCATION)/$(PYTHON_PACKAGE) - -PYTHON_PACKAGE_PTH = $(addsuffix .pth,$(PYTHON_PACKAGE)) -INSTALL_PYTHON_PACKAGE_PTH = $(addprefix $(PYTHON_INSTALL_LOCATION)/,$(PYTHON_PACKAGE_PTH)) - -PYTHON_SCRIPTS = $(filter-out $(LOADABLE_LIBRARY),$(PYTHON_MODULES)) -PYTHON_LIBRARY = $(filter $(LOADABLE_LIBRARY),$(PYTHON_MODULES)) -PYTHON_SHRLIBNAME = $(PYTHON_LIBRARY:%=$(LOADABLE_SHRLIB_PREFIX)%$(LOADABLE_SHRLIB_SUFFIX)) - -INSTALL_PYTHONS = $(addprefix $(INSTALL_PYTHON)/,$(PYTHON_SCRIPTS)) -INSTALL_PYTHONS += $(addprefix $(INSTALL_PYTHON)/,$(PYTHON_SHRLIBNAME)) - -buildInstall: $(INSTALL_PYTHONS) $(INSTALL_PYTHON_PACKAGE_PTH) - -$(INSTALL_PYTHON)/%: % - @echo "Installing python modules $@" - @$(INSTALL) -d -m 644 $< $(INSTALL_PYTHON) - -$(INSTALL_PYTHON)/%: ../% - @echo "Installing python modules $@" - @$(INSTALL) -d -m 644 $< $(INSTALL_PYTHON) - -$(PYTHON_INSTALL_LOCATION)/%: % - @echo "Installing python pth file $@" - @$(INSTALL) -d -m 644 $< $(PYTHON_INSTALL_LOCATION) - -$(PYTHON_PACKAGE_PTH): - @echo $(PYTHON_PACKAGE) > $@ - -%_wrap.c: ../%.i - $(SWIG) -python -o $@ $< - -ifdef BASE_3_15 -clean: -else -clean:: -endif - @$(RM) *.py *.so *.pth - -endif -endif diff --git a/src/template/ext/top/configure/RULES_TOP b/src/template/ext/top/configure/RULES_TOP deleted file mode 100644 index 1f81d3d39..000000000 --- a/src/template/ext/top/configure/RULES_TOP +++ /dev/null @@ -1,4 +0,0 @@ -# extensions/configure/RULES_TOP - -include $(CONFIG)/RULES_TOP - diff --git a/src/template/ext/top/configure/os/CONFIG.linux-x86.linux-386 b/src/template/ext/top/configure/os/CONFIG.linux-x86.linux-386 deleted file mode 100644 index ed73b3464..000000000 --- a/src/template/ext/top/configure/os/CONFIG.linux-x86.linux-386 +++ /dev/null @@ -1,2 +0,0 @@ - -include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.Common.Common b/src/template/ext/top/configure/os/CONFIG_SITE.Common.Common deleted file mode 100644 index 21363a633..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.Common.Common +++ /dev/null @@ -1,10 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# java jdk definitions -#CLASSPATH += -classpath .:..:$(INSTALL_JAVA):$(JAVA_DIR)/bin/../classes:$(JAVA_DIR)/bin/../lib/classes.zip -#JAVACCMD = $(subst \,/,$(JAVA_DIR)/bin/javac$(EXE) $(CLASSPATH) $(JAVAC_FLAGS) ) -#JAVAHCMD = $(subst \,/,$(JAVA_DIR)/bin/javah$(EXE) -jni $(CLASSPATH) $(JAVAH_FLAGS)) -#JARCMD = $(subst \,/,$(JAVA_DIR)/bin/jar$(EXE) $(JAR_OPTIONS) $(MANIFEST) $(JAR) $(JAR_INPUT)) - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc-gnu.aix-ppc-gnu b/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc-gnu.aix-ppc-gnu deleted file mode 100644 index 19d65aead..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc-gnu.aix-ppc-gnu +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.aix-ppc.aix-ppc - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc.aix-ppc b/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc.aix-ppc deleted file mode 100644 index 3f40e0b37..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.aix-ppc.aix-ppc +++ /dev/null @@ -1,77 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -# sun X11 -X11_LIB = /usr/openwin/lib -X11_INC = /usr/openwin/include -# mit X11 -#X11_LIB = /opt/X11R5/lib -#X11_INC = /opt/X11R5/include -# osf motif -#MOTIF_INC = /opt/local/Motif2.0/include -#MOTIF_LIB = /opt/local/Motif2.0/lib -# sun SDK motif -#MOTIF_INC = /opt/SUNWmotif/include -#MOTIF_LIB = /opt/SUNWmotif/lib -# sun 5.4,5.6 SDK motif -MOTIF_INC = /usr/dt/include -MOTIF_LIB = /usr/dt/lib -OPENWIN = /usr/openwin - -INTERVIEWS_BIN=/usr/local/interviews/bin/O.solaris -INTERVIEWS_LIB=/usr/local/interviews/lib/O.solaris -IV_INC=/usr/local/interviews/include -IV-2_6_INC=/usr/local/interviews/include/IV-2_6 -IV_BIN=/usr/local/interviews/bin/O.solaris -IV_LIB=/usr/local/interviews/lib/O.solaris - -WINGZ_INC = /opt/local/Wingz2/incl -WINGZ_LIB = /opt/local/Wingz2/lib -#MATHEMATICA = /usr/local/math -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -XRTGRAPH_EXTENSIONS = YES -XRTGRAPH = /opt/local/xrtgraph -QUESTWIN = /usr/local/questwin - -TK_LIB = /opt/local/lib -TK_INC = /opt/local/include -TCL_LIB = /opt/local/lib -TCL_INC = /opt/local/include -DP_LIB = /opt/local/lib -DP_INC = /opt/local/include -BLT_LIB = /opt/local/lib -BLT_INC = /opt/local/include - -IDL = /usr/local/idl -# IDL=$(IDL)/external/rpc is the sun4 version -IDLRPC = $(IDL)/external/rpc.solaris - -ZLIB_PREFIX = /usr/local/oag -ZLIB = $(notdir $(wildcard $(ZLIB_PREFIX)/lib/libz.a)) -ifeq ($(ZLIB) , libz.a) -ZLIB_LIB = $(ZLIB_PREFIX)/lib -ZLIB_INC = -I$(ZLIB_PREFIX)/include -ZLIB_CFLAG = -DzLib -ZLIB_PROD_LIB = z -z_DIR=$(ZLIB_PREFIX)/lib -else -ZLIB_LIB = -ZLIB_INC = -ZLIB_CFLAG = -ZLIB_PROD_LIB = -z_DIR= -endif - -PYTHON_DIR=/opt/local/lib/python2.2 -PYTHON_INCLUDE=/opt/local/include/python2.2 - -JAVA_DIR=/usr/java diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 deleted file mode 100644 index f1745159b..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 +++ /dev/null @@ -1,54 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common --include $(TOP)/configure/os/CONFIG_SITE.win32-x86.win32-x86 - -# ---------- java definitions -JAVA_DIR=c:/j2sdk1.4.1_01 - -# ---------- tcl/tk definitions -TCL = c:\\Tcl -TK_LIB = $(TCL)/lib -TK_INC = $(TCL)/include -TCL_LIB = $(TCL)/lib -TCL_INC = $(TCL)/include -DP_LIB = $(TCL)/lib -DP_INC = $(TCL)/include -BLT_LIB = $(TCL)/lib -BLT_INC = $(TCL)/include - -IDL = /usr/local/idl -# IDL=$(IDL)/external/rpc is the sun4 version -IDLRPC = $(IDL)/external/rpc.solaris - -#X11_LIB = c:/cygwin/lib -#X11_INC = c:/cygwin/include - -#MOTIF_LIB = $(X11_LIB) -#MOTIF_INC = $(X11_INC) - -OPENWIN = -INTERVIEWS_BIN = -WINGZ_INC = -WINGZ_LIB = -MATHEMATICA = -QUESTWIN = - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -XRTGRAPH_EXTENSIONS = NO -XRTGRAPH = - -SCIPLOT = ../../src/medmdev/medm - -# z library created in SDDS extension -ZLIB_CFLAG = -DzLib -ZLIB_PROD_LIB = z -z_DIR = $(EPICS_EXTENSIONS_LIB) diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppc.darwin-ppc b/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppc.darwin-ppc deleted file mode 100644 index d8fb7c158..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppc.darwin-ppc +++ /dev/null @@ -1,81 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -PYTHON_DIR=/usr/lib/python2.2 -PYTHON_INCLUDE=/System/Library/Frameworks/Python.framework/Versions/2.3/include/python2.3 - -# Following 3 for SDDS -#USE_GD_LIBRARY=1 -#USE_RUNCONTROL=1 -#USE_LOGDAEMON=1 - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - -# -# XDarwin -# -X11_LIB=/usr/X11R6/lib -X11_INC=/usr/X11R6/include/X11 -XPM_LIB=/usr/X11R6/lib -XPM_INC=/usr/X11R6/include/X11 - -# -# Fink OpenMotif -# -MOTIF_LIB=/sw/lib -MOTIF_INC=/sw/include - -# -# DarwinPorts OpenMotif -# -#MOTIF_LIB=/opt/local/lib -#MOTIF_INC=/opt/local/include - -# -# Interviews -# -IV_INC= -IV-2_6_INC= -IV_BIN= -IV_LIB= - -OPENWIN = -WINGZ_INC = -WINGZ_LIB = -MATHEMATICA = - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /opt/local/xrtgraph - -SCIPLOT = YES -QUESTWIN = - -TK_LIB = /sw/lib -TK_INC = /sw/include -TCL_LIB = /sw/lib -TCL_INC = /sw/include -DP_LIB = /sw/lib -DP_INC = /sw/include -BLT_LIB = /sw/lib -BLT_INC = /sw/include - -# -# Preliminary JAVA support -# -JAVA_DIR=/System/Library/Frameworks/JavaVM.framework/Home -JAVA_INC=/System/Library/Frameworks/JavaVM.framework/Headers -JAVA_INCLUDES = -I$(JAVA_INC) - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppcx86.darwin-ppcx86 b/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppcx86.darwin-ppcx86 deleted file mode 100644 index 6e31ffdb4..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-ppcx86.darwin-ppcx86 +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.darwin-ppc.darwin-ppc - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-x86.darwin-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.darwin-x86.darwin-x86 deleted file mode 100644 index 9e98c70ef..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.darwin-x86.darwin-x86 +++ /dev/null @@ -1,81 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -PYTHON_DIR=/usr/lib/python2.2 -PYTHON_INCLUDE=/System/Library/Frameworks/Python.framework/Versions/2.3/include/python2.3 - -# Following 3 for SDDS -#USE_GD_LIBRARY=1 -#USE_RUNCONTROL=1 -#USE_LOGDAEMON=1 - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - -# -# XDarwin -# -X11_LIB=/usr/X11R6/lib -X11_INC=/usr/X11R6/include -XPM_LIB=/usr/X11R6/lib -XPM_INC=/usr/X11R6/include - -# -# Fink OpenMotif -# -#MOTIF_LIB=/sw/lib -#MOTIF_INC=/sw/include - -# -# DarwinPorts OpenMotif -# -MOTIF_LIB=/opt/local/lib -MOTIF_INC=/opt/local/include - -# -# Interviews -# -IV_INC= -IV-2_6_INC= -IV_BIN= -IV_LIB= - -OPENWIN = -WINGZ_INC = -WINGZ_LIB = -MATHEMATICA = - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /opt/local/xrtgraph - -SCIPLOT = YES -QUESTWIN = - -TK_LIB = /sw/lib -TK_INC = /sw/include -TCL_LIB = /sw/lib -TCL_INC = /sw/include -DP_LIB = /sw/lib -DP_INC = /sw/include -BLT_LIB = /sw/lib -BLT_INC = /sw/include - -# -# Preliminary JAVA support -# -JAVA_DIR=/System/Library/Frameworks/JavaVM.framework/Home -JAVA_INC=/System/Library/Frameworks/JavaVM.framework/Headers -JAVA_INCLUDES = -I$(JAVA_INC) - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.freebsd-x86_64.freebsd-x86_64 b/src/template/ext/top/configure/os/CONFIG_SITE.freebsd-x86_64.freebsd-x86_64 deleted file mode 100644 index c4d1d5670..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.freebsd-x86_64.freebsd-x86_64 +++ /dev/null @@ -1,10 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-ppc.linux-ppc b/src/template/ext/top/configure/os/CONFIG_SITE.linux-ppc.linux-ppc deleted file mode 100644 index 4d78b29d7..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-ppc.linux-ppc +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug deleted file mode 100644 index 4d78b29d7..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86-debug.linux-x86-debug +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-athlon b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-athlon deleted file mode 100644 index 25036ccac..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-athlon +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-x86 deleted file mode 100644 index 8641a9d27..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86.linux-x86 +++ /dev/null @@ -1,57 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -#X11_LIB=/usr/X11R6/lib -#X11_INC=/usr/X11R6/include -#MOTIF_LIB=/usr/X11R6/lib -#MOTIF_INC=/usr/X11R6/include - -#With the release of Fedora Core 5 the -#X11 and MOTIF libraries now live at /usr/lib -X11_LIB=/usr/lib -X11_INC=/usr/include -MOTIF_LIB=/usr/lib -MOTIF_INC=/usr/include - -OPENWIN = -WINGZ = -MATHEMATICA = -QUESTWIN = -TK_TCL = /usr/lib -IDL = - -#JAVA_DIR=/usr/local/java -#JAVA_DIR=/usr/java/j2sdk1.4.1 -JAVA_DIR=/usr -JAVA_INC=$(JAVA_DIR)/include - -INTERVIEWS_BIN=/usr/local/interviews/bin/O.Linux - -IV_INC=/usr/local/interviews/include -IV_BIN=/usr/local/interviews/bin/O.Linux -IV_LIB=/usr/local/interviews/lib/O.Linux - -PYTHON_DIR=/usr/lib/python2.2 -PYTHON_INCLUDE=/usr/include/python2.2 - -CLAPACK_LIB = /usr/local/oag/3rdParty/CLAPACK/Linux_P4SSE2/lib -ATLAS_LIB = /usr/local/oag/3rdParty/ATLAS/Linux_P4SSE2/lib -F2C_LIB = /usr/local/oag/3rdParty/F2C/Linux_P4SSE2/lib -CLAPACK_INCLUDE = /usr/local/oag/3rdParty/CLAPACK/Linux_P4SSE2/include -ATLAS_INCLUDE = /usr/local/oag/3rdParty/ATLAS/Linux_P4SSE2/include - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /usr/local/xrtgraph -# Define SCIPLOT = YES if no XRT/graph 3.x -SCIPLOT=YES - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug deleted file mode 100644 index 4d78b29d7..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64-debug.linux-x86_64-debug +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 b/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 deleted file mode 100644 index 8d1386636..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.linux-x86_64.linux-x86_64 +++ /dev/null @@ -1,34 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.linux-x86.linux-x86 - -X11_LIB=/usr/lib64 -X11_INC=/usr/include - -# OpenMotif location -MOTIF_LIB=/usr/lib64 -MOTIF_INC=/usr/include -#MOTIF_LIB=/usr/X11R6/lib64 -#MOTIF_INC=/usr/X11R6/include - -# testing pre-compiled versions -CLAPACK_LIB = /usr/local/oag/3rdParty/ATLAS/Linux_Core2Duo64SSE3/lib -ATLAS_LIB = /usr/local/oag/3rdParty/ATLAS/Linux_Core2Duo64SSE3/lib -ATLAS_INCLUDE = /usr/local/oag/3rdParty/ATLAS/Linux_Core2Duo64SSE3/include - -JAVA_DIR=/usr - -# Sciplot and XRTgraph used by medm -SCIPLOT=YES -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /usr/local/xrtgraph64 -XRTGRAPH_EXTENSIONS = -XRTGRAPH = - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug deleted file mode 100644 index b0b61ce0a..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-debug.solaris-sparc-debug +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-gnu.solaris-sparc-gnu b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-gnu.solaris-sparc-gnu deleted file mode 100644 index b0b61ce0a..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc-gnu.solaris-sparc-gnu +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc deleted file mode 100644 index bd113bea3..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc +++ /dev/null @@ -1,90 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -# sun X11 -X11_LIB = /usr/openwin/lib -X11_INC = /usr/openwin/include -# mit X11 -#X11_LIB = /opt/X11R5/lib -#X11_INC = /opt/X11R5/include -# osf motif -#MOTIF_INC = /opt/local/Motif2.0/include -#MOTIF_LIB = /opt/local/Motif2.0/lib -# sun SDK motif -#MOTIF_INC = /opt/SUNWmotif/include -#MOTIF_LIB = /opt/SUNWmotif/lib -# sun 5.4,5.6 SDK motif -MOTIF_INC = /usr/dt/include -MOTIF_LIB = /usr/dt/lib -OPENWIN = /usr/openwin - -INTERVIEWS_BIN=/usr/local/interviews/bin/O.solaris -INTERVIEWS_LIB=/usr/local/interviews/lib/O.solaris -IV_INC=/usr/local/interviews/include -IV-2_6_INC=/usr/local/interviews/include/IV-2_6 -IV_BIN=/usr/local/interviews/bin/O.solaris -IV_LIB=/usr/local/interviews/lib/O.solaris - -WINGZ_INC = /opt/local/Wingz2/incl -WINGZ_LIB = /opt/local/Wingz2/lib -#MATHEMATICA = /usr/local/math - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = YES -#XRTGRAPH = /opt/local/xrtgraph -SCIPLOT = YES - -QUESTWIN = /usr/local/questwin - -TK_LIB = /opt/local/lib -TK_INC = /opt/local/include -TCL_LIB = /opt/local/lib -TCL_INC = /opt/local/include -DP_LIB = /opt/local/lib -DP_INC = /opt/local/include -BLT_LIB = /opt/local/lib -BLT_INC = /opt/local/include - -IDL = /usr/local/idl -# IDL=$(IDL)/external/rpc is the sun4 version -IDLRPC = $(IDL)/external/rpc.solaris - -# sun 5.4 -#JAVA_DIR=/opt/local/java -# sun 5.6 -JAVA_DIR=/usr/java -JAVA_INC=$(JAVA_DIR)/include - -ZLIB_PREFIX = /usr/local/oag -ZLIB = $(notdir $(wildcard $(ZLIB_PREFIX)/lib/libz.a)) -ifeq ($(ZLIB) , libz.a) -ZLIB_LIB = $(ZLIB_PREFIX)/lib -ZLIB_INC = -I$(ZLIB_PREFIX)/include -ZLIB_CFLAG = -DzLib -ZLIB_PROD_LIB = z -z_DIR=$(ZLIB_PREFIX)/lib -else -ZLIB_LIB = -ZLIB_INC = -ZLIB_CFLAG = -ZLIB_PROD_LIB = -z_DIR= -endif - -PYTHON_DIR=/opt/local/lib/python2.2 -PYTHON_INCLUDE=/opt/local/include/python2.2 - -CLAPACK_LIB = /usr/local/oag/3rdParty/CLAPACK/SunOS_SunUS5/lib -ATLAS_LIB = /usr/local/oag/3rdParty/ATLAS/SunOS_SunUS5/lib -F2C_LIB = /usr/local/oag/3rdParty/F2C/SunOS_SunUS5/lib -CLAPACK_INCLUDE = /usr/local/oag/3rdParty/CLAPACK/SunOS_SunUS5/include -ATLAS_INCLUDE = /usr/local/oag/3rdParty/ATLAS/SunOS_SunUS5/include diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64-gnu.solaris-sparc64-gnu b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64-gnu.solaris-sparc64-gnu deleted file mode 100644 index e8b88e0de..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64-gnu.solaris-sparc64-gnu +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc64.solaris-sparc64 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64.solaris-sparc64 b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64.solaris-sparc64 deleted file mode 100644 index 87628e74e..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-sparc64.solaris-sparc64 +++ /dev/null @@ -1,24 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc - -FORCE_ZLIB_BUILD=YES - -CLAPACK_LIB = /usr/local/oag/3rdParty/CLAPACK/SunOS_SunUSIII_4/lib -ATLAS_LIB = /usr/local/oag/3rdParty/ATLAS/SunOS_SunUSIII_4/lib -F2C_LIB = /usr/local/oag/3rdParty/F2C/SunOS_SunUSIII_4/lib -CLAPACK_INCLUDE = /usr/local/oag/3rdParty/CLAPACK/SunOS_SunUSIII_4/include -ATLAS_INCLUDE = /usr/local/oag/3rdParty/ATLAS/SunOS_SunUSIII_4/include - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -#XRTGRAPH_EXTENSIONS = -#XRTGRAPH = -SCIPLOT = YES diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-debug.solaris-x86-debug b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-debug.solaris-x86-debug deleted file mode 100644 index 2c322fcfa..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-debug.solaris-x86-debug +++ /dev/null @@ -1,6 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - --include $(TOP)/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-gnu.solaris-x86-gnu b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-gnu.solaris-x86-gnu deleted file mode 100644 index bf9746289..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86-gnu.solaris-x86-gnu +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 deleted file mode 100644 index 299dc0834..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 +++ /dev/null @@ -1,20 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-sparc.solaris-sparc - -#XRTGRAPH_EXTENSIONS= -#XRTGRAPH= -SCIPLOT=YES - -X11_LIB = /usr/lib -X11_INC = /usr/include -MOTIF_INC = /usr/include -MOTIF_LIB = /usr/lib - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86_64.solaris-x86_64 b/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86_64.solaris-x86_64 deleted file mode 100644 index 9ac039a5b..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.solaris-x86_64.solaris-x86_64 +++ /dev/null @@ -1,14 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.solaris-x86.solaris-x86 - -XRTGRAPH= -SCIPLOT=YES - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-cygwin.win32-x86-cygwin b/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-cygwin.win32-x86-cygwin deleted file mode 100644 index f6ca56942..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-cygwin.win32-x86-cygwin +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-debug.win32-x86-debug b/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-debug.win32-x86-debug deleted file mode 100644 index ebc1b8238..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-debug.win32-x86-debug +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.win32-x86.win32-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw b/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw deleted file mode 100644 index f6ca56942..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86-mingw.win32-x86-mingw +++ /dev/null @@ -1,11 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.cygwin-x86.cygwin-x86 - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86.win32-x86 b/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86.win32-x86 deleted file mode 100644 index 8118893a7..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.win32-x86.win32-x86 +++ /dev/null @@ -1,216 +0,0 @@ -# -# CONFIG_SITE.win32-x86.win32-x86,v 1.3 2003/09/03 19:06:10 jba Exp -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - -# Where to find utilities/libraries -# If you do not have a certain product, -# leave the line empty. -# - --include $(TOP)/configure/os/CONFIG_SITE.Common.Common - -# If objects were compiled with different default runtime libraries -# (not a good idea), specify which one you want to use in the product -# by making it the default and the others nodefault. Use -# WIN32_RUNTIME = MD, MT, or ML in Makefile.Host if you want to do -# this. It will avoid LNK4098 warnings. -# msvcrt.lib -MD Multi-thread DLL -# msvcrtd.lib -MDd Multi-thread DLL, Debug -# libcmt.lib -MT Multi-thread -# libcmtd.lib -MTd Multi-thread, Debug -# libc.lib -ML Single-thread -# libcd.lib -MLd Single-thread, Debug - -# MD Multi-thread DLL product -ARCH_DEP_LDFLAGS_MD_NO += /DEFAULTLIB:"msvcrtd.lib" -ARCH_DEP_LDFLAGS_MD_NO += /NODEFAULTLIB:"msvcrt.lib" -ARCH_DEP_LDFLAGS_MD_YES += /DEFAULTLIB:"msvcrt.lib" -ARCH_DEP_LDFLAGS_MD_YES += /NODEFAULTLIB:"msvcrtd.lib" -ARCH_DEP_LDFLAGS_MD += $(ARCH_DEP_LDFLAGS_MD_$(HOST_OPT)) -ARCH_DEP_LDFLAGS_MD += /NODEFAULTLIB:"libcmt.lib" -ARCH_DEP_LDFLAGS_MD += /NODEFAULTLIB:"libcmtd.lib" -ARCH_DEP_LDFLAGS_MD += /NODEFAULTLIB:"libc.lib" -ARCH_DEP_LDFLAGS_MD += /NODEFAULTLIB:"libcd.lib" - -# MT Multi-threaded product -ARCH_DEP_LDFLAGS_MT_NO += /DEFAULTLIB:"libcmtd.lib" -ARCH_DEP_LDFLAGS_MT_NO += /NODEFAULTLIB:"libcmt.lib" -ARCH_DEP_LDFLAGS_MT_YES += /DEFAULTLIB:"libcmt.lib" -ARCH_DEP_LDFLAGS_MT_YES += /NODEFAULTLIB:"libcmtd.lib" -ARCH_DEP_LDFLAGS_MT += $(ARCH_DEP_LDFLAGS_MT_$(HOST_OPT)) -ARCH_DEP_LDFLAGS_MT += /NODEFAULTLIB:"msvcrt.lib" -ARCH_DEP_LDFLAGS_MT += /NODEFAULTLIB:"msvcrtd.lib" -ARCH_DEP_LDFLAGS_MT += /NODEFAULTLIB:"libc.lib" -ARCH_DEP_LDFLAGS_MT += /NODEFAULTLIB:"libcd.lib" - -# ML Single-threaded product -ARCH_DEP_LDFLAGS_ML_NO += /DEFAULTLIB:"libcd.lib" -ARCH_DEP_LDFLAGS_ML_NO += /NODEFAULTLIB:"libc.lib" -ARCH_DEP_LDFLAGS_ML_YES += /DEFAULTLIB:"libc.lib" -ARCH_DEP_LDFLAGS_ML_YES += /NODEFAULTLIB:"libcd.lib" -ARCH_DEP_LDFLAGS_ML += $(ARCH_DEP_LDFLAGS_ML_$(HOST_OPT)) -ARCH_DEP_LDFLAGS_ML += /NODEFAULTLIB:"msvcrt.lib" -ARCH_DEP_LDFLAGS_ML += /NODEFAULTLIB:"msvcrtd.lib" -ARCH_DEP_LDFLAGS_ML += /NODEFAULTLIB:"libcmt.lib" -ARCH_DEP_LDFLAGS_ML += /NODEFAULTLIB:"libcmtd.lib" - -ARCH_DEP_LDFLAGS += $(ARCH_DEP_LDFLAGS_$(WIN32_RUNTIME)) - -# ---------- java definitions -JAVA_DIR=c:/j2sdk1.4.1_01 - -# ---------- tcl/tk definitions -TCL = c:\\Tcl -TK_LIB = $(TCL)/lib -TK_INC = $(TCL)/include -TCL_LIB = $(TCL)/lib -TCL_INC = $(TCL)/include -DP_LIB = $(TCL)/lib -DP_INC = $(TCL)/include -BLT_LIB = $(TCL)/lib -BLT_INC = $(TCL)/include - -IDL = /usr/local/idl -# IDL=$(IDL)/external/rpc is the sun4 version -IDLRPC = $(IDL)/external/rpc.solaris - -OPENWIN = -INTERVIEWS_BIN = -WINGZ_INC = -WINGZ_LIB = -MATHEMATICA = -QUESTWIN = - -# Define XRTGRAPH_EXTENSIONS = YES only if using XRT/graph 3.x -# and you want the extensions for MEDM -XRTGRAPH_EXTENSIONS = NO -#XRTGRAPH = - -SCIPLOT = YES - -# z library created in SDDS extension -ZLIB_CFLAG = -DzLib -ZLIB_PROD_LIB = z -z_DIR = $(EPICS_EXTENSIONS_LIB) - -CLAPACK_INCLUDE = c:/CLAPACK/include -CLAPACK_LIB = c:/CLAPACK/lib - -EXCEED = Exceed13.0 - -ifeq ($(EXCEED),Exceed5) - X11_LIB = c:/exceed5/xdk/lib - X11_INC = c:/exceed5/xdk/include - EXCEED_XLIBS=xmstatic xt xlibgui xlib xmu - xmstatic_DIR=$(X11_LIB) - xt_DIR=$(X11_LIB) - xlibgui_DIR=$(X11_LIB) - xlib_DIR=$(X11_LIB) - xmu_DIR=$(X11_LIB) - EXCEED_CFLAGS= -endif -ifeq ($(EXCEED),Exceed6.0) - X11_LIB = c:/exceed/xdk/lib - X11_INC = c:/exceed/xdk/include - EXCEED_XLIBS=xmstatic HCLXt xlibgui xlib HCLXmu - xmstatic_DIR=$(X11_LIB) - HCLXt_DIR=$(X11_LIB) - xlibgui_DIR=$(X11_LIB) - xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS= -endif -ifeq ($(EXCEED),Exceed6.1) - X11_LIB = c:/exceed/xdk/lib - X11_INC = c:/exceed/xdk/include - EXCEED_XLIBS=XmStatic XmStatXt xlibgui xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - xlibgui_DIR=$(X11_LIB) - xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC -endif -ifeq ($(EXCEED),Exceed6.2) - X11_LIB = c:/exceed/xdk/lib - X11_INC = c:/exceed/xdk/include - EXCEED_XLIBS=XmStatic XmStatXt xlibgui Xlib hclXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - xlibgui_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - hclXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC -endif -ifeq ($(EXCEED),Exceed7.0) - X11_LIB = c:/Exceed/Exceed/xdk/lib - X11_INC = c:/Exceed/Exceed/xdk/include - EXCEED_XLIBS=XmStatic XmStatXt XlibGui Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - XlibGui_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif -ifeq ($(EXCEED),Exceed7.10) - X11_LIB = c:/Exceed7.10/XDK/lib - X11_INC = c:/Exceed7.10/XDK/include - EXCEED_XLIBS=XmStatic XmStatXt XlibGui Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - XlibGui_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif -ifeq ($(EXCEED),Exceed10.0) - XDK=C:/Exceed10.0/xdk - X11_LIB = $(XDK)/lib - X11_INC = $(XDK)/include - #X11_LIB = c:/Exceed10.0/XDK/lib - #X11_INC = c:/Exceed10.0/XDK/include - EXCEED_XLIBS=XmStatic XmStatXt Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif -ifeq ($(EXCEED),Exceed12.0) - XDK=C:/Exceed12.0/XDK - X11_LIB = $(XDK)/lib - X11_INC = $(XDK)/include - EXCEED_XLIBS=XmStatic XmStatXt Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif -ifeq ($(EXCEED),Exceed13.0) - XDK=C:/Exceed13.0/XDK - X11_LIB = $(XDK)/lib - X11_INC = $(XDK)/include - EXCEED_XLIBS=XmStatic XmStatXt Xlib HCLXmu - XmStatic_DIR=$(X11_LIB) - XmStatXt_DIR=$(X11_LIB) - Xlib_DIR=$(X11_LIB) - HCLXmu_DIR=$(X11_LIB) - EXCEED_CFLAGS=/DXMSTATIC /DMOTIFAPP -endif - - -###################################################### -# Override for XFree86/LessTif -#X11_LIB = c:/Cygwin/usr/X11R6/lib -#X11_INC = c:/Cygwin/usr/X11R6/include -#EXCEED_XLIBS = Xm Xt Xp Xmu X11 Xext -#EXCEED_CFLAGS = -###################################################### - -MOTIF_LIB = $(X11_LIB) -MOTIF_INC = $(X11_INC) - diff --git a/src/template/ext/top/configure/os/CONFIG_SITE.windows-x64.windows-x64 b/src/template/ext/top/configure/os/CONFIG_SITE.windows-x64.windows-x64 deleted file mode 100644 index 68a0c149a..000000000 --- a/src/template/ext/top/configure/os/CONFIG_SITE.windows-x64.windows-x64 +++ /dev/null @@ -1,6 +0,0 @@ -# -# Site Specific Configuration Information -# Only the local epics system manager should modify this file - --include $(TOP)/configure/os/CONFIG_SITE.win32-x86.win32-x86 - diff --git a/src/template/ext/top/exampleExt/Makefile b/src/template/ext/top/exampleExt/Makefile deleted file mode 100644 index 618991fa7..000000000 --- a/src/template/ext/top/exampleExt/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -TOP=../.. -include $(TOP)/configure/CONFIG - -PROD_HOST = caExample -caExample_SRCS += caExample.c -caExample_LIBS += $(EPICS_BASE_HOST_LIBS) - -#caExample_CFLAGS += #C source file compiler flags, e.g. -DMYDEF=3 -#caExample_LDFLAGS += #Linker flags, e.g. -L$(MOTIF_LIB) -L$(X11_LIB) -#caExample_SYS_LIBS_solaris += #System libraries for OS_CLASS solaris, e.g. socket - -include $(TOP)/configure/RULES - diff --git a/src/template/ext/top/exampleExt/RELEASE_NOTES.HTM b/src/template/ext/top/exampleExt/RELEASE_NOTES.HTM deleted file mode 100644 index 56dce9346..000000000 --- a/src/template/ext/top/exampleExt/RELEASE_NOTES.HTM +++ /dev/null @@ -1,16 +0,0 @@ - - - -
-

caExample Release Notes

-

author name

-
- -
- -

05 Oct 2000 - v1.0

- -

Initial version

- - - diff --git a/src/template/ext/top/exampleExt/caExample.c b/src/template/ext/top/exampleExt/caExample.c deleted file mode 100644 index cc342e237..000000000 --- a/src/template/ext/top/exampleExt/caExample.c +++ /dev/null @@ -1,25 +0,0 @@ -/*caExample.c*/ -#include -#include -#include -#include - -#include "cadef.h" - -int main(int argc,char **argv) -{ - double data; - chid mychid; - - if(argc != 2) { - fprintf(stderr,"usage: caExample pvname\n"); - exit(1); - } - SEVCHK(ca_context_create(ca_disable_preemptive_callback),"ca_context_create"); - SEVCHK(ca_create_channel(argv[1],NULL,NULL,10,&mychid),"ca_create_channel failure"); - SEVCHK(ca_pend_io(5.0),"ca_pend_io failure"); - SEVCHK(ca_get(DBR_DOUBLE,mychid,(void *)&data),"ca_get failure"); - SEVCHK(ca_pend_io(5.0),"ca_pend_io failure"); - printf("%s %f\n",argv[1],data); - return(0); -} diff --git a/src/template/ext/top/simpleExt/Makefile b/src/template/ext/top/simpleExt/Makefile deleted file mode 100644 index 52cfac525..000000000 --- a/src/template/ext/top/simpleExt/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -TOP=../.. -include $(TOP)/configure/CONFIG - -# Product -#PROD_HOST = caExample -#caExample_SRCS += caExample.cc -#caExample_CFLAGS += -#caExample_LDFLAGS += -#caExample_LIBS += ca Com -#ca_LIB=$(EPICS_BASE_LIB) -#Com_LIB=$(EPICS_BASE_LIB) - -# Library -#LIBRARY_HOST = abc -#abc_SRCS += abc.c -#abc_DLL_LIBS = ca Com - - -include $(TOP)/configure/RULES - - diff --git a/src/template/ext/top/src/Makefile b/src/template/ext/top/src/Makefile deleted file mode 100644 index d672087ca..000000000 --- a/src/template/ext/top/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -TOP = .. -include $(TOP)/configure/CONFIG - -DIRS += _EXTNAME_ - -include $(TOP)/configure/RULES_DIRS - diff --git a/src/template/base/top/caServerApp/Makefile b/src/template/top/caServerApp/Makefile similarity index 100% rename from src/template/base/top/caServerApp/Makefile rename to src/template/top/caServerApp/Makefile diff --git a/src/template/base/top/caServerApp/README b/src/template/top/caServerApp/README similarity index 100% rename from src/template/base/top/caServerApp/README rename to src/template/top/caServerApp/README diff --git a/src/template/base/top/caServerApp/exAsyncPV.cc b/src/template/top/caServerApp/exAsyncPV.cc similarity index 100% rename from src/template/base/top/caServerApp/exAsyncPV.cc rename to src/template/top/caServerApp/exAsyncPV.cc diff --git a/src/template/base/top/caServerApp/exChannel.cc b/src/template/top/caServerApp/exChannel.cc similarity index 100% rename from src/template/base/top/caServerApp/exChannel.cc rename to src/template/top/caServerApp/exChannel.cc diff --git a/src/template/base/top/caServerApp/exPV.cc b/src/template/top/caServerApp/exPV.cc similarity index 100% rename from src/template/base/top/caServerApp/exPV.cc rename to src/template/top/caServerApp/exPV.cc diff --git a/src/template/base/top/caServerApp/exScalarPV.cc b/src/template/top/caServerApp/exScalarPV.cc similarity index 100% rename from src/template/base/top/caServerApp/exScalarPV.cc rename to src/template/top/caServerApp/exScalarPV.cc diff --git a/src/template/base/top/caServerApp/exServer.cc b/src/template/top/caServerApp/exServer.cc similarity index 100% rename from src/template/base/top/caServerApp/exServer.cc rename to src/template/top/caServerApp/exServer.cc diff --git a/src/template/base/top/caServerApp/exServer.h b/src/template/top/caServerApp/exServer.h similarity index 100% rename from src/template/base/top/caServerApp/exServer.h rename to src/template/top/caServerApp/exServer.h diff --git a/src/template/base/top/caServerApp/exVectorPV.cc b/src/template/top/caServerApp/exVectorPV.cc similarity index 100% rename from src/template/base/top/caServerApp/exVectorPV.cc rename to src/template/top/caServerApp/exVectorPV.cc diff --git a/src/template/base/top/caServerApp/main.cc b/src/template/top/caServerApp/main.cc similarity index 100% rename from src/template/base/top/caServerApp/main.cc rename to src/template/top/caServerApp/main.cc diff --git a/src/template/base/top/caServerApp/test.adl b/src/template/top/caServerApp/test.adl similarity index 100% rename from src/template/base/top/caServerApp/test.adl rename to src/template/top/caServerApp/test.adl diff --git a/src/template/base/top/caServerApp/vxEntry.cc b/src/template/top/caServerApp/vxEntry.cc similarity index 100% rename from src/template/base/top/caServerApp/vxEntry.cc rename to src/template/top/caServerApp/vxEntry.cc diff --git a/src/tools/DBD.pm b/src/tools/DBD.pm deleted file mode 100644 index aabe26d26..000000000 --- a/src/tools/DBD.pm +++ /dev/null @@ -1,125 +0,0 @@ -package DBD; - -use strict; -use warnings; - -use DBD::Base; -use DBD::Breaktable; -use DBD::Driver; -use DBD::Link; -use DBD::Menu; -use DBD::Recordtype; -use DBD::Recfield; -use DBD::Record; -use DBD::Registrar; -use DBD::Function; -use DBD::Variable; - -use Carp; - -sub new { - my ($class) = @_; - my $this = { - 'DBD::Breaktable' => {}, - 'DBD::Driver' => {}, - 'DBD::Link' => {}, - 'DBD::Function' => {}, - 'DBD::Menu' => {}, - 'DBD::Recordtype' => {}, - 'DBD::Record' => {}, - 'DBD::Registrar' => {}, - 'DBD::Variable' => {}, - 'COMMENTS' => [], - 'POD' => [] - }; - bless $this, $class; - return $this; -} - -sub add { - my ($this, $obj, $obj_name) = @_; - my $obj_class = ref $obj; - confess "DBD::add: Unknown DBD object type '$obj_class'" - unless $obj_class =~ m/^DBD::/ - and exists $this->{$obj_class}; - $obj_name = $obj->name unless defined $obj_name; - if (exists $this->{$obj_class}->{$obj_name}) { - return if $obj->equals($this->{$obj_class}->{$obj_name}); - dieContext("A different $obj->{WHAT} named '$obj_name' already exists"); - } - else { - $this->{$obj_class}->{$obj_name} = $obj; - } -} - -sub add_comment { - my $this = shift; - push @{$this->{COMMENTS}}, @_; -} - -sub comments { - return @{shift->{COMMENTS}}; -} - -sub add_pod { - my $this = shift; - push @{$this->{POD}}, @_; -} - -sub pod { - return @{shift->{POD}}; -} - -sub breaktables { - return shift->{'DBD::Breaktable'}; -} -sub breaktable { - my ($this, $name) = @_; - return $this->{'DBD::Breaktable'}->{$name}; -} - -sub drivers { - return shift->{'DBD::Driver'}; -} - -sub links { - return shift->{'DBD::Link'}; -} - -sub functions { - return shift->{'DBD::Function'}; -} - -sub menus { - return shift->{'DBD::Menu'}; -} -sub menu { - my ($this, $menu_name) = @_; - return $this->{'DBD::Menu'}->{$menu_name}; -} - -sub recordtypes { - return shift->{'DBD::Recordtype'}; -} -sub recordtype { - my ($this, $rtyp_name) = @_; - return $this->{'DBD::Recordtype'}->{$rtyp_name}; -} - -sub records { - return shift->{'DBD::Record'}; -} -sub record { - my ($this, $record_name) = @_; - return $this->{'DBD::Record'}->{$record_name}; -} - -sub registrars { - return shift->{'DBD::Registrar'}; -} - -sub variables { - return shift->{'DBD::Variable'}; -} - -1; diff --git a/src/tools/DBD/Base.pm b/src/tools/DBD/Base.pm deleted file mode 100644 index 0751c68fd..000000000 --- a/src/tools/DBD/Base.pm +++ /dev/null @@ -1,142 +0,0 @@ -# Common utility functions used by the DBD components - -package DBD::Base; - -use strict; -use warnings; - -use Carp; -require Exporter; - -our @ISA = qw(Exporter); - -our @EXPORT = qw(&pushContext &popContext &dieContext &warnContext &is_reserved - &escapeCcomment &escapeCstring $RXident $RXname $RXuint $RXint $RXhex $RXoct - $RXuintx $RXintx $RXnum $RXdqs $RXstr); - - -our $RXident = qr/ [a-zA-Z] [a-zA-Z0-9_]* /x; -our $RXname = qr/ [a-zA-Z0-9_\-:.\[\]<>;]+ /x; -our $RXhex = qr/ (?: 0 [xX] [0-9A-Fa-f]+ ) /x; -our $RXoct = qr/ 0 [0-7]* /x; -our $RXuint = qr/ \d+ /x; -our $RXint = qr/ -? $RXuint /ox; -our $RXuintx = qr/ ( $RXhex | $RXoct | $RXuint ) /ox; -our $RXintx = qr/ ( $RXhex | $RXoct | $RXint ) /ox; -our $RXnum = qr/ -? (?: \d+ | \d* \. \d+ ) (?: [eE] [-+]? \d+ )? /x; -our $RXdqs = qr/ " (?: [^"] | \\" )* " /x; -our $RXstr = qr/ ( $RXname | $RXnum | $RXdqs ) /ox; - -our @context; - - -sub pushContext { - my ($ctxt) = @_; - unshift @context, $ctxt; -} - -sub popContext { - my ($ctxt) = @_; - my $pop = shift @context; - ($ctxt ne $pop) and - dieContext("Leaving context \"$ctxt\", found \"$pop\" instead.", - "\tBraces must be closed in the same file they open in."); -} - -sub dieContext { - my $msg = join "\n\t", @_; - die "$msg\nContext: ", join(' in ', @context), "\n"; -} - -sub warnContext { - my $msg = join "\n\t", @_; - print STDERR "$msg\nContext: ", join(' in ', @context), "\n"; -} - - -# Reserved words from C++ and the DB/DBD file parser -my %reserved = map { $_ => undef } qw(and and_eq asm auto bitand bitor bool - break case catch char class compl const const_cast continue default delete - do double dynamic_cast else enum explicit export extern false float for - friend goto if inline int long mutable namespace new not not_eq operator or - or_eq private protected public register reinterpret_cast return short signed - sizeof static static_cast struct switch template this throw true try typedef - typeid typename union unsigned using virtual void volatile wchar_t while xor - xor_eq addpath alias breaktable choice device driver field function grecord - include info menu path record recordtype registrar variable); -sub is_reserved { - my $id = shift; - return exists $reserved{$id}; -} - -sub identifier { - my ($this, $id, $what) = @_; - confess "DBD::Base::identifier: $what undefined!" - unless defined $id; - $id =~ m/^$RXident$/o or dieContext("Illegal $what '$id'", - "Identifiers are used in C code so must start with a letter, followed", - "by letters, digits and/or underscore characters only."); - dieContext("Illegal $what '$id'", - "Identifier is a C++ reserved word.") - if is_reserved($id); - return $id; -} - - -# Output filtering - -sub escapeCcomment { - ($_) = @_; - s/\*\//**/g; - return $_; -} - -sub escapeCstring { - ($_) = @_; - # How to do this? - return $_; -} - - -# Base methods for the DBD component objects - -sub new { - my $class = shift; - my $this = {}; - bless $this, $class; - return $this->init(@_); -} - -sub init { - my ($this, $name, $what) = @_; - $this->{NAME} = $this->identifier($name, "$what name"); - $this->{WHAT} = $what; - return $this; -} - -sub name { - return shift->{NAME}; -} - -sub what { - return shift->{WHAT}; -} - -sub add_comment { - my $this = shift; - confess "add_comment() not supported by $this->{WHAT} ($this)\n", - "Context: ", join(' in ', @context), "\n"; -} - -sub add_pod { - my $this = shift; - warnContext "Warning: Pod text inside $this->{WHAT} will be ignored"; -} - -sub equals { - my ($a, $b) = @_; - return $a->{NAME} eq $b->{NAME} - && $a->{WHAT} eq $b->{WHAT}; -} - -1; diff --git a/src/tools/DBD/Breaktable.pm b/src/tools/DBD/Breaktable.pm deleted file mode 100644 index c14ab8d65..000000000 --- a/src/tools/DBD/Breaktable.pm +++ /dev/null @@ -1,59 +0,0 @@ -package DBD::Breaktable; -use DBD::Base; -@ISA = qw(DBD::Base); - -use Carp; - -sub init { - my ($this, $name) = @_; - $this->SUPER::init($name, "breakpoint table"); - $this->{POINT_LIST} = []; - $this->{COMMENTS} = []; - $this->{POD} = []; - return $this; -} - -sub add_point { - my ($this, $raw, $eng) = @_; - confess "DBD::Breaktable::add_point: Raw value undefined!" - unless defined $raw; - confess "DBD::Breaktable::add_point: Engineering value undefined!" - unless defined $eng; - push @{$this->{POINT_LIST}}, [$raw, $eng]; -} - -sub points { - return @{shift->{POINT_LIST}}; -} - -sub point { - my ($this, $idx) = @_; - return $this->{POINT_LIST}[$idx]; -} - -sub add_comment { - my $this = shift; - push @{$this->{COMMENTS}}, @_; -} - -sub comments { - return @{shift->{COMMENTS}}; -} - -sub add_pod { - my $this = shift; - push @{$this->{POD}}, @_; -} - -sub pod { - return @{shift->{POD}}; -} - -sub equals { - my ($a, $b) = @_; - return $a->SUPER::equals($b) - && join(',', map "$_->[0]:$_->[1]", @{$a->{POINT_LIST}}) - eq join(',', map "$_->[0]:$_->[1]", @{$b->{POINT_LIST}}); -} - -1; diff --git a/src/tools/DBD/Device.pm b/src/tools/DBD/Device.pm deleted file mode 100644 index 2fa1777d9..000000000 --- a/src/tools/DBD/Device.pm +++ /dev/null @@ -1,51 +0,0 @@ -package DBD::Device; -use DBD::Base; -@ISA = qw(DBD::Base); - -my %link_types = ( - CONSTANT => qr/$RXnum/o, - PV_LINK => qr/$RXname \s+ [.NPCAMS ]*/ox, - JSON_LINK => qr/\{ .* \}/ox, - VME_IO => qr/\# (?: \s* [CS] \s* $RXintx)* \s* (?: @ .*)?/ox, - CAMAC_IO => qr/\# (?: \s* [BCNAF] \s* $RXintx)* \s* (?: @ .*)?/ox, - RF_IO => qr/\# (?: \s* [RMDE] \s* $RXintx)*/ox, - AB_IO => qr/\# (?: \s* [LACS] \s* $RXintx)* \s* (?: @ .*)?/ox, - GPIB_IO => qr/\# (?: \s* [LA] \s* $RXintx)* \s* (?: @ .*)?/ox, - BITBUS_IO => qr/\# (?: \s* [LNPS] \s* $RXuintx)* \s* (?: @ .*)?/ox, - BBGPIB_IO => qr/\# (?: \s* [LBG] \s* $RXuintx)* \s* (?: @ .*)?/ox, - VXI_IO => qr/\# (?: \s* [VCS] \s* $RXintx)* \s* (?: @ .*)?/ox, - INST_IO => qr/@.*/ -); - -sub init { - my ($this, $link_type, $dset, $choice) = @_; - dieContext("Unknown link type '$link_type', valid types are:", - sort keys %link_types) unless exists $link_types{$link_type}; - $this->SUPER::init($dset, "device support (dset)"); - $this->{LINK_TYPE} = $link_type; - $this->{CHOICE} = $choice; - return $this; -} - -sub link_type { - return shift->{LINK_TYPE}; -} - -sub choice { - return shift->{CHOICE}; -} - -sub legal_addr { - my ($this, $addr) = @_; - my $rx = $link_types{$this->{LINK_TYPE}}; - return $addr =~ m/^ $rx $/x; -} - -sub equals { - my ($a, $b) = @_; - return $a->SUPER::equals($b) - && $a->{LINK_TYPE} eq $b->{LINK_TYPE} - && $a->{CHOICE} eq $b->{CHOICE}; -} - -1; diff --git a/src/tools/DBD/Driver.pm b/src/tools/DBD/Driver.pm deleted file mode 100644 index ddbae8f38..000000000 --- a/src/tools/DBD/Driver.pm +++ /dev/null @@ -1,9 +0,0 @@ -package DBD::Driver; -use DBD::Base; -@ISA = qw(DBD::Base); - -sub init { - return shift->SUPER::init(shift, "driver support (drvet)"); -} - -1; diff --git a/src/tools/DBD/Function.pm b/src/tools/DBD/Function.pm deleted file mode 100644 index 4a4a4cbfe..000000000 --- a/src/tools/DBD/Function.pm +++ /dev/null @@ -1,9 +0,0 @@ -package DBD::Function; -use DBD::Base; -@ISA = qw(DBD::Base); - -sub init { - return shift->SUPER::init(shift, "function"); -} - -1; diff --git a/src/tools/DBD/Link.pm b/src/tools/DBD/Link.pm deleted file mode 100644 index 4a4568e82..000000000 --- a/src/tools/DBD/Link.pm +++ /dev/null @@ -1,22 +0,0 @@ -package DBD::Link; -use DBD::Base; -@ISA = qw(DBD::Base); - -sub init { - my ($this, $name, $jlif) = @_; - $this->SUPER::init($jlif, "link support (jlif)"); - $this->{KEY} = $name; - return $this; -} - -sub key { - return shift->{KEY}; -} - -sub equals { - my ($a, $b) = @_; - return $a->SUPER::equals($b) - && $a->{KEY} eq $b->{KEY}; -} - -1; diff --git a/src/tools/DBD/Menu.pm b/src/tools/DBD/Menu.pm deleted file mode 100644 index e5521ed49..000000000 --- a/src/tools/DBD/Menu.pm +++ /dev/null @@ -1,84 +0,0 @@ -package DBD::Menu; -use DBD::Base; -@ISA = qw(DBD::Base); - -sub init { - my ($this, $name) = @_; - $this->SUPER::init($name, "menu"); - $this->{CHOICE_LIST} = []; - $this->{CHOICE_INDEX} = {}; - $this->{COMMENTS} = []; - return $this; -} - -sub add_choice { - my ($this, $name, $value) = @_; - $name = $this->identifier($name, "Choice name"); - foreach $pair ($this->choices) { - dieContext("Duplicate menu choice name '$name'") - if ($pair->[0] eq $name); - dieContext("Duplicate menu choice string '$value'") - if ($pair->[1] eq $value); - } - push @{$this->{CHOICE_LIST}}, [$name, $value]; - $this->{CHOICE_INDEX}->{$value} = $name; -} - -sub choices { - return @{shift->{CHOICE_LIST}}; -} - -sub choice { - my ($this, $idx) = @_; - return $this->{CHOICE_LIST}[$idx]; -} - -sub legal_choice { - my ($this, $value) = @_; - return exists $this->{CHOICE_INDEX}->{$value}; -} - -sub add_comment { - my $this = shift; - push @{$this->{COMMENTS}}, @_; -} - -sub comments { - return @{shift->{COMMENTS}}; -} - -sub equals { - my ($a, $b) = @_; - return $a->SUPER::equals($b) - && join(',', map "$_->[0]:$_->[1]", @{$a->{CHOICE_LIST}}) - eq join(',', map "$_->[0]:$_->[1]", @{$b->{CHOICE_LIST}}); -} - -sub toDeclaration { - my $this = shift; - my $name = $this->name; - my @choices = map { - sprintf " %-31s /* %s */", @{$_}[0], escapeCcomment(@{$_}[1]); - } $this->choices; - my $num = scalar @choices; - return "typedef enum {\n" . - join(",\n", @choices) . - "\n} $name;\n" . - "#define ${name}_NUM_CHOICES $num\n\n"; -} - -sub toDefinition { - my $this = shift; - my $name = $this->name; - my @strings = map { - "\t\"" . escapeCstring(@{$_}[1]) . "\"" - } $this->choices; - return "static const char * const ${name}ChoiceStrings[] = {\n" . - join(",\n", @strings) . "\n};\n" . - "const dbMenu ${name}MenuMetaData = {\n" . - "\t\"" . escapeCstring($name) . "\",\n" . - "\t${name}_NUM_CHOICES,\n" . - "\t${name}ChoiceStrings\n};\n\n"; -} - -1; diff --git a/src/tools/DBD/Output.pm b/src/tools/DBD/Output.pm deleted file mode 100644 index c3bce9e58..000000000 --- a/src/tools/DBD/Output.pm +++ /dev/null @@ -1,138 +0,0 @@ -package DBD::Output; - -use strict; -use warnings; - -require Exporter; - -our @ISA = qw(Exporter); -our @EXPORT = qw(&OutputDBD &OutputDB); - -use DBD; -use DBD::Base; -use DBD::Breaktable; -use DBD::Device; -use DBD::Driver; -use DBD::Link; -use DBD::Menu; -use DBD::Recordtype; -use DBD::Recfield; -use DBD::Record; -use DBD::Registrar; -use DBD::Function; -use DBD::Variable; - -sub OutputDBD { - my ($out, $dbd) = @_; - OutputMenus($out, $dbd->menus); - OutputRecordtypes($out, $dbd->recordtypes); - OutputDrivers($out, $dbd->drivers); - OutputLinks($out, $dbd->links); - OutputRegistrars($out, $dbd->registrars); - OutputFunctions($out, $dbd->functions); - OutputVariables($out, $dbd->variables); - OutputBreaktables($out, $dbd->breaktables); -} - -sub OutputDB { - my ($out, $dbd) = @_; - OutputRecords($out, $dbd->records); -} - -sub OutputMenus { - my ($out, $menus) = @_; - while (my ($name, $menu) = each %{$menus}) { - printf $out "menu(%s) {\n", $name; - printf $out " choice(%s, \"%s\")\n", @{$_} - foreach $menu->choices; - print $out "}\n"; - } -} - -sub OutputRecordtypes { - my ($out, $recordtypes) = @_; - while (my ($name, $recordtype) = each %{$recordtypes}) { - printf $out "recordtype(%s) {\n", $name; - print $out " %$_\n" - foreach $recordtype->cdefs; - foreach my $field ($recordtype->fields) { - printf $out " field(%s, %s) {\n", - $field->name, $field->dbf_type; - while (my ($attr, $val) = each %{$field->attributes}) { - $val = "\"$val\"" - if $val !~ m/^$RXname$/ox - || $attr eq 'prompt' - || $attr eq 'initial'; - printf $out " %s(%s)\n", $attr, $val; - } - print $out " }\n"; - } - printf $out "}\n"; - printf $out "device(%s, %s, %s, \"%s\")\n", - $name, $_->link_type, $_->name, $_->choice - foreach $recordtype->devices; - } -} - -sub OutputDrivers { - my ($out, $drivers) = @_; - printf $out "driver(%s)\n", $_ - foreach keys %{$drivers}; -} - -sub OutputLinks { - my ($out, $links) = @_; - while (my ($name, $link) = each %{$links}) { - printf $out "link(%s, %s)\n", $link->key, $name; - } -} - -sub OutputRegistrars { - my ($out, $registrars) = @_; - printf $out "registrar(%s)\n", $_ - foreach keys %{$registrars}; -} - -sub OutputFunctions { - my ($out, $functions) = @_; - printf $out "function(%s)\n", $_ - foreach keys %{$functions}; -} - -sub OutputVariables { - my ($out, $variables) = @_; - while (my ($name, $variable) = each %{$variables}) { - printf $out "variable(%s, %s)\n", $name, $variable->var_type; - } -} - -sub OutputBreaktables { - my ($out, $breaktables) = @_; - while (my ($name, $breaktable) = each %{$breaktables}) { - printf $out "breaktable(\"%s\") {\n", $name; - printf $out " %s, %s\n", @{$_} - foreach $breaktable->points; - print $out "}\n"; - } -} - -sub OutputRecords { - my ($out, $records) = @_; - while (my ($name, $rec) = each %{$records}) { - next if $name ne $rec->name; # Alias - printf $out "record(%s, \"%s\") {\n", $rec->recordtype->name, $name; - printf $out " alias(\"%s\")\n", $_ - foreach $rec->aliases; - foreach my $recfield ($rec->recfields) { - my $field_name = $recfield->name; - my $value = $rec->get_field($field_name); - printf $out " field(%s, \"%s\")\n", $field_name, $value - if defined $value; - } - printf $out " info(\"%s\", \"%s\")\n", $_, $rec->info_value($_) - foreach $rec->info_names; - print $out "}\n"; - } -} - -1; diff --git a/src/tools/DBD/Parser.pm b/src/tools/DBD/Parser.pm deleted file mode 100644 index c5f83d6d0..000000000 --- a/src/tools/DBD/Parser.pm +++ /dev/null @@ -1,313 +0,0 @@ -package DBD::Parser; - -use strict; -use warnings; - -require Exporter; - -our @ISA = qw(Exporter); -our @EXPORT = qw(&ParseDBD); - -use DBD; -use DBD::Base; -use DBD::Breaktable; -use DBD::Device; -use DBD::Driver; -use DBD::Link; -use DBD::Menu; -use DBD::Recordtype; -use DBD::Recfield; -use DBD::Record; -use DBD::Registrar; -use DBD::Function; -use DBD::Variable; - -our $debug=0; - -sub ParseDBD { - (my $dbd, $_) = @_; - while (1) { - parseCommon($dbd); - if (m/\G menu \s* \( \s* $RXstr \s* \) \s* \{/oxgc) { - print "Menu: $1\n" if $debug; - my ($menu_name) = unquote($1); - parse_menu($dbd, $menu_name); - } - elsif (m/\G driver \s* \( \s* $RXstr \s* \)/oxgc) { - print "Driver: $1\n" if $debug; - my ($driver_name) = unquote($1); - $dbd->add(DBD::Driver->new($driver_name)); - } - elsif (m/\G link \s* \( \s* $RXstr \s*, \s* $RXstr \s* \)/oxgc) { - print "Link $1, $2\n" if $debug; - my ($key, $lset) = unquote($1, $2); - $dbd->add(DBD::Link->new($key, $lset)); - } - elsif (m/\G registrar \s* \( \s* $RXstr \s* \)/oxgc) { - print "Registrar: $1\n" if $debug; - my ($registrar_name) = unquote($1); - $dbd->add(DBD::Registrar->new($registrar_name)); - } - elsif (m/\G function \s* \( \s* $RXstr \s* \)/oxgc) { - print "Function: $1\n" if $debug; - my ($function_name) = unquote($1); - $dbd->add(DBD::Function->new($function_name)); - } - elsif (m/\G breaktable \s* \( \s* $RXstr \s* \) \s* \{/oxgc) { - print "Breaktable: $1\n" if $debug; - my ($breaktable_name) = unquote($1); - parse_breaktable($dbd, $breaktable_name); - } - elsif (m/\G recordtype \s* \( \s* $RXstr \s* \) \s* \{/oxgc) { - print "Recordtype: $1\n" if $debug; - my ($recordtype_name) = unquote($1); - parse_recordtype($dbd, $recordtype_name); - } - elsif (m/\G g?record \s* \( \s* $RXstr \s*, \s* $RXstr \s* \) \s* \{/oxgc) { - print "Record: $1, $2\n" if $debug; - my ($record_type, $record_name) = unquote($1, $2); - parse_record($dbd, $record_type, $record_name); - } - elsif (m/\G alias \s* \( \s* $RXstr \s*, \s* $RXstr \s* \)/oxgc) { - print "Alias: $1, $2\n" if $debug; - my ($record_name, $alias) = unquote($1, $2); - my $rec = $dbd->record($record_name); - dieContext("Alias '$alias' refers to unknown record '$record_name'") - unless defined $rec; - dieContext("Can't create alias '$alias', name already used") - if defined $dbd->record($alias); - $rec->add_alias($alias); - $dbd->add($rec, $alias); - } - elsif (m/\G variable \s* \( \s* $RXstr \s* \)/oxgc) { - print "Variable: $1\n" if $debug; - my ($variable_name) = unquote($1); - $dbd->add(DBD::Variable->new($variable_name)); - } - elsif (m/\G variable \s* \( \s* $RXstr \s* , \s* $RXstr \s* \)/oxgc) { - print "Variable: $1, $2\n" if $debug; - my ($variable_name, $variable_type) = unquote($1, $2); - $dbd->add(DBD::Variable->new($variable_name, $variable_type)); - } - elsif (m/\G device \s* \( \s* $RXstr \s* , \s* $RXstr \s* , - \s* $RXstr \s* , \s*$RXstr \s* \)/oxgc) { - print "Device: $1, $2, $3, $4\n" if $debug; - my ($record_type, $link_type, $dset, $choice) = - unquote($1, $2, $3, $4); - my $rtyp = $dbd->recordtype($record_type); - if (!defined $rtyp) { - $rtyp = DBD::Recordtype->new($record_type); - warn "Device using undefined record type '$record_type', place-holder created\n"; - $dbd->add($rtyp); - } - $rtyp->add_device(DBD::Device->new($link_type, $dset, $choice)); - } else { - last unless m/\G (.*) $/moxgc; - dieContext("Syntax error in '$1'"); - } - } -} - -sub parseCommon { - my ($obj) = @_; - while (1) { - # Skip leading whitespace - m/\G \s* /oxgc; - - # Extract POD - if (m/\G ( = [a-zA-Z] .* ) \n/oxgc) { - $obj->add_pod($1, parsePod()); - } - elsif (m/\G \# /oxgc) { - if (m/\G \# ! BEGIN \{ ( [^}]* ) \} ! \# \# \n/oxgc) { - print "File-Begin: $1\n" if $debug; - pushContext("file '$1'"); - } - elsif (m/\G \# ! END \{ ( [^}]* ) \} ! \# \# \n?/oxgc) { - print "File-End: $1\n" if $debug; - popContext("file '$1'"); - } - else { - m/\G (.*) \n/oxgc; - $obj->add_comment($1); - print "Comment: $1\n" if $debug; - } - } else { - return; - } - } -} - -sub unquote { - return map { m/^ ("?) (.*) \1 $/ox; $2 } @_; -} - -sub parsePod { - pushContext("Pod markup"); - my @pod; - while (1) { - if (m/\G ( =cut .* ) \n?/oxgc) { - popContext("Pod markup"); - return @pod; - } - elsif (m/\G ( .* ) $/oxgc) { - dieContext("Unexpected end of input file, Pod block not closed"); - } - elsif (m/\G ( .* ) \n/oxgc) { - push @pod, $1 - } - } -} - -sub parse_menu { - my ($dbd, $menu_name) = @_; - pushContext("menu($menu_name)"); - my $menu = DBD::Menu->new($menu_name); - while(1) { - parseCommon($menu); - if (m/\G choice \s* \( \s* $RXstr \s* , \s* $RXstr \s* \)/oxgc) { - print " Menu-Choice: $1, $2\n" if $debug; - my ($choice_name, $value) = unquote($1, $2); - $menu->add_choice($choice_name, $value); - } - elsif (m/\G \}/oxgc) { - print " Menu-End:\n" if $debug; - $dbd->add($menu); - popContext("menu($menu_name)"); - return; - } else { - m/\G (.*) $/moxgc or dieContext("Unexpected end of input"); - dieContext("Syntax error in '$1'"); - } - } -} - -sub parse_breaktable { - my ($dbd, $breaktable_name) = @_; - pushContext("breaktable($breaktable_name)"); - my $bt = DBD::Breaktable->new($breaktable_name); - while(1) { - parseCommon($bt); - if (m/\G point\s* \(\s* $RXstr \s* , \s* $RXstr \s* \)/oxgc) { - print " Breaktable-Point: $1, $2\n" if $debug; - my ($raw, $eng) = unquote($1, $2); - $bt->add_point($raw, $eng); - } - elsif (m/\G $RXstr \s* (?: , \s*)? $RXstr (?: \s* ,)?/oxgc) { - print " Breaktable-Data: $1, $2\n" if $debug; - my ($raw, $eng) = unquote($1, $2); - $bt->add_point($raw, $eng); - } - elsif (m/\G \}/oxgc) { - print " Breaktable-End:\n" if $debug; - $dbd->add($bt); - popContext("breaktable($breaktable_name)"); - return; - } else { - m/\G (.*) $/moxgc or dieContext("Unexpected end of input"); - dieContext("Syntax error in '$1'"); - } - } -} - -sub parse_recordtype { - my ($dbd, $record_type) = @_; - pushContext("recordtype($record_type)"); - my $rtyp = DBD::Recordtype->new($record_type); - while(1) { - parseCommon($rtyp); - if (m/\G field \s* \( \s* $RXstr \s* , \s* $RXstr \s* \) \s* \{/oxgc) { - print " Recordtype-Field: $1, $2\n" if $debug; - my ($field_name, $field_type) = unquote($1, $2); - parse_field($rtyp, $field_name, $field_type); - } - elsif (m/\G % (.*) \n/oxgc) { - print " Recordtype-Cdef: $1\n" if $debug; - $rtyp->add_cdef($1); - } - elsif (m/\G \}/oxgc) { - print " Recordtype-End:\n" if $debug; - $dbd->add($rtyp); - popContext("recordtype($record_type)"); - return; - } else { - m/\G (.*) $/moxgc or dieContext("Unexpected end of input"); - dieContext("Syntax error in '$1'"); - } - } -} - -sub parse_record { - my ($dbd, $record_type, $record_name) = @_; - pushContext("record($record_type, $record_name)"); - my $rtyp = $dbd->recordtype($record_type); - my $rec = $dbd->record($record_name); - if (defined $rec) { - my $otyp = $rec->recordtype; - my $otyp_name = $otyp->name; - $rtyp = $otyp if $record_type eq '*'; - dieContext("A(n) $otyp_name record '$record_name' already exists") - unless $otyp == $rtyp; - } else { - dieContext("No record exists named '$record_name'") - if $record_type eq '*'; - dieContext("No recordtype exists named '$record_type'") - unless defined $rtyp; - $rec = DBD::Record->new($rtyp, $record_name); - } - while (1) { - parseCommon($rec); - if (m/\G field \s* \( \s* $RXstr \s* , \s* $RXstr \s* \)/oxgc) { - print " Record-Field: $1, $2\n" if $debug; - my ($field_name, $value) = unquote($1, $2); - $rec->put_field($field_name, $value); - } - elsif (m/\G info \s* \( \s* $RXstr \s* , \s* $RXstr \s* \)/oxgc) { - print " Record-Info: $1, $2\n" if $debug; - my ($info_name, $value) = unquote($1, $2); - $rec->add_info($info_name, $value); - } - elsif (m/\G alias \s* \( \s* $RXstr \s* \)/oxgc) { - print " Record-Alias: $1\n" if $debug; - my ($alias) = unquote($1); - dieContext("Can't create alias '$alias', name in use") - if defined $dbd->record($1); - $rec->add_alias($alias); - $dbd->add($rec, $alias); - } - elsif (m/\G \}/oxgc) { - print " Record-End:\n" if $debug; - $dbd->add($rec); - popContext("record($record_type, $record_name)"); - return; - } else { - m/\G (.*) $/moxgc or dieContext("Unexpected end of input"); - dieContext("Syntax error in '$1'"); - } - } -} - -sub parse_field { - my ($rtyp, $field_name, $field_type) = @_; - my $fld = DBD::Recfield->new($field_name, $field_type); - pushContext("field($field_name, $field_type)"); - while(1) { - parseCommon($fld); - if (m/\G (\w+) \s* \( \s* $RXstr \s* \)/oxgc) { - print " Field-Attribute: $1, $2\n" if $debug; - my ($attr, $value) = unquote($1, $2); - $fld->add_attribute($attr, $value); - } - elsif (m/\G \}/oxgc) { - print " Field-End:\n" if $debug; - $rtyp->add_field($fld); - popContext("field($field_name, $field_type)"); - return; - } else { - m/\G (.*) $/moxgc or dieContext("Unexpected end of input"); - dieContext("Syntax error in '$1'"); - } - } -} - -1; diff --git a/src/tools/DBD/Recfield.pm b/src/tools/DBD/Recfield.pm deleted file mode 100644 index 89beb7be7..000000000 --- a/src/tools/DBD/Recfield.pm +++ /dev/null @@ -1,525 +0,0 @@ -package DBD::Recfield; -use DBD::Base; -@ISA = qw(DBD::Base); - -# The hash value is a regexp that matches all legal values of this field -# NB: The regexps are not currently used, and are wrong for some types. -our %field_types = ( - DBF_STRING => qr/.{0,40}/, - DBF_CHAR => $RXintx, - DBF_UCHAR => $RXuintx, - DBF_SHORT => $RXintx, - DBF_USHORT => $RXuintx, - DBF_LONG => $RXintx, - DBF_ULONG => $RXuintx, - DBF_INT64 => $RXintx, - DBF_UINT64 => $RXuintx, - DBF_FLOAT => $RXnum, - DBF_DOUBLE => $RXnum, - DBF_ENUM => qr/.*/, - DBF_MENU => qr/.*/, - DBF_DEVICE => qr/.*/, - DBF_INLINK => qr/.*/, - DBF_OUTLINK => qr/.*/, - DBF_FWDLINK => qr/.*/, - DBF_NOACCESS => qr// -); - -# The hash value is a regexp that matches all legal values of this attribute -our %field_attrs = ( - asl => qr/^ASL[01]$/, - initial => qr/^.*$/, - promptgroup => qr/^.*$/, - prompt => qr/^.*$/, - special => qr/^(?:SPC_\w+|\d{3,})$/, - pp => qr/^(?:TRUE|FALSE)$/, - interest => qr/^\d+$/, - base => qr/^(?:DECIMAL|HEX)$/, - size => qr/^\d+$/, - extra => qr/^.*$/, - menu => qr/^$RXident$/o, - prop => qr/^(?:YES|NO)$/ -); - -# Convert old promptgroups into new-style -my %promptgroupMap = ( - GUI_COMMON => '10 - Common', - GUI_ALARMS => '70 - Alarm', - GUI_BITS1 => '41 - Bits (1)', - GUI_BITS2 => '42 - Bits (2)', - GUI_CALC => '30 - Action', - GUI_CLOCK => '30 - Action', - GUI_COMPRESS => '30 - Action', - GUI_CONVERT => '60 - Convert', - GUI_DISPLAY => '80 - Display', - GUI_HIST => '30 - Action', - GUI_INPUTS => '40 - Input', - GUI_LINKS => '40 - Link', - GUI_MBB => '30 - Action', - GUI_MOTOR => '30 - Action', - GUI_OUTPUT => '50 - Output', - GUI_PID => '30 - Action', - GUI_PULSE => '30 - Action', - GUI_SELECT => '40 - Input', - GUI_SEQ1 => '51 - Output (1)', - GUI_SEQ2 => '52 - Output (2)', - GUI_SEQ3 => '53 - Output (3)', - GUI_SUB => '30 - Action', - GUI_TIMER => '30 - Action', - GUI_WAVE => '30 - Action', - GUI_SCAN => '20 - Scan', -); - -sub new { - my ($class, $name, $type) = @_; - dieContext("Illegal field type '$type', valid field types are:", - sort keys %field_types) unless exists $field_types{$type}; - my $this = {}; - bless $this, "${class}::${type}"; - return $this->init($name, $type); -} - -sub init { - my ($this, $name, $type) = @_; - $this->SUPER::init($name, "record field"); - dieContext("Illegal field type '$type', valid field types are:", - sort keys %field_types) unless exists $field_types{$type}; - $this->{DBF_TYPE} = $type; - $this->{ATTR_INDEX} = {}; - $this->{COMMENTS} = []; - return $this; -} - -sub dbf_type { - return shift->{DBF_TYPE}; -} - -sub set_number { - my ($this, $number) = @_; - $this->{NUMBER} = $number; -} - -sub number { - return shift->{NUMBER}; -} - -sub add_attribute { - my ($this, $attr, $value) = @_; - $value = $promptgroupMap{$value} - if $attr eq 'promptgroup' && exists $promptgroupMap{$value}; - my $match = $field_attrs{$attr}; - if (defined $match) { - dieContext("Bad value '$value' for field attribute '$attr'") - unless $value =~ m/$match/; - } - else { - warnContext("Unknown field attribute '$attr' with value '$value'; " . - "known attributes are:", - join(", ", sort keys %field_attrs)); - } - $this->{ATTR_INDEX}->{$attr} = $value; -} - -sub attributes { - return shift->{ATTR_INDEX}; -} - -sub attribute { - my ($this, $attr) = @_; - return $this->attributes->{$attr}; -} - -sub equals { - dieContext("Record field objects are not comparable"); -} - -sub check_valid { - my ($this) = @_; - my $name = $this->name; - my $default = $this->attribute("initial"); - dieContext("Default value '$default' is invalid for field '$name'") - if (defined($default) and !$this->legal_value($default)); -} - -sub add_comment { - my $this = shift; - push @{$this->{COMMENTS}}, @_; -} - -sub comments { - return @{shift->{COMMENTS}}; -} - - -# The C structure member name is usually the field name converted to -# lower-case. However if that is a reserved word, use the original. -sub C_name { - my ($this) = @_; - my $name = lc $this->name; - $name = $this->name - if is_reserved($name); - return $name; -} - -sub toDeclaration { - my ($this, $ctype) = @_; - my $name = $this->C_name; - my $result = sprintf " %-19s %-12s", $ctype, "$name;"; - my $prompt = $this->attribute('prompt'); - $result .= "/* $prompt */" if defined $prompt; - return $result; -} - - -################################################################################ - -package DBD::Recfield::DBF_STRING; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - return (length $value < $this->attribute('size')); - # NB - we use '<' to allow space for the terminating nil byte -} - -sub check_valid { - my ($this) = @_; - dieContext("Size missing for DBF_STRING field '$name'") - unless exists $this->attributes->{'size'}; - $this->SUPER::check_valid; -} - -sub toDeclaration { - my ($this) = @_; - my $name = lc $this->name; - my $size = $this->attribute('size'); - my $result = sprintf " %-19s %-12s", 'char', "${name}[${size}];"; - my $prompt = $this->attribute('prompt'); - $result .= "/* $prompt */" if defined $prompt; - return $result; -} - - -################################################################################ - -package DBD::Recfield::DBF_CHAR; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe; - return ($value =~ m/^ $RXint $/x and - $value >= -128 and - $value <= 127); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsInt8"); -} - - -################################################################################ - -package DBD::Recfield::DBF_UCHAR; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe; - return ($value =~ m/^ $RXuint $/x and - $value >= 0 and - $value <= 255); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsUInt8"); -} - - -################################################################################ - -package DBD::Recfield::DBF_SHORT; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe; - return ($value =~ m/^ $RXint $/x and - $value >= -32768 and - $value <= 32767); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsInt16"); -} - - -################################################################################ - -package DBD::Recfield::DBF_USHORT; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe; - return ($value =~ m/^ $RXuint $/x and - $value >= 0 and - $value <= 65535); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsUInt16"); -} - - -################################################################################ - -package DBD::Recfield::DBF_LONG; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe; - return ($value =~ m/^ $RXint $/x); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsInt32"); -} - - -################################################################################ - -package DBD::Recfield::DBF_ULONG; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe; - return ($value =~ m/^ $RXuint $/x and - $value >= 0); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsUInt32"); -} - - -################################################################################ - -package DBD::Recfield::DBF_INT64; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe; - return ($value =~ m/^ $RXint $/x); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsInt64"); -} - - -################################################################################ - -package DBD::Recfield::DBF_UINT64; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe; - return ($value =~ m/^ $RXuint $/x and - $value >= 0); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsUInt64"); -} - - -################################################################################ - -package DBD::Recfield::DBF_FLOAT; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - return ($value =~ m/^ $RXnum $/x); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsFloat32"); -} - - -################################################################################ - -package DBD::Recfield::DBF_DOUBLE; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - return ($value =~ m/^ $RXnum $/x); -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsFloat64"); -} - - -################################################################################ - -package DBD::Recfield::DBF_ENUM; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - return 1; -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsEnum16"); -} - - -################################################################################ - -package DBD::Recfield::DBF_MENU; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - # FIXME: If we know the menu name and the menu exists, check further - return 1; -} - -sub check_valid { - my ($this) = @_; - dieContext("Menu name missing for DBF_MENU field '$name'") - unless defined($this->attribute("menu")); - $this->SUPER::check_valid; -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsEnum16"); -} - - -################################################################################ - -package DBD::Recfield::DBF_DEVICE; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - return 1; -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("epicsEnum16"); -} - - -################################################################################ - -package DBD::Recfield::DBF_INLINK; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - return 1; -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("DBLINK"); -} - - -################################################################################ - -package DBD::Recfield::DBF_OUTLINK; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - return 1; -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("DBLINK"); -} - - -################################################################################ - -package DBD::Recfield::DBF_FWDLINK; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - return 1; -} - -sub toDeclaration { - return shift->SUPER::toDeclaration("DBLINK"); -} - - -################################################################################ - -package DBD::Recfield::DBF_NOACCESS; - -use DBD::Base; -@ISA = qw(DBD::Recfield); - -sub legal_value { - my ($this, $value) = @_; - return ($value eq ''); -} - -sub check_valid { - my ($this) = @_; - dieContext("Type information missing for DBF_NOACCESS field '$name'") - unless defined($this->attribute("extra")); - $this->SUPER::check_valid; -} - -sub toDeclaration { - my ($this) = @_; - my $extra = $this->attribute('extra'); - my $result = sprintf " %-31s ", "$extra;"; - my $prompt = $this->attribute('prompt'); - $result .= "/* $prompt */" if defined $prompt; - return $result; -} - -1; diff --git a/src/tools/DBD/Record.pm b/src/tools/DBD/Record.pm deleted file mode 100644 index 1b7980c2d..000000000 --- a/src/tools/DBD/Record.pm +++ /dev/null @@ -1,123 +0,0 @@ -package DBD::Record; - -use strict; -use warnings; - -use DBD::Base; - -our @ISA = qw(DBD::Base); - -use Carp; - -our ($macrosOk); -my $warned; - -sub init { - my ($this, $type, $name) = @_; - confess "DBD::Record::init: Not a DBD::Recordtype" - unless $type->isa('DBD::Recordtype'); - $this->SUPER::init($name, "record"); - $this->{RECORD_TYPE} = $type; - $this->{ALIASES} = []; - $this->{RECFIELD_LIST} = []; - $this->{FIELD_INDEX} = {}; - $this->{INFO_LIST} = []; - $this->{INFO_ITEMS} = {}; - $this->{COMMENTS} = []; - $this->{POD} = []; - return $this; -} - -# Override, record names are not as strict as recordtype and menu names -sub identifier { - my ($this, $id, $what) = @_; - confess "DBD::Record::identifier: $what undefined!" - unless defined $id; - if ($macrosOk) { - # FIXME - Check name with macro - } - elsif ($id !~ m/^$RXname$/o) { - my @message; - push @message, "A $what should contain only letters, digits and these", - "special characters: _ - : . [ ] < > ;" unless $warned++; - warnContext("Deprecated $what '$id'", @message); - } - return $id; -} - -sub recordtype { - return shift->{RECORD_TYPE}; -} - -sub add_alias { - my ($this, $alias) = @_; - push @{$this->{ALIASES}}, $this->identifier($alias, "alias name"); -} - -sub aliases { - return @{shift->{ALIASES}}; -} - -sub put_field { - my ($this, $field_name, $value) = @_; - my $recfield = $this->{RECORD_TYPE}->field($field_name); - dieContext("No field named '$field_name'") - unless defined $recfield; - dieContext("Can't set $field_name to '$value'") - unless $recfield->legal_value($value); - push @{$this->{RECFIELD_LIST}}, $recfield - unless exists $this->{FIELD_INDEX}->{$field_name}; - $this->{FIELD_INDEX}->{$field_name} = $value; -} - -sub recfields { - return @{shift->{RECFIELD_LIST}}; -} - -sub field_names { # In their original order... - return map {$_->name} @{shift->{RECFIELD_LIST}}; -} - -sub get_field { - my ($this, $field_name) = @_; - return $this->{FIELD_INDEX}->{$field_name} - if exists $this->{FIELD_INDEX}->{$field_name}; - my $recfield = $this->{RECORD_TYPE}->field($field_name); - return $recfield->attribute("initial"); -} - -sub add_info { - my ($this, $info_name, $value) = @_; - push @{$this->{INFO_LIST}}, $info_name - unless exists $this->{INFO_ITEMS}->{$info_name}; - $this->{INFO_ITEMS}->{$info_name} = $value; -} - -sub info_names { - return @{shift->{INFO_LIST}}; -} - -sub info_value { - my ($this, $info_name) = @_; - return $this->{INFO_ITEMS}->{$info_name}; -} - -sub add_comment { - my ($this, $comment) = @_; - push @{$this->{COMMENTS}}, $comment; -} - -sub comments { - return @{shift->{COMMENTS}}; -} - -sub add_pod { - my $this = shift; - push @{$this->{POD}}, @_; -} - -sub pod { - return @{shift->{POD}}; -} - -1; diff --git a/src/tools/DBD/Recordtype.pm b/src/tools/DBD/Recordtype.pm deleted file mode 100644 index e4b0d5481..000000000 --- a/src/tools/DBD/Recordtype.pm +++ /dev/null @@ -1,124 +0,0 @@ -package DBD::Recordtype; -use DBD::Base; -@ISA = qw(DBD::Base); - -use Carp; - -sub init { - my ($this, $name) = @_; - $this->SUPER::init($name, "record type"); - $this->{FIELD_LIST} = []; - $this->{FIELD_INDEX} = {}; - $this->{DEVICE_LIST} = []; - $this->{DEVICE_INDEX} = {}; - $this->{CDEFS} = []; - $this->{COMMENTS} = []; - $this->{POD} = []; - return $this; -} - -sub add_field { - my ($this, $field) = @_; - confess "DBD::Recordtype::add_field: Not a DBD::Recfield" - unless $field->isa('DBD::Recfield'); - my $field_name = $field->name; - dieContext("Duplicate field name '$field_name'") - if exists $this->{FIELD_INDEX}->{$field_name}; - $field->check_valid; - $field->set_number(scalar @{$this->{FIELD_LIST}}); - push @{$this->{FIELD_LIST}}, $field; - $this->{FIELD_INDEX}->{$field_name} = $field; -} - -sub fields { - return @{shift->{FIELD_LIST}}; -} - -sub field_names { # In their original order... - return map {$_->name} @{shift->{FIELD_LIST}}; -} - -sub field { - my ($this, $field_name) = @_; - return $this->{FIELD_INDEX}->{$field_name}; -} - -sub add_device { - my ($this, $device) = @_; - confess "DBD::Recordtype::add_device: Not a DBD::Device" - unless $device->isa('DBD::Device'); - my $choice = $device->choice; - if (exists $this->{DEVICE_INDEX}->{$choice}) { - return if $device->equals($this->{DEVICE_INDEX}->{$choice}); - my @warning = ("Two $this->{NAME} device supports '$choice' conflict"); - my $old = $this->{DEVICE_INDEX}->{$choice}; - push @warning, "Link types differ" - if $old->link_type ne $device->link_type; - push @warning, "DSETs differ" - if $old->name ne $device->name; - dieContext(@warning); - } - push @{$this->{DEVICE_LIST}}, $device; - $this->{DEVICE_INDEX}->{$choice} = $device; -} - -sub devices { - return @{shift->{DEVICE_LIST}}; -} - -sub device { - my ($this, $choice) = @_; - return $this->{DEVICE_INDEX}->{$choice}; -} - -sub add_comment { - my ($this, $comment) = @_; - push @{$this->{COMMENTS}}, $comment; -} - -sub comments { - return @{shift->{COMMENTS}}; -} - -sub add_cdef { - my ($this, $cdef) = @_; - push @{$this->{CDEFS}}, $cdef; -} - -sub cdefs { - return @{shift->{CDEFS}}; -} - -sub toCdefs { - return join("\n", shift->cdefs) . "\n\n"; -} - -sub add_pod { - my $this = shift; - push @{$this->{POD}}, @_; -} - -sub pod { - return @{shift->{POD}}; -} - -sub equals { - my ($new, $known) = @_; - return 0 if ! $known->fields; - return 1 if ! $new->fields; - dieContext("Duplicate definition of record type '$known->{NAME}'"); -} - -sub toDeclaration { - my $this = shift; - my @fields = map { - $_->toDeclaration - } $this->fields; - my $name = $this->name; - $name .= "Record" unless $name eq "dbCommon"; - return "typedef struct $name {\n" . - join("\n", @fields) . - "\n} $name;\n\n"; -} - -1; diff --git a/src/tools/DBD/Registrar.pm b/src/tools/DBD/Registrar.pm deleted file mode 100644 index 29d12cd11..000000000 --- a/src/tools/DBD/Registrar.pm +++ /dev/null @@ -1,9 +0,0 @@ -package DBD::Registrar; -use DBD::Base; -@ISA = qw(DBD::Base); - -sub init { - return shift->SUPER::init(shift, "registrar function"); -} - -1; diff --git a/src/tools/DBD/Variable.pm b/src/tools/DBD/Variable.pm deleted file mode 100644 index cd1b0a334..000000000 --- a/src/tools/DBD/Variable.pm +++ /dev/null @@ -1,38 +0,0 @@ -package DBD::Variable; -use DBD::Base; -@ISA = qw(DBD::Base); - -my %valid_types = ( - # C type name => corresponding iocshArg type identifier - int => 'iocshArgInt', - double => 'iocshArgDouble' -); - -sub init { - my ($this, $name, $type) = @_; - $type = "int" unless defined $type; - exists $valid_types{$type} or - dieContext("Unknown variable type '$type', valid types are:", - sort keys %valid_types); - $this->SUPER::init($name, "variable"); - $this->{VAR_TYPE} = $type; - return $this; -} - -sub var_type { - my $this = shift; - return $this->{VAR_TYPE}; -} - -sub iocshArg_type { - my $this = shift; - return $valid_types{$this->{VAR_TYPE}}; -} - -sub equals { - my ($a, $b) = @_; - return $a->SUPER::equals($b) - && $a->{VAR_TYPE} eq $b->{VAR_TYPE}; -} - -1; diff --git a/src/tools/EPICS/Copy.pm b/src/tools/EPICS/Copy.pm deleted file mode 100644 index d61800e0e..000000000 --- a/src/tools/EPICS/Copy.pm +++ /dev/null @@ -1,75 +0,0 @@ -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use Carp; - -# Copy directories and files from a template - -sub copyTree { - my ($src, $dst, $Rnamesubs, $Rtextsubs) = @_; - # $Rnamesubs contains substitutions for file names, - # $Rtextsubs contains substitutions for file content. - - opendir my $FILES, $src - or croak "opendir failed while copying $src: $!\n"; - my @entries = readdir $FILES; - closedir $FILES; - - foreach (@entries) { - next if m/^\.\.?$/; # ignore . and .. - next if m/^CVS$/; # Shouldn't exist, but... - - my $srcName = "$src/$_"; - - # Substitute any _VARS_ in the name - s/@(\w+?)@/$Rnamesubs->{$1} || "@$1@"/eg; - my $dstName = "$dst/$_"; - - if (-d $srcName) { - print ":" unless $opt_d; - copyDir($srcName, $dstName, $Rnamesubs, $Rtextsubs); - } elsif (-f $srcName) { - print "." unless $opt_d; - copyFile($srcName, $dstName, $Rtextsubs); - } elsif (-l $srcName) { - carp "\nSoft link in template, ignored:\n\t$srcName\n"; - } else { - carp "\nUnknown file type in template, ignored:\n\t$srcName\n"; - } - } -} - -sub copyDir { - my ($src, $dst, $Rnamesubs, $Rtextsubs) = @_; - if (-e $dst && ! -d $dst) { - carp "\nTarget exists but is not a directory, skipping:\n\t$dst\n"; - return; - } - print "Creating directory '$dst'\n" if $opt_d; - mkdir $dst, 0777 or croak "Can't create $dst: $!\n" - unless -d $dst; - copyTree($src, $dst, $Rnamesubs, $Rtextsubs); -} - -sub copyFile { - my ($src, $dst, $Rtextsubs) = @_; - return if (-e $dst); - print "Creating file '$dst'\n" if $opt_d; - open(my $SRC, '<', $src) - and open(my $DST, '>', $dst) - or croak "$! copying $src to $dst\n"; - while (<$SRC>) { - # Substitute any @VARS@ in the text - s{@(\w+?)@} - {exists $Rtextsubs->{$1} ? $Rtextsubs->{$1} : "\@$1\@"}eg; - print $DST $_; - } - close $DST; - close $SRC; -} - -1; diff --git a/src/tools/EPICS/Getopts.pm b/src/tools/EPICS/Getopts.pm deleted file mode 100644 index f448985d0..000000000 --- a/src/tools/EPICS/Getopts.pm +++ /dev/null @@ -1,146 +0,0 @@ -package EPICS::Getopts; -require 5.000; -require Exporter; - -=head1 NAME - -EPICS::Getopts - Process single-character command-line options - -=head1 SYNOPSIS - - use EPICS::Getopts; - - getopts('vo:I@') or die "Bad option\n"; - # -v is a counted flag; -o takes an argument and - # sets $opt_o to its value; -I may be used more than - # once, the values are pushed onto @opt_I - -=head1 DESCRIPTION - -This version of getopts has been modified from the Perl original to add -functionality that was needed by EPICS Perl applications. Some functionality of -the original has also been removed. The main changes were: - -=over 2 - -=item * - -Arguments without any modifiers are now counted, rather than storing a binary -value in the C<$opt_x> variable. This means that multiple copies of the same -option can be detected by the program. - -=item * - -A new B> modifier is supported which collects the option arguments in an -array C<@opt_x>. Multiple copies of this option can be given, which pushes each -argument value onto the end of the array. - -=back - - -=head1 FUNCTIONS - -=over 4 - -=item B> - -The getopts() function processes single-character options. It takes one -argument, a string containing all the options that should be recognized. For -option letters in the string that are followed by a colon B> it sets -C<$opt_x> (where x is the option letter) to the value of that argument. For -option letters followed by an at sign B> it pushes each subsequent argument -onto the array C<@opt_x> (where x is the option letter). For option letters -without any qualifier it adds 1 to the value of C<$opt_x>. Options which take an -argument don't care whether there is a space between the option and the -argument. - -If unspecified switches are found on the command-line, the user will be warned -that an unknown option was given. The getopts() function returns true unless an -invalid option was found. - -Note that, if your code is running under the recommended C -pragma, you will need to declare the necesary package variables with "our" -before the call to getopts: - - our($opt_v, $opt_o, @opt_I); - -To allow programs to process arguments that look like options but aren't, the -function will stop processing options when it sees the argument B>. The -B> will be removed from @ARGV. - -=back - -=cut - -@ISA = qw(Exporter); -@EXPORT = qw(getopts); - -# EPICS::Getopts.pm - An EPICS-specific version of getopts -# -# This version of getopts is modified from the Perl original in the -# following ways: -# -# 1. The perl routine in GetOpt::Std allows a perl hash to be passed -# in as a third argument and used for storing option values. This -# functionality has been deleted. -# 2. Arguments without a ':' modifier are now counted, rather than -# being binary. This means that multiple copies of the same option -# can be detected by the program. -# 3. A new '@' modifier is provided which collects the option arguments -# in an array @opt_X. Multiple copies of this option are permitted, -# which push the argument values onto the end of the list. - -sub getopts ( $;$ ) { - my ($argumentative) = @_; - my (@args,$first,$rest); - my $errs = 0; - local $_; - local @EXPORT; - - @args = split( / */, $argumentative ); - while(@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) { - ($first,$rest) = ($1,$2); - if (/^--$/) { # early exit if -- - shift @ARGV; - last; - } - $pos = index($argumentative,$first); - if ($pos >= 0) { - if (defined($args[$pos+1]) and (index(':@', $args[$pos+1]) >= 0)) { - shift(@ARGV); - if ($rest eq '') { - ++$errs unless @ARGV; - $rest = shift(@ARGV); - } - if ($args[$pos+1] eq ':') { - ${"opt_$first"} = $rest; - push @EXPORT, "\$opt_$first"; - } elsif ($args[$pos+1] eq '@') { - push @{"opt_$first"}, $rest; - push @EXPORT, "\@opt_$first"; - } - } else { - ${"opt_$first"} += 1; - push @EXPORT, "\$opt_$first"; - if ($rest eq '') { - shift(@ARGV); - } else { - $ARGV[0] = "-$rest"; - } - } - } else { - warn "Unknown option: $first\n"; - ++$errs; - if ($rest ne '') { - $ARGV[0] = "-$rest"; - } else { - shift(@ARGV); - } - } - } - local $Exporter::ExportLevel = 1; - import EPICS::Getopts; - $errs == 0; -} - -1; diff --git a/src/tools/EPICS/Path.pm b/src/tools/EPICS/Path.pm deleted file mode 100644 index b86c88007..000000000 --- a/src/tools/EPICS/Path.pm +++ /dev/null @@ -1,152 +0,0 @@ -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -package EPICS::Path; -require 5.000; -require Exporter; - -=head1 NAME - -EPICS::Path - Path-handling utilities for EPICS tools - -=head1 SYNOPSIS - - use lib '/path/to/base/lib/perl'; - use EPICS::Path; - - my $dir = UnixPath('C:\Program Files\EPICS'); - print LocalPath($dir), "\n"; - print AbsPath('../lib', $dir); - -=head1 DESCRIPTION - -This module provides functions for processing pathnames that are commonly needed -by EPICS tools. Windows is not the only culprit, some older automount daemons -insert strange prefixes into absolute directory paths that we have to remove -before storing the result for use later. - -Note that these functions are only designed to work on operating systems that -recognize a forward slash C as a directory separator; this does include -Windows, but not pre-OS-X versions of MacOS which used a colon C<:> instead. - -=head1 FUNCTIONS - -=over 4 - -=cut - -use Carp; -use Cwd qw(getcwd abs_path); -use File::Spec; - -@ISA = qw(Exporter); -@EXPORT = qw(UnixPath LocalPath AbsPath); - -=item B> - -C should be used on any pathnames provided by external tools to -convert them into a form that Perl understands. - -On cygwin we convert Windows drive specs to the equivalent cygdrive path, and on -Windows we switch directory separators from back-slash to forward slashes. - -=cut - -sub UnixPath { - my ($newpath) = @_; - if ($^O eq 'cygwin') { - $newpath =~ s{\\}{/}go; - $newpath =~ s{^([a-zA-Z]):/}{/cygdrive/$1/}; - } elsif ($^O eq 'MSWin32') { - $newpath =~ s{\\}{/}go; - } - return $newpath; -} - -=item B> - -C should be used when generating pathnames for external tools or to -put into a file. It converts paths from the Unix form that Perl understands to -any necessary external representation, and also removes automounter prefixes to -put the path into its canonical form. - -Before Leopard, the Mac OS X automounter inserted a verbose prefix, and in case -anyone is still using SunOS (pre-Solaris) it added its own prefix as well. - -=cut - -sub LocalPath { - my ($newpath) = @_; - if ($^O eq 'darwin') { - # Darwin automounter - $newpath =~ s{^/private/var/auto\.}{/}; - } elsif ($^O eq 'sunos') { - # SunOS automounter - $newpath =~ s{^/tmp_mnt/}{/}; - } - return $newpath; -} - -=item B> - -=item B> - -The C function in Perl's F module doesn't like non-existent -path components other than in the final position, but EPICS tools needs to be -able to handle them in paths like F<$(TOP)/lib/$(T_A)> before the F<$(TOP)/lib> -directory has been created. - -C takes a path C<$path> and optionally an absolute path to a directory -that the first is relative to; if the second argument is not provided the -current working directory is used instead. The result returned has also been -filtered through C to remove any automounter prefixes. - -=cut - -sub AbsPath { - my ($path, $cwd) = @_; - - $path = '.' unless defined $path; - - if (defined $cwd) { - croak("'$cwd' is not an absolute path") - unless $cwd =~ m[^ / ]x; - } else { - $cwd = getcwd(); - } - - # Move leading ./ and ../ components from $path to $cwd - if (my ($dots, $not) = ($path =~ m[^ ( (?: \. \.? /+ )+ ) ( .* ) $]x)) { - $cwd .= "/$dots"; - $path = $not; - } - - # Handle any trailing .. part - if ($path eq '..') { - $cwd .= '/..'; - $path = '.' - } - - # Now calculate the absolute path - my $abs = File::Spec->rel2abs($path, abs_path($cwd)); - $abs = abs_path($abs) if -e $abs; - - return LocalPath($abs); -} - -=back - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2008 UChicago Argonne LLC, as Operator of Argonne National -Laboratory. - -This software is distributed under the terms of the EPICS Open License. - -=cut - -1; diff --git a/src/tools/EPICS/Readfile.pm b/src/tools/EPICS/Readfile.pm deleted file mode 100644 index 4358a6ad2..000000000 --- a/src/tools/EPICS/Readfile.pm +++ /dev/null @@ -1,181 +0,0 @@ -#************************************************************************* -# Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -package EPICS::Readfile; -require 5.000; -require Exporter; - -=head1 NAME - -EPICS::Readfile - DBD and DB-file input for EPICS tools - -=head1 SYNOPSIS - - use lib '/path/to/base/lib/perl'; - use EPICS::macLib; - use EPICS::Readfile; - - my $macros = EPICS::macLib->new('a=1', 'b=2'); - my @path = qw(../dbd /opt/epics/base/dbd); - my $contents = Readfile('input.dbd', $macros, \@path); - printf "Read in %d files", scalar @inputfiles; - -=head1 DESCRIPTION - -This module provides a function for reading DBD and DB files that is commonly -needed by EPICS tools. - -=cut - -use EPICS::macLib; - -@ISA = qw(Exporter); -@EXPORT = qw(@inputfiles &Readfile); - -our $debug=0; -our @inputfiles; - -sub slurp { - my ($FILE, $Rpath) = @_; - my @path = @{$Rpath}; - print "slurp($FILE):\n" if $debug; - if ($FILE !~ m[/]) { - foreach $dir (@path) { - print " trying $dir/$FILE\n" if $debug; - if (-r "$dir/$FILE") { - $FILE = "$dir/$FILE"; - last; - } - } - die "Can't find file '$FILE'\n" unless -r $FILE; - } - print " opening $FILE\n" if $debug; - open FILE, "<$FILE" or die "Can't open $FILE: $!\n"; - push @inputfiles, $FILE; - my @lines = ("##!BEGIN{$FILE}!##\n"); - # Consider replacing these markers with C pre-processor linemarkers. - # See 'info cpp' * Preprocessor Output:: for details. - push @lines, ; - push @lines, "##!END{$FILE}!##\n"; - close FILE or die "Error closing $FILE: $!\n"; - print " read ", scalar @lines, " lines\n" if $debug; - return join '', @lines; -} - -sub expandMacros { - my ($macros, $input) = @_; - return $input unless $macros; - return $macros->expandString($input); -} - -sub splitPath { - my ($path) = @_; - my (@path) = split /[:;]/, $path; - grep s/^$/./, @path; - return @path; -} - -my $RXstr = qr/ " (?: [^"] | \\" )* "/ox; -my $RXnam = qr/[a-zA-Z0-9_\-:.[\]<>;]+/o; -my $string = qr/ ( $RXnam | $RXstr ) /ox; - -sub unquote { - my ($s) = @_; - $s =~ s/^"(.*)"$/$1/o; - return $s; -} - - -=head1 FUNCTIONS - -=over 4 - -=item B> - -This function reads an EPICS DBD or DB file into a string, substitutes any -macros present, then parses the contents for any C, C and -C commands found therein and recursively executes those commands. The -return value from the function is a string comprising the fully expanded -contents of those files. Before executing them any commands will be replaced -with specially formatted comments that allow the original command to be -recovered during later parsing. - -I takes as arguments the input filename, an optional handle to a set -of macro values from L, and a reference to an array -containing the current search path. - -If macro expansion is not required, the second argument may be any boolean False -value such as C<0> or C<()>. See L for more details about -this argument. - -The path argument is a reference to an array of directory paths to be searched, -in order. These paths may be used to locate the original input file and any -include files that it references. The path array will be modified by any -C or C commands found while parsing the input files. - -While processing input filenames (either the original argument or an include -filename) if the filename does not contain any forward-slash C characters the -path will be searched and the first file matching that name will be used. If the -filename contains one or more forward-slash characters it must be either an -absolute path or one that is relative to the current working directory; the -search path is not used in this case. - -=back - -=head1 VARIABLES - -=over 4 - -=item B> - -As new files are processed their names are added to this array which may be -examimed after the I function returns, for example to calculate the -complete set of dependencies for the input file. - -=back - -=cut - -sub Readfile { - my ($file, $macros, $Rpath) = @_; - print "Readfile($file)\n" if $debug; - my $input = expandMacros($macros, slurp($file, $Rpath)); - my @input = split /\n/, $input; - my @output; - foreach (@input) { - if (m/^ \s* include \s+ $string /ox) { - $arg = unquote($1); - print " include $arg\n" if $debug; - push @output, "##! include \"$arg\""; - push @output, Readfile($arg, $macros, $Rpath); - } elsif (m/^ \s* addpath \s+ $string /ox) { - $arg = unquote($1); - print " addpath $arg\n" if $debug; - push @output, "##! addpath \"$arg\""; - push @{$Rpath}, splitPath($arg); - } elsif (m/^ \s* path \s+ $string /ox) { - $arg = unquote($1); - print " path $arg\n" if $debug; - push @output, "##! path \"$arg\""; - @{$Rpath} = splitPath($arg); - } else { - push @output, $_; - } - } - return join "\n", @output; -} - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2015 UChicago Argonne LLC, as Operator of Argonne National -Laboratory. - -This software is distributed under the terms of the EPICS Open License. - -=cut - -1; diff --git a/src/tools/EPICS/Release.pm b/src/tools/EPICS/Release.pm deleted file mode 100644 index e2c4a6826..000000000 --- a/src/tools/EPICS/Release.pm +++ /dev/null @@ -1,113 +0,0 @@ -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use Carp; - -# -# Parse all relevent configure/RELEASE* files and includes -# -sub readReleaseFiles { - my ($relfile, $Rmacros, $Rapps, $arch) = @_; - - my $hostarch = $ENV{'EPICS_HOST_ARCH'}; - $Rmacros->{'EPICS_HOST_ARCH'} = $hostarch if $hostarch; - - return unless (-e $relfile); - readRelease($relfile, $Rmacros, $Rapps); - - if ($hostarch) { - my $hrelfile = "$relfile.$hostarch"; - readRelease($hrelfile, $Rmacros, $Rapps) if (-e $hrelfile); - $hrelfile .= '.Common'; - readRelease($hrelfile, $Rmacros, $Rapps) if (-e $hrelfile); - } - - if ($arch) { - my $crelfile = "$relfile.Common.$arch"; - readRelease($crelfile, $Rmacros, $Rapps) if (-e $crelfile); - - if ($hostarch) { - my $arelfile = "$relfile.$hostarch.$arch"; - readRelease($arelfile, $Rmacros, $Rapps) if (-e $arelfile); - } - } -} - -# -# Parse a configure/RELEASE* file and anything it includes -# -sub readRelease { - my ($file, $Rmacros, $Rapps) = @_; - # $Rmacros is a reference to a hash, $Rapps a ref to an array - - open(my $IN, '<', $file) or croak "Can't open $file: $!\n"; - while (<$IN>) { - chomp; - s/ \r $//x; # Shouldn't need this, but sometimes... - s/ # .* $//x; # Remove trailing comments - s/ \s+ $//x; # Remove trailing whitespace - next if m/^ \s* $/x; # Skip blank lines - - # Handle " = " plus the := and ?= variants - my ($macro, $op, $val) = m/^ \s* (\w+) \s* ([?:]?=) \s* (.*) /x; - if ($macro ne '') { - $macro = 'TOP' if $macro =~ m/^ INSTALL_LOCATION /x; - if (exists $Rmacros->{$macro}) { - next if $op eq '?='; - } else { - push @$Rapps, $macro; - } - $val = expandMacros($val, $Rmacros) if $op eq ':='; - $Rmacros->{$macro} = $val; - next; - } - # Handle "include " and "-include " syntax - my ($op, $path) = m/^ \s* (-? include) \s+ (.*)/x; - $path = expandMacros($path, $Rmacros); - if (-e $path) { - readRelease($path, $Rmacros, $Rapps); - } elsif ($op eq "include") { - carp "EPICS/Release.pm: Include file '$path' not found\n"; - } - } - close $IN; -} - -# -# Expand all (possibly nested) macros in a string -# -sub expandMacros { - my ($str, $Rmacros) = @_; - # $Rmacros is a reference to a hash - - while (my ($pre, $var, $post) = $str =~ m/ (.*) \$\( (\w+) \) (.*) /x) { - last unless exists $Rmacros->{$var}; - $str = $pre . $Rmacros->{$var} . $post; - } - return $str; -} - -# -# Expand all (possibly nested) macros in dictionary -# -sub expandRelease { - my ($Rmacros) = @_; - # $Rmacros is a reference to a hash - - while (my ($macro, $val) = each %$Rmacros) { - while (my ($pre,$var,$post) = $val =~ m/ (.*) \$\( (\w+) \) (.*) /x) { - carp "EPICS/Release.pm: Undefined macro \$($var) used\n" - unless exists $Rmacros->{$var}; - croak "EPICS/Release.pm: Circular definition of macro $macro\n" - if $macro eq $var; - $val = $pre . $Rmacros->{$var} . $post; - $Rmacros->{$macro} = $val; - } - } -} - -1; diff --git a/src/tools/EPICS/macLib.pm b/src/tools/EPICS/macLib.pm deleted file mode 100644 index 412c6d709..000000000 --- a/src/tools/EPICS/macLib.pm +++ /dev/null @@ -1,250 +0,0 @@ -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -package EPICS::macLib::entry; - -sub new ($$) { - my $class = shift; - my $this = { - name => shift, - type => shift, - raw => '', - val => '', - visited => 0, - error => 0, - }; - bless $this, $class; - return $this; -} - -sub report ($) { - my ($this) = @_; - return unless defined $this->{raw}; - printf "%1s %-16s %-16s %s\n", - ($this->{error} ? '*' : ' '), $this->{name}, $this->{raw}, $this->{val}; -} - - -package EPICS::macLib; - -use Carp; - -sub new ($@) { - my $proto = shift; - my $class = ref($proto) || $proto; - my $this = { - dirty => 0, - noWarn => 0, - macros => [{}], # [0] is current scope, [1] is parent etc. - }; - bless $this, $class; - $this->installList(@_); - return $this; -} - -sub installList ($@) { - # Argument is a list of strings which are arguments to installMacros - my $this = shift; - while (@_) { - $this->installMacros(shift); - } -} - -sub installMacros ($$) { - # Argument is a string: a=1,b="2",c,d='hello' - my $this = shift; - $_ = shift; - until (defined pos($_) and pos($_) == length($_)) { - m/\G \s* /xgc; # Skip whitespace - if (m/\G ( [A-Za-z0-9_-]+ ) \s* /xgc) { - my ($name, $val) = ($1); - if (m/\G = \s* /xgc) { - # The value follows, handle quotes and escapes - until (pos($_) == length($_)) { - if (m/\G , /xgc) { last; } - elsif (m/\G ' ( ( [^'] | \\ ' )* ) ' /xgc) { $val .= $1; } - elsif (m/\G " ( ( [^"] | \\ " )* ) " /xgc) { $val .= $1; } - elsif (m/\G \\ ( . ) /xgc) { $val .= $1; } - elsif (m/\G ( . ) /xgc) { $val .= $1; } - else { die "How did I get here?"; } - } - $this->putValue($name, $val); - } elsif (m/\G , /xgc or (pos($_) == length($_))) { - $this->putValue($name, undef); - } else { - warn "How did I get here?"; - } - } elsif (m/\G ( .* )/xgc) { - croak "Can't find a macro definition in '$1'"; - } else { - last; - } - } -} - -sub putValue ($$$) { - my ($this, $name, $raw) = @_; - if (exists $this->{macros}[0]{$name}) { - if (!defined $raw) { - delete $this->{macros}[0]{$name}; - } else { - $this->{macros}[0]{$name}{raw} = $raw; - } - } else { - my $entry = EPICS::macLib::entry->new($name, 'macro'); - $entry->{raw} = $raw; - $this->{macros}[0]{$name} = $entry; - } - $this->{dirty} = 1; -} - -sub pushScope ($) { - my ($this) = @_; - unshift @{$this->{macros}}, {}; -} - -sub popScope ($) { - my ($this) = @_; - shift @{$this->{macros}}; -} - -sub suppressWarning($$) { - my ($this, $suppress) = @_; - $this->{noWarn} = $suppress; -} - -sub expandString($$) { - my ($this, $src) = @_; - $this->_expand; - (my $name = $src) =~ s/^ (.{20}) .* $/$1.../xs; - my $entry = EPICS::macLib::entry->new($name, 'string'); - my $result = $this->_translate($entry, 0, $src); - return $result unless $entry->{error}; - return $this->{noWarn} ? $result : undef; -} - -sub reportMacros ($) { - my ($this) = @_; - $this->_expand; - print "Macro report\n============\n"; - foreach my $scope (@{$this->{macros}}) { - foreach my $name (keys %{$scope}) { - my $entry = $scope->{$name}; - $entry->report; - } - } continue { - print " -- scope ends --\n"; - } -} - - -# Private routines, not intended for public use - -sub _expand ($) { - my ($this) = @_; - return unless $this->{dirty}; - foreach my $scope (@{$this->{macros}}) { - foreach my $name (keys %{$scope}) { - my $entry = $scope->{$name}; - $entry->{val} = $this->_translate($entry, 1, $entry->{raw}); - } - } - $this->{dirty} = 0; -} - -sub _lookup ($$$$$) { - my ($this, $name) = @_; - foreach my $scope (@{$this->{macros}}) { - if (exists $scope->{$name}) { - return undef # Macro marked as deleted - unless defined $scope->{$name}{raw}; - return $scope->{$name}; - } - } - return undef; -} - -sub _translate ($$$$) { - my ($this, $entry, $level, $str) = @_; - return $this->_trans($entry, $level, '', \$str); -} - -sub _trans ($$$$$) { - my ($this, $entry, $level, $term, $R) = @_; - return $$R - if (!defined $$R or - $$R =~ m/\A [^\$]* \Z/x); # Short-circuit if no macros - my $quote = 0; - my $val; - until (defined pos($$R) and pos($$R) == length($$R)) { - if ($term and ($$R =~ m/\G (?= [$term] ) /xgc)) { - last; - } - if ($$R =~ m/\G \$ ( [({] ) /xgc) { - my $macEnd = $1; - $macEnd =~ tr/({/)}/; - my $name2 = $this->_trans($entry, $level+1, "=$macEnd", $R); - my $entry2 = $this->_lookup($name2); - if (!defined $entry2) { # Macro not found - if ($$R =~ m/\G = /xgc) { # Use default value given - $val .= $this->_trans($entry, $level+1, $macEnd, $R); - } else { - unless ($this->{noWarn}) { - $entry->{error} = 1; - printf STDERR "macLib: macro '%s' is undefined (expanding %s '%s')\n", - $name2, $entry->{type}, $entry->{name}; - } - $val .= "\$($name2)"; - } - $$R =~ m/\G [$macEnd] /xgc; # Discard close bracket - } else { # Macro found - if ($entry2->{visited}) { - $entry->{error} = 1; - printf STDERR "macLib: %s '%s' is recursive (expanding %s '%s')\n", - $entry->{type}, $entry->{name}, $entry2->{type}, $entry2->{name}; - $val .= "\$($name)"; - } else { - if ($$R =~ m/\G = /xgc) { # Discard default value - local $this->{noWarn} = 1; # Temporarily kill warnings - $this->_trans($entry, $level+1, $macEnd, $R); - } - $$R =~ m/\G [$macEnd] /xgc; # Discard close bracket - if ($this->{dirty}) { # Translate raw value - $entry2->{visited} = 1; - $val .= $this->_trans($entry, $level+1, '', \$entry2->{raw}); - $entry2->{visited} = 0; - } else { - $val .= $entry2->{val}; # Here's one I made earlier... - } - } - } - } elsif ($level > 0) { # Discard quotes and escapes - if ($quote and $$R =~ m/\G $quote /xgc) { - $quote = 0; - } elsif ($$R =~ m/\G ( ['"] ) /xgc) { - $quote = $1; - } elsif ($$R =~ m/\G \\? ( . ) /xgc) { - $val .= $1; - } else { - warn "How did I get here? level=$level"; - } - } else { # Level 0 - if ($$R =~ m/\G \\ ( . ) /xgc) { - $val .= "\\$1"; - } elsif ($$R =~ m/\G ( [^\\\$'")}]* ) /xgc) { - $val .= $1; - } elsif ($$R =~ m/\G ( . ) /xgc) { - $val .= $1; - } else { - warn "How did I get here? level=$level"; - } - } - } - return $val; -} - -1; diff --git a/src/tools/Makefile b/src/tools/Makefile deleted file mode 100644 index e7457ae67..000000000 --- a/src/tools/Makefile +++ /dev/null @@ -1,96 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../.. - -include $(TOP)/configure/CONFIG - -# Bootstrap resolution: tools not installed yet -TOOLS = $(TOP)/src/tools - -PERL_MODULES += EPICS/Copy.pm -PERL_MODULES += EPICS/Path.pm -PERL_MODULES += EPICS/Release.pm -PERL_MODULES += EPICS/Readfile.pm -PERL_MODULES += EPICS/Getopts.pm -PERL_MODULES += EPICS/macLib.pm - -PERL_MODULES += DBD.pm -PERL_MODULES += DBD/Base.pm -PERL_MODULES += DBD/Breaktable.pm -PERL_MODULES += DBD/Device.pm -PERL_MODULES += DBD/Driver.pm -PERL_MODULES += DBD/Link.pm -PERL_MODULES += DBD/Function.pm -PERL_MODULES += DBD/Menu.pm -PERL_MODULES += DBD/Output.pm -PERL_MODULES += DBD/Parser.pm -PERL_MODULES += DBD/Recfield.pm -PERL_MODULES += DBD/Recordtype.pm -PERL_MODULES += DBD/Record.pm -PERL_MODULES += DBD/Registrar.pm -PERL_MODULES += DBD/Variable.pm - -PERL_SCRIPTS += assembleSnippets.pl -PERL_SCRIPTS += convertRelease.pl -PERL_SCRIPTS += cvsclean.pl -PERL_SCRIPTS += dos2unix.pl -PERL_SCRIPTS += expandVars.pl -PERL_SCRIPTS += fullPathName.pl -PERL_SCRIPTS += installEpics.pl -PERL_SCRIPTS += makeIncludeDbd.pl -PERL_SCRIPTS += makeMakefile.pl -PERL_SCRIPTS += makeTestfile.pl -PERL_SCRIPTS += mkmf.pl -PERL_SCRIPTS += munch.pl -PERL_SCRIPTS += replaceVAR.pl -PERL_SCRIPTS += tap-to-junit-xml.pl -PERL_SCRIPTS += useManifestTool.pl -PERL_SCRIPTS += genVersionHeader.pl - -PERL_SCRIPTS += dbdToMenuH.pl -PERL_SCRIPTS += dbdToRecordtypeH.pl -PERL_SCRIPTS += dbdExpand.pl -PERL_SCRIPTS += dbExpand.pl -PERL_SCRIPTS += dbdToHtml.pl -PERL_SCRIPTS += podToHtml.pl -PERL_SCRIPTS += podRemove.pl -PERL_SCRIPTS += registerRecordDeviceDriver.pl - -HTMLS = style.css -HTMLS += EPICS/Getopts.html -HTMLS += EPICS/Path.html -HTMLS += EPICS/Readfile.html -HTMLS += fullPathName.html -HTMLS += podToHtml.html -HTMLS += podRemove.html -HTMLS += munch.html - -# Build Package Config Files - -FINAL_LOCATION ?= $(shell $(PERL) $(TOOLS)/fullPathName.pl $(INSTALL_LOCATION)) -C_CFLAGS += $(filter-out -g,$(filter-out -O%,$(filter-out -W%,$(CPPFLAGS)))) -C_CFLAGS += $(filter-out -g,$(filter-out -O%,$(filter-out -W%,$(CFLAGS)))) -PKGVARS += FINAL_LOCATION OS_CLASS CMPLR_CLASS C_CFLAGS LDFLAGS LDLIBS -PKGVARS += EPICS_VERSION EPICS_REVISION EPICS_MODIFICATION EPICS_PATCH_LEVEL -PKGVARS += CC CCC CPP AR LD -PKGVARS += EPICS_BASE_IOC_LIBS - -EXPANDFLAGS += $(foreach var,$(PKGVARS),-D$(var)="$(strip $($(var)))") -PKGCONFIG += epics-base-$(T_A).pc -ifeq ($(T_A),$(EPICS_HOST_ARCH)) -PKGCONFIG += epics-base.pc -endif - -EXPAND += $(PKGCONFIG:%=%@) -CLEANS += epics-base-$(T_A).pc@ - -include $(TOP)/configure/RULES - -epics-base-$(T_A).pc@: ../epics-base-arch.pc@ - @$(RM) $@ - @$(CP) $< $@ - diff --git a/src/tools/assembleSnippets.pl b/src/tools/assembleSnippets.pl deleted file mode 100644 index e6f0c77a3..000000000 --- a/src/tools/assembleSnippets.pl +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2015 ITER Organization. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; -use warnings; - -use Getopt::Std; -use Sys::Hostname; -use File::Basename; -use Data::Dumper; - -our ($opt_o, $opt_d, $opt_m, $opt_i, $opt_M); - -$Getopt::Std::OUTPUT_HELP_VERSION = 1; -&HELP_MESSAGE if !getopts('M:i:m:o:d') || @ARGV == 0; - -my $out; -my $dep; -my %snippets; -my $ipattern; - -my $datetime = localtime(); -my $user = $ENV{LOGNAME} || $ENV{USER} || $ENV{USERNAME}; -my $host = hostname; -my %replacements = ( - _DATETIME_ => $datetime, - _USERNAME_ => $user, - _HOST_ => $host, -); - -if ($opt_o) { - open $out, '>', $opt_o or - die "Can't create $opt_o: $!\n"; - print STDERR "opened file $opt_o for output\n" if $opt_d; - $replacements{_OUTPUTFILE_} = $opt_o; -} else { - open $out, '>&', STDOUT; - print STDERR "using STDOUT for output\n" if $opt_d; - $replacements{_OUTPUTFILE_} = 'STDERR'; -} - -if ($opt_m) { - foreach my $r (split /,/, $opt_m) { - (my $k, my $v) = split /=/, $r; - $replacements{$k} = $v; - } -} - -if ($opt_M) { - open $dep, '>', $opt_M or - die "Can't create $opt_M: $!\n"; - print STDERR "opened dependency file $opt_M for output\n" if $opt_d; - print $dep basename($opt_o), ":"; -} - -if ($opt_i) { - $ipattern = qr($opt_i); -} - -# %snippets is a hash {rank} -# of hashes {name-after-rank} -# of arrays[] [files...] -# of arrays[2] [filename, command] -print STDERR "reading input files\n" if $opt_d; -foreach (@ARGV) { - my $name = basename($_); - if ($opt_i and not $name =~ /$ipattern/) { - print STDERR " snippet $_ does not match input pattern $opt_i - ignoring\n" if $opt_d; - next; - } - if ($name =~ /\A([ARD]?)([0-9]+)(.*[^~])\z/) { - print STDERR " considering snippet $_\n" if $opt_d; - if (exists $snippets{$2}) { - my %rank = %{$snippets{$2}}; - my @files = @{ $rank{(keys %rank)[0]} }; - my $existcmd = $files[0]->[1]; - if ($1 eq "D" and $existcmd ne "D") { - print STDERR " ignoring 'D' default for existing rank $2\n" if $opt_d; - next; - } elsif ($1 eq "R") { - print STDERR " 'R' command - deleting existing rank $2 snippets\n" if $opt_d; - $snippets{$2} = {}; - } elsif ($existcmd eq "D") { - print STDERR " deleting existing rank $2 default snippet\n" if $opt_d; - $snippets{$2} = {}; - } - } - if ($opt_d) { - print STDERR " adding snippet "; - print STDERR "marked as default " if $1 eq "D"; - print STDERR "to rank $2\n"; - } - $snippets{$2}{$3} = () if (not exists $snippets{$2}{$3}); - push @{$snippets{$2}{$3}}, [ $_, $1 ]; - } -} - -if ($opt_d) { - print STDERR "finished reading input files\n"; - print STDERR "dumping the final snippet structure\n"; - print STDERR Dumper(\%snippets); - print STDERR "dumping the macro replacements\n"; - print STDERR Dumper(\%replacements); - print STDERR "creating output\n"; -} - -foreach my $r (sort {$a<=>$b} keys %snippets) { - print STDERR " working on rank $r\n" if $opt_d; - foreach my $n (sort keys %{$snippets{$r}}) { - foreach my $s (@{$snippets{$r}{$n}}) { - my $in; - my $f = $s->[0]; - print STDERR " snippet $n from file $f\n" if $opt_d; - open $in, '<', $f or die "Can't open $f: $!\n"; - $replacements{_SNIPPETFILE_} = $f; - print $dep " \\\n $f" if $opt_M; - while (<$in>) { - chomp; - foreach my $k (keys %replacements) { - s/$k/$replacements{$k}/g; - } - print $out $_, "\n"; - } - close $in; - } - } -} - -print STDERR "finished creating output, closing\n" if $opt_d; -if ($opt_M) { - print $dep "\n"; - close $dep; -} -close $out; - -sub HELP_MESSAGE { - print STDERR "Usage: assembleSnippets.pl [options] snippets ...\n"; - print STDERR "Options:\n"; - print STDERR " -o file output file [STDOUT]\n"; - print STDERR " -d debug mode [no]\n"; - print STDERR " -m macros list of macro replacements as \"key=val,key=val\"\n"; - print STDERR " -i pattern pattern for input files to match\n"; - print STDERR " -M file write file with dependency rule suitable for make\n"; - exit 2; -} diff --git a/src/tools/convertRelease.pl b/src/tools/convertRelease.pl deleted file mode 100644 index e2f13a556..000000000 --- a/src/tools/convertRelease.pl +++ /dev/null @@ -1,272 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# Convert configure/RELEASE file(s) into something else. -# - -use strict; -use warnings; - -use Cwd qw(cwd); -use Getopt::Std; -$Getopt::Std::STANDARD_HELP_VERSION = 1; - -use FindBin qw($Bin); -use lib ("$Bin/../../lib/perl", $Bin); - -use EPICS::Path; -use EPICS::Release; - -use vars qw($arch $top $iocroot $root); - -our ($opt_a, $opt_t, $opt_T); - -getopts('a:t:T:') or HELP_MESSAGE(); - -my $cwd = UnixPath(cwd()); - -if ($opt_a) { - $arch = $opt_a; -} else { # Look for O. in current path - $cwd =~ m{ / O. ([\w-]+) $}x; - $arch = $1; -} - -if ($opt_T) { - $top = $opt_T; -} else { # Find $top from current path - # This approach only works inside iocBoot/* and configure/* - $top = $cwd; - $top =~ s{ / iocBoot .* $}{}x; - $top =~ s{ / configure .* $}{}x; -} - -# The IOC may need a different path to get to $top -if ($opt_t) { - $iocroot = $opt_t; - $root = $top; - if ($iocroot eq $root) { - # Identical paths, -t not needed - undef $opt_t; - } else { - while (substr($iocroot, -1, 1) eq substr($root, -1, 1)) { - chop $iocroot; - chop $root; - } - } -} - -HELP_MESSAGE() unless @ARGV == 1; - -my $outfile = $ARGV[0]; - -# TOP refers to this application -my %macros = (TOP => LocalPath($top)); -my @apps = ('TOP'); # Records the order of definitions in RELEASE file - -# Read the RELEASE file(s) -my $relfile = "$top/configure/RELEASE"; -die "Can't find $relfile" unless (-f $relfile); -readReleaseFiles($relfile, \%macros, \@apps, $arch); -expandRelease(\%macros); - - -# This is a perl switch statement: -for ($outfile) { - m/releaseTops/ and do { releaseTops(); last; }; - m/dllPath\.bat/ and do { dllPath(); last; }; - m/relPaths\.sh/ and do { relPaths(); last; }; - m/cdCommands/ and do { cdCommands(); last; }; - m/envPaths/ and do { envPaths(); last; }; - m/checkRelease/ and do { checkRelease(); last; }; - die "Output file type \'$outfile\' not supported"; -} - - -############### Subroutines only below here ############### - -sub HELP_MESSAGE { - print STDERR <$outfile") or die "$! creating $outfile"; - print OUT "\@ECHO OFF\n"; - # This SET syntax is essential for supporting embedded spaces and '&' - # characters in both the PATH variable and the new directory components - print OUT "SET \"PATH=", join(';', binDirs(), '%PATH%'), "\"\n"; - close OUT; -} - -sub relPaths { - unlink $outfile; - open(OUT, ">$outfile") or die "$! creating $outfile"; - print OUT "export PATH=\"", join(':', binDirs(), '$PATH'), "\"\n"; - close OUT; -} - -sub binDirs { - die "Architecture not set (use -a option)\n" unless ($arch); - my @includes = grep !m/^ (RULES | TEMPLATE_TOP) $/x, @apps; - my @path; - foreach my $app (@includes) { - my $path = $macros{$app} . "/bin/$arch"; - next unless -d $path; - $path =~ s/^$root/$iocroot/o if ($opt_t); - push @path, LocalPath($path); - } - return @path; -} - -# -# Generate cdCommands file with cd path strings for vxWorks IOCs and -# RTEMS IOCs using CEXP (need parentheses around command arguments). -# -sub cdCommands { - die "Architecture not set (use -a option)" unless ($arch); - my @includes = grep !m/^(RULES | TEMPLATE_TOP)$/x, @apps; - - unlink($outfile); - open(OUT,">$outfile") or die "$! creating $outfile"; - - my $startup = $cwd; - $startup =~ s/^$root/$iocroot/o if ($opt_t); - $startup =~ s/([\\"])/\\$1/g; # escape back-slashes and double-quotes - - print OUT "startup = \"$startup\"\n"; - - my $ioc = $cwd; - $ioc =~ s/^.*\///; # iocname is last component of directory name - - print OUT "putenv(\"IOC=$ioc\")\n"; - - foreach my $app (@includes) { - my $iocpath = my $path = $macros{$app}; - $iocpath =~ s/^$root/$iocroot/o if ($opt_t); - $iocpath =~ s/([\\"])/\\$1/g; # escape back-slashes and double-quotes - my $app_lc = lc($app); - print OUT "$app_lc = \"$iocpath\"\n" - if (-d $path); - print OUT "putenv(\"$app=$iocpath\")\n" - if (-d $path); - print OUT "${app_lc}bin = \"$iocpath/bin/$arch\"\n" - if (-d "$path/bin/$arch"); - } - close OUT; -} - -# -# Generate envPaths file with epicsEnvSet commands for iocsh IOCs. -# Include parentheses anyway in case CEXP users want to use this. -# -sub envPaths { - my @includes = grep !m/^ (RULES | TEMPLATE_TOP) $/x, @apps; - - unlink($outfile); - open(OUT,">$outfile") or die "$! creating $outfile"; - - my $ioc = $cwd; - $ioc =~ s/^.*\///; # iocname is last component of directory name - - print OUT "epicsEnvSet(\"IOC\",\"$ioc\")\n"; - - foreach my $app (@includes) { - my $iocpath = my $path = $macros{$app}; - $iocpath =~ s/^$root/$iocroot/o if ($opt_t); - $iocpath =~ s/([\\"])/\\$1/g; # escape back-slashes and double-quotes - print OUT "epicsEnvSet(\"$app\",\"$iocpath\")\n" if (-d $path); - } - close OUT; -} - -# -# Check RELEASE file consistency with support modules -# -sub checkRelease { - my $status = 0; - delete $macros{RULES}; - delete $macros{TOP}; - delete $macros{TEMPLATE_TOP}; - - while (my ($app, $path) = each %macros) { - my %check = (TOP => $path); - my @order = (); - my $relfile = "$path/configure/RELEASE"; - readReleaseFiles($relfile, \%check, \@order, $arch); - expandRelease(\%check); - delete $check{TOP}; - delete $check{EPICS_HOST_ARCH}; - - while (my ($parent, $ppath) = each %check) { - if (exists $macros{$parent} && - AbsPath($macros{$parent}) ne AbsPath($ppath)) { - print "\n" unless ($status); - print "Definition of $parent conflicts with $app support.\n"; - print "In this application a RELEASE file defines\n"; - print "\t$parent = $macros{$parent}\n"; - print "but $app at $path defines\n"; - print "\t$parent = $ppath\n"; - $status = 1; - } - } - } - - my @modules = grep(!m/^(RULES|TOP|TEMPLATE_TOP)$/, @apps); - my $app = shift @modules; - my $latest = AbsPath($macros{$app}); - my %paths = ($latest => $app); - foreach $app (@modules) { - my $path = AbsPath($macros{$app}); - if ($path ne $latest && exists $paths{$path}) { - my $prev = $paths{$path}; - print "\n" unless ($status); - print "This application's RELEASE file(s) define\n"; - print "\t$app = $macros{$app}\n"; - print "after but not adjacent to\n\t$prev = $macros{$prev}\n"; - print "both of which resolve to $path\n" - if $path ne $macros{$app} || $path ne $macros{$prev}; - $status = 2; - } - $paths{$path} = $app; - $latest = $path; - } - if ($status == 2) { - print "Module definitions that share paths must be grouped together.\n"; - print "Either remove a definition, or move it to a line immediately\n"; - print "above or below the other(s).\n"; - print "Any non-module definitions belong in configure/CONFIG_SITE.\n"; - $status = 1; - } - - print "\n" if $status; - exit $status; -} diff --git a/src/tools/cvsclean.pl b/src/tools/cvsclean.pl deleted file mode 100644 index 8dac418d7..000000000 --- a/src/tools/cvsclean.pl +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# This file is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - -# Find and delete cvs .#* and editor backup *~ -# files from all dirs of the directory tree. - -use File::Find; - -@ARGV = ('.') unless @ARGV; - -find sub { unlink if -f && m/(^\.\#)|(~$)/ }, @ARGV; diff --git a/src/tools/dbExpand.pl b/src/tools/dbExpand.pl deleted file mode 100644 index abfea833b..000000000 --- a/src/tools/dbExpand.pl +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env perl - -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# $Id$ - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use DBD; -use DBD::Parser; -use DBD::Output; -use EPICS::Getopts; -use EPICS::Readfile; -use EPICS::macLib; - -our ($opt_D, @opt_I, @opt_S, $opt_o, $opt_V); - -getopts('DI@S@o:V') or - die "Usage: dbExpand [-D] [-I dir] [-S macro=val] [-o out.db] in.dbd in.db ..."; - -my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32? -my $macros = EPICS::macLib->new(@opt_S); -my $dbd = DBD->new(); - -$macros->suppressWarning(!$opt_V); -$DBD::Record::macrosOk = !$opt_V; - -# Calculate filename for the dependency warning message below -my $dep = $opt_o; -my $dot_d = ''; -if ($opt_D) { - $dep =~ s{\.\./O\.Common/(.*)}{$1\$\(DEP\)}; - $dot_d = '.d'; -} else { - $dep = "\$(COMMON_DIR)/$dep"; -} - -die "dbExpand.pl: No input files for $opt_o\n" if !@ARGV; - -my $errors = 0; - -while (@ARGV) { - my $file = shift @ARGV; - eval { - &ParseDBD($dbd, &Readfile($file, $macros, \@opt_I)); - }; - if ($@) { - warn "dbExpand.pl: $@"; - my $outfile = $opt_o ? " to create '$opt_o$dot_d'" : ''; - warn " while reading '$file'$outfile\n"; - warn " Your Makefile may need this dependency rule:\n", - " $dep: \$(COMMON_DIR)/$file\n" - if $@ =~ m/Can't find file '$file'/; - ++$errors; - } -} - -if ($opt_D) { # Output dependencies only, ignore errors - my %filecount; - my @uniqfiles = grep { not $filecount{$_}++ } @inputfiles; - print "$opt_o: ", join(" \\\n ", @uniqfiles), "\n\n"; - print map { "$_:\n" } @uniqfiles; - exit 0; -} - -die "dbExpand.pl: Exiting due to errors\n" if $errors; - -my $out; -if ($opt_o) { - open $out, '>', $opt_o or die "Can't create $opt_o: $!\n"; -} else { - $out = *STDOUT; -} - -&OutputDB($out, $dbd); - -if ($opt_o) { - close $out or die "Closing $opt_o failed: $!\n"; -} -exit 0; diff --git a/src/tools/dbdExpand.pl b/src/tools/dbdExpand.pl deleted file mode 100644 index 71f938418..000000000 --- a/src/tools/dbdExpand.pl +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env perl - -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use DBD; -use DBD::Parser; -use DBD::Output; -use EPICS::Getopts; -use EPICS::Readfile; -use EPICS::macLib; - -our ($opt_D, @opt_I, @opt_S, $opt_o); - -getopts('DI@S@o:') or - die "Usage: dbdExpand [-D] [-I dir] [-S macro=val] [-o out.dbd] in.dbd ..."; - -my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32? -my $macros = EPICS::macLib->new(@opt_S); -my $dbd = DBD->new(); - -$macros->suppressWarning(1); - -# Calculate filename for the dependency warning message below -my $dep = $opt_o; -my $dot_d = ''; -if ($opt_D) { - $dep =~ s{\.\./O\.Common/(.*)}{\1\$\(DEP\)}; - $dot_d = '.d'; -} else { - $dep = "\$(COMMON_DIR)/$dep"; -} - -die "dbdExpand.pl: No input files for $opt_o\n" if !@ARGV; - -my $errors = 0; - -while (@ARGV) { - my $file = shift @ARGV; - eval { - ParseDBD($dbd, Readfile($file, $macros, \@opt_I)); - }; - if ($@) { - warn "dbdExpand.pl: $@"; - warn " while reading '$file' to create '$opt_o$dot_d'\n"; - warn " Your Makefile may need this dependency rule:\n", - " $dep: \$(COMMON_DIR)/$file\n" - if $@ =~ m/Can't find file '$file'/; - ++$errors; - } -} - -if ($opt_D) { # Output dependencies only, ignore errors - my %filecount; - my @uniqfiles = grep { not $filecount{$_}++ } @inputfiles; - print "$opt_o: ", join(" \\\n ", @uniqfiles), "\n\n"; - print map { "$_:\n" } @uniqfiles; - exit 0; -} - -die "dbdExpand.pl: Exiting due to errors\n" if $errors; - -my $out; -if ($opt_o) { - open $out, '>', $opt_o or die "Can't create $opt_o: $!\n"; -} else { - $out = *STDOUT; -} - -OutputDBD($out, $dbd); - -if ($opt_o) { - close $out or die "Closing $opt_o failed: $!\n"; -} -exit 0; diff --git a/src/tools/dbdReport.pl b/src/tools/dbdReport.pl deleted file mode 100644 index 876ec0abb..000000000 --- a/src/tools/dbdReport.pl +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/perl - -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use DBD; -use DBD::Parser; -use EPICS::Getopts; -use EPICS::macLib; -use EPICS::Readfile; -use Text::Wrap; - -#$EPICS::Readfile::debug = 1; -#$DBD::Parser::debug = 1; - -getopts('I@S@') or die usage(); - -sub usage() { - "Usage: dbdReport [-I dir:dir2] [-S macro=val,...] file.dbd ..."; -} - -my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32? -my $macros = EPICS::macLib->new(@opt_S); -my $dbd = DBD->new(); - -ParseDBD($dbd, Readfile(shift @ARGV, $macros, \@opt_I)) while @ARGV; - -$Text::Wrap::columns = 75; - -my @menus = sort keys %{$dbd->menus}; -print wrap("Menus:\t", "\t", join(', ', @menus)), "\n" - if @menus; -my @drivers = sort keys %{$dbd->drivers}; -print wrap("Drivers: ", "\t", join(', ', @drivers)), "\n" - if @drivers; -my @variables = sort keys %{$dbd->variables}; -print wrap("Variables: ", "\t", join(', ', @variables)), "\n" - if @variables; -my @registrars = sort keys %{$dbd->registrars}; -print wrap("Registrars: ", "\t", join(', ', @registrars)), "\n" - if @registrars; -my @breaktables = sort keys %{$dbd->breaktables}; -print wrap("Breaktables: ", "\t", join(', ', @breaktables)), "\n" - if @breaktables; -my %recordtypes = %{$dbd->recordtypes}; -if (%recordtypes) { - @rtypes = sort keys %recordtypes; - print wrap("Recordtypes: ", "\t", join(', ', @rtypes)), "\n"; - foreach my $rtyp (@rtypes) { - my @devices = $recordtypes{$rtyp}->devices; - print wrap("Devices($rtyp): ", "\t", - join(', ', map {$_->choice} @devices)), "\n" - if @devices; - } -} -my @records = sort keys %{$dbd->records}; -print wrap("Records: ", "\t", join(', ', @records)), "\n" - if @records; - diff --git a/src/tools/dbdToHtml.pl b/src/tools/dbdToHtml.pl deleted file mode 100644 index 2c0417cbb..000000000 --- a/src/tools/dbdToHtml.pl +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/perl -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use DBD; -use DBD::Parser; -use EPICS::Getopts; -use EPICS::macLib; -use EPICS::Readfile; - -BEGIN { - $::XHTML = eval "require Pod::Simple::XHTML; 1"; - $::ENTITIES = eval "require HTML::Entities; 1"; - if (!$::XHTML) { - require Pod::Simple::HTML; - } - if (!$::ENTITIES) { - my %entities = ( - q{>} => 'gt', - q{<} => 'lt', - q{'} => '#39', - q{"} => 'quot', - q{&} => 'amp', - ); - - sub encode_entities { - my $str = shift; - my $ents = join '', keys %entities; - $str =~ s/([ $ents ])/'&' . ($entities{$1} || sprintf '#x%X', ord $1) . ';'/xge; - return $str; - } - } -} - -my $tool = 'dbdToHtml'; - -use vars qw($opt_D @opt_I $opt_o); -getopts('DI@o:') or - die "Usage: $tool [-D] [-I dir] [-o file.html] file.dbd.pod\n"; - -my $dbd = DBD->new(); - -my $infile = shift @ARGV; -$infile =~ m/\.dbd.pod$/ or - die "$tool: Input file '$infile' must have '.dbd.pod' extension\n"; - -ParseDBD($dbd, Readfile($infile, 0, \@opt_I)); - -if (!$opt_o) { - ($opt_o = $infile) =~ s/\.dbd\.pod$/.html/; - $opt_o =~ s/^.*\///; - $opt_o =~ s/dbCommonRecord/dbCommon/; -} - -if ($opt_D) { # Output dependencies only - my %filecount; - my @uniqfiles = grep { not $filecount{$_}++ } @inputfiles; - print "$opt_o: ", join(" \\\n ", @uniqfiles), "\n\n"; - print map { "$_:\n" } @uniqfiles; - exit 0; -} - -(my $title = $opt_o) =~ s/\.html$//; - -open my $out, '>', $opt_o or - die "Can't create $opt_o: $!\n"; - -# Parse the Pod text from the root DBD object -my $pod = join "\n", '=for html
', '', - map { - # Handle a 'recordtype' Pod directive - if (m/^ =recordtype \s+ (\w+) /x) { - my $rn = $1; - my $rtyp = $dbd->recordtype($rn); - die "Unknown recordtype '$rn' in $infile POD directive\n" - unless $rtyp; - rtypeToPod($rtyp, $dbd); - } - # Handle a 'menu' Pod directive - elsif (m/^ =menu \s+ (\w+) /x) { - my $mn = $1; - my $menu = $dbd->menu($mn); - die "Unknown menu '$mn' in $infile POD directive\n" - unless $menu; - menuToPod($menu); - } - elsif (m/^ =title \s+ (.*)/x) { - $title = $1; - "=head1 $title"; - } - else { - $_; - } - } $dbd->pod, - '=for html
', ''; - -my $podHtml; - -if ($::XHTML) { - $podHtml = Pod::Simple::XHTML->new(); - $podHtml->html_doctype(<< '__END_DOCTYPE'); - - -__END_DOCTYPE - $podHtml->html_header_tags($podHtml->html_header_tags . - "\n"); -} else { # Fall back to HTML - $podHtml = Pod::Simple::HTML->new(); - $podHtml->html_css('style.css'); -} - -$podHtml->force_title(encode_entities($title)); -$podHtml->perldoc_url_prefix(''); -$podHtml->perldoc_url_postfix('.html'); -$podHtml->output_fh($out); -$podHtml->parse_string_document($pod); -close $out; - - -sub menuToPod { - my ($menu) = @_; - my $index = 0; - return '=begin html', '', '
', - '', - map({choiceTableRow($_, $index++)} $menu->choices), - '
IndexIdentifierChoice String
', '', '=end html'; -} - -sub choiceTableRow { - my ($ch, $index) = @_; - my ($id, $name) = @{$ch}; - return '', - "$index", - "$id", - "$name", - ''; -} - -sub rtypeToPod { - my ($rtyp, $dbd) = @_; - return map { - # Handle a 'fields' Pod directive - if (m/^ =fields \s+ (\w+ (?:\s* , \s* \w+ )* )/x) { - my @names = split /\s*,\s*/, $1; - # Look up the named fields - my @fields = map { - my $field = $rtyp->field($_); - die "Unknown field name '$_' in $infile POD\n" - unless $field; - $field; - } @names; - # Generate Pod for the table - '=begin html', '', '
', - '', - '', - '', - map({fieldTableRow($_, $dbd)} @fields), - '
FieldSummaryTypeDCTDefaultReadWriteCA PP
', '', '=end html'; - } - # Handle a 'menu' Pod directive - elsif (m/^ =menu \s+ (\w+) /x) { - my $mn = $1; - my $menu = $dbd->menu($mn); - die "Unknown menu '$mn' in $infile POD directive\n" - unless $menu; - menuToPod($menu); - } - else { - # Raw text line - $_; - } - } $rtyp->pod; -} - -sub fieldTableRow { - my ($fld, $dbd) = @_; - my $html = ''; - $html .= $fld->name; - $html .= ''; - $html .= $fld->attribute('prompt'); - $html .= ''; - my $type = $fld->public_type; - $html .= $type; - $html .= ' [' . $fld->attribute('size') . ']' - if $type eq 'STRING'; - if ($type eq 'MENU') { - my $mn = $fld->attribute('menu'); - my $menu = $dbd->menu($mn); - my $url = $menu ? "#Menu_$mn" : "${mn}.html"; - $html .= " (
$mn)"; - } - $html .= ''; - $html .= $fld->attribute('promptgroup') ? 'Yes' : 'No'; - $html .= ''; - $html .= $fld->attribute('initial') || ' '; - $html .= ''; - $html .= $fld->readable; - $html .= ''; - $html .= $fld->writable; - $html .= ''; - $html .= $fld->attribute('pp') eq 'TRUE' ? 'Yes' : 'No'; - $html .= "\n"; - return $html; -} - -# Native type presented to dbAccess users -sub DBD::Recfield::public_type { - my $fld = shift; - m/^ =type \s+ (.+) /x && return $1 for $fld->comments; - my $type = $fld->dbf_type; - $type =~ s/^DBF_//; - return $type; -} - -# Check if this field is readable -sub DBD::Recfield::readable { - my $fld = shift; - m/^ =read \s+ (?i) (Yes|No) /x && return $1 for $fld->comments; - return 'Probably' - if $fld->attribute('special') eq "SPC_DBADDR"; - return $fld->dbf_type eq 'DBF_NOACCESS' ? 'No' : 'Yes'; -} - -# Check if this field is writable -sub DBD::Recfield::writable { - my $fld = shift; - m/^ =write \s+ (?i) (Yes|No) /x && return $1 for $fld->comments; - my $special = $fld->attribute('special'); - return 'No' - if $special eq "SPC_NOMOD"; - return 'Maybe' - if $special eq "SPC_DBADDR"; - return $fld->dbf_type eq "DBF_NOACCESS" ? 'No' : 'Yes'; -} - diff --git a/src/tools/dbdToMenuH.pl b/src/tools/dbdToMenuH.pl deleted file mode 100644 index eaa236902..000000000 --- a/src/tools/dbdToMenuH.pl +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/perl - -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use EPICS::Getopts; -use File::Basename; -use DBD; -use DBD::Parser; -use EPICS::macLib; -use EPICS::Readfile; - -my $tool = 'dbdToMenuH.pl'; - -use vars qw($opt_D @opt_I $opt_o $opt_s); -getopts('DI@o:') or - die "Usage: $tool: [-D] [-I dir] [-o menu.h] menu.dbd [menu.h]\n"; - -my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32? -my $dbd = DBD->new(); - -my $infile = shift @ARGV; -$infile =~ m/\.dbd$/ or - die "$tool: Input file '$infile' must have '.dbd' extension\n"; -my $inbase = basename($infile); - -my $outfile; -if ($opt_o) { - $outfile = $opt_o; -} elsif (@ARGV) { - $outfile = shift @ARGV; -} else { - ($outfile = $infile) =~ s/\.dbd$/.h/; - $outfile =~ s/^.*\///; -} -my $outbase = basename($outfile); - -# Derive a name for the include guard -my $guard_name = "INC_$outbase"; -$guard_name =~ tr/a-zA-Z0-9_/_/cs; -$guard_name =~ s/(_[hH])?$/_H/; - -ParseDBD($dbd, Readfile($infile, 0, \@opt_I)); - -if ($opt_D) { - my %filecount; - my @uniqfiles = grep { not $filecount{$_}++ } @inputfiles; - print "$outfile: ", join(" \\\n ", @uniqfiles), "\n\n"; - print map { "$_:\n" } @uniqfiles; -} else { - open OUTFILE, ">$outfile" or die "$tool: Can't open $outfile: $!\n"; - print OUTFILE "/* $outbase generated from $inbase */\n\n", - "#ifndef $guard_name\n", - "#define $guard_name\n\n"; - my $menus = $dbd->menus; - while (my ($name, $menu) = each %{$menus}) { - print OUTFILE $menu->toDeclaration; - } -# FIXME: Where to put metadata for widely used menus? -# In the generated menu.h file is wrong: can't create a list of menu.h files. -# Can only rely on registerRecordDeviceDriver output, so we must require that -# all such menus be named "menu...", and any other menus must be defined in -# the record.dbd file that needs them. -# print OUTFILE "\n#ifdef GEN_MENU_METADATA\n\n"; -# while (($name, $menu) = each %{$menus}) { -# print OUTFILE $menu->toDefinition; -# } -# print OUTFILE "\n#endif /* GEN_MENU_METADATA */\n"; - print OUTFILE "\n#endif /* $guard_name */\n"; - close OUTFILE; -} diff --git a/src/tools/dbdToRecordtypeH.pl b/src/tools/dbdToRecordtypeH.pl deleted file mode 100644 index ccf6b21b2..000000000 --- a/src/tools/dbdToRecordtypeH.pl +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/perl - -#************************************************************************* -# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use EPICS::Getopts; -use File::Basename; -use DBD; -use DBD::Parser; -use EPICS::macLib; -use EPICS::Readfile; - -my $tool = 'dbdToRecordtypeH.pl'; - -use vars qw($opt_D @opt_I $opt_o $opt_s); -getopts('DI@o:s') or - die "Usage: $tool [-D] [-I dir] [-o xRecord.h] xRecord.dbd [xRecord.h]\n"; - -my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32? -my $dbd = DBD->new(); - -my $infile = shift @ARGV; -$infile =~ m/\.dbd$/ or - die "$tool: Input file '$infile' must have '.dbd' extension\n"; -my $inbase = basename($infile); - -my $outfile; -if ($opt_o) { - $outfile = $opt_o; -} elsif (@ARGV) { - $outfile = shift @ARGV; -} else { - ($outfile = $infile) =~ s/\.dbd$/.h/; - $outfile =~ s/^.*\///; - $outfile =~ s/dbCommonRecord/dbCommon/; -} -my $outbase = basename($outfile); - -# Derive a name for the include guard -my $guard_name = "INC_$outbase"; -$guard_name =~ tr/a-zA-Z0-9_/_/cs; -$guard_name =~ s/(_[hH])?$/_H/; - -ParseDBD($dbd, Readfile($infile, 0, \@opt_I)); - -my $rtypes = $dbd->recordtypes; -die "$tool: Input file must contain a single recordtype definition.\n" - unless (1 == keys %{$rtypes}); - -if ($opt_D) { # Output dependencies only, to stdout - my %filecount; - my @uniqfiles = grep { not $filecount{$_}++ } @inputfiles; - print "$outfile: ", join(" \\\n ", @uniqfiles), "\n\n"; - print map { "$_:\n" } @uniqfiles; -} else { - open OUTFILE, ">$outfile" or die "$tool: Can't open $outfile: $!\n"; - print OUTFILE "/* $outbase generated from $inbase */\n\n", - "#ifndef $guard_name\n", - "#define $guard_name\n\n"; - - our ($rn, $rtyp) = each %{$rtypes}; - - print OUTFILE $rtyp->toCdefs; - - my @menu_fields = grep { - $_->dbf_type eq 'DBF_MENU' - } $rtyp->fields; - my %menu_used; - grep { - !$menu_used{$_}++ - } map { - $_->attribute('menu') - } @menu_fields; - our $menus_defined = $dbd->menus; - while (my ($name, $menu) = each %{$menus_defined}) { - print OUTFILE $menu->toDeclaration; - if ($menu_used{$name}) { - delete $menu_used{$name} - } - } - our @menus_external = keys %menu_used; - - print OUTFILE $rtyp->toDeclaration; - - unless ($rn eq 'dbCommon') { - my $n = 0; - print OUTFILE "typedef enum {\n", - join(",\n", - map { "\t${rn}Record$_ = " . $n++ } $rtyp->field_names), - "\n} ${rn}FieldIndex;\n\n"; - print OUTFILE "#ifdef GEN_SIZE_OFFSET\n\n"; - if ($opt_s) { - newtables(); - } else { - oldtables(); - } - print OUTFILE "#endif /* GEN_SIZE_OFFSET */\n"; - } - print OUTFILE "\n", - "#endif /* $guard_name */\n"; - close OUTFILE; -} - -sub oldtables { - # Output compatible with R3.14.x - print OUTFILE - "#include \n" . - "#include \n" . - "#ifdef __cplusplus\n" . - "extern \"C\" {\n" . - "#endif\n" . - "static int ${rn}RecordSizeOffset(dbRecordType *prt)\n" . - "{\n" . - " ${rn}Record *prec = 0;\n\n" . - " assert(prt->no_fields == " . scalar($rtyp->fields) . ");\n" . - join("\n", map { - " prt->papFldDes[${rn}Record" . $_->name . "]->size = " . - "sizeof(prec->" . $_->C_name . ");" - } $rtyp->fields) . "\n" . - join("\n", map { - " prt->papFldDes[${rn}Record" . $_->name . "]->offset = (unsigned short)(" . - "(char *)&prec->" . $_->C_name . " - (char *)prec);" - } $rtyp->fields) . "\n" . - " prt->rec_size = sizeof(*prec);\n" . - " return 0;\n" . - "}\n" . - "epicsExportRegistrar(${rn}RecordSizeOffset);\n\n" . - "#ifdef __cplusplus\n" . - "}\n" . - "#endif\n"; -} - -sub newtables { - # Output for an eventual DBD-less IOC - print OUTFILE (map { - "extern const dbMenu ${_}MenuMetaData;\n" - } @menus_external), "\n"; - while (my ($name, $menu) = each %{$menus_defined}) { - print OUTFILE $menu->toDefinition; - } - print OUTFILE (map { - "static const char ${rn}FieldName$_\[] = \"$_\";\n" } - $rtyp->field_names), "\n"; - my $n = 0; - print OUTFILE "static const dbRecordData ${rn}RecordMetaData;\n\n", - "static dbFldDes ${rn}FieldMetaData[] = {\n", - join(",\n", map { - my $fn = $_->name; - my $cn = $_->C_name; - " { ${rn}FieldName${fn}," . - $_->dbf_type . ',"' . - $_->attribute('initial') . '",' . - ($_->attribute('special') || '0') . ',' . - ($_->attribute('pp') || 'FALSE') . ',' . - ($_->attribute('interest') || '0') . ',' . - ($_->attribute('asl') || 'ASL0') . ',' . - $n++ . ",\n\t\&${rn}RecordMetaData," . - "GEOMETRY_DATA(${rn}Record,$cn) }"; - } $rtyp->fields), - "\n};\n\n"; - print OUTFILE "static const ${rn}FieldIndex ${rn}RecordLinkFieldIndices[] = {\n", - join(",\n", map { - " ${rn}Record" . $_->name; - } grep { - $_->dbf_type =~ m/^DBF_(IN|OUT|FWD)LINK/; - } $rtyp->fields), - "\n};\n\n"; - my @sorted_names = sort $rtyp->field_names; - print OUTFILE "static const char * const ${rn}RecordSortedFieldNames[] = {\n", - join(",\n", map { - " ${rn}FieldName$_" - } @sorted_names), - "\n};\n\n"; - print OUTFILE "static const ${rn}FieldIndex ${rn}RecordSortedFieldIndices[] = {\n", - join(",\n", map { - " ${rn}Record$_" - } @sorted_names), - "\n};\n\n"; - print OUTFILE "extern rset ${rn}RSET;\n\n", - "static const dbRecordData ${rn}RecordMetaData = {\n", - " \"$rn\",\n", - " sizeof(${rn}Record),\n", - " NELEMENTS(${rn}FieldMetaData),\n", - " ${rn}FieldMetaData,\n", - " ${rn}RecordVAL,\n", - " \&${rn}FieldMetaData[${rn}RecordVAL],\n", - " NELEMENTS(${rn}RecordLinkFieldIndices),\n", - " ${rn}RecordLinkFieldIndices,\n", - " ${rn}RecordSortedFieldNames,\n", - " ${rn}RecordSortedFieldIndices,\n", - " \&${rn}RSET\n", - "};\n\n", - "#ifdef __cplusplus\n", - "extern \"C\" {\n", - "#endif\n\n"; - print OUTFILE "dbRecordType * epicsShareAPI ${rn}RecordRegistrar(dbBase *pbase, int nDevs)\n", - "{\n", - " dbRecordType *prt = dbCreateRecordtype(&${rn}RecordMetaData, nDevs);\n"; - print OUTFILE " ${rn}FieldMetaData[${rn}RecordDTYP].typDat.pdevMenu = \&prt->devMenu;\n"; - while (my ($name, $menu) = each %{$menus_defined}) { - print OUTFILE " dbRegisterMenu(pbase, \&${name}MenuMetaData);\n"; - } - print OUTFILE map { - " ${rn}FieldMetaData[${rn}Record" . - $_->name . - "].typDat.pmenu = \n". - " \&" . - $_->attribute('menu') . - "MenuMetaData;\n"; - } @menu_fields; - print OUTFILE map { - " ${rn}FieldMetaData[${rn}Record" . - $_->name . - "].typDat.base = CT_HEX;\n"; - } grep { - $_->attribute('base') eq 'HEX'; - } $rtyp->fields; - print OUTFILE " dbRegisterRecordtype(pbase, prt);\n"; - print OUTFILE " return prt;\n}\n\n", - "#ifdef __cplusplus\n", - "} /* extern \"C\" */\n", - "#endif\n\n"; -} diff --git a/src/tools/dos2unix.pl b/src/tools/dos2unix.pl deleted file mode 100644 index 35163ac1f..000000000 --- a/src/tools/dos2unix.pl +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# Converts text file in DOS CR/LF format to unix ISO format - -@files=@ARGV; - -$| = 1; -foreach( @files ) { - open(INPUT, "<$_"); - $backup = "$_.bak"; - rename( $_, $backup) || die "Unable to rename $_\n$!\n"; - # Make the output be binary so it won't convert /n back to /r/n - binmode OUTPUT, ":raw"; - open(OUTPUT, ">$_"); - binmode OUTPUT, ":raw"; - while() { - # Remove CR-LF sequences - s/\r\n/\n/; - print OUTPUT; - } - close INPUT; - close OUTPUT; - unlink ($backup) or die "Cannot remove $backup"; -} diff --git a/src/tools/epics-base-arch.pc@ b/src/tools/epics-base-arch.pc@ deleted file mode 100644 index 8e30cd30e..000000000 --- a/src/tools/epics-base-arch.pc@ +++ /dev/null @@ -1,41 +0,0 @@ -# standard variables -prefix=@FINAL_LOCATION@ -exec_prefix=${prefix} -bindir=${prefix}/bin/@ARCH@ -libdir=${prefix}/lib/@ARCH@ - -# non-standard variables - -# EPICS Base install location -FINAL_LOCATION=${prefix} -ARCH=@ARCH@ -OS_CLASS=@OS_CLASS@ -CMPLR_CLASS=@CMPLR_CLASS@ - -EPICS_BASE_IOC_LIBS=@EPICS_BASE_IOC_LIBS@ - -# Directories - -includedir_osi=${prefix}/include -includedir_osd=${prefix}/include/os/@OS_CLASS@ -includedir_comp=${prefix}/include/compiler/@CMPLR_CLASS@ - -includedirs=${includedir_osi} ${includedir_osd} ${includedir_comp} - -dbddir=${prefix}/dbd -dbdir=${prefix}/db - -# Tool chain - -CC=@CC@ -CXX=@CCC@ -CPP=@CPP@ -AR=@AR@ -LD=@LD@ - -Name: epics-base-@ARCH@ -Version: @EPICS_VERSION@.@EPICS_REVISION@.@EPICS_MODIFICATION@.@EPICS_PATCH_LEVEL@ -Description: EPICS Base for @ARCH@ -Cflags: -I${includedir_osi} -I${includedir_osd} -I${includedir_comp} @C_CFLAGS@ -Libs: -L${libdir} @LDFLAGS@ -Libs.private: @LDLIBS@ diff --git a/src/tools/epics-base.pc@ b/src/tools/epics-base.pc@ deleted file mode 100644 index c1540666a..000000000 --- a/src/tools/epics-base.pc@ +++ /dev/null @@ -1,29 +0,0 @@ -# standard variables -prefix=@FINAL_LOCATION@ -exec_prefix=${prefix} -bindir=${prefix}/bin/@ARCH@ -libdir=${prefix}/lib/@ARCH@ - -# non-standard variables - -# EPICS Base install location -FINAL_LOCATION=${prefix} -ARCH=@ARCH@ -OS_CLASS=@OS_CLASS@ -CMPLR_CLASS=@CMPLR_CLASS@ - -# Directories - -includedir_osi=${prefix}/include -includedir_osd=${prefix}/include/os/@OS_CLASS@ -includedir_comp=${prefix}/include/compiler/@CMPLR_CLASS@ - -includedirs=${includedir_osi} ${includedir_osd} ${includedir_comp} - -dbddir=${prefix}/dbd -dbdir=${prefix}/db - -Name: epics-base -Version: @EPICS_VERSION@.@EPICS_REVISION@.@EPICS_MODIFICATION@.@EPICS_PATCH_LEVEL@ -Description: EPICS Base for the host arch -Requires: epics-base-@ARCH@ = @EPICS_VERSION@.@EPICS_REVISION@.@EPICS_MODIFICATION@.@EPICS_PATCH_LEVEL@ diff --git a/src/tools/expandVars.pl b/src/tools/expandVars.pl deleted file mode 100644 index 01e65fb3a..000000000 --- a/src/tools/expandVars.pl +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env perl -# -# Tool to expand @VAR@ variables while copying a file. -# The file will *not* be copied if it already exists. -# -# Author: Andrew Johnson -# Date: 10 February 2005 -# - -use strict; - -use FindBin qw($Bin); -use lib ("$Bin/../../lib/perl", $Bin); - -use EPICS::Getopts; -use EPICS::Path; -use EPICS::Release; -use EPICS::Copy; - -# Process command line options -our ($opt_a, $opt_d, @opt_D, $opt_h, $opt_t); -getopts('a:dD@ht:') - or HELP_MESSAGE(); - -# Handle the -h command -HELP_MESSAGE() if $opt_h; - -die "Path to TOP not set, use -t option\n" - unless $opt_t; - -# Check filename arguments -my $infile = shift - or die "No input filename argument\n"; -my $outfile = shift - or die "No output filename argument\n"; - -# Where are we? -my $top = AbsPath($opt_t); -print "TOP = $top\n" if $opt_d; - -# Read RELEASE file into vars -my %vars = (TOP => $top); -my @apps = ('TOP'); -readReleaseFiles("$top/configure/RELEASE", \%vars, \@apps, $opt_a); -expandRelease(\%vars); - -$vars{'ARCH'} = $opt_a if $opt_a; - -while ($_ = shift @opt_D) { - m/^ (\w+) \s* = \s* (.*) $/x; - $vars{$1} = $2; - print "$1 = $2\n" if $opt_d; -} - -# Do it! -copyFile($infile, $outfile, \%vars); - -##### File contains subroutines only below here - -sub HELP_MESSAGE { - print STDERR < [B<-h>] /path/to/something - -=head1 DESCRIPTION - -The EPICS build system needs the ability to get the absolute path of a file or -directory that does not exist at the time. The AbsPath() function in the -EPICS::Path module provides the necessary functionality, which this script makes -available to the build system. The string which is returned on the standard -output stream has had any shell special characters escaped with a back-slash -(except on Windows). - -=head1 OPTIONS - -B understands the following options: - -=over 4 - -=item B<-h> - -Help, display this document as text. - -=back - -=cut - -our ($opt_h); - -sub HELP_MESSAGE { - pod2usage(-exitval => 2, -verbose => $opt_h); -} - -HELP_MESSAGE() if !getopts('h') || $opt_h || @ARGV != 1; - -my $path = AbsPath(shift); - -# Escape shell special characters unless on Windows, which doesn't allow them. -$path =~ s/([!"\$&'\(\)*,:;<=>?\[\\\]^`{|}])/\\$1/g unless $^O eq 'MSWin32'; - -print "$path\n"; - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2009 UChicago Argonne LLC, as Operator of Argonne National -Laboratory. - -This software is distributed under the terms of the EPICS Open License. - -=cut diff --git a/src/tools/genVersionHeader.pl b/src/tools/genVersionHeader.pl deleted file mode 100644 index 5851ea831..000000000 --- a/src/tools/genVersionHeader.pl +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2014 Brookhaven National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# Generate a C header file which -# defines a macro with a string -# describing the VCS revision -# - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use EPICS::Getopts; -use POSIX qw(strftime); - -use strict; - -# RFC 8601 date+time w/ zone (eg "2014-08-29T09:42:47-0700") -my $tfmt = '%Y-%m-%dT%H:%M:%S'; -$tfmt .= '%z' unless $^O eq 'MSWin32'; # %z returns zone name on Windows -my $now = strftime($tfmt, localtime); - -our ($opt_h, $opt_v, $opt_q); -our $opt_t = '.'; -our $opt_N = 'VCSVERSION'; -our $opt_V = $now; - -my $vcs; - -getopts('hvqt:N:V:') && @ARGV == 1 - or HELP_MESSAGE(); - -my ($outfile) = @ARGV; - -if (!$vcs && -d "$opt_t/_darcs") { # Darcs - print "== Found /_darcs directory\n" if $opt_v; - # v1-4-dirty - # is tag 'v1' plus 4 patches - # with uncommited modifications - my $result = `cd "$opt_t" && echo "\$(darcs show tags | head -1)-\$((\$(darcs changes --count --from-tag .)-1))"`; - chomp $result; - print "== darcs show tags, changes:\n$result\n==\n" if $opt_v; - if (!$? && $result ne '') { - $opt_V = $result; - $vcs = 'Darcs'; - # see if working copy has modifications, additions, removals, or missing files - my $hasmod = `darcs whatsnew --repodir="$opt_t" -l`; - $opt_V .= '-dirty' unless $?; - } -} -if (!$vcs && -d "$opt_t/.hg") { # Mercurial - print "== Found /.hg directory\n" if $opt_v; - # v1-4-abcdef-dirty - # is 4 commits after tag 'v1' with short hash abcdef - # with uncommited modifications - my $result = `hg tip --template '{latesttag}-{latesttagdistance}-{node|short}'`; - print "== hg tip:\n$result\n==\n" if $opt_v; - if (!$? && $result ne '') { - $opt_V = $result; - $vcs = 'Mercurial'; - # see if working copy has modifications, additions, removals, or missing files - my $hasmod = `hg status -m -a -r -d`; - chomp $hasmod; - $opt_V .= '-dirty' if $hasmod ne ''; - } -} -if (!$vcs && -d "$opt_t/.git") { # Git - print "== Found /.git directory\n" if $opt_v; - # v1-4-abcdef-dirty - # is 4 commits after tag 'v1' with short hash abcdef - # with uncommited modifications - my $result = `git describe --always --tags --dirty --abbrev=20`; - chomp $result; - print "== git describe:\n$result\n==\n" if $opt_v; - if (!$? && $result ne '') { - $opt_V = $result; - $vcs = 'Git'; - } -} -if (!$vcs && -d "$opt_t/.svn") { # Subversion - print "== Found /.svn directory\n" if $opt_v; - # 12345-dirty - my $result = `cd "$opt_t" && svn info --non-interactive`; - chomp $result; - print "== svn info:\n$result\n==\n" if $opt_v; - if (!$? && $result =~ /^Revision:\s*(\d+)/m) { - $opt_V = $1; - $vcs = 'Subversion'; - # see if working copy has modifications, additions, removals, or missing files - my $hasmod = `cd "$opt_t" && svn status --non-interactive`; - chomp $hasmod; - $opt_V .= '-dirty' if $hasmod ne ''; - } -} -if (!$vcs && -d "$opt_t/.bzr") { # Bazaar - print "== Found /.bzr directory\n" if $opt_v; - # 12444-anj@aps.anl.gov-20131003210403-icfd8mc37g8vctpf-dirty - my $result = `bzr version-info -q --custom --template="{revno}-{revision_id}-{clean}"`; - print "== bzr version-info:\n$result\n==\n" if $opt_v; - if (!$? && $result ne '') { - $result =~ s/-([01])$/$1 ? '' : '-dirty'/e; - $opt_V = $result; - $vcs = 'Bazaar'; - } -} -if (!$vcs) { - print "== No VCS directories\n" if $opt_v; - if ($opt_V eq '') { - $vcs = 'build date/time'; - $opt_V = $now; - } - else { - $vcs = 'Makefile'; - } -} - -my $output = << "__END"; -/* Generated file, do not edit! */ - -/* Version determined from $vcs */ - -#ifndef $opt_N - #define $opt_N \"$opt_V\" -#endif -__END - -print "== Want:\n$output==\n" if $opt_v; - -my $DST; -if (open($DST, '+<', $outfile)) { - my $actual = join('', <$DST>); - print "== Current:\n$actual==\n" if $opt_v; - - if ($actual eq $output) { - print "Keeping VCS header $outfile\n $opt_N = \"$opt_V\"\n" - unless $opt_q; - exit 0; - } - print "Updating VCS header $outfile\n $opt_N = \"$opt_V\"\n" - unless $opt_q; -} else { - print "Creating VCS header $outfile\n $opt_N = \"$opt_V\"\n" - unless $opt_q; - open($DST, '>', $outfile) - or die "Can't create $outfile: $!\n"; -} - -seek $DST, 0, 0; -truncate $DST, 0; -print $DST $output; -close $DST; - -sub HELP_MESSAGE { - print STDERR < DOES work on Win32, but the above - # chmod 0777 fails to install a newer version on top. - chmod $mode, $target unless $^O eq 'MSWin32'; -} - -sub Usage { - my ($txt) = @_; - my $omode = sprintf '%#o', $mode; - - print << "END"; -Usage: $tool [OPTIONS]... SRCS... DEST - -d Create non-existing directories - -h Print usage - -m mode Octal permissions for installed files ($omode by default) - -q Install quietly - SRCS Source files to be installed - DEST Destination directory -END - - print "\n$txt\n" if $txt; - - exit $opt_h ? 0 : 2; -} diff --git a/src/tools/makeIncludeDbd.pl b/src/tools/makeIncludeDbd.pl deleted file mode 100644 index f4ab8be3d..000000000 --- a/src/tools/makeIncludeDbd.pl +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2014 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; -use File::Basename; - -sub Usage { - my $txt = shift; - - print "Usage: makeIncludeDbd.pl input file list ... outfile\n"; - print "Error: $txt\n" if $txt; - exit 2; -} - -Usage("No input files specified") - unless $#ARGV > 1; - -my $target = pop @ARGV; -my @inputs = map { basename($_); } @ARGV; - -open(my $OUT, '>', $target) - or die "$0: Can't create $target, $!\n"; - -print $OUT "# Generated file $target\n\n"; -print $OUT map { "include \"$_\"\n"; } @inputs; - -close $OUT; diff --git a/src/tools/makeMakefile.pl b/src/tools/makeMakefile.pl deleted file mode 100644 index ea48d1c9b..000000000 --- a/src/tools/makeMakefile.pl +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# makeMakefile.pl -# -# called from RULES_ARCHS -# -# -# Usage: perl makeMakefile.pl O.*-dir top Makefile-Type - -$dir = $ARGV[0]; -$top= $ARGV[1]; -$type = $ARGV[2]; -$makefile="$dir/Makefile"; -$b_t=""; - -if ($type ne "") -{ - $b_t = "B_T=$type"; -} - -if ($dir =~ m'O.(.+)') -{ - $t_a = $1; -} -else -{ - die "Cannot extract T_A from $dir"; -} - -mkdir ($dir, 0777) unless -d $dir; - -open OUT, "> $makefile" or die "Cannot create $makefile"; - -print OUT "#This Makefile created by makeMakefile.pl\n\n\n"; -print OUT "all :\n"; -print OUT " \$(MAKE) -f ../Makefile$type TOP=$top T_A=$t_a $b_t \$@\n\n"; -print OUT ".DEFAULT: force\n"; -print OUT " \$(MAKE) -f ../Makefile$type TOP=$top T_A=$t_a $b_t \$@\n\n"; -print OUT "force: ;\n"; - -close OUT; - -# EOF makeMakefile.pl - diff --git a/src/tools/makeTestfile.pl b/src/tools/makeTestfile.pl deleted file mode 100644 index 4ac5162db..000000000 --- a/src/tools/makeTestfile.pl +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# The makeTestfile.pl script generates a file $target.t which is needed -# because some versions of the Perl test harness can only run test scripts -# that are actually written in Perl. The script we generate runs the -# real test program which must be in the same directory as the .t file. -# If the script is given an argument -tap it sets HARNESS_ACTIVE in the -# environment to make the epicsUnitTest code generate strict TAP output. - -# Usage: makeTestfile.pl target.t executable -# target.t is the name of the Perl script to generate -# executable is the name of the file the script runs - -use strict; - -my ($target, $exe) = @ARGV; - -# Use system on Windows, exec doesn't work the same there and -# GNUmake thinks the test has finished as soon as Perl exits. -my $exec = $^O eq 'MSWin32' ? "system('./$exe') == 0" : "exec './$exe'"; - -open(my $OUT, '>', $target) or die "Can't create $target: $!\n"; - -print $OUT <$depFile" or die "\aERROR opening file $depFile for writing: $!\n"; - - my $old_handle = select(DEPENDS); - - print "# DO NOT EDIT: This file created by $tool\n\n"; - - foreach $file (@includes) { - print "$objFile : $file\n"; - } - print "\n\n"; - - select($old_handle) ; # in this case, STDOUT -} - -#------------------------------------------- -# scan file for #includes -sub scanFile { - my $file = shift; - my $incfile; - my $line; - print "Scanning file $file\n" if $debug; - open FILE, $file or return; - foreach $line ( ) { - $incfile = findNextIncName($line,$file=~/\.substitutions$/); - next if !$incfile; - next if $output{$incfile}; - push @includes,$incfile; - $output{$incfile} = 1; - } - close FILE; -} - -#------------------------------------------ -# scan files in includes list -sub scanIncludesList { - my $file; - foreach $file (@includes) { - scanFile($file); - } -} - -#----------------------------------------- -# find filename on #include and file lines -sub findNextIncName { - my $line = shift; - my $is_subst = shift; - my $incname = ""; - my $incfile = 0; - my $dir; - - local $/ = $endline; - if ($is_subst) { - return 0 if not $line =~ /^\s*file\s*([^\s{]*)/; - $incname = $1; - $incname = substr $incname, 1, length($incname)-2 if $incname =~ /^".+?"$/; - } else { - return 0 if not $line =~ /^#?\s*include\s*('.*?'|<.*?>|".*?")/; - $incname = substr $1, 1, length($1)-2; - } - print "DEBUG: $incname\n" if $debug; - - return $incname if -f $incname; - return 0 if ( $incname =~ /^\// || $incname =~ /^\\/ ); - - foreach $dir ( @incdirs ) { - chomp($dir); - $incfile = "$dir/$incname"; - print "DEBUG: checking for $incname in $dir\n" if $debug; - return $incfile if -f $incfile; - } - return 0; -} diff --git a/src/tools/munch.pl b/src/tools/munch.pl deleted file mode 100644 index f62b579ad..000000000 --- a/src/tools/munch.pl +++ /dev/null @@ -1,208 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; -use warnings; - -use Getopt::Std; -$Getopt::Std::STANDARD_HELP_VERSION = 1; - -use Pod::Usage; - -=head1 NAME - -munch.pl - Combine C++ static constructors and destructors for libraries - -=head1 SYNOPSIS - -B [B<-h>] [B<-o> file_ctdt.c] file.nm - -=head1 DESCRIPTION - -Creates a ctdt.c file of C++ static constructors and destructors, as required -for all vxWorks binaries containing C++ code. The VxWorks linking loader and -unloader only call one constructor function, so the code generated by this -script is needed to ensure that all the static constructors and destructors in -the library module will be executed at the appropriate time. - -The file input to this function is generated by running the B program on the -library concerned. The processing algorithm was reverse-engineered from the -B scripts provided with various versions of VxWorks up to 6.9. - -=head1 OPTIONS - -B understands the following options: - -=over 4 - -=item B<-h> - -Help, display this document as text. - -=item B<-o> file_ctdt.c - -Name of the output file to be created. - -=back - -If no output filename is set with a B<-o> option, the generated C code will be -sent to the standard output stream. - -=cut - -our ($opt_o, $opt_h); - -sub HELP_MESSAGE { - pod2usage(-exitval => 2, -verbose => $opt_h); -} - -HELP_MESSAGE() if !getopts('ho:') || $opt_h || @ARGV != 1; - -# Is exception handler frame info required? -my $need_eh_frame = 0; - -# Is module destructor needed? -my $need_mod_dtor = 0; - -# Constructor and destructor names: -# Array contains names from input file. -# Hash is used to skip duplicate names. -my (@ctors, %ctors); -my (@dtors, %dtors); - -while (<>) -{ - chomp; - $need_eh_frame++ if m/__? gxx_personality_v [0-9]/x; - $need_mod_dtor++ if m/__? cxa_atexit $/x; - next if m/__? GLOBAL_. (F | I._GLOBAL_.D) .+/x; - if (m/__? GLOBAL_ . D .+/x) { - my ($addr, $type, $name) = split ' ', $_, 3; - push @dtors, $name unless exists $dtors{$name}; - $dtors{$name} = 1; - } - if (m/__? GLOBAL_ . I .+/x) { - my ($addr, $type, $name) = split ' ', $_, 3; - push @ctors, $name unless exists $ctors{$name}; - $ctors{$name} = 1; - } -} - -push my @out, - '/* C++ static constructor and destructor lists */', - '/* This is generated by munch.pl, do not edit! */', - '', - '#include ', - '', - '/* Declarations */', - (map {cDecl($_)} @ctors, @dtors), - '', - 'char __dso_handle = 0;', - ''; - -moduleDestructor() if $need_mod_dtor; -exceptionHandlerFrame() if $need_eh_frame; - -push @out, - '/* List of Constructors */', - 'void (*_ctors[])(void) = {', - (join ",\n", (map {' ' . cName($_)} @ctors), ' NULL'), - '};', - '', - '/* List of Destructors */', - 'void (*_dtors[])(void) = {', - (join ",\n", (map {' ' . cName($_)} @dtors), ' NULL'), - '};', - ''; - -if ($opt_o) { - open(my $OUT, '>', $opt_o) - or die "Can't create $opt_o: $!\n"; - print $OUT join "\n", @out; - close $OUT - or die "Can't close $opt_o: $!\n"; -} else { - print join "\n", @out; -} - -# Outputs the C code for registering a module destructor -sub moduleDestructor { - my $mod_dtor = 'mod_dtor'; - push @dtors, $mod_dtor; - push @out, - '/* Module destructor */', - "static void $mod_dtor(void) {", - ' extern void __cxa_finalize(void *);', - '', - ' __cxa_finalize(&__dso_handle);', - '}', - ''; -} - -# Outputs the C code for registering exception handler frame info -sub exceptionHandlerFrame { - my $eh_ctor = 'eh_ctor'; - my $eh_dtor = 'eh_dtor'; - - # Add EH ctor/dtor to _start_ of arrays - unshift @ctors, $eh_ctor; - unshift @dtors, $eh_dtor; - - push @out, - '/* Exception handler frame */', - 'extern const unsigned __EH_FRAME_BEGIN__[];', - '', - "static void $eh_ctor(void) {", - ' extern void __register_frame_info (const void *, void *);', - ' static struct {', - ' void *a, *b, *c, *d;', - ' unsigned long e;', - ' void *f, *g;', - ' } object;', - '', - ' __register_frame_info(__EH_FRAME_BEGIN__, &object);', - '}', - '', - "static void $eh_dtor(void) {", - ' extern void *__deregister_frame_info (const void *);', - '', - ' __deregister_frame_info(__EH_FRAME_BEGIN__);', - '}', - ''; -} - -sub cName { - my ($name) = @_; - $name =~ s/^__/_/; - $name =~ s/\./\$/g; - return $name; -} - -sub cDecl { - my ($name) = @_; - my $decl = 'extern void ' . cName($name) . '(void)'; - # 68k and MIPS targets allow periods in symbol names, which - # can only be reached using an assembler string. - if (m/\./) { - $decl .= "\n __asm__ (\"" . $name . "\");"; - } else { - $decl .= ';'; - } - return $decl; -} - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2013 UChicago Argonne LLC, as Operator of Argonne National -Laboratory. - -This software is distributed under the terms of the EPICS Open License. - -=cut diff --git a/src/tools/podRemove.pl b/src/tools/podRemove.pl deleted file mode 100644 index 14fbf58f0..000000000 --- a/src/tools/podRemove.pl +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2015 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; -use warnings; - -use Getopt::Std; -$Getopt::Std::STANDARD_HELP_VERSION = 1; - -use Pod::Usage; - -=head1 NAME - -podRemove.pl - Remove POD directives from files - -=head1 SYNOPSIS - -B [B<-h>] [B<-o> file] file.pod - -=head1 DESCRIPTION - -Removes Perl's POD documentation from a text file - -=head1 OPTIONS - -B understands the following options: - -=over 4 - -=item B<-h> - -Help, display this document as text. - -=item B<-o> file - -Name of the output file to be created. - -=back - -If no output filename is set, the file created will be named after the input -file, removing any directory components in the path and removing any .pod file -extension. - -=cut - -our ($opt_o, $opt_h); - -sub HELP_MESSAGE { - pod2usage(-exitval => 2, -verbose => $opt_h); -} - -HELP_MESSAGE() if !getopts('ho:') || $opt_h || @ARGV != 1; - -my $infile = shift @ARGV; - -if (!$opt_o) { - ($opt_o = $infile) =~ s/\.pod$//; - $opt_o =~ s/^.*\///; -} - -open my $inp, '<', $infile or - die "podRemove.pl: Can't open $infile: $!\n"; -open my $out, '>', $opt_o or - die "podRemove.pl: Can't create $opt_o: $!\n"; - -my $inPod = 0; -while (<$inp>) { - if (m/\A=[a-zA-Z]/) { - $inPod = !m/\A=cut/; - } - else { - print $out $_ unless $inPod; - } -} - -close $out; -close $inp; - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2015 UChicago Argonne LLC, as Operator of Argonne National -Laboratory. - -This software is distributed under the terms of the EPICS Open License. - -=cut diff --git a/src/tools/podToHtml.pl b/src/tools/podToHtml.pl deleted file mode 100644 index 81716ae37..000000000 --- a/src/tools/podToHtml.pl +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; -use warnings; - -use Getopt::Std; -$Getopt::Std::STANDARD_HELP_VERSION = 1; - -use Pod::Simple::HTML; - -use Pod::Usage; - -=head1 NAME - -podToHtml.pl - Convert EPICS .pod files to .html - -=head1 SYNOPSIS - -B [B<-h>] [B<-s>] [B<-o> file.html] file.pod - -=head1 DESCRIPTION - -Converts files from Perl's POD format into HTML format. - -The generated HTML output file refers to a CSS style sheet F which -can be located in a parent directory of the final installation directory. The -relative path to that file (i.e. the number of parent directories to traverse) -is calculated based on the number of components in the path to the input file. - -=head1 OPTIONS - -B understands the following options: - -=over 4 - -=item B<-h> - -Help, display this document as text. - -=item B<-s> - -Indicates that the first component of the input file path is not part of the -final installation path, thus should be removed before calculating the relative -path to the style-sheet file. - -=item B<-o> file.html - -Name of the HTML output file to be created. - -=back - -If no output filename is set, the file created will be named after the input -file, removing any directory components in the path and replacing any file -extension with .html. - -=cut - -our ($opt_o, $opt_h); -our $opt_s = 0; - -sub HELP_MESSAGE { - pod2usage(-exitval => 2, -verbose => $opt_h); -} - -HELP_MESSAGE() if !getopts('ho:s') || $opt_h || @ARGV != 1; - -my $infile = shift @ARGV; - -my @inpath = split /\//, $infile; -my $file = pop @inpath; - -if (!$opt_o) { - ($opt_o = $file) =~ s/\. \w+ $/.html/x; -} - -# Calculate path to style.css file -shift @inpath if $opt_s; # Remove leading .. -my $root = '../' x scalar @inpath; - -open my $out, '>', $opt_o or - die "Can't create $opt_o: $!\n"; - -my $podHtml = Pod::Simple::HTML->new(); - -$podHtml->html_css($root . 'style.css'); -$podHtml->perldoc_url_prefix(''); -$podHtml->perldoc_url_postfix('.html'); -$podHtml->set_source($infile); -$podHtml->output_string(\my $html); -$podHtml->run; - -print $out $html; -close $out; - -=head1 COPYRIGHT AND LICENSE - -Copyright (C) 2013 UChicago Argonne LLC, as Operator of Argonne National -Laboratory. - -This software is distributed under the terms of the EPICS Open License. - -=cut diff --git a/src/tools/registerRecordDeviceDriver.pl b/src/tools/registerRecordDeviceDriver.pl deleted file mode 100644 index cd54f90f8..000000000 --- a/src/tools/registerRecordDeviceDriver.pl +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -use strict; - -use FindBin qw($Bin); -use lib "$Bin/../../lib/perl"; - -use DBD; -use DBD::Parser; -use EPICS::Readfile; -use EPICS::Path; -use EPICS::Getopts; -use Text::Wrap; - -our ($opt_D, @opt_I, $opt_o, $opt_l); - -getopts('Dlo:I@') or - die "Usage: registerRecordDeviceDriver [-D] [-l] [-o out.c] [-I dir] in.dbd subname [TOP]"; - -my @path = map { split /[:;]/ } @opt_I; # FIXME: Broken on Win32? - -my ($file, $subname, $bldTop) = @ARGV; - -my $dbd = DBD->new(); -ParseDBD($dbd, Readfile($file, "", \@path)); - -if ($opt_D) { # Output dependencies only - my %filecount; - my @uniqfiles = grep { not $filecount{$_}++ } @inputfiles; - print "$opt_o: ", join(" \\\n ", @uniqfiles), "\n\n"; - print map { "$_:\n" } @uniqfiles; - exit 0; -} - -$Text::Wrap::columns = 75; - -# Eliminate chars not allowed in C symbol names -my $c_bad_ident_chars = '[^0-9A-Za-z_]'; -$subname =~ s/$c_bad_ident_chars/_/g; - -# Process bldTop like convertRelease.pl does -$bldTop = LocalPath(UnixPath($bldTop)); -$bldTop =~ s/([\\"])/\\\1/g; # escape back-slashes and double-quotes - -# Create output file -my $out; -if ($opt_o) { - open $out, '>', $opt_o or die "Can't create $opt_o: $!\n"; -} else { - $out = *STDOUT; -} - -print $out (<< "END"); -/* THIS IS A GENERATED FILE. DO NOT EDIT! */ -/* Generated from $file */ - -#include -#ifndef USE_TYPED_RSET -# define USE_TYPED_RSET -#endif -#include "compilerDependencies.h" -#include "epicsStdlib.h" -#include "iocsh.h" -#include "iocshRegisterCommon.h" -#include "registryCommon.h" -#include "recSup.h" - -END - -print $out (<< "END") if $opt_l; -#define epicsExportSharedSymbols -#include "shareLib.h" - -END - -print $out (<< "END"); -extern "C" { - -END - -my %rectypes = %{$dbd->recordtypes}; -my @rtypnames; -my @dsets; -if (%rectypes) { - my @allrtypnames = sort keys %rectypes; - # Record types with no fields defined are declarations, - # for building shared libraries containing device support. - @rtypnames = grep { scalar $rectypes{$_}->fields } @allrtypnames; - - if (@rtypnames) { - # Declare the record support entry tables - print $out wrap('epicsShareExtern typed_rset ', ' ', - join(', ', map {"*pvar_rset_${_}RSET"} @rtypnames)), ";\n\n"; - - # Declare the RecordSizeOffset functions - print $out "typedef int (*rso_func)(dbRecordType *pdbRecordType);\n"; - print $out wrap('epicsShareExtern rso_func ', ' ', - join(', ', map {"pvar_func_${_}RecordSizeOffset"} @rtypnames)), ";\n\n"; - - # List of record type names - print $out "static const char * const recordTypeNames[] = {\n"; - print $out wrap(' ', ' ', join(', ', map {"\"$_\""} @rtypnames)); - print $out "\n};\n\n"; - - # List of pointers to each RSET and RecordSizeOffset function - print $out "static const recordTypeLocation rtl[] = {\n"; - print $out join(",\n", map { - " {(struct typed_rset *)pvar_rset_${_}RSET, pvar_func_${_}RecordSizeOffset}" - } @rtypnames); - print $out "\n};\n\n"; - } - - for my $rtype (@allrtypnames) { - my @devices = $rectypes{$rtype}->devices; - for my $dtype (@devices) { - my $dset = $dtype->name; - push @dsets, $dset; - } - } - - if (@dsets) { - # Declare the device support entry tables - print $out wrap('epicsShareExtern dset ', ' ', - join(', ', map {"*pvar_dset_$_"} @dsets)), ";\n\n"; - - # List of dset names - print $out "static const char * const deviceSupportNames[] = {\n"; - print $out wrap(' ', ' ', join(', ', map {"\"$_\""} @dsets)); - print $out "\n};\n\n"; - - # List of pointers to each dset - print $out "static const dset * const devsl[] = {\n"; - print $out wrap(' ', ' ', join(", ", map {"pvar_dset_$_"} @dsets)); - print $out "\n};\n\n"; - } -} - -my %drivers = %{$dbd->drivers}; -if (%drivers) { - my @drivers = sort keys %drivers; - - # Declare the driver entry tables - print $out wrap('epicsShareExtern drvet ', ' ', - join(', ', map {"*pvar_drvet_$_"} @drivers)), ";\n\n"; - - # List of drvet names - print $out "static const char *driverSupportNames[] = {\n"; - print $out wrap(' ', ' ', join(', ', map {"\"$_\""} @drivers)); - print $out "};\n\n"; - - # List of pointers to each drvet - print $out "static struct drvet *drvsl[] = {\n"; - print $out join(",\n", map {" pvar_drvet_$_"} @drivers); - print $out "};\n\n"; -} - -my %links = %{$dbd->links}; -if (%links) { - my @links = sort keys %links; - - # Declare the link interfaces - print $out wrap('epicsShareExtern jlif ', ' ', - join(', ', map {"*pvar_jlif_$_"} @links)), ";\n\n"; - - # List of pointers to each link interface - print $out "static struct jlif *jlifsl[] = {\n"; - print $out join(",\n", map {" pvar_jlif_$_"} @links); - print $out "};\n\n"; -} - -my @registrars = sort keys %{$dbd->registrars}; -my @functions = sort keys %{$dbd->functions}; -push @registrars, map {"register_func_$_"} @functions; -if (@registrars) { - # Declare the registrar functions - print $out "typedef void (*reg_func)(void);\n"; - print $out wrap('epicsShareExtern reg_func ', ' ', - join(', ', map {"pvar_func_$_"} @registrars)), ";\n\n"; -} - -my %variables = %{$dbd->variables}; -if (%variables) { - my @varnames = sort keys %variables; - - # Declare the variables - for my $var (@varnames) { - my $vtype = $variables{$var}->var_type; - print $out "epicsShareExtern $vtype * const pvar_${vtype}_$var;\n"; - } - - # Generate the structure for registering variables with iocsh - print $out "\nstatic struct iocshVarDef vardefs[] = {\n"; - for my $var (@varnames) { - my $vtype = $variables{$var}->var_type; - my $itype = $variables{$var}->iocshArg_type; - print $out " {\"$var\", $itype, pvar_${vtype}_$var},\n"; - } - print $out " {NULL, iocshArgInt, NULL}\n};\n\n"; -} - -# Now for actual registration routine - -print $out (<< "END"); -int $subname(DBBASE *pbase) -{ - static int executed = 0; -END - -print $out (<< "END") if $bldTop ne ''; - const char *bldTop = "$bldTop"; - const char *envTop = getenv("TOP"); - - if (envTop && strcmp(envTop, bldTop)) { - printf("Warning: IOC is booting with TOP = \\"%s\\"\\n" - " but was built with TOP = \\"%s\\"\\n", - envTop, bldTop); - } - -END - -print $out (<< 'END'); - if (!pbase) { - printf("pdbbase is NULL; you must load a DBD file first.\n"); - return -1; - } - - if (executed) { - printf("Warning: Registration already done.\n"); - } - executed = 1; - -END - -print $out (<< 'END') if %rectypes && @rtypnames; - registerRecordTypes(pbase, NELEMENTS(rtl), recordTypeNames, rtl); -END - -print $out (<< 'END') if @dsets; - registerDevices(pbase, NELEMENTS(devsl), deviceSupportNames, devsl); -END - -print $out (<< 'END') if %drivers; - registerDrivers(pbase, NELEMENTS(drvsl), driverSupportNames, drvsl); -END - -print $out (<< 'END') if %links; - registerJLinks(pbase, NELEMENTS(jlifsl), jlifsl); -END - -print $out (<< "END") for @registrars; - pvar_func_$_(); -END - -print $out (<< 'END') if %variables; - iocshRegisterVariable(vardefs); -END - -print $out (<< "END"); - return 0; -} - -/* $subname */ -static const iocshArg rrddArg0 = {"pdbbase", iocshArgPdbbase}; -static const iocshArg *rrddArgs[] = {&rrddArg0}; -static const iocshFuncDef rrddFuncDef = - {"$subname", 1, rrddArgs}; -static void rrddCallFunc(const iocshArgBuf *) -{ - $subname(*iocshPpdbbase); -} - -} // extern "C" - -/* - * Register commands on application startup - */ -static int Registration() { - iocshRegisterCommon(); - iocshRegister(&rrddFuncDef, rrddCallFunc); - return 0; -} - -static int done EPICS_UNUSED = Registration(); -END - -if ($opt_o) { - close $out or die "Closing $opt_o failed: $!\n"; -} -exit 0; diff --git a/src/tools/replaceVAR.pl b/src/tools/replaceVAR.pl deleted file mode 100644 index 82c76bb3d..000000000 --- a/src/tools/replaceVAR.pl +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env perl -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# Called from within the object directory -# Replaces VAR(xxx) with $(xxx) -# and VAR_xxx_ with $(xxx) - -while () { - s/VAR\(/\$\(/g; - s/VAR_([^_]*)_/\$\($1\)/g; - print; -} diff --git a/src/tools/style.css b/src/tools/style.css deleted file mode 100644 index 09647403b..000000000 --- a/src/tools/style.css +++ /dev/null @@ -1,442 +0,0 @@ -BODY, .logo { background: white; } - -BODY { - color: black; - font-family: arial,sans-serif; - margin: 0; - padding: 1ex; -} - -TABLE { - border-collapse: collapse; - border-spacing: 0; - border-width: 0; - color: inherit; -} - -IMG { border: 0; } -FORM { margin: 0; } -input { margin: 2px; } - -.logo { - float: left; - width: 264px; - height: 77px; -} - -.front .logo { - float: none; - display:block; -} - -.front .searchbox { - margin: 2ex auto; - text-align: center; -} - -.front .menubar { - text-align: center; -} - -.menubar { - background: #006699; - margin: 1ex 0; - padding: 1px; -} - -.menubar A { - padding: 0.8ex; - font: bold 10pt Arial,Helvetica,sans-serif; -} - -.menubar A:link, .menubar A:visited { - color: white; - text-decoration: none; -} - -.menubar A:hover { - color: #ff6600; - text-decoration: underline; -} - -A:link, A:visited { - background: transparent; - color: #006699; -} - -A[href="#POD_ERRORS"] { - background: transparent; - color: #FF0000; -} - -TD { - margin: 0; - padding: 0; -} - -DIV { - border-width: 0; -} - -DT { - margin-top: 1em; -} - -.credits TD { - padding: 0.5ex 2ex; -} - -.huge { - font-size: 32pt; -} - -.s { - background: #dddddd; - color: inherit; -} - -.s TD, .r TD { - padding: 0.2ex 1ex; - vertical-align: baseline; -} - -TH { - background: #bbbbbb; - color: inherit; - padding: 0.4ex 1ex; - text-align: left; -} - -TH A:link, TH A:visited { - background: transparent; - color: black; -} - -.box { - border: 1px solid #006699; - margin: 1ex 0; - padding: 0; -} - -.distfiles TD { - padding: 0 2ex 0 0; - vertical-align: baseline; -} - -.manifest TD { - padding: 0 1ex; - vertical-align: top; -} - -.l1 { - font-weight: bold; -} - -.l2 { - font-weight: normal; -} - -.t1, .t2, .t3, .t4, .t5 { - background: #006699; - color: white; -} -.t4 { - padding: 0.2ex 0.4ex; -} -.t1, .t2, .t3 { - padding: 0.5ex 1ex; -} - -/* IE does not support .box>.t1 Grrr */ -.box .t1, .box .t2, .box .t3, .box .t5 { - margin: 0; -} - -.t1 { - font-size: 1.4em; - font-weight: bold; - text-align: center; -} - -.t2 { - font-size: 1.0em; - font-weight: bold; - text-align: left; -} - -.t3 { - font-size: 1.0em; - font-weight: normal; - text-align: left; -} - -.t5 { - font-size: 0.8em; - font-weight: normal; - text-align: center; -} - -/* width: 100%; border: 0.1px solid #FFFFFF; */ /* NN4 hack */ - -.datecell { - text-align: center; - width: 17em; -} - -.cell { - padding: 0.2ex 1ex; - text-align: left; -} - -.DBD_Menu.index { - padding: 0.2ex 2ex; - text-align: right; -} - -.DBD_Menu.choice { - font: 1.0em monospace; -} - -.label { - background: #aaaaaa; - color: black; - font-weight: bold; - padding: 0.2ex 1ex; - text-align: right; - white-space: nowrap; - vertical-align: baseline; -} - -.categories { - border-bottom: 3px double #006699; - margin-bottom: 1ex; - padding-bottom: 3ex; - padding-top: 2ex; -} - -.categories TABLE { - margin: auto; -} - -.categories TD { - padding: 0.5ex 1ex; - vertical-align: baseline; -} - -.path A { - background: transparent; - color: #006699; - font-weight: bold; -} - -.pages { - background: #dddddd; - color: #006699; - padding: 0.2ex 0.4ex; -} - -.path { - background: #dddddd; - border-bottom: 1px solid #006699; - color: #006699; - /* font-size: 1.4em;*/ - margin: 1ex 0; - padding: 0.5ex 1ex; -} - -.menubar TD { - background: #006699; - color: white; -} - -.menubar { - background: #006699; - color: white; - margin: 1ex 0; - padding: 1px; -} - -.menubar .links { - background: transparent; - color: white; - padding: 0.2ex; - text-align: left; -} - -.menubar .searchbar { - background: black; - color: black; - margin: 0px; - padding: 2px; - text-align: right; -} - -A.m:link, A.m:visited { - background: #006699; - color: white; - font: bold 10pt Arial,Helvetica,sans-serif; - text-decoration: none; -} - -A.o:link, A.o:visited { - background: #006699; - color: #ccffcc; - font: bold 10pt Arial,Helvetica,sans-serif; - text-decoration: none; -} - -A.o:hover { - background: transparent; - color: #ff6600; - text-decoration: underline; -} - -A.m:hover { - background: transparent; - color: #ff6600; - text-decoration: underline; -} - -table.dlsip { - background: #dddddd; - border: 0.4ex solid #dddddd; -} - -.pod, .manifest { margin-right: 0; } - -.pod PRE { - background: #eeeeee; - border: 1px solid #888888; - color: black; - padding: 1em; - white-space: pre; -} - -.pod H1 { - background: transparent; - color: #006699; - font-size: 1.4em; -} - -.pod H1 A { text-decoration: none; } -.pod H2 A { text-decoration: none; } -.pod H3 A { text-decoration: none; } -.pod H4 A { text-decoration: none; } - -.pod H2 { - background: transparent; - color: #006699; - font-size: 1.2em; -} - -.pod H3 { - background: transparent; - color: #006699; - font-size: 1em; - font-style: italic; -} - -.pod H4 { - background: transparent; - color: #006699; - font-size: 1em; - font-weight: normal; -} - -.pod IMG { - vertical-align: top; -} - -.pod .toc A { - text-decoration: none; -} - -.pod .toc LI { - line-height: 1.2em; - list-style-type: none; -} - -.faq DT { - font-size: 1.4em; - font-weight: bold; -} - -.chmenu { - background: black; - color: red; - font: bold 1.1em Arial,Helvetica,sans-serif; - margin: 1ex auto; - padding: 0.5ex; -} - -.chmenu TD { - padding: 0.2ex 1ex; -} - -.chmenu A:link, .chmenu A:visited { - background: transparent; - color: white; - text-decoration: none; -} - -.chmenu A:hover { - background: transparent; - color: #ff6600; - text-decoration: underline; -} - -.column { - padding: 0.5ex 1ex; - vertical-align: top; -} - -.datebar { - margin: auto; - width: 14em; -} - -.date { - background: transparent; - color: #008000; -} - -.footer { - margin-top: 1ex; - text-align: right; - color: #006699; - font-size: x-small; - border-top: 1px solid #006699; - line-height: 120%; -} - -.front .footer { - border-top: none; -} - -#permalink { - float: right -} - -#permalink A { - font-size: small; -} - -.sr { - font-size: inherit; - margin: 0; -} - -.cpanstats { - float: left; - text-align: left; - color: #bbb; - white-space: pre; -} - -form.tool { - margin: 1ex; -} - -.styleswitch { - text-align: right; -} diff --git a/src/tools/tap-to-junit-xml.pl b/src/tools/tap-to-junit-xml.pl deleted file mode 100644 index fe8aa86fb..000000000 --- a/src/tools/tap-to-junit-xml.pl +++ /dev/null @@ -1,546 +0,0 @@ -#!/usr/local/bin/perl -=head1 NAME - -tap-to-junit-xml - convert perl-style TAP test output to JUnit-style XML - -=head1 SYNOPSIS - -tap-to-junit-xml [--help|--man] - [--[no]hidesummary] - [--input ] - [--output ] - [--puretap] - [] [outputprefix] - -=head1 DESCRIPTION - -Parse test suite output in TAP (Test Anything Protocol, -C) format, and produce XML output in a similar format -to that produced by the ant task. This is useful for consumption by -continuous-integration systems like Hudson (C). - -C<"test suite name"> is a descriptive string used as the B attribute on the -top-level node of the output XML. Defaults to "make test". - -If C is specified, multi-file output will be generated, with -multiple XML files created using C as the start of their -filenames. The files are separated by testplan. This option is ignored -if --puretap is specified (TAP only allows one testplan per input file). -This prefix may contain slashes, in which case the files will be -placed into a directory hierarchy accordingly (although care should be taken to -ensure these directories exist in advance). - -If --input I is not specified, STDIN will be read. -If C or --output is not specified, a single XML file will be -generated on STDOUT. - ---output I is used to write a single XML file to I. - ---puretap parses a single TAP source and handles parse errors and directives -(todo, skip, bailout). --puretap ignores unknown (non-TAP) input. Without ---puretap, the script will parse some additional non-TAP test input, such as -Perl tests that can include a "Test Summary Report", but it won't generate -correct XML unless the TAP testplan comes before the test cases. ---hidesummary report (the default) will hide the summary report, --no-hidesummary -will display it (neither has an effect when --puretap is specified). - -=head1 EXAMPLE - - prove -v 2>&1 | tee tests.log - tap-to-junit-xml "make test" testxml/tests < tests.log - -(JUnit-formatted XML is now in "testxml/tests*.xml".) - -=head1 DEPENDENCIES - - Getopt::Long - Pod::Usage - TAP::Parser - Time::HiRes - XML::Generator - -=head1 BUGS - - - Output is optimized for Hudson, and may not look quite as good in - other UIs. - - Doesn't do anything with the STDERR from tests. - - Doesn't fill in the 'errors' attribute in the element. - (--puretap handles parse errors) - - Doesn't handle "todo" or "skip" (--puretap does) - - Doesn't get the elapsed time for each 'test' (i.e. assertion.) - (TAP output has no elapsed time convention). - -=head1 SOURCE - -http://github.com/jmason/tap-to-junit-xml/tree/master - -=head1 AUTHOR - -original, junit_xml.pl, by Matisse Enzer ; see -C. - -pretty much entirely rewritten by Justin Mason , Feb 2008. - -Miscellaneous fixes and mods (--puretap) by Jascha Lee , Mar 2009. - -=head1 VERSION - - Mar 27 2008 jm - Mar 17 2009 jl - -=head1 COPYRIGHT & LICENSE - -Copyright (c) 2007 Matisse Enzer. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it -under the same terms as Perl itself. -=cut - -use strict; -use warnings; - -use Getopt::Long qw(:config no_ignore_case); -use Pod::Usage; -use TAP::Parser; -use Time::HiRes qw(gettimeofday tv_interval); -use XML::Generator qw(:noimport); - -my %opts; -pod2usage() unless GetOptions( \%opts, 'help|h', - 'hidesummary!', - 'input=s', - 'man', - 'output=s', - 'puretap' - ); - -pod2usage(-verbose => 1) if defined $opts{'help'}; -pod2usage(-verbose => 2) if defined $opts{'man'}; - -my $opt_suitename = shift @ARGV; -my $opt_multifile = 0; -my $opt_mfprefix; - -if (defined $ARGV[0]) { - $opt_multifile = 1; - $opt_mfprefix = $ARGV[0]; -} - -# should the 'Test Summary Report' at the end of a test suite be displayed -# as if it was a testcase? in my opinion, no -my $HIDE_TEST_SUMMARY_REPORT = defined $opts{'hidesummary'} ? $opts{'hidesummary'} : 1; - -my $suite_name = $opt_suitename || 'make test'; -my $safe_suite_name = $suite_name; $safe_suite_name =~ s/[^-:_A-Za-z0-9]+/_/gs; - -# TODO: it'd be nice to respect 'Universal desirable behavior #1' from -# http://testanything.org/wiki/index.php/TAP_Consumers -- 'Should work on the -# TAP as a stream (ie. as each line is received) rather than wait until all the -# TAP is received'. But it seems TAP::Parser itself doesn't support it! -# maybe when TAP::Parser does that, we'll do it too. -my $tapfh; -if ( defined $opts{'input'} ) { - open $tapfh, '<', $opts{'input'} or die "Can't open TAP file '$opts{'input'}': $!\n"; -} -else { - $tapfh = \*STDIN; -} - -my $outfh; -if ( defined $opts{'output'} ) { - open $outfh, '>', $opts{'output'} or die "Can't open output file '$opts{'output'}' for writing: $!\n"; -} -else { - $outfh = \*STDOUT; -} - -my $tap = TAP::Parser->new( { source => $tapfh } ); -my $xmlgen = XML::Generator->new( ':pretty'); -my $xmlgenunescaped = XML::Generator->new( escape => 'unescaped', - conformance => 'strict', - pretty => 2 - ); -my @properties = _get_properties($xmlgen); -if ( defined $opts{'puretap'} ) { - # - # Instead of trying to parse everything in one pass, which fails if the - # testplan is last, parse through the results for the test cases and - # then construct the information from the TAP and wrap it - # around the test cases. Ignore 'unknown' information. [JL] - # - my @testcases = _parse_testcases( $tap, $xmlgen ); - errorOut( $tap, $xmlgen ) if $tap->parse_errors; - print $outfh $xmlgen->testsuites( - $xmlgen->testsuite( { name => $safe_suite_name, - tests => $tap->tests_planned, - failures => scalar $tap->failed, - errors => 0, - time => 0, - id => 1 }, - @testcases )); - -} -else { - my $test_results = _parse_tests( $tap, $xmlgen ); - if ($opt_multifile) { - _gen_junit_multifile_xml( $xmlgen, \@properties, $test_results ); - } else { - print $outfh _get_junit_xml( $xmlgen, \@properties, $test_results ); - } -} -exit; - -#------------------------------------------------------------------------------- - -sub _get_junit_xml { - my ( $xmlgen, $properties, $test_results ) = @_; - my $xml = "\n" . - $xmlgen->testsuites({ - name => $suite_name, - }, @$test_results); - return $xml; -} - -sub _gen_junit_multifile_xml { - my ( $xmlgen, $properties, $test_results ) = @_; - my $count = 1; - foreach my $testsuite (@$test_results) { - open OUT, ">${opt_mfprefix}.${count}.xml" - or die "cannot write ${opt_mfprefix}.${count}.xml"; - print OUT "\n"; - print OUT $testsuite; - close OUT; - $count++; - } -} - -# -# Wrap up parse errors and output them as test cases. -# -sub errorOut { - my $parser = shift; - my $xmlgen = shift; - die "errorOut() needs some args" unless $parser and $xmlgen; - my ($xml, @errors, $name); - my $count = 1; - foreach my $error ( $parser->parse_errors ) { - $name = sprintf "%s%02d", 'Error_', $count++; - $xml = $xmlgen->testcase( { name => $name, - classname => 'TestsNotRun.ParseError', - time => 0 }, - - $xmlgen->error( { type => 'TAPParseError', - message => $error } )); - push @errors, $xml; - } - print $outfh $xmlgen->testsuites( - $xmlgen->testsuite( { name => 'TestsNotRun.ParseError', - tests => $tap->tests_planned, - failures => 0, - errors => scalar $tap->parse_errors, - time => 0, - id => 1 }, - @errors )); - exit 86; -} - -# -# Construct an array of XML'd test cases -# -sub _parse_testcases { - my $parser = shift; - my $xmlgen = shift; - return () unless $parser and $xmlgen; - my ($name, $directive, $xml, @testcases); - - while ( my $result = $parser->next ) { - if ( $result->is_bailout ) { - $xml = $xmlgen->testcase( { name => 'BailOut', - classname => "$safe_suite_name.Tests", - time => 0 }, - - $xmlgen->error( { type => 'BailOut', - message => $result->explanation } )); - - push @testcases, $xml; - last; - } - next unless $result->is_test; - $directive = $result->directive; - $name = sprintf "%s%02d", 'Test_', $result->number; - $name .= "_$directive" if $directive; - if ( $result->is_ok ) { - $xml = $xmlgen->testcase( { name => $name, - classname => "$safe_suite_name.Tests", - time => 0 } ); - push @testcases, $xml; - } - else { - $xml = $xmlgen->testcase( { name => $name, - classname => "$safe_suite_name.Tests", - time => 0 }, - $xmlgen->failure( { type => 'TAPTestFailed', - message => $result->as_string } )); - push @testcases, $xml; - } - } - - return @testcases; -} - -sub _parse_tests { - my ( $parser, $xmlgen ) = @_; - - my $ctx = { - testsuites => [ ], - test_name => 'notest', - plan_ntests => 0, - case_id => 0, - }; - - _new_ctx($ctx); - - my $lastunk = ''; - - # unknown t/basic_lint......... - # plan 1..1 - # comment # Running under perl version 5.008008 for linux - # comment # Current time local: Thu Jan 24 17:44:30 2008 - # comment # Current time GMT: Thu Jan 24 17:44:30 2008 - # comment # Using Test.pm version 1.25 - # unknown /usr/bin/perl -T -w ../spamassassin.raw -C log/test_rules_copy --siteconfigpath log/localrules.tmp -p log/test_default.cf -L --lint - # unknown Checking anything - # test ok 1 - # test ok 2 - # unknown t/basic_meta......... - # plan 1..2 - # comment # Running under perl version 5.008008 for linux - # comment # Current time local: Thu Jan 24 17:44:31 2008 - # comment # Current time GMT: Thu Jan 24 17:44:31 2008 - # comment # Using Test.pm version 1.25 - # test not ok 1 - # comment # Failed test 1 in t/basic_meta.t at line 91 - # test ok 2 - # unknown Failed 1/2 subtests - # unknown t/basic_obj_api...... - # plan 1..4 - # comment # Running under perl version 5.008008 for linux - # comment # Current time local: Thu Jan 24 17:44:33 2008 - # comment # Current time GMT: Thu Jan 24 17:44:33 2008 - # comment # Using Test.pm version 1.25 - # test ok 1 - # test ok 2 - # test ok 3 - # test ok 4 - # test ok 9 - # unknown - # unknown Test Summary Report - # unknown ------------------- - # unknown t/basic_meta.t (Wstat: 0 Tests: 2 Failed: 1) - # unknown Failed test: 1 - # unknown Files=3, Tests=7, 6 wallclock secs ( 0.01 usr 0.00 sys + 4.39 cusr 0.23 csys = 4.63 CPU) - # unknown Result: FAIL - # unknown Failed 1/3 test programs. 1/7 subtests failed. - # unknown make: *** [test_dynamic] Error 255 - - while ( my $r = $parser->next ) { - my $t = $r->type; - my $s = $r->as_string; $s =~ s/\s+$//; - - # warn "JMD $t $s"; - - if ($t eq 'unknown') { - $lastunk = $s; - - # PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(1, 'blib/lib', 'blib/arch')" t/basic_* - # if ($s =~ /test_harness\(.*?\)" (.+)$/) { - # $suite_name = $1; - # } - if ($s =~ /^Test Summary Report$/) { - # create a block for the summary - $ctx->{plan_ntests} = 0; - $ctx->{test_name} = "Test Summary Report"; - $ctx->{case_tests} = 1; - _finish_test_block($ctx); - } - elsif ($s =~ /^Result: FAIL$/) { - $ctx->{case_tests}++; - $ctx->{case_failures}++; - my $test_case = { - classname => test_name_to_classname($ctx->{test_name}), - name => 'result', - 'time' => 0, - }; - my $failure = $xmlgen->failure({ - type => "OverallTestsFailed", - message => $s - }, "__FAILUREMESSAGETODO__"); - - if (!$HIDE_TEST_SUMMARY_REPORT) { - push @{$ctx->{test_cases}}, $xmlgen->testcase($test_case, $failure); - } - } - elsif ($s =~ /^(\S+?)\.\.\.+1\.\.(\d+?)\s*$/) { - # perl 5.6.x "Test" format plan line - # unknown t/basic_lint....................1..1 - - my ($name, $nt) = ($1,$2); - if ($ctx->{plan_ntests}) { # only if there have been tests planned - _finish_test_block($ctx); - } - - $ctx->{plan_ntests} = $nt+0; - $ctx->{test_name} = "$name.t"; - } - } - elsif ($t eq 'plan') { - if ($ctx->{plan_ntests}) { # only if there have been tests planned - _finish_test_block($ctx); - } - - $ctx->{plan_ntests} = 0; - $s =~ /(\d+)$/ and $ctx->{plan_ntests} = $1+0; - - $ctx->{test_name} = $lastunk; - $ctx->{test_name} =~ s/\.*\s*$//gs; - $ctx->{test_name} .= ".t"; - } - elsif ($t eq 'test') { - my $ntest = 0; - if ($s =~ /(?:not |)\S+ (\d+)/) { $ntest = $1+0; } - - if ($ntest > $ctx->{plan_ntests}) { - # jump in test numbers, more than planned; this is probably TAP::Parser's wierdness. - # (when it sees the "ok" line at the end of a test case with no number, - # it outputs the current total number of tests so far.) - next; - } - - # clean this up in a Hudson-compatible way; ":" and "/" are out, "." also causes - # trouble by creating an extra "directory" in the results - - my $test_case = { - classname => test_name_to_classname($ctx->{test_name}), - name => sprintf("test %6d", $ntest), # space-padding ensures ordering - 'time' => 0, - }; - - $ctx->{case_tests}++; - my $failure = undef; - if ($s =~ /^not /i) { - $ctx->{case_failures}++; - $failure = $xmlgen->failure({ - type => "TAPTestFailed", - message => $s - }, "__FAILUREMESSAGETODO__"); - push @{$ctx->{test_cases}}, $xmlgen->testcase($test_case, $failure); - } - else { - push @{$ctx->{test_cases}}, $xmlgen->testcase($test_case); - } - } - - $ctx->{sysout} .= $s."\n"; - } - - if (scalar(@{$ctx->{test_cases}}) == 0 && - scalar(@{$ctx->{testsuites}}) == 0) - { - # no tests found! create a block containing *something* at least - $ctx->{case_tests}++; - my $test_case = { - classname => test_name_to_classname($ctx->{test_name}), - name => 'result', - 'time' => 0, - }; - push @{$ctx->{test_cases}}, $xmlgen->testcase($test_case); - } - - _finish_test_block($ctx); - return $ctx->{testsuites}; -} - -sub _new_ctx { - my $ctx = shift; - $ctx->{start_time} = [gettimeofday]; - $ctx->{test_cases} = []; - $ctx->{case_tests} = 0; - $ctx->{case_failures} = 0; - $ctx->{case_time} = 0; - $ctx->{case_id}++; - $ctx->{sysout} = ''; - return $ctx; -} - -sub _finish_test_block { - my $ctx = shift; - $ctx->{sysout} =~ s/\n\S+\.*\s*\n$/\n/s; # remove next test's "t/foo....." line - - my $elapsed_time = 0; # TODO - #my $elapsed_time = tv_interval( $ctx->{start_time}, [gettimeofday] ); - - # clean it up to valid Java packagename format (or at least something Hudson will - # consume) - my $name = $ctx->{test_name}; - $name =~ s/[^-:_A-Za-z0-9]+/_/gs; - $name = "$safe_suite_name.$name"; # a "directory" for the suite name - - my $testsuite = { - 'time' => $elapsed_time, - 'name' => $name, - tests => $ctx->{case_tests}, - failures => $ctx->{case_failures}, - 'id' => $ctx->{case_id}, - errors => 0, - }; - - my @fixedcases = (); - foreach my $tc (@{$ctx->{test_cases}}) { - if ($tc =~ s/__FAILUREMESSAGETODO__/ cdata($ctx->{sysout}) /ges) { - push @fixedcases, \$tc; # inhibits escaping! - } else { - push @fixedcases, $tc; - } - } - - # use "unescaped"; we have already fixed escaping on these strings. - # note that a reference means 'this is unescaped', bizarrely. - push @{$ctx->{testsuites}}, $xmlgenunescaped->testsuite($testsuite, - @fixedcases, - \("\n".cdata($ctx->{sysout})."\n"), - \("")); - - _new_ctx($ctx); -}; - -sub cdata { - my $s = shift; - $s =~ s/\]\]>/\](warning: defanged by tap-to-junit-xml)\]>/gs; - return ''; -} - -sub _get_properties { - my $xmlgen = shift; - my @props; - foreach my $key ( sort keys %ENV ) { - push @props, $xmlgen->property( { name => "$key", value => $ENV{$key} } ); - } - return @props; -} - -sub test_name_to_classname { - my $safe = shift; - $safe =~ s/[^-:_A-Za-z0-9]+/_/gs; - $safe = "$safe_suite_name.$safe"; # a "directory" for the suite name - $safe; -} - -__END__ - -# JUnit references: -# http://www.nabble.com/JUnit-4-XML-schematized--td13946472.html -# http://jra1mw.cvs.cern.ch:8180/cgi-bin/jra1mw.cgi/org.glite.testing.unit/config/JUnitXSchema.xsd?view=markup -# skipped tests: -# https://hudson.dev.java.net/issues/show_bug.cgi?id=1251 -# Hudson source: -# http://fisheye5.cenqua.com/browse/hudson/hudson/main/core/src/main/java/hudson/tasks/junit/CaseResult.java diff --git a/src/tools/test/Breaktable.plt b/src/tools/test/Breaktable.plt deleted file mode 100644 index 99df5457a..000000000 --- a/src/tools/test/Breaktable.plt +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 9; - -use DBD::Breaktable; - -my $bpt = DBD::Breaktable->new('test'); -isa_ok $bpt, 'DBD::Breaktable'; -is $bpt->name, 'test', 'Breakpoint table name'; -is $bpt->points, 0, 'Points == zero'; -$bpt->add_point(0, 0.5); -is $bpt->points, 1, 'First point added'; -is_deeply $bpt->point(0), [0, 0.5], 'First point correct'; -$bpt->add_point(1, 1.5); -is $bpt->points, 2, 'Second point added'; -is_deeply $bpt->point(0), [0, 0.5], 'First point still correct'; -is_deeply $bpt->point(1), [1, 1.5], 'Second point correct'; -is_deeply $bpt->point(2), undef, 'Third point undefined'; - diff --git a/src/tools/test/DBD.plt b/src/tools/test/DBD.plt deleted file mode 100644 index 2bfe6ef48..000000000 --- a/src/tools/test/DBD.plt +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 18; - -use DBD; - -my $dbd = DBD->new; -isa_ok $dbd, 'DBD'; - -is keys %{$dbd->breaktables}, 0, 'No breaktables yet'; -my $brk = DBD::Breaktable->new('Brighton'); -$dbd->add($brk); -my %brks = %{$dbd->breaktables}; -is_deeply \%brks, {Brighton => $brk}, 'Added breaktable'; - -is keys %{$dbd->drivers}, 0, 'No drivers yet'; -my $drv = DBD::Driver->new('Danforth'); -$dbd->add($drv); -my %drvs = %{$dbd->drivers}; -is_deeply \%drvs, {Danforth => $drv}, 'Added driver'; - -is keys %{$dbd->functions}, 0, 'No functions yet'; -my $fnc = DBD::Function->new('Frank'); -$dbd->add($fnc); -my %fncs = %{$dbd->functions}; -is_deeply \%fncs, {Frank => $fnc}, 'Added function'; - -is keys %{$dbd->menus}, 0, 'No menus yet'; -my $menu = DBD::Menu->new('Mango'); -$dbd->add($menu); -my %menus = %{$dbd->menus}; -is_deeply \%menus, {Mango => $menu}, 'Added menu'; -is $dbd->menu('Mango'), $menu, 'Named menu'; - -is keys %{$dbd->recordtypes}, 0, 'No recordtypes yet'; -my $rtyp = DBD::Recordtype->new('Rita'); -$dbd->add($rtyp); -my %rtypes = %{$dbd->recordtypes}; -is_deeply \%rtypes, {Rita => $rtyp}, 'Added recordtype'; -is $dbd->recordtype('Rita'), $rtyp, 'Named recordtype'; - -is keys %{$dbd->registrars}, 0, 'No registrars yet'; -my $reg = DBD::Registrar->new('Reggie'); -$dbd->add($reg); -my %regs = %{$dbd->registrars}; -is_deeply \%regs, {Reggie => $reg}, 'Added registrar'; - -is keys %{$dbd->variables}, 0, 'No variables yet'; -my $ivar = DBD::Variable->new('IntVar'); -my $dvar = DBD::Variable->new('DblVar', 'double'); -$dbd->add($ivar); -my %vars = %{$dbd->variables}; -is_deeply \%vars, {IntVar => $ivar}, 'First variable'; -$dbd->add($dvar); -%vars = %{$dbd->variables}; -is_deeply \%vars, {IntVar => $ivar, DblVar => $dvar}, 'Second variable'; - diff --git a/src/tools/test/Device.plt b/src/tools/test/Device.plt deleted file mode 100644 index 3341d5ee0..000000000 --- a/src/tools/test/Device.plt +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 16; - -use DBD::Device; - -my $dev = DBD::Device->new('VME_IO', 'test', 'Device'); -isa_ok $dev, 'DBD::Device'; -is $dev->name, 'test', 'Device name'; -is $dev->link_type, 'VME_IO', 'Link type'; -is $dev->choice, 'Device', 'Choice string'; -ok $dev->legal_addr('#C0xFEED S123 @xxx'), 'Address legal'; -my %dev_addrs = ( - CONSTANT => '12345', - PV_LINK => 'Any:Record.NAME CPP.MS', - VME_IO => '# C1 S2 @Anything', - CAMAC_IO => '# B1 C2 N3 A4 F5 @Anything', - RF_IO => '# R1 M2 D3 E4', - AB_IO => '# L1 A2 C3 S4 @Anything', - GPIB_IO => '# L1 A2 @Anything', - BITBUS_IO => '# L1 N2 P3 S4 @Anything', - BBGPIB_IO => '# L1 B2 G3 @Anything', - VXI_IO => '# V1 C2 S3 @Anything', - INST_IO => '@Anything' -); -while (my ($link, $addr) = each(%dev_addrs)) { - $dev->init($link, 'test', 'Device'); - ok $dev->legal_addr($addr), "$link address"; -} - diff --git a/src/tools/test/Driver.plt b/src/tools/test/Driver.plt deleted file mode 100644 index 17e3a0c78..000000000 --- a/src/tools/test/Driver.plt +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 2; - -use DBD::Driver; - -my $drv = DBD::Driver->new('test'); -isa_ok $drv, 'DBD::Driver'; -is $drv->name, 'test', 'Driver name'; - diff --git a/src/tools/test/Function.plt b/src/tools/test/Function.plt deleted file mode 100644 index 130693293..000000000 --- a/src/tools/test/Function.plt +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 2; - -use DBD::Function; - -my $func = DBD::Function->new('test'); -isa_ok $func, 'DBD::Function'; -is $func->name, 'test', 'Function name'; - diff --git a/src/tools/test/Makefile b/src/tools/test/Makefile deleted file mode 100644 index 2fed19509..000000000 --- a/src/tools/test/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -#************************************************************************* -# Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in the file LICENSE that is included with this distribution. -#************************************************************************* -TOP=../../.. - -include $(TOP)/configure/CONFIG - -TESTS += Breaktable -TESTS += DBD -TESTS += Device -TESTS += Driver -TESTS += Function -TESTS += macLib -TESTS += Menu -TESTS += Recfield -TESTS += Recordtype -TESTS += Registrar -TESTS += Snippets -TESTS += Variable - -TESTSCRIPTS_HOST += $(TESTS:%=%.t) - -include $(TOP)/configure/RULES - diff --git a/src/tools/test/Menu.plt b/src/tools/test/Menu.plt deleted file mode 100644 index 8165d000c..000000000 --- a/src/tools/test/Menu.plt +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 14; - -use DBD::Menu; - -my $menu = DBD::Menu->new('test'); -isa_ok $menu, 'DBD::Menu'; -is $menu->name, 'test', 'Menu name'; -is $menu->choices, 0, 'Choices == zero'; -$menu->add_choice('ch1', 'Choice 1'); -is $menu->choices, 1, 'First choice added'; -ok $menu->legal_choice('Choice 1'), 'First choice legal'; -is_deeply $menu->choice(0), ['ch1', 'Choice 1'], 'First choice found'; -$menu->add_choice('ch2', 'Choice 2'); -is $menu->choices, 2, 'Second choice added'; -ok $menu->legal_choice('Choice 1'), 'First choice still legal'; -is_deeply $menu->choice(0), ['ch1', 'Choice 1'], 'First choice still found'; -ok $menu->legal_choice('Choice 2'), 'Second choice legal'; -is_deeply $menu->choice(1), ['ch2', 'Choice 2'], 'Second choice found'; -ok !$menu->legal_choice('Choice 3'), 'Third choice not legal'; -is_deeply $menu->choice(2), undef, 'Third choice undefined'; - -like $menu->toDeclaration, qr/ ^ - \s* typedef \s+ enum \s+ \{ \s* \n - \s* ch1 \s+ \/\* [^*]* \*\/, \s* \n - \s* ch2 \s+ \/\* [^*]* \*\/ \s* \n - \s* \} \s* test \s* ; \s* \n - \s* \# \s* define \s+ test_NUM_CHOICES \s+ 2 \s* \n - \s* $ /x, 'C declaration'; diff --git a/src/tools/test/Recfield.plt b/src/tools/test/Recfield.plt deleted file mode 100644 index cdad4dbb7..000000000 --- a/src/tools/test/Recfield.plt +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 76; - -use DBD::Recfield; - -my $fld_string = DBD::Recfield->new('str', 'DBF_STRING'); -isa_ok $fld_string, 'DBD::Recfield'; -isa_ok $fld_string, 'DBD::Recfield::DBF_STRING'; -$fld_string->set_number(0); -is $fld_string->number, 0, 'Field number'; -$fld_string->add_attribute("size", "41"); -is keys %{$fld_string->attributes}, 1, "Size set"; -ok $fld_string->legal_value("Hello, world!"), 'Legal value'; -ok !$fld_string->legal_value("x"x41), 'Illegal string'; -$fld_string->check_valid; -like $fld_string->toDeclaration, qr/^\s*char\s+str\[41\];\s*$/, "C declaration"; - -my $fld_char = DBD::Recfield->new('chr', 'DBF_CHAR'); -isa_ok $fld_char, 'DBD::Recfield'; -isa_ok $fld_char, 'DBD::Recfield::DBF_CHAR'; -is $fld_char->name, 'chr', 'Field name'; -is $fld_char->dbf_type, 'DBF_CHAR', 'Field type'; -ok !$fld_char->legal_value("-129"), 'Illegal - value'; -ok $fld_char->legal_value("-128"), 'Legal - value'; -ok $fld_char->legal_value("127"), 'Legal + value'; -ok !$fld_char->legal_value("0x80"), 'Illegal + hex value'; -$fld_char->check_valid; -like $fld_char->toDeclaration, qr/^\s*epicsInt8\s+chr;\s*$/, "C declaration"; - -my $fld_uchar = DBD::Recfield->new('uchr', 'DBF_UCHAR'); -isa_ok $fld_uchar, 'DBD::Recfield'; -isa_ok $fld_uchar, 'DBD::Recfield::DBF_UCHAR'; -is $fld_uchar->name, 'uchr', 'Field name'; -is $fld_uchar->dbf_type, 'DBF_UCHAR', 'Field type'; -ok !$fld_uchar->legal_value("-1"), 'Illegal - value'; -ok $fld_uchar->legal_value("0"), 'Legal 0 value'; -ok $fld_uchar->legal_value("0377"), 'Legal + value'; -ok !$fld_uchar->legal_value("0400"), 'Illegal + octal value'; -$fld_uchar->check_valid; -like $fld_uchar->toDeclaration, qr/^\s*epicsUInt8\s+uchr;\s*$/, "C declaration"; - -my $fld_short = DBD::Recfield->new('shrt', 'DBF_SHORT'); -isa_ok $fld_short, 'DBD::Recfield'; -isa_ok $fld_short, 'DBD::Recfield::DBF_SHORT'; -is $fld_short->name, 'shrt', 'Field name'; -is $fld_short->dbf_type, 'DBF_SHORT', 'Field type'; -ok !$fld_short->legal_value("-32769"), 'Illegal - value'; -ok $fld_short->legal_value("-32768"), 'Legal - value'; -ok $fld_short->legal_value("32767"), 'Legal + value'; -ok !$fld_short->legal_value("0x8000"), 'Illegal + hex value'; -$fld_short->check_valid; -like $fld_short->toDeclaration, qr/^\s*epicsInt16\s+shrt;\s*$/, "C declaration"; - -my $fld_ushort = DBD::Recfield->new('ushrt', 'DBF_USHORT'); -isa_ok $fld_ushort, 'DBD::Recfield'; -isa_ok $fld_ushort, 'DBD::Recfield::DBF_USHORT'; -is $fld_ushort->name, 'ushrt', 'Field name'; -is $fld_ushort->dbf_type, 'DBF_USHORT', 'Field type'; -ok !$fld_ushort->legal_value("-1"), 'Illegal - value'; -ok $fld_ushort->legal_value("0"), 'Legal 0 value'; -ok $fld_ushort->legal_value("65535"), 'Legal + value'; -ok !$fld_ushort->legal_value("0x10000"), 'Illegal + hex value'; -$fld_ushort->check_valid; -like $fld_ushort->toDeclaration, qr/^\s*epicsUInt16\s+ushrt;\s*$/, "C declaration"; - -my $fld_long = DBD::Recfield->new('lng', 'DBF_LONG'); -isa_ok $fld_long, 'DBD::Recfield'; -isa_ok $fld_long, 'DBD::Recfield::DBF_LONG'; -is $fld_long->name, 'lng', 'Field name'; -is $fld_long->dbf_type, 'DBF_LONG', 'Field type'; -ok $fld_long->legal_value("-12345678"), 'Legal - value'; -ok $fld_long->legal_value("0x12345678"), 'Legal + value'; -ok !$fld_long->legal_value("0xfigure"), 'Illegal value'; -$fld_long->check_valid; -like $fld_long->toDeclaration, qr/^\s*epicsInt32\s+lng;\s*$/, "C declaration"; - -my $fld_ulong = DBD::Recfield->new('ulng', 'DBF_ULONG'); -isa_ok $fld_ulong, 'DBD::Recfield'; -isa_ok $fld_ulong, 'DBD::Recfield::DBF_ULONG'; -is $fld_ulong->name, 'ulng', 'Field name'; -is $fld_ulong->dbf_type, 'DBF_ULONG', 'Field type'; -ok !$fld_ulong->legal_value("-1"), 'Illegal - value'; -ok $fld_ulong->legal_value("00"), 'Legal 0 value'; -ok $fld_ulong->legal_value("0xffffffff"), 'Legal + value'; -ok !$fld_ulong->legal_value("0xfacepaint"), 'Illegal value'; -$fld_ulong->check_valid; -like $fld_ulong->toDeclaration, qr/^\s*epicsUInt32\s+ulng;\s*$/, "C declaration"; - -my $fld_float = DBD::Recfield->new('flt', 'DBF_FLOAT'); -isa_ok $fld_float, 'DBD::Recfield'; -isa_ok $fld_float, 'DBD::Recfield::DBF_FLOAT'; -is $fld_float->name, 'flt', 'Field name'; -is $fld_float->dbf_type, 'DBF_FLOAT', 'Field type'; -ok $fld_float->legal_value("-1.2345678e9"), 'Legal - value'; -ok $fld_float->legal_value("0.12345678e9"), 'Legal + value'; -ok !$fld_float->legal_value("0x1.5"), 'Illegal value'; -$fld_float->check_valid; -like $fld_float->toDeclaration, qr/^\s*epicsFloat32\s+flt;\s*$/, "C declaration"; - -my $fld_double = DBD::Recfield->new('dbl', 'DBF_DOUBLE'); -isa_ok $fld_double, 'DBD::Recfield'; -isa_ok $fld_double, 'DBD::Recfield::DBF_DOUBLE'; -is $fld_double->name, 'dbl', 'Field name'; -is $fld_double->dbf_type, 'DBF_DOUBLE', 'Field type'; -ok $fld_double->legal_value("-12345e-67"), 'Legal - value'; -ok $fld_double->legal_value("12345678e+9"), 'Legal + value'; -ok !$fld_double->legal_value("e5"), 'Illegal value'; -$fld_double->check_valid; -like $fld_double->toDeclaration, qr/^\s*epicsFloat64\s+dbl;\s*$/, "C declaration"; - diff --git a/src/tools/test/Recordtype.plt b/src/tools/test/Recordtype.plt deleted file mode 100644 index c5384b7a9..000000000 --- a/src/tools/test/Recordtype.plt +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 17; - -use DBD::Recordtype; -use DBD::Recfield; -use DBD::Device; - -my $rtyp = DBD::Recordtype->new('test'); -isa_ok $rtyp, 'DBD::Recordtype'; -is $rtyp->name, 'test', 'Record name'; -is $rtyp->fields, 0, 'No fields yet'; - -my $fld1 = DBD::Recfield->new('NAME', 'DBF_STRING'); -$fld1->add_attribute("size", "41"); -$fld1->check_valid; - -my $fld2 = DBD::Recfield->new('DTYP', 'DBF_DEVICE'); -$fld2->check_valid; - -$rtyp->add_field($fld1); -is $rtyp->fields, 1, 'First field added'; - -$rtyp->add_field($fld2); -is $rtyp->fields, 2, 'Second field added'; - -my @fields = $rtyp->fields; -is_deeply \@fields, [$fld1, $fld2], 'Field list'; - -my @names = $rtyp->field_names; -is_deeply \@names, ['NAME', 'DTYP'], 'Field name list'; - -is $rtyp->field('NAME'), $fld1, 'Field name lookup'; - -is $fld1->number, 0, 'Field number 0'; -is $fld2->number, 1, 'Field number 1'; - -is $rtyp->devices, 0, 'No devices yet'; - -my $dev1 = DBD::Device->new('INST_IO', 'testDset', 'test device'); -$rtyp->add_device($dev1); -is $rtyp->devices, 1, 'First device added'; - -my @devices = $rtyp->devices; -is_deeply \@devices, [$dev1], 'Device list'; - -is $rtyp->device('test device'), $dev1, 'Device name lookup'; - -is $rtyp->cdefs, 0, 'No cdefs yet'; -$rtyp->add_cdef("cdef"); -is $rtyp->cdefs, 1, 'First cdef added'; - -my @cdefs = $rtyp->cdefs; -is_deeply \@cdefs, ["cdef"], 'cdef list'; diff --git a/src/tools/test/Registrar.plt b/src/tools/test/Registrar.plt deleted file mode 100644 index b297077b4..000000000 --- a/src/tools/test/Registrar.plt +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 2; - -use DBD::Registrar; - -my $reg = DBD::Registrar->new('test'); -isa_ok $reg, 'DBD::Registrar'; -is $reg->name, 'test', 'Registrar name'; - diff --git a/src/tools/test/Snippets.plt b/src/tools/test/Snippets.plt deleted file mode 100644 index cf3ff2d9c..000000000 --- a/src/tools/test/Snippets.plt +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env perl - -use File::Path; -use Sys::Hostname; - -use Test::More tests => 29; - -my $user = $ENV{LOGNAME} || $ENV{USER} || $ENV{USERNAME}; -my $host = hostname; - -mkdir "a$$"; -mkdir "b$$"; - -sub mksnip { - my ($dir, $file, $line) = @_; - open(my $fh, '>', "$dir$$/$file") or die "can't open $dir$$/$file : $!"; - print $fh $line; - close $fh; -} - -sub assemble { - my @cmd = ( 'perl', '../../assembleSnippets.pl', '-o', "out$$" ); - push @cmd, @_; - system(@cmd); - open(my $fh, '<', "out$$") or die "can't open out$$ : $!"; - chomp(my @result = <$fh>); - close $fh; - return join (' ', @result); -} - -# Adding two snippets of same rank, sorting alphabetically -mksnip('a', '10_a', '10'); -mksnip('b', '10_c', '12'); -is assemble("a$$/10_a", "b$$/10_c"), '10 12', "adding same rank; ordered"; -is assemble("b$$/10_c", "a$$/10_a"), '10 12', "adding same rank; reverse order"; - -# Same, with 'A' cmd -mksnip('a', 'A10_a', '10'); -mksnip('b', 'A10_c', '12'); -is assemble("a$$/10_a", "b$$/A10_c"), '10 12', "'A' add same rank; ordered"; -is assemble("b$$/10_c", "a$$/A10_a"), '10 12', "'A' add same rank; reverse order"; - -# Same name does not create issues -mksnip('b', '10_a', '10x'); -is assemble("a$$/10_a", "b$$/10_a"), '10 10x', "adding same name twice; order a-b"; -is assemble("b$$/10_a", "a$$/10_a"), '10x 10', "adding same name twice; order b-a"; - -# Backup files (trailing ~) and hidden files (leading '.') get ignored -mksnip('b', '10_c~', '12~'); -mksnip('b', '.10_c', '.12'); -is assemble("b$$/10_c", "b$$/10_c~"), '12', "backup file (trailing ~) gets ignored"; -is assemble("b$$/10_c", "b$$/.10_c"), '12', "hidden file (leading .) gets ignored"; - -# Non-numeric filenames get ignored -mksnip('a', 'foo10_a', 'foo10'); -is assemble("b$$/10_c", "a$$/foo10_a"), '12', "file starting with [^ADR0-9] gets ignored"; - -# 'R' command replaces existing snippets of same rank -mksnip('a', 'R10_b', '11'); -is assemble("a$$/10_a", "b$$/10_c", "a$$/R10_b"), '11', "'R' cmd; replace all"; -is assemble("a$$/10_a", "a$$/R10_b", "b$$/10_c"), '11 12', "'R' cmd; replace one (ordered)"; -is assemble("b$$/10_c", "a$$/R10_b", "a$$/10_a"), '10 11', "'R' cmd; replace one (reverse order)"; - -# 'D' command establishes default that gets overwritten or ignored -mksnip('a', 'D10_a', 'D10'); -mksnip('b', 'D10_c', 'D12'); -is assemble("a$$/D10_a", "b$$/10_c"), '12', "'D' default; replaced by regular"; -is assemble("a$$/D10_a", "b$$/D10_c"), 'D12', "'D' default; replaced by new default (ordered)"; -is assemble("b$$/D10_c", "a$$/D10_a"), 'D10', "'D' default; replaced by new default (reverse order)"; -is assemble("a$$/D10_a", "a$$/R10_b"), '11', "'D' default; replaced by 'R' cmd"; -is assemble("b$$/10_c", "a$$/D10_a"), '12', "'D' default; ignored when regular exists"; - -# Ranks are sorted numerically -mksnip('b', '09_a', '09'); -mksnip('a', '15_a', '15'); -mksnip('b', '2_a', '2'); -is assemble("a$$/10_a", "b$$/2_a", "a$$/15_a", "b$$/09_a"), '2 09 10 15', "ranks are sorted numerically"; - -# Builtin macros -mksnip('a', '30_a', '_USERNAME_'); -mksnip('a', '30_b', '_OUTPUTFILE_'); -mksnip('a', '30_c', '_SNIPPETFILE_'); -mksnip('a', '30_d', '_HOST_'); -is assemble("a$$/30_a"), "$user", "builtin macro _USERNAME_"; -is assemble("a$$/30_b"), "out$$", "builtin macro _OUTPUTFILE_"; -is assemble("a$$/30_c"), "a$$/30_c", "builtin macro _SNIPPETFILE_"; -is assemble("a$$/30_d"), "$host", "builtin macro _HOST_"; - -# User macros -mksnip('b', '35_a', 'Line _M1_'); -mksnip('b', '35_b', 'Line _M1_ with _M2_'); -mksnip('b', '35_c', 'Line _M2_ with _M2_'); -is assemble("-m", "_M1_=REP1", "b$$/35_a"), "Line REP1", "single user macro; single occurrence"; -is assemble("-m", "_M1_=REP1,_M2_=REP2", "b$$/35_b"), "Line REP1 with REP2", "multiple user macros"; -is assemble("-m", "_M2_=REP2", "b$$/35_c"), "Line REP2 with REP2", "single user macro; multiple occurrences"; - -# Input pattern -mksnip('a', '10_a.cmd', '10cmd'); -is assemble("-i", "\.cmd", "a$$/10_a", "b$$/10_c", "a$$/R10_b", "a$$/10_a.cmd"), '10cmd', "input pattern"; - -# Dependency file generation -assemble("-M", "./dep$$", "a$$/10_a", "b$$/10_c"); -open(my $fh, '<', "dep$$") or die "can't open dep$$ : $!"; -chomp(my @result = <$fh>); -close $fh; -is "$result[0]", "out$$: \\", "dependency file (line 1)"; -is "$result[1]", " a$$/10_a \\", "dependency file (line 2)"; -is "$result[2]", " b$$/10_c", "dependency file (line 3)"; - -rmtree([ "a$$", "b$$", "out$$", "dep$$" ]); diff --git a/src/tools/test/Variable.plt b/src/tools/test/Variable.plt deleted file mode 100644 index 57f92e9a7..000000000 --- a/src/tools/test/Variable.plt +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 4; - -use DBD::Variable; - -my $ivar = DBD::Variable->new('test'); -isa_ok $ivar, 'DBD::Variable'; -is $ivar->name, 'test', 'Variable name'; -is $ivar->var_type, 'int', 'variable defaults to int'; -my $dvar = DBD::Variable->new('test', 'double'); -is $dvar->var_type, 'double', 'double variable'; diff --git a/src/tools/test/macLib.plt b/src/tools/test/macLib.plt deleted file mode 100644 index d492c3bc1..000000000 --- a/src/tools/test/macLib.plt +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/perl - -use lib '../..'; - -use Test::More tests => 35; - -use EPICS::macLib; - -use Data::Dumper; - -my $m = EPICS::macLib->new; -isa_ok $m, 'EPICS::macLib'; -is $m->expandString(''), '', 'Empty string'; - -{ - local *STDERR; - my $output; - open STDERR, '>', \$output; - is $m->expandString('$(undef)'), undef, 'Warning $(undef)'; - chomp $output; - is $output, q/macLib: macro 'undef' is undefined (expanding string '$(undef)')/, 'macLib error message'; -} - -$m->suppressWarning(1); -is $m->expandString('$(undef)'), '$(undef)', 'Suppressed $(undef)'; - -$m->putValue('a', 'foo'); -is $m->expandString('$(a)'), 'foo', '$(a)'; -is $m->expandString('${a}'), 'foo', '${a}'; -is $m->expandString('$(a=bar)'), 'foo', '$(a=bar)'; -is $m->expandString('${a=bar}'), 'foo', '${a=bar}'; -is $m->expandString('$(undef)'), '$(undef)', '$(undef) again'; -is $m->expandString('${undef}'), '$(undef)', '${undef} again'; - -$m->suppressWarning(0); -is $m->expandString('$(undef=$(a))'), 'foo', '$(undef=$(a))'; -is $m->expandString('${undef=${a}}'), 'foo', '${undef=${a}}'; -is $m->expandString('${undef=$(a)}'), 'foo', '${undef=$(a)}'; -is $m->expandString('$(undef=${a})'), 'foo', '$(undef=${a})'; -is $m->expandString('$(a=$(undef))'), 'foo', '$(a=$(undef))'; - -$m->putValue('b', 'baz'); -is $m->expandString('$(b)'), 'baz', '$(b)'; -is $m->expandString('$(a)'), 'foo', '$(a)'; -is $m->expandString('$(a)$(b)'), 'foobaz', '$(a)$(b)'; -is $m->expandString('$(a)/$(b)'), 'foo/baz', '$(a)/$(b)'; -is $m->expandString('$(a)\$(b)'), 'foo\$(b)', '$(a)\$(b)'; -is $m->expandString('$(a)$$(b)'), 'foo$baz', '$(a)$$(b)'; - -$m->putValue('c', '$(a)'); -is $m->expandString('$(c)'), 'foo', '$(c)'; -is $m->expandString('$(undef=$(c))'), 'foo', '$(undef=$(c))'; - -$m->putValue('d', 'c'); -is $m->expandString('$(d)'), 'c', '$(d)'; -is $m->expandString('$($(d))'), 'foo', '$($(d))'; -is $m->expandString('$($(b)=$(a))'), 'foo', '$($(b)=$(a))'; - -$m->suppressWarning(1); -$m->putValue('c', undef); -is $m->expandString('$(c)'), '$(c)', '$(c) deleted'; - -$m->installMacros('c=fum,d'); -is $m->expandString('$(c)'), 'fum', 'installMacros, $(c)'; - -is $m->expandString('$(d)'), '$(d)', 'installMacros deletion'; - -$m->pushScope; -is $m->expandString('$(a)'), 'foo', 'pushScope, $(a)'; -$m->putValue('a', 'grinch'); -is $m->expandString('$(a)'), 'grinch', 'new $(a) in child'; - -$m->putValue('b', undef); -is $m->expandString('$(b)'), '$(b)', '$(b) deleted in child'; - -$m->popScope; -is $m->expandString('$(a)'), 'foo', 'popScope, $(a) restored'; -is $m->expandString('$(b)'), 'baz', '$(b) restored'; - diff --git a/src/tools/useManifestTool.pl b/src/tools/useManifestTool.pl deleted file mode 100644 index 9e59e9f1f..000000000 --- a/src/tools/useManifestTool.pl +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env perl -# -# Use MS Visual C++ compiler version number to determine if -# we want to use the Manifest Tool (status=1) or not (status=0) -# -# VC compiler versions >= 14.00 will have status=1 -# VC compiler versions 10.00 - 13.10 will have status=0 -# EPICS builds with older VC compilers is not supported -# - -my $versionString=`cl 2>&1`; - -if ($versionString =~ m/Version 16./) { - $status=0; -} elsif ($versionString =~ m/Version 15./){ - $status=1; -} elsif ($versionString =~ m/Version 14./){ - $status=1; -} elsif ($versionString =~ m/Version 13.10/){ - $status=0; -} elsif ($versionString =~ m/Version 13.0/){ - $status=0; -} elsif ($versionString =~ m/Version 12./){ - $status=0; -} elsif ($versionString =~ m/Version 11./){ - $status=0; -} elsif ($versionString =~ m/Version 10./){ - $status=0; -} else { - $status=0; -} -print "$status\n"; -exit; diff --git a/startup/EpicsHostArch b/startup/EpicsHostArch deleted file mode 100755 index 8861ac56c..000000000 --- a/startup/EpicsHostArch +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/sh -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# -# EpicsHostArch - returns the Epics host architecture suitable -# for assigning to the EPICS_HOST_ARCH variable - -if [ "x${1}" != "x" ] -then - suffix="-"${1} -else - suffix="" -fi - -sysname=`uname` - -case $sysname in - Linux ) - os=linux - cpu=`uname -m` - case $cpu in - i386 | i486 | i586 | i686 ) - cpu=x86 ;; - x86_64 ) - ;; # $cpu is correct - armv6l | armv7l ) - cpu=arm ;; - esac - echo ${os}-${cpu}${suffix} - ;; - Darwin ) - os=darwin - cpu=`uname -m` - case $cpu in - "Power Macintosh") - cpu=ppc ;; - i386 | x86_64 ) - cpu=x86 ;; - esac - echo ${os}-${cpu}${suffix} - ;; - SunOS ) - version=`uname -r | sed '1s/^\([0-9]*\).*$/\1/'` - if [ ${version} -ge 5 ]; then - os=solaris - else - os=sun4 - fi - cpu=`uname -m` - case $cpu in - sun4*) - cpu=sparc - ;; - i86pc) - cpu=x86 - ;; - esac - echo ${os}-${cpu}${suffix} - ;; - * ) - sysname=`uname -o` - case $sysname in - Cygwin ) - os=cygwin - cpu=`uname -m` - case $cpu in i386 | i486 | i586 | i686 ) - cpu=x86 - ;; - esac - echo ${os}-${cpu}${suffix} - ;; - * ) - echo unsupported - ;; - esac - ;; -esac - diff --git a/startup/EpicsHostArch.pl b/startup/EpicsHostArch.pl deleted file mode 100755 index 09f7ffddd..000000000 --- a/startup/EpicsHostArch.pl +++ /dev/null @@ -1,47 +0,0 @@ -eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*- - if $running_under_some_shell; # EpicsHostArch.pl -#************************************************************************* -# Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -# Returns the Epics host architecture suitable -# for assigning to the EPICS_HOST_ARCH variable - -use Config; -use POSIX; - -$suffix=""; -$suffix="-".$ARGV[0] if ($ARGV[0] ne ""); - -$EpicsHostArch = GetEpicsHostArch(); -print "$EpicsHostArch$suffix"; - -sub GetEpicsHostArch { # no args - $arch=$Config{'archname'}; - if ($arch =~ /sun4-solaris/) { return "solaris-sparc"; - } elsif ($arch =~ m/i86pc-solaris/) { return "solaris-x86"; - } elsif ($arch =~ m/i[3-6]86-linux/){ return "linux-x86"; - } elsif ($arch =~ m/x86_64-linux/) { return "linux-x86_64"; - } elsif ($arch =~ m/arm-linux/) { return "linux-arm"; - } elsif ($arch =~ m/MSWin32-x86/) { return "win32-x86"; - } elsif ($arch =~ m/MSWin32-x64/) { return "windows-x64"; - } elsif ($arch =~ m/cygwin/) { - my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname(); - if ($cpu =~ m/x86_64/) { return "cygwin-x86_64"; } - return "cygwin-x86"; - } elsif ($arch =~ m/darwin/) { - my($kernel, $hostname, $release, $version, $cpu) = POSIX::uname(); - if ($cpu =~ m/Power Macintosh/) { return "darwin-ppc"; } - elsif ($cpu =~ m/i386/) { return "darwin-x86"; } - elsif ($cpu =~ m/x86_64/) { return "darwin-x86"; } - else { return "unsupported"; } - } else { return "unsupported"; } -} - -#EOF EpicsHostArch.pl - diff --git a/startup/Site.cshrc b/startup/Site.cshrc deleted file mode 100755 index 24f34abb9..000000000 --- a/startup/Site.cshrc +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/csh -f -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# Site-specific EPICS environment settings -# -# sites should modify these definitions - -# Location of epics base -if ( ! $?EPICS_BASE ) then - set EPICS_BASE=/usr/local/epics/base -endif - -# Location of epics extensions -if ( ! $?EPICS_EXTENSIONS ) then - setenv EPICS_EXTENSIONS /usr/local/epics/extensions -endif - -# Postscript printer definition needed by some extensions (eg medm, dp, dm, ...) -if ( ! $?PSPRINTTER ) then - setenv PSPRINTER lp -endif - -# Needed only by medm extension -#setenv EPICS_DISPLAY_PATH -# Needed only by medm extension -setenv BROWSER firefox - -# Needed only by orbitscreen extension -if ( ! $?ORBITSCREENHOME ) then - setenv ORBITSCREENHOME $EPICS_EXTENSIONS/src/orbitscreen -endif - -# Needed only by adt extension -if ( ! $?ADTHOME ) then - setenv ADTHOME /usr/local/oag/apps/src/appconfig/adt - echo $ADTHOME -endif - -# Needed only by ar extension (archiver) -setenv EPICS_AR_PORT 7002 - -# Needed for java extensions -if ( $?CLASSPATH ) then - setenv CLASSPATH "${CLASSPATH}:${EPICS_EXTENSIONS}/javalib" -else - setenv CLASSPATH "${EPICS_EXTENSIONS}/javalib" -endif - -# Allow private versions of extensions without a bin subdir -if ( $?EPICS_EXTENSIONS_PVT ) then - set path = ( $path $EPICS_EXTENSIONS_PVT) -endif - -################################################################## - -# Start of set R3.14 environment variables - -setenv EPICS_HOST_ARCH `$EPICS_BASE/startup/EpicsHostArch.pl` - -# Allow private versions of base -if ( $?EPICS_BASE_PVT ) then - if ( -e $EPICS_BASE_PVT/bin/$EPICS_HOST_ARCH ) then - set path = ( $path $EPICS_BASE_PVT/bin/$EPICS_HOST_ARCH) - endif -endif - -# Allow private versions of extensions -if ( $?EPICS_EXTENSIONS_PVT ) then - if ( -e $EPICS_EXTENSIONS_PVT/bin/$EPICS_HOST_ARCH ) then - set path = ( $path $EPICS_EXTENSIONS_PVT/bin/$EPICS_HOST_ARCH) - endif -endif -set path = ( $path $EPICS_EXTENSIONS/bin/$EPICS_HOST_ARCH ) - -# End of set R3.14 environment variables -################################################################## diff --git a/startup/Site.profile b/startup/Site.profile deleted file mode 100755 index 677001401..000000000 --- a/startup/Site.profile +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -# Site-specific EPICS environment settings -# -# sites should modify these definitions - -# Location of epics base -if [ -z "${MY_EPICS_BASE}" ] ; then - MY_EPICS_BASE=/usr/local/epics/base -fi - -# Location of epics extensions (medm, msi, etc.) -if [ -z "${EPICS_EXTENSIONS}" ] ; then - EPICS_EXTENSIONS=/usr/local/epics/extensions -fi - -# Postscript printer definition needed by some extensions (eg medm, dp, dm, ...) -if [ -z "${PSPRINTER}" ] ; then - export PSPRINTER=lp -fi - -#Needed only by the idl and ezcaIDL extensions. -#export EPICS_EXTENSIONS - -# Needed only by medm extension -#export EPICS_DISPLAY_PATH=/path/to/adl/files -export BROWSER=firefox - -# Needed only by orbitscreen extension -#if [ -z "${ORBITSCREENHOME}" ] ; then -# export "ORBITSCREENHOME=${EPICS_EXTENSIONS/src/orbitscreen}" -#fi - -# Needed only by adt extension -#if [ -z "${ADTHOME}" ] ; then -# ADTHOME= -# export ADTHOME -#fi - -# Needed only by ar extension (archiver) -#EPICS_AR_PORT=7002 -#export EPICS_AR_PORT - -# Needed for java extensions -if [ -z "${CLASSPATH}" ] ; then - CLASSPATH="${EPICS_EXTENSIONS}/javalib" -else - CLASSPATH="${CLASSPATH}:${EPICS_EXTENSIONS}/javalib" -fi -export CLASSPATH - -# Allow private versions of extensions without a bin subdir -if [ -n "${EPICS_EXTENSIONS_PVT}" ] ; then - PATH="${PATH}:${EPICS_EXTENSIONS_PVT}" -fi - -#--------------------------------------------------------------- -# Start of set R3.14 environment variables -# -EPICS_HOST_ARCH=`"${MY_EPICS_BASE}"/startup/EpicsHostArch.pl` -export EPICS_HOST_ARCH - -# Allow private versions of base -if [ -n "${EPICS_BASE_PVT}" ] ; then - if [ -d "${EPICS_BASE_PVT}/bin/${EPICS_HOST_ARCH}" ]; then - PATH="${PATH}:${EPICS_BASE_PVT}/bin/${EPICS_HOST_ARCH}" - fi -fi - -# Allow private versions of extensions -if [ -n "${EPICS_EXTENSIONS_PVT}" ] ; then - if [ -d "${EPICS_EXTENSIONS_PVT}/bin/${EPICS_HOST_ARCH}" ]; then - PATH="${PATH}:${EPICS_EXTENSIONS_PVT}/bin/${EPICS_HOST_ARCH}" - fi -fi -PATH="${PATH}:${EPICS_EXTENSIONS}/bin/${EPICS_HOST_ARCH}" - -# End of set R3.14 environment variables - -#--------------------------------------------------------------- diff --git a/startup/cygwin.bat b/startup/cygwin.bat deleted file mode 100755 index ff75b5335..000000000 --- a/startup/cygwin.bat +++ /dev/null @@ -1,122 +0,0 @@ -@ECHO OFF -REM ************************************************************************* -REM Copyright (c) 2002 The University of Chicago, as Operator of Argonne -REM National Laboratory. -REM Copyright (c) 2002 The Regents of the University of California, as -REM Operator of Los Alamos National Laboratory. -REM EPICS BASE Versions 3.13.7 -REM and higher are distributed subject to a Software License Agreement found -REM in file LICENSE that is included with this distribution. -REM ************************************************************************* -REM -REM Site-specific EPICS environment settings -REM -REM sites should modify these definitions - -REM ====================================================== -REM ====== REQUIRED ENVIRONMENT VARIABLES FOLLOW ====== -REM ====================================================== - -REM ====================================================== -REM ---------------- WINDOWS --------------------------- -REM ====================================================== -REM ----- WIN95 ----- -REM set PATH=C:\WINDOWS;C:\WINDOWS\COMMAND -REM ----- WINNT, WIN2000 ----- -REM set PATH=C:\WINNT;C:\WINNT\SYSTEM32 -REM ----- WINXP, Vista, Windows 7 ----- -set PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\SYSTEM32\Wbem - -REM ====================================================== -REM ---------------- make and perl --------------------- -REM ====================================================== - -REM --------------- ActiveState perl ------------------- -set PATH=C:\Perl\bin;%PATH% - -REM --------------- mingw make ------------------------ -REM set PATH=C:\mingw-make\bin;%PATH% -REM set PATH=C:\mingw-make82-3\bin;%PATH% - -REM --------------- gnuwin32 make ---------------------- -set PATH=C:\gnuwin32\bin;%PATH% - -REM ====================================================== -REM ---------------- cygwin tools ------------------------ -REM ====================================================== -REM (make & perl if above perl and make are REMs) -REM Dont use cygwin GNU make and Perl! -REM cygwin contains tk/tcl, vim, perl, and many unix tools -REM need grep from here NOT from cvs directory -set PATH=%PATH%;.;.. -set PATH=%PATH%;c:\cygwin\bin - -REM ====================================================== -REM --------------- EPICS -------------------------------- -REM ====================================================== -set EPICS_HOST_ARCH=cygwin-x86 -set PATH=%PATH%;G:\epics\base\bin\%EPICS_HOST_ARCH% -set PATH=%PATH%;G:\epics\extensions\bin\%EPICS_HOST_ARCH% - -REM ====================================================== -REM ------- OPTIONAL ENVIRONMENT VARIABLES FOLLOW -------- -REM ====================================================== - -REM ====================================================== -REM ----------------- remote CVS ------------------------- -REM ====================================================== -REM set CVS_RSH=c:/cygwin/bin/ssh.exe -REM set CVSROOT=:ext:jba@aps.anl.gov:/usr/local/epicsmgr/cvsroot -REM set HOME=c:/users/%USERNAME% -REM set HOME=c:/users/jba - -REM ====================================================== -REM ------------------- Bazaar --------------------------- -REM ====================================================== -set PATH=%PATH%;C:\Program files\Bazaar - -REM ====================================================== -REM ----------------- GNU make flags --------------------- -REM ====================================================== -set MAKEFLAGS=-w - -REM ====================================================== -REM -------------- vim (use cygwin vim ) ----------------- -REM ====================================================== -REM HOME needed by vim to write .viminfo file. -REM VIM needed by vim to find _vimrc file. -REM set VIM=c:\cygwin - -REM ====================================================== -REM --------------- Epics Channel Access ----------------- -REM Modify and uncomment the following lines -REM to override the base/configure/CONFIG_ENV defaults -REM ====================================================== -REM set EPICS_CA_ADDR_LIST=n.n.n.n n.n.n.n -REM set EPICS_CA_AUTO_ADDR_LIST=YES - -REM set EPICS_CA_CONN_TMO=30.0 -REM set EPICS_CA_BEACON_PERIOD=15.0 -REM set EPICS_CA_REPEATER_PORT=5065 -REM set EPICS_CA_SERVER_PORT=5064 -REM set EPICS_TS_MIN_WEST=420 - -REM ====================================================== -REM --------------- JAVA --------------------------------- -REM ====================================================== -REM Needed for java extensions -REM set CLASSPATH=G:\epics\extensions\javalib -REM set PATH=%PATH%;C:\j2sdk1.4.1_01\bin -REM set CLASSPATH=%CLASSPATH%;C:\j2sdk1.4.1_01\lib\tools.jar - -REM ====================================================== -REM --------------- Exceed ------------------------------- -REM Needed for X11 extensions -REM ====================================================== -REM set EX_VER=7.10 -REM set EX_VER=12.00 -REM set EX_VER=14.00 -REM set PATH=%PATH%;C:\Exceed%EX_VER%\XDK\ -REM set PATH=%PATH%;C:\Program Files\Hummingbird\Connectivity\%EX_VER%\Exceed\ - - diff --git a/startup/win32.bat b/startup/win32.bat deleted file mode 100755 index af9155dd7..000000000 --- a/startup/win32.bat +++ /dev/null @@ -1,147 +0,0 @@ -@ECHO OFF -REM ************************************************************************* -REM Copyright (c) 2002 The University of Chicago, as Operator of Argonne -REM National Laboratory. -REM Copyright (c) 2002 The Regents of the University of California, as -REM Operator of Los Alamos National Laboratory. -REM EPICS BASE Versions 3.13.7 -REM and higher are distributed subject to a Software License Agreement found -REM in file LICENSE that is included with this distribution. -REM ************************************************************************* -REM -REM Site-specific EPICS environment settings -REM -REM sites should modify these definitions - -REM ====================================================== -REM ====== REQUIRED ENVIRONMENT VARIABLES FOLLOW ====== -REM ====================================================== - -REM ====================================================== -REM ---------------- WINDOWS --------------------------- -REM ====================================================== -REM ----- WIN95 ----- -REM set PATH=C:\WINDOWS;C:\WINDOWS\COMMAND -REM ----- WINNT, WIN2000 ----- -REM set PATH=C:\WINNT;C:\WINNT\SYSTEM32 -REM ----- WINXP, Vista, Windows 7 ----- -set PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\SYSTEM32\Wbem - -REM ====================================================== -REM ---------------- make and perl --------------------- -REM ====================================================== - -REM --------------- ActiveState perl ------------------- -set PATH=C:\Perl\bin;%PATH% - -REM --------------- mingw make ------------------------ -REM set PATH=C:\mingw-make\bin;%PATH% -REM set PATH=C:\mingw-make82-3\bin;%PATH% - -REM --------------- gnuwin32 make ---------------------- -set PATH=C:\gnuwin32\bin;%PATH% - -REM ====================================================== -REM ---------------- cygwin tools ------------------------ -REM ====================================================== -REM (make & perl if above perl and make are REMs) -REM Dont use cygwin GNU make and Perl! -REM cygwin contains tk/tcl, vim, perl, and many unix tools -REM need grep from here NOT from cvs directory -REM set PATH=%PATH%;.;.. -REM set PATH=%PATH%;c:\cygwin\bin - -REM ====================================================== -REM --------------- Visual c++ ------------------------- -REM ====================================================== - -REM ------ Microsoft Visual Studio 2005 ------ -REM call "C:\Program files\Microsoft Visual Studio 8\VC\vcvarsall.bat" x86_amd64 -REM set PATH=%PATH%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin -REM set INCLUDE=%INCLUDE%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include -REM REM set LIBPATH=%LIBPATH%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib -REM set LIB=%LIB%;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib - -REM ------ Microsoft Visual Studio 2008 ------ -REM call "C:\Program files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat" -REM call "C:\Program files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" x86_amd64 -REM set PATH=C:\Program Files\Microsoft SDKs\Windows\v7.0\bin;%PATH% -REM set INCLUDE=C:\Program Files\Microsoft SDKs\Windows\v7.0\include;%INCLUDE% -REM set LIBPATH=C:\Program Files\Microsoft SDKs\Windows\v7.0\lib;%LIBPATH% -REM set LIB=C:\Program Files\Microsoft SDKs\Windows\v7.0\lib;%LIB% - -REM ----- Visual Studion 2010 ----- -REM -- windows-x64 --- -REM call "C:\Program files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64 -REM -- win32-x86 --- -call "C:\Program files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86 - -REM ====================================================== -REM --------------- EPICS -------------------------------- -REM ====================================================== -REM set EPICS_HOST_ARCH=windows-x64 -set EPICS_HOST_ARCH=win32-x86 -set PATH=%PATH%;G:\epics\base\bin\%EPICS_HOST_ARCH% -set PATH=%PATH%;G:\epics\extensions\bin\%EPICS_HOST_ARCH% - -REM ====================================================== -REM ------- OPTIONAL ENVIRONMENT VARIABLES FOLLOW -------- -REM ====================================================== - -REM ====================================================== -REM ----------------- remote CVS ------------------------- -REM ====================================================== -REM set CVS_RSH=c:/cygwin/bin/ssh.exe -REM set CVSROOT=:ext:jba@aps.anl.gov:/usr/local/epicsmgr/cvsroot -REM set HOME=c:/users/%USERNAME% -REM set HOME=c:/users/jba - -REM ====================================================== -REM ------------------- Bazaar --------------------------- -REM ====================================================== -set PATH=%PATH%;C:\Program files\Bazaar - -REM ====================================================== -REM ----------------- GNU make flags --------------------- -REM ====================================================== -set MAKEFLAGS=-w - -REM ====================================================== -REM -------------- vim (use cygwin vim ) ----------------- -REM ====================================================== -REM HOME needed by vim to write .viminfo file. -REM VIM needed by vim to find _vimrc file. -REM set VIM=c:\cygwin - -REM ====================================================== -REM --------------- Epics Channel Access ----------------- -REM Modify and uncomment the following lines -REM to override the base/configure/CONFIG_ENV defaults -REM ====================================================== -REM set EPICS_CA_ADDR_LIST=n.n.n.n n.n.n.n -REM set EPICS_CA_AUTO_ADDR_LIST=YES - -REM set EPICS_CA_CONN_TMO=30.0 -REM set EPICS_CA_BEACON_PERIOD=15.0 -REM set EPICS_CA_REPEATER_PORT=5065 -REM set EPICS_CA_SERVER_PORT=5064 -REM set EPICS_TS_MIN_WEST=420 - -REM ====================================================== -REM --------------- JAVA --------------------------------- -REM ====================================================== -REM Needed for java extensions -REM set CLASSPATH=G:\epics\extensions\javalib -REM set PATH=%PATH%;C:\j2sdk1.4.1_01\bin -REM set CLASSPATH=%CLASSPATH%;C:\j2sdk1.4.1_01\lib\tools.jar - -REM ====================================================== -REM --------------- Exceed ------------------------------- -REM Needed for X11 extensions -REM ====================================================== -REM set EX_VER=7.10 -REM set EX_VER=12.00 -REM set EX_VER=14.00 -REM set PATH=%PATH%;C:\Exceed%EX_VER%\XDK\ -REM set PATH=%PATH%;C:\Program Files\Hummingbird\Connectivity\%EX_VER%\Exceed\ -