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..ecb1c9d89 100644 --- a/configure/CONFIG +++ b/configure/CONFIG @@ -1,117 +1,32 @@ -#************************************************************************* -# 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 +CONFIG = $(RULES)/configure +include $(CONFIG)/CONFIG -# 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) +# Override the Base definition: +INSTALL_LOCATION = $(TOP) +# Set location of locally generated tools +EYACC = $(INSTALL_HOST_BIN)/antelope$(HOSTEXE) +ELEX = $(INSTALL_HOST_BIN)/e_flex$(HOSTEXE) -S$(INSTALL_INCLUDE)/flex.skel.static +# 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 65e62dfb1..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 = $(wildcard $(GNU_TARGET:%=$(GNU_DIR)/%/include)) -GNU_TARGET_LIB_DIR = $(wildcard $(GNU_TARGET:%=$(GNU_DIR)/%/lib)) - -CROSS_INCLUDES = $(GNU_TARGET_INCLUDE_DIR:%=-I%) -CROSS_LDFLAGS = $(GNU_TARGET_LIB_DIR:%=-L%) - -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 c11f54e21..000000000 --- a/configure/CONFIG_SITE_ENV +++ /dev/null @@ -1,98 +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. The format is -# :::: -# where the start and end are mmddhh - that is month,day,hour -# e.g. for ANL in 2018: EPICS_TIMEZONE=CUS::360:031102:110402 -# The future dates below assume the rules don't get changed; -# see http://www.timeanddate.com/time/dst/2018.html to check. -# -# DST for 2017 US: Mar 12 - Nov 05 -# EU: Mar 26 - Oct 29 -EPICS_TIMEZONE = CUS::360:031202:110502 -#EPICS_TIMEZONE = MET::-60:032602:102902 -# -# DST for 2018 US: Mar 11 - Nov 04 -# EU: Mar 25 - Oct 28 -#EPICS_TIMEZONE = CUS::360:031102:110402 -#EPICS_TIMEZONE = MET::-60:032502:102802 -# -# DST for 2019 US: Mar 10 - Nov 03 -# EU: Mar 31 - Oct 27 -#EPICS_TIMEZONE = CUS::360:031002:110302 -#EPICS_TIMEZONE = MET::-60:033102:102702 -# -# DST for 2020 US: Mar 08 - Nov 01 -# EU: Mar 29 - Oct 25 -#EPICS_TIMEZONE = CUS::360:030802:110102 -#EPICS_TIMEZONE = MET::-60:032902:102502 -# -# DST for 2021 US: Mar 14 - Nov 07 -# EU: Mar 28 - Oct 31 -#EPICS_TIMEZONE = CUS::360:031402:110702 -#EPICS_TIMEZONE = MET::-60:032802:103102 -# -# DST for 2022 US: Mar 13 - Nov 06 -# EU: Mar 27 - Oct 30 -#EPICS_TIMEZONE = CUS::360:031302:110602 -#EPICS_TIMEZONE = MET::-60:032702:103002 - -# EPICS_TS_NTP_INET -# NTP time server ip address for VxWorks and RTEMS. -# IOC will use its boot host if this is 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..dd260766b 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/user/epics-base-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 ea84db8be..000000000 --- a/configure/RULES_BUILD +++ /dev/null @@ -1,530 +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) - -#--------------------------------------------------------------- - -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 462320f66..000000000 --- a/configure/os/CONFIG.Common.linux-xscale_be +++ /dev/null @@ -1,28 +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 = $(GNU_TARGET:%=%-) - - # Configure for readline if requested - OP_SYS_INCLUDES += $(READLINE_DIR:%=-I%/include) - READLINE_LDFLAGS = $(READLINE_DIR:%=-L%/lib) - RUNTIME_LDFLAGS_READLINE_YES_NO = $(READLINE_DIR:%=-Wl,-rpath,%/lib) - RUNTIME_LDFLAGS += \ - $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)_$(STATIC_BUILD)) - SHRLIBDIR_LDFLAGS += $(READLINE_LDFLAGS) - PRODDIR_LDFLAGS += $(READLINE_LDFLAGS) -endif diff --git a/configure/os/CONFIG.Common.linuxCommon b/configure/os/CONFIG.Common.linuxCommon deleted file mode 100644 index 965de09b8..000000000 --- a/configure/os/CONFIG.Common.linuxCommon +++ /dev/null @@ -1,46 +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 if USE_RPATH=YES and STATIC_BUILD=NO -SHRLIBDIR_RPATH_LDFLAGS_YES_NO = $(SHRLIB_DEPLIB_DIRS:%=-Wl,-rpath,%) -SHRLIBDIR_LDFLAGS += \ - $(SHRLIBDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)_$(STATIC_BUILD)) - -# Set runtime path for products if USE_RPATH=YES and STATIC_BUILD=NO -PRODDIR_RPATH_LDFLAGS_YES_NO = $(PROD_DEPLIB_DIRS:%=-Wl,-rpath,%) -PRODDIR_LDFLAGS += \ - $(PRODDIR_RPATH_LDFLAGS_$(LINKER_USE_RPATH)_$(STATIC_BUILD)) - -# 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 e7be9fae0..000000000 --- a/configure/os/CONFIG.Common.vxWorksCommon +++ /dev/null @@ -1,177 +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) - -#-------------------------------------------------- -# This finds nm on any supported VxWorks version - -NMPROG = $(CMPLR_PREFIX)nm$(CMPLR_SUFFIX)$(HOSTEXE) -NM = $(firstword $(wildcard $(WIND_BASE)/*/$(WIND_HOST_TYPE)/bin/$(NMPROG))) - -#-------------------------------------------------- -# 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_HOME = $(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 -CROSS_LDFLAGS = -# -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 63bd5d8be..000000000 --- a/configure/os/CONFIG.linux-x86.linux-arm +++ /dev/null @@ -1,28 +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 readline if needed -OP_SYS_INCLUDES += $(READLINE_DIR:%=-I%/include) -READLINE_LDFLAGS = $(READLINE_DIR:%=-L%/lib) -RUNTIME_LDFLAGS_READLINE_YES_NO = $(READLINE_DIR:%=-Wl,-rpath,%/lib) -RUNTIME_LDFLAGS += \ - $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)_$(STATIC_BUILD)) -SHRLIBDIR_LDFLAGS += $(READLINE_LDFLAGS) -PRODDIR_LDFLAGS += $(READLINE_LDFLAGS) - -# 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 015229647..000000000 --- a/configure/os/CONFIG_SITE.Common.linux-xscale_be +++ /dev/null @@ -1,4 +0,0 @@ -# CONFIG_SITE.Common.linux-xscale_be -# -# Site specific definitions for all linux-xscale_be target builds. -#------------------------------------------------------- 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 0b0654aeb..000000000 --- a/configure/os/CONFIG_SITE.Common.vxWorksCommon +++ /dev/null @@ -1,25 +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/tornado22-$(ARCH_CLASS) -WIND_BASE = /usr/local/vw/vxWorks-$(VXWORKS_VERSION) -#WIND_BASE = /ade/vxWorks/$(VXWORKS_VERSION) 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 a1edb423d..000000000 --- a/configure/os/CONFIG_SITE.linux-x86.linux-arm +++ /dev/null @@ -1,31 +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 -# Examples are installations at the APS: -GNU_DIR = /usr/local/vw/zynq-2011.09 -#GNU_DIR = /usr/local/Xilinx/SDK/2016.3/gnu/arm/lin -#GNU_DIR = /APSshare/XilinxSDK/2015.4/gnu/arm/lin - -# If cross-building shared libraries and the paths on the target machine are -# different than on the build host, you should uncomment the lines below to -# disable putting runtime library paths in products and shared libraries. -# You will also need to provide another way for programs to find their shared -# libraries at runtime, such as by setting LD_LIBRARY_PATH or by using -# mechanisms related to /etc/ld.so.conf -#SHRLIBDIR_RPATH_LDFLAGS_YES_NO = -#PRODDIR_RPATH_LDFLAGS_YES_NO = -# Note: It may be simpler to just set STATIC_BUILD=YES here and not -# try to use shared libraries at all in these circumstances. - -# To use libreadline, point this to its install prefix -#READLINE_DIR = $(GNU_DIR) -#READLINE_DIR = /tools/cross/linux-x86.linux-arm/readline -# See CONFIG_SITE.Common.linux-arm for other COMMANDLINE_LIBRARY values -#COMMANDLINE_LIBRARY = READLINE - 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/libCom/Com.rc b/src/Com.rc similarity index 100% rename from src/libCom/Com.rc rename to src/Com.rc diff --git a/src/Makefile b/src/Makefile index 257099840..8143ad5ba 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,80 +1,65 @@ #************************************************************************* -# Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne +# 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. +# in file LICENSE that is included with this distribution. #************************************************************************* TOP = .. include $(TOP)/configure/CONFIG -DIRS += tools +# Uncomment this to remove the (benign) valgrind helper stubs +#USR_CFLAGS += -DNVALGRIND -DIRS += tools/test -tools/test_DEPEND_DIRS = tools +LIBCOM = $(TOP)/src -DIRS += template/base -template/base_DEPEND_DIRS = tools +INC += valgrind/valgrind.h -DIRS += template/ext -template/ext_DEPEND_DIRS = tools +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 -# Common +# Library to build: +LIBRARY=Com -DIRS += libCom -libCom_DEPEND_DIRS = tools +Com_SYS_LIBS_WIN32 = ws2_32 advapi32 user32 -DIRS += libCom/RTEMS -libCom/RTEMS_DEPEND_DIRS = libCom +Com_RCS = Com.rc -DIRS += libCom/test -libCom/test_DEPEND_DIRS = libCom/RTEMS +ifeq ($(T_A),$(EPICS_HOST_ARCH)) + # Antelope & flex are needed to finish libCom + DELAY_INSTALL_LIBS = YES +endif -# 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 +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/as/Makefile b/src/as/Makefile similarity index 100% rename from src/libCom/as/Makefile rename to src/as/Makefile diff --git a/src/libCom/as/RULES b/src/as/RULES similarity index 83% rename from src/libCom/as/RULES rename to src/as/RULES index a2a416f6e..f693cf37d 100644 --- a/src/libCom/as/RULES +++ b/src/as/RULES @@ -6,7 +6,7 @@ # Copyright (c) 2002 The Regents of the University of California, as # Operator of Los Alamos National Laboratory. # EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. +# in file LICENSE that is included with this distribution. #************************************************************************ # This is a Makefile fragment, see src/libCom/Makefile. @@ -16,6 +16,6 @@ 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.c: $(INSTALL_HOST_BIN)/antelope$(HOSTEXE) +asLib_lex.c: $(INSTALL_HOST_BIN)/e_flex$(HOSTEXE) asLib_lex.c: $(INSTALL_INCLUDE)/flex.skel.static diff --git a/src/libCom/as/asLib.h b/src/as/asLib.h similarity index 100% rename from src/libCom/as/asLib.h rename to src/as/asLib.h diff --git a/src/libCom/as/asLib.y b/src/as/asLib.y similarity index 100% rename from src/libCom/as/asLib.y rename to src/as/asLib.y diff --git a/src/libCom/as/asLibRoutines.c b/src/as/asLibRoutines.c similarity index 100% rename from src/libCom/as/asLibRoutines.c rename to src/as/asLibRoutines.c diff --git a/src/libCom/as/asLib_lex.l b/src/as/asLib_lex.l similarity index 100% rename from src/libCom/as/asLib_lex.l rename to src/as/asLib_lex.l diff --git a/src/libCom/as/asTrapWrite.c b/src/as/asTrapWrite.c similarity index 100% rename from src/libCom/as/asTrapWrite.c rename to src/as/asTrapWrite.c diff --git a/src/libCom/as/asTrapWrite.h b/src/as/asTrapWrite.h similarity index 100% rename from src/libCom/as/asTrapWrite.h rename to src/as/asTrapWrite.h diff --git a/src/libCom/bucketLib/Makefile b/src/bucketLib/Makefile similarity index 100% rename from src/libCom/bucketLib/Makefile rename to src/bucketLib/Makefile diff --git a/src/libCom/bucketLib/bucketLib.c b/src/bucketLib/bucketLib.c similarity index 100% rename from src/libCom/bucketLib/bucketLib.c rename to src/bucketLib/bucketLib.c diff --git a/src/libCom/bucketLib/bucketLib.h b/src/bucketLib/bucketLib.h similarity index 100% rename from src/libCom/bucketLib/bucketLib.h rename to src/bucketLib/bucketLib.h 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 72044bd49..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 */ - "%d" /* dec */, - "0" /* bin and val is 0 */, - "0o%o" /* oct */, - "0x%X" /* hex */ - }; - - /* dbr_long_t is actually an int on all supported platforms */ - sprintf(ret, fmt[outType], (int) 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/ca/legacy/gdd/Makefile deleted file mode 100644 index 335d49001..000000000 --- a/src/ca/legacy/gdd/Makefile +++ /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 is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -INC += gdd.h -INC += gddI.h -INC += gddContainer.h -INC += gddContainerI.h -INC += gddArray.h -INC += gddArrayI.h -INC += gddScalar.h -INC += gddScalarI.h -INC += gddNewDel.h -INC += gddUtils.h -INC += gddUtilsI.h -INC += gddErrorCodes.h -INC += aitTypes.h -INC += aitConvert.h -INC += aitHelpers.h -INC += dbMapper.h -INC += gddAppTable.h -INC += gddAppFuncTable.h -INC += smartGDDPointer.h -INC += gddEnumStringTable.h - -# Can't put this in INC, it causes a circular build dependency -TARGETS += $(INSTALL_INCLUDE)/gddApps.h - -HTMLS += gdd.html -HTMLS += gddref.html -HTMLS += gddref2.html - -GDDSRCS = gdd.cc gddTest.cc gddAppTable.cc gddNewDel.cc \ - gddAppDefs.cc aitTypes.c aitConvert.cc aitHelpers.cc \ - gddArray.cc gddContainer.cc gddErrorCodes.cc gddUtils.cc \ - gddEnumStringTable.cc - -LIBRARY = gdd - -gdd_SRCS = dbMapper $(GDDSRCS) - -gdd_LIBS = Com - -gdd_RCS = gdd.rc - -PROD_HOST += genApps -genApps_SRCS = genApps.cc $(GDDSRCS) -genApps_SYS_LIBS_WIN32 = ws2_32 - -PROD_LIBS = Com - -PROD_HOST += aitGen -aitGen_SRCS = aitTypes.c aitGen.c - -# aitGen.c doesn't compile for linux-arm at -O3 when using gcc-3.4.5 -aitGen_CFLAGS_linux-arm = -O2 - -CLEANS += $(COMMON_DIR)/aitConvertGenerated.cc - -USR_CXXFLAGS_Linux = -fno-strict-aliasing -USR_CXXFLAGS_RTEMS = -fno-strict-aliasing -USR_CXXFLAGS_vxWorks = -fno-strict-aliasing - -ifeq ($(T_A),$(EPICS_HOST_ARCH)) - # genApps and aitGen are needed to finish libgdd - DELAY_INSTALL_LIBS = YES -endif - -include $(TOP)/configure/RULES - -# Manual dependencies -# -aitConvert$(DEP): $(COMMON_DIR)/aitConvertGenerated.cc -aitConvert$(OBJ): $(COMMON_DIR)/aitConvertGenerated.cc -dbMapper$(DEP): $(COMMON_DIR)/gddApps.h - -# Rules for generated files -# -$(COMMON_DIR)/aitConvertGenerated.cc: $(EPICS_BASE_HOST_BIN)/aitGen$(HOSTEXE) - $(TOOLS)/aitGen$(HOSTEXE) $@ - -$(COMMON_DIR)/gddApps.h : $(EPICS_BASE_HOST_BIN)/genApps$(HOSTEXE) - $(TOOLS)/genApps$(HOSTEXE) $@ - diff --git a/src/ca/legacy/gdd/README b/src/ca/legacy/gdd/README deleted file mode 100644 index 4c5dd4094..000000000 --- a/src/ca/legacy/gdd/README +++ /dev/null @@ -1,158 +0,0 @@ -# -# Author: Jim Kowalkowski -# Date: 2/96 -# - -Some Notes: - -****** -The following function described in gddAppTable.h and defined in gddAppDefs.cc: - - gddApplicationTypeTable* gddGenerateApplicationTypeTable(void); - -is designed to be called in an application to create the type table -with a default set of attributes already registered. The current mechanism -for generating the default registered attributes is the C++ code in -gddAppDefs.cc. See this file for a list of registered attributes. - -Creating am application type table using new will perform the same function. - -****** -The gddCleanUp object will automatically clean up the free list storage -when it is destructed. There should only be one of these in an application. -It is not required. - -****** -To build for vxWorks, define an environment variable "VX_BUILD=vw" and type -make. It will build for the HOST_ARCH architecture and then vxWorks. - -You must have gcc/g++ 2.5.8 or later available to cross compile to 68k object -code and vxWorks. You can get the gcc 2.5.8 package from the HiDEOS home -page along with instructions on building it. - -The vxldscript.MRI file instructs the gnu loader on how to propare -object files to load under vxWorks. - -You must use the ldpp program under vxWorks shell to load g++ generated -object modules. The ldpp program is available in the EPICS base package. -Contact me if you want a copy of it. - -It is really not difficult to get g++ object files to load under vxWorks -or to get the g++ compiled installed and running. The makefile is set up -to handle builds for vxWorks. - -****** -aitTypes.h: Definitions of the architecture independant types. -aitTypes.c: definitions of several lookup tables -aitConvert.h: conversion table description,byte ordering routines -aitConvert.c: conversion information not generated -aitGen.c: creates the general conversion functions -aitConvertGenerated.c: file of generated conversion functions - -dbMapper.cc: mappings from DBR types to ait types and GDDs -dbMapper.h: mappings from DBR types to ait types and GDDs - -gddApps.h: - This file contains "#define" statements for quick indexing into - managed containers. Generated by program genApps.cc. - -******* -Still needed: - -1) AppTable method to map application type to offset (index) into a - managed container. -* mostly complete - -2) Function to map DBRxxxx types to Application types and back. -* still working on mapping method - -3) Methods for managing network byte order conversions in gdd class. - -4) Method to extract data (and bounds information) from a gdd into a - user's buffer. - -6) #defines to remove extra checks and make the programs run faster. - -************ 6/13/96 ************* - -ref_cnt should be an unsigned short instead of char - -menus need to be fixed - use aitFixedString or aitString - -get/operator=() should be smarter, do conversion if types do not match - -************ 6/20/96 ************** - -fix the flatten functions so they work properly with aitString and fixed -string - -fix the aitString class, add the install string method and change others - -*********** 6/21/96 ************ - -fixe the aitString::compact function, and all other stuff that works with -string info so that if the string that the aitString is holding is NULL, -then the system will act correctly. The flatten functions have trouble -with this when the described string is NULL. - -*********** 6/24/96 ************* - -still need to fix the transfer of aitString data into a pre-made gdd. -If only array of 5 aitString is placed into a pre-made array of 16, -then the last 11 should be initialized to NULLs or something, same for -fixed string - especially the fixed string - -************** 6/26/96 ************ - -aitString:copy() still has troubles. Need to correct the -aitConvertStringFloat64() and others. How are they supposed to work? -Should they be calling aitString::installString() instead of copy()? Yes, -that is the answer. In the convert functions, the temp variable -used to hold a value (character value) is always a stack variable and -needs to be copied. Maybe the temp char variable should be copied over -the existing string if it will fit. No. - -************** 8/28/96 **************** - -network/host byte ordering issue: - -Change isNetworkByteOrder() in class gdd to: - isLocalDataFormat() - true if data format is local host format - isNetworkDataFormat() - true if data format is network format - - Both the above can be true at the same time if local host data format - is the same as network data format - -Add method to class gdd: - markLocalDataFormat() - markNotLocalDataFormat() - -Modify putRef() functions of gdd class: - add third argument to specify the byte order that data is in. - default mode to local data format. this turns out to be ugly - because the second argument (gddDestructor*) defaults to NULL. - But this is probably OK, since this will not be used often. - -Modify getRef() functions of gdd class: - add another argument that specifies the data format the user desires. - default to local data format, first access to an array that is not - in the correct format will cause the entire array to be converted - to the desired format. - -putConvert() and getConvert() notes: - getConvert will always return values in local data format - putConvert will always take local data format values as arguments - -put() and get() notes: - get always returns data in local data format - put always takes data in local data format - -Modify dbMapper.cc: - add dbMapperToDbrMode({to_network_byte_order,keep_in_local_order}) - change all function to honor this mode setting - any gdd converted to a dbr type could be change to network byte order - depending on this mode. - -Jim - - diff --git a/src/ca/legacy/gdd/aitConvert.cc b/src/ca/legacy/gdd/aitConvert.cc deleted file mode 100644 index b2a4e42e3..000000000 --- a/src/ca/legacy/gdd/aitConvert.cc +++ /dev/null @@ -1,449 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 -// Date: 2/96 -// - -#define AIT_CONVERT_SOURCE 1 - -#include -#include -#include -#include -#include "epicsStdio.h" -#include "cvtFast.h" - -#define epicsExportSharedSymbols -#include "aitConvert.h" - -int aitNoConvert(void* /*dest*/,const void* /*src*/,aitIndex /*count*/, const gddEnumStringTable *) {return -1;} - -#ifdef AIT_CONVERT -#undef AIT_CONVERT -#endif -#ifdef AIT_TO_NET_CONVERT -#undef AIT_TO_NET_CONVERT -#endif -#ifdef AIT_FROM_NET_CONVERT -#undef AIT_FROM_NET_CONVERT -#endif - -/* put the fixed conversion functions here (ones not generated) */ - -bool getStringAsDouble ( const char * pString, - const gddEnumStringTable * pEST, double & result ) -{ - if ( ! pString ) { - return false; - } - double ftmp; - unsigned itmp; - if ( pEST && pEST->getIndex ( pString, itmp ) ) { - ftmp = itmp; - } - else { - int j = epicsScanDouble( pString, &ftmp ); - if ( j != 1 ) { - j = sscanf ( pString,"%x", &itmp ); - if ( j == 1 ) { - ftmp = itmp; - } - else { - return false; - } - } - } - result = ftmp; - return true; -} - -bool putDoubleToString ( - const double in, const gddEnumStringTable * pEST, - char * pString, size_t strSize ) -{ - if ( strSize <= 1u ) { - return false; - } - if ( pEST && in >= 0 && in <= UINT_MAX ) { - unsigned utmp = static_cast < unsigned > ( in ); - pEST->getString ( utmp, pString, strSize ); - if ( pString[0] != '\0' ) { - return true; - } - } -#if 1 - bool cvtDoubleToStringInRange = - ( in < 1.e4 && in > 1.e-4 ) || - ( in > -1.e4 && in < -1.e-4 ) || - in == 0.0; - // conservative - static const unsigned cvtDoubleToStringSizeMax = 15; - int nChar; - if ( cvtDoubleToStringInRange && - strSize > cvtDoubleToStringSizeMax ) { - nChar = cvtDoubleToString ( in, pString, 4 ); - } - else { - nChar = epicsSnprintf ( - pString, strSize-1, "%g", in ); - } - if ( nChar < 1 ) { - return false; - } - assert ( size_t(nChar) < strSize ); -#else - int nChar = epicsSnprintf ( - pString, strSize-1, "%g", in ); - if ( nChar <= 0 ) { - return false; - } -#endif - size_t nCharU = static_cast < size_t > ( nChar ); - nChar = epicsMin ( nCharU, strSize-1 ) + 1; - memset ( &pString[nChar], '\0', strSize - nChar ); - return true; -} - -/* ------- extra string conversion functions --------- */ -static int aitConvertStringString(void* d,const void* s, - aitIndex c, const gddEnumStringTable *) -{ - // does not work - need to be fixed - aitIndex i; - aitString *in=(aitString*)s, *out=(aitString*)d; - - for(i=0;inumberOfStrings() ) { - unsigned nChar = pEnumStringTable->getStringLength ( in[i] ); - if ( nChar < static_cast ( INT_MAX - status ) ) { - out[i].copy( pEnumStringTable->getString ( in[i] ), nChar ); - status += static_cast ( nChar );; - } - else { - return -1; - } - } - else { - char temp[AIT_FIXED_STRING_SIZE]; - int tmpStatus = sprintf ( temp, "%hu", in[i] ); - if ( tmpStatus >= 0 && tmpStatus < INT_MAX - status ) { - out[i].copy ( temp, static_cast < unsigned > ( tmpStatus ) ); - status += tmpStatus; - } - else { - return -1; - } - } - } - return status; -} - -#ifdef AIT_NEED_BYTE_SWAP -static int aitConvertToNetStringEnum16(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - return aitConvertStringEnum16(d,s,c,pEnumStringTable); -} - -static int aitConvertFromNetStringEnum16(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - return aitConvertStringEnum16(d,s,c,pEnumStringTable); -} -#endif - -static int aitConvertFixedStringEnum16(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - aitIndex i; - int status=0; - aitFixedString* out=(aitFixedString*)d; - aitEnum16* in=(aitEnum16*)s; - for (i=0;inumberOfStrings() ) { - unsigned nChar = pEnumStringTable->getStringLength ( in[i] ); - if ( nChar < static_cast < unsigned > ( INT_MAX - status ) ) { - pEnumStringTable->getString ( - in[i], - out[i].fixed_string, - sizeof( out[i].fixed_string ) ); - status += static_cast < int > ( nChar ); - } - else { - return -1; - } - } - else { - int tmpStatus = sprintf ( out[i].fixed_string, "%hu", in[i] ); - if ( tmpStatus > 0 && tmpStatus < INT_MAX - status ) { - status += tmpStatus; - } - else { - return -1; - } - } - } - return status; -} - -#ifdef AIT_NEED_BYTE_SWAP -static int aitConvertToNetFixedStringEnum16(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - return aitConvertFixedStringEnum16(d,s,c,pEnumStringTable); -} - -static int aitConvertFromNetFixedStringEnum16(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - return aitConvertFixedStringEnum16(d,s,c,pEnumStringTable); -} -#endif - -static int aitConvertEnum16FixedString (void* d,const void* s,aitIndex c, - const gddEnumStringTable *pEnumStringTable) -{ - aitIndex i; - int status = 0; - aitEnum16* out = (aitEnum16*)d; - aitFixedString* in = (aitFixedString*)s; - aitEnum16 choice, nChoices; - - // - // convert only after a range check - // - if ( pEnumStringTable ) { - assert (pEnumStringTable->numberOfStrings()<=0xffff); - nChoices = static_cast(pEnumStringTable->numberOfStrings()); - } - else { - nChoices = 0; - } - - for (i=0;igetString(choice), in[i].fixed_string)==0) { - out[i] = choice; - status += sizeof(out[i]); - break; - } - } - // - // if no string matches then look for a numeric match - // - if (choice>=nChoices) { - int temp; - if ( sscanf ( in[i].fixed_string,"%i", &temp ) == 1 ) { - if ( temp >= 0 && temp < nChoices ) { - out[i] = (aitUint16) temp; - status += sizeof(out[i]); - } - else { - // - // no match, return an error - // - return -1; - } - } - else { - return -1; - } - } - } - return status; -} - -#ifdef AIT_NEED_BYTE_SWAP -static int aitConvertToNetEnum16FixedString(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - return aitConvertEnum16FixedString(d,s,c,pEnumStringTable); -} - -static int aitConvertFromNetEnum16FixedString(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - return aitConvertEnum16FixedString(d,s,c,pEnumStringTable); -} -#endif - -static int aitConvertEnum16String (void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - aitIndex i; - int status = 0; - aitEnum16* out = (aitEnum16*)d; - aitString* in = (aitString*)s; - aitEnum16 choice, nChoices; - - // - // convert only after a range check - // - if ( pEnumStringTable ) { - assert (pEnumStringTable->numberOfStrings()<=0xffff); - nChoices = static_cast(pEnumStringTable->numberOfStrings()); - } - else { - nChoices = 0u; - } - - for (i=0;igetString(choice), in[i].string())==0) { - out[i] = choice; - status += sizeof(out[i]); - break; - } - } - // - // if no string matches then look for a numeric match - // - if (choice>=nChoices) { - int temp; - if ( sscanf ( in[i].string(),"%i", &temp ) == 1 ) { - if ( temp >= 0 && temp < nChoices ) { - out[i] = (aitUint16) temp; - status += sizeof(out[i]); - } - else { - // - // no match, return an error - // - return -1; - } - } - else { - return -1; - } - } - } - return status; -} - -#ifdef AIT_NEED_BYTE_SWAP -static int aitConvertToNetEnum16String(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - return aitConvertEnum16String(d,s,c,pEnumStringTable); -} - -static int aitConvertFromNetEnum16String(void* d,const void* s, - aitIndex c, const gddEnumStringTable *pEnumStringTable) -{ - return aitConvertEnum16String(d,s,c,pEnumStringTable); -} -#endif - -#define AIT_CONVERT 1 -#include "aitConvertGenerated.cc" -#undef AIT_CONVERT - -/* include the network byte order functions if needed */ -#ifdef AIT_NEED_BYTE_SWAP - -#define AIT_TO_NET_CONVERT 1 -#include "aitConvertGenerated.cc" -#undef AIT_TO_NET_CONVERT - -#define AIT_FROM_NET_CONVERT 1 -#include "aitConvertGenerated.cc" -#undef AIT_FROM_NET_CONVERT - -#endif - diff --git a/src/ca/legacy/gdd/aitConvert.h b/src/ca/legacy/gdd/aitConvert.h deleted file mode 100644 index 6571df44e..000000000 --- a/src/ca/legacy/gdd/aitConvert.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. -\*************************************************************************/ -#ifndef AIT_CONVERT_H__ -#define AIT_CONVERT_H__ - -/* - * Author: Jim Kowalkowski - * Date: 2/96 - */ - -#include - -#if defined(_MSC_VER) && _MSC_VER < 1200 -# pragma warning ( push ) -# pragma warning ( disable:4786 ) -#endif - -#include "shareLib.h" -#include "osiSock.h" - -#include "aitTypes.h" -#include "gddEnumStringTable.h" - -#if defined(__i386) || defined(i386) -#define AIT_NEED_BYTE_SWAP 1 -#endif - -#ifdef AIT_NEED_BYTE_SWAP -#define aitLocalNetworkDataFormatSame 0 -#else -#define aitLocalNetworkDataFormatSame 1 -#endif - -typedef enum { aitLocalDataFormat=0, aitNetworkDataFormat } aitDataFormat; - -/* all conversion functions have this prototype */ -typedef int (*aitFunc)(void* dest,const void* src,aitIndex count,const gddEnumStringTable *pEnumStringTable); - -#ifdef __cplusplus -extern "C" { -#endif - -/* main conversion table */ -epicsShareExtern aitFunc aitConvertTable[aitTotal][aitTotal]; -/* do not make conversion table if not needed */ -#ifdef AIT_NEED_BYTE_SWAP -epicsShareExtern aitFunc aitConvertToNetTable[aitTotal][aitTotal]; -epicsShareExtern aitFunc aitConvertFromNetTable[aitTotal][aitTotal]; -#else -#define aitConvertToNetTable aitConvertTable -#define aitConvertFromNetTable aitConvertTable -#endif /* AIT_NEED_BYTE_SWAP */ - -#ifdef __cplusplus -} -#endif - -/* ---------- convenience routines for performing conversions ---------- */ - -#if defined(__cplusplus) - -inline int aitConvert(aitEnum desttype, void* dest, - aitEnum srctype, const void* src, aitIndex count, - const gddEnumStringTable *pEnumStringTable = 0 ) - { return (*aitConvertTable[desttype][srctype])(dest,src,count,pEnumStringTable); } - -inline int aitConvertToNet(aitEnum desttype, void* dest, - aitEnum srctype, const void* src, aitIndex count, - const gddEnumStringTable *pEnumStringTable = 0 ) - { return (*aitConvertToNetTable[desttype][srctype])(dest,src,count,pEnumStringTable); } - -inline int aitConvertFromNet(aitEnum desttype, void* dest, - aitEnum srctype, const void* src, aitIndex count, - const gddEnumStringTable *pEnumStringTable = 0 ) - { return (*aitConvertFromNetTable[desttype][srctype])(dest,src,count,pEnumStringTable); } - -#else - -#define aitConvert(DESTTYPE,DEST,SRCTYPE,SRC,COUNT) \ - (*aitConvertTable[DESTTYPE][SRCTYPE])(DEST,SRC,COUNT) - -#define aitConvertToNet(DESTTYPE,DEST,SRCTYPE,SRC,COUNT) \ - (*aitConvertToNetTable[DESTTYPE][SRCTYPE])(DEST,SRC,COUNT) - -#define aitConvertFromNet(DESTTYPE,DEST,SRCTYPE,SRC,COUNT) \ - (*aitConvertFromNetTable[DESTTYPE][SRCTYPE])(DEST,SRC,COUNT) - -#endif - -/* ----------- byte order conversion definitions ------------ */ - -#define aitUint64 aitUint32 - -#if defined(__cplusplus) - -inline void aitToNetOrder16(aitUint16* dest,aitUint16* src) - { *dest=htons(*src); } -inline void aitToNetOrder32(aitUint32* dest,aitUint32* src) - { *dest=htonl(*src); } -inline void aitFromNetOrder16(aitUint16* dest,aitUint16* src) - { *dest=ntohs(*src); } -inline void aitFromNetOrder32(aitUint32* dest,aitUint32* src) - { *dest=ntohl(*src); } -inline void aitToNetOrder64(aitUint64* dest, aitUint64* src) -{ - aitUint32 ait_temp_var_; - ait_temp_var_=(aitUint32)htonl(src[1]); - dest[1]=(aitUint32)htonl(src[0]); - dest[0]=ait_temp_var_; -} -inline void aitFromNetOrder64(aitUint64* dest, aitUint64* src) -{ - aitUint32 ait_temp_var_; - ait_temp_var_=(aitUint32)ntohl(src[1]); - dest[1]=(aitUint32)ntohl(src[0]); - dest[0]=ait_temp_var_; -} - -#else - -/* !The following generate code! */ -#define aitToNetOrder16(dest,src) (*(dest)=htons(*(src))) -#define aitToNetOrder32(dest,src) (*(dest)=htonl(*(src))) -#define aitFromNetOrder16(dest,src) (*(dest)=ntohs(*(src))) -#define aitFromNetOrder32(dest,src) (*(dest)=ntohl(*(src))) - -/* be careful using these because of brackets, these should be functions */ -#define aitToNetOrder64(dest,src) \ -{ \ - aitUint32 ait_temp_var_; \ - ait_temp_var_=(aitUint32)htonl((src)[1]); \ - (dest)[1]=(aitUint32)htonl((src)[0]); \ - (dest)[0]=ait_temp_var_; \ -} -#define aitFromNetOrder64(dest,src) \ -{ \ - aitUint32 ait_temp_var_; \ - ait_temp_var_=(aitUint32)ntohl((src)[1]); \ - (dest)[1]=(aitUint32)ntohl((src)[0]); \ - (dest)[0]=ait_temp_var_; \ -} - -#endif /* __cpluspluc */ - -#define aitToNetFloat64 aitToNetOrder64 -#define aitToNetFloat32 aitToNetOrder32 -#define aitFromNetFloat64 aitFromNetOrder64 -#define aitFromNetFloat32 aitFromNetOrder32 - -bool getStringAsDouble ( const char * pString, - const gddEnumStringTable *pEST, double & result ); - -bool putDoubleToString ( - const double in, const gddEnumStringTable * pEST, - char * pString, size_t strSize ); - -#if defined ( _MSC_VER ) && _MSC_VER < 1200 -# pragma warning ( pop ) -#endif - -#endif - diff --git a/src/ca/legacy/gdd/aitGen.c b/src/ca/legacy/gdd/aitGen.c deleted file mode 100644 index 39f885531..000000000 --- a/src/ca/legacy/gdd/aitGen.c +++ /dev/null @@ -1,440 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 - * Date: 2/96 - */ - -#include -#include -#include -#include -#include - -#define epicsExportSharedSymbols -#include "aitTypes.h" - -void initMinMaxAIT ( void ); - -/* - * maximum value for each type - joh - */ -double aitMax[aitTotal]; - -/* - * minimum value for each ait type - joh - */ -double aitMin[aitTotal]; - -/* - Still need to generate to "FromNet" matrix and rename the "Net" conversions - to "ToNet". -*/ - -void MakeNormalFunc(int i,int j,int k); -void MakeToFunc(int i,int j,int k); -void MakeFromFunc(int i,int j,int k); -void GenName(int i,int j,int k); -void GenVars(int i,int j); -void MakeStringFuncFrom(int i,int j,int k); -void MakeStringFuncTo(int i,int j,int k); -void MakeFStringFuncFrom(int i,int j,int k); -void MakeFStringFuncTo(int i,int j,int k); - -#define pr fprintf - -#define AIT_TO_NET 0 -#define AIT_FROM_NET 1 -#define AIT_NORMAL 2 - -#define AIT_SWAP_NONE 0 -#define AIT_SWAP_16 1 -#define AIT_SWAP_32 2 -#define AIT_SWAP_64 3 - -static const char* table_type[] = { - "aitConvertToNet", - "aitConvertFromNet", - "aitConvert" }; -static const char* table_def[] = { - "#if defined(AIT_TO_NET_CONVERT)", - "#elif defined(AIT_FROM_NET_CONVERT)", - "#else /* AIT_CONVERT */" }; - -static FILE *dfd; - -/* - * maximum, minimum value for each ait type - joh - */ -void initMinMaxAIT (void) -{ - unsigned i; - - for ( i = 0u; i < sizeof ( aitMax ) / sizeof ( aitMax [ 0 ] ); i++ ) { - aitMax [ i ] = -DBL_MAX; - } - - for ( i = 0u; i < sizeof ( aitMax ) / sizeof ( aitMax [ 0 ] ); i++ ) { - aitMin [ i ] = DBL_MAX; - } - - aitMax [ aitEnumInt8 ] = SCHAR_MAX; - aitMax [ aitEnumUint8 ] = UCHAR_MAX; - aitMax [ aitEnumInt16 ] = SHRT_MAX; - aitMax [ aitEnumUint16 ] = USHRT_MAX; - aitMax [ aitEnumEnum16 ] = USHRT_MAX; - aitMax [ aitEnumInt32 ] = INT_MAX; - aitMax [ aitEnumUint32 ] = UINT_MAX; - aitMax [ aitEnumFloat32 ] = FLT_MAX; - aitMax [ aitEnumFloat64 ] = DBL_MAX; - - aitMin [ aitEnumInt8 ] = SCHAR_MIN; - aitMin [ aitEnumUint8 ] = 0u; - aitMin [ aitEnumInt16 ] = SHRT_MIN; - aitMin [ aitEnumUint16 ] = 0u; - aitMin [ aitEnumEnum16 ] = 0u; - aitMin [ aitEnumInt32 ] = INT_MIN; - aitMin [ aitEnumUint32 ] = 0u; - aitMin [ aitEnumFloat32 ] = -FLT_MAX; - aitMin [ aitEnumFloat64 ] = -DBL_MAX; -} - -int main(int argc,char* argv[]) -{ - int i,j,k; - - initMinMaxAIT (); - - if(argc<2) - { - fprintf(stderr,"You must enter a file name on command line\n"); - return -1; - } - - if((dfd=fopen(argv[1],"w"))==NULL) - { - pr(stderr,"file %s failed to open\n",argv[1]); - return -1; - } - - /* -----------------------------------------------------------------*/ - /* generate basic conversion functions */ - - pr(dfd,"\n"); - - /* generate each group - to/from/normal */ - for(k=0;k<3;k++) - { - pr(dfd,"%s\n",table_def[k]); - for(i=aitConvertAutoFirst;i<=aitConvertAutoLast;i++) - for(j=aitConvertAutoFirst;j<=aitConvertAutoLast;j++) - { - switch(k) - { - case AIT_TO_NET: MakeToFunc(i,j,k); break; - case AIT_FROM_NET: MakeFromFunc(i,j,k); break; - case AIT_NORMAL: MakeNormalFunc(i,j,k); break; - default: break; - } - } - } - pr(dfd,"#endif\n\n"); - - for(k=0;k<3;k++) - { - pr(dfd,"%s\n",table_def[k]); - for(i=aitConvertAutoFirst;i<=aitConvertAutoLast;i++) - { - if (i!=aitEnumEnum16) { - MakeStringFuncTo(i,aitEnumString,k); - MakeStringFuncFrom(aitEnumString,i,k); - MakeFStringFuncTo(i,aitEnumFixedString,k); - MakeFStringFuncFrom(aitEnumFixedString,i,k); - } - } - } - pr(dfd,"#endif\n\n"); - - /* generate the three conversion table matrices */ - for(k=0;k<3;k++) - { - pr(dfd,"%s\n",table_def[k]); - pr(dfd,"aitFunc %sTable[aitTotal][aitTotal]={\n",table_type[k]); - - /* generate network conversion matrix */ - for(i=aitFirst;i<=aitLast;i++) - { - pr(dfd," {\n"); - for(j=aitFirst;j<=aitLast;j++) - { - if(iaitConvertLast || - jaitConvertLast) - pr(dfd,"aitNoConvert"); - else - pr(dfd,"%s%s%s",table_type[k], - &(aitName[i])[3],&(aitName[j])[3]); - - if(j=%g && ftmp<=%g) {\n", - aitMin[i], aitMax[i]); - pr(dfd,"\t\t\t\tout[i] = (%s) ftmp;\n", aitName[i]); - pr(dfd,"\t\t\t}\n"); - pr(dfd,"\t\t\telse {\n"); - pr(dfd,"\t\t\t\treturn -1;\n"); - pr(dfd,"\t\t\t}\n"); - pr(dfd,"\t\t}\n"); - pr(dfd,"\t\telse {\n"); - pr(dfd,"\t\t\treturn -1;\n"); - pr(dfd,"\t\t}\n"); - pr(dfd,"\t}\n"); - pr(dfd,"\treturn (int) (sizeof(%s)*c);\n}\n", aitName[i]); -} - -void MakeFStringFuncFrom(int i,int j,int k) -{ - /* assumes that void* d in an array of char pointers of length c */ - /* takes numeric data from source j and convert it to string in dest i */ - - pr(dfd,"static int %s%s%s(void* d,const void* s,aitIndex c, const gddEnumStringTable * pEST)\n", - table_type[k],&(aitName[i])[3],&(aitName[j])[3]); - pr(dfd,"{\n"); - pr(dfd,"\taitFixedString* out=(aitFixedString*)d;\n"); - pr(dfd,"\t%s* in=(%s*)s;\n",aitName[j],aitName[j]); - - pr(dfd,"\tfor(aitIndex i=0;i=%g && ftmp<=%g) {\n", - aitMin[i], aitMax[i]); - pr(dfd,"\t\t\t\tout[i] = (%s) ftmp;\n", aitName[i]); - pr(dfd,"\t\t\t}\n"); - pr(dfd,"\t\t\telse {\n"); - pr(dfd,"\t\t\t\treturn -1;\n"); - pr(dfd,"\t\t\t}\n"); - pr(dfd,"\t\t}\n"); - pr(dfd,"\t\telse {\n"); - pr(dfd,"\t\t\treturn -1;\n"); - pr(dfd,"\t\t}\n"); - pr(dfd,"\t}\n"); - pr(dfd,"\treturn (int) (sizeof(%s)*c);\n}\n", aitName[i]); -} - -void GenName(int i,int j,int k) -{ - const char* i_name = &((aitName[i])[3]); - const char* j_name = &((aitName[j])[3]); - - pr(dfd,"static int %s%s%s(void* d,const void* s,aitIndex c, const gddEnumStringTable *)\n", - table_type[k],i_name,j_name); -} - -void GenVars(int i,int j) -{ - pr(dfd,"\taitIndex i;\n"); - pr(dfd,"\t%s* d_val=(%s*)d;\n",aitName[i],aitName[i]); - pr(dfd,"\t%s* s_val=(%s*)s;\n\n",aitName[j],aitName[j]); -} - -void MakeFromFunc(int i,int j,int k) -{ - int conv_type; - char *len_msg,*conv_msg; - - /* destination = i, source = j, type = k */ - GenName(i,j,k); - pr(dfd,"{\n"); - - /* check if we need network byte swaps */ - if (strstr(aitName[j],"16")) - { len_msg="16"; conv_type=AIT_SWAP_16; } - else if(strstr(aitName[j],"32")) - { len_msg="32"; conv_type=AIT_SWAP_32; } - else if(strstr(aitName[j],"64")) - { len_msg="64"; conv_type=AIT_SWAP_64; } - else - { len_msg=""; conv_type=AIT_SWAP_NONE; } - - if (strstr(aitName[j],"Float")) - conv_msg="Float"; - else - conv_msg="Order"; - - GenVars(i,j); - - if(i==j || conv_type==AIT_SWAP_NONE) - { - if(conv_type!=AIT_SWAP_NONE) - { - pr(dfd,"\tfor(i=0;i - -#include "epicsTime.h" // define struct timespec if nec - -#define epicsExportSharedSymbols -#include "aitTypes.h" -#include "aitHelpers.h" - -// -// 1/1/90 20 yr (5 leap) of seconds -// -const unsigned aitTimeStamp::epicsEpochSecPast1970 = 7305 * 86400; - -void aitString::mallocFailure(void) -{ - str=(char *)""; - len=0u; - bufLen=1u; - type=aitStrRefConstImortal; - fprintf(stderr,"aitString: no pool => continuing with zero char str\n"); -} - -void aitString::dump(const char* p) const -{ - fprintf(stderr,"<%s>:",p); - dump(); -} - -void aitString::dump(void) const -{ - fprintf(stderr,"this=%p ", this); - if(str) fprintf(stderr,"string=%p<%s>, ",str,str); - else fprintf(stderr,"no string present, "); - fprintf(stderr,"length=%u, ",len); - fprintf(stderr,"buf length=%u, ",bufLen); - if(type==aitStrRefConstImortal) fprintf(stderr,"type=Imortal Constant Reference\n"); - else if(type==aitStrRefConst) fprintf(stderr,"type=Constant Reference\n"); - else if(type==aitStrRef) fprintf(stderr,"type=Reference\n"); - else if(type==aitStrCopy) fprintf(stderr,"type=Allocated\n"); - else fprintf(stderr,"type=Invalid\n"); -} - -aitIndex aitString::compact(aitString* array, aitIndex arraySize, - void* buf, aitIndex bufSize) -{ - aitIndex i; - aitUint32 pos; - char* ptr=(char*)buf; - aitString* str=(aitString*)buf; - - // copy the array first - pos=sizeof(aitString)*arraySize; - if(bufSizebufSize) break; // quick exit from loop - if(array[i].string()) - { - memcpy(&ptr[pos],array[i].string(),array[i].length()+1u); - str[i].installBuf(&ptr[pos], array[i].length(), array[i].length()+1u); - pos+=str[i].length()+1; - } - } - return pos; -} - -aitUint32 aitString::totalLength(aitString* array, aitIndex arraySize) -{ - aitIndex i; - aitUint32 tot; - - tot=sizeof(aitString)*arraySize; - for(i=0;i=bufSizeIn) { - return -1; - } - - if (this->type==aitStrRefConst || this->type==aitStrRefConstImortal - || bufSizeIn>this->bufLen) { - - char *pStrNew; - pStrNew = new char [bufSizeIn]; - if (!pStrNew) { - mallocFailure(); - return -1; - } - if (this->type==aitStrCopy) { - delete [] this->str; - } - this->str = pStrNew; - this->bufLen = bufSizeIn; - this->type = aitStrCopy; - } - // test above verifies that bufLen exceeds - // length of p - strncpy (this->str,p,this->bufLen); - this->len = newStrLength; - return 0; -} - -int aitString::init(const char* p, aitStrType typeIn, unsigned strLengthIn, unsigned bufSizeIn) -{ - int rc; - - this->init(); - switch (typeIn) { - case aitStrCopy: - rc = this->copy(p, strLengthIn, bufSizeIn); - break; - case aitStrRef: - rc = this->installBuf(p, strLengthIn, bufSizeIn); - break; - case aitStrRefConst: - rc = this->installConstBuf(p, strLengthIn, bufSizeIn); - break; - case aitStrRefConstImortal: - rc = this->installConstImortalBuf(p, strLengthIn, bufSizeIn); - break; - default: - rc=-1; - break; - } - return rc; -} - -aitTimeStamp::operator struct epicsTimeStamp () const -{ - epicsTimeStamp ts; - - if (this->tv_sec>aitTimeStamp::epicsEpochSecPast1970) { - ts.secPastEpoch = this->tv_sec - aitTimeStamp::epicsEpochSecPast1970; - ts.nsec = this->tv_nsec; - } - else { - ts.secPastEpoch = 0; - ts.nsec = 0; - } - return ts; -} - -void aitTimeStamp::get (struct epicsTimeStamp &ts) const -{ - if (this->tv_sec>aitTimeStamp::epicsEpochSecPast1970) { - ts.secPastEpoch = this->tv_sec - aitTimeStamp::epicsEpochSecPast1970; - ts.nsec = this->tv_nsec; - } - else { - ts.secPastEpoch = 0; - ts.nsec = 0; - } -} - -aitTimeStamp::aitTimeStamp (const struct epicsTimeStamp &ts) -{ - this->tv_sec = ts.secPastEpoch + aitTimeStamp::epicsEpochSecPast1970; - this->tv_nsec = ts.nsec; -} - -aitTimeStamp aitTimeStamp::operator = (const struct epicsTimeStamp &rhs) -{ - this->tv_sec = rhs.secPastEpoch + aitTimeStamp::epicsEpochSecPast1970; - this->tv_nsec = rhs.nsec; - return *this; -} - -aitTimeStamp :: aitTimeStamp ( const epicsTime & ts ) -{ - epicsTimeStamp ets = ts; - *this = ets; -} - -aitTimeStamp aitTimeStamp :: operator = ( const epicsTime & rhs ) -{ - epicsTimeStamp ets = rhs; - return *this = ets; -} - -aitTimeStamp :: operator epicsTime () const -{ - epicsTimeStamp ets = *this; - return epicsTime ( ets ); -} - -aitTimeStamp::operator struct timespec () const -{ - struct timespec ts; - ts.tv_sec = (unsigned long) this->tv_sec; - ts.tv_nsec = (unsigned long) this->tv_nsec; - return ts; -} - -void aitTimeStamp::get (struct timespec &ts) const -{ - ts.tv_sec = (unsigned long) this->tv_sec; - ts.tv_nsec = (unsigned long) this->tv_nsec; -} - -aitTimeStamp::aitTimeStamp (const struct timespec &ts) -{ - this->tv_sec = (aitUint32) ts.tv_sec; - this->tv_nsec = (aitUint32) ts.tv_nsec; -} - -aitTimeStamp aitTimeStamp::operator = (const struct timespec &rhs) -{ - this->tv_sec = (aitUint32) rhs.tv_sec; - this->tv_nsec = (aitUint32) rhs.tv_nsec; - return *this; -} diff --git a/src/ca/legacy/gdd/aitHelpers.h b/src/ca/legacy/gdd/aitHelpers.h deleted file mode 100644 index aa66a38e7..000000000 --- a/src/ca/legacy/gdd/aitHelpers.h +++ /dev/null @@ -1,462 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 aitHelpersInclude -#define aitHelpersInclude - -/* - * Authors: Jeff Hill and Jim Kowalkowski - * Date: 6/20/96 - */ - -#include -#include -#ifndef assert // allows use of epicsAssert.h -#include -#endif - -#include "shareLib.h" - -#define NSecPerSec 1000000000u -#define NSecPerUSec 1000u -#define SecPerMin 60u - -inline char* strDup(const char* x) -{ - char* y = new char[strlen(x)+1]; - strcpy(y,x); - return y; -} - -struct timespec; -struct epicsTimeStamp; -class epicsTime; -class gdd; - -class epicsShareClass aitTimeStamp { - friend inline aitTimeStamp operator+ (const aitTimeStamp &lhs, const aitTimeStamp &rhs); - friend inline aitTimeStamp operator- (const aitTimeStamp &lhs, const aitTimeStamp &rhs); - friend inline int operator>= (const aitTimeStamp &lhs, const aitTimeStamp &rhs); - friend class gdd; -public: - aitTimeStamp () : tv_sec(0u), tv_nsec(0u) {} - aitTimeStamp (const aitTimeStamp &t) : tv_sec(t.tv_sec), tv_nsec(t.tv_nsec) {} - aitTimeStamp (const unsigned long tv_secIn, const unsigned long tv_nsecIn) : - tv_sec(tv_secIn), tv_nsec(tv_nsecIn) - { - if (tv_nsecIn>=NSecPerSec) { - this->tv_sec += this->tv_nsec/NSecPerSec; - this->tv_nsec = this->tv_nsec%NSecPerSec; - } - } - - // - // fetched as fields so this file is not required - // to include os dependent struct timeval - // - void getTV(long &tv_secOut, long &uSecOut) const - { - assert (this->tv_sec<=LONG_MAX); - tv_secOut = (long) this->tv_sec; - assert (this->tv_nsec<=LONG_MAX); - uSecOut = (long) this->tv_nsec/NSecPerUSec; - } - - // - // for use when loading struct timeval - // - void get(unsigned long &tv_secOut, unsigned long &tv_nsecOut) const - { - tv_secOut = this->tv_sec; - tv_nsecOut = this->tv_nsec; - } - - operator double() const - { - return ((double)this->tv_nsec)/NSecPerSec+this->tv_sec; - } - - operator float() const - { - return ((float)this->tv_nsec)/NSecPerSec+this->tv_sec; - } - - // - // convert to and from POSIX timespec format - // - operator struct timespec () const; - void get (struct timespec &) const; - aitTimeStamp (const struct timespec &ts); - aitTimeStamp operator = (const struct timespec &rhs); - - // - // convert to and from EPICS epicsTimeStamp format - // - operator struct epicsTimeStamp () const; - void get (struct epicsTimeStamp &) const; - aitTimeStamp (const epicsTimeStamp &ts); - aitTimeStamp operator = (const epicsTimeStamp &rhs); - - // conversion to from epicsTime - aitTimeStamp (const epicsTime &ts); - aitTimeStamp operator = (const epicsTime &rhs); - operator epicsTime () const; - - static aitTimeStamp getCurrent(); - -//private: - unsigned long tv_sec; - unsigned long tv_nsec; -private: - static const unsigned epicsEpochSecPast1970; -}; - -inline aitTimeStamp operator+ (const aitTimeStamp &lhs, const aitTimeStamp &rhs) -{ - return aitTimeStamp(lhs.tv_sec + rhs.tv_sec, lhs.tv_nsec + rhs.tv_nsec); -} - -// -// like data type unsigned this assumes that the lhs > rhs -// (otherwise we assume tv_sec wrap around) -// -inline aitTimeStamp operator- (const aitTimeStamp &lhs, const aitTimeStamp &rhs) -{ - unsigned long tv_nsec, tv_sec; - - if (lhs.tv_sec= (const aitTimeStamp &lhs, const aitTimeStamp &rhs) -{ - int rc=0; - - if (lhs.tv_sec>rhs.tv_sec) - rc=1; - else if(lhs.tv_sec==rhs.tv_sec) - if(lhs.tv_nsec>=rhs.tv_nsec) - rc=1; - return rc; -} - - -// --------------------------------------------------------------------------- -// very simple class for string storage (for now) -// -// -enum aitStrType { - aitStrRefConstImortal, // any constant string that always exists - ie "abc" - aitStrRefConst, // user provides constant string buffer for life of aitSting - aitStrRef, // user provides modifiable string buffer for life of aitSting - aitStrCopy}; // aitSting copies into internal storage -class epicsShareClass aitString -{ -public: - inline aitString(void); - inline aitString(const aitString* p); - inline aitString(const aitString& p); - inline aitString(const char* p, aitStrType type=aitStrCopy); - inline aitString(const char* p, aitStrType type, unsigned strLength); - inline aitString(const char* p, aitStrType type, unsigned strLength, unsigned bufSize); - - inline ~aitString(void); // free up string is required - - inline void clear(void); // clear everything, free string if required - void dump(void) const; - void dump(const char* id) const; - - // casts from aitString to other things - pulls info out of aitString - inline operator aitUint16(void) const { return (aitUint16)this->len; } - inline operator aitUint32(void) const { return (aitUint32)this->len; } - inline operator aitInt32(void) const { return (aitInt32)this->len; } - inline operator const char*(void) const { return this->str; } - inline operator char*(void) const - { - assert(type!=aitStrRefConst && type!=aitStrRefConstImortal); - return str; - } - inline int isConstant(void) const; - - inline aitUint32 length(void) const { return (aitUint32)this->len; } - inline const char* string(void) const { return this->str; } - - // completely reset the aitString to a new value - // - the same as copy() - inline aitString& operator=(const aitString& pString); - inline aitString& operator=(const aitString* pString); - inline aitString& operator=(const char* pString); - - inline int copy(const aitString* pString); - inline int copy(const aitString& pString); - inline int copy(const char* pString); - inline int copy(const char* pString, unsigned stringLength); - int copy(const char* pString, unsigned stringLength, unsigned bufSize); - - // - // make ait string point at string in application's modifiable buffer - // - inline int installBuf(const char* pString); - inline int installBuf(const char* pString, unsigned stringLength); - inline int installBuf(const char* pString, unsigned stringLength, unsigned bufSize); - - // - // make ait string point at constant string in application's constant buffer - // - inline int installConstBuf(const char* pString); - inline int installConstBuf(const char* pString, unsigned stringLength); - inline int installConstBuf(const char* pString, unsigned stringLength, unsigned bufSize); - - // - // make ait string point at constant string in application's constant buffer - // that exists forever (such as "abc") - // - inline int installConstImortalBuf(const char* pString); - inline int installConstImortalBuf(const char* pString, unsigned stringLength); - inline int installConstImortalBuf(const char* pString, unsigned stringLength, unsigned bufSize); - - inline void extractString(char* to_here, unsigned bufSize); - - // take the aitString array, and put it and all the string into buf, - // return the total length the data copied - static aitUint32 totalLength(aitString* array,aitIndex arraySize); - static aitUint32 stringsLength(aitString* array,aitIndex arraySize); - static aitIndex compact(aitString* array, aitIndex arraySize, - void* buf, aitIndex bufSize); - - // - // for gdd's use only! (to construct class inside union) - // (it is possible to leak memory if this is called on - // an already constructed aitString). This practice should - // be eliminated by deriving from aitString and replacing - // the new operator? - // - inline void init(void); - -private: - - char* str; - unsigned len:14; // actual length of string - unsigned bufLen:14; // length of string buffer - unsigned type:4; // aitStrType goes here - - void mallocFailure(void); - inline aitStrType getType(void) const { return (aitStrType)type; } - int init(const char* p, aitStrType type, unsigned strLength, unsigned bufSize); -}; - -inline void aitString::init(void) -{ - this->str=(char *)""; - this->len=0u; - this->bufLen=1u; - this->type=aitStrRefConstImortal; -} - -inline int aitString::isConstant(void) const -{ - return ( (getType()==aitStrRefConst||getType()==aitStrRefConstImortal) && this->str)?1:0; -} - -inline void aitString::clear(void) -{ - if(this->str && this->type==aitStrCopy) delete [] this->str; - this->init(); -} - -inline void aitString::extractString(char* p, unsigned bufLength) -{ - if (bufLength==0u) { - return; - } - else if (this->str) { - strncpy(p,this->str,bufLength); - p[bufLength-1u]='\0'; - } - else { - p[0u] = '\0'; - } -} - -// -// make ait string point at string in application's buffer -// -inline int aitString::installBuf(const char* pString, unsigned strLengthIn, unsigned bufSizeIn) -{ - if (this->type==aitStrCopy) { - delete [] this->str; - } - this->str = (char *) pString; - this->bufLen = bufSizeIn; - this->type = aitStrRef; - this->len = strLengthIn; - return 0; -} - -inline int aitString::installBuf(const char* pString) -{ - unsigned strLengthIn = (unsigned) strlen(pString); - return this->installBuf(pString, strLengthIn, strLengthIn+1u); -} - -inline int aitString::installBuf(const char* pString, unsigned strLengthIn) -{ - return this->installBuf(pString, strLengthIn, strLengthIn+1u); -} - - -// -// make ait string point at constant string in application's buffer -// -inline int aitString::installConstBuf(const char* pString, unsigned strLengthIn, unsigned bufSizeIn) -{ - if (this->type==aitStrCopy) { - delete [] this->str; - } - this->str = (char *) pString; - this->bufLen = bufSizeIn; - this->type = aitStrRefConst; - this->len = strLengthIn; - return 0; -} - -inline int aitString::installConstBuf(const char* pString) -{ - unsigned strLengthIn = (unsigned) strlen(pString); - return this->installConstBuf(pString, strLengthIn, strLengthIn+1u); -} - -inline int aitString::installConstBuf(const char* pString, unsigned strLengthIn) -{ - return this->installConstBuf(pString, strLengthIn, strLengthIn+1u); -} - -// -// make ait string point at constant string in application's buffer -// that always exists (such as "abc") -// -inline int aitString::installConstImortalBuf(const char* pString, - unsigned strLengthIn, unsigned bufSizeIn) -{ - if (this->type==aitStrCopy) { - delete [] this->str; - } - this->str = (char *) pString; - this->bufLen = bufSizeIn; - this->type = aitStrRefConstImortal; - this->len = strLengthIn; - return 0; -} - -inline int aitString::installConstImortalBuf(const char* pString) -{ - unsigned strLengthIn = (unsigned) strlen(pString); - return this->installConstImortalBuf(pString, strLengthIn, strLengthIn+1u); -} - -inline int aitString::installConstImortalBuf(const char* pString, unsigned strLengthIn) -{ - return this->installConstImortalBuf(pString, strLengthIn, strLengthIn+1u); -} - - -inline int aitString::copy(const char* pString, unsigned stringLength) -{ - return this->copy(pString, stringLength, - this->bufLen>(stringLength+1u) ? this->bufLen : (stringLength+1u) ); -} - -inline int aitString::copy(const char* p) -{ - return this->copy(p, (unsigned) strlen(p)); -} - -inline int aitString::copy(const aitString* p) -{ - if (p->type==aitStrRefConstImortal) { - // - // fast reference if the string is constant and it - // exists forever - // - return this->installConstImortalBuf(p->str, p->len, p->len+1u); - } - return this->copy(p->str, p->len); -} - -inline int aitString::copy(const aitString& p) -{ - return this->copy(&p); -} - -inline aitString& aitString::operator=(const aitString& p) - { this->copy(p); return *this; } -inline aitString& aitString::operator=(const aitString* p) - { this->copy(p); return *this; } -inline aitString& aitString::operator=(const char* p) - { this->copy(p); return *this; } - -inline aitString::~aitString(void) -{ - // dump("~aitString"); - this->clear(); -} - -inline aitString::aitString(void) -{ - this->init(); -} - -inline aitString::aitString(const char* p, aitStrType typeIn) -{ - unsigned strLengthIn = (unsigned) strlen(p); - this->init(p, typeIn, strLengthIn, strLengthIn+1u); -} - -inline aitString::aitString(const char* p, aitStrType typeIn, unsigned strLengthIn) -{ - this->init(p, typeIn, strLengthIn, strLengthIn+1u); -} - -inline aitString::aitString(const char* p, aitStrType typeIn, unsigned strLength, unsigned bufSize) -{ - this->init(p,typeIn,strLength,bufSize); -} - -inline aitString::aitString(const aitString* p) -{ - this->init(); - this->copy(p); -} - -inline aitString::aitString(const aitString& p) -{ - this->init(); - this->copy(p); -} - -#endif // aitHelpersInclude diff --git a/src/ca/legacy/gdd/aitTypes.c b/src/ca/legacy/gdd/aitTypes.c deleted file mode 100644 index 35a87ce1e..000000000 --- a/src/ca/legacy/gdd/aitTypes.c +++ /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 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 - * Date: 2/96 - */ - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "aitTypes.h" - -epicsShareDef const size_t aitSize[aitTotal] = { - 0, - sizeof(aitInt8), - sizeof(aitUint8), - sizeof(aitInt16), - sizeof(aitUint16), - sizeof(aitEnum16), - sizeof(aitInt32), - sizeof(aitUint32), - sizeof(aitFloat32), - sizeof(aitFloat64), - sizeof(aitFixedString), - sizeof(aitString), - 0 -}; - -epicsShareDef const char* aitName[aitTotal] = { - "aitInvalid", - "aitInt8", - "aitUint8", - "aitInt16", - "aitUint16", - "aitEnum16", - "aitInt32", - "aitUint32", - "aitFloat32", - "aitFloat64", - "aitFixedString", - "aitString", - "aitContainer" -}; - -/* - * conversion characters used with stdio lib - */ -epicsShareDef const char* aitPrintf[aitTotal] = { - 0, - "c", - "c", - "hd", - "hu", - "hu", - "d", - "u", - "g", - "g", - "s", - 0, /* printf doesnt know about aitString */ - 0 -}; -epicsShareDef const char* aitScanf[aitTotal] = { - 0, - "c", - "c", - "hd", - "hu", - "hu", - "d", - "u", - "g", - "lg", - "s", - 0, /* scanf doesnt know about aitString */ - 0 -}; - - - diff --git a/src/ca/legacy/gdd/aitTypes.h b/src/ca/legacy/gdd/aitTypes.h deleted file mode 100644 index 135abc3c6..000000000 --- a/src/ca/legacy/gdd/aitTypes.h +++ /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. -\*************************************************************************/ -#ifndef AIT_TYPES_H -#define AIT_TYPES_H 1 - -/* - * Author: Jim Kowalkowski - * Date: 2/96 - */ - -/* This is the file the user sets up for a given architecture */ - -#define AIT_FIXED_STRING_SIZE 40 - -#include "shareLib.h" - -typedef signed char aitInt8; -typedef unsigned char aitUint8; -typedef short aitInt16; -typedef unsigned short aitUint16; -typedef aitUint16 aitEnum16; -typedef int aitInt32; -typedef unsigned int aitUint32; -typedef float aitFloat32; -typedef double aitFloat64; -typedef aitUint32 aitIndex; -typedef void* aitPointer; - -typedef union { - struct { - aitUint16 aitStat; - aitUint16 aitSevr; - } s; - aitUint32 u; -} aitStatus; - -/* should the bool be added as a conversion type? it currently is not */ -typedef enum { - aitFalse=0, - aitTrue -} aitBool; - -typedef struct { - char fixed_string[AIT_FIXED_STRING_SIZE]; -} aitFixedString; - -#ifdef __cplusplus -#include "aitHelpers.h" -#else -/* need time stamp structure different from posix unfortunetly */ -typedef struct { - aitUint32 tv_sec; - aitUint32 tv_nsec; -} aitTimeStamp; - -/* strings are a struct so they are different then aitInt8 */ -typedef struct { - char* string; - aitUint32 len; -} aitString; -#endif - -/* all normal types */ -#define aitTotal 13 -#define aitFirst aitEnumInvalid -#define aitLast aitEnumContainer -#define aitValid(x) ((x)<=aitLast && (x)>aitFirst) - -/* all conversion types */ -#define aitConvertTotal 11 -#define aitConvertFirst aitEnumInt8 -#define aitConvertLast aitEnumString -#define aitConvertAutoFirst aitEnumInt8 -#define aitConvertAutoLast aitEnumFloat64 -#define aitConvertValid(x) ((x)>=aitConvertFirst && (x)<=aitConvertLast) - -/* currently no 64-bit integer support */ -typedef enum { - aitEnumInvalid=0, - aitEnumInt8, - aitEnumUint8, - aitEnumInt16, - aitEnumUint16, - aitEnumEnum16, - aitEnumInt32, - aitEnumUint32, - aitEnumFloat32, - aitEnumFloat64, - aitEnumFixedString, - aitEnumString, - aitEnumContainer -} aitEnum; - -typedef union { - aitInt8 Int8; - aitUint8 Uint8; - aitInt16 Int16; - aitUint16 Uint16; - aitEnum16 Enum16; - aitInt32 Int32; - aitUint32 Uint32; - aitFloat32 Float32; - aitFloat64 Float64; - aitIndex Index; - aitPointer Pointer; - aitFixedString* FString; - aitUint8 Dumb1[sizeof(aitString)]; /* aitString String; */ - aitUint8 Dumb3[sizeof(aitTimeStamp)]; /* aitTimeStamp Stamp; */ -} aitType; - -/* - classes are not allowed in union that required construction/destruction - so I am insuring that the size of aitType is large enough to hold - strings and timestamps in an obsure, horrible way with the Dumb variables -*/ - - -#ifdef __cplusplus -extern "C" { -#endif -epicsShareExtern const size_t aitSize[aitTotal]; -epicsShareExtern const char* aitName[aitTotal]; -epicsShareExtern const char* aitPrintf[aitTotal]; -epicsShareExtern const char* aitScanf[aitTotal]; -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/src/ca/legacy/gdd/dbMapper.cc b/src/ca/legacy/gdd/dbMapper.cc deleted file mode 100644 index c15c26110..000000000 --- a/src/ca/legacy/gdd/dbMapper.cc +++ /dev/null @@ -1,1802 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 -// Date: 2/96 - -#define DB_MAPPER_SOURCE 1 - -#include -#include - -#define epicsExportSharedSymbols -#include "gddApps.h" -#include "gddAppTable.h" -#include "dbMapper.h" -// #include "templates/dbMapperTempl.h" - -// hardcoded in same order as aitConvert.h -// no way to detect a string type!!!!!!! - -extern epicsShareDef const int gddAitToDbr[aitConvertLast+1] = { - DBR_STRING, - DBR_CHAR, - DBR_CHAR, - DBR_SHORT, - DBR_SHORT, - DBR_ENUM, - DBR_LONG, - DBR_LONG, - DBR_FLOAT, - DBR_DOUBLE, - DBR_STRING, - DBR_STRING -}; - -extern epicsShareDef const unsigned gddDbrToAitNElem = - sizeof(gddAitToDbr)/sizeof(gddAitToDbr[0]); - -/* - * application type ("app" field) is initialized - * at run tim using the "app_name" field. - */ -epicsShareDef gddDbrToAitTable gddDbrToAit[DBM_N_DBR_TYPES] = { - // Atomic - { aitEnumFixedString, 0, "value" }, // DBR_STRING - { aitEnumInt16, 0, "value" }, // DBR_SHORT - { aitEnumFloat32, 0, "value" }, // DBR_FLOAT - { aitEnumEnum16, 0, "value" }, // DBR_ENUM - { aitEnumInt8, 0, "value" }, // DBR_CHAR - { aitEnumInt32, 0, "value" }, // DBR_LONG - { aitEnumFloat64, 0, "value" }, // DBR_DOUBLE - // Status - { aitEnumFixedString, 0, "value" }, // DBR_STS_STRING - { aitEnumInt16, 0, "value" }, // DBR_STS_SHORT - { aitEnumFloat32, 0, "value" }, // DBR_STS_FLOAT - { aitEnumEnum16, 0, "value" }, // DBR_STS_ENUM - { aitEnumInt8, 0, "value" }, // DBR_STS_CHAR - { aitEnumInt32, 0, "value" }, // DBR_STS_LONG - { aitEnumFloat64, 0, "value" }, // DBR_STS_DOUBLE - // Time - { aitEnumFixedString, 0, "value" }, // DBR_TIME_STRING - { aitEnumInt16, 0, "value" }, // DBR_TIME_SHORT - { aitEnumFloat32, 0, "value" }, // DBR_TIME_FLOAT - { aitEnumEnum16, 0, "value" }, // DBR_TIME_ENUM - { aitEnumInt8, 0, "value" }, // DBR_TIME_CHAR - { aitEnumInt32, 0, "value" }, // DBR_TIME_LONG - { aitEnumFloat64, 0, "value" }, // DBR_TIME_DOUBLE - // Graphic - { aitEnumFixedString, 0, "value" }, // DBR_GR_STRING - { aitEnumInt16, 0, "dbr_gr_short" }, // DBR_GR_SHORT - { aitEnumFloat32, 0, "dbr_gr_float" }, // DBR_GR_FLOAT - { aitEnumEnum16, 0, "dbr_gr_enum" }, // DBR_GR_ENUM - { aitEnumInt8, 0, "dbr_gr_char" }, // DBR_GR_CHAR - { aitEnumInt32, 0, "dbr_gr_long" }, // DBR_GR_LONG - { aitEnumFloat64, 0, "dbr_gr_double" }, // DBR_GR_DOUBLE - // Control - { aitEnumFixedString, 0, "value" }, // DBR_CTRL_STRING - { aitEnumInt16, 0, "dbr_ctrl_short" }, // DBR_CTRL_SHORT - { aitEnumFloat32, 0, "dbr_ctrl_float" }, // DBR_CTRL_FLOAT - { aitEnumEnum16, 0, "dbr_ctrl_enum" }, // DBR_CTRL_ENUM - { aitEnumInt8, 0, "dbr_ctrl_char" }, // DBR_CTRL_CHAR - { aitEnumInt32, 0, "dbr_ctrl_long" }, // DBR_CTRL_LONG - { aitEnumFloat64, 0, "dbr_ctrl_double" }, // DBR_CTRL_DOUBLE - // Ack - { aitEnumUint16, 0, "ackt" }, // DBR_PUT_ACKT - { aitEnumUint16, 0, "acks" }, // DBR_PUT_ACKS - { aitEnumFixedString, 0, "dbr_stsack_string" }, // DBR_STSACK_STRING - // Class - { aitEnumFixedString, 0, "class" } // DBR_CLASS_NAME -}; - -#if DBM_N_DBR_TYPES != (LAST_BUFFER_TYPE+1) -#error db mapper is out of sync with db_access.h -#endif - -static gddApplicationTypeTable* type_table = NULL; -static aitDataFormat local_data_format=aitLocalDataFormat; - -extern epicsShareDef const unsigned gddAitToDbrNElem = - sizeof(gddDbrToAit)/sizeof(gddDbrToAit[0]); - -// -// special gddDestructor guarantees same form of new and delete -// -class dbMapperFixedStringDestructor: public gddDestructor { - virtual void run (void *); -}; - - -// I generated a container for each of the important DBR types. This -// includes all the control and graphic structures. The others are -// not needed become you can get time stamp and status in each gdd. -// Currently the containers are built here with c++ code. - -// string type needs to be written special and not use template -// maybe create a template for the string type -// the problem is that the value of a string structure is an array, -// not just a single element - -static smartGDDPointer mapStringToGdd(void* v,aitIndex count) { - aitFixedString* db = (aitFixedString*)v; - aitEnum to_type = gddDbrToAit[DBR_STRING].type; - aitUint16 to_app = gddDbrToAit[DBR_STRING].app; - - if(count<=1) - { - smartGDDPointer dd = new gddScalar(to_app,to_type); - dd->unreference(); - dd->put(*db); - return dd; - } - else - { - smartGDDPointer dd=new gddAtomic(to_app,to_type,1,count); - dd->unreference(); - aitFixedString* pCopy = new aitFixedString [count]; - memcpy (pCopy,db,sizeof(aitFixedString)*count); - dd->putRef(db,new dbMapperFixedStringDestructor); - return dd; - } -} - -static int mapGddToString(void* vd, aitIndex count, - const gdd & dd, const gddEnumStringTable &enumStringTable) { - aitFixedString* db = (aitFixedString*)vd; - aitIndex sz = dd.getDataSizeElements(); - const void* v = dd.dataVoid(); - int status; - - if (count>sz) { - memset (db+sz, '\0', sizeof(*db)*(count-sz)); - count = sz; - } - - if(local_data_format==aitLocalDataFormat) { - if((aitFixedString*)v!=db) { - status = aitConvert(aitEnumFixedString,db, - dd.primitiveType(),v,count, &enumStringTable); - } - else { - status = sz*sizeof(aitFixedString); - } - } - else { - status = aitConvertToNet(aitEnumFixedString, - db,dd.primitiveType(),v,count, &enumStringTable); - } - - return status; -} - -static smartGDDPointer mapShortToGdd(void* v,aitIndex count) { - dbr_short_t* sv = (dbr_short_t*)v; - - if(count>1) { - smartGDDPointer dd=new gddAtomic(gddDbrToAit[DBR_SHORT].app, - gddDbrToAit[DBR_SHORT].type,1,count); - dd->unreference(); - dbr_short_t* pCopy = (dbr_short_t*) new char [sizeof(dbr_short_t)*count]; - memcpy (pCopy,sv,sizeof(dbr_short_t)*count); - dd->putRef(pCopy, new gddDestructor); - return dd; - } else { - smartGDDPointer dd=new gddScalar(gddDbrToAit[DBR_SHORT].app); - dd->unreference(); - *dd=*sv; - return dd; - } -} - -static int mapGddToShort(void* vd, aitIndex count, const gdd &dd, - const gddEnumStringTable &enumStringTable) { - dbr_short_t* sv = (dbr_short_t*)vd; - aitIndex sz = dd.getDataSizeElements(); - const void * v=dd.dataVoid(); - int status; - - if (count>sz) { - memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); - count = sz; - } - - if (local_data_format==aitLocalDataFormat) { - if((dbr_short_t*)v!=sv) { - status = aitConvert(aitEnumInt16,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - else { - status = count*sizeof(dbr_short_t); - } - } - else { - status = aitConvertToNet(aitEnumInt16,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - - return status; -} - -static smartGDDPointer mapFloatToGdd(void* v,aitIndex count) { - dbr_float_t* sv = (dbr_float_t*)v; - - if(count>1) { - smartGDDPointer dd=new gddAtomic(gddDbrToAit[DBR_FLOAT].app, - gddDbrToAit[DBR_FLOAT].type,1,count); - dd->unreference(); - dbr_float_t* pCopy = (dbr_float_t*) new char [sizeof(dbr_float_t)*count]; - memcpy (pCopy,sv,sizeof(dbr_float_t)*count); - dd->putRef(pCopy, new gddDestructor); - return dd; - } else { - smartGDDPointer dd=new gddScalar(gddDbrToAit[DBR_FLOAT].app); - dd->unreference(); - *dd=*sv; - return dd; - } -} - -static int mapGddToFloat(void* vd, aitIndex count, - const gdd & dd, const gddEnumStringTable &enumStringTable) { - dbr_float_t* sv = (dbr_float_t*)vd; - aitIndex sz=dd.getDataSizeElements(); - const void * v = dd.dataVoid(); - int status; - - if (count>sz) { - memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); - count = sz; - } - - if(local_data_format==aitLocalDataFormat) { - if((dbr_float_t*)v!=sv) { - status = aitConvert(aitEnumFloat32,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - else { - status = sz*sizeof(dbr_float_t); - } - } - else { - status = aitConvertToNet(aitEnumFloat32,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - - return status; -} - -static smartGDDPointer mapEnumToGdd(void* v,aitIndex count) { - dbr_enum_t* sv = (dbr_enum_t*)v; - smartGDDPointer dd; - - if(count>1) { - dd=new gddAtomic(gddDbrToAit[DBR_ENUM].app, - gddDbrToAit[DBR_ENUM].type,1,count); - dd->unreference(); - dbr_enum_t* pCopy = (dbr_enum_t *) new char [sizeof(dbr_enum_t)*count]; - memcpy (pCopy,sv,sizeof(dbr_enum_t)*count); - dd->putRef(pCopy, new gddDestructor); - } else { - dd=new gddScalar(gddDbrToAit[DBR_ENUM].app); - dd->unreference(); - *dd=*sv; - } - return dd; -} - -static int mapGddToEnum(void* vd, aitIndex count, const gdd & dd, - const gddEnumStringTable &enumStringTable) { - dbr_enum_t* sv = (dbr_enum_t*)vd; - aitIndex sz=dd.getDataSizeElements(); - const void* v = dd.dataVoid(); - int status; - - if (count>sz) { - memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); - count = sz; - } - - if(local_data_format==aitLocalDataFormat) { - if((dbr_enum_t*)v!=sv) { - status = aitConvert(aitEnumEnum16,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - else { - status = sizeof(dbr_enum_t)*count; - } - } - else { - status = aitConvertToNet(aitEnumEnum16,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - - return status; -} - -static smartGDDPointer mapCharToGdd(void* v,aitIndex count) { - dbr_char_t* sv = (dbr_char_t*)v; - smartGDDPointer dd; - - if(count>1) { - dd=new gddAtomic(gddDbrToAit[DBR_CHAR].app, - gddDbrToAit[DBR_CHAR].type,1,count); - dd->unreference(); - dbr_char_t* pCopy = (dbr_char_t *) new char [sizeof(dbr_char_t)*count]; - memcpy (pCopy,sv,sizeof(dbr_char_t)*count); - dd->putRef(pCopy, new gddDestructor); - } else { - dd=new gddScalar(gddDbrToAit[DBR_CHAR].app); - dd->unreference(); - *dd=*sv; - } - return dd; -} - -static int mapGddToChar(void* vd, aitIndex count, - const gdd & dd, const gddEnumStringTable &enumStringTable) { - dbr_char_t* sv = (dbr_char_t*)vd; - aitIndex sz=dd.getDataSizeElements(); - const void* v = dd.dataVoid(); - int status; - - if (count>sz) { - memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); - count = sz; - } - - if (local_data_format==aitLocalDataFormat) { - if((dbr_char_t*)v!=sv) { - status = aitConvert(aitEnumInt8,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - else { - status = sz*sizeof(dbr_char_t); - } - } - else { - status = aitConvertToNet(aitEnumInt8,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - - return status; -} - -static smartGDDPointer mapLongToGdd(void* v,aitIndex count) { - dbr_long_t* sv = (dbr_long_t*)v; - smartGDDPointer dd; - - if(count>1) { - dd=new gddAtomic(gddDbrToAit[DBR_LONG].app, - gddDbrToAit[DBR_LONG].type,1,count); - dd->unreference(); - dbr_long_t* pCopy = (dbr_long_t*) new char [sizeof(dbr_long_t)*count]; - memcpy (pCopy,sv,sizeof(dbr_long_t)*count); - dd->putRef(pCopy, new gddDestructor); - } else { - dd=new gddScalar(gddDbrToAit[DBR_LONG].app); - dd->unreference(); - *dd=*sv; - } - return dd; -} - -static int mapGddToLong(void* vd, aitIndex count, const gdd & dd, - const gddEnumStringTable &enumStringTable) { - dbr_long_t* sv = (dbr_long_t*)vd; - aitIndex sz=dd.getDataSizeElements(); - const void* v = dd.dataVoid(); - int status; - - if (count>sz) { - memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); - count = sz; - } - - if (local_data_format==aitLocalDataFormat) { - if ((dbr_long_t*)v!=sv) { - status = aitConvert(aitEnumInt32,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - else { - status = count*sizeof(dbr_long_t); - } - } - else { - status = aitConvertToNet(aitEnumInt32,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - - return status; -} - -static smartGDDPointer mapDoubleToGdd(void* v,aitIndex count) { - dbr_double_t* sv = (dbr_double_t*)v; - smartGDDPointer dd; - - if(count>1) { - dd=new gddAtomic(gddDbrToAit[DBR_DOUBLE].app, - gddDbrToAit[DBR_DOUBLE].type,1,count); - dd->unreference(); - dbr_double_t* pCopy = (dbr_double_t *) new char [sizeof(dbr_double_t)*count]; - memcpy (pCopy,sv,sizeof(dbr_double_t)*count); - dd->putRef(pCopy, new gddDestructor); - } else { - dd=new gddScalar(gddDbrToAit[DBR_DOUBLE].app); - dd->unreference(); - *dd=*sv; - } - return dd; -} - -static int mapGddToDouble(void* vd, aitIndex count, const gdd & dd, - const gddEnumStringTable &enumStringTable) { - dbr_double_t* sv = (dbr_double_t*)vd; - aitIndex sz=dd.getDataSizeElements(); - const void* v = dd.dataVoid(); - int status; - - if (count>sz) { - memset (sv+sz, '\0', sizeof(*sv)*(count-sz)); - count = sz; - } - - if (local_data_format==aitLocalDataFormat) { - if ((dbr_double_t*)v!=sv) { - status = aitConvert(aitEnumFloat64,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - else { - status = count*sizeof(dbr_double_t); - } - } - else { - status = aitConvertToNet(aitEnumFloat64,sv, - dd.primitiveType(),v,count, &enumStringTable); - } - - return status; -} - -// ******************************************************************** -// sts structure mappings -// ******************************************************************** - -static smartGDDPointer mapStsStringToGdd(void* v,aitIndex count) -{ - dbr_sts_string* db = (dbr_sts_string*)v; - aitFixedString* dbv = (aitFixedString*)db->value; - aitEnum to_type = gddDbrToAit[DBR_STS_STRING].type; - aitUint16 to_app = gddDbrToAit[DBR_STS_STRING].app; - smartGDDPointer dd; - - if(count<=1) - { - dd=new gddScalar(to_app,to_type); - dd->unreference(); - dd->put(*dbv); - } - else - { - dd=new gddAtomic(to_app,to_type,1,count); - dd->unreference(); - aitFixedString* pCopy = (aitFixedString*) new char [sizeof(aitFixedString)*count]; - memcpy (pCopy,dbv,sizeof(aitFixedString)*count); - dd->putRef(pCopy, new gddDestructor); - } - - dd->setStatSevr(db->status,db->severity); - return dd; -} - -static int mapStsGddToString(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_sts_string* db = (dbr_sts_string*)v; - aitFixedString* dbv = (aitFixedString*)db->value; - - dd.getStatSevr(db->status,db->severity); - return mapGddToString(dbv, count, dd, enumStringTable); -} - -static smartGDDPointer mapStsShortToGdd(void* v,aitIndex count) -{ - dbr_sts_short* dbv = (dbr_sts_short*)v; - smartGDDPointer dd=mapShortToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - return dd; -} - -static int mapStsGddToShort(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_sts_short* dbv = (dbr_sts_short*)v; - dd.getStatSevr(dbv->status,dbv->severity); - return mapGddToShort(&dbv->value, count, dd, enumStringTable); -} - -static smartGDDPointer mapStsFloatToGdd(void* v,aitIndex count) -{ - dbr_sts_float* dbv = (dbr_sts_float*)v; - smartGDDPointer dd=mapFloatToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - return dd; -} - -static int mapStsGddToFloat(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_sts_float* dbv = (dbr_sts_float*)v; - dd.getStatSevr(dbv->status,dbv->severity); - return mapGddToFloat(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapStsEnumToGdd(void* v,aitIndex count) -{ - dbr_sts_enum* dbv = (dbr_sts_enum*)v; - smartGDDPointer dd=mapEnumToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - return dd; -} - -static int mapStsGddToEnum(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_sts_enum* dbv = (dbr_sts_enum*)v; - dd.getStatSevr(dbv->status,dbv->severity); - return mapGddToEnum(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapStsCharToGdd(void* v,aitIndex count) -{ - dbr_sts_char* dbv = (dbr_sts_char*)v; - smartGDDPointer dd=mapCharToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - return dd; -} - -static int mapStsGddToChar(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_sts_char* dbv = (dbr_sts_char*)v; - dd.getStatSevr(dbv->status,dbv->severity); - dbv->RISC_pad = '\0'; // shut up purify - return mapGddToChar(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapStsLongToGdd(void* v,aitIndex count) -{ - dbr_sts_long* dbv = (dbr_sts_long*)v; - smartGDDPointer dd=mapLongToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - return dd; -} - -static int mapStsGddToLong(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_sts_long* dbv = (dbr_sts_long*)v; - dd.getStatSevr(dbv->status,dbv->severity); - return mapGddToLong(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapStsDoubleToGdd(void* v,aitIndex count) -{ - dbr_sts_double* dbv = (dbr_sts_double*)v; - smartGDDPointer dd=mapDoubleToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - return dd; -} - -static int mapStsGddToDouble(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_sts_double* dbv = (dbr_sts_double*)v; - dd.getStatSevr(dbv->status,dbv->severity); - dbv->RISC_pad = 0; // shut up purify - return mapGddToDouble(&dbv->value,count,dd, enumStringTable); -} - -// ******************************************************************** -// time structure mappings -// ******************************************************************** - -static smartGDDPointer mapTimeStringToGdd(void* v,aitIndex count) -{ - dbr_time_string* db = (dbr_time_string*)v; - aitFixedString* dbv = (aitFixedString*)db->value; - aitEnum to_type = gddDbrToAit[DBR_TIME_STRING].type; - aitUint16 to_app = gddDbrToAit[DBR_TIME_STRING].app; - smartGDDPointer dd; - - if(count<=1) - { - dd=new gddScalar(to_app,to_type); - dd->unreference(); - dd->put(*dbv); - } - else - { - dd=new gddAtomic(to_app,to_type,1,count); - dd->unreference(); - aitFixedString* pCopy = (aitFixedString*) new char [sizeof(aitFixedString)*count]; - memcpy (pCopy,dbv,sizeof(aitFixedString)*count); - dd->putRef(pCopy, new gddDestructor); - } - - dd->setStatSevr(db->status,db->severity); - dd->setTimeStamp(&db->stamp); - return dd; -} - -static int mapTimeGddToString(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_time_string* db = (dbr_time_string*)v; - aitFixedString* dbv = (aitFixedString*)db->value; - - dd.getStatSevr(db->status,db->severity); - dd.getTimeStamp(&db->stamp); - return mapGddToString(dbv, count, dd, enumStringTable); -} - -static smartGDDPointer mapTimeShortToGdd(void* v,aitIndex count) -{ - dbr_time_short* dbv = (dbr_time_short*)v; - smartGDDPointer dd=mapShortToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - dd->setTimeStamp(&dbv->stamp); - return dd; -} - -static int mapTimeGddToShort(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_time_short* dbv = (dbr_time_short*)v; - dd.getStatSevr(dbv->status,dbv->severity); - dd.getTimeStamp(&dbv->stamp); - dbv->RISC_pad = 0; // shut up purify - return mapGddToShort(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapTimeFloatToGdd(void* v,aitIndex count) -{ - dbr_time_float* dbv = (dbr_time_float*)v; - smartGDDPointer dd=mapFloatToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - dd->setTimeStamp(&dbv->stamp); - return dd; -} - -static int mapTimeGddToFloat(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_time_float* dbv = (dbr_time_float*)v; - dd.getStatSevr(dbv->status,dbv->severity); - dd.getTimeStamp(&dbv->stamp); - return mapGddToFloat(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapTimeEnumToGdd(void* v,aitIndex count) -{ - dbr_time_enum* dbv = (dbr_time_enum*)v; - smartGDDPointer dd=mapEnumToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - dd->setTimeStamp(&dbv->stamp); - return dd; -} - -static int mapTimeGddToEnum(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_time_enum* dbv = (dbr_time_enum*)v; - dd.getStatSevr(dbv->status,dbv->severity); - dd.getTimeStamp(&dbv->stamp); - dbv->RISC_pad = 0; // shut up purify - return mapGddToEnum(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapTimeCharToGdd(void* v,aitIndex count) -{ - dbr_time_char* dbv = (dbr_time_char*)v; - smartGDDPointer dd=mapCharToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - dd->setTimeStamp(&dbv->stamp); - return dd; -} - -static int mapTimeGddToChar(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_time_char* dbv = (dbr_time_char*)v; - dd.getStatSevr(dbv->status,dbv->severity); - dd.getTimeStamp(&dbv->stamp); - dbv->RISC_pad0 = 0; // shut up purify - dbv->RISC_pad1 = '\0'; // shut up purify - return mapGddToChar(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapTimeLongToGdd(void* v,aitIndex count) -{ - dbr_time_long* dbv = (dbr_time_long*)v; - smartGDDPointer dd=mapLongToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - dd->setTimeStamp(&dbv->stamp); - return dd; -} - -static int mapTimeGddToLong(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_time_long* dbv = (dbr_time_long*)v; - dd.getStatSevr(dbv->status,dbv->severity); - dd.getTimeStamp(&dbv->stamp); - return mapGddToLong(&dbv->value,count,dd, enumStringTable); -} - -static smartGDDPointer mapTimeDoubleToGdd(void* v,aitIndex count) -{ - dbr_time_double* dbv = (dbr_time_double*)v; - smartGDDPointer dd=mapDoubleToGdd(&dbv->value,count); - dd->setStatSevr(dbv->status,dbv->severity); - dd->setTimeStamp(&dbv->stamp); - return dd; -} - -static int mapTimeGddToDouble(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - dbr_time_double* dbv = (dbr_time_double*)v; - dd.getStatSevr(dbv->status,dbv->severity); - dd.getTimeStamp(&dbv->stamp); - dbv->RISC_pad = 0; // shut up purify - return mapGddToDouble(&dbv->value,count,dd, enumStringTable); -} - -// ******************************************************************** -// graphic structure mappings -// ******************************************************************** - -// -------------map the short structures---------------- -static smartGDDPointer mapGraphicShortToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_gr_short* db = (dbr_gr_short*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_SHORT].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_short_value]; - - aitString* str=NULL; - (*dd)[gddAppTypeIndex_dbr_gr_short_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_gr_short_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_short_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_short_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_short_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_short_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_gr_short_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); - else vdd.setPrimType(aitEnumInt16); - vdd.setBound(0,0,count); - - dbr_short_t* pCopy = (dbr_short_t*) new char [sizeof(dbr_short_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_short_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static smartGDDPointer mapControlShortToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_ctrl_short* db = (dbr_ctrl_short*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_SHORT].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_short_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_ctrl_short_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_ctrl_short_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_short_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_short_controlLow]=db->lower_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_short_controlHigh]=db->upper_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_short_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_short_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_short_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_short_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumInt16,1,&count); - else vdd.setPrimType(aitEnumInt16); - vdd.setBound(0,0,count); - - dbr_short_t* pCopy = (dbr_short_t*) new char [sizeof(dbr_short_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_short_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static int mapGraphicGddToShort(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_gr_short* db = (dbr_gr_short*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_short_value]; - - dd[gddAppTypeIndex_dbr_gr_short_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_short_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_short_graphicHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_short_alarmHighWarning]; - - vdd.getStatSevr(db->status,db->severity); - return mapGddToShort(&db->value,count,vdd, enumStringTable); -} - -static int mapControlGddToShort(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_ctrl_short* db = (dbr_ctrl_short*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_short_value]; - - dd[gddAppTypeIndex_dbr_ctrl_short_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_short_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_short_graphicHigh]; - db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_short_controlLow]; - db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_short_controlHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_short_alarmHighWarning]; - - vdd.getStatSevr(db->status,db->severity); - return mapGddToShort(&db->value,count,vdd, enumStringTable); -} - -// -------------map the float structures---------------- -static smartGDDPointer mapGraphicFloatToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_gr_float* db = (dbr_gr_float*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_FLOAT].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_float_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_gr_float_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_gr_float_precision]=db->precision; - (*dd)[gddAppTypeIndex_dbr_gr_float_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_float_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_float_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_float_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_float_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_gr_float_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumFloat32,1,&count); - else vdd.setPrimType(aitEnumFloat32); - vdd.setBound(0,0,count); - - dbr_float_t* pCopy = (dbr_float_t*) new char [sizeof(dbr_float_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_float_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static smartGDDPointer mapControlFloatToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_ctrl_float* db = (dbr_ctrl_float*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_FLOAT].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_float_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_ctrl_float_precision]=db->precision; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_controlLow]=db->lower_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_controlHigh]=db->upper_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_float_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumFloat32,1,&count); - else vdd.setPrimType(aitEnumFloat32); - vdd.setBound(0,0,count); - - dbr_float_t* pCopy = (dbr_float_t*) new char [sizeof(dbr_float_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_float_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static int mapGraphicGddToFloat(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_gr_float* db = (dbr_gr_float*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_float_value]; - - dd[gddAppTypeIndex_dbr_gr_float_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->precision=dd[gddAppTypeIndex_dbr_gr_float_precision]; - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_float_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_float_graphicHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_float_alarmHighWarning]; - db->RISC_pad0 = 0; // shut up purify - - vdd.getStatSevr(db->status,db->severity); - return mapGddToFloat(&db->value,count,vdd, enumStringTable); -} - -static int mapControlGddToFloat(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_ctrl_float* db = (dbr_ctrl_float*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_float_value]; - - dd[gddAppTypeIndex_dbr_ctrl_float_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->precision=dd[gddAppTypeIndex_dbr_ctrl_float_precision]; - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_float_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_float_graphicHigh]; - db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_float_controlLow]; - db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_float_controlHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_float_alarmHighWarning]; - db->RISC_pad = 0; // shut up purify - - vdd.getStatSevr(db->status,db->severity); - return mapGddToFloat(&db->value,count,vdd, enumStringTable); -} - -// -------------map the enum structures---------------- -static smartGDDPointer mapGraphicEnumToGdd(void* v, aitIndex /*count*/) -{ - dbr_gr_enum* db = (dbr_gr_enum*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_ENUM].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_enum_value]; - gdd& menu = (*dd)[gddAppTypeIndex_dbr_gr_enum_enums]; - aitFixedString* str = menu; - //aitFixedString* f = (aitFixedString*)db->strs; - aitIndex sz,i; - - // int i; - // old way using aitString menu - // for(i=0;ino_str;i++) str[i]=((const char*)&(db->strs[i][0])); - - if(menu.dataPointer()==NULL || !menu.isAtomic()) - { - // need to copy the menu chunk from dbr to aitFixedString chunk - menu.setDimension(1); - sz=db->no_str; - str=new aitFixedString[db->no_str]; - menu.putRef(str,new dbMapperFixedStringDestructor); - } - else - { - if((sz=menu.getDataSizeElements())>(aitIndex)db->no_str) - sz=db->no_str; - } - - unsigned minl = epicsMin(sizeof(aitFixedString),sizeof(str[0].fixed_string)) - 1; - for (i=0;istrs[i][0]), minl); - memset(&str[i].fixed_string[minl], '\0', sizeof(aitFixedString)-minl); - } - menu.setBound(0,0,sz); - - // should always be a scaler - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - vdd.setStatSevr(db->status,db->severity); - return dd; -} - -static smartGDDPointer mapControlEnumToGdd(void* v, aitIndex /*count*/) -{ - dbr_ctrl_enum* db = (dbr_ctrl_enum*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_ENUM].app); - gdd& menu = (*dd)[gddAppTypeIndex_dbr_ctrl_enum_enums]; - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_enum_value]; - aitFixedString* str = menu; - //aitFixedString* f = (aitFixedString*)db->strs; - aitIndex sz,i; - - // int i; - // old way using aitString menu - // for(i=0;ino_str;i++) str[i]=((const char*)&(db->strs[i][0])); - - if(menu.dataPointer()==NULL || !menu.isAtomic()) - { - // need to copy the menu chunk from dbr to aitFixedString chunk - menu.setDimension(1); - sz=db->no_str; - str=new aitFixedString[db->no_str]; - menu.putRef(str,new dbMapperFixedStringDestructor); - } - else - { - if((sz=menu.getDataSizeElements())>(aitIndex)db->no_str) - sz=db->no_str; - } - - unsigned minl = epicsMin(sizeof(aitFixedString),(size_t)MAX_ENUM_STRING_SIZE) - 1; - for (i=0;istrs[i][0]), minl); - memset(&str[i].fixed_string[minl], '\0', sizeof(aitFixedString)-minl); - } - menu.setBound(0,0,sz); - - // should always be a scaler - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - vdd.setStatSevr(db->status,db->severity); - return dd; -} - -static int mapGraphicGddToEnum ( - void * v, aitIndex count, const gdd & dd, - const gddEnumStringTable & enumStringTable ) -{ - dbr_gr_enum * db = ( dbr_gr_enum * ) v; - const gdd & vdd = dd[gddAppTypeIndex_dbr_gr_enum_value]; - - vdd.getStatSevr ( db->status, db->severity ); - unsigned noStr = enumStringTable.numberOfStrings (); - if ( noStr < MAX_ENUM_STATES ) { - db->no_str = static_cast < dbr_short_t > ( noStr ); - } - else { - db->no_str = MAX_ENUM_STATES; - } - for ( int i=0; i < db->no_str; i++ ) { - enumStringTable.getString ( i, - &(db->strs[i][0]), MAX_ENUM_STRING_SIZE ); - } - for ( int j = db->no_str; j < MAX_ENUM_STATES; j++ ) { - db->strs[j][0] = '\0'; - } - return mapGddToEnum ( &db->value, - count, vdd, enumStringTable ); -} - -static int mapControlGddToEnum ( - void * v, aitIndex count, const gdd & dd, - const gddEnumStringTable & enumStringTable ) -{ - dbr_ctrl_enum* db = ( dbr_ctrl_enum * ) v; - const gdd & vdd = dd[gddAppTypeIndex_dbr_ctrl_enum_value]; - - vdd.getStatSevr ( db->status, db->severity ); - unsigned noStr = enumStringTable.numberOfStrings (); - if ( noStr < MAX_ENUM_STATES ) { - db->no_str = static_cast < dbr_short_t > ( noStr ); - } - else { - db->no_str = MAX_ENUM_STATES; - } - for ( int i=0; i < db->no_str; i++ ) { - enumStringTable.getString ( i, - &(db->strs[i][0]), MAX_ENUM_STRING_SIZE ); - } - for ( int j = db->no_str; j < MAX_ENUM_STATES; j++ ) { - db->strs[j][0] = '\0'; - } - return mapGddToEnum ( &db->value, - count, vdd, enumStringTable ); -} - -// -------------map the char structures---------------- -static smartGDDPointer mapGraphicCharToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_gr_char* db = (dbr_gr_char*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_CHAR].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_char_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_gr_char_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_gr_char_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_char_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_char_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_char_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_char_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_gr_char_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumInt8,1,&count); - else vdd.setPrimType(aitEnumInt8); - vdd.setBound(0,0,count); - - dbr_char_t* pCopy = (dbr_char_t *) new char [sizeof(dbr_char_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_char_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static smartGDDPointer mapControlCharToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_ctrl_char* db = (dbr_ctrl_char*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_CHAR].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_char_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_ctrl_char_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_ctrl_char_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_char_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_char_controlLow]=db->lower_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_char_controlHigh]=db->upper_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_char_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_char_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_char_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_char_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumInt8,1,&count); - else vdd.setPrimType(aitEnumInt8); - vdd.setBound(0,0,count); - - dbr_char_t* pCopy = (dbr_char_t*) new char [sizeof(dbr_char_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_char_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static int mapGraphicGddToChar(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_gr_char* db = (dbr_gr_char*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_char_value]; - - dd[gddAppTypeIndex_dbr_gr_char_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_char_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_char_graphicHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_char_alarmHighWarning]; - db->RISC_pad = 0; - - vdd.getStatSevr(db->status,db->severity); - return mapGddToChar(&db->value,count,vdd, enumStringTable); -} - -static int mapControlGddToChar(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_ctrl_char* db = (dbr_ctrl_char*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_char_value]; - - dd[gddAppTypeIndex_dbr_ctrl_char_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_char_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_char_graphicHigh]; - db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_char_controlLow]; - db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_char_controlHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_char_alarmHighWarning]; - db->RISC_pad = '\0'; // shut up purify - - vdd.getStatSevr(db->status,db->severity); - return mapGddToChar(&db->value,count,vdd, enumStringTable); -} - -// -------------map the long structures---------------- -static smartGDDPointer mapGraphicLongToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_gr_long* db = (dbr_gr_long*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_LONG].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_long_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_gr_long_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_gr_long_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_long_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_long_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_long_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_long_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_gr_long_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumInt32,1,&count); - else vdd.setPrimType(aitEnumInt32); - vdd.setBound(0,0,count); - - dbr_long_t* pCopy = (dbr_long_t*) new char [sizeof(dbr_long_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_long_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static smartGDDPointer mapControlLongToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_ctrl_long* db = (dbr_ctrl_long*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_LONG].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_long_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_ctrl_long_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_ctrl_long_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_long_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_long_controlLow]=db->lower_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_long_controlHigh]=db->upper_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_long_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_long_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_long_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_long_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumInt32,1,&count); - else vdd.setPrimType(aitEnumInt32); - vdd.setBound(0,0,count); - - dbr_long_t* pCopy = (dbr_long_t *)new char [sizeof(dbr_long_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_long_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static int mapGraphicGddToLong(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_gr_long* db = (dbr_gr_long*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_long_value]; - - dd[gddAppTypeIndex_dbr_gr_long_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_long_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_long_graphicHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_long_alarmHighWarning]; - - vdd.getStatSevr(db->status,db->severity); - return mapGddToLong(&db->value,count,vdd, enumStringTable); -} - -static int mapControlGddToLong(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_ctrl_long* db = (dbr_ctrl_long*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_long_value]; - - dd[gddAppTypeIndex_dbr_ctrl_long_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_long_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_long_graphicHigh]; - db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_long_controlLow]; - db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_long_controlHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_long_alarmHighWarning]; - - vdd.getStatSevr(db->status,db->severity); - return mapGddToLong(&db->value,count,vdd, enumStringTable); -} - -// -------------map the double structures---------------- -static smartGDDPointer mapGraphicDoubleToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_gr_double* db = (dbr_gr_double*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_GR_DOUBLE].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_gr_double_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_gr_double_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_gr_double_precision]=db->precision; - (*dd)[gddAppTypeIndex_dbr_gr_double_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_double_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_gr_double_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_double_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_gr_double_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_gr_double_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumFloat64,1,&count); - else vdd.setPrimType(aitEnumFloat64); - vdd.setBound(0,0,count); - - dbr_double_t* pCopy = (dbr_double_t *) new char [sizeof(dbr_double_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_double_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static smartGDDPointer mapControlDoubleToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_ctrl_double* db = (dbr_ctrl_double*)v; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_CTRL_DOUBLE].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_ctrl_double_value]; - - aitString* str = NULL; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_units].getRef(str); - str->copy(db->units); - - (*dd)[gddAppTypeIndex_dbr_ctrl_double_precision]=db->precision; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_graphicLow]=db->lower_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_graphicHigh]=db->upper_disp_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_controlLow]=db->lower_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_controlHigh]=db->upper_ctrl_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_alarmLow]=db->lower_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_alarmHigh]=db->upper_alarm_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_alarmLowWarning]=db->lower_warning_limit; - (*dd)[gddAppTypeIndex_dbr_ctrl_double_alarmHighWarning]=db->upper_warning_limit; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd=db->value; - } else { - if(vdd.dimension()!=1) vdd.reset(aitEnumFloat64,1,&count); - else vdd.setPrimType(aitEnumFloat64); - vdd.setBound(0,0,count); - - dbr_double_t* pCopy = (dbr_double_t *) new char [sizeof(dbr_double_t)*count]; - memcpy (pCopy,&db->value,sizeof(dbr_double_t)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static int mapGraphicGddToDouble(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_gr_double* db = (dbr_gr_double*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_gr_double_value]; - - dd[gddAppTypeIndex_dbr_gr_double_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->precision=dd[gddAppTypeIndex_dbr_gr_double_precision]; - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_gr_double_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_gr_double_graphicHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_gr_double_alarmHighWarning]; - db->RISC_pad0 = 0; // shut up purify - - vdd.getStatSevr(db->status,db->severity); - return mapGddToDouble(&db->value,count,vdd, enumStringTable); -} - -static int mapControlGddToDouble(void* v, aitIndex count, const gdd & dd, const gddEnumStringTable &enumStringTable) -{ - const aitString* str; - dbr_ctrl_double* db = (dbr_ctrl_double*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_ctrl_double_value]; - - dd[gddAppTypeIndex_dbr_ctrl_double_units].getRef(str); - if(str->string()) { - strncpy(db->units,str->string(), sizeof(db->units)); - db->units[sizeof(db->units)-1u] = '\0'; - } - - db->precision=dd[gddAppTypeIndex_dbr_ctrl_double_precision]; - db->lower_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_double_graphicLow]; - db->upper_disp_limit=dd[gddAppTypeIndex_dbr_ctrl_double_graphicHigh]; - db->lower_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_double_controlLow]; - db->upper_ctrl_limit=dd[gddAppTypeIndex_dbr_ctrl_double_controlHigh]; - db->lower_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmLow]; - db->upper_alarm_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmHigh]; - db->lower_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmLowWarning]; - db->upper_warning_limit=dd[gddAppTypeIndex_dbr_ctrl_double_alarmHighWarning]; - db->RISC_pad0 = '\0'; // shut up purify - - vdd.getStatSevr(db->status,db->severity); - return mapGddToDouble(&db->value,count,vdd, enumStringTable); -} - -static smartGDDPointer mapStsAckStringToGdd(void* v, aitIndex count) -{ - // must be a container - dbr_stsack_string* db = (dbr_stsack_string*)v; - aitFixedString* dbv = (aitFixedString*)db->value; - smartGDDPointer dd = type_table->getDD(gddDbrToAit[DBR_STSACK_STRING].app); - gdd& vdd = (*dd)[gddAppTypeIndex_dbr_stsack_string_value]; - - (*dd)[gddAppTypeIndex_dbr_stsack_string_ackt]=db->ackt; - (*dd)[gddAppTypeIndex_dbr_stsack_string_acks]=db->acks; - - vdd.setStatSevr(db->status,db->severity); - - if(count==1) { - if(vdd.dimension()) vdd.clear(); - vdd.put(*dbv); - } else { - if(vdd.dimension()!=1) - vdd.reset(aitEnumFixedString,1,&count); - else vdd.setPrimType(aitEnumFixedString); - vdd.setBound(0,0,count); - - aitFixedString* pCopy = (aitFixedString*) new char [sizeof(aitFixedString)*count]; - memcpy (pCopy,&db->value,sizeof(aitFixedString)*count); - vdd.putRef(pCopy, new gddDestructor); - } - return dd; -} - -static int mapStsAckGddToString(void* v, aitIndex count, const gdd &dd, - const gddEnumStringTable &enumStringTable) -{ - dbr_stsack_string* db = (dbr_stsack_string*)v; - const gdd& vdd = dd[gddAppTypeIndex_dbr_stsack_string_value]; - - db->ackt=dd[gddAppTypeIndex_dbr_stsack_string_ackt]; - db->acks=dd[gddAppTypeIndex_dbr_stsack_string_acks]; - - // Unlike all the others, which are dbr_short_t, status and - // severity for a dbr_stsack_string are dbr_ushort_t. Have to - // convert. - dbr_short_t st,sv; - vdd.getStatSevr(st,sv); - db->status = (dbr_ushort_t)st; - db->severity = (dbr_ushort_t)sv; - return mapGddToString (&db->value, count, vdd, enumStringTable); -} - -// -------------map the ack elements -------------------- -static smartGDDPointer mapAcktToGdd(void* v,aitIndex count) { - dbr_put_ackt_t* sv = (dbr_put_ackt_t*)v; - smartGDDPointer dd; - - // Count should be 1, but leave it general - if(count>1) { - dd=new gddAtomic(gddDbrToAit[DBR_PUT_ACKT].app, - gddDbrToAit[DBR_PUT_ACKT].type,1,count); - dd->unreference(); - dbr_put_ackt_t* pCopy = (dbr_put_ackt_t*) new char [sizeof(dbr_put_ackt_t)*count]; - memcpy (pCopy,sv,sizeof(dbr_put_ackt_t)*count); - dd->putRef(pCopy, new gddDestructor); - } else { - dd=new gddScalar(gddDbrToAit[DBR_PUT_ACKT].app); - dd->unreference(); - *dd=*sv; - } - return dd; -} - -static int mapGddToAckt(void* vd, aitIndex count, const gdd & dd, - const gddEnumStringTable &enumStringTable) { - dbr_put_ackt_t* sv = (dbr_put_ackt_t*)vd; - aitIndex sz = dd.getDataSizeElements(); - const void* v=dd.dataVoid(); - int status; - - // Count should be 1, but leave it general - if (count==sz) { - if (local_data_format==aitLocalDataFormat) { - if((dbr_put_ackt_t*)v!=sv) { - status = - aitConvert(aitEnumUint16,sv, - dd.primitiveType(),v,sz,&enumStringTable); - } - else { - status = sz*sizeof(dbr_put_ackt_t); - } - } - else { - status = - aitConvertToNet(aitEnumUint16,sv, - dd.primitiveType(),v,sz, &enumStringTable); - } - } - else { - status = -1; - } - - return status; -} - -static smartGDDPointer mapAcksToGdd(void* v,aitIndex count) { - dbr_put_acks_t* sv = (dbr_put_acks_t*)v; - smartGDDPointer dd; - - // Count should be 1, but leave it general - if(count>1) { - dd=new gddAtomic(gddDbrToAit[DBR_PUT_ACKS].app, - gddDbrToAit[DBR_PUT_ACKS].type,1,count); - dd->unreference(); - dbr_put_acks_t* pCopy = (dbr_put_acks_t*) new char [sizeof(dbr_put_acks_t)*count]; - memcpy (pCopy,sv,sizeof(dbr_put_acks_t)*count); - dd->putRef(pCopy, new gddDestructor); - } else { - dd=new gddScalar(gddDbrToAit[DBR_PUT_ACKS].app); - dd->unreference(); - *dd=*sv; - } - return dd; -} - -static int mapGddToAcks(void* vd, aitIndex count, const gdd &dd, - const gddEnumStringTable &enumStringTable) { - dbr_put_acks_t* sv = (dbr_put_acks_t*)vd; - aitIndex sz = dd.getDataSizeElements(); - const void* v=dd.dataVoid(); - int status; - - // Count should be 1, but leave it general - if (count==sz) { - if (local_data_format==aitLocalDataFormat) { - if((dbr_put_acks_t*)v!=sv) { - status = - aitConvert(aitEnumUint16,sv, - dd.primitiveType(),v,sz, &enumStringTable); - } - else { - status = sz*sizeof(dbr_put_acks_t); - } - } - else { - status = - aitConvertToNet(aitEnumUint16,sv, - dd.primitiveType(),v,sz, &enumStringTable); - } - } - else { - status = -1; - } - - return status; -} - -// -------------map the class name element -------------- - -static smartGDDPointer mapClassNameToGdd(void* v,aitIndex count) { - aitFixedString* db = (aitFixedString*)v; - aitEnum to_type = gddDbrToAit[DBR_CLASS_NAME].type; - aitUint16 to_app = gddDbrToAit[DBR_CLASS_NAME].app; - smartGDDPointer dd; - - // Count should be 1, but leave it general - if(count<=1) - { - dd=new gddScalar(to_app,to_type); - dd->unreference(); - dd->put(*db); - } - else - { - dd=new gddAtomic(to_app,to_type,1,count); - dd->unreference(); - aitFixedString* pCopy = (aitFixedString*) new char [sizeof(aitFixedString)*count]; - memcpy (pCopy,db,sizeof(aitFixedString)*count); - dd->putRef(pCopy, new gddDestructor); - } - return dd; -} - -static int mapGddToClassName(void* vd, aitIndex count, const gdd & dd, - const gddEnumStringTable &enumStringTable) { - aitFixedString* db = (aitFixedString*)vd; - aitIndex sz = dd.getDataSizeElements(); - const void* v = dd.dataVoid(); - int status; - - // Count should be 1, but leave it general - if (count<=sz) { - if(local_data_format==aitLocalDataFormat) { - if((aitFixedString*)v!=db) { - status = - aitConvert(aitEnumFixedString,db, - dd.primitiveType(),v,count, &enumStringTable); - } - else { - status = sz*sizeof(aitFixedString); - } - } - else { - status = - aitConvertToNet(aitEnumFixedString,db, - dd.primitiveType(),v,count, &enumStringTable); - } - } - else { - status = -1; - } - - return status; -} - - -// ----------------must run this to use mapping functions-------------- -epicsShareFunc void gddMakeMapDBR(gddApplicationTypeTable& tt) { gddMakeMapDBR(&tt); } -epicsShareFunc void gddMakeMapDBR(gddApplicationTypeTable* tt) -{ - type_table=tt; - size_t i; - - // Storing the DBRxxx type code in the app table will not work - // for most of the types. This is because many share the same - // app type "value", this includes the normal, sts, and time structures - - for(i=0;igetApplicationType(gddDbrToAit[i].app_name); - tt->storeValue(gddDbrToAit[i].app,i); - } -} - -// -// dbMapperFixedStringDestructor::run() -// -// special gddDestructor guarantees same form of new and delete -// -void dbMapperFixedStringDestructor::run (void *pUntyped) -{ - aitFixedString *ps = (aitFixedString *) pUntyped; - delete [] ps; -} - -// An array of one function per DBR structure is provided here so conversions -// can take place quickly by knowing the DBR enumerated type. -// -// C++ will not make a const decl external linkage unless -// we explicitly specify extern -// -extern epicsShareDef const gddDbrMapFuncTable gddMapDbr[DBM_N_DBR_TYPES] = { - { mapStringToGdd, mapGddToString }, // DBR_STRING - { mapShortToGdd, mapGddToShort }, // DBR_SHORT - { mapFloatToGdd, mapGddToFloat }, // DBR_FLOAT - { mapEnumToGdd, mapGddToEnum }, // DBR_ENUM - { mapCharToGdd, mapGddToChar }, // DBR_CHAR - { mapLongToGdd, mapGddToLong }, // DBR_LONG - { mapDoubleToGdd, mapGddToDouble }, // DBR_DOUBLE - { mapStsStringToGdd, mapStsGddToString }, // DBR_STS_STRING - { mapStsShortToGdd, mapStsGddToShort }, // DBR_STS_SHORT - { mapStsFloatToGdd, mapStsGddToFloat }, // DBR_STS_FLOAT - { mapStsEnumToGdd, mapStsGddToEnum }, // DBR_STS_ENUM - { mapStsCharToGdd, mapStsGddToChar }, // DBR_STS_CHAR - { mapStsLongToGdd, mapStsGddToLong }, // DBR_STS_LONG - { mapStsDoubleToGdd, mapStsGddToDouble }, // DBR_STS_DOUBLE - { mapTimeStringToGdd, mapTimeGddToString }, // DBR_TIME_STRING - { mapTimeShortToGdd, mapTimeGddToShort }, // DBR_TIME_SHORT - { mapTimeFloatToGdd, mapTimeGddToFloat }, // DBR_TIME_FLOAT - { mapTimeEnumToGdd, mapTimeGddToEnum }, // DBR_TIME_ENUM - { mapTimeCharToGdd, mapTimeGddToChar }, // DBR_TIME_CHAR - { mapTimeLongToGdd, mapTimeGddToLong }, // DBR_TIME_LONG - { mapTimeDoubleToGdd, mapTimeGddToDouble }, // DBR_TIME_DOUBLE - { mapStsStringToGdd, mapStsGddToString }, // DBR_GR_STRING - { mapGraphicShortToGdd, mapGraphicGddToShort }, // DBR_GR_SHORT - { mapGraphicFloatToGdd, mapGraphicGddToFloat }, // DBR_GR_FLOAT - { mapGraphicEnumToGdd, mapGraphicGddToEnum }, // DBR_GR_ENUM - { mapGraphicCharToGdd, mapGraphicGddToChar }, // DBR_GR_CHAR - { mapGraphicLongToGdd, mapGraphicGddToLong }, // DBR_GR_LONG - { mapGraphicDoubleToGdd,mapGraphicGddToDouble }, // DBR_GR_DOUBLE - { mapStsStringToGdd, mapStsGddToString }, // DBR_CTRL_STRING - { mapControlShortToGdd, mapControlGddToShort }, // DBR_CTRL_SHORT - { mapControlFloatToGdd, mapControlGddToFloat }, // DBR_CTRL_FLOAT - { mapControlEnumToGdd, mapControlGddToEnum }, // DBR_CTRL_ENUM - { mapControlCharToGdd, mapControlGddToChar }, // DBR_CTRL_CHAR - { mapControlLongToGdd, mapControlGddToLong }, // DBR_CTRL_LONG - { mapControlDoubleToGdd,mapControlGddToDouble }, // DBR_CTRL_DOUBLE - { mapAcktToGdd, mapGddToAckt }, // DBR_PUT_ACKT - { mapAcksToGdd, mapGddToAcks }, // DBR_PUT_ACKS - { mapStsAckStringToGdd, mapStsAckGddToString }, // DBR_STSACK_STRING - { mapClassNameToGdd, mapGddToClassName } // DBR_CLASS_NAME -}; - -#if DBM_N_DBR_TYPES != (LAST_BUFFER_TYPE+1) -#error db mapper is out of sync with db_access.h -#endif - -extern epicsShareDef const unsigned gddMapDbrNElem = - sizeof(gddMapDbr)/sizeof(gddDbrToAit[0]); - diff --git a/src/ca/legacy/gdd/dbMapper.h b/src/ca/legacy/gdd/dbMapper.h deleted file mode 100644 index c059c8386..000000000 --- a/src/ca/legacy/gdd/dbMapper.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. -\*************************************************************************/ -#ifndef DB_MAPPER_H -#define DB_MAPPER_H - -/* - * Author: Jim Kowalkowski - * Date: 2/96 - */ - -#include "shareLib.h" -#include "aitTypes.h" -#include "gdd.h" -#include "smartGDDPointer.h" - -#include "db_access.h" -#include "cadef.h" - -class gddApplicationTypeTable; - -// Function proto to convert from a db_struct to a gdd. The gdd will -// reference the data in the db_struct if the db_struct points to an -// array. The second argument is the number of elements if db_struct -// represents an array, or zero if the db_struct is a scalar. -typedef smartGDDPointer (*to_gdd)(void* db_struct, aitIndex element_count); - -// Function proto to convert from a gdd to a dbr structure, returns the -// number of elements that the value field of db_struct points to if the -// gdd points to an array or -1 if the number of elements in the value -// field is not identical to element_count available in db_struct. -typedef int (*to_dbr)(void* db_struct, aitIndex element_count, - const gdd &, const gddEnumStringTable &enumStringTable); - -struct gddDbrMapFuncTable { - to_gdd conv_gdd; - to_dbr conv_dbr; -}; -typedef struct gddDbrMapFuncTable gddDbrMapFuncTable; - -struct gddDbrToAitTable { - aitEnum type; - aitUint16 app; - const char* app_name; -}; -typedef struct gddDbrToAitTable gddDbrToAitTable; - -#define DBM_N_DBR_TYPES 39 -epicsShareExtern gddDbrToAitTable gddDbrToAit[DBM_N_DBR_TYPES]; -epicsShareExtern const int gddAitToDbr[aitConvertLast+1]; -epicsShareExtern const gddDbrMapFuncTable gddMapDbr[DBM_N_DBR_TYPES]; - -epicsShareFunc void gddMakeMapDBR(gddApplicationTypeTable& tt); -epicsShareFunc void gddMakeMapDBR(gddApplicationTypeTable* tt); - -#endif - diff --git a/src/ca/legacy/gdd/gdd.cc b/src/ca/legacy/gdd/gdd.cc deleted file mode 100644 index acb53da4e..000000000 --- a/src/ca/legacy/gdd/gdd.cc +++ /dev/null @@ -1,1827 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 -// Date: 2/96 - -#include -#include -#include - -#include -#include - -#define epicsExportSharedSymbols -#include "gdd.h" - -gdd_NEWDEL_NEW(gdd) -gdd_NEWDEL_DEL(gdd) -gdd_NEWDEL_STAT(gdd) - -epicsMutex * gdd::pGlobalMutex; - -static epicsThreadOnceId gddOnce = EPICS_THREAD_ONCE_INIT; - -class gddFlattenDestructor : public gddDestructor -{ -public: - gddFlattenDestructor(void) { } - gddFlattenDestructor(void* user_arg):gddDestructor(user_arg) { } - void run(void*); -}; - -class gddContainerCleaner : public gddDestructor -{ -public: - gddContainerCleaner(void) { } - gddContainerCleaner(void* user_arg):gddDestructor(user_arg) { } - void run(void*); -}; - -void gddFlattenDestructor::run(void*) -{ - return; -} - -void gddContainerCleaner::run(void* v) -{ - gddContainer* cdd = (gddContainer*)v; - int tot = cdd->total(); - int i; - for(i=0;iremove(0); -} - -// -// special gddDestructor guarantees same form of new and delete -// -class gddAitUint8Destructor: public gddDestructor { - virtual void run (void *); -}; - -// -// special gddDestructor guarantees same form of new and delete -// -class gddAitStringDestructor: public gddDestructor { - virtual void run (void *); -}; - -// --------------------------The gdd functions------------------------- - -extern "C" void gddStaticInit ( void * p ) -{ - epicsMutex * * pMutex = static_cast < epicsMutex * * > ( p ); - *pMutex = newEpicsMutex; -} - -gdd::gdd(int app, aitEnum prim, int dimen) -{ - init(app,prim,dimen); -} - -gdd::gdd(int app, aitEnum prim, int dimen, aitUint32* val) -{ - init(app,prim,dimen); - for(int i=0;iprim_type = prim; - dim=(aitUint8)dimen; - destruct=NULL; - ref_cnt=1; - flags=0; - bounds=NULL; - setStatSevr(0u,0u); - - if(dim) - { - switch(dim) - { - case 1: bounds=(gddBounds*)new gddBounds1D; bounds->set(0,0); break; - case 2: bounds=(gddBounds*)new gddBounds2D; break; - case 3: bounds=(gddBounds*)new gddBounds3D; break; - default: bounds=(gddBounds*)new gddBounds[dim]; break; - } - memset ( & this->data, '\0', sizeof ( this->data ) ); - } - else if(primitiveType()==aitEnumString) - { - aitString* str=(aitString*)dataAddress(); - str->init(); - } - else if (primitiveType()==aitEnumFixedString) - { - this->data.FString = new aitFixedString; - memset ( this->data.FString, '\0', sizeof(aitFixedString) ); - } - else { - memset ( & this->data, '\0', sizeof ( this->data ) ); - } -} - -gdd::gdd(gdd* dd) -{ - // - // added this because the "copy()" below bombs - // if the GDD isnt initialized - // joh - 4-23-99 - // - this->init (dd->appl_type, dd->primitiveType(), dd->dimension()); - - copyInfo(dd); -} - -gdd::~gdd(void) -{ - gdd* dd; - gdd* temp; - - // fprintf(stderr,"A gdd is really being deleted %8.8x!!\n",this); - - if(isContainer()) - { - if(destruct) - destruct->destroy(dataPointer()); - else - { - for(dd=(gdd*)dataPointer();dd;) - { - temp=dd; - dd=dd->next(); - temp->unreference(); - } - freeBounds(); - } - } - else if(isAtomic()) - { - if(destruct) destruct->destroy(dataPointer()); - if(bounds) freeBounds(); - } - else - { - // - // this destroys any scalar string data that may be present - // - this->setPrimType (aitEnumInvalid); - } - this->setApplType (0); - memset ( & this->data, '\0', sizeof ( this->data ) ); -} - -// this routine is private so we dont need to initialize -// string data when changing to a scalar, but we do need -// to be careful about how it is called -void gdd::freeBounds(void) -{ - if(bounds) - { - switch(dim) - { - case 0: - fprintf ( stderr, "gdd: freeing bounds, bounds exist, but gdd is scalar?\n" ); - break; - case 1: { gddBounds1D* d1=(gddBounds1D*)bounds; delete d1; } break; - case 2: { gddBounds2D* d2=(gddBounds2D*)bounds; delete d2; } break; - case 3: { gddBounds3D* d3=(gddBounds3D*)bounds; delete d3; } break; - default: delete [] bounds; break; - } - bounds=NULL; - } - dim=0; -} - -void gdd::setDimension(int d, const gddBounds* bnds) -{ - if ( dim != 0 ) { - if ( isFlat() || isManaged() ) { - throw std::logic_error ( - "sorry: cant change the bounds on an atomic, managed or flat gdd" ); - } - } - if(dim!=d) - { - if ( dim == 0 ) { - // run destructors for scalar string data - if ( primitiveType() == aitEnumFixedString ) - { - // aitString type could have destructors - if ( destruct ) { - destruct->destroy(dataPointer()); - destruct = 0; - } - else - if (data.FString) delete data.FString; - } - else if ( primitiveType() == aitEnumString ) - { - // aitString type could have destructors - if ( destruct ) { - destruct->destroy(dataAddress()); - destruct = 0; - } - else - { - aitString* s = (aitString*)dataAddress(); - s->clear(); - } - } - // changing from scalar to vector so set the - // vector pointer to nill - memset ( & this->data, '\0', sizeof ( this->data ) ); - } - else { - this->freeBounds(); - } - dim=(aitUint8)d; - switch(dim) - { - case 0: bounds=0; break; - case 1: bounds=(gddBounds*)new gddBounds1D; bounds->set(0,0); break; - case 2: bounds=(gddBounds*)new gddBounds2D; break; - case 3: bounds=(gddBounds*)new gddBounds3D; break; - default: bounds=(gddBounds*)new gddBounds[dim]; break; - } - if ( dim == 0 ) { - if ( destruct ) { - destruct->destroy(dataAddress()); - destruct = 0; - } - // run constructers for scalar string data types - if ( primitiveType() == aitEnumString ) { - aitString* str=(aitString*)dataAddress(); - str->init(); - } - else if ( primitiveType() ==aitEnumFixedString ) { - this->data.FString = new aitFixedString; - memset (this->data.FString, '\0', sizeof(aitFixedString)); - } - else { - memset ( & this->data, '\0', sizeof ( this->data ) ); - } - } - } - if ( bnds ) - { - for(int i=0;ireference(); - - if(isContainer()||isFlat()) - markManaged(); - - return 0; -} - -gddStatus gdd::genCopy(aitEnum t, const void* d, aitDataFormat f) -{ - gddStatus rc=0; - - if(isScalar()) - set(t,d,f); - else if(isAtomic()) - { - if(!dataPointer()) - { - if ( primitiveType()==aitEnumString ) { - size_t nElem = describedDataSizeElements (); - aitString * pStrVec = new aitString [ nElem ]; - if ( ! pStrVec ) { - gddAutoPrint("gdd::genCopy()",gddErrorNewFailed); - rc = gddErrorNewFailed; - } - else { - destruct = new gddAitStringDestructor; - if ( destruct ) { - destruct->reference(); - setData ( pStrVec ); - } - else { - delete [] pStrVec; - gddAutoPrint("gdd::genCopy()",gddErrorNewFailed); - rc = gddErrorNewFailed; - } - } - } - else { - size_t sz=describedDataSizeBytes(); - aitUint8 * buf = new aitUint8[sz]; - if ( buf == NULL ) { - gddAutoPrint("gdd::genCopy()",gddErrorNewFailed); - rc=gddErrorNewFailed; - } - else - { - destruct=new gddAitUint8Destructor; - if (destruct==NULL) { - gddAutoPrint("gdd::genCopy()",gddErrorNewFailed); - rc=gddErrorNewFailed; - delete [] buf; - } - else { - setData(buf); - destruct->reference(); - } - } - } - } - if(rc==0) - { - if(f==aitLocalDataFormat) - aitConvert(primitiveType(),dataPointer(),t,d, - getDataSizeElements()); - else - aitConvertFromNet(primitiveType(),dataPointer(),t,d, - getDataSizeElements()); - - markLocalDataFormat(); - } - } - else - { - gddAutoPrint("gdd::genCopy()",gddErrorTypeMismatch); - rc=gddErrorTypeMismatch; - } - - return rc; -} - - -gddStatus gdd::changeType(int app,aitEnum prim) -{ - gddStatus rc=0; - - // this should only be allowed for setting the type if it is - // undefined or if the data is a scalar - - if(isScalar() || primitiveType()==aitEnumInvalid) - { - setApplType(app); - setPrimType(prim); - } - else - { - gddAutoPrint("gdd::changeType()",gddErrorTypeMismatch); - rc=gddErrorTypeMismatch; - } - - return rc; -} - -gddStatus gdd::setBound(unsigned index_dim, aitIndex first, aitIndex count) -{ - gddStatus rc=0; - if(index_dimappl_type); - setPrimType(aitEnumContainer); - setStatSevr(dd->getStat(),dd->getSevr()); - - if(dd->isContainer()) - { - cdd=(gddContainer*)dd; - gddCursor cur=cdd->getCursor(); - for(ndd=cur.first();ndd;ndd=cur.next()) - { - pdd=new gdd(ndd->applicationType(), - ndd->primitiveType(),ndd->dimension()); - pdd->setNext((gdd*)dataPointer()); - setData(pdd); - bounds->setSize(bounds->size()+1); - pdd->copyStuff(ndd,ctype); - } - } - else if(dd->isScalar()) { - if (dd->primitiveType()==aitEnumString) { - aitString* pStrDest =(aitString*)&data; - aitString* pStrSrc =(aitString*)&dd->data; - *pStrDest = *pStrSrc; - } - else if (dd->primitiveType()==aitEnumFixedString) { - aitFixedString* pStrDest =(aitFixedString*)data.Pointer; - aitFixedString* pStrSrc =(aitFixedString*)dd->data.Pointer; - memcpy (pStrDest, pStrSrc, sizeof(aitFixedString)); - } - else { - data=dd->data; - } - } - else // atomic - { - const gddBounds* bnds = dd->getBounds(); - for(unsigned i=0;idimension();i++) bounds[i]=bnds[i]; - - switch(ctype) - { - case 1: // copy() - if ( primitiveType()==aitEnumString ) { - size_t nElem = dd->describedDataSizeElements (); - aitString * pStrVec = new aitString [ nElem ]; - if ( ! pStrVec ) { - gddAutoPrint("gdd::copyStuff()",gddErrorNewFailed); - rc=gddErrorNewFailed; - } - else { - destruct = new gddAitStringDestructor; - if ( destruct ) { - const aitString * pSrc = - static_cast ( dd->dataPointer() ); - for ( unsigned j=0; j < nElem; j++ ) { - pStrVec[j] = pSrc[j]; - } - destruct->reference(); - setData ( pStrVec ); - } - else { - delete [] pStrVec; - gddAutoPrint("gdd::copyStuff()",gddErrorNewFailed); - rc=gddErrorNewFailed; - } - } - } - else { - size_t a_size = dd->getDataSizeBytes(); - aitUint8* array = new aitUint8[a_size]; - if ( array ) { - destruct=new gddAitUint8Destructor; - if (destruct!=NULL) { - destruct->reference(); - memcpy(array,dd->dataPointer(),a_size); - setData(array); - } - else { - delete [] array; - gddAutoPrint("gdd::copyStuff()",gddErrorNewFailed); - rc=gddErrorNewFailed; - } - } - else - { - gddAutoPrint("gdd::copyStuff()",gddErrorNewFailed); - rc=gddErrorNewFailed; - } - } - break; - case 2: // Dup() - data=dd->getData(); // copy the data reference - destruct=dd->destruct; - if(destruct) destruct->reference(); - break; - case 0: // copyInfo() - default: break; - } - } - return rc; -} - -size_t gdd::getDataSizeBytes(void) const -{ - size_t sz=0; - const gdd* pdd; - aitString* str; - - if(isContainer()) - { - const gddContainer* cdd=(const gddContainer*)this; - constGddCursor cur=cdd->getCursor(); - for(pdd=cur.first();pdd;pdd=cur.next()) - sz+=pdd->getTotalSizeBytes(); - } - else - { - if(aitValid(primitiveType())) - { - if(primitiveType()==aitEnumString) - { - if(dimension()) str=(aitString*)dataPointer(); - else str=(aitString*)dataAddress(); - sz+=(size_t)(aitString::totalLength(str, - getDataSizeElements())); - } - else - sz+=(size_t)(getDataSizeElements())*aitSize[primitiveType()]; - } - } - return sz; -} - -size_t gdd::describedDataSizeBytes(void) const -{ - size_t sz=0; - - // does not work well for aitString - only reports the aitString info - - if(!isContainer()) - sz+=(size_t)(describedDataSizeElements())*aitSize[primitiveType()]; - - return sz; -} - -size_t gdd::getTotalSizeBytes(void) const -{ - size_t sz; - size_t tsize; - const gdd* pdd; - - // add up size of bounds + size of this DD - sz=sizeof(gdd)+(sizeof(gddBounds)*dimension()); - - // special case the aitString/aitFixedString here - sucks bad - if(isScalar()) - { - if(primitiveType()==aitEnumString) - { - aitString* str=(aitString*)dataAddress(); - sz+=str->length()+1; // include the NULL - } - else if(primitiveType()==aitEnumFixedString) - sz+=sizeof(aitFixedString); - } - else if(isAtomic()) - { - if(aitValid(primitiveType())) - { - if(primitiveType()==aitEnumString) - { - // special case the aitString here - tsize=(size_t)(aitString::totalLength((aitString*)dataPointer(), - getDataSizeElements())); - } - else - tsize=(size_t)(getDataSizeElements())*aitSize[primitiveType()]; - - sz+=(size_t)align8(tsize); // include alignment - } - } - else if(isContainer()) - { - const gddContainer* cdd=(const gddContainer*)this; - constGddCursor cur=cdd->getCursor(); - for(pdd=cur.first();pdd;pdd=cur.next()) - sz+=pdd->getTotalSizeBytes(); - } - return sz; -} - -aitUint32 gdd::getDataSizeElements(void) const -{ - unsigned long total=1u; - unsigned i; - - if(dimension()>0u && dataPointer()) - { - for(i=0u;i0) flat_dd->convertAddressToOffsets(); - return sz; -} - -// IMPORTANT NOTE: -// Currently the user cannot register an empty container as a prototype. -// The destructor will not be installed to clean up the container when -// it is freed. - -// This is an important function -// Data should be flattened as follows: -// 1) all the GDDs, seen as an array an GDDs -// 2) all the bounds info for all the GDDs -// 3) all the data for all GDDs -// -// In addition, the user should be able to flatten GDDs without the data -// and flatten portions or all the data without flattening GDDs - -size_t gdd::flattenWithAddress(void* buf, size_t size, aitIndex* total_dd) -{ - gdd* pdd = (gdd*)buf; - size_t pos,sz,spos; - aitUint32 i; - gddBounds* bnds; - - // copy this gdd (first one) to get things started - // this is done in two passes - one to copy DDs, one for bounds/data - // need to be able to check if the DD has been flattened already - - if((sz=getTotalSizeBytes())>size) return 0; - pdd[0]=*this; - pdd[0].destruct=NULL; - pdd[0].flags=0; - pos=1; - - // not enough to just copy the gdd info if the primitive type is - // aitString or aitFixedString (even if scalar gdd) - // must special case the strings - that really sucks - - if(isScalar()) - { - // here is special case for the string types - if(primitiveType()==aitEnumFixedString) - { - if(data.FString) - memcpy((char*)&pdd[pos],data.FString,sizeof(aitFixedString)); - - pdd[0].data.FString=(aitFixedString*)&pdd[pos]; - } - else if(primitiveType()==aitEnumString) - { - aitString* str=(aitString*)pdd[0].dataAddress(); - if(str->string()) - { - memcpy((char*)&pdd[pos],str->string(),str->length()+1); - str->installBuf((char*)&pdd[pos],str->length(),str->length()+1); - } - else - str->init(); - } - } - else if(isContainer()) - { - // need to check for bounds in the container and flatten them - if(dataPointer()) - { - // process all the container's DDs - spos=pos; - pos+=flattenDDs((gddContainer*)this,&pdd[pos], - size-(pos*sizeof(gdd))); - - // copy all the data from the entire container into the buffer - flattenData(&pdd[0],pos,&pdd[pos],size-(pos*sizeof(gdd))); - - pdd[0].markFlat(); - pdd[0].setData(&pdd[spos]); - } - else - sz=0; // failure should occur - cannot flatten an empty container - } - else if(isAtomic()) - { - // Just copy the data from this DD into the buffer, copy bounds - if(bounds) - { - pdd[0].markFlat(); - bnds=(gddBounds*)(&pdd[pos]); - for(i=0;istring()) - { - memcpy(ptr,str->string(),str->length()+1); - str->installBuf((char *)ptr, str->length(), str->length()+1); - ptr+=str->length()+1; - } - else - str->init(); - } - else if(dd[i].primitiveType()==aitEnumFixedString) - { - if(dd[i].data.FString) - memcpy(ptr,dd[i].data.FString,sizeof(aitFixedString)); - dd[i].data.FString=(aitFixedString*)ptr; - ptr+=sizeof(aitFixedString); - } - } - } - return 0; -} - -int gdd::flattenDDs(gddContainer* dd, void* buf, size_t size) -{ - gdd* ptr=(gdd*)buf; - int i,tot,pos,spos; - gdd *pdd; - gddCursor cur; - - cur=dd->getCursor(); - - // make first pass to copy all the container's DDs into the buffer - for(tot=0,pdd=cur.first();pdd;pdd=pdd->next(),tot++) - { - ptr[tot]=*pdd; - ptr[tot].destruct=NULL; - ptr[tot].setNext(&ptr[tot+1]); - ptr[tot].noReferencing(); - } - ptr[tot-1].setNext(NULL); - - // make second pass to copy all child containers into buffer - for(pos=tot,i=0;ireference(); - } - } - } - return pos; -} - -gddStatus gdd::convertOffsetsToAddress(void) -{ - aitUint8* pdd = (aitUint8*)this; - size_t bnds = (size_t)(bounds); - size_t dp = (size_t)(dataPointer()); - gdd* tdd; - gddContainer* cdd; - gddCursor cur; - aitString* str; - aitIndex i; - const char* cstr; - - if(isContainer()) - { - // change bounds and data first - bounds=(gddBounds*)(pdd+bnds); - setData(pdd+dp); - cdd=(gddContainer*)this; - cur=cdd->getCursor(); - - for(tdd=cur.first();tdd;tdd=cur.next()) - { - if(tdd->next()) tdd->setNext((gdd*)(pdd+(size_t)tdd->next())); - tdd->convertOffsetsToAddress(); - } - } - else - { - if(isAtomic()) - { - bounds=(gddBounds*)(pdd+bnds); - setData(pdd+dp); - if(primitiveType()==aitEnumString) - { - // force all the strings in the array to offsets - str=(aitString*)dataPointer(); - for(i=0;istring()) - { - cstr=str->string(); - str->installBuf((char *)(pdd+(size_t)cstr), - str->length(), str->length()+1u); - } - else - str->init(); - } - } - } - return 0; -} - -gddStatus gdd::convertAddressToOffsets(void) -{ - aitUint8* pdd = (aitUint8*)this; - aitUint8* bnds = (aitUint8*)(bounds); - aitUint8* dp = (aitUint8*)(dataPointer()); - gddContainer* tdd; - gddCursor cur; - gdd *cdd,*ddd; - aitString* str; - aitIndex i; - const char* cstr; - - // does not ensure that all the members of a container are flat! - if(!isFlat()) - { - gddAutoPrint("gdd::convertAddressToOffsets()",gddErrorNotAllowed); - return gddErrorNotAllowed; - } - - if(isContainer()) - { - tdd=(gddContainer*)this; - cur=tdd->getCursor(); - - for(cdd=cur.first();cdd;) - { - ddd=cdd; - cdd=cur.next(); - ddd->convertAddressToOffsets(); - if(cdd) ddd->setNext((gdd*)((aitUint8*)(ddd->next())-pdd)); - } - - // bounds and data of container to offsets - setData((gdd*)(dp-pdd)); - bounds=(gddBounds*)(bnds-pdd); - } - else - { - if(isAtomic()) - { - if(primitiveType()==aitEnumString) - { - // force all the strings in the array to offsets - str=(aitString*)dataPointer(); - for(i=0;istring(); - if(cstr) str->installBuf((char *)(cstr-(const char*)pdd), - str->length(), str->length()+1u); - else str->init(); - } - } - } - return 0; -} - -void gdd::destroyData(void) -{ - if (isScalar()) - { - // this destroys the string types - this->setPrimType (aitEnumInvalid); - memset ( & this->data, '\0', sizeof ( this->data ) ); - } - else { - if(destruct) - { - if(isContainer()) - destruct->destroy(this); - else - destruct->destroy(dataPointer()); - - destruct=NULL; - } - freeBounds(); - this->prim_type = aitEnumInvalid; - memset ( & this->data, '\0', sizeof ( this->data ) ); - } -} - -gddStatus gdd::clearData(void) -{ - gddStatus rc=0; - - if(isContainer()||isManaged()||isFlat()) - { - gddAutoPrint("gdd::clearData()",gddErrorNotAllowed); - rc=gddErrorNotAllowed; - } - else if ( this->isScalar () ) { - // clear scaler types - if ( this->primitiveType() == aitEnumString ) { - aitString * str=(aitString*)dataAddress(); - str->clear(); - } - else if ( this->primitiveType() == aitEnumFixedString ) { - memset ( this->data.FString, '\0', sizeof(aitFixedString) ); - } - else { - memset ( & this->data, '\0', sizeof ( this->data ) ); - } - } - else { - if(destruct) - { - destruct->destroy(dataPointer()); - destruct=NULL; - } - setDimension ( 0, 0 ); - } - return rc; -} - -gddStatus gdd::clear(void) -{ - if(isFlat()||isManaged()) - { - gddAutoPrint("gdd::clear()",gddErrorNotAllowed); - return gddErrorNotAllowed; - } - - if(isAtomic()) - { - destroyData(); - } - else if(isContainer()) - { - gddContainer* cdd = (gddContainer*)this; - gddCursor cur = cdd->getCursor(); - gdd *dd,*tdd; - - for(dd=cur.first();dd;) - { - tdd=dd; - dd=cur.next(); - if(tdd->unreference()<0) delete tdd; - } - freeBounds(); - } - - // - // this code clears out aitString and - // aitFixedString scalars (the doc says - // that every field is set to invalid) - // - changeType(0,aitEnumInvalid); - memset ( & this->data, '\0', sizeof ( this->data ) ); - - return 0; -} - -// Curently gives no indication of failure, which is bad. -// Obviously managed or flattened DDs cannot be redone. -// However, a DD that is within a managed or flattened container can -// use this to describe data - how's that for obscure -// This is required if the "value" is to be allowed within a container -// The "value" could be scalar or an array of unknown size. The same is -// true of the enum strings and "units" attribute. - -gddStatus gdd::reset(aitEnum prim, int dimen, aitIndex* cnt) -{ - int i; - gddStatus rc; - - if((rc=clear())==0) - { - setPrimType(prim); - setDimension(dimen); - for(i=0;ifixed_string, - sizeof(d)); - d.fixed_string[sizeof(d)-1u] = '\0'; - } - else - get(aitEnumFixedString,&d); -} - -void gdd::getConvert(aitString& d) const -{ - get(aitEnumString,&d); -} - -void gdd::getConvert(aitFixedString& d) const -{ - get(aitEnumFixedString,d.fixed_string); -} - -gddStatus gdd::put(const aitString& d) -{ - gddStatus rc=0; - if(isScalar()) - { - // - // destroy existing fixed string if it exists - // and construct new aitString object - // - setPrimType(aitEnumString); - aitString* s=(aitString*)dataAddress(); - *s=d; - } - else - { - gddAutoPrint("gdd::put(aitString&)",gddErrorNotAllowed); - rc=gddErrorNotAllowed; - } - - return rc; -} - -gddStatus gdd::put(const aitFixedString& d) -{ - gddStatus rc=0; - - if(isScalar()) - { - this->setPrimType(aitEnumFixedString); - - if (data.FString!=NULL) - memcpy (data.FString->fixed_string, d.fixed_string, sizeof(d.fixed_string)); - } - else - { - gddAutoPrint("gdd::put(aitString&)",gddErrorNotAllowed); - rc=gddErrorNotAllowed; - } - return rc; -} - -void gdd::putConvert(const aitString& d) -{ - set(aitEnumString,&d); -} - -void gdd::putConvert(const aitFixedString& d) -{ - set(aitEnumFixedString,(void*)d.fixed_string); -} - -// copy each of the strings into this DDs storage area -gddStatus gdd::put(const aitString* const d) -{ - return genCopy(aitEnumString,d); -} - -// copy each of the strings into this DDs storage area -gddStatus gdd::put(const aitFixedString* const d) -{ - gddStatus rc=0; - - if(isAtomic()) - if(dataPointer()) - aitConvert(primitiveType(),dataPointer(),aitEnumFixedString,d, - getDataSizeElements()); - else - genCopy(aitEnumFixedString,d); - else - { - gddAutoPrint("gdd::put(const aitFixedString*const)",gddErrorNotAllowed); - rc=gddErrorTypeMismatch; - } - - return rc; -} - -gddStatus gdd::putRef(const gdd*) -{ - gddAutoPrint("gdd::putRef(const gdd*) - NOT IMPLEMENTED", - gddErrorNotSupported); - return gddErrorNotSupported; -} - -gddStatus gdd::put ( const gdd * dd ) -{ - if ( this->isScalar() && dd->isScalar() ) - { - // this is the simple case - just make this scalar look like the other - this->set(dd->primitiveType(),dd->dataVoid()); - } - else if ( isContainer() || dd->isContainer() ) - { - gddAutoPrint("gdd::put(const gdd*)",gddErrorNotSupported); - return gddErrorNotSupported; - } - else if ( this->dimension() > 1 || dd->dimension() > 1 ) - { - // sorry, no support currently for multidimensional arrays - return gddErrorOutOfBounds; - } - else if ( this->isScalar() ) // dd must be atomic if this is true - { - this->set ( dd->primitiveType(), dd->dataPointer() ); - } - // at this point this GDD must be atomic - // and the src gdd is either atomic or scalar - else { - // this must be single dimensional atomic at this point - - // dd can be scaler or single dimensional atomic at this point - // so fetch the bounds carefully - aitUint32 srcFirst; - aitUint32 srcElemCount; - if ( dd->isScalar() ) { - srcFirst = 0; - srcElemCount = 1; - } - else { - srcFirst = dd->getBounds()->first(); - srcElemCount = dd->getBounds()->size(); - } - - // clip to lower limit of source - aitUint32 srcCopyFirst; - if ( this->getBounds()->first () > srcFirst ) { - srcCopyFirst = this->getBounds()->first(); - } - else { - srcCopyFirst = srcFirst; - } - - // clip to upper limit of source - aitUint32 srcCopySize; - const aitUint32 unusedSrcBelow = srcCopyFirst - srcFirst; - if ( srcElemCount && srcElemCount <= unusedSrcBelow ) { - return gddErrorOutOfBounds; - } - - aitUint32 srcAvailSize = srcElemCount - unusedSrcBelow; - aitUint32 destSize = this->getBounds()->size(); - if ( destSize > 0 && srcAvailSize > destSize ) { - srcCopySize = destSize; - } - else { - srcCopySize = srcAvailSize; - } - - if ( dataVoid() == NULL ) - { - if (primitiveType()==aitEnumInvalid) { - setPrimType (dd->primitiveType()); - } - if ( primitiveType()==aitEnumString ) { - aitString * pStrVec = new aitString [ srcCopySize ]; - if( ! pStrVec ) { - return gddErrorNewFailed; - } - destruct = new gddAitStringDestructor; - if ( destruct ) { - destruct->reference(); - setData ( pStrVec ); - } - else { - delete [] pStrVec; - gddAutoPrint("gdd::copyData(const gdd*)",gddErrorNewFailed); - return gddErrorNewFailed; - } - } - else { - size_t sz = srcCopySize * aitSize[primitiveType()]; - - // allocate a data buffer for the user - aitUint8 * arr = new aitUint8[sz]; - if( ! arr ) { - return gddErrorNewFailed; - } - destruct=new gddAitUint8Destructor; - if (destruct!=NULL) { - destruct->reference(); - setData(arr); - } - else { - delete [] arr; - gddAutoPrint("gdd::copyData(const gdd*)",gddErrorNewFailed); - return gddErrorNewFailed; - } - } - - // the rule is that if storage is not preallocated then its ok - // for the dest bounds to shrink to match the original dest - // bounds intersection with the source data bounds - for ( unsigned i = 0; i < this->dimension(); i++ ) { - if ( i == 0 ) { - this->setBound ( i, srcCopyFirst, srcCopySize ); - } - else { - this->setBound ( i, 0, 1 ); - } - } - } - - aitUint8* pDst = (aitUint8*) this->dataPointer(); - assert ( srcCopyFirst >= this->getBounds()->first() ); - const aitUint32 unusedDstLow = srcCopyFirst - this->getBounds()->first(); - if ( unusedDstLow > 0 ) { - // - // zero portions that dont match - // (should eventually throw an exception ?) - // - aitUint32 byteCount = aitSize[primitiveType()] * unusedDstLow; - memset (pDst, '\0', byteCount); - pDst += byteCount; - } - - aitUint8* pSrc = (aitUint8*) dd->dataVoid(); - pSrc += aitSize[dd->primitiveType()] * unusedSrcBelow; - int gddStatus = aitConvert (this->primitiveType(), pDst, - dd->primitiveType(), pSrc, srcCopySize); - if ( gddStatus < 0 ) { - return gddErrorTypeMismatch; - } - - assert ( this->getBounds()->size() >= srcCopySize + unusedDstLow ); - const aitUint32 unusedDstHigh = this->getBounds()->size() - ( srcCopySize + unusedDstLow ); - if ( unusedDstHigh > 0 ) { - pDst += aitSize[primitiveType()] * srcCopySize; - // - // zero portions that dont match - // (should eventually throw an exception ?) - // - aitUint32 byteCount = aitSize[primitiveType()] * unusedDstHigh; - memset (pDst, '\0', byteCount); - } - } - - setStatSevr(dd->getStat(),dd->getSevr()); - aitTimeStamp ts; - dd->getTimeStamp(&ts); - setTimeStamp(&ts); - - return 0; // success -} - -size_t gdd::outHeader(void* buf,aitUint32 bufsize) const -{ - // simple encoding for now.. will change later - // this is the SLOW, simple version - - aitUint8* b = (aitUint8*)buf; - aitUint8* app = (aitUint8*)&appl_type; - aitUint8* stat = (aitUint8*)&status; - aitUint8* ts_sec = (aitUint8*)&time_stamp.tv_sec; - aitUint8* ts_nsec = (aitUint8*)&time_stamp.tv_nsec; - size_t i,j,sz; - aitIndex ff,ss; - aitUint8 *f,*s; - - // verify that header will fit into buffer first - sz=4+sizeof(status)+sizeof(time_stamp)+sizeof(appl_type)+ - sizeof(prim_type)+sizeof(dim)+(dim*sizeof(gddBounds)); - - if(sz>bufsize) return 0; // blow out here! - - *(b++)='H'; *(b++)='E'; *(b++)='A'; *(b++)='D'; - - // how's this for putrid - *(b++)=dim; - *(b++)=prim_type; - - if(aitLocalNetworkDataFormatSame) - { - *(b++)=app[0]; *(b++)=app[1]; - for(i=0;i0u); - i=sizeof(time_stamp.tv_sec)-1u; do { *(b++)=ts_sec[i]; } while(i-->0u); - i=sizeof(time_stamp.tv_nsec)-1u; do { *(b++)=ts_nsec[i]; } while(i-->0u); - } - - // put out the bounds info - for(j=0;j0u); - i=sizeof(aitIndex)-1u; do { *(b++)=f[i]; } while(i-->0u); - } - } - return sz; -} -size_t gdd::outData(void* buf,aitUint32 bufsize, aitEnum e, aitDataFormat f) const -{ - // put data into user's buffer in the format that the user wants (e/f). - // if e is invalid, then use whatever format this gdd describes. - - aitUint32 sz = getDataSizeElements(); - aitUint32 len = getDataSizeBytes(); - aitEnum type=(e==aitEnumInvalid)?primitiveType():e; - - if(len>bufsize) return 0; // blow out early - - if(sz>0) - { - if(f==aitLocalDataFormat) - aitConvert(type,buf,primitiveType(),dataVoid(),sz); - else - aitConvertToNet(type,buf,primitiveType(),dataVoid(),sz); - } - - return len; -} -size_t gdd::out(void* buf,aitUint32 bufsize,aitDataFormat f) const -{ - size_t index = outHeader(buf,bufsize); - size_t rc; - - if(index>0) - rc=outData(((char*)buf)+index,bufsize-index,aitEnumInvalid,f)+index; - else - rc=0; - - return rc; -} - -size_t gdd::inHeader(void* buf) -{ - // simple encoding for now.. will change later - // this is the SLOW, simple version - - aitUint16 inapp; - aitUint8 inprim; - aitUint8 indim; - - aitUint8* b = (aitUint8*)buf; - aitUint8* b1 = b; - aitUint8* app = (aitUint8*)&inapp; - aitUint8* stat = (aitUint8*)&status; - aitUint8* ts_sec = (aitUint8*)&time_stamp.tv_sec; - aitUint8* ts_nsec = (aitUint8*)&time_stamp.tv_nsec; - size_t i,j; - aitIndex ff,ss; - aitUint8 *f,*s; - - if(strncmp((char*)b,"HEAD",4)!=0) return 0; - b+=4; - - indim=*(b++); - inprim=*(b++); - - if(aitLocalNetworkDataFormatSame) - { - app[0]=*(b++); app[1]=*(b++); - init(inapp,(aitEnum)inprim,indim); - for(i=0u;i0u); - i=sizeof(time_stamp.tv_sec)-1u; do { ts_sec[i]=*(b++); } while(i-->0u); - i=sizeof(time_stamp.tv_nsec)-1u; do { ts_nsec[i]=*(b++); } while(i-->0u); - } - - // read in the bounds info - f=(aitUint8*)&ff; - s=(aitUint8*)&ss; - - for(j=0u;j0u); - i=sizeof(aitIndex)-1u; do { f[i]=*(b++); } while(i-->0u); - } - bounds[j].setFirst(ff); - bounds[j].setSize(ss); - } - return (size_t)(b-b1); -} -size_t gdd::inData(void* buf,aitUint32 tot, aitEnum e, aitDataFormat f) -{ - size_t rc; - - // Get data from a buffer and put it into this gdd. Lots of rules here. - // 1) tot is the total number of elements to copy from buf to this gdd. - // * if tot is zero, then use the element count described in the gdd. - // * if tot is not zero, then set the gdd up as a 1 dimensional array - // with tot elements in it. - // 2) e is the primitive data type of the incoming data. - // * if e is aitEnumInvalid, then use the gdd primitive type. - // * if e is valid and gdd primitive type is invalid, set the gdd - // primitive type to e. - // * if e is valid and so is this gdd primitive type, then convert the - // incoming data from type e to gdd primitive type. - - // Bad error condition, don't do anything. - if(e==aitEnumInvalid && primitiveType()==aitEnumInvalid) - return 0; - - aitIndex sz=tot; - aitEnum src_type=(e==aitEnumInvalid)?primitiveType():e; - aitEnum dest_type=(primitiveType()==aitEnumInvalid)?e:primitiveType(); - - // I'm not sure if this is the best way to do this. - if(sz>0) - reset(dest_type,dimension(),&sz); - - if(genCopy(src_type,buf,f)==0) - rc=getDataSizeBytes(); - else - rc=0; - - return rc; -} -size_t gdd::in(void* buf, aitDataFormat f) -{ - size_t index = inHeader(buf); - size_t rc; - - if(index>0) - rc=inData(((char*)buf)+index,0,aitEnumInvalid,f)+index; - else - rc=0; - - return rc; - -} - -// -// rewrote this to properly construct/destruct -// scalar string types when the prim type changes -// joh 05-22-98 -// -// -void gdd::setPrimType (aitEnum t) -{ - // - // NOOP if there is no change - // - if ( this->prim_type == t ) { - return; - } - - // - // I (joh) assume that something needs to be done when - // the primative type of a container changes. For now I - // assuming that the gdd should be cleared. - // - if(isContainer()) { - this->clear(); - } - - // - // run constructors/destructors for string data - // if it is scalar - // - if (isScalar()) - { - // - // run destructors for existing string data - // - if(primitiveType()==aitEnumFixedString) - { - // aitString type could have destructors - if ( destruct ) { - destruct->destroy(dataPointer()); - destruct = 0; - } - else - if (data.FString) delete data.FString; - } - else if(primitiveType()==aitEnumString) - { - // aitString type could have destructors - if ( destruct ) { - destruct->destroy(dataAddress()); - destruct = 0; - } - else - { - aitString* s = (aitString*)dataAddress(); - s->clear(); - } - } - - // - // run constructors for new string data types - // - if (t==aitEnumString) { - aitString* str=(aitString*)dataAddress(); - str->init(); - } - else if (t==aitEnumFixedString) { - this->data.FString = new aitFixedString; - memset ( this->data.FString, '\0', sizeof(aitFixedString) ); - } - else { - memset ( & this->data, '\0', sizeof(this->data) ); - } - } - - // - // I (joh) assume that Jim intended that - // calling of the destructors for arrays of string - // data when the primitive type changes is handled - // by the application. Not sure - nothing was done - // by Jim to take care of this as far as I can tell. - // - else if(isAtomic()) - { - if ( dataPointer() && destruct ) { - destruct->destroy(dataPointer()); - destruct=NULL; - } - memset (&this->data, '\0', sizeof(this->data)); - } - - this->prim_type = t; -} - -// -// gdd::indexDD() -// -// modified by JOH 4-23-99 so that the correct method -// is used if the container gdd is not organized -// as an array of GDDs in memory (i.e. its not flat) -// -const gdd* gdd::indexDD (aitIndex index) const -{ - aitIndex i; - unsigned nElem; - - if (index==0u) { - return this; - } - - // - // otherwise this had better be a container - // we are indexing - // - assert (this->prim_type==aitEnumContainer); - - // - // catch out of bounds index - // - nElem = getDataSizeElements(); - assert (index<=nElem); - - // - // if the container GDD is "flat" - // - if (this->isFlat()) { - return this + index; - } - - // - // otherwise linear search for it - // - gdd* dd = (gdd*) dataPointer(); - i = nElem; - while (i>index) { - dd=(gdd*)dd->next(); - i--; - } - return dd; -} - -// -// gddAitUint8Destructor::run() -// -// special gddDestructor guarantees same form of new and delete -// -void gddAitUint8Destructor::run (void *pUntyped) -{ - aitUint8 *pui8 = (aitUint8 *) pUntyped; - delete [] pui8; -} - -// -// gddAitStringDestructor::run() -// -// special gddDestructor guarantees same form of new and delete -// -void gddAitStringDestructor::run (void *pUntyped) -{ - aitString *pStr = (aitString *) pUntyped; - delete [] pStr; -} - diff --git a/src/ca/legacy/gdd/gdd.gif b/src/ca/legacy/gdd/gdd.gif deleted file mode 100644 index ab12e2e02..000000000 Binary files a/src/ca/legacy/gdd/gdd.gif and /dev/null differ diff --git a/src/ca/legacy/gdd/gdd.h b/src/ca/legacy/gdd/gdd.h deleted file mode 100644 index b713c2204..000000000 --- a/src/ca/legacy/gdd/gdd.h +++ /dev/null @@ -1,516 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 GDD_H -#define GDD_H - -/* - * Author: Jim Kowalkowski - * Date: 2/96 - */ - -// Still need to handle to network byte order stuff. -// Should always be marked net byte order on CPUs with native network byte -// order. No extra code should be run in this case. This should be -// easy with #defines since the AIT library defines a macro if network -// byte order is not native byte order - -#include -#include -#include -#include - -#include - -#if defined(_WIN32) -#elif defined(vxWorks) -# include -#elif defined(UNIX) - // hopefully a posix compliant OS -# include -# include -#endif - -// gddNewDel.h - a simple bunch of macros to make a class use free lists -// with new/remove operators - -#include "gddNewDel.h" -#include "gddUtils.h" -#include "gddErrorCodes.h" -#include "aitTypes.h" -#include "aitConvert.h" - -class gddContainer; -class gddArray; -class gddScalar; - -struct epicsTimeStamp; -struct timespec; - -// Not Complete in this prototype: -// - Read only DD. -// - Small array management using free lists - -// - need bit in DD to indicate that no referencing is allowed for the DD -// - need bit to indicate that DD should not be modified, for a container -// this means that the container cannot be added to or removed from. - -// Notes: -// gdds do not need to be linked lists. I could have used a container -// to describe arrays of DDs, and manage the commonly used ones (DD array -// sizes on free lists when the container was destroyed. The constructor -// to the container could take the number of DDs the container will -// manage. This would be similar to the gddBounds method. -// -// Has weak support for changing the dimension of a DD. In other words -// it is not easy to get a "value" DD (defaulting to scaler) and change -// the dimension to a two dimensional array. Need to add routines to -// restructure the bounds. -// -// Need to add methods for inserting const pointers into the DD. -// -// Overriding the operator[] can make the linked list contained in the -// container appear as an array. - -// --------------------------------------------------------------------- -// class structure for DDs: -// -// gddScalar -// | -// gddAtomic gddContainer -// | | -// gdd -// -// All the subclasses of gdd are around to simplify creation and use of -// DDs. - -// --------------------------------------------------------------------- -// This is the main Data Descriptor (DD). - -class epicsShareClass gdd -{ -public: - gdd(void); - gdd(gdd*); - gdd(int app); - gdd(int app,aitEnum prim); - gdd(int app,aitEnum prim,int dimen); - gdd(int app,aitEnum prim,int dimen,aitUint32* size_array); - - enum - { - GDD_MANAGED_MASK=0x01, - GDD_FLAT_MASK=0x02, - GDD_NET_MASK=0x04, - GDD_NOREF_MASK=0x08, - GDD_CONSTANT_MASK=0x10 - }; - - unsigned applicationType(void) const; - aitEnum primitiveType(void) const; - unsigned dimension(void) const; - aitType& getData(void); - const aitType& getData(void) const; - aitType* dataUnion(void); - const aitType* dataUnion(void) const; - const gddDestructor* destructor(void) const; - gdd* next(void); - const gdd* next(void) const; - void setNext(gdd*); - - const gddBounds* getBounds(void) const; - const gddBounds* getBounds(int bn) const; - - void dump(void) const; - void test(void); - - void setPrimType(aitEnum t); - void setApplType(int t); - void setDimension(int d,const gddBounds* = NULL); - void destroyData(void); - gddStatus reset(aitEnum primtype,int dimension, aitIndex* dim_counts); - gddStatus clear(void); // clear all fields of the DD, including arrays - gddStatus changeType(int appltype, aitEnum primtype); - gddStatus setBound(unsigned dim_to_set, aitIndex first, aitIndex count); - gddStatus getBound(unsigned dim_to_get, aitIndex& first, aitIndex& count) const; - gddStatus registerDestructor(gddDestructor*); - gddStatus replaceDestructor(gddDestructor*); - const void* dataVoid(void) const; - void* dataVoid(void); - const void* dataAddress(void) const; - void* dataAddress(void); - const void* dataPointer(void) const; - void* dataPointer(void); - const void* dataPointer(aitIndex element_offset) const; - void* dataPointer(aitIndex element_offset); - - void getTimeStamp(struct timespec* const ts) const; - void getTimeStamp(aitTimeStamp* const ts) const; - void getTimeStamp(struct epicsTimeStamp* const ts) const; - - void setTimeStamp(const struct timespec* const ts); - void setTimeStamp(const aitTimeStamp* const ts); - void setTimeStamp(const struct epicsTimeStamp* const ts); - - void setStatus(aitUint32); - void setStatus(aitUint16 high, aitUint16 low); - void getStatus(aitUint32&) const; - void getStatus(aitUint16& high, aitUint16& low) const; - - void setStat(aitUint16); - void setSevr(aitUint16); - aitUint16 getStat(void) const; - aitUint16 getSevr(void) const; - void setStatSevr(aitInt16 stat, aitInt16 sevr); - void getStatSevr(aitInt16& stat, aitInt16& sevr) const; - - size_t getTotalSizeBytes(void) const; - size_t getDataSizeBytes(void) const; - aitUint32 getDataSizeElements(void) const; - - // Note for all copy operations: - // Cannot change a container into atomic or scaler type, cannot change - // scaler or atomic type to container - - // copyInfo() will copy DD info only, this means appl, primitive type - // and bounds. Scalar data will be copied, but no arrays. - // copy() will copy DD info, bounds, allocate array data buffer and - // copy data into it. - // Dup() will copy DD info. bounds, data references copied only. - - gddStatus copyInfo(const gdd*); - gddStatus copy(const gdd*); - gddStatus Dup(const gdd*); - - // copy the entire DD structure into a contiguous buffer, return the - // last byte of the buffer that was used. - size_t flattenWithAddress(void* buffer,size_t size,aitIndex* total_dd=0); - size_t flattenWithOffsets(void* buffer,size_t size,aitIndex* total_dd=0); - gddStatus convertOffsetsToAddress(void); - gddStatus convertAddressToOffsets(void); - - int isScalar(void) const; - int isContainer(void) const; - int isAtomic(void) const; - - int isManaged(void) const; - int isFlat(void) const; - int isLocalDataFormat(void) const; - int isNetworkDataFormat(void) const; - int isConstant(void) const; - int isNoRef(void) const; - - void markConstant(void); - void markManaged(void); - void markUnmanaged(void); - void markLocalDataFormat(void); - void markNotLocalDataFormat(void); - - // The only way for a user to get rid of a DD is to Unreference it. - // NoReferencing() means that the DD cannot be referenced. - gddStatus noReferencing(void); - gddStatus reference(void) const; - gddStatus unreference(void) const; - - gdd& operator=(const gdd& v); - - // get a pointer to the data in the DD - void getRef(const aitFloat64*& d) const; - void getRef(const aitFloat32*& d) const; - void getRef(const aitUint32*& d) const; - void getRef(const aitInt32*& d) const; - void getRef(const aitUint16*& d) const; - void getRef(const aitInt16*& d) const; - void getRef(const aitUint8*& d) const; - void getRef(const aitInt8*& d) const; - void getRef(const aitString*& d) const; - void getRef(const aitFixedString*& d) const; - void getRef(const void*& d) const; - void getRef(aitFloat64*& d); - void getRef(aitFloat32*& d); - void getRef(aitUint32*& d); - void getRef(aitInt32*& d); - void getRef(aitUint16*& d); - void getRef(aitInt16*& d); - void getRef(aitUint8*& d); - void getRef(aitInt8*& d); - void getRef(aitString*& d); - void getRef(aitFixedString*& d); - void getRef(void*& d); - - // make the DD points to user data with a destroy method, - // put the referenced in and adjust the primitive type - void putRef(void*,aitEnum,gddDestructor* =0); - void putRef(aitFloat64*,gddDestructor* =0); - void putRef(aitFloat32*,gddDestructor* =0); - void putRef(aitUint8*,gddDestructor* =0); - void putRef(aitInt8*,gddDestructor* =0); - void putRef(aitUint16*,gddDestructor* =0); - void putRef(aitInt16*,gddDestructor* =0); - void putRef(aitUint32*,gddDestructor* =0); - void putRef(aitInt32*,gddDestructor* =0); - void putRef(aitString*,gddDestructor* =0); - void putRef(aitFixedString*,gddDestructor* =0); - // work with constants - void putRef(const aitFloat64*,gddDestructor* =0); - void putRef(const aitFloat32*,gddDestructor* =0); - void putRef(const aitUint8*,gddDestructor* =0); - void putRef(const aitInt8*,gddDestructor* =0); - void putRef(const aitUint16*,gddDestructor* =0); - void putRef(const aitInt16*,gddDestructor* =0); - void putRef(const aitUint32*,gddDestructor* =0); - void putRef(const aitInt32*,gddDestructor* =0); - void putRef(const aitString*,gddDestructor* =0); - void putRef(const aitFixedString*,gddDestructor* =0); - gddStatus putRef(const gdd*); - - // get the data in the form the user wants (do conversion) - void getConvert(aitFloat64& d) const; - void getConvert(aitFloat32& d) const; - void getConvert(aitUint32& d) const; - void getConvert(aitInt32& d) const; - void getConvert(aitUint16& d) const; - void getConvert(aitInt16& d) const; - void getConvert(aitUint8& d) const; - void getConvert(aitInt8& d) const; - void getConvert(aitString& d) const; - void getConvert(aitFixedString& d) const; - - // convert the user data to the type in the DD and set value - void putConvert(aitFloat64 d); - void putConvert(aitFloat32 d); - void putConvert(aitUint32 d); - void putConvert(aitInt32 d); - void putConvert(aitUint16 d); - void putConvert(aitInt16 d); - void putConvert(aitUint8 d); - void putConvert(aitInt8 d); - void putConvert(const aitString& d); - void putConvert(const aitFixedString& d); - - // copy the user data into the already set up DD array - gddStatus put(const aitFloat64* const d); - gddStatus put(const aitFloat32* const d); - gddStatus put(const aitUint32* const d); - gddStatus put(const aitInt32* const d); - gddStatus put(const aitUint16* const d); - gddStatus put(const aitInt16* const d); - gddStatus put(const aitUint8* const d); - gddStatus put(const aitInt8* const d); - gddStatus put(const aitString* const d); - gddStatus put(const aitFixedString* const d); - gddStatus put(const gdd* dd); - - // put the user data into the DD and reset the primitive type - gddStatus put(aitFloat64 d); - gddStatus put(aitFloat32 d); - gddStatus put(aitUint32 d); - gddStatus put(aitInt32 d); - gddStatus put(aitUint16 d); - gddStatus put(aitInt16 d); - gddStatus put(aitUint8 d); - gddStatus put(aitInt8 d); - gddStatus put(const aitString& d); - gddStatus put(const aitFixedString& d); - gddStatus put(aitType* d); - - // copy the array data out of the DD - void get(void* d) const; - void get(void* d,aitEnum) const; - void get(aitFloat64* d) const; - void get(aitFloat32* d) const; - void get(aitUint32* d) const; - void get(aitInt32* d) const; - void get(aitUint16* d) const; - void get(aitInt16* d) const; - void get(aitUint8* d) const; - void get(aitInt8* d) const; - void get(aitString* d) const; - void get(aitFixedString* d) const; - - // copy the data out of the DD - void get(aitFloat64& d) const; - void get(aitFloat32& d) const; - void get(aitUint32& d) const; - void get(aitInt32& d) const; - void get(aitUint16& d) const; - void get(aitInt16& d) const; - void get(aitUint8& d) const; - void get(aitInt8& d) const; - void get(aitString& d) const; - void get(aitFixedString& d) const; - void get(aitType& d) const; - - // Same as putRef() methods - gdd& operator=(aitFloat64* v); - gdd& operator=(aitFloat32* v); - gdd& operator=(aitUint32* v); - gdd& operator=(aitInt32* v); - gdd& operator=(aitUint16* v); - gdd& operator=(aitInt16* v); - gdd& operator=(aitUint8* v); - gdd& operator=(aitInt8* v); - gdd& operator=(aitString* v); - gdd& operator=(aitFixedString* v); - - // Same as put() methods - gdd& operator=(aitFloat64 d); - gdd& operator=(aitFloat32 d); - gdd& operator=(aitUint32 d); - gdd& operator=(aitInt32 d); - gdd& operator=(aitUint16 d); - gdd& operator=(aitInt16 d); - gdd& operator=(aitUint8 d); - gdd& operator=(aitInt8 d); - gdd& operator=(const aitString& d); - // gdd& operator=(aitFixedString d); // not present - - // Same as getRef() methods - operator const aitFloat64*(void) const; - operator const aitFloat32*(void) const; - operator const aitUint32*(void) const; - operator const aitInt32*(void) const; - operator const aitUint16*(void) const; - operator const aitInt16*(void) const; - operator const aitUint8*(void) const; - operator const aitInt8*(void) const; - operator const aitString*(void) const; - operator const aitFixedString*(void) const; - - operator aitFloat64*(void); - operator aitFloat32*(void); - operator aitUint32*(void); - operator aitInt32*(void); - operator aitUint16*(void); - operator aitInt16*(void); - operator aitUint8*(void); - operator aitInt8*(void); - operator aitString*(void); - operator aitFixedString*(void); - - // Same as get() methods - operator aitFloat64(void) const; - operator aitFloat32(void) const; - operator aitUint32(void) const; - operator aitInt32(void) const; - operator aitUint16(void) const; - operator aitInt16(void) const; - operator aitUint8(void) const; - operator aitInt8(void) const; - operator aitString(void) const; - // operator aitFixedString(void); // not present - - // - // added by JOH 4-23-99 so that the correct method - // is used if the container gdd is not organized - // as an array of GDDs in memory - // - // note that this requires a reference (pointers - // do not invoke this function) - // - gdd & operator [] (aitIndex index); - const gdd & operator [] (aitIndex index) const; - gdd & operator [] (int index); - const gdd & operator [] (int index) const; - - // - // The following can be slow and inefficient - // if the GDD isnt "flat" - // - // Only appropriate for container GDDs - // - const gdd* getDD(aitIndex index) const; - const gdd* getDD(aitIndex index, const gddScalar*&) const; - const gdd* getDD(aitIndex index, const gddArray*&) const; - const gdd* getDD(aitIndex index, const gddContainer*&) const; - gdd* getDD(aitIndex index); - gdd* getDD(aitIndex index,gddScalar*&); - gdd* getDD(aitIndex index,gddArray*&); - gdd* getDD(aitIndex index,gddContainer*&); - - gddStatus genCopy(aitEnum t, const void* d, - aitDataFormat f=aitLocalDataFormat); - void adjust(gddDestructor* d,void* v,aitEnum type, - aitDataFormat f=aitLocalDataFormat); - void get(aitEnum t,void* v,aitDataFormat f=aitLocalDataFormat) const; - void set(aitEnum t,const void* v,aitDataFormat f=aitLocalDataFormat); - - // following methods are used to import and export data into and out - // of this gdd. For the out methods, the returned count in the number - // of bytes put into the user's buffer. For the in methods, the - // returned count in the number of bytes put into the gdd from the - // user's buffer. The in methods always change the data format to local - // from whatever input format is specified with the argument. The out - // methods convert the gdd to whatever format is specified with the - // aitDataFormat argument. If aitEnum argument left as invalid, then - // data in the user's buffer will be assumed to be the same as the - // type defined in the gdd. - - size_t out(void* buf,aitUint32 bufsize,aitDataFormat =aitNetworkDataFormat) const; - size_t outHeader(void* buf,aitUint32 bufsize) const; - size_t outData(void* buf,aitUint32 bufsize, - aitEnum = aitEnumInvalid, aitDataFormat = aitNetworkDataFormat) const; - - size_t in(void* buf, aitDataFormat =aitNetworkDataFormat); - size_t inHeader(void* buf); - size_t inData(void* buf,aitUint32 number_of_elements = 0, - aitEnum = aitEnumInvalid, aitDataFormat = aitNetworkDataFormat); - - gdd_NEWDEL_FUNC(bounds) // managed on free lists - -protected: - ~gdd(void); // users must call Unreference() - - void init(int app, aitEnum prim, int dimen); - void freeBounds(void); - void dumpInfo(void) const; - gddStatus copyStuff(const gdd*,int type); - gddStatus clearData(void); - - size_t describedDataSizeBytes(void) const; - aitUint32 describedDataSizeElements(void) const; - - void markFlat(void); - gddStatus flattenData(gdd* dd, int tot_dds, void* buf, size_t size); - int flattenDDs(gddContainer* dd, void* buf, size_t size); - aitUint32 align8(unsigned long count) const; - - void setData(void* d); - - aitType data; // array pointer or scaler data - gddBounds* bounds; // array of bounds information length dim - gdd* nextgdd; - mutable gddDestructor* destruct; // NULL=none supplied, use remove - aitTimeStamp time_stamp; - aitStatus status; - aitUint16 appl_type; // application type code - aitUint8 prim_type; // primitive type code - aitUint8 dim; // 0=scaler, >0=array - - gdd_NEWDEL_DATA // required for using generic new and remove - -private: - mutable aitUint32 ref_cnt; - aitUint8 flags; - - static epicsMutex * pGlobalMutex; - const gdd* indexDD (aitIndex index) const; -}; - -// include these to be backward compatible with first gdd library version -#include "gddArray.h" -#include "gddScalar.h" -#include "gddContainer.h" - -#include "gddI.h" -#include "gddArrayI.h" -#include "gddScalarI.h" -#include "gddContainerI.h" - -#endif diff --git a/src/ca/legacy/gdd/gdd.html b/src/ca/legacy/gdd/gdd.html deleted file mode 100644 index 2235ea1a1..000000000 --- a/src/ca/legacy/gdd/gdd.html +++ /dev/null @@ -1,497 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -GDD User's Guide -


-

General Data Descriptor Library User's Guide

- -


General Overview

-The purpose of the General Data Descriptor Library (GDD library) is to -fully describe, hold, and manage scalar and array data. Using a GDD, -you can describe a piece of data's type, dimensionality, and structure. -In addition you can identify the data with an integer application type value -which can be translated into a text string. A user can store data into and -retreived data from a GDD in any desired data type. A GDD can contain -a list of GDDs. This allows users to create and describe hierarchical -data structures dynamically. GDDs organized in this fashion are known -as containers. -

-As mentioned above, a GDD can describe an n-dimension array. The user -can describe the bounds of the n-dimensional array. To facilitate the -use of large, and perhaps shared data arrays, a GDD allows a user to -store a reference to an array of data. In addition, a destructor function -can be registed in the GDD to inform the owner of the data array when -the GDD referencing the data goes away. The purpose of the destructor -function is to delete the array of data, since the GDD does not know -what to do with referenced data. -

-To manage GDDs in a multi-tasking system or a system that -uses many layers of software, GDDs implement reference counting. With -reference counting, only one instance of a GDD can be shared by many subsystems. -The GDD creator function can pass it to many other functions without -worrying about deleting it, only when the last function using the GDD requests -that it be destroyed does it really go away. -

-As menitioned above, a GDD allows the user to describe the data in terms -of the application. This is done by the user by assigning an arbitrary -integer identifier to a GDD. The user places a meaning on the identifiers -such as 1=high-alarm-limit, 2=low-alarm-limit. This identifier is termed -application type. A second component of the GDD library known as the -Application Type Table is used to manage the application type identifiers. -Application type values are registered in the table along with a text -string and optionally a prototype GDD. The prototype GDD can be a -container GDD. The table allows users to retreive GDDs of a specific -application type. -

-A GDD describes and manages a piece of data using the following information: -

-

    -
  • Application Type (user assigned integer value) -
  • Primitive Type (storage type identifier - int/double/short/etc.) -
  • Dimension (of array data) -
  • Bounds (array data structure information) -
  • Destructor (to delete referenced array data) -
  • Time Stamp (last time updated) -
  • Status (user assign data status field) -
  • Reference Count -
  • Data Field -
- -

-The GDD library is a C++ class library and therefore requires using the -C++ compiler. - -


GDD Description

-The gdd class is the main class in the GDD library. It controls almost -all actions performed on the data. The gdd class is further broken down -into three subclasses for performing operations on specific types of GDDs: -gddContainer, gddAtomic, and gddScalar. The gddContainer class aids in the -creation of container type GDDs. It adds functions such as "insert GDD", -"remove GDD", and "give me GDD x from the container" to the basic gdd class. -The gddAtomic class helps create and manage array data GDDs. The gddScalar -class makes it easy to create scalar GDDs. -

-All GDDs must be created dynamically, a GDD cannot be created on the -stack as a local variable. The gdd class forbids the user from deleting -the gdd. In order for reference counting to work correctly the user must -"unreference" the gdd instance instead of deleting it. The gdd class does -take over the memory management routines for itself and all it's subclasses. -This means that you are not using the malloc()/free() memory management when -GDDs are created and destroyed. It is important to remember that since -reference counting is used, a GDD passed into a function must be referenced -before the function returns if the GDD is to be kept for longer then the -running of that function. In other words, if you are creating a library -function "add" that records process variable names in a linked list, and the -process variable names are passed to you as GDDs, then you must reference -the GDD since the linked list exists after the return of the "add" function. -If you are creating a GDD, you must unreference it when you are finished -with it, even it you have passed it into other library functions. -Generalizing on this, it is the responsibility of the GDD creator or -GDD referencer to unreference the GDD instance when they are finished -with it. -

-For a GDD to be useful after it is created, it must be given information -to describe the data to will hold. This data was summarized in the overview -section. To further understand the meaning of all these items and use -them correctly, each needs to be discussed. - -


Primitive Types

-As mentioned in the overview, a piece of descriptive information that a -GDD maintains is the primitive type code. This field -describes the format of the data (storage type). -The primitive type field of a GDD is an enumeration -of all the general storage types supported by the compilers. A user can -determine dynamically what the storage format of the data in a GDD is using -the primitive type code information. The GDD library redefines the general -storage class names for integers and floating point numbers and enumerates -them in the "aitTypes.h" header file. The redefined names describe the -format and the bit length so that they can be used across architectures. -The initial part of the header file name "aitTypes.h" is ait which -stands for "Architecture Independant Types". The standard data types -supported by the GDD library are -
-	aitInt8           8 bit character
-	aitUint8          8 bit unsigned character
-	aitInt16          16 bit short
-	aitUint16         16 bit unsigned short
-	aitEnum16         16 enumerated value
-	aitInt32          32 bit integer
-	aitUint32         32 bit unsigned integer
-	aitFloat32        32 bit floating point number
-	aitFloat64        64 bit floating point number
-	aitPointer        Standard pointer
-	aitIndex          32 bit index value
-	aitStatus         32 bit unsigned integer for status value
-	aitFixedString    40 byte string of characters
-	aitString         Variable length string data type
-	aitTimeStamp      Two 32 bit integers describing time (seconds/nanoseconds)
-
-These data types should be used whenever possible to prevent problems when -compiling programs for different architectures. Most of the data types -described above are enumerated for use as a primitive type code. The -enumerated names are just the above type names with the word "Enum" -inserted after "ait". It should be noted that aitTimeStamp is not a -standard primitive type. -
-typedef enum {
-	 aitEnumInvalid=0,
-	 aitEnumInt8,
-	 aitEnumUint8,
-	 aitEnumInt16,
-	 aitEnumUint16,
-	 aitEnumEnum16,
-	 aitEnumInt32,
-	 aitEnumUint32,
-	 aitEnumFloat32,
-	 aitEnumFloat64,
-	 aitEnumFixedString,
-	 aitEnumString,
-	 aitEnumContainer
-} aitEnum;
-
-The enumerated type code allows a user to dynamically convert from one -type to another. The AIT portion of the GDD library contains a large -primitive type conversion matrix. The conversion matrix is indexed by -the source and destination enumeration type codes. The 12x12 matrix -contains functions pointers for each type of conversion that can take -place. Generally this matrix is never accessed directly by the user, -a convert function: -
-	void aitConvert(aitEnum dest_type, void* dest_data,
-						 aitEnum src_type, const void* src_data,
-						 aitIndex element_count)
-
-runs the correct function to perform the calculation. This function is used -extensively in the gdd class when data is put into or retrieved from a GDD. -

-The primitive type code really only describes the storage format and length -of an element within a GDD. This code does not imply or assign any meaning -to the data. Assigning meaning to the data is the job of the application -type code. - -


Application Types

-The application type is a 32 bit integer value that is user assigned. Each -value is arbitrary and is designed to give meaning to the chunk of data. -Normally each value has a character string associated with it which can -be looked up through a standard hash table. The GDD library predefines -many values and structures for standard control system applications; -this portion of the library will be dicussed in detail later in this document. -

-A typical way that application type codes are used is in defining structures. -A type code of 54 may be assigned the meaning "Temperature Reading". The -"Temperature Reading" structure may be a container with four GDDs in it: -a value, a high alarm limit, a low alarm limit, and units. Each -of these GDDs also have an application type code. A generic program can -actually be written to completely discover the contents of the -"Temperature Reading" structure and configure itself to display meaningful -data. - -


Time Stamp and Status

-Each GDD can store a time stamp and status value. The time stamp is a -standard 32-bit seconds, 32-bit nanoseconds since a standard epoch. The -status is a 32-bit value that is user assigned. The purpose of the time -stamp is to reflect the time when the data held within the GDD was read -and stored. The status is intented to reflect the validity of the data -within the GDD. In the context of EPICS, the status field is really a -16-bit status and 16-bit severity code. -

-Storing time stamp and status information in each GDD was really a processing -versus storage compromise. Most data in a control system that is -constantly changing and needs to be transfered in GDDs requires a status -and time stamp. Transfering this type of data in one GDD in fairly easy. -If GDDs did not contain time stamps and status, then this actively changing -data would need to be transfered as a structure of three GDDs: one for -the value, one for the status, and one for the time stamp. In addition -to the three GDDs, a fourth that describes the GDD container will need to -be transfered. - -


Dimension and Bounds Information

-A GDD that is a scalar is self contained. All information to describe -the data within the GDD is contained within the GDD. If the GDD describes -a structure (a container), or the GDD describes an array, then dimension -and array bounds information are needed. A GDD can describe an array -of any dimension. Each dimension is required to have a description -of it's size in terms of bounds. -

-Bounds, and consequencely a single dimension, in GDD are described by two -fields, a start and an element count. With this setup, and n-dimensional -space can be described. For example, a typical three dimension array -would be described as A(5,4,6), which is a 5x4x6 cube. In a GDD this -cube would be described with dimension=3, bounds={(0,5)(0,4)(0,6)}. If -we want to describe a subset of this array, we would normally do so by -giving two endpoints of the sub-cube, such as (1,2,3)->(2,3,5). In GDD -terms, this would be bounds={(1,2),(2,3),(3,5)}. -

-The dimension information is stored directly within the GDD. The bounds -information is not. If bounds are required, then they are allocated as -a single dimensional array and referenced by the GDD. Methods exist in -the GDD class to automatically manipulate, allocate, and deallocate -bounds structures. Typically GDD are assigned a dimension when created -and do not morph into a different space. - -


Data Field

-A GDD contains a data field large enough to hold any scalar value or -a pointer. This field is the union of all the primitive data types. -Currently it takes up 8 bytes, which is the size of a double. If a GDD -refers to an array of data, then the pointer to the actual data is stored -in the data field. If the dimension is greater then zero, then the data -field references the actual data. - -


Destructor

-Since GDDs can reference arrays of data, the user can optionally register -a destructor to be called when the GDD is destroyed. The GDD can store -a reference to a user destructor. The GDD library contains a destructor -base class called gddDestructor. A "destroy" method exists in this class -that is called when the GDD is being destroyed. Users must derive a class -from gddDestructor and define a "run" method. The "run" method gets -invoked with the address of the data array. The user, in the "run" -method, casts the address to the appropriate data type and deletes -the array. The default behavior of the gddDestuctor if the user does not -override the "run" method will be to cast the data array to a -character array and delete it. -

-The gddDestructor allows reference counting similar to the GDD class. -Typically a data array will be associated with one instance of the -gddDestructor class. If more then one GDD needs to reference the array, -then each GDD is registered with the same gddDestructor. Each time -the gddDestructor is registered, the reference count should be bumped -up. The gddDestructor "run" method will only be invoked when the -reference count drops to zero. - -


Strings and Fixed Strings

-Strings are special cases in the GDD library. There is a class called -aitString designed to work with and manage strings. Strings is the GDD -library generally contain two components: a reference to a character -array and a length. Storing a string in a GDD always results in a -reference to a character array, even if the GDD is a scalar. Character -strings are first put into an aitString and then inserted into the GDD. -The GDD data field can hold an instance of the aitString class for use -when the GDD is a scalar with one string in it. A scalar string GDD -still references the actual string within the aitString class. -

-A fixed string class exists in the GDD library in order to support -certain features of EPICS. Fixed strings are used internally and -should generally not be used when creating and maniplulating strings with -the GDD library. Fixed strings are too big to fit into a GDD and also -always referenced, even if the GDD is a scalar. - -


GDD Summary

-Several important issues related to where the actual data is stored -must be remembered when using GDDs: - -
    -
  1. If a gdd is a scalar, then the gdd holds the data it describes, the - dimension is zero, and the bounds are empty. -
  2. If a gdd is an array, then the gdd refers to the data it describes, - refers to bounds that describe it's structure, has a dimension - greater then zero, and optionally - refers to a user's data destructor. -
  3. If a gdd is a container, then the dimension is fixed at one and the - bounds describe how many elements (GDDs) are in the container. - The destructor in the container case knows how to free up all the - GDDs in the container. -
- -


Creating and Using GDDs

-
-	#include "gdd.h"
-	.
-	.
-	// my destructor ------------------
-	class myDest : public gddDestructor
-	{
-	public:
-		myDest(void) : gddDestructor() { }
-		void run(void*);
-	}
-
-	void myDest::run(void* v)
-	{
-		aitInt16* i16 = (aitInt16*)v;
-		delete [] i16;
-	}
-	// --------------------------------
-	.
-	.
-	.
-	int app_type_code = 100;
-
-	// create a scalar GDD of type Int32 and put the value 5 into it
-	aitInt32 ival = 5;
-	aitFloat64 sval;
-	gdd* dds = new gddScalar(app_type_code,aitEnumInt32);
-	dds->put(ival);
-	dds->getConvert(sval);
-	dds->dump();
-
-	aitString str = "test string";
-	gdd* dd_str = new gddScalar(++app_type_code,aitEnumString);
-	dd_str->put(str);
-	printf("string length = %n",str->length());
-	dd_str->dump();
-
-	// create an array GDD and of dimension 1 and bound of 20 elements
-	// reference the array into the container
-	aitUint32 tot_elements = 20;
-	int dim = 1;
-	aitFloat64 a[20];
-	gdd* dda = new gddAtomic(++app_type_code,aitEnumFloat64,dim,&tot_elements);
-	dda->putRef(a);
-	dda->dump();
-
-	aitInt16* i16 = new aitInt16[tot_elements];
-	gdd* ddb = new gddAtomic(++app_type_code,aitEnumInt16,dim,&tot_elements);
-	ddb->putRef(i16,new myDest);
-	ddb->dump();
-
-	// create a container GDD that holds to GDDs and put the previously
-	// created GDDs into it.
-	int tot_in_container = 2;
-	gddContainer* ddc = new gddContainer(++app_type_code,tot_in_container);
-	ddc->insert(dds);
-	ddc->insert(dda);
-	ddc->dump();
-
-	// clean up the container GDD, this will clean up all member GDDs,
-	// myDest run() should also be invoked
-	delete ddc;
-	.
-	.
-	.
-
- -


Application Type Table Description

-A facility within the GDD library is designed to store application -type code to string mappings. The facility can also be used to store -and retrieve prototype GDDs by application type code. The application -type table is really a simple database containing records with the following -information: -
    -
  • Application type code (32-bit integer) -
  • Application type name (variable length character string) -
  • Prototype GDD (gdd scalar, atomic, or container) -
  • Indexing maps -
-The type table has methods for registering or inserting records into the -database. Methods also exist to query the type name given a type code, and -to query the type code given the type name. Type codes are values -assigned to a type name when the type name is registered; the user is given the -type code value when the registeration takes place. A type code sometimes has -a prototype GDD associated with it, especially if it is a container GDD. -Methods also exist to retrieve a new GDD given an application type code. The -new GDD structure will be a copy of the prototype GDD for that type code. -The application type table -is commonly used create GDDs. A given application type code usually -implies a certain structure to the data. The prototype mechanism allows -this imposed structure to be adhered to when the GDD is created. This is -particularly important when it comes to container type GDDs. The type -table basically copies the prototype when the user requests a GDD with a -particular type code. The application type table also packs GDDs in -an efficient manage, which allows very high performance creation and -deletion of container GDDs and atomic GDDs. -

-GDDs in general have several components that are references, they do not -hold all the information they need. Creating and using array GDDs or -container GDDs -can be very time consuming. For an array GDD, the bounds and a destructor -must be allocated in addition to the GDD itself and referenced into the -GDD. For a container GDD, the GDD elements are really stored as a linked -list. To access the third element of a container, the linked list must be -traversed. With aitString GDDs the situation is worse yet. The GDD class -allow for a given GDD to be packed or flattened into a single linear buffer. -This mechanism includes packing GDD containers. In the array case, -the actual GDD is the first thing in the buffer, followed by any bounds -information, followed by the actual data array. The fields of the GDD -work exactly as before, except that they reference bounds and data that is -in the same buffer. In the case of containers, all the GDDs are stored as -an array of GDDs at the front of the buffer, followed by the bounds -information for each of the GDDs, followed by each of the GDD's data arrays if -present. There are many advantages of this configuration. Since all the -GDDs in a container are stored as an array instead of a linked list, the -user can directly index a particular GDD within the container. The -application type table performs this packing on a GDD that is registered -as a prototype for a particular type code. Since the GDD for a given -type code is now a fixed size, the type code table can manage the GDDs on -a free list. Each type code database entry with a prototype GDD contains -a free list -of GDDs for that type code. Creating a GDD using the type code table -involves retrieving a preallocated, packed GDD from a particular free list -and giving it to the user. This operation is very fast and efficient since -complex GDD structures are already constructed. -

-As stated above, container GDDs managed by the application type table can -be directly indexed as an array by the user. Unfortunetly the application -type code and indexes have no correlation - you cannot use the application -type code to index the GDD container. The type table has mapping functions -that convert between an application type code and an index into a container -GDD. Of course each type code maintains it's own index map and the -container GDD type code determines which mapping is to be used. A mechanism -exists in the GDD library for generating "#define" statements that -label container index values with a unique string. Preregistered containers -use this mechanism to generate indexing labels. The index label is a -concatenation of the type code names. If a container GDD type code name is -"TemperatureReading" and the first element is "Value", then the index -label generated will be "TemperatureReading_Value". At any time in a -running application, the user can request that index labels for all -registered prototypes be generated and dumped into a file. - -The library preregisters a number of application type names: - -

    -
  • "units" -
  • "maxElements" -
  • "precision" -
  • "graphicHigh" -
  • "graphicLow" -
  • "controlHigh" -
  • "controlLow" -
  • "alarmHigh" -
  • "alarmLow" -
  • "alarmHighWarning" -
  • "alarmLowWarning" -
  • "value" -
  • "enums" -
  • "menuitem" -
  • "status" -
  • "severity" -
  • "seconds" -
  • "nanoseconds" -
  • "name" -
  • "all" -
  • "attributes" -
-In addition, if EPICS is used then the following are registered: -
    -
  • "dbr_gr_short" -
  • "dbr_gr_float" -
  • "dbr_gr_enum" -
  • "dbr_gr_char" -
  • "dbr_gr_long" -
  • "dbr_gr_double" -
  • "dbr_ctrl_short" -
  • "dbr_ctrl_float" -
  • "dbr_ctrl_enum" -
  • "dbr_ctrl_char" -
  • "dbr_ctrl_long" -
  • "dbr_ctrl_double" -
- -The file gddApps.h contains all the index label defines for the EPICS -related GDD containers. - -


Using the Application Type Table

- -

GDD Reference Manual -


Home page for Jim Kowalkowski.
- -
Argonne National Laboratory -Copyright -Information
-
jbk@aps.anl.gov (Jim Kowalkowski)
updated 9/13/96
- diff --git a/src/ca/legacy/gdd/gdd.rc b/src/ca/legacy/gdd/gdd.rc deleted file mode 100644 index d677c6f7a..000000000 --- a/src/ca/legacy/gdd/gdd.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","General Data Descriptor Library for EPICS\0" - VALUE "CompanyName", "The EPICS collaboration\0" - VALUE "FileDescription", "General Data Descriptor Library\0" - VALUE "FileVersion", EPICS_VERSION_STRING "\0" - VALUE "InternalName", "gdd\0" - VALUE "LegalCopyright", "Copyright (C) Univ. of California, Univ. of Chicago\0" - VALUE "OriginalFilename", "gdd.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/legacy/gdd/gddAppDefs.cc b/src/ca/legacy/gdd/gddAppDefs.cc deleted file mode 100644 index 2da4058b5..000000000 --- a/src/ca/legacy/gdd/gddAppDefs.cc +++ /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 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 -// Date: 2/96 - -#define epicsExportSharedSymbols -#include "gddAppTable.h" - -// useless utility function -gddApplicationTypeTable* gddGenerateApplicationTypeTable(long x/*=(1<<13)*/) -{ - gddApplicationTypeTable* tt = new gddApplicationTypeTable((unsigned int)x); - return tt; -} - -void gddApplicationTypeTable::GenerateTypes(void) -{ - gddScalar* add_units = new gddScalar(0,aitEnumString); - - // One attempt at building a menu using aitString, which is not so - // good. - // gddAtomic* add_enum = new gddAtomic(0,aitEnumString,1,16); - // aitString add_enum_buf[16]; - // add_enum->putRef(add_enum_buf); - - // Just describe the menu - allow the block of choiced to be - // referenced in. - // gddAtomic* add_enum = new gddAtomic(0,aitEnumFixedString,1,16); - - // ---------------------------------------------------------------- - // register simple types - - // should I allow a dd retrieved through the tag table to be adjusted - // even though it is flattened? What if an array needs to change size - - // or type in a flattened dd? - - // value - filled by user no dd to register - // units - variable length of array of chars - - // not really required attributes - they are contained in DDs - registerApplicationType(GDD_NAME_STATUS); - registerApplicationType(GDD_NAME_SEVERITY); - registerApplicationType(GDD_NAME_TIME_STAMP); - registerApplicationType(GDD_NAME_PV_NAME); - registerApplicationType(GDD_NAME_CLASS); - - // required attributes - int type_prec=registerApplicationType(GDD_NAME_PRECISION); - int type_ghigh=registerApplicationType(GDD_NAME_GRAPH_HIGH); - int type_glow=registerApplicationType(GDD_NAME_GRAPH_LOW); - int type_chigh=registerApplicationType(GDD_NAME_CONTROL_HIGH); - int type_clow=registerApplicationType(GDD_NAME_CONTROL_LOW); - int type_ahigh=registerApplicationType(GDD_NAME_ALARM_HIGH); - int type_alow=registerApplicationType(GDD_NAME_ALARM_LOW); - int type_awhigh=registerApplicationType(GDD_NAME_ALARM_WARN_HIGH); - int type_awlow=registerApplicationType(GDD_NAME_ALARM_WARN_LOW); - int type_maxele=registerApplicationType(GDD_NAME_MAX_ELEMENTS); - int type_value=registerApplicationType(GDD_NAME_VALUE); - int type_menu=registerApplicationType(GDD_NAME_ENUM); - int type_units=registerApplicationTypeWithProto(GDD_NAME_UNITS,add_units); - int type_ackt=registerApplicationType(GDD_NAME_ACKT); - int type_acks=registerApplicationType(GDD_NAME_ACKS); - - // old menu method - // int type_menu=registerApplicationType(GDD_NAME_ENUM); - - // ---------------------------------------------------------------- - // register container types - not as easy - - // container of all PV attributes - gddContainer* cdd_attr=new gddContainer(1); - cdd_attr->insert(getDD(type_prec)); - cdd_attr->insert(getDD(type_ghigh)); - cdd_attr->insert(getDD(type_glow)); - cdd_attr->insert(getDD(type_chigh)); - cdd_attr->insert(getDD(type_clow)); - cdd_attr->insert(getDD(type_ahigh)); - cdd_attr->insert(getDD(type_alow)); - cdd_attr->insert(getDD(type_awhigh)); - cdd_attr->insert(getDD(type_awlow)); - cdd_attr->insert(getDD(type_units)); - cdd_attr->insert(getDD(type_maxele)); - registerApplicationTypeWithProto(GDD_NAME_ATTRIBUTES,cdd_attr); - - // container of everything about a PV - gddContainer* cdd_all=new gddContainer(1); - cdd_all->insert(getDD(type_prec)); - cdd_all->insert(getDD(type_ghigh)); - cdd_all->insert(getDD(type_glow)); - cdd_all->insert(getDD(type_chigh)); - cdd_all->insert(getDD(type_clow)); - cdd_all->insert(getDD(type_ahigh)); - cdd_all->insert(getDD(type_alow)); - cdd_all->insert(getDD(type_awhigh)); - cdd_all->insert(getDD(type_awlow)); - cdd_all->insert(getDD(type_units)); - cdd_all->insert(getDD(type_value)); - registerApplicationTypeWithProto(GDD_NAME_ALL,cdd_all); - - // ------------- generate required dbr containers ----------------- - - // DBR_GR_SHORT - gddContainer* cdd_gr_short=new gddContainer(0); - cdd_gr_short->insert(new gddScalar(type_value,aitEnumInt16)); - cdd_gr_short->insert(new gddScalar(type_ghigh,aitEnumInt16)); - cdd_gr_short->insert(new gddScalar(type_glow,aitEnumInt16)); - cdd_gr_short->insert(new gddScalar(type_ahigh,aitEnumInt16)); - cdd_gr_short->insert(new gddScalar(type_alow,aitEnumInt16)); - cdd_gr_short->insert(new gddScalar(type_awhigh,aitEnumInt16)); - cdd_gr_short->insert(new gddScalar(type_awlow,aitEnumInt16)); - cdd_gr_short->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_gr_short",cdd_gr_short); - - // DBR_GR_FLOAT - gddContainer* cdd_gr_float=new gddContainer(0); - cdd_gr_float->insert(new gddScalar(type_value,aitEnumFloat32)); - cdd_gr_float->insert(new gddScalar(type_prec,aitEnumInt16)); - cdd_gr_float->insert(new gddScalar(type_ghigh,aitEnumFloat32)); - cdd_gr_float->insert(new gddScalar(type_glow,aitEnumFloat32)); - cdd_gr_float->insert(new gddScalar(type_ahigh,aitEnumFloat32)); - cdd_gr_float->insert(new gddScalar(type_alow,aitEnumFloat32)); - cdd_gr_float->insert(new gddScalar(type_awhigh,aitEnumFloat32)); - cdd_gr_float->insert(new gddScalar(type_awlow,aitEnumFloat32)); - cdd_gr_float->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_gr_float",cdd_gr_float); - - // DBR_GR_ENUM - gddContainer* cdd_gr_enum=new gddContainer(0); - // old: cdd_gr_enum->insert(new gddAtomic(type_menu,aitEnumFixedString,1)); - cdd_gr_enum->insert(getDD(type_menu)); - cdd_gr_enum->insert(new gddScalar(type_value,aitEnumEnum16)); - registerApplicationTypeWithProto("dbr_gr_enum",cdd_gr_enum); - - // DBR_GR_CHAR - gddContainer* cdd_gr_char=new gddContainer(0); - cdd_gr_char->insert(new gddScalar(type_value,aitEnumInt8)); - cdd_gr_char->insert(new gddScalar(type_ghigh,aitEnumInt8)); - cdd_gr_char->insert(new gddScalar(type_glow,aitEnumInt8)); - cdd_gr_char->insert(new gddScalar(type_ahigh,aitEnumInt8)); - cdd_gr_char->insert(new gddScalar(type_alow,aitEnumInt8)); - cdd_gr_char->insert(new gddScalar(type_awhigh,aitEnumInt8)); - cdd_gr_char->insert(new gddScalar(type_awlow,aitEnumInt8)); - cdd_gr_char->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_gr_char",cdd_gr_char); - - // DBR_GR_LONG - gddContainer* cdd_gr_long=new gddContainer(0); - cdd_gr_long->insert(new gddScalar(type_value,aitEnumInt32)); - cdd_gr_long->insert(new gddScalar(type_ghigh,aitEnumInt32)); - cdd_gr_long->insert(new gddScalar(type_glow,aitEnumInt32)); - cdd_gr_long->insert(new gddScalar(type_ahigh,aitEnumInt32)); - cdd_gr_long->insert(new gddScalar(type_alow,aitEnumInt32)); - cdd_gr_long->insert(new gddScalar(type_awhigh,aitEnumInt32)); - cdd_gr_long->insert(new gddScalar(type_awlow,aitEnumInt32)); - cdd_gr_long->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_gr_long",cdd_gr_long); - - // DBR_GR_DOUBLE - gddContainer* cdd_gr_double=new gddContainer(0); - cdd_gr_double->insert(new gddScalar(type_value,aitEnumFloat64)); - cdd_gr_double->insert(new gddScalar(type_prec,aitEnumInt16)); - cdd_gr_double->insert(new gddScalar(type_ghigh,aitEnumFloat64)); - cdd_gr_double->insert(new gddScalar(type_glow,aitEnumFloat64)); - cdd_gr_double->insert(new gddScalar(type_ahigh,aitEnumFloat64)); - cdd_gr_double->insert(new gddScalar(type_alow,aitEnumFloat64)); - cdd_gr_double->insert(new gddScalar(type_awhigh,aitEnumFloat64)); - cdd_gr_double->insert(new gddScalar(type_awlow,aitEnumFloat64)); - cdd_gr_double->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_gr_double",cdd_gr_double); - - // DBR_CTRL_SHORT - gddContainer* cdd_ctrl_short=new gddContainer(0); - cdd_ctrl_short->insert(new gddScalar(type_value,aitEnumInt16)); - cdd_ctrl_short->insert(new gddScalar(type_ghigh,aitEnumInt16)); - cdd_ctrl_short->insert(new gddScalar(type_glow,aitEnumInt16)); - cdd_ctrl_short->insert(new gddScalar(type_chigh,aitEnumInt16)); - cdd_ctrl_short->insert(new gddScalar(type_clow,aitEnumInt16)); - cdd_ctrl_short->insert(new gddScalar(type_ahigh,aitEnumInt16)); - cdd_ctrl_short->insert(new gddScalar(type_alow,aitEnumInt16)); - cdd_ctrl_short->insert(new gddScalar(type_awhigh,aitEnumInt16)); - cdd_ctrl_short->insert(new gddScalar(type_awlow,aitEnumInt16)); - cdd_ctrl_short->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_ctrl_short",cdd_ctrl_short); - - // DBR_CTRL_FLOAT - gddContainer* cdd_ctrl_float=new gddContainer(0); - cdd_ctrl_float->insert(new gddScalar(type_value,aitEnumFloat32)); - cdd_ctrl_float->insert(new gddScalar(type_prec,aitEnumInt16)); - cdd_ctrl_float->insert(new gddScalar(type_ghigh,aitEnumFloat32)); - cdd_ctrl_float->insert(new gddScalar(type_glow,aitEnumFloat32)); - cdd_ctrl_float->insert(new gddScalar(type_chigh,aitEnumFloat32)); - cdd_ctrl_float->insert(new gddScalar(type_clow,aitEnumFloat32)); - cdd_ctrl_float->insert(new gddScalar(type_ahigh,aitEnumFloat32)); - cdd_ctrl_float->insert(new gddScalar(type_alow,aitEnumFloat32)); - cdd_ctrl_float->insert(new gddScalar(type_awhigh,aitEnumFloat32)); - cdd_ctrl_float->insert(new gddScalar(type_awlow,aitEnumFloat32)); - cdd_ctrl_float->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_ctrl_float",cdd_ctrl_float); - - // DBR_CTRL_ENUM - gddContainer* cdd_ctrl_enum=new gddContainer(0); - //old:cdd_ctrl_enum->insert(new gddAtomic(type_menu,aitEnumFixedString,1)); - cdd_ctrl_enum->insert(getDD(type_menu)); - cdd_ctrl_enum->insert(new gddScalar(type_value,aitEnumEnum16)); - registerApplicationTypeWithProto("dbr_ctrl_enum",cdd_ctrl_enum); - - // DBR_CTRL_CHAR - gddContainer* cdd_ctrl_char=new gddContainer(0); - cdd_ctrl_char->insert(new gddScalar(type_value,aitEnumInt8)); - cdd_ctrl_char->insert(new gddScalar(type_ghigh,aitEnumInt8)); - cdd_ctrl_char->insert(new gddScalar(type_glow,aitEnumInt8)); - cdd_ctrl_char->insert(new gddScalar(type_chigh,aitEnumInt8)); - cdd_ctrl_char->insert(new gddScalar(type_clow,aitEnumInt8)); - cdd_ctrl_char->insert(new gddScalar(type_ahigh,aitEnumInt8)); - cdd_ctrl_char->insert(new gddScalar(type_alow,aitEnumInt8)); - cdd_ctrl_char->insert(new gddScalar(type_awhigh,aitEnumInt8)); - cdd_ctrl_char->insert(new gddScalar(type_awlow,aitEnumInt8)); - cdd_ctrl_char->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_ctrl_char",cdd_ctrl_char); - - // DBR_CTRL_LONG - gddContainer* cdd_ctrl_long=new gddContainer(0); - cdd_ctrl_long->insert(new gddScalar(type_value,aitEnumInt32)); - cdd_ctrl_long->insert(new gddScalar(type_ghigh,aitEnumInt32)); - cdd_ctrl_long->insert(new gddScalar(type_glow,aitEnumInt32)); - cdd_ctrl_long->insert(new gddScalar(type_chigh,aitEnumInt32)); - cdd_ctrl_long->insert(new gddScalar(type_clow,aitEnumInt32)); - cdd_ctrl_long->insert(new gddScalar(type_ahigh,aitEnumInt32)); - cdd_ctrl_long->insert(new gddScalar(type_alow,aitEnumInt32)); - cdd_ctrl_long->insert(new gddScalar(type_awhigh,aitEnumInt32)); - cdd_ctrl_long->insert(new gddScalar(type_awlow,aitEnumInt32)); - cdd_ctrl_long->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_ctrl_long",cdd_ctrl_long); - - // DBR_CTRL_DOUBLE - gddContainer* cdd_ctrl_double=new gddContainer(0); - cdd_ctrl_double->insert(new gddScalar(type_value,aitEnumFloat64)); - cdd_ctrl_double->insert(new gddScalar(type_prec,aitEnumInt16)); - cdd_ctrl_double->insert(new gddScalar(type_ghigh,aitEnumFloat64)); - cdd_ctrl_double->insert(new gddScalar(type_glow,aitEnumFloat64)); - cdd_ctrl_double->insert(new gddScalar(type_chigh,aitEnumFloat64)); - cdd_ctrl_double->insert(new gddScalar(type_clow,aitEnumFloat64)); - cdd_ctrl_double->insert(new gddScalar(type_ahigh,aitEnumFloat64)); - cdd_ctrl_double->insert(new gddScalar(type_alow,aitEnumFloat64)); - cdd_ctrl_double->insert(new gddScalar(type_awhigh,aitEnumFloat64)); - cdd_ctrl_double->insert(new gddScalar(type_awlow,aitEnumFloat64)); - cdd_ctrl_double->insert(getDD(type_units)); - registerApplicationTypeWithProto("dbr_ctrl_double",cdd_ctrl_double); - - // DBR_STSACK_STRING - gddContainer* cdd_stsack_string=new gddContainer(0); - cdd_stsack_string->insert(new gddScalar(type_value,aitEnumString)); - cdd_stsack_string->insert(new gddScalar(type_acks,aitEnumUint16)); - cdd_stsack_string->insert(new gddScalar(type_ackt,aitEnumUint16)); - registerApplicationTypeWithProto("dbr_stsack_string",cdd_stsack_string); -} - diff --git a/src/ca/legacy/gdd/gddAppFuncTable.h b/src/ca/legacy/gdd/gddAppFuncTable.h deleted file mode 100644 index fca158d27..000000000 --- a/src/ca/legacy/gdd/gddAppFuncTable.h +++ /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 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 gddAppFuncTableH -#define gddAppFuncTableH - -// -// ANSI C -// -#include - -// -// GDD -// -#include "gdd.h" -#include "gddAppTable.h" -#include "errMdef.h" -#include "errlog.h" - -typedef aitUint32 gddAppFuncTableStatus; - -#define S_gddAppFuncTable_Success 0u -#define S_gddAppFuncTable_badType (M_gddFuncTbl|1u) /*application type unregistered*/ -#define S_gddAppFuncTable_gddLimit (M_gddFuncTbl|2u) /*at gdd lib limit*/ -#define S_gddAppFuncTable_noMemory (M_gddFuncTbl|3u) /*dynamic memory pool exhausted*/ - -#ifndef NELEMENTS -#define NELEMENTS(array) (sizeof(array)/sizeof((array)[0])) -#endif - -// -// class gddAppFuncTable -// -template -class gddAppFuncTable { - -public: - gddAppFuncTable() : pMFuncRead(0), appTableNElem(0u) - { - } - - ~gddAppFuncTable() - { - if (this->pMFuncRead) { - delete [] this->pMFuncRead; - } - } - - // - // installReadFunc() - // - // The 2nd parameter should be declared as follows: - // - // gddAppFuncTableStatus PV::memberFunction(gdd &value); - // - gddAppFuncTableStatus installReadFunc (const unsigned type, - gddAppFuncTableStatus (PV::*pMFuncIn)(gdd &) ); - - // - // installReadFunc() - // - // The 2nd parameter should be declared as follows: - // - // gddAppFuncTableStatus PV::memberFunction(gdd &value); - // - gddAppFuncTableStatus installReadFunc ( const char * pName, - gddAppFuncTableStatus (PV::*pMFuncIn)(gdd &) ); - - // - // - // - gddAppFuncTableStatus read ( PV &pv, gdd &value ); - gddAppFuncTableStatus callReadFunc ( PV &pv, gdd &value ); - -private: - // - // The total number of application tags to manage should be - // hidden from the application (eventually allow for auto - // expansion of the table) - // - gddAppFuncTableStatus (PV::**pMFuncRead)(gdd &); - unsigned appTableNElem; - - void newTbl ( unsigned neMaxType ); -}; - -// -// gddAppFuncTable::installReadFunc() -// -// The 2nd parameter should be declared as follows: -// -// gddAppFuncTableStatus PV::memberFunction(gdd &value); -// -// A typedef is not used here because of portability -// problems resulting from compiler weaknesses -// -template -gddAppFuncTableStatus gddAppFuncTable::installReadFunc ( - const unsigned type, gddAppFuncTableStatus (PV::*pMFuncIn)(gdd &) ) -{ - // - // Attempt to expand the table if the app type will not fit - // - if (type>=this->appTableNElem) { - this->newTbl(type); - if (type>=this->appTableNElem) { - return S_gddAppFuncTable_noMemory; - } - } - this->pMFuncRead[type]=pMFuncIn; - return S_gddAppFuncTable_Success; -} - -// -// installReadFunc() -// -// The 2nd parameter should be declared as follows: -// -// gddAppFuncTableStatus PV::memberFunction(gdd &value); -// -template -gddAppFuncTableStatus gddAppFuncTable::installReadFunc ( - const char * pName, gddAppFuncTableStatus (PV::*pMFuncIn)(gdd &) ) -{ - aitUint32 type; - gddStatus rc; - - rc = gddApplicationTypeTable:: - app_table.registerApplicationType (pName, type); - if (rc!=0 && rc!=gddErrorAlreadyDefined) { - printf( -"at gdd lib limit => read of PV attribute \"%s\" will fail\n", pName); - return S_gddAppFuncTable_gddLimit; - } -# ifdef DEBUG - printf("installing PV attribute %s = %d\n", pName, type); -# endif - - return this->installReadFunc(type, pMFuncIn); -} - -// -// gddAppFuncTable::newTbl() -// -// The total number of application tags to manage should be -// hidden from the application -// -// The typedef is not used here because of portability -// problems resulting from compiler weaknesses -// -template -void gddAppFuncTable::newTbl(unsigned newApplTypeMax) -{ - gddAppFuncTableStatus (PV::**pMNewFuncTbl)(gdd &); - unsigned maxApp; - unsigned i; - - if (this->appTableNElem>newApplTypeMax) { - return; - } - maxApp = newApplTypeMax+(1u<<6u); - -# if defined(_MSC_VER) && _MSC_VER <= 1200 - // - // MS Visual C++ 6.0 (_MSC_VER==1200) or lower - // compilers allocate the wrong amount of memory - // (i.e. too little) for member function pointers, - // only explicit calculation via sizeof() works. - // - pMNewFuncTbl = (gddAppFuncTableStatus (PV::**)(gdd &)) - new char[sizeof( gddAppFuncTableStatus (PV::*)(gdd &) ) * maxApp]; -# else - typedef gddAppFuncTableStatus (PV::*pMF_t)(gdd &); - pMNewFuncTbl = new pMF_t [maxApp]; -# endif - if (pMNewFuncTbl) { - for (i=0u; iappTableNElem) { - pMNewFuncTbl[i] = this->pMFuncRead[i]; - } - else { - // - // some versions of NULL include (void *) cast - // (so I am using vanilla zero here) - // - pMNewFuncTbl[i] = 0; - } - } - if (this->pMFuncRead) { - delete [] this->pMFuncRead; - } - this->pMFuncRead = pMNewFuncTbl; - this->appTableNElem = maxApp; - } -} - -// -// gddAppFuncTable::read() -// -template -gddAppFuncTableStatus gddAppFuncTable::read(PV &pv, gdd &value) -{ - gddAppFuncTableStatus status; - - // - // if this gdd is a container then step through it - // and fetch all of the values inside - // - if (value.isContainer()) { - gddContainer *pCont = (gddContainer *) &value; - gddCursor curs = pCont->getCursor(); - gdd *pItem; - - status = S_gddAppFuncTable_Success; - for (pItem=curs.first(); pItem; pItem=curs.next()) - { - status = this->read(pv, *pItem); - if (status) { - break; - } - } - return status; - } - return callReadFunc(pv, value); -} - -// -// gddAppFuncTable::callReadFunc() -// -template -gddAppFuncTableStatus gddAppFuncTable::callReadFunc (PV &pv, gdd &value) -{ - unsigned type; - gddAppFuncTableStatus (PV::*pFunc)(gdd &); - - // - // otherwise call the function associated - // with this application type - // - type = value.applicationType(); - if (type>=this->appTableNElem) { - errPrintf (S_gddAppFuncTable_badType, __FILE__, - __LINE__, "- large appl type code = %u\n", - type); - return S_gddAppFuncTable_badType; - } - pFunc = this->pMFuncRead[type]; - if ( pFunc == 0 ) { - errPrintf (S_gddAppFuncTable_badType, __FILE__, - __LINE__, "- ukn appl type code = %u\n", - type); - return S_gddAppFuncTable_badType; - } - return (pv.*pFunc)(value); -} - -#endif // gddAppFuncTableH - diff --git a/src/ca/legacy/gdd/gddAppTable.cc b/src/ca/legacy/gdd/gddAppTable.cc deleted file mode 100644 index 2315516fe..000000000 --- a/src/ca/legacy/gdd/gddAppTable.cc +++ /dev/null @@ -1,622 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 -// Date: 2/96 - -#define epicsExportSharedSymbols -#include "gddAppTable.h" - -// -----------------general destructor for managed gdds-------------------- - -void gddApplicationTypeDestructor::run(void* v) -{ - gdd* ec = (gdd*)v; - // fprintf(stderr," destructing %8.8x\n",v); - gddApplicationTypeTable* db = (gddApplicationTypeTable*)arg; - db->freeDD(ec); -} - -gddApplicationTypeElement::gddApplicationTypeElement(void) { } -gddApplicationTypeElement::~gddApplicationTypeElement(void) { } - -// --------------------------app table stuff----------------------------- - -gddApplicationTypeTable gddApplicationTypeTable::app_table; - -gddApplicationTypeTable& gddApplicationTypeTable::AppTable(void) -{ - return gddApplicationTypeTable::app_table; -} - -gddApplicationTypeTable::gddApplicationTypeTable(aitUint32 tot) -{ - aitUint32 i,total; - - // round tot up to nearest power of 2 - for(i=1u<<31;i && !(tot&i);i>>=1); - if(i==0) - total=1; - else if(i==tot) - total=tot; - else - total=i<<1; - - max_groups=total/APPLTABLE_GROUP_SIZE; - if((max_groups*APPLTABLE_GROUP_SIZE) != total) ++max_groups; - max_allowed=total; - total_registered=1; - attr_table=new gddApplicationTypeElement*[max_groups]; - - for(i=0;inext(); - delete [] blk; - } - } - - if(attr_table[i][j].map) - delete [] attr_table[i][j].map; - break; - case gddApplicationTypeUndefined: break; - default: break; - } - } - delete [] attr_table[i]; - } - } - delete [] attr_table; -} - -int gddApplicationTypeTable::describeDD(gddContainer* dd, FILE* fd, - int level, char* tn) -{ - gddCursor cur = dd->getCursor(); - gdd* pdd; - char tmp[8]; - char* cp; - char* str; - - strcpy(tmp,"unknown"); - - for(pdd=cur.first();pdd;pdd=pdd->next()) - { - if((cp=getName(pdd->applicationType()))==NULL) cp=tmp; - fprintf(fd,"#define gddAppTypeIndex_%s_%s %d\n",tn,cp,level++); - } - - for(pdd=cur.first();pdd;pdd=pdd->next()) - { - if((cp=getName(pdd->applicationType()))==NULL) cp=tmp; - if(pdd->isContainer()) - { - str = new char[strlen(cp)+strlen(tn)+3]; - strcpy(str,tn); - strcat(str,"_"); - strcat(str,cp); - level=describeDD((gddContainer*)pdd,fd,level,str); - delete [] str; - } - } - return level; -} - -void gddApplicationTypeTable::describe(FILE* fd) -{ - unsigned i,j; - gdd* dd; - char* tn; - - fprintf(fd,"\n"); - for(i=0;iisContainer()) - describeDD((gddContainer*)dd,fd,1,tn); - // fprintf(fd,"\n"); - } - break; - case gddApplicationTypeUndefined: break; - default: break; - } - } - } - } - fprintf(fd,"\n"); -} - -gddStatus gddApplicationTypeTable::registerApplicationType( - const char* const name,aitUint32& new_app) -{ - aitUint32 i,group,app,rapp; - gddStatus rc; - - if( (new_app=getApplicationType(name)) ) - { - // gddAutoPrint(gddErrorAlreadyDefined); - return gddErrorAlreadyDefined; - } - if(total_registered>max_allowed) - { - gddAutoPrint("gddAppTable::registerApplicationType()",gddErrorAtLimit); - return gddErrorAtLimit; - } - - { - epicsGuard < epicsMutex > guard ( sem ); - rapp=total_registered++; - } - - if((rc=splitApplicationType(rapp,group,app))<0) return rc; - - if(attr_table[group]) - { - // group already allocated - check is app already refined - if(attr_table[group][app].type!=gddApplicationTypeUndefined) - { - // gddAutoPrint(gddErrorAlreadyDefined); - return gddErrorAlreadyDefined; - } - } - else - { - // group must be allocated - attr_table[group]=new gddApplicationTypeElement[APPLTABLE_GROUP_SIZE]; - - // initialize each element of the group as undefined - for(i=0;i %d\n",name,(int)new_app); - return 0; -} - -// registering a prototype of an empty container causes problems. -// The current implementation does not monitor this so the container -// is not cleared when free. A user may, however, include an empty -// container within a prototype container, and everything will work -// correctly. - -gddStatus gddApplicationTypeTable::registerApplicationTypeWithProto( - const char* const name, gdd* protoDD, aitUint32& new_app) -{ - aitUint32 group,app,rapp; - aitUint8* blk; - size_t sz; - aitIndex tot; - aitUint16 x; - aitUint16 i; - gddStatus rc; - - if( (rc=registerApplicationType(name,new_app)) ) return rc; - - rapp=new_app; - protoDD->setApplType(rapp); - splitApplicationType(rapp,group,app); - - // user gives me the protoDD, so I should not need to reference it. - // Warning, it the user does unreference() on it unknowningly, it will - // go away and cause big problems - - // make sure that the currently registered destructor gets called - // before setting the new one, this should occur in protoDD. - - // be sure to copy data from DD and create buffer that can be copied - // easily when user asks for a DD with proto - - // important!! put destructor into each managed DD - what if atomic? - // protoDD->registerDestructor(new gddApplicationTypeDestructor(protoDD)); - - sz=protoDD->getTotalSizeBytes(); - blk=new aitUint8[sz]; - protoDD->flattenWithAddress(blk,sz,&tot); - attr_table[group][app].proto_size=sz; - attr_table[group][app].total_dds=tot; - protoDD->unreference(); - - attr_table[group][app].type=gddApplicationTypeProto; - attr_table[group][app].proto=(gdd*)blk; - attr_table[group][app].free_list=NULL; - - // create the stupid mapping table - bad implementation for now - attr_table[group][app].map=new aitUint16[total_registered]; - attr_table[group][app].map_size=total_registered; - for(i=0;inext(); - attr_table[group][app].sem.unlock (); - } - else - { - attr_table[group][app].sem.unlock (); - // copy the prototype - blk=new aitUint8[attr_table[group][app].proto_size]; - // fprintf(stderr,"Creating a new proto DD! %d %8.8x\n",app,blk); - attr_table[group][app].proto->flattenWithAddress(blk, - attr_table[group][app].proto_size); - dd=(gdd*)blk; - } - dd->registerDestructor(new gddApplicationTypeDestructor(this)); - dd->markManaged(); // must be sure to mark the thing as managed! - break; - case gddApplicationTypeNormal: - dd=new gdd(app); - // fprintf(stderr,"Creating a new normal DD! %d\n",app); - break; - case gddApplicationTypeUndefined: dd=NULL; break; - default: break; - } - - return dd; -} - -gddStatus gddApplicationTypeTable::freeDD(gdd* dd) -{ - aitUint32 group,app,i; - gddStatus rc; - - if((rc=splitApplicationType(dd->applicationType(),group,app))<0) return rc; - - if(attr_table[group][app].type==gddApplicationTypeProto) - { - // this can be time consuming, clear out all user data from the DD - // this is done because we are allowed to register atomic protos - // that user can attach data to - which causes problems because - // the actual structure of the DD is unknown - - for(i=1;isetNext(attr_table[group][app].free_list); - attr_table[group][app].free_list=dd; - attr_table[group][app].sem.unlock (); - } - else if (attr_table[group][app].type==gddApplicationTypeNormal) - { - // fprintf(stderr,"freeDD a normal DD\n"); - dd->unreference(); - } - else { - fprintf ( stderr,"gddApplicationTypeTable::freeDD - unexpected DD type was %d\n", - attr_table[group][app].type ); - } - - return 0; -} - -gddStatus gddApplicationTypeTable::storeValue(aitUint32 ap, aitUint32 uv) -{ - aitUint32 group,app; - gddStatus rc=0; - - if((rc=splitApplicationType(ap,group,app))<0) return rc; - if(attr_table[group]==NULL || - attr_table[group][app].type==gddApplicationTypeUndefined) - rc=gddErrorNotDefined; - else - attr_table[group][app].user_value=uv; - - gddAutoPrint("gddAppTable::storeValue()",rc); - return rc; -} - -aitUint32 gddApplicationTypeTable::getValue(aitUint32 ap) -{ - aitUint32 group,app; - if(splitApplicationType(ap,group,app)<0) return 0; - if(attr_table[group]==NULL || - attr_table[group][app].type==gddApplicationTypeUndefined) - return 0; - - return attr_table[group][app].user_value; -} - -// ----------------------smart copy functions------------------------ -// the source in the container we must walk through is this called -gddStatus gddApplicationTypeTable::copyDD_src(gdd& dest, const gdd& src) -{ - gddStatus rc=0,s; - gddCursor cur; - gdd* dd; - aitIndex index; - - // this could be done better (faster) if we did not always recurse for - // each GDD. I could have checked for type container before recursing. - - if(src.isContainer()) - { - gddContainer& cdd = (gddContainer&) src; - - // go through src gdd and map app types to index into dest - cur=cdd.getCursor(); - for(dd=cur.first();dd;dd=dd->next()) copyDD_src(dest,*dd); - } - else - { - // find src gdd in dest container and just do put() - s=mapAppToIndex(dest.applicationType(),src.applicationType(),index); - - if(s==0) - rc=dest[index].put(&src); - } - return rc; -} - -// the destination in the container we must walk through is this called -gddStatus gddApplicationTypeTable::copyDD_dest(gdd& dest, const gdd& src) -{ - gddStatus rc=0,s; - gddCursor cur; - gdd* dd; - aitIndex index; - - if(dest.isContainer()) - { - gddContainer& cdd = (gddContainer&) dest; - // go through dest gdd and map app types to index into src - cur=cdd.getCursor(); - for(dd=cur.first();dd;dd=dd->next()) copyDD_dest(*dd,src); - } - else - { - // find dest gdd in src container and just do put() - s=mapAppToIndex(src.applicationType(),dest.applicationType(),index); - - if(s==0) - rc=dest.put(&src[index]); - } - return rc; -} - -gddStatus gddApplicationTypeTable::smartCopy(gdd* dest, const gdd* src) -{ - gddStatus rc = gddErrorNotAllowed; - - // only works with managed containers because app table mapping - // feature is used. - - if(dest->isContainer() && dest->isManaged()) - rc=copyDD_src(*dest,*src); - else if(src->isContainer() && src->isManaged()) - rc=copyDD_dest(*dest,*src); - else if(!src->isContainer() && !dest->isContainer()) { - if ( src->applicationType() == dest->applicationType() ) { - rc=dest->put(src); // both are not containers, let gdd handle it - } - else { - rc=gddErrorNotDefined; - } - } - - gddAutoPrint("gddAppTable::smartCopy()",rc); - - return rc; -} - -// ----------------------smart reference functions------------------------ -// the source in the container we must walk through is this called -gddStatus gddApplicationTypeTable::refDD_src(gdd& dest, const gdd& src) -{ - gddStatus rc=0,s; - gddCursor cur; - gdd* dd; - aitIndex index; - - // this could be done better (faster) if we did not always recurse for - // each GDD. I could have checked for type container before recursing. - - if(src.isContainer()) - { - gddContainer& cdd=(gddContainer&)src; - // go through src gdd and map app types to index into dest - cur=cdd.getCursor(); - for(dd=cur.first();dd;dd=dd->next()) refDD_src(dest,*dd); - } - else - { - // find src gdd in dest container and just do put() - s=mapAppToIndex(dest.applicationType(),src.applicationType(),index); - - if(s==0) - rc=dest[index].putRef(&src); - } - return rc; -} - -// the destination in the container we must walk through is this called -gddStatus gddApplicationTypeTable::refDD_dest(gdd& dest, const gdd& src) -{ - gddStatus rc=0,s; - gddCursor cur; - gdd* dd; - aitIndex index; - - if(dest.isContainer()) - { - gddContainer& cdd=(gddContainer&)dest; - // go through dest gdd and map app types to index into src - cur=cdd.getCursor(); - for(dd=cur.first();dd;dd=dd->next()) refDD_dest(*dd,src); - } - else - { - // find dest gdd in src container and just do put() - s=mapAppToIndex(src.applicationType(),dest.applicationType(),index); - - if(s==0) - rc=dest.putRef(&src[index]); - } - return rc; -} - -gddStatus gddApplicationTypeTable::smartRef(gdd* dest, const gdd* src) -{ - gddStatus rc=0; - - // only works with managed containers because app table mapping - // feature is used. - - if(dest->isContainer() && dest->isManaged()) - rc=refDD_src(*dest,*src); - else if(src->isContainer() && src->isManaged()) - rc=refDD_dest(*dest,*src); - else if(!src->isContainer() && !dest->isContainer()) - rc=dest->putRef(src); // both are not containers, let gdd handle it - else - rc=gddErrorNotAllowed; - - gddAutoPrint("gddAppTable::smartRef()",rc); - return rc; -} diff --git a/src/ca/legacy/gdd/gddAppTable.h b/src/ca/legacy/gdd/gddAppTable.h deleted file mode 100644 index fe67c6577..000000000 --- a/src/ca/legacy/gdd/gddAppTable.h +++ /dev/null @@ -1,203 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 GDD_APPLTYPE_TABLE_H -#define GDD_APPLTYPE_TABLE_H - -/* - * Author: Jim Kowalkowski - * Date: 2/96 - */ - -#include "gdd.h" -#include "gddUtils.h" -#include - -// must be power of 2 for group size -#define APPLTABLE_GROUP_SIZE 64 -#define APPLTABLE_GROUP_SIZE_POW 6 - -// default set of application type names -#define GDD_UNITS_SIZE 8 -#define GDD_NAME_UNITS "units" -#define GDD_NAME_MAX_ELEMENTS "maxElements" -#define GDD_NAME_PRECISION "precision" -#define GDD_NAME_GRAPH_HIGH "graphicHigh" -#define GDD_NAME_GRAPH_LOW "graphicLow" -#define GDD_NAME_CONTROL_HIGH "controlHigh" -#define GDD_NAME_CONTROL_LOW "controlLow" -#define GDD_NAME_ALARM_HIGH "alarmHigh" -#define GDD_NAME_ALARM_LOW "alarmLow" -#define GDD_NAME_ALARM_WARN_HIGH "alarmHighWarning" -#define GDD_NAME_ALARM_WARN_LOW "alarmLowWarning" -#define GDD_NAME_VALUE "value" -#define GDD_NAME_ENUM "enums" -#define GDD_NAME_MENUITEM "menuitem" -#define GDD_NAME_STATUS "status" -#define GDD_NAME_SEVERITY "severity" -#define GDD_NAME_TIME_STAMP "timeStamp" -#define GDD_NAME_ALL "all" -#define GDD_NAME_ATTRIBUTES "attributes" -#define GDD_NAME_PV_NAME "name" -#define GDD_NAME_ACKT "ackt" -#define GDD_NAME_ACKS "acks" -#define GDD_NAME_CLASS "class" - -typedef enum -{ - gddApplicationTypeUndefined, - gddApplicationTypeProto, - gddApplicationTypeNormal -} gddApplicationTypeType; - -class gddApplicationTypeTable; - -class gddApplicationTypeDestructor : public gddDestructor -{ -public: - gddApplicationTypeDestructor(gddApplicationTypeTable* v) : gddDestructor(v) { } - void run(void*); -}; - -class gddApplicationTypeElement -{ -public: - gddApplicationTypeElement(void); - ~gddApplicationTypeElement(void); - - char* app_name; - size_t proto_size; - aitIndex total_dds; - gdd* proto; - gdd* free_list; - epicsMutex sem; - gddApplicationTypeType type; - aitUint32 user_value; - aitUint16* map; - aitUint16 map_size; -}; - -// The app table allows registering a prototype DD for app. This class -// allows the user to ask for a DD given a app. The class will manage -// a free list of DD buffers if the app has a prototype DD -// associated with it. The gddApplicationTypeDestructor allows the DD to be -// returned to the free list for the DD app in the app table. - -class epicsShareClass gddApplicationTypeTable -{ -public: - gddApplicationTypeTable(aitUint32 total_number_of_apps=(1<<9)); - ~gddApplicationTypeTable(void); - - // standard method - gddStatus registerApplicationType(const char* const name, aitUint32& app); - gddStatus registerApplicationTypeWithProto(const char* const name, - gdd* protoDD, aitUint32& app); - - // alternative method to register types - aitUint32 registerApplicationType(const char* const name); - aitUint32 registerApplicationTypeWithProto(const char* const name, - gdd* protoDD); - - // hashing still not used for string names to app types - aitUint32 getApplicationType(const char* const name) const; - char* getName(aitUint32 app) const; - gddStatus mapAppToIndex(aitUint32 container_app, - aitUint32 app_to_map, aitUint32& index); - - // copy as best as possible from src to dest, one of the gdd must be - // managed for this to succeed - gddStatus smartCopy(gdd* dest, const gdd* src); - gddStatus smartRef(gdd* dest, const gdd* src); - - // old style interface - int tagC2I(const char* const ctag, int& tag); - int tagC2I(const char* const ctag, int* const tag); - int tagI2C(int tag, char* const ctag); - int insertApplicationType(int tag, const char* ctag); - - gdd* getDD(aitUint32 app); - - // This should be a protected function, users should - // always unreference a DD. Probably can occurs if there is another - // manager in the system. This function cannot distinguish between - // a DD managed by it or someone else. The AppDestructor will call - // this function indirectly by unreferencing the DD. - gddStatus freeDD(gdd*); - - aitUint32 maxAttributes(void) const { return max_allowed; } - aitUint32 totalregistered(void) const { return total_registered; } - void describe(FILE*); - gddStatus storeValue(aitUint32 app, aitUint32 user_value); - aitUint32 getValue(aitUint32 app); - - static gddApplicationTypeTable& AppTable(void); - static gddApplicationTypeTable app_table; - -protected: - void GenerateTypes(void); - - gddStatus copyDD_src(gdd& dest, const gdd& src); - gddStatus copyDD_dest(gdd& dest, const gdd& src); - gddStatus refDD_src(gdd& dest, const gdd& src); - gddStatus refDD_dest(gdd& dest, const gdd& src); - -private: - gddStatus splitApplicationType(aitUint32 r,aitUint32& g,aitUint32& a) const; - aitUint32 group(aitUint32 rapp) const; - aitUint32 index(aitUint32 rapp) const; - int describeDD(gddContainer* dd, FILE* fd, int level, char* tn); - - aitUint32 total_registered; - aitUint32 max_allowed; - aitUint32 max_groups; - - gddApplicationTypeElement** attr_table; - epicsMutex sem; -}; - -inline aitUint32 gddApplicationTypeTable::group(aitUint32 rapp) const - { return (rapp&(~(APPLTABLE_GROUP_SIZE-1)))>>APPLTABLE_GROUP_SIZE_POW; } -inline aitUint32 gddApplicationTypeTable::index(aitUint32 rapp) const - { return rapp&(APPLTABLE_GROUP_SIZE-1); } - -inline gddStatus gddApplicationTypeTable::splitApplicationType(aitUint32 rapp, - aitUint32& g, aitUint32& app) const -{ - gddStatus rc=0; - g=group(rapp); - app=index(rapp); - if(rapp>=total_registered) - { - rc=gddErrorOutOfBounds; - gddAutoPrint("gddAppTable::splitApplicationType()",rc); - } - return rc; -} - -inline aitUint32 gddApplicationTypeTable::registerApplicationType( - const char* const name) -{ - aitUint32 app; - registerApplicationType(name,app); - return app; -} - -inline aitUint32 gddApplicationTypeTable::registerApplicationTypeWithProto( - const char* const name, gdd* protoDD) -{ - aitUint32 app; - registerApplicationTypeWithProto(name,protoDD,app); - return app; -} - -gddApplicationTypeTable* gddGenerateApplicationTypeTable(aitUint32 x=(1<<10)); - -#endif - diff --git a/src/ca/legacy/gdd/gddArray.cc b/src/ca/legacy/gdd/gddArray.cc deleted file mode 100644 index 8c9df0835..000000000 --- a/src/ca/legacy/gdd/gddArray.cc +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 - -// Author: Jim Kowalkowski -// Date: 3/97 - -#define epicsExportSharedSymbols -#include "gdd.h" - -// ----------------------The gddAtomic functions------------------------- - -gddAtomic::gddAtomic(int app, aitEnum prim, int dimen, ...): - gdd(app,prim,dimen) -{ - va_list ap; - int i; - aitIndex val; - - va_start(ap,dimen); - for(i=0;i0) - for(i=0;i0) - for(i=0;i0) - for(i=0;i0) - for(i=0;i -#include -#include - -// Author: Jim Kowalkowski -// Date: 3/97 - -#define epicsExportSharedSymbols -#include "gdd.h" - -// --------------------The gddContainer functions--------------------- - -gddCursor gddContainer::getCursor(void) -{ - return gddCursor (this); -} - -constGddCursor gddContainer::getCursor(void) const -{ - return constGddCursor (this); -} - -gddContainer::gddContainer(void):gdd(0,aitEnumContainer,1) { } -gddContainer::gddContainer(int app):gdd(app,aitEnumContainer,1) { } - -gddContainer::gddContainer(int app,int tot) : gdd(app,aitEnumContainer,1) - { cInit(tot); } - -void gddContainer::cInit(int tot) -{ - int i; - gdd* dd_list; - gdd* temp; - - setBound(0,0,tot); - dd_list=NULL; - - for(i=0;inoReferencing(); - temp->setNext(dd_list); - dd_list=temp; - } - setData(dd_list); -} - - -gddContainer::gddContainer(gddContainer* ec) -{ - // - // added this because the "copy()" below bombs - // if the GDD isnt initialized - // joh - 4-23-99 - // - this->init (ec->appl_type, aitEnumContainer, 1); - -#if 1 - // - // this replaces some the strange code below - // that existed before - // joh - 4-23-99 - // - copyInfo(ec); -#else - unsigned i; - gdd* dd_list; - gdd* temp; - - copy(ec); - dd_list=NULL; - - // this needs to recursively add to the container, only copy the - // info and bounds information and scaler data, not arrays - - for(i=0;inoReferencing(); - temp->setNext(dd_list); - dd_list=temp; - } - setData(dd_list); -#endif -} - -gddStatus gddContainer::insert(gdd* dd) -{ - dd->setNext(cData()); - setData(dd); - bounds->setSize(bounds->size()+1); - return 0; -} - -gddStatus gddContainer::remove(aitIndex index) -{ - gddCursor cur = getCursor(); - gdd *dd,*prev_dd; - aitIndex i; - - prev_dd=NULL; - - for(i=0; (dd=cur[i]) && i!=index; i++) prev_dd=dd; - - if(i==index && dd) - { - if(prev_dd) - prev_dd->setNext(dd->next()); - else - setData(dd->next()); - - dd->unreference(); - bounds->setSize(bounds->size()-1); - return 0; - } - else - { - gddAutoPrint("gddContainer::remove()",gddErrorOutOfBounds); - return gddErrorOutOfBounds; - } -} - -// ------------------------cursor functions------------------------------- - -const gdd* constGddCursor::operator[](int index) -{ - int i,start; - const gdd* dd; - - if(index>=curr_index) - { - start=curr_index; - dd=curr; - } - else - { - start=0; - dd=list->cData(); - } - - for(i=start;inext(); - curr_index=index; - curr=dd; - return dd; -} - diff --git a/src/ca/legacy/gdd/gddContainer.h b/src/ca/legacy/gdd/gddContainer.h deleted file mode 100644 index 7830eb641..000000000 --- a/src/ca/legacy/gdd/gddContainer.h +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 GDD_CONTAINER_H -#define GDD_CONTAINER_H - -/* - * Author: Jim Kowalkowski - * Date: 3/97 - */ - -#include "shareLib.h" - -class constGddCursor; -class gddCursor; - -/* this class needs to be able to register a destructor for the container */ - -class epicsShareClass gddContainer : public gdd -{ -public: - gddContainer(void); - gddContainer(int app); - gddContainer(gddContainer* ac); - gddContainer(int app,int number_of_things_in_it); - - gddStatus insert(gdd*); - gddStatus remove(aitIndex index); - int total(void) const; - - void dump(void) const; - void test(void); - - // preferred method for looking into a container - gddCursor getCursor(void); - constGddCursor getCursor(void) const; - - const gdd* cData(void) const; - gdd* cData(void); - -protected: - gddContainer(int,int,int,int*); - ~gddContainer(void); - - void cInit(int num_things_within); - gddStatus changeType(int,aitEnum); - gddStatus setBound(int,aitIndex,aitIndex); - gddStatus getBound(int,aitIndex&,aitIndex&) const; - gddStatus setBound(aitIndex,aitIndex); - -private: - friend class constGddCursor; -}; - -class epicsShareClass constGddCursor { -public: - constGddCursor(void); - constGddCursor(const gddContainer* ec); - - const gdd* first(void); - const gdd* first(const gddScalar*&); - const gdd* first(const gddAtomic*&); - const gdd* first(const gddContainer*&); - - const gdd* next(void); - const gdd* next(const gddScalar*&); - const gdd* next(const gddAtomic*&); - const gdd* next(const gddContainer*&); - - const gdd* current(void) const; - const gdd* current(const gddScalar*&) const; - const gdd* current(const gddAtomic*&) const; - const gdd* current(const gddContainer*&) const; - - const gdd* operator[](int index); - -private: - const gddContainer* list; - const gdd* curr; - int curr_index; -}; - -class epicsShareClass gddCursor : private constGddCursor { -public: - gddCursor(void); - gddCursor(gddContainer* ec); - - gdd* first(void); - gdd* first(gddScalar*&); - gdd* first(gddAtomic*&); - gdd* first(gddContainer*&); - - gdd* next(void); - gdd* next(gddScalar*&); - gdd* next(gddAtomic*&); - gdd* next(gddContainer*&); - - gdd* current(void) const; - gdd* current(gddScalar*&) const; - gdd* current(gddAtomic*&) const; - gdd* current(gddContainer*&) const; - - gdd* operator[](int index); -}; - -#endif diff --git a/src/ca/legacy/gdd/gddContainerI.h b/src/ca/legacy/gdd/gddContainerI.h deleted file mode 100644 index 55f306342..000000000 --- a/src/ca/legacy/gdd/gddContainerI.h +++ /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. -\*************************************************************************/ -#ifndef GDD_CONTAINERI_H -#define GDD_CONTAINERI_H - -/* - * Author: Jim Kowalkowski - * Date: 3/97 - */ - -inline gddContainer::gddContainer(int,int,int,int*) { } -inline gddContainer::~gddContainer(void) { } - -inline gddStatus gddContainer::changeType(int,aitEnum) { - gddAutoPrint("gddContainer::changeType()",gddErrorNotAllowed); - return gddErrorNotAllowed; } -inline gddStatus gddContainer::setBound(int,aitIndex,aitIndex) { - gddAutoPrint("setBound()",gddErrorNotAllowed); - return gddErrorNotAllowed; } -inline gddStatus gddContainer::getBound(int,aitIndex&,aitIndex&) const { - gddAutoPrint("getBound()",gddErrorNotAllowed); - return gddErrorNotAllowed; } - -inline gdd* gddContainer::cData(void) - { return (gdd*)dataPointer(); } - -inline const gdd* gddContainer::cData(void) const - { return (const gdd*)dataPointer(); } - -inline int gddContainer::total(void) const - { return bounds->size(); } - -inline gddStatus gddContainer::setBound(aitIndex f, aitIndex c) - { bounds->set(f,c); return 0; } - -inline constGddCursor::constGddCursor(void):list(NULL) - { curr=NULL; } -inline constGddCursor::constGddCursor(const gddContainer* ec):list(ec) - { curr=ec->cData(); curr_index=0; } - -inline const gdd* constGddCursor::first(void) - { curr=list->cData(); curr_index=0; return curr; } -inline const gdd* constGddCursor::first(const gddScalar*& dd) - { return (const gdd*)(dd=(gddScalar*)first()); } -inline const gdd* constGddCursor::first(const gddAtomic*& dd) - { return (const gdd*)(dd=(gddAtomic*)first()); } -inline const gdd* constGddCursor::first(const gddContainer*& dd) - { return (const gdd*)(dd=(gddContainer*)first()); } - -inline const gdd* constGddCursor::next(void) - { if(curr) { curr_index++;curr=curr->next(); } return curr; } -inline const gdd* constGddCursor::next(const gddScalar*& dd) - { return (const gdd*)(dd=(gddScalar*)next()); } -inline const gdd* constGddCursor::next(const gddAtomic*& dd) - { return (const gdd*)(dd=(gddAtomic*)next()); } -inline const gdd* constGddCursor::next(const gddContainer*& dd) - { return (const gdd*)(dd=(gddContainer*)next()); } - -inline const gdd* constGddCursor::current(void) const - { return curr; } -inline const gdd* constGddCursor::current(const gddScalar*& dd) const - { return (const gdd*)(dd=(gddScalar*)current()); } -inline const gdd* constGddCursor::current(const gddAtomic*& dd) const - { return (const gdd*)(dd=(gddAtomic*)current()); } -inline const gdd* constGddCursor::current(const gddContainer*& dd) const - { return (const gdd*)(dd=(gddContainer*)current()); } - -inline gddCursor::gddCursor(void){} -inline gddCursor::gddCursor(gddContainer* ec) : - constGddCursor(ec) {} - -inline gdd* gddCursor::first(void) - { return (gdd *) constGddCursor::first(); } -inline gdd* gddCursor::first(gddScalar*& dd) - { return (gdd *) constGddCursor::first((const gddScalar*&)dd); } -inline gdd* gddCursor::first(gddAtomic*& dd) - { return (gdd *) constGddCursor::first((const gddAtomic*&)dd); } -inline gdd* gddCursor::first(gddContainer*& dd) - { return (gdd *) constGddCursor::first((const gddContainer*&)dd); } - -inline gdd* gddCursor::next(void) - { return (gdd *) constGddCursor::next(); } -inline gdd* gddCursor::next(gddScalar*& dd) - { return (gdd*)constGddCursor::next((const gddScalar*&)dd); } -inline gdd* gddCursor::next(gddAtomic*& dd) - { return (gdd*)constGddCursor::next((const gddAtomic*&)dd); } -inline gdd* gddCursor::next(gddContainer*& dd) - { return (gdd*)constGddCursor::next((const gddContainer*&)dd); } - -inline gdd* gddCursor::current(void) const - { return (gdd*)constGddCursor::current(); } -inline gdd* gddCursor::current(gddScalar*& dd) const - { return (gdd*)constGddCursor::current((const gddScalar*&)dd); } -inline gdd* gddCursor::current(gddAtomic*& dd) const - { return (gdd*)constGddCursor::current((const gddAtomic*&)dd); } -inline gdd* gddCursor::current(gddContainer*& dd) const - { return (gdd*)constGddCursor::current((const gddContainer*&)dd); } - -inline gdd* gddCursor::operator[](int index) -{ return (gdd *) constGddCursor::operator [](index); } - -#endif diff --git a/src/ca/legacy/gdd/gddEnumStringTable.cc b/src/ca/legacy/gdd/gddEnumStringTable.cc deleted file mode 100644 index fd74b35d8..000000000 --- a/src/ca/legacy/gdd/gddEnumStringTable.cc +++ /dev/null @@ -1,152 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// gddEnumStringTable.cc -// Author: Jeff Hill -// - -#include - -#include - -#define epicsExportSharedSymbols -#include "gddEnumStringTable.h" - -gddEnumStringTable::~gddEnumStringTable () -{ - for ( unsigned i = 0u; i < this->nStringSlots; i++ ) { - delete [] this->pStringTable[i].pString; - } - delete [] this->pStringTable; -} - -bool gddEnumStringTable::expand ( unsigned nStringsRequired ) -{ - stringEntry * pNextTable = new ( std::nothrow ) stringEntry [nStringsRequired]; - if ( pNextTable ) { - for ( unsigned i = 0u; i < this->nStringSlots; i++ ) { - pNextTable[i] = this->pStringTable[i]; - } - for ( unsigned j = this->nStringSlots; j < nStringsRequired; j++ ) { - pNextTable[j].pString = 0; - pNextTable[j].length = 0; - } - delete [] this->pStringTable; - this->pStringTable = pNextTable; - this->nStringSlots = nStringsRequired; - return true; - } - else { - return false; - } -} - -void gddEnumStringTable::reserve ( unsigned nStringsIn ) -{ - if ( nStringsIn > this->nStringSlots ) { - this->expand ( nStringsIn ); - } -} - -void gddEnumStringTable::clear () -{ - for ( unsigned i = 0u; i < this->nStringSlots; i++ ) { - delete [] this->pStringTable[i].pString; - } - delete [] this->pStringTable; - this->pStringTable = 0; - this->nStringSlots = 0; - this->nStrings = 0; -} - -bool gddEnumStringTable::setString ( unsigned index, const char *pString ) -{ - if ( index >= this->nStringSlots ) { - unsigned nStringsNext; - if ( this->nStringSlots < 16 ) { - nStringsNext = 16; - } - else { - nStringsNext = this->nStringSlots; - } - while ( index >= nStringsNext ) { - nStringsNext += nStringsNext; - } - if ( ! this->expand ( nStringsNext ) ) { - return false; - } - } - unsigned nChar = strlen ( pString ); - char *pNewString = new ( std::nothrow ) char [ nChar + 1 ]; - if ( ! pNewString ) { - return false; - } - delete [] this->pStringTable[index].pString; - this->pStringTable[index].pString = pNewString; - strcpy ( this->pStringTable[index].pString, pString ); - this->pStringTable[index].length = nChar; - if ( this->nStrings <= index ) { - this->nStrings = index + 1; - } - return true; -} - -void gddEnumStringTable::getString ( unsigned index, char *pBuf, unsigned size ) const -{ - if ( index < this->nStrings && size ) { - if ( this->pStringTable[index].pString ) { - strncpy ( pBuf, this->pStringTable[index].pString, size ); - pBuf[ size - 1 ] = '\0'; - } - else { - pBuf[ 0 ] = '\0'; - } - } - else { - pBuf[ 0 ] = '\0'; - } -} - -const char * gddEnumStringTable::getString ( unsigned index ) const -{ - if ( index < this->nStrings ) { - if ( this->pStringTable[index].pString ) { - return this->pStringTable[index].pString; - } - else { - return ""; - } - } - else { - return ""; - } -} - -unsigned gddEnumStringTable::getStringLength ( unsigned index ) const -{ - if ( index < this->nStrings ) { - return this->pStringTable[index].length; - } - else { - return 0; - } -} - -bool gddEnumStringTable::getIndex ( const char * pString, unsigned & indexOut ) const -{ - for ( unsigned index = 0u; index < this->nStrings; index++ ) { - if ( ! strcmp ( pString, this->pStringTable[index].pString ) ) { - indexOut = index; - return true; - } - } - return false; -} - diff --git a/src/ca/legacy/gdd/gddEnumStringTable.h b/src/ca/legacy/gdd/gddEnumStringTable.h deleted file mode 100644 index 5d92433a8..000000000 --- a/src/ca/legacy/gdd/gddEnumStringTable.h +++ /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. -\*************************************************************************/ -// -// gddEnumStringTable.h -// Author: Jeff Hill -// - -#ifndef gddEnumStringTableh -#define gddEnumStringTableh - -#include "shareLib.h" - -class epicsShareClass gddEnumStringTable { -public: - gddEnumStringTable (); - ~gddEnumStringTable (); - void clear (); - void reserve ( unsigned nStrings ); - bool setString ( unsigned index, const char *pString ); - void getString ( unsigned index, char *pBuf, unsigned size ) const; - const char * getString ( unsigned index ) const; - unsigned getStringLength ( unsigned index ) const; - bool getIndex ( const char * pString, unsigned & index ) const; - unsigned numberOfStrings () const; -private: - unsigned nStrings; - unsigned nStringSlots; - struct stringEntry { - char * pString; - unsigned length; - } * pStringTable; - bool expand ( unsigned nStringsRequired ); -}; - -inline gddEnumStringTable::gddEnumStringTable () : - nStrings ( 0 ), nStringSlots ( 0 ), pStringTable ( 0 ) {} - -inline unsigned gddEnumStringTable::numberOfStrings () const -{ - return this->nStrings; -} - -#endif // ifndef gddEnumStringTableh diff --git a/src/ca/legacy/gdd/gddErrorCodes.cc b/src/ca/legacy/gdd/gddErrorCodes.cc deleted file mode 100644 index 7c20292be..000000000 --- a/src/ca/legacy/gdd/gddErrorCodes.cc +++ /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. -\*************************************************************************/ - -// Author: Jim Kowalkowski -// Date: 3/97 - -// -------------------------- Error messages ------------------------- - -const char* gddErrorMessages[]= -{ - "Invalid", - "TypeMismatch", - "NotAllowed", - "AlreadyDefined", - "NewFailed", - "OutOfBounds", - "AtLimit", - "NotDefined", - "NotSupported", - "Overflow", - "Underflow" -}; - diff --git a/src/ca/legacy/gdd/gddErrorCodes.h b/src/ca/legacy/gdd/gddErrorCodes.h deleted file mode 100644 index 061fbab71..000000000 --- a/src/ca/legacy/gdd/gddErrorCodes.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. -\*************************************************************************/ -#ifndef GDD_ERROR_CODES_H -#define GDD_ERROR_CODES_H - -/* - * Author: Jim Kowalkowski - * Date: 2/96 - */ - -#include "shareLib.h" - -/* - gdd.cc contains a table (gddErrorMessages) that has all the text - strings for each of the error codes -*/ - -typedef long gddStatus; - -#define gddErrorTypeMismatch -1 -#define gddErrorNotAllowed -2 -#define gddErrorAlreadyDefined -3 -#define gddErrorNewFailed -4 -#define gddErrorOutOfBounds -5 -#define gddErrorAtLimit -6 -#define gddErrorNotDefined -7 -#define gddErrorNotSupported -8 -#define gddErrorOverflow -9 -#define gddErrorUnderflow -10 - -epicsShareExtern char* gddErrorMessages[]; - -#define gddPrintError(x) \ - fprintf(stderr,"gdd Error: %s\n",gddErrorMessages[x*(-1)]); - -#define gddPrintErrorWithMessage(msg,x) \ - fprintf(stderr,"gdd Error: %s (%s)\n",gddErrorMessages[x*(-1)],msg); - -#define gddGetErrorMessage(x) gddErrorMessages[x*(-1)] - -#ifdef GDDAUTOPRINT -#define gddAutoPrint(s,x) if(x) gddPrintErrorWithMessage(s,x) -#else -#define gddAutoPrint(s,x) ; -#endif - -#endif diff --git a/src/ca/legacy/gdd/gddI.h b/src/ca/legacy/gdd/gddI.h deleted file mode 100644 index ef13f66bd..000000000 --- a/src/ca/legacy/gdd/gddI.h +++ /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 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 GDDI_H -#define GDDI_H - -/* - * Author: Jim Kowalkowski - * Date: 3/97 - */ - -inline void gdd::setData(void* d) { data.Pointer=d; } -inline const gddDestructor* gdd::destructor(void) const { return destruct; } - -inline gdd::gdd(void) { init(0,aitEnumInvalid,0); } -inline gdd::gdd(int app) { init(app,aitEnumInvalid,0); } -inline gdd::gdd(int app,aitEnum prim) { init(app,prim,0); } - -inline unsigned gdd::applicationType(void) const{ return appl_type; } -inline aitEnum gdd::primitiveType(void) const { return (aitEnum)prim_type; } -inline const gddBounds* gdd::getBounds(void) const { return bounds; } -inline const gddBounds* gdd::getBounds(int bn) const { return &bounds[bn]; } - -inline gdd* gdd::next(void) { return nextgdd; } -inline const gdd* gdd::next(void) const { return nextgdd; } -inline void gdd::setNext(gdd* n) { nextgdd=n; } -inline unsigned gdd::dimension(void) const { return dim; } -inline aitType& gdd::getData(void) { return data; } -inline const aitType& gdd::getData(void) const { return data; } -inline aitType* gdd::dataUnion(void) { return &data; } -inline const aitType* gdd::dataUnion(void)const { return &data; } -inline void gdd::setApplType(int t) { appl_type=(aitUint16)t; } -inline gddStatus gdd::copyInfo(const gdd* dd) { return copyStuff(dd,0); } -inline gddStatus gdd::copy(const gdd* dd) { return copyStuff(dd,1); } -inline gddStatus gdd::Dup(const gdd* dd) { return copyStuff(dd,2); } -inline const void* gdd::dataAddress(void) const { return (void*)&data; } -inline void* gdd::dataAddress(void) { return (void*)&data; } -inline const void* gdd::dataPointer(void) const { return data.Pointer; } -inline void* gdd::dataPointer(void) { return data.Pointer; } - -inline const void* gdd::dataVoid(void) const -{ - return (dimension()||primitiveType()==aitEnumFixedString)? - dataPointer():dataAddress(); -} - -inline void* gdd::dataVoid(void) -{ - return (dimension()||primitiveType()==aitEnumFixedString)? - dataPointer():dataAddress(); -} - -inline aitUint32 gdd::align8(unsigned long count) const -{ - unsigned long tmp=count&(~((unsigned long)0x07)); - return (tmp!=count)?tmp+8:tmp; -} - -inline const void* gdd::dataPointer(aitIndex f) const - { return (void*)(((aitUint8*)dataPointer())+aitSize[primitiveType()]*f); } - -inline void* gdd::dataPointer(aitIndex f) - { return (void*)(((aitUint8*)dataPointer())+aitSize[primitiveType()]*f); } - -inline int gdd::isManaged(void) const { return flags&GDD_MANAGED_MASK; } -inline int gdd::isFlat(void) const { return flags&GDD_FLAT_MASK; } -inline int gdd::isNoRef(void) const { return flags&GDD_NOREF_MASK; } -inline int gdd::isConstant(void) const { return flags&GDD_CONSTANT_MASK; } -inline int gdd::isLocalDataFormat(void) const { return !(flags&GDD_NET_MASK); } -inline int gdd::isNetworkDataFormat(void) const - { return !isLocalDataFormat() || aitLocalNetworkDataFormatSame; } - -inline void gdd::markConstant(void) { flags|=GDD_CONSTANT_MASK; } -inline void gdd::markFlat(void) { flags|=GDD_FLAT_MASK; } -inline void gdd::markManaged(void) { flags|=GDD_MANAGED_MASK; } -inline void gdd::markUnmanaged(void) { flags&=~GDD_MANAGED_MASK; } -inline void gdd::markLocalDataFormat(void) { flags&=~GDD_NET_MASK; } -inline void gdd::markNotLocalDataFormat(void) { flags|=GDD_NET_MASK; } - -inline void gdd::getTimeStamp(struct timespec* const ts) const { time_stamp.get(*ts); } -inline void gdd::setTimeStamp(const struct timespec* const ts) { time_stamp=*ts; } - -inline void gdd::getTimeStamp(aitTimeStamp* const ts) const { *ts = time_stamp; } -inline void gdd::setTimeStamp(const aitTimeStamp* const ts) { time_stamp=*ts; } - -inline void gdd::getTimeStamp(struct epicsTimeStamp* const ts) const { time_stamp.get(*ts); } -inline void gdd::setTimeStamp(const struct epicsTimeStamp* const ts) { time_stamp=*ts; } - -inline void gdd::setStatus(aitUint32 s) { status.u = s; } -inline void gdd::getStatus(aitUint32& s) const { s = status.u; } -inline void gdd::setStatus(aitUint16 high, aitUint16 low) - { status.u = (aitUint32)high << 16 | low; } -inline void gdd::getStatus(aitUint16& high, aitUint16& low) const - { high = (aitUint16)(status.u >> 16); - low = (aitUint16)(status.u & 0x0000ffff); } - -inline void gdd::setStat(aitUint16 s) - { status.s.aitStat = s; } -inline void gdd::setSevr(aitUint16 s) - { status.s.aitSevr = s; } -inline aitUint16 gdd::getStat(void) const - { return status.s.aitStat; } -inline aitUint16 gdd::getSevr(void) const - { return status.s.aitSevr; } -inline void gdd::getStatSevr(aitInt16& stat, aitInt16& sevr) const - { stat = status.s.aitStat; sevr = status.s.aitSevr; } -inline void gdd::setStatSevr(aitInt16 stat, aitInt16 sevr) - { status.s.aitStat = stat; status.s.aitSevr = sevr; } - -inline gdd& gdd::operator=(const gdd& v) - { memcpy(this,&v,sizeof(gdd)); return *this; } - -inline int gdd::isScalar(void) const { return dimension()==0?1:0; } -inline int gdd::isContainer(void) const - { return (primitiveType()==aitEnumContainer)?1:0; } -inline int gdd::isAtomic(void) const - { return (dimension()>0&&primitiveType()!=aitEnumContainer)?1:0; } -inline gddStatus gdd::noReferencing(void) -{ - int rc=0; - if(ref_cnt>1) - { - gddAutoPrint("gdd::noReferencing()",gddErrorNotAllowed); - rc=gddErrorNotAllowed; - } - else flags|=GDD_NOREF_MASK; - return rc; -} -inline gddStatus gdd::reference(void) const -{ - epicsGuard < epicsMutex > guard ( * gdd::pGlobalMutex ); - - int rc=0; - - if(isNoRef()) - { - fprintf(stderr,"reference of gdd marked \"no-referencing\" ignored!!\n"); - gddAutoPrint("gdd::reference()",gddErrorNotAllowed); - rc = gddErrorNotAllowed; - } - else if ( this->ref_cnt < 0xffffffff ) { - this->ref_cnt++; - } - else { - fprintf(stderr,"gdd reference count overflow!!\n"); - gddAutoPrint("gdd::reference()",gddErrorOverflow); - rc=gddErrorOverflow; - } - return rc; -} - -inline gddStatus gdd::unreference(void) const -{ - epicsGuard < epicsMutex > guard ( * gdd::pGlobalMutex ); - - int rc=0; - - if ( ref_cnt > 1u ) { - ref_cnt--; - } - else if ( ref_cnt == 1u ) - { - if ( isManaged() ) { - // managed dd always destroys the entire thing - if(destruct) destruct->destroy((void *)this); - destruct=NULL; - } - else if(!isFlat()) { - // hopefully catch ref/unref missmatches while - // gdd is on free list - ref_cnt = 0; - delete this; - } - } - else { - fprintf(stderr,"gdd reference count underflow!!\n"); - gddAutoPrint("gdd::unreference()",gddErrorUnderflow); - rc=gddErrorUnderflow; - } - return rc; -} - -inline void gdd::adjust(gddDestructor* d, void* v, aitEnum type,aitDataFormat) -{ - if(destruct) destruct->destroy(dataPointer()); - destruct=d; - if(destruct) destruct->reference(); - setPrimType(type); - setData(v); -} - -// These function do NOT work well for aitFixedString because -// fixed strings are always stored by reference. You WILL get -// into trouble is the gdd does not contain a fixed string -// before you putConvert() something into it. - -#if aitLocalNetworkDataFormatSame == AIT_FALSE -inline void gdd::get(aitEnum t,void* v,aitDataFormat f) const -#else -inline void gdd::get(aitEnum t,void* v,aitDataFormat) const -#endif -{ - if(primitiveType()==aitEnumFixedString) - { - if(dataPointer()) aitConvert(t,v,primitiveType(),dataPointer(),1); - } - else - { -#if aitLocalNetworkDataFormatSame == AIT_FALSE - if(f!=aitLocalDataFormat) - aitConvertToNet(t,v,primitiveType(),dataAddress(),1); - else -#endif - aitConvert(t,v,primitiveType(),dataAddress(),1); - } -} - -#if aitLocalNetworkDataFormatSame == AIT_FALSE -inline void gdd::set(aitEnum t,const void* v,aitDataFormat f) -#else -inline void gdd::set(aitEnum t,const void* v,aitDataFormat) -#endif -{ - if (primitiveType()==aitEnumInvalid) { - this->setPrimType (t); - } - -#if aitLocalNetworkDataFormatSame == AIT_FALSE - if(f!=aitLocalDataFormat) - aitConvertFromNet(primitiveType(),dataVoid(),t,v,1); - else -#endif - aitConvert(primitiveType(),dataVoid(),t,v,1); - - markLocalDataFormat(); -} - -// -------------------getRef(data pointer) functions---------------- -inline void gdd::getRef(const aitFloat64*& d)const { d=(aitFloat64*)dataVoid(); } -inline void gdd::getRef(const aitFloat32*& d)const { d=(aitFloat32*)dataVoid(); } -inline void gdd::getRef(const aitUint32*& d)const { d=(aitUint32*)dataVoid(); } -inline void gdd::getRef(const aitInt32*& d)const { d=(aitInt32*)dataVoid(); } -inline void gdd::getRef(const aitUint16*& d)const { d=(aitUint16*)dataVoid(); } -inline void gdd::getRef(const aitInt16*& d)const { d=(aitInt16*)dataVoid(); } -inline void gdd::getRef(const aitUint8*& d)const { d=(aitUint8*)dataVoid(); } -inline void gdd::getRef(const aitInt8*& d)const { d=(aitInt8*)dataVoid(); } -inline void gdd::getRef(const void*& d)const { d=dataVoid(); } -inline void gdd::getRef(const aitFixedString*& d)const { d=(aitFixedString*)dataVoid(); } -inline void gdd::getRef(const aitString*& d)const { d=(aitString*)dataVoid(); } -inline void gdd::getRef(aitFloat64*& d) { d=(aitFloat64*)dataVoid(); } -inline void gdd::getRef(aitFloat32*& d) { d=(aitFloat32*)dataVoid(); } -inline void gdd::getRef(aitUint32*& d) { d=(aitUint32*)dataVoid(); } -inline void gdd::getRef(aitInt32*& d) { d=(aitInt32*)dataVoid(); } -inline void gdd::getRef(aitUint16*& d) { d=(aitUint16*)dataVoid(); } -inline void gdd::getRef(aitInt16*& d) { d=(aitInt16*)dataVoid(); } -inline void gdd::getRef(aitUint8*& d) { d=(aitUint8*)dataVoid(); } -inline void gdd::getRef(aitInt8*& d) { d=(aitInt8*)dataVoid(); } -inline void gdd::getRef(void*& d) { d=dataVoid(); } -inline void gdd::getRef(aitFixedString*& d) { d=(aitFixedString*)dataVoid(); } -inline void gdd::getRef(aitString*& d) { d=(aitString*)dataVoid(); } - -// -------------------putRef(data pointer) functions---------------- -inline void gdd::putRef(void* v,aitEnum code, gddDestructor* d) - { adjust(d, v, code); } -inline void gdd::putRef(aitFloat64* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumFloat64); } -inline void gdd::putRef(aitFloat32* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumFloat32); } -inline void gdd::putRef(aitUint8* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumUint8); } -inline void gdd::putRef(aitInt8* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumInt8); } -inline void gdd::putRef(aitUint16* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumUint16); } -inline void gdd::putRef(aitInt16* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumInt16); } -inline void gdd::putRef(aitUint32* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumUint32); } -inline void gdd::putRef(aitInt32* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumInt32); } -inline void gdd::putRef(aitString* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumString); } -inline void gdd::putRef(aitFixedString* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumFixedString); } - -// -------------------putRef(const data pointer) functions---------------- -inline void gdd::putRef(const aitFloat64* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumFloat64); markConstant(); } -inline void gdd::putRef(const aitFloat32* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumFloat32); markConstant(); } -inline void gdd::putRef(const aitUint8* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumUint8); markConstant(); } -inline void gdd::putRef(const aitInt8* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumInt8); markConstant(); } -inline void gdd::putRef(const aitUint16* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumUint16); markConstant(); } -inline void gdd::putRef(const aitInt16* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumInt16); markConstant(); } -inline void gdd::putRef(const aitUint32* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumUint32); markConstant(); } -inline void gdd::putRef(const aitInt32* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumInt32); markConstant(); } -inline void gdd::putRef(const aitString* v, gddDestructor* d) - { adjust(d, (void*)v, aitEnumString); markConstant(); } -inline void gdd::putRef(const aitFixedString* v,gddDestructor* d) - { adjust(d, (void*)v, aitEnumFixedString); markConstant(); } - -// ---------------------get(pointer) functions-------------------------- -inline void gdd::get(void* d) const { - if(isScalar()) - aitConvert(primitiveType(),d,primitiveType(),dataAddress(),1); - else - aitConvert(primitiveType(),d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(void* d,aitEnum e) const { - if(isScalar()) - aitConvert(e,d,primitiveType(),dataAddress(),1); - else - aitConvert(e,d,primitiveType(),dataPointer(),getDataSizeElements()); -} -inline void gdd::get(aitFloat64* d) const -{ - if(isScalar()) - aitConvert(aitEnumFloat64,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumFloat64,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(aitFloat32* d) const { - if(isScalar()) - aitConvert(aitEnumFloat32,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumFloat32,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(aitUint32* d) const { - if(isScalar()) - aitConvert(aitEnumUint32,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumUint32,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(aitInt32* d) const { - if(isScalar()) - aitConvert(aitEnumInt32,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumInt32,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(aitUint16* d) const { - if(isScalar()) - aitConvert(aitEnumUint16,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumUint16,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(aitInt16* d) const { - if(isScalar()) - aitConvert(aitEnumInt16,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumInt16,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(aitUint8* d) const { - if(isScalar()) - aitConvert(aitEnumUint8,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumUint8,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(aitString* d) const { - if(isScalar()) - aitConvert(aitEnumString,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumString,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} -inline void gdd::get(aitFixedString* d) const { - if(isScalar()) - aitConvert(aitEnumFixedString,d,primitiveType(),dataAddress(),1); - else - aitConvert(aitEnumFixedString,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} - -// special case for string scalar to aitInt8 array! -inline void gdd::get(aitInt8* d) const -{ - if(primitiveType()==aitEnumString && dim==0) - { - aitString* str = (aitString*)dataAddress(); - strcpy((char*)d,str->string()); - } - else if(primitiveType()==aitEnumFixedString && dim==0) - strcpy((char*)d,data.FString->fixed_string); - else - aitConvert(aitEnumInt8,d,primitiveType(),dataPointer(), - getDataSizeElements()); -} - -// -------------------getConvert(scalar) functions ---------------------- -inline void gdd::getConvert(aitFloat64& d) const { get(&d, aitEnumFloat64); } -inline void gdd::getConvert(aitFloat32& d) const { get(&d, aitEnumFloat32); } -inline void gdd::getConvert(aitUint32& d) const { get(&d, aitEnumUint32); } -inline void gdd::getConvert(aitInt32& d) const { get(&d, aitEnumInt32); } -inline void gdd::getConvert(aitUint16& d) const { get(&d, aitEnumUint16); } -inline void gdd::getConvert(aitInt16& d) const { get(&d, aitEnumInt16); } -inline void gdd::getConvert(aitUint8& d) const { get(&d, aitEnumUint8); } -inline void gdd::getConvert(aitInt8& d) const { get(&d, aitEnumInt8); } - -// -------------------putConvert(scalar) functions ---------------------- -inline void gdd::putConvert(aitFloat64 d){ set(aitEnumFloat64,&d); } -inline void gdd::putConvert(aitFloat32 d){ set(aitEnumFloat32,&d); } -inline void gdd::putConvert(aitUint32 d) { set(aitEnumUint32,&d); } -inline void gdd::putConvert(aitInt32 d) { set(aitEnumInt32,&d); } -inline void gdd::putConvert(aitUint16 d) { set(aitEnumUint16,&d); } -inline void gdd::putConvert(aitInt16 d) { set(aitEnumInt16,&d); } -inline void gdd::putConvert(aitUint8 d) { set(aitEnumUint8,&d); } -inline void gdd::putConvert(aitInt8 d) { set(aitEnumInt8,&d); } - -// ------------------------put(pointer) functions---------------------- -inline gddStatus gdd::put(const aitFloat64* const d) - { return genCopy(aitEnumFloat64,d); } -inline gddStatus gdd::put(const aitFloat32* const d) - { return genCopy(aitEnumFloat32,d); } -inline gddStatus gdd::put(const aitUint32* const d) - { return genCopy(aitEnumUint32,d); } -inline gddStatus gdd::put(const aitInt32* const d) - { return genCopy(aitEnumInt32,d); } -inline gddStatus gdd::put(const aitUint16* const d) - { return genCopy(aitEnumUint16,d); } -inline gddStatus gdd::put(const aitInt16* const d) - { return genCopy(aitEnumInt16,d); } -inline gddStatus gdd::put(const aitUint8* const d) - { return genCopy(aitEnumUint8,d); } - -// special case for aitInt8 array to aitString scalar -inline gddStatus gdd::put(const aitInt8* const d) -{ - gddStatus rc=0; - - if(primitiveType()==aitEnumString && dim==0) - { - aitString* p = (aitString*)dataAddress(); - p->copy((char*)d); - } - else if(primitiveType()==aitEnumFixedString && dim==0) { - strncpy(data.FString->fixed_string,(char*)d, - sizeof(aitFixedString)); - data.FString->fixed_string[sizeof(aitFixedString)-1u]='\0'; - } - else - rc=genCopy(aitEnumInt8,d); - - return rc; -} - -// ----------------put(scalar) functions---------------- -inline gddStatus gdd::put(aitFloat64 d) { - gddStatus rc=0; - if(isScalar()) { setPrimType(aitEnumFloat64); data.Float64=d; } - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} -inline gddStatus gdd::put(aitFloat32 d) { - gddStatus rc=0; - if(isScalar()) { setPrimType(aitEnumFloat32); data.Float32=d;} - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} -inline gddStatus gdd::put(aitUint32 d) { - gddStatus rc=0; - if(isScalar()) { setPrimType(aitEnumUint32); data.Uint32=d; } - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} -inline gddStatus gdd::put(aitInt32 d) { - gddStatus rc=0; - if(isScalar()) { setPrimType(aitEnumInt32); data.Int32=d; } - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} -inline gddStatus gdd::put(aitUint16 d) { - gddStatus rc=0; - if(isScalar()) { setPrimType(aitEnumUint16); data.Uint16=d; } - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} -inline gddStatus gdd::put(aitInt16 d) { - gddStatus rc=0; - if(isScalar()) { setPrimType(aitEnumInt16); data.Int16=d; } - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} -inline gddStatus gdd::put(aitUint8 d) { - gddStatus rc=0; - if(isScalar()) { setPrimType(aitEnumUint8); data.Uint8=d; } - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} -inline gddStatus gdd::put(aitInt8 d) { - gddStatus rc=0; - if(isScalar()) { setPrimType(aitEnumInt8); data.Int8=d; } - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} -inline gddStatus gdd::put(aitType* d) { - gddStatus rc=0; - if(isScalar()) { data=*d; } - else { rc=gddErrorNotAllowed; gddAutoPrint("gdd:put()",rc); } - return rc; -} - -// ------------------get(scalar) functions----------------- -inline void gdd::get(aitFloat64& d) const { - if(primitiveType()==aitEnumFloat64) d=getData().Float64; - else get(aitEnumFloat64,&d); -} -inline void gdd::get(aitFloat32& d) const { - if(primitiveType()==aitEnumFloat32) d=getData().Float32; - else get(aitEnumFloat32,&d); -} -inline void gdd::get(aitUint32& d) const { - if(primitiveType()==aitEnumUint32) d=getData().Uint32; - else get(aitEnumUint32,&d); -} -inline void gdd::get(aitInt32& d) const { - if(primitiveType()==aitEnumInt32) d=getData().Int32; - else get(aitEnumInt32,&d); -} -inline void gdd::get(aitUint16& d) const { - if(primitiveType()==aitEnumUint16) d=getData().Uint16; - else get(aitEnumUint16,&d); -} -inline void gdd::get(aitInt16& d) const { - if(primitiveType()==aitEnumInt16) d=getData().Int16; - else get(aitEnumInt16,&d); -} -inline void gdd::get(aitUint8& d) const { - if(primitiveType()==aitEnumUint8) d=getData().Uint8; - else get(aitEnumUint8,&d); -} -inline void gdd::get(aitInt8& d) const { - if(primitiveType()==aitEnumInt8) d=getData().Int8; - else get(aitEnumInt8,&d); -} -inline void gdd::get(aitType& d) const { d=data; } - -// ---------- gdd x = primitive data type pointer functions---------- -inline gdd& gdd::operator=(aitFloat64* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitFloat32* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitUint32* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitInt32* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitUint16* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitInt16* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitUint8* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitInt8* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitString* v) { putRef(v); return *this;} -inline gdd& gdd::operator=(aitFixedString* v){ putRef(v); return *this;} - -// ----------------- gdd x = primitive data type functions---------------- -inline gdd& gdd::operator=(aitFloat64 d) - { setPrimType(aitEnumFloat64); data.Float64=d; return *this; } -inline gdd& gdd::operator=(aitFloat32 d) - { setPrimType(aitEnumFloat32); data.Float32=d;return *this; } -inline gdd& gdd::operator=(aitUint32 d) - { setPrimType(aitEnumUint32); data.Uint32=d; return *this; } -inline gdd& gdd::operator=(aitInt32 d) - { setPrimType(aitEnumInt32); data.Int32=d; return *this; } -inline gdd& gdd::operator=(aitUint16 d) - { setPrimType(aitEnumUint16); data.Uint16=d; return *this; } -inline gdd& gdd::operator=(aitInt16 d) - { setPrimType(aitEnumInt16); data.Int16=d; return *this; } -inline gdd& gdd::operator=(aitUint8 d) - { setPrimType(aitEnumUint8); data.Uint8=d; return *this; } -inline gdd& gdd::operator=(aitInt8 d) - { setPrimType(aitEnumInt8); data.Int8=d; return *this; } -inline gdd& gdd::operator=(const aitString& d) - { put(d); return *this; } - -// ------------- primitive type pointer = gdd x functions -------------- - -inline gdd::operator aitFloat64*(void) - { return (aitFloat64*)dataPointer(); } -inline gdd::operator aitFloat32*(void) - { return (aitFloat32*)dataPointer(); } -inline gdd::operator aitUint32*(void) - { return (aitUint32*)dataPointer(); } -inline gdd::operator aitInt32*(void) - { return (aitInt32*)dataPointer(); } -inline gdd::operator aitUint16*(void) - { return (aitUint16*)dataPointer(); } -inline gdd::operator aitInt16*(void) - { return (aitInt16*)dataPointer(); } -inline gdd::operator aitUint8*(void) - { return (aitUint8*)dataPointer(); } -inline gdd::operator aitInt8*(void) - { return (aitInt8*)dataPointer(); } -inline gdd::operator aitString*(void) - { return (aitString*)dataPointer(); } -inline gdd::operator aitFixedString*(void) - { return (aitFixedString*)dataPointer(); } - -inline gdd::operator const aitFloat64*(void) const - { return (aitFloat64*)dataPointer(); } -inline gdd::operator const aitFloat32*(void) const - { return (aitFloat32*)dataPointer(); } -inline gdd::operator const aitUint32*(void) const - { return (aitUint32*)dataPointer(); } -inline gdd::operator const aitInt32*(void) const - { return (aitInt32*)dataPointer(); } -inline gdd::operator const aitUint16*(void) const - { return (aitUint16*)dataPointer(); } -inline gdd::operator const aitInt16*(void) const - { return (aitInt16*)dataPointer(); } -inline gdd::operator const aitUint8*(void) const - { return (aitUint8*)dataPointer(); } -inline gdd::operator const aitInt8*(void) const - { return (aitInt8*)dataPointer(); } -inline gdd::operator const aitString*(void) const - { return (aitString*)dataPointer(); } -inline gdd::operator const aitFixedString*(void) const - { return (aitFixedString*)dataPointer(); } - -// ------------- primitive type = gdd x functions -------------- -inline gdd::operator aitFloat64(void) const { aitFloat64 d; get(d); return d; } -inline gdd::operator aitFloat32(void) const { aitFloat32 d; get(d); return d; } -inline gdd::operator aitUint32(void) const { aitUint32 d; get(d); return d; } -inline gdd::operator aitInt32(void) const { aitInt32 d; get(d); return d; } -inline gdd::operator aitUint16(void) const { aitUint16 d; get(d); return d; } -inline gdd::operator aitInt16(void) const { aitInt16 d; get(d); return d; } -inline gdd::operator aitUint8(void) const { aitUint8 d; get(d); return d; } -inline gdd::operator aitInt8(void) const { aitInt8 d; get(d); return d; } -inline gdd::operator aitString(void) const { aitString d; get(d); return d; } - -inline gdd & gdd::operator [] (int index) -{ - assert (index>=0); - return (gdd &) *this->indexDD(index); -} - -inline const gdd & gdd::operator [] (int index) const -{ - assert (index>=0); - return *this->indexDD(index); -} - -inline const gdd* gdd::getDD(aitIndex index) const - { return indexDD(index); } - -inline gdd* gdd::getDD(aitIndex index) - { return (gdd *) indexDD(index); } - -inline gdd* gdd::getDD(aitIndex index,gddScalar*& dd) - { return (gdd*)(dd=(gddScalar*)indexDD(index)); } - -inline gdd* gdd::getDD(aitIndex index,gddArray*& dd) - { return (gdd*)(dd=(gddAtomic*)indexDD(index)); } - -inline gdd* gdd::getDD(aitIndex index,gddContainer*& dd) - { return (gdd*)(dd=(gddContainer*)indexDD(index)); } - -inline const gdd* gdd::getDD(aitIndex index, const gddScalar*& dd) const - { return (const gdd*)(dd=(const gddScalar*)indexDD(index)); } - -inline const gdd* gdd::getDD(aitIndex index, const gddArray*& dd) const - { return (const gdd*)(dd=(const gddAtomic*)indexDD(index)); } - -inline const gdd* gdd::getDD(aitIndex index, const gddContainer*& dd) const - { return (const gdd*)(dd=(const gddContainer*)indexDD(index)); } - -inline gdd & gdd::operator [] (aitIndex index) -{ - return *this->getDD(index); -} - -inline const gdd & gdd::operator [] (aitIndex index) const -{ - return *this->getDD(index); -} - -#endif diff --git a/src/ca/legacy/gdd/gddNewDel.cc b/src/ca/legacy/gdd/gddNewDel.cc deleted file mode 100644 index 4e6f3c05f..000000000 --- a/src/ca/legacy/gdd/gddNewDel.cc +++ /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 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 -// Date: 2/96 - -#define epicsExportSharedSymbols -#include "gddNewDel.h" -#include - -class gddCleanUpNode -{ -public: - void* buffer; - gddCleanUpNode* next; -}; - -class gddCleanUp -{ -public: - gddCleanUp(); - ~gddCleanUp(); - void Add(void*); -private: - gddCleanUpNode * bufs; - epicsMutex lock; -}; - -static gddCleanUp * pBufferCleanUpGDD = NULL; - -static epicsThreadOnceId gddCleanupOnce = EPICS_THREAD_ONCE_INIT; - -extern "C" { -static void gddCleanupInit ( void * ) -{ - pBufferCleanUpGDD = new gddCleanUp; - assert ( pBufferCleanUpGDD ); -} -} - -void gddGlobalCleanupAdd ( void * pBuf ) -{ - epicsThreadOnce ( & gddCleanupOnce, gddCleanupInit, 0 ); - pBufferCleanUpGDD->Add ( pBuf ); -} - -gddCleanUp::gddCleanUp() : bufs ( NULL ) {} - -gddCleanUp::~gddCleanUp() -{ - gddCleanUpNode *p1,*p2; - - for(p1=gddCleanUp::bufs;p1;) - { - p2=p1; - p1=p1->next; - free((char*)p2->buffer); - delete p2; - } -} - -void gddCleanUp::Add(void* v) -{ - gddCleanUpNode* p = new gddCleanUpNode; - p->buffer=v; - { - epicsGuard < epicsMutex > guard ( lock ); - p->next=gddCleanUp::bufs; - gddCleanUp::bufs=p; - } -} - diff --git a/src/ca/legacy/gdd/gddNewDel.h b/src/ca/legacy/gdd/gddNewDel.h deleted file mode 100644 index 2bd88598e..000000000 --- a/src/ca/legacy/gdd/gddNewDel.h +++ /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. -\*************************************************************************/ -#ifndef GDD_NEWDEL_H -#define GDD_NEWDEL_H - -/* - * Author: Jim Kowalkowski - * Date: 2/96 - */ - -// this file if formatted with tab stop = 4 - -#include -#include "epicsMutex.h" -#include "epicsGuard.h" -#include "epicsThread.h" - -// Avoid using templates at the cost of very poor readability. -// This forces the user to have a static data member named "gddNewDel_freelist" - -// To use this stuff: -// -// ** In class description header file: -// class myClass -// { -// public: -// gdd_NEWDEL_FUNC(address_to_be_used_for_freelist_next_pointer) -// private: -// gdd_NEWDEL_DATA(myClass) -// }; -// -// ** In source file where functions for class are written: -// gdd_NEWDEL_STAT(myClass) -// gdd_NEWDEL_DEL(myClass) -// gdd_NEWDEL_NEW(myClass) - -#define gdd_CHUNK_NUM 20 -#define gdd_CHUNK(mine) (gdd_CHUNK_NUM*sizeof(mine)) - -void gddGlobalCleanupAdd ( void * pBuf ); - -// private data to add to a class -#define gdd_NEWDEL_DATA \ - static char* newdel_freelist; \ - static epicsMutex *pNewdel_lock; \ - static epicsThreadOnceId once; - -// public interface for the new/delete stuff -// user gives this macro the address they want to use for the next pointer -#define gdd_NEWDEL_FUNC(fld) \ - void* operator new(size_t); \ - void operator delete(void*); \ - char* newdel_next(void) { char* pfld = (char *)&fld; \ - char** x = (char**)pfld; return *x; } \ - void newdel_setNext(char* n) { char* pfld = (char *)&fld; \ - char** x=(char**)pfld; *x=n; } \ - static void gddNewDelInit (void) { pNewdel_lock = newEpicsMutex; } - - -// declaration of the static variable for the free list -#define gdd_NEWDEL_STAT(clas) \ - char* clas::newdel_freelist=NULL; \ - epicsMutex * clas::pNewdel_lock = NULL; \ - epicsThreadOnceId clas::once = EPICS_THREAD_ONCE_INIT; - -// code for the delete function -#define gdd_NEWDEL_DEL(clas) \ - void clas::operator delete(void* v) { \ - clas* dn = (clas*)v; \ - if(dn->newdel_next()==(char*)(-1)) free((char*)v); \ - else { \ - epicsGuard < epicsMutex > guard ( *clas::pNewdel_lock ); \ - dn->newdel_setNext(clas::newdel_freelist); \ - clas::newdel_freelist=(char*)dn; \ - } \ - } - -// following function assumes that reading/writing address is atomic - -// code for the new function -#define gdd_NEWDEL_NEW(clas) \ - extern "C" { void clas##_gddNewDelInit ( void * ) { \ - clas::gddNewDelInit(); } } \ - void* clas::operator new(size_t size) { \ - int tot; \ - clas *nn,*dn; \ - epicsThreadOnce ( &once, clas##_gddNewDelInit, 0 ); \ - epicsGuard < epicsMutex > guard ( *clas::pNewdel_lock ); \ - if(!clas::newdel_freelist) { \ - tot=gdd_CHUNK_NUM; \ - nn=(clas*)malloc(gdd_CHUNK(clas)); \ - gddGlobalCleanupAdd (nn); \ - for(dn=nn;--tot;dn++) dn->newdel_setNext((char*)(dn+1)); \ - (dn)->newdel_setNext(clas::newdel_freelist); \ - clas::newdel_freelist=(char*)nn; \ - } \ - if(size==sizeof(clas)) { \ - { \ - dn=(clas*)clas::newdel_freelist; \ - clas::newdel_freelist=((clas*)clas::newdel_freelist)->newdel_next(); \ - } \ - dn->newdel_setNext(NULL); \ - } else { \ - dn=(clas*)malloc(size); \ - dn->newdel_setNext((char*)(-1)); \ - } \ - return (void*)dn; \ - } - -#endif - diff --git a/src/ca/legacy/gdd/gddScalar.h b/src/ca/legacy/gdd/gddScalar.h deleted file mode 100644 index e735a04cc..000000000 --- a/src/ca/legacy/gdd/gddScalar.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 GDD_SCALAR_H -#define GDD_SCALAR_H - -/* - * Author: Jim Kowalkowski - * Date: 3/97 - * - */ - -#include "shareLib.h" - -// ------------------------------------------------------------------------ -// Add handling of the special case where the data is a scaler - the -// dimension is zero - -class epicsShareClass gddScalar : public gdd -{ -public: - gddScalar(void); - gddScalar(gddScalar* ad); - gddScalar(int app); - gddScalar(int app,aitEnum prim); - - void dump(void) const; - void test(void); - - gddScalar& operator=(aitFloat64 d); - gddScalar& operator=(aitFloat32 d); - gddScalar& operator=(aitUint32 d); - gddScalar& operator=(aitInt32 d); - gddScalar& operator=(aitUint16 d); - gddScalar& operator=(aitInt16 d); - gddScalar& operator=(aitUint8 d); - gddScalar& operator=(aitInt8 d); - -protected: - gddScalar(int app, aitEnum prim, int dimen, aitUint32* size_array); - ~gddScalar(void); - -private: -}; - -#endif diff --git a/src/ca/legacy/gdd/gddScalarI.h b/src/ca/legacy/gdd/gddScalarI.h deleted file mode 100644 index 0f4d724b3..000000000 --- a/src/ca/legacy/gdd/gddScalarI.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 GDD_SCALARI_H -#define GDD_SCALARI_H - -inline gddScalar::gddScalar(void) { } -inline gddScalar::gddScalar(gddScalar* ad) : gdd(ad) { } -inline gddScalar::gddScalar(int app) : gdd(app) { } -inline gddScalar::gddScalar(int app,aitEnum prim) : gdd(app,prim) { } - -inline gddScalar& gddScalar::operator=(aitFloat64 d) { *((gdd*)this)=d; return *this; } -inline gddScalar& gddScalar::operator=(aitFloat32 d) { *((gdd*)this)=d; return *this; } -inline gddScalar& gddScalar::operator=(aitUint32 d) { *((gdd*)this)=d; return *this; } -inline gddScalar& gddScalar::operator=(aitInt32 d) { *((gdd*)this)=d; return *this; } -inline gddScalar& gddScalar::operator=(aitUint16 d) { *((gdd*)this)=d; return *this; } -inline gddScalar& gddScalar::operator=(aitInt16 d) { *((gdd*)this)=d; return *this; } -inline gddScalar& gddScalar::operator=(aitUint8 d) { *((gdd*)this)=d; return *this; } -inline gddScalar& gddScalar::operator=(aitInt8 d) { *((gdd*)this)=d; return *this; } - -inline gddScalar::gddScalar(int app, aitEnum prim, int dimen, aitUint32* size_array): - gdd(app,prim,dimen,size_array) { } - -inline gddScalar::~gddScalar(void) { } - -#endif diff --git a/src/ca/legacy/gdd/gddTest.cc b/src/ca/legacy/gdd/gddTest.cc deleted file mode 100644 index 881a55df9..000000000 --- a/src/ca/legacy/gdd/gddTest.cc +++ /dev/null @@ -1,538 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 -// Date: 2/96 - -#include -#define epicsExportSharedSymbols -#include "gdd.h" - -// -----------------------test routines------------------------ - -void gdd::dump(void) const -{ - gddScalar* sdd; - gddAtomic* add; - gddContainer* cdd; - - if(isScalar()) - { - sdd=(gddScalar*)this; - sdd->dump(); - return; - } - if(isAtomic()) - { - add=(gddAtomic*)this; - add->dump(); - return; - } - if(isContainer()) - { - cdd=(gddContainer*)this; - cdd->dump(); - return; - } -} - -void gdd::dumpInfo(void) const -{ - unsigned i; - aitIndex f,c; - unsigned long sz_tot,sz_data,sz_elem; - const aitIndex max=20u; - aitIndex prt_tot; - - sz_tot = getTotalSizeBytes(); - sz_data = getDataSizeBytes(); - sz_elem = getDataSizeElements(); - - prt_tot=sz_elem>max?max:sz_elem; - - fprintf(stderr,"----------dump This=%p---------\n", this); - fprintf(stderr," dimension=%u ", dimension()); - fprintf(stderr,"app-type=%u ", applicationType()); - - if(isScalar()) fprintf(stderr,"Scalar\n"); - if(isAtomic()) fprintf(stderr,"Atomic\n"); - if(isContainer()) fprintf(stderr,"Container\n"); - - fprintf(stderr," prim-type=%s",aitName[primitiveType()]); - switch(primitiveType()) - { - case aitEnumInvalid: - fprintf(stderr,"(aitEnumInvalid)"); - break; - case aitEnumInt8: - fprintf(stderr,"(aitEnumInt8)"); - if(isScalar()) fprintf(stderr," value=0x%2.2x ",data.Int8); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitInt8* i8=(aitInt8*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumInt16: - fprintf(stderr,"(aitEnumInt16)"); - if(isScalar()) fprintf(stderr," value=%hd ",data.Int16); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitInt16* i16=(aitInt16*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumInt32: - fprintf(stderr,"(aitEnumInt32)"); - if(isScalar()) fprintf(stderr," value=%d ",data.Int32); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitInt32* i32=(aitInt32*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumUint8: - fprintf(stderr,"(aitEnumUint8)"); - if(isScalar()) fprintf(stderr," value=0x%2.2x ",data.Uint8); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitUint8* ui8=(aitUint8*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumUint16: - fprintf(stderr,"(aitEnumUint16)"); - if(isScalar()) fprintf(stderr," value=%hu ",data.Uint16); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitUint16* ui16=(aitUint16*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumEnum16: - fprintf(stderr,"(aitEnumEnum16)"); - if(isScalar()) fprintf(stderr," value=%hu ",data.Enum16); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitEnum16* e16=(aitEnum16*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumUint32: - fprintf(stderr,"(aitEnumUint32)"); - if(isScalar()) fprintf(stderr," value=%u ",data.Uint32); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitUint32* ui32=(aitUint32*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumFloat32: - fprintf(stderr,"(aitEnumFloat32)"); - if(isScalar()) fprintf(stderr," value=%f ",data.Float32); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitFloat32* f32=(aitFloat32*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumFloat64: - fprintf(stderr,"(aitEnumFloat64)"); - if(isScalar()) fprintf(stderr," value=%f ",data.Float64); - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitFloat64* f64=(aitFloat64*)dataPointer(); - for(i=0;i\n"); - } - break; - case aitEnumFixedString: - fprintf(stderr,"(aitEnumFixedString)"); - if(isScalar()) - { - if(data.FString) - fprintf(stderr," value=<%s>\n",(char *)data.FString); - else - fprintf(stderr," value=\n"); - } - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitFixedString* fs=(aitFixedString*)dataPointer(); - for(i=0;i ",fs[i].fixed_string); - fprintf(stderr,">\n"); - } - break; - case aitEnumString: - fprintf(stderr,"(aitEnumString)"); - if(isScalar()) - { - aitString* str = (aitString*)dataAddress(); - fprintf(stderr,"\n"); - str->dump(); - } - if(isAtomic()&&dataPointer()) - { - fprintf(stderr,"\n %d values=<\n",(int)prt_tot); - aitString* ss=(aitString*)dataPointer(); - for(i=0;i ",ss[i].string()); - fprintf(stderr,">\n"); - } - break; - case aitEnumContainer: - fprintf(stderr,"(aitEnumContainer)"); - break; - default: break; - } - - fprintf(stderr," ref-count=%d\n",ref_cnt); - fprintf(stderr," total-bytes=%ld,",sz_tot); - fprintf(stderr," data-size=%ld,",sz_data); - fprintf(stderr," element-count=%ld\n",sz_elem); - - if(!isScalar()) - { - if(destruct) - fprintf(stderr," destructor=%p\n", destruct); - else - fprintf(stderr," destructor=NULL\n"); - } - - for(i=0;igetCursor(); - for(dd=cur.first();dd;dd=cur.next()) - { - if(dd->isAtomic()) { add=(gddAtomic*)dd; add->dump(); } - if(dd->isScalar()) { sdd=(gddScalar*)dd; sdd->dump(); } - if(dd->isContainer()) { cdd=(gddContainer*)dd; cdd->dump(); } - } -} - -#ifdef NO_DUMP_TEST -void gdd::test() { } -#else -void gdd::test() -{ - aitInt32 i32[3] = { -32,4,3 }; - aitIndex bnds = 3; - gddAtomic* add = (gddAtomic*)this; - gddAtomic* dd = new gddAtomic(98,aitEnumInt32,1,3); - - reset(aitEnumInt32,1,&bnds); - add->put(i32); - fprintf(stderr,"----TESTING DD DUMP:\n"); - add->dump(); - - // test copy(), copyInfo(), Dup() - fprintf(stderr,"----TESTING COPYINFO(): (1)COPYINFO, (2)ORIGINAL\n"); - dd->copyInfo(this); dd->dump(); add->dump(); - fprintf(stderr,"----TESTING DUP(): (1)DUP, (2)ORIGINAL\n"); - dd->clear(); dd->Dup(this); dd->dump(); add->dump(); - fprintf(stderr,"----TESTING COPY(): (1)COPY, (2)ORIGINAL\n"); - dd->clear(); dd->copy(this); dd->dump(); add->dump(); - dd->unreference(); - - // test flatten functions and Convert functions - size_t sz = getTotalSizeBytes(); - aitUint8* buf = new aitUint8[sz]; - gddAtomic* pdd = (gddAtomic*)buf; - flattenWithAddress(buf,sz); - fprintf(stderr,"----TESTING FLATTENWITHADDRESS():\n"); - pdd->dump(); - fprintf(stderr,"----CONVERTADDRESSTOOFFSETS() THEN BACK AND DUMP:\n"); - pdd->convertAddressToOffsets(); - pdd->convertOffsetsToAddress(); - pdd->dump(); - pdd->unreference(); - delete [] buf; -} -#endif - -#ifndef NO_DUMP_TEST -class gddAtomicDestr : public gddDestructor -{ -public: - gddAtomicDestr(void) { } - void run(void*); -}; - -void gddAtomicDestr::run(void* v) -{ - fprintf(stderr,"**** gddAtomicDestr::run from gddAtomic::test %p\n",v); -} -#endif - -#ifdef NO_DUMP_TEST -void gddAtomic::test(void) { } -#else -void gddAtomic::test(void) -{ - aitFloat32 f32[6] = { 32.0f,2.0f,1.0f, 7.0f,8.0f,9.0f }; - aitFloat64 f64[6] = { 64.0,5.0,4.0, 10.0,11.0,12.0 }; - aitInt8 i8[6] = { -8,2,1, 13,14,15 }; - aitInt16 i16[6] = { -16,3,2, 16,17,18 }; - aitInt32 i32[6] = { -32,4,3, 19,20,21 }; - aitUint8 ui8[6] = { 8,5,4, 22,23,24 }; - aitUint16 ui16[6] = { 16,6,5, 25,26,27 }; - aitUint32 ui32[6] = { 32,7,6, 28,29,30 }; - aitIndex bnds[2] = { 2,3 }; - - // Rules: - // reset() clear out everything and set data pointer to NULL - // put() will auto allocate if data pointer is NULL, otherwise copy - // putRef() will clear current data pointer and set new one - - // if the data pointer is NULL when put() is called, then a - // generic gddDestructor will be created to delete the buffer - - reset(aitEnumFloat32,2,bnds); - put(f32); dump(); - putRef(f32,new gddAtomicDestr); dump(); - - reset(aitEnumFloat64,2,bnds); - put(f64); dump(); - putRef(f64,new gddAtomicDestr); dump(); - - reset(aitEnumInt8,2,bnds); - put(i8); dump(); - putRef(i8,new gddAtomicDestr); dump(); - - reset(aitEnumUint8,2,bnds); - put(ui8); dump(); - putRef(ui8,new gddAtomicDestr); dump(); - - reset(aitEnumInt16,2,bnds); - put(i16); dump(); - putRef(i16,new gddAtomicDestr); dump(); - - reset(aitEnumUint16,2,bnds); - put(ui16); dump(); - putRef(ui16,new gddAtomicDestr); dump(); - - reset(aitEnumInt32,2,bnds); - put(i32); dump(); - putRef(i32,new gddAtomicDestr); dump(); - - reset(aitEnumUint32,2,bnds); - put(ui32); dump(); - putRef(ui32,new gddAtomicDestr); dump(); -} -#endif - -#ifdef NO_DUMP_TEST -void gddScalar::test(void) { } -#else -void gddScalar::test(void) -{ - int i; - aitFloat32 fa32,f32 = 32.0f; - aitFloat64 fa64,f64 = 64.0; - aitInt8 ia8,i8 = -8; - aitInt16 ia16,i16 = -16; - aitInt32 ia32,i32 = -32; - aitUint8 uia8,ui8 = 8; - aitUint16 uia16,ui16 = 16; - aitUint32 uia32,ui32 = 32; - - // printf("get float32 = %f\n",fa32); - // printf("op= float32 = %f\n",fa32); - - fprintf(stderr,"float32===="); - for(i=0;ireference(); add1->reference(); sdd2->reference(); - insert(sdd1); insert(sdd2); insert(add1); dump(); - - fprintf(stderr,"=====TESTING CURSOR:\n"); - gddCursor cur = getCursor(); - gdd* dd; - int i; - for(i=0; (dd=cur[i]); i++) fprintf(stderr,"%p ",dd); - fprintf(stderr,"\n"); - for(dd=cur.first();dd;dd=cur.next()) fprintf(stderr,"%p ",dd); - fprintf(stderr,"\n"); - - remove(0); remove(0); remove(0); dump(); - sdd1->reference(); add1->reference(); sdd2->reference(); - insert(add1); insert(sdd1); insert(sdd2); dump(); - - sz = getTotalSizeBytes(); - buf = new aitUint8[sz]; - - fprintf(stderr,"=====TESTING FLATTEN FUNCTION BUFFER=%p:\n",buf); - flattenWithAddress(buf,sz); - cdd1=(gddContainer*)buf; - cdd1->dump(); - fprintf(stderr,"=====CHANGE ADDRESSES TO OFFSETS:\n"); - cdd1->convertAddressToOffsets(); - fprintf(stderr,"=====CHANGE OFFSETS TO ADDRESSES:\n"); - cdd1->convertOffsetsToAddress(); - fprintf(stderr,"=====RE-DUMP OF FLATTENED CONTAINER:\n"); - cdd1->dump(); - fprintf(stderr,"=====RE-DUMP OF ORIGINAL CONTAINER:\n"); - dump(); - cdd1->unreference(); - delete [] buf; - - // test copy(), Dup(), copyInfo() - fprintf(stderr,"=======CREATING TEST CONTAINER FOR *COPY* TEST:\n"); - cdd1 = new gddContainer; - fprintf(stderr,"=======COPYINFO():\n"); - cdd1->copyInfo(this); cdd1->dump(); - fprintf(stderr,"=======DUP():\n"); - cdd1->Dup(this); cdd1->dump(); - fprintf(stderr,"=======COPY():\n"); - cdd1->copy(this); cdd1->dump(); - fprintf(stderr,"=======UNREFERENCE THE TEST CONTAINER:\n"); - cdd1->unreference(); - - fprintf(stderr,"=====DUMPING ORIGINAL:\n"); - dump(); - clear(); - - fprintf(stderr,"=======TEST COMPLETE, DELETE STUFF:\n"); - fprintf(stderr," first scaler:\n "); sdd1->unreference(); - fprintf(stderr," first atomic:\n "); add1->unreference(); - fprintf(stderr," second scaler:\n "); sdd2->unreference(); - dump(); -} -#endif - diff --git a/src/ca/legacy/gdd/gddUtils.cc b/src/ca/legacy/gdd/gddUtils.cc deleted file mode 100644 index b0f5a5a0e..000000000 --- a/src/ca/legacy/gdd/gddUtils.cc +++ /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: Jim Kowalkowski -// Date: 3/97 - -#include -#include -#include - -#define epicsExportSharedSymbols -#include "gddNewDel.h" -#include "gddUtils.h" - -gdd_NEWDEL_NEW(gddBounds1D) -gdd_NEWDEL_DEL(gddBounds1D) -gdd_NEWDEL_STAT(gddBounds1D) - -gdd_NEWDEL_NEW(gddBounds2D) -gdd_NEWDEL_DEL(gddBounds2D) -gdd_NEWDEL_STAT(gddBounds2D) - -gdd_NEWDEL_NEW(gddBounds3D) -gdd_NEWDEL_DEL(gddBounds3D) -gdd_NEWDEL_STAT(gddBounds3D) - -gdd_NEWDEL_NEW(gddDestructor) -gdd_NEWDEL_DEL(gddDestructor) -gdd_NEWDEL_STAT(gddDestructor) - -// --------------------------The gddBounds functions------------------- - -// gddBounds::gddBounds(void) { first=0; count=0; } - -// --------------------------The gddDestructor functions------------------- - -gddStatus gddDestructor::destroy(void* thing) -{ - if(ref_cnt==0 || --ref_cnt==0) - { - run(thing); - delete this; - } - return 0; -} - -void gddDestructor::run(void* thing) -{ - aitInt8* pd = (aitInt8*)thing; - delete [] pd; -} - diff --git a/src/ca/legacy/gdd/gddUtils.h b/src/ca/legacy/gdd/gddUtils.h deleted file mode 100644 index ef45bf74c..000000000 --- a/src/ca/legacy/gdd/gddUtils.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 GDD_UTILS_H -#define GDD_UTILS_H - -/* - * Author: Jim Kowalkowski - * Date: 2/96 - */ - -#ifdef vxWorks -#include -#include -#include -#include -#endif - -#include "aitTypes.h" -#include "gddErrorCodes.h" -#include "gddNewDel.h" -#include "shareLib.h" - -// --------------------------------------------------------------------- -// Describe the bounds of a single dimension in terms of the first -// element and the number of elements in the dimension. - -class epicsShareClass gddBounds -{ -public: - // I found a weird memory management quirk with SunOS when constructors - // are present in a class that is used as an array in another class - // as it is in gddBounds2D. The memory manager reallocates the entire - // gddBounds2D in some sort of buffer pool which stays allocated when the - // program completes - - // gddBounds(void); - // gddBounds(aitIndex c); - // gddBounds(aitIndex f, aitIndex c); - - void setSize(aitIndex c); - void setFirst(aitIndex c); - void set(aitIndex f, aitIndex c); - void get(aitIndex& f, aitIndex& c); - aitIndex size(void) const; - aitIndex first(void) const; - -private: - aitIndex start; - aitIndex count; -}; - - -// --------------------------------------------------------------------- -// This is a class for managing the destruction of user data held within -// a DD. It allows multiple DDs to reference the same chunk of user -// data. The data would remain alive until the reference count goes to -// zero, at this time the user destructor function will be called with -// a pointer to the piece of data to deal with. The intention here is -// that user will create a subclass of this and supply the virtual -// function run(void*). The default behavior will be to treat the void* -// data as an array of aitInt8 and call remove. - -// **** WARNING! -// The reference count is initialized to zero. This means that if you -// create one and want to keep it, you must reference it twice - the -// initial time and a time for your personal use. This is because the -// gdd library automatically increments the reference count on -// destructors when data is referenced into a gdd with a destructor. -// Remember the rule: if you pass a destructor to someone, then that -// someone now owns the destructor. A reference count of 1 indicates that -// the thing will go away when unreferenced - which is what you will -// have if you only reference the destructor once after it is created. - -class epicsShareClass gddDestructor -{ -public: - gddDestructor(void); - gddDestructor(void* user_arg); - - void reference(void); - int refCount(void) const; - - gddStatus destroy(void* thing_to_remove); - virtual void run(void* thing_to_remove); - - gdd_NEWDEL_FUNC(arg) // for using generic new and remove -protected: - aitUint16 ref_cnt; - void* arg; - virtual ~gddDestructor () {} -private: - gdd_NEWDEL_DATA -}; - -#include "gddUtilsI.h" - -// --------------------------------------------------------------------- -// Special managment for 1D-2D-3D bounds - others use normal new/remove. -// Since bounds are maintained as arrays, where the length of the array is -// the dimension of the data, we will manage the normal cases using -// free lists. - -class epicsShareClass gddBounds1D -{ -public: - gddBounds1D(void) { } - gddBounds* boundArray(void); - gdd_NEWDEL_FUNC(b[0]) // required for using generic new and remove -private: - gddBounds b[1]; - gdd_NEWDEL_DATA // required for using generic new/remove -}; -inline gddBounds* gddBounds1D::boundArray(void) { return b; } - -class epicsShareClass gddBounds2D -{ -public: - gddBounds2D(void) { } - gddBounds* boundArray(void); - gdd_NEWDEL_FUNC(b[0]) // required for using generic new and remove -private: - gddBounds b[2]; - gdd_NEWDEL_DATA // required for using generic new/remove -}; -inline gddBounds* gddBounds2D::boundArray(void) { return b; } - -class epicsShareClass gddBounds3D -{ -public: - gddBounds3D(void) { } - gddBounds* boundArray(void); - gdd_NEWDEL_FUNC(b[0]) // for using generic new and remove -private: - gddBounds b[3]; - gdd_NEWDEL_DATA // required for using generic new/remove -}; -inline gddBounds* gddBounds3D::boundArray(void) { return b; } - -#endif - diff --git a/src/ca/legacy/gdd/gddUtilsI.h b/src/ca/legacy/gdd/gddUtilsI.h deleted file mode 100644 index c2eaf90ac..000000000 --- a/src/ca/legacy/gdd/gddUtilsI.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 GDD_UTILSI_H -#define GDD_UTILSI_H - -/* - * Author: Jim Kowalkowski - * Date: 3/97 - */ - -// inline gddBounds::gddBounds(aitIndex c) { start=0; count=c; } -// inline gddBounds::gddBounds(aitIndex f, aitIndex c) { start=f; count=c; } - -inline void gddBounds::setSize(aitIndex c) { count=c; } -inline void gddBounds::setFirst(aitIndex f) { start=f; } -inline void gddBounds::set(aitIndex f, aitIndex c) { start=f; count=c; } -inline void gddBounds::get(aitIndex& f, aitIndex& c){ f=start; c=count; } -inline aitIndex gddBounds::size(void) const { return count; } -inline aitIndex gddBounds::first(void) const { return start; } - -inline gddDestructor::gddDestructor(void) { ref_cnt=0; arg=NULL; } -inline gddDestructor::gddDestructor(void* usr_arg) { ref_cnt=0; arg=usr_arg; } -inline void gddDestructor::reference(void) { ref_cnt++; } -inline int gddDestructor::refCount(void) const { return ref_cnt; } - -#endif diff --git a/src/ca/legacy/gdd/gddref.html b/src/ca/legacy/gdd/gddref.html deleted file mode 100644 index 80aac6778..000000000 --- a/src/ca/legacy/gdd/gddref.html +++ /dev/null @@ -1,511 +0,0 @@ - - -GDD Reference Manual - - -

GDD Reference Manual

- -gdd
-gddAtomic
-gddScalar
-gddContainer
-gddApplicationTypeTable
-

-gddDestructor
-gddBounds
-gddBounds1D gddBounds2D gddBounds3D
-gddCursor
-gddSemaphore
-gddIntLock
-

-aitConvert
-aitTimeStamp
-aitString
-aitTypes/aitEnums
-

-new/delete Free List Management
-Application Type Code Index Labels
-gddStatus - Error Codes
-

-DBR To ait Conversion Functions
-gddMakeMapDBR
-gddMapDbr
-gddAitToDbr
-gddDbrToAit
-

-User's Guide
- -


gdd

-Main GDD library base class. A fundemental class for describing a scalar -value, an array or an array of GDDs know as a container. See the User's -Guide for a detailed explanation. - -

#include "gdd.h"

- -gdd(void)
-gdd(gdd*)
- -Construct a new gdd that is empty or that is a copy of another gdd instance. - -

-gdd(int ApplicationType);
-gdd(int ApplicationType, aitEnum PrimitiveType);
-gdd(int ApplicationType, aitEnum PrimitiveType, int Dimension);
-gdd(int ApplicationType, aitEnum PrimitiveType, int Dimension, - aitUint32* ElementCounts);
- -Construct a new gdd, describing various data properties. If Dimension -is greater that zero, then ElementCounts is an array with Dimension -number of elements in it. Each element of the array describes how many -elements are in that dimension. The ElementCount information is used to -initialize the bounds of a GDD. - -

-unsigned applicationType(void) const;
-aitEnum primitiveType(void) const;
-unsigned dimension(void) const;
-gddStatus changeType(int AppType, aitEnum PrimType) const;
- -Return the GDDs application type code. Return the type of data stored in the -GDD. Remember that the application type code is arbitrarily set by the user -and it imposes a user-level meaning to the data. The primitive type code -is generally a compiler supported data type with a predetermined size, such -as double, float, short, int, etc.. Return the dimension of the data in -the GDD; zero indicates a scalar. ChangeType() allows for a GDD that is -a scalar or a GDD with an undefined primitive type to be converted to -a new primitive type and application type code. Changes in this case -are safe. - -

changeType() return codes: -
-
0 - Success -
gddErrorTypeMismatch - GDD is not scalar or primitive type valid -
-
- -

-gddDestructor* destructor(void) const;
-gddStatus registerDestructor(gddDestructor*);
-gddStatus replaceDestructor(gddDestructor*);
- -Methods for manipulating the user-defined GDD destructor. Destructor() -just returns a reference to the GDDs destructor. RegisterDestructor() -installs a destructor in the GDD if one is not already present. -ReplaceDestructor() forces a GDDs destructor to be replaced. - -

registerDestructor() return codes: -
-
0 - Success -
gddErrorAlreadyDefined - gddDestructor already registered in GDD -
-
- -

-const gddBounds* getBounds(void) const;
-const gddBounds* getBounds(int dimension) const;
-gddStatus getBound(unsigned dim_to_get, aitIndex& first, aitIndex& count);
-gddStatus setBound(unsigned dim_to_set, aitIndex first, aitIndex count);
- -Retrieve the bounds array from the GDD or get a gddBounds for a -particular dimension with the first two methods listed. Get and set -information contained within the bounds structure of a GDD. Dimension -bounds in the GDD library are always expressed as (first,count), see the -User's guide for details. - -

getBound() and setBound return codes: -
-
0 - Success -
gddErrorOutOfBounds - requested dimension does not exist -
-
- -

-void dump(void);
- -Print out all the information contained in the fields of a GDD in a -useful,readable fashion. Good tool for learning about the information -a GDD holds. - -

-void setPrimType(aitEnum PrimitiveEnumType);
-void setApplType(int ApplicationTypeCode);
- -Force the GDD to change the primitive type of the data it describes. -Changing the primitive type code is generally an unnatural thing to do. -Force a GDD to change the application type, which effectively changes -the high-level meaning of the data held within the GDD. - -

-void setDimension(int);
- -Describe the data a GDD hold in terms of a different dimension. This call -does not alter the data, it does however deallocate bounds and reallocate -them to match the new dimension. This call can really cause probably when -dealing with packed or flattened GDDs. This operation is not advisable -is simple applications, users are better off deleting the GDD and -creating one that suites the data in mosts instances. - -

-void* dataAddress(void) const;
-void* dataPointer(void) const;
-void* dataPointer(aitIndx element_offset) const;
- -All of these methods are designed to give the user general access to -the data within a GDD. These calls are meant to be used internally and -by specialized libraries. The last method listed will give the starting -address of a portion of a simple single dimensional array given an -element offset. - -

-void destroyData(void);
- -If the GDD is describing an array and a destructor is present, then run -the destructor. If the GDD is a container, then run the destructor -giving the argument to the run() function the address of the container -rather then the data that the GDD holds. - -

-gddStatus reset(aitEnum primtype,int dimension, aitIndex* dim_counts);
-gddStatus clear(void);
-gddStatus clearData(void);
- -The clear() method completely clears out a GDD, this includes removing -bounds information, running destructors, and resetting every field in a -GDD to invalid. The clearData() method keeps the GDD information intact, -but runs the data destructors and clears out the data field. Reset() -first runs clear() on the GDD, and then resets the primitive type, dimension, -and bounds information, the appliacation type code remains the same. - -

clear() return codes: -
-
0 - Success -
gddErrorNotAllowed - if GDD is flattened or managed -
-
-
clearData() return codes: -
-
0 - Success -
gddErrorNotAllowed - if GDD is a container -
-
-
reset() return codes: -
-
0 - Success -
gddErrorNotAllowed - if GDD is flattened, managed, or a container -
-
- -

-void getTimeStamp(struct timespec* const ts) const;
-void getTimeStamp(aitTimeStamp* const ts) const;
-void setTimeStamp(const struct timespec* const ts);
-void setTimeStamp(const aitTimeStamp* const ts);
- -Manipulate the time stamp field of the GDD using an aitTimeStamp structure -or a standard struct timespec. - -

-void setStatus(aitUint32);
-void getStatus(aitUint32&);
- -Use the status field of the GDD is a general fashion. The status field -is assigned a value arbitrarily by the user. - -

-void setStat(aitUint16);
-void setSevr(aitUint16);
-aitUint16 getStat(void) const;
-aitUint16 getSevr(void) const;
-void setStatSevr(aitInt16 stat, aitInt16 sevr);
-void getStatSevr(aitInt16& stat, aitInt16& sevr);
- -Manipulate the status field of a GDD as a combination 16-bit status -and 16-bit severity field. - -

size_t getTotalSizeBytes(void) const;
- -Return the total size in bytes of the entire GDD including all the data -it references and bounds array. This is the length of the GDD and all -the items it references. - -

size_t getDataSizeBytes(void) const;
-Return the total size in bytes of the data that the GDD contains or references. - -

aitUint32 getDataSizeElements(void) const;
-Return the number of elements that the GDD describes. - -

gddStatus copyData(const gdd* dd);
-Copy the data from gdd dd to this gdd. This function resets the bounds, the -dimension, the primitive type and the application. In addition, it -allocates a buffer large enough to hold all the data from dd and copies -the data from dd to the new buffer and references it into this gdd. A new -standard gddDestructor is allocated and registered into this GDD that -will be used to delete the newly created data buffer. -

return codes: -
-
0 - Success -
gddErrorNotAllowed - if this GDD is flattened, managed, or a container -
-
- -

gddStatus copyInfo(gdd* dd);
-Copy the data description fields from dd to this gdd. The primitive type, -application type, dimension, and bounds are copied. This gdd is cleared -completely before the information from dd is copied. If dd is a container, -then this gdd becomes a container which looks just like dd without any -data. -

return codes: -
-
0 - Success -
gddErrorNotAllowed - if this GDD is flattened or managed -
-
- -

-gddStatus copy(gdd* dd);
-gddStatus dup(gdd* dd);
-Copy() does everything that copyInfo() does, but also copies the data just as -copyData() would. Dup() does everything that copyInfo() does, but references -the data that dd contains. If dd has a user registered destructor, the this -gdd registers the same destructor instance and bumps up the destructor -reference count. -

return codes: -
-
0 - Success -
gddErrorNotAllowed - if this GDD is flattened or managed -
-
- -

-size_t flattenWithAddress(void* buf, size_t buf_size, - aitIndex* total_dds);
-size_t flattenWithOffsets(void* buf, size_t buf_size, - aitIndex* total_dds);
-These functions pack this gdd instance into buffer buf. Both functions -return the amount of space in bytes used by this gdd. The function will -not go beyond buf_size. The parameter total_dds will be modified to -reflect the total gdds packed into buf. Flattened GDDs can be -directly indexed, the total_dds variable indicates the number of elements -in the gdd array starting at buf. This function can pack scalar GDDs, -atomic GDDs, or container GDDs recursively. The organization of the -buffer is as follows: All GDDs are first, all bounds information follows, -and array data for all the GDDs follow the bounds. The flattenWithAddress() -method is the standard way to produce a useable, packed GDD. The method -flattenWithOffsets() puts offsets in where address normally go in GDD -fields. This function allows GDD to be transfered from one machine or -address space to another when used in conjunction with -convertOffsetsToAddress() and convertAddressToOffsets(). - -

-gddStatus convertAddressToOffsets(void);
-gddStatus convertOffsetsToAddress(void);
-These functions run through this gdd and convert all addressing information -from offsets (from zero) to real addresses or real addresses to offsets. -These function work recursively with container type GDDs. The function -convertAddressToOffsets() can only work with a GDD that is flattened. -

convertAddressToOffsets() return codes: -
-
0 - Success -
gddErrorNotAllowed - if this GDD is not flattened -
-
- -

-int isScalar(void) const;
-int isAtomic(void) const;
-int isContainer(void) const;
-Each return true to indicate the type of GDD that this is. - -

-int isManaged(void) const;
-void markManaged(void);
-void markUnmanaged(void);
-Manipulate the GDD managed state flag. A managed GDD is managed by a -higher level facility such as the application type table. Managed GDDs -have special properties, such as a destructor that knows how to place the -GDD back on a free list buffer pool. All GDDs retrieved from the -application type table that are associated with a prototype will be -managed. Certain copy operations are not allows on managed GDDs. See -the User's Guide for further details. - -

int isFlat(void) const;
-Discover if this GDD has been flattened. - -

-int isLocalDataFormat(void) const;
-int isNetworkDataFormat(void) const;
-void markLocalDataFormat(void);
-Indicate that data stored in the GDD is in a local byte order or floating -point format. Discover if data in the GDD is in local data format. - -

-int isConstant(void) const;
-void markConstant(void);
-Control the constant state flag of this GDD. The data in a constant GDD -cannot be changed. - -

-int isNoRef(void) const;
-gddStatus noReferencing(void);
-gddStatus reference(void);
-gddStatus unreference(void);
-Control and manipulate the reference counts of a GDD. Reference() bumps -up the GDD reference count. Unreference() decrements the reference count of -this GDD, if the reference count drops to zero, then the GDD is deleted. -NoReferencing() locks the GDD reference count and disallows further -referencing of this GDD. -

noReferencing() return codes: -
-
0 - Success -
gddErrorNotAllowed - if this GDD has reference count > 1 already -
-
-
reference() return codes: -
-
0 - Success -
gddErrorNotAllowed - if referencing is not allowed on this GDD -
-
-
unreference() return codes: -
-
0 - Success -
gddErrorUnderflow - if reference count is zero before decrement -
-
- -

gddStatus genCopy(aitEnum dtype, const void* buffer);
-Generalized copy routine that takes data from buffer of type dtype and -puts it into this gdd. If this gdd is a scalar, then one element from -buffer is converted to the primitive type of the GDD and copied in. If -this GDD is an array, then the number of elements copied is determined by -the bounds information stored in this GDD. Is this GDD described an array, -but has no data buffer associated with it, then a new buffer is -allocated which is the size the bounds describes, and the data from -parameter buffer is converted to the GDD primitive type and put into -the newly created GDD buffer. Not a commonly used function. -

return codes: -
-
0 - Success -
gddErrorTypeMismatch - If this GDD is a container -
-
- -

-void adjust(gddDestructor* dest, void* dbuf, aitEnum dtype);
-This function runs the destructor in this GDD if present, effectively -destroying the data is this GDD. The parameter dest becomes the new -destructor, dbuf becomes the GDD's referenced data buffer, and dtype -becomes the new primitive type for this GDD. Not a commonly used function. - -

-void set(aitEnum dtype, void* dbuf);
-void get(aitEnum dtype, void* dbuf);
-Generalized functions for copying the first element of this GDD into and out -from dbuf. Set() takes one element pointed to by dbuf of type dtype and -converts it to this GDD primitive type and copies it to this GDDs data field. -Get() takes one element of this GDD's data field and convert it to dtype and -copies it into dbuf. Not a commonly used function. - -

void getRef(ait_xxxxx*& dbuf);
-Standard way to get access to the data buffer an array-type GDD references. -There is one of these methods for each of the supported ait types. The -dbuf parameter is modified to point to the GDD's data buffer. There is a -danger here. Data pointers in a GDD are stored as void*. The primitive -type indicates the true type of data. These methods can be used to -cast the data pointer to any of the ait types, completely ingoring the -primitive type code. The idea here is that the user will dicover the -correct primitive type and call the correct method. - -

-void putRef(ait_xxxxx* dbuf, gddDestructor dest=NULL);
-void putRef(const ait_xxxxx* dbuf, gddDestructor dest=NULL);
-void putRef(void* dbuf,aitEnum code,gddDestructor dest=NULL);
-Standard way to reference data into a GDD and optionally supply a destructor. -These methods are designed to work with array or atomic type GDDs. -There is one of these methods for each of the support ait types. All these -methods invoke adjust() to do the work with the correct aitEnum type code. -See adjust() for further details. The second method listed marks the GDD -state as constant. - -

void getConvert(ait_xxxxx& dbuf);
-Standard way to retreive scalar data from this GDD. There is one of these -methods for each of the ait types. The data in the GDD will be converted -from it's primitive type to the ait_xxxxx data type and placed into dbuf. -These methods invoke "void get(aitEnum dtype, void* dbuf)". - -

void putConvert(ait_xxxxx dbuf);
-Standard way to place a scalar value into a GDD. There is one of these -methods for each of the ait types. The data will be converted from -ait_xxxxx to the GDD's primitive type and placed into the data field. -These methods invoke set(). - -

gddStatus put(const ait_xxxxx* const dbuf);
-Standard way to copy data from dbuf of type ait_xxxxx into this GDD's buffer. -There is one of these methods for each of the ait types. -These methods invoke genCopy() with proper arguments, see genCopy() for -further details. The return codes of these methods are the same as -genCopy(). - -

gddStatus put(ait_xxxxx dbuf);
-Standard way to place a scalar value into this scalar GDD and reset the -There is one of these methods for each of the ait types. -primtive type to match ait_xxxxx. No conversions take place in these -methods, they are meant to adjust the primitive type. -

return codes: -
-
0 - Success -
gddErrorNotAllowed - If this GDD is not a scalar -
-
- -

gddStatus put(const gdd* dbuf);
-Put the data from dbuf into this GDD. Resets all information in this GDD -to match dbuf. -

return codes: -
-
0 - Success -
gddErrorNotSupported - If this GDD or dbuf is a container. Also if - dbuf has dimension greater than one. -
gddErrorOutOfBounds - Attempting to copying more dbuf elements - into this GDD then this GDD can hold. -
gddErrorNotAllowed - If this GDD has no allocated data but has a - destructor registered. -
-
- -

-void get(ait_xxxxx* dbuf);
-void get(void* dbuf, aitEnum dtype);
-Standard way to retrieve array data from this GDD into dbuf with -primitive type conversion. -There is one of these methods for each of the ait types. -The amount of data copied out of this GDD depends on the primitive type -(for size of element information), and the dimension/bounds for the -total element count. These methods will convert the data from the GDDs -primitive type to the ait_xxxxx type as the copy is taking place. -Depending on the conversion, the size required by dbuf may be more or -less then the size of this GDD's data buffer. - -

void get(ait_xxxxx& dbuf);
-Standard way to get scalar data out of this GDD and perform data conversions -from this GDD primitive type to ait_xxxxx. -There is one of these methods for each of the ait types. -These methods simply invoke "void get(aitEnum dtype, void* dbuf)", see this -method for further details. - -

gdd& operator=(ait_xxxxx* v);
-Convenience methods so the equal operator can be used. Same as putRef(...) -methods. - -

gdd& operator=(ait_xxxxx v);
-Convenience methods so the equal operator can be used. Same as put(...) -methods. - -

operator ait_xxxxx*(void) const;
-

operator ait_xxxxx(void) const;
-Convenience methods so casting can be done from this GDD to any supported -ait_xxxxx pointer variable. Same as getRef(...) and get(...) methods. - - - - diff --git a/src/ca/legacy/gdd/gddref2.html b/src/ca/legacy/gdd/gddref2.html deleted file mode 100644 index 928696208..000000000 --- a/src/ca/legacy/gdd/gddref2.html +++ /dev/null @@ -1,658 +0,0 @@ - - -GDD Reference Manual - - -

GDD Reference Manual

- -gdd
-gddAtomic
-gddScalar
-gddContainer
-gddApplicationTypeTable
-

-gddDestructor
-gddBounds
-gddBounds1D gddBounds2D gddBounds3D
-gddCursor
-gddSemaphore
-gddIntLock
-

-aitConvert
-aitTimeStamp
-aitString
-aitTypes/aitEnums
-

-new/delete Free List Management
-Application Type Code Index Labels
-gddStatus - Error Codes
-

-DBR To ait Conversion Functions
-gddMakeMapDBR
-gddMapDbr
-gddAitToDbr
-gddDbrToAit
-

-User's Guide
- -


gddAtomic

-Specialized subclass of gdd that provides conveniences ways to create -and manage array-type GDDs. - -

#include "gdd.h"

- -gddAtomic(void)
-gddAtomic(gddAtomic* dd)
- -Construct a new gdd that is empty or that is a copy of another gddAtomic -instance. - -

-gddAtomic(int ApplicationType);
-gddAtomic(int ApplicationType, aitEnum PrimitiveType);
-gdd(int ApplicationType, aitEnum PrimitiveType, int Dimension, - aitUint32* ElementCounts);
-gddAtomic(int ApplicationType, aitEnum PrimitiveType, int Dimension, ...); -
- -Construct a new gdd, describing various data properties. If Dimension -is greater that zero, then ElementCounts is an array with Dimension -number of elements in it. Each element of the array describes how many -elements are in that dimension. The ElementCount information is used to -initialize the bounds of a GDD. The last constructor takes a variable -number of arguments which are the upper bounds for each dimension; the -number of variable arguments must be equal to the Dimension argument. - -

-gddStatus getBoundingBoxSize(aitUint32* buf);
-gddStatus getBoundingBoxOrigin(aitUint32* buf);
-gddStatus setBoundingBoxSize(const aitUint32* const buf);
-gddStatus setBoundingBoxOrigin(const aitUint32* const buf);
-Convenience routines for setting bounds information using bounding box -information. The number of elements of buf must be equal to the dimension -defined in the GDD. These methods can be used to set the bounds information -within a GDD in a convenience way by specifying the origin and size. -Bounds in GDDs are descibed (origin,element_count) for each dimension. These -methods provide an alternative method to set all the origins at once or -all the element_counts at once. -

changeType() return codes: -
-
0 - Success -
gddErrorOutOfBounds - If this GDD has dimension zero -
-
- -

gddScalar

-Specialized subclass of gddAtomic that provides convenient ways to create -and manage scalar-type GDDs. - -

#include "gdd.h"

- -gddAtomic(void)
-gddAtomic(gddAtomic* dd)
- -Construct a new gddScalar that is empty or that is a copy of another gddScalar -instance. - -

-gddAtomic(int ApplicationType);
-gddAtomic(int ApplicationType, aitEnum PrimitiveType);
- -Construct a new gddScalar, describing various data properties. Dimension is -a gddScalar is always zero. - -


gddContainer

-Specialized subclass of gdd that provides convenient ways to create -and manage container-type GDDs. - -

#include "gdd.h"

- -gddContainer(void)
-gddContainer(gddContainer* dd)
- -Construct a new gddContainer that is empty or that is a copy of another -gddContainer instance. A gddContainer always has dimension one and a -single bounds structure allocated to tell how many GDDs are in the container. - -

-gddContainer(int ApplicationType);
-gddContainer(int ApplicationType, int total_gdds);
- -Construct a new gddContainer, describing the application type. The argument -total_gdds sets the number GDDs contained within the gddContainer in -the element count of this GDDs bound structure. The last constructor listed -also creates total_gdds GDDs, puts them together in a linked list and -sets the data field of this GDD to point to the linked list. The last -constructor creates the container with total_gdds empty GDDs in it. - -

-gddStatus insert(gdd* dd);
-gddStatus remove(aitIndex index);
-Insert dd to the container. Care must be taken not to use the insert method -on a flattened container. Remove GDD number index from the container. The -GDD at index is removed from the container and unreferenced. -

remove() return codes: -
-
0 - Success -
gddErrorOutOfBounds - If GDD at index does not exist. -
-
- -

-gdd* operator[](aitIndex index);
-gdd* getDD(aitIndex index);
-gdd* getDD(aitIndex index, gddScalar*&);
-gdd* getDD(aitIndex index, gddAtomic*&);
-gdd* getDD(aitIndex index, gddContainer*&);
-Return the GDD at index. - -

-gddCursor getCursor(void) const;
-Get a simple linked list iterator which is useful for manipulating containers. -See gddCursor explanation. - -


gddCursor

-A simple class for moving forward through the GDDs stored in a container. - -

#include "gdd.h"

- -gddCursor(const gddContainer* c)
-Construct a new gddCursor that can be used to walk through gddContainer c. - -

gddStatus first(.....);
-Set this iterator to the first element of the container. Returns the -first GDD in the container. - -

gddStatus next(.....);
-Set this iterator to the next element of the container. Returns the -next GDD in the container. - -

gddStatus current(.....);
-Returns the current GDD that the cursor points to within the container. - -


gddApplicationTypeTable

-A database for registering application type names and retrieving application -type codes. The database also manages GDD prototype structures associated -with application type names. Methods exist for allocating and freeing GDDs -given a type code. See User's Guide for details. - -

#include "gddAppTable.h"

- -gddApplicationTypeTable(aitUint32 total)
-Construct an application type table capable of holding total amount -of application type codes. The user does not need to create one of these, -the library automatically generates one instance of this class large enough -to hold 512 type codes. This automatically generated instance registers -all the standard EPICS control system type codes, see User's Guide. - -

-gddStatus registerApplicationType(const char* const name, aitUint32& app);
-gddStatus registerApplicationTypeWithProto(const char* const name, - gdd* protoDD, aitUint32& app);
-
-Register an application type name. The type table will return the -application type code in app that the system has assigned to the name. -The latter function allow a prototype GDD to be registered aloong with -the name. This prototype is describes the structure of the data associated -with the application type name. See User's Guide for more details. -

return codes: -
-
0 - Success -
gddErrorAlreadyDefined - If name is already refined, app - still returns the type code assigned to the name. -
gddErrorAtLimit - The type table is filled, no more names can be - stored in it. -
-
- -

-aitUint32 getApplicationType(const char* const name) const;
-char* getName(aitUint32 app) const;
-
-Convert a character string type name to it's integer value. Convert an -integer value to it's character string name. - -

gddStatus mapAppToIndex(aitUint32 container_app, - aitUint32 app_to_map, aitUint32& index);
-Special function for converting type codes to container GDD array indexes. -The GDD must be a flattened GDD managed by the application type table for -mapping to take place. The container_app argument is the main -structure that contains app_to_map. The index is populated -with the position where app_to_map is within container_app. -See User's Guide for details. -

return codes: -
-
0 - Success -
gddErrorOutOfBounds - app_to_map cannot be mapped -
gddErrorNotDefined - container_app does not exist or app_to_map not - in container_app -
-
- -

gddStatus smartCopy(gdd* dest, gdd* src);
-Given any GDD dest and any GDD src, copy all the data from src to dest -where application type codes match. The src and dest can be any type of -GDD: scalar, array, or container. The src dset do not need to be the -same type of GDD. If dest and src are both containers. The function will -look through each of the src GDDs to find matches for each of the dest GDDs. -SmartCopy() may result in no data being copied if none of the src type codes -match the dest type codes. The dest and src container GDDs do not need to -be in the same order. -

return codes: -
-
0 - Success -
gddErrorNotAllowed - src or dest is container and is not managed -
other - see put(const gdd*) -
-
- -

gdd* getDD(aitUint32 app);
-Allocate a GDD for the app and return it. If app has a prototype -registered with it, then the returned gdd will be managed and match the -prototype. - -

gddStatus freeDD(gdd* dd);
-Free any gdd. The method basically just calls unreference on dd. If the -GDD is managed, then it puts it onto a free list for it's application type -code. - -

-aitUint32 maxAttributes(void) const;
-aitUint32 totalregistered(void) const;
-
-Return the total number of names registered in this application type table. -Return the total number of names that can be registered in this application -type table. - -

void describe(FILE* fd);
-Print out "#define" statements for each of the names registered in this -table. Also print out container index labels in the form of #defines. See -User's Guide for details. The file gddApps.h is generated using this -function. - -

static gddApplicationTypeTable& AppTable(void);
-Return the automatically generated application type table for use in a -program. - -


gddDestructor

-The gdd class knows how to run and manage gddDestructors. User's assign -destructors to gdd by deriving classes from gddDestructor. - -

#include "gdd.h"

- - -gddDestructor(void);
-gddDestructor(void* user_arg);
-
-Create a gddDestructor, optionally placing an arbitrary pointer in the -destructor which can be referenced when the destructor is actual run. - -

-gddStatus destroy(void* thing_to_remove);
-virtual void run(void* thing_to_remove);
-
-The destroy method in invoked by anyone withing to request the destructor -to be run. Destroy invokes the user-written function run when -it's reference count goes to zero. Run should not be invoked -directly by the user. The argument to destroy is the buffer that -needs to be freed by by the destructor. The gdd class invokes destroy -when unreference is called and the gdd's reference count goes to zero. The -default behavior of run is to cast the buffer thing_to_remove to a -character array and delete it. - -

-void reference(void);
-int refCount(void) const;
-
-Calling refCount will return the current value in the destructor -reference count. Reference will bump up the reference count of this -destructor. - -


gddBounds

-A simple class to describe the boundaries of a dimension. - -

#include "gdd.h"

- -void setSize(aitIndex c);
-Sets the number of elements for this bounds. - -

-void set(aitIndex first, aitIndex cnt);
-void get(aitIndex& first, aitIndex& cnt);
-
-Set and get the first element in this bounds and the number of elements. - -

aitIndex size(void) const;
-Return the number of element in this bounds. - -

aitIndex first(void) const;
-Return the first element in this bounds. - -


gddBounds1D gddBounds2D gddBounds3D

-Specialized classes for describing with one, two, and three dimension data. -Since three of less dimension are the most common, bounds array classes for -each type exist and are managed on free lists. All of these classes -overload the new/delete operators so that the memory allocater is not used. -All of these classes are just arrays of gddBounds. Only one method exists -in these classes, gddBounds* boundArray(void), which returns a pointer -to the array of gddBounds. - -

#include "gdd.h"

- -


gddSemaphore

-Simple wrapper around the underlying OS semphore functions. Implimentation -is OS dependant and is not really relevant in single threaded application. -This is a binary semaphore meant to be used for locking sections of code -or perhaps in a simple producer/consumer program. - -

#include "gddUtils.h"

- - -gddSemaphore(void)
-gddSemaphore(gddSemType init)
-
-Create a simple binary gddSemaphore which defaults to full. Create a -gddSemaphore which is set initially to state init. Init -is either gddSemEmpty or gddSemFull. - -

-void give(void)
-void take(void)
-
-Operations for manipulating the semaphore. Take will block if the -semaphore is empty, waiting until it is full. Give sets the -semaphore back to full state. - -

int take(aitUint32 usec)
-Attempt to perform the semaphore take operation. Only block for usec -microseconds. Returns true if time-out occurred and semaphore is not -really taken. - -


gddIntLock

-A simple wrapper around OS interrupt locking services. - -

#include "gddUtils.h"

- -


aitConvert

-A set of convenience functions for quickly converting arrays of data from one -aitType to another. The header file for these functions also contains a -set of standard functions for converting each of the ait types from/to -network byte order. - -

#include "aitConvert.h"

- -

void aitConvert(aitEnum desttype, void* dest, - aitEnum srctype, const void* src, aitIndex count)
-Take count number of elements from src of type srctype, -copy then to dest and at the same time convert them to type -desttype. - -

-void aitConvertToNet(aitEnum desttype, void* dest, - aitEnum srctype, const void* src, aitIndex count)
-void aitConvertFromNet(aitEnum desttype, void* dest, - aitEnum srctype, const void* src, aitIndex count)
-
-Same as aitConvert but change the byte order or data format to/from -network format. If the local host data format is network data format, -then these function are exactly the same as aitConvert. - -

aitLocalNetworkDataFormatSame
-This is a #define which is true if local host byte order is the same -as network byte order, otherwise it is false. - -


aitTimeStamp

-A class for storing and manipulating standard time stamps. This time -is similar to POSIX time stamps, it maintains time in seconds/nanoseconds -past a standard epoch. POSIX defines a time stamp as a long for seconds -and a type time_t for nanoseconds. Time_t is OS dependant and so is a -long. aitTimeStamp forces seconds and nanoseconds to be unsigned 32 bit -integers so the storage size is fixed and known. - -

#include "aitHelpers.h"

-Automatically included if aitTypes.h is included. - -

-operator double()
-operator float()
-
-Convert (cast) the seconds/nanoseconds to a double or float seconds with -decimal fraction of a second past epoch. - -

static aitTimeStamp getCurrent();
-Retrieve the current time in aitTimeStamp format. - -

void get(unsigned long &tv_secOut,unsigned long &tv_nsecOut);
-Retreive the various parts of the time stamp as separate quantities. - -

aitTimeStamp()
-aitTimeStamp(const aitTimeStamp &t)
-aitTimeStamp(const unsigned long sec, const unsigned long nsec)
-Create an aitTimeStamp that is initially zero or set to various values. - -

-const unsigned NSecPerSec = 1000000000u;
-const unsigned NSecPerUSec = 1000u;
-const unsigned SecPerMin = 60u;
-
-Various constants for working with time. - -

-aitTimeStamp operator+ (const aitTimeStamp &lhs, const aitTimeStamp &rhs);
-aitTimeStamp operator- (const aitTimeStamp &lhs, const aitTimeStamp &rhs);
-int operator>= (const aitTimeStamp &lhs, const aitTimeStamp &rhs);
-
-They are global functions for adding and subtracting and comparing time stamps. - -


aitString

-Standard class for holding and managing a variable length string. Strings -is GDD have two attributes associated with them: length and state. Length -is simply the total length of the string and state either constant or -allocated. - -

#include "aitHelpers.h"

-Automatically included if aitTypes.h is included. - -

aitString(void);
-Construct an aitString that is empty. - -

-aitString(char* str);
-aitString(aitString* str);
-aitString(aitString& str);
-
-Construct an aitString which contains a copy of str. The -state of this aitString will be "allocated". - -

-aitString(const char* str);
-aitString(const aitString* str);
-aitString(const aitString& str);
-
-Construct an aitString which contains a reference to str. The -state of this aitString will be "constant". - -

void clear(void);
-Clear out this aitString, freeing up any storage that may be allocated. - -

-void dump(void) const;
-void dump(const char* id) const;
-
-Print the contents of this aitString to stdout in a readable format. Good -tool for debugging or understanding the aitString class. - -

-operator const char*(void) const;
-operator char*(void) const;
-
-Pull out a reference to the string that this aitString is holding. These -are casting operators from aitString to char*. - -

int isConstant(void) const;
-Returns true is this aitString hold a constant string. - -

-aitUint32 length(void) const;
-const char* string(void) const;
-
-Return the length of the string in this aitString. Return a reference to -the string in this aitString. - -

-aitString& operator=(......);
-int copy(......);
-
-Create a copy of the variable string arguments in this aitString. This -aitString attributes will match that of the arguments. The assignment -operators just invoke copy(......). - -

void replaceData(......);
-Replace the data in this aitString with the string in the argument. This -function will only copy this aitStrings length number of bytes into it's -string from the argument string. - -

void installString(......);
-Invoke replaceData if this aitString is "constant". Invoke copy if this -aitString is not "constant". - -

-static aitUint32 totalLength(aitString* array,aitIndex arraySize);
-static aitUint32 stringsLength(aitString* array,aitIndex arraySize);
-static aitIndex compact(aitString* array, aitIndex arraySize, - void* buf, aitIndex bufSize);
-
-totalLength() returns the total number of bytes that an array of aitStrings -requires. This length include the size of all the strings in the aitStrings. -Array is the aitString array, arraySize is the number of -elements in array array. The function stringsLength -returns the total length of all the strings in aitString array array. -The function compact takes aitString array array with -arraySize elements and places all the data contiguously into buffer -buf. The compacted buffer is bufSize number of bytes. The -compact function places all the aitString instances of the array at -the front of buf. The aitStrings in buf reference strings that are -further into the buffer buf. Compact returns the total -number of bytes used in buf. - -


aitTypes/aitEnums

-Standard GDD data types and enumerations for them. This header file contains -many macros for dicovering information about aitTypes. See the header. - -

#include "aitTypes.h"

- -

-	aitInt8			8 bit signed integer
-	aitUint8			8 bit unsigned integer
-	aitInt16			16 bit signed integer
-	aitUint16		16 bit unsigned integer
-	aitEnum16		16 bit unsigned integer
-	aitInt32			32 bit signed integer
-	aitUint32		32 bit unsigned integer
-	aitFloat32		32 bit floating point number
-	aitFloat64		64 bit floating point number
-	aitIndex			32 bit unsigned integer for indexing arrays
-	aitPointer		largest pointer a system can hold
-	aitStatus		32 bit unsigned integer
-	aitBool			standard "c" enum - value aitTrue or aitFalse
-	aitFixedString	A fixed string of length AIT_FIXED_STRING_SIZE
-	aitTimeStamp	The standard seconds/nanoseconds time stamp
-	aitString		Class for manipulating and storing strings
-
- -

-aitTotal
-aitConvertTotal
-aitValid(x)
-aitConvertValid(x)
-
-Value of the first two are the number of valid types. All the ait types -cannot be automatically converted using aitConvert. AitValid(x) returns -true if x has a valid ait type enumeration associated with it. -AitConvertValid(x) returns true if enumerated value x can be converted using -aitConvert. - -

aitEnum
-This is an enumerated data type, there is one name per ait types. See -header file for the definition. - -

aitType
-Data union of all the ait types. - -

-aitSize[aitTotal]
-aitName[aitTotal]
-aitStringType[aitTotal]
-
-Arrays used for discovering information about ait types using the enumerated -ait type name as the index into the array. aitSize returns the size in -bytes of the ait type. aitName returns a character string name of the -ait type. aitStringType returns a string which can be used in sscanf to -read or convert a string into the actual ait type. - -


gddStatus - Error Codes

-Error codes returned by various GDD library functions and methods. See header -file. -

#include "gddErrorsCodes.h"

-char* gddErrorMessages[]
-Return an error message string name for an error code. - -


new/delete Free List Management

-

#include "gddNewDel.h"

-A set of generic member function macros that can be added to any class -to allow the class to be managed on a free list using the new/delete -operators. See the header file for details on how to use this -facility. Most GDD library classes use this facility. - -


Application Type Code Index Labels

-

#include "gddApps.h"

-This file is generated from the standard application type table. It -contains all the #define statements for preregistered containers and -application type codes. - -


-DBR To ait Conversion Functions
-gddMapDbr
-gddAitToDbr
-gddDbrToAit
-

-

#include "dbMapper.h"

-Large set of utility functions for converting between EPICS DBR data types -and GDD containers. - -

void gddMakeMapDBR(gddApplicationTypeTable& table);
-The DBR mapping facility is not initialized automatically. It must be -initialized using this function before any of the functions are called. -It should be passed the standard default -application type table as an argument. - -

chtype gddAitToDbr[]
-Given an ait type code, return the equivalent EPICS DBR type code. - -

gddDbrToAitTable gddDbrToAit[]
-Given a DBR type code, return a structure that describe the ait/GDD type code -informtion for that DBR type code. The information in gddDbrToAitTable is -the GDD application type code and GDD application type name for a given DBR -type. This information is not extremely useful for simple applications. - -

gddDbrMapFuncTable gddMapDbr[]
-Array of conversion functions that convert between DBR structures and GDD -types. The index of this array is always the DBR type code, not the -GDD application type code. Each element of the array contains to functions: -conv_gdd and conv_dbr. Conv_gdd takes a DBR structure and returns a GDD -equivalent to the DBR structure. Conv_dbr takes a GDD and puts all the data -into a DBR structure. - -

-struct gddDbrMapFuncTable {
-	to_gdd conv_gdd;
-	to_dbr conv_dbr;
-};
-
-gdd* to_gdd(void* dbr_data_structure, aitIndex dbr_element_count);
-int to_dbr(void* dbr_data_structure, gdd* gdd_instance); 
-
- - - - diff --git a/src/ca/legacy/gdd/genApps.cc b/src/ca/legacy/gdd/genApps.cc deleted file mode 100644 index c8b934a76..000000000 --- a/src/ca/legacy/gdd/genApps.cc +++ /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. -\*************************************************************************/ -// Author: Jim Kowalkowski -// Date: 2/96 - -#define epicsExportSharedSymbols -#include "gddAppTable.h" - -#if 0 -#ifndef GDD_NO_EPICS -#include "dbrMapper.h" -#endif -#endif - -int main(int argc, char* argv[]) -{ - FILE* fd; - - gddApplicationTypeTable& tt = gddApplicationTypeTable::AppTable(); - - if(argc<2) - { - fprintf(stderr,"You must enter a file name on command line\n"); - return -1; - } - - if((fd=fopen(argv[1],"w"))==NULL) - { - fprintf(stderr,"Cannot open file %s\n",argv[1]); - return -1; - } - -#if 0 -#ifndef GDD_NO_EPICS - gddMakeMapDBR(tt); -#endif -#endif - - tt.describe(fd); - fclose(fd); - - return 0; -} - diff --git a/src/ca/legacy/gdd/smartGDDPointer.h b/src/ca/legacy/gdd/smartGDDPointer.h deleted file mode 100644 index 3cbaff2f6..000000000 --- a/src/ca/legacy/gdd/smartGDDPointer.h +++ /dev/null @@ -1,186 +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. -\*************************************************************************/ - -// -// Smart Pointer Class for GDD -// ( handles referencing / unreferencing a gdd each time it is used ) -// -// Author: Jeff Hill -// - -#ifndef smartGDDPointer_h -#define smartGDDPointer_h - -#include "gdd.h" -#include "shareLib.h" - -// -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// !! WARNING WARNING WARNING WARNING WARNING WARNING WARNING !! -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// // be careful to manually unreference here -// // (the reference count is initialized to one by the gdd ctor) -// Gdd * pDD0 = new gdd; -// smartGDDPointer pDD1 (pDD0); -// pDD0->unreference (); -// -// // from here on down the smart pointer maintains the ref count -// smartGDDPointer pDD2 = pDD1; -// smartGDDPointer pDD3 = pDD2; -// pDD2 = pDD3; -// -template < class T > -class smartGDDPointerTemplate { -public: - smartGDDPointerTemplate (); - smartGDDPointerTemplate ( T & valueIn ); - smartGDDPointerTemplate ( T * pValueIn ); - smartGDDPointerTemplate ( const smartGDDPointerTemplate & ptrIn ); - ~smartGDDPointerTemplate (); - smartGDDPointerTemplate < T > & operator = ( T * rhs ); - smartGDDPointerTemplate < T > & operator = ( const smartGDDPointerTemplate & rhs ); - operator smartGDDPointerTemplate < const T > () const; - void set ( T * pNewValue ); - T * get () const; - T * operator -> () const; - T & operator * () const; - bool operator ! () const; - bool valid () const; - void swap ( smartGDDPointerTemplate < T > & ); - // - // see Meyers, "more effective C++", for explanation on - // why conversion to dumb pointer is ill advised here - // - //operator const gdd * () const; -protected: - T * pValue; -}; - -typedef smartGDDPointerTemplate < gdd > smartGDDPointer; -typedef smartGDDPointerTemplate < const gdd > smartConstGDDPointer; - -template < class T > -inline smartGDDPointerTemplate < T >::smartGDDPointerTemplate () : - pValue (0) {} - -template < class T > -inline smartGDDPointerTemplate < T >::smartGDDPointerTemplate ( T & valueIn ) : - pValue ( & valueIn ) -{ - gddStatus status = this->pValue->reference (); - assert ( ! status ); -} - -template < class T > -inline smartGDDPointerTemplate < T >::smartGDDPointerTemplate ( T * pValueIn ) : - pValue ( pValueIn ) -{ - if ( this->pValue != NULL ) { - gddStatus status = this->pValue->reference (); - assert ( ! status ); - } -} - -template < class T > -inline smartGDDPointerTemplate < T > :: - smartGDDPointerTemplate ( const smartGDDPointerTemplate < T > & ptrIn ) : - pValue ( ptrIn.pValue ) -{ - if ( this->pValue != NULL ) { - gddStatus status = this->pValue->reference (); - assert ( ! status ); - } -} - -template < class T > -inline smartGDDPointerTemplate < T > :: ~smartGDDPointerTemplate () -{ - if ( this->pValue != NULL ) { - gddStatus status = this->pValue->unreference (); - assert ( ! status ); - } -} - -template < class T > -inline void smartGDDPointerTemplate < T > :: set ( T * pNewValue ) -{ - if ( this->pValue != pNewValue ) { - if ( pNewValue ) { - gddStatus status = pNewValue->reference (); - assert ( ! status ); - } - if ( this->pValue ) { - this->pValue->unreference (); - } - this->pValue = pNewValue; - } -} - -template < class T > -inline T * smartGDDPointerTemplate < T > :: get () const -{ - return this->pValue; -} - -template < class T > -inline smartGDDPointerTemplate < T > & - smartGDDPointerTemplate < T >::operator = ( T * rhs ) -{ - this->set ( rhs ); - return *this; -} - -template < class T > -inline smartGDDPointerTemplate < T > & - smartGDDPointerTemplate < T >::operator = ( const smartGDDPointerTemplate < T > & rhs ) -{ - this->set ( rhs.pValue ); - return *this; -} - -template < class T > -inline T * smartGDDPointerTemplate < T > :: operator -> () const -{ - return this->pValue; -} - -template < class T > -inline T & smartGDDPointerTemplate < T > :: operator * () const -{ - return * this->pValue; -} - -template < class T > -inline bool smartGDDPointerTemplate < T > :: operator ! () const -{ - return this->pValue ? false : true; -} - -template < class T > -inline bool smartGDDPointerTemplate < T > :: valid () const -{ - return this->pValue ? true : false; -} - -template < class T > -inline void smartGDDPointerTemplate < T > :: swap ( smartGDDPointerTemplate < T > & in ) -{ - T * pTmp = this->pValue; - this->pValue = in.pValue; - in.pValue = pTmp; -} - -template < class T > -smartGDDPointerTemplate < T > :: operator smartGDDPointerTemplate < const T > () const -{ - return smartGDDPointerTemplate < const T > ( this->pValue ); -} - -#endif // smartGDDPointer_h - diff --git a/src/ca/legacy/pcas/Makefile b/src/ca/legacy/pcas/Makefile deleted file mode 100644 index 04884424e..000000000 --- a/src/ca/legacy/pcas/Makefile +++ /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 is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* - -TOP=../../../.. - -include $(TOP)/configure/CONFIG - -DIRS = build example - -example_DEPEND_DIRS = build - -include $(TOP)/configure/RULES_DIRS - - diff --git a/src/ca/legacy/pcas/README b/src/ca/legacy/pcas/README deleted file mode 100644 index b016c6737..000000000 --- a/src/ca/legacy/pcas/README +++ /dev/null @@ -1,26 +0,0 @@ -README file for the EPICS Channel Access Server - -Author Jeff Hill johill@lanl.gov - - -Directory Structure -------------------- -o example - example server tool -o generic - generic server lib source code -o os - os dependnet server lib source code -o io - io dependnet server lib source code -o build/singleThread - server lib object code for single threaded use -o build/multiThread - server lib object code for multi threaded use - -Internal Source Code Naming Conventions ---------------------------------------- -o API class X will almost always have associated internal (usually - private base) class named XI -o for class X there will - o sometimes be X.h - the class declaration (and simple inlines) - o sometimes be XIL.h - complex inline functions (that will not - compile unless the compiler has seen - the declarations of other classes) - o be X.cc - all other source code for the class - - diff --git a/src/ca/legacy/pcas/RELEASE_NOTES b/src/ca/legacy/pcas/RELEASE_NOTES deleted file mode 100644 index 7037312b1..000000000 --- a/src/ca/legacy/pcas/RELEASE_NOTES +++ /dev/null @@ -1,253 +0,0 @@ - - - -Changes between epics 3.13 Beta 4 and 3.13 Beta 5 - -**** API Change **** -o The canonical PV name is returned from caServer::pvExistTest() -in the supplied buffer and not in a gdd data descriptor. See -"casdef.h". -old API: - // - // pvExistTest() - // - // The server tool is encouraged to accept multiple PV name - // aliases for the same PV here. However, a unique canonical name - // must be selected for each PV. - // - // returns S_casApp_success and fills in canonicalPVName - // if the PV is in this server tool - // - // returns S_casApp_pvNotFound if the PV does not exist in - // the server tool - // - // The server tool returns the unique canonical name for - // the pv into the gdd. A gdd is used here because this - // operation is allowed to complete asynchronously. - // - virtual caStatus pvExistTest (const casCtx &ctx, const char *pPVName, - gdd &canonicalPVName) = 0; -new API: - // - // pvExistTest() - // - // The server tool is encouraged to accept multiple PV name - // aliases for the same PV here. However, one unique canonical name - // must be selected by the server tool and returned to the - // server lib for each PV. The server will use this canonical - // name to prevent internal duplication of data structures for - // process variables that have multiple aliases. - // - // o returns S_casApp_success and a valid canonical name string - // when the PV is in this server tool - // - // o returns S_casApp_pvNotFound if the PV does not exist in - // the server tool - // - // Examples: - // caServerXXX::pvExistTest(const casCtx &ctx, const char *pPVName) - // { - // return pvExistReturn(S_casApp_success, pPVName); // common - // return pvExistReturn(S_casApp_pvNotFound); // no PV by that name - // - // char pName[9] = "myPVName"; - // return pvExistReturn(S_casApp_success, pName); // also common - // return pvExistReturn(S_casApp_asyncCompletion); // not now - // } - // - virtual pvExistReturn pvExistTest (const casCtx &ctx, - const char *pPVName)=0; - -**** API Change **** -o The server tool must now use one of class casAsyncReadIO, casAsyncWriteIO, or -casAsyncPVExistIO in place of casAsyncIO. See "casdef.h". - -**** API Change **** -o Virtual function prototype change: -Before: "aitEnum casPV::bestExternalType()" -After: "aitEnum casPV::bestExternalType() const" - -**** API Change **** -o The following virtual functions were added to casPV: - // - // Returns the maximum bounding box for all present and - // future data stored within the PV. - // - // The routine "dimension()" returns the maximum - // number of dimensions in the hypercube (0=scaler, - // 1=array, 2=plane, 3=cube ...}. - // - // The routine "maxBound(dimension)" returns the - // maximum length of a particular dimension of the - // hypercube as follows: - // - // dim equal to 0 1 3 ... - // ------------------------------------------- - // hypercube - // type - // --------- - // - // array array - // length - // - // plane x y - // - // cube x y z - // - // . - // . - // . - // - // The default (base) "dimension()" returns zero (scaler). - // The default (base) "maxBound()" returns scaler bounds - // for all dimensions. - // - // Clients will see that the PV's data is scaler if - // these routines are not supplied in the derived class. - // - // If the "dimension" argument to maxBounds() is set to - // zero then the bound on the first dimension is being - // fetched. If the "dimension" argument to maxBound() is - // set to one then the bound on the second dimension - // are being fetched... - // - virtual unsigned maxDimension() const; // return zero if scaler - virtual aitIndex maxBound (unsigned dimension) const; - -The defaults in base class casPV implement identical behavior -to the past if these routines are not supplied by the derived -class. - -Changes between epics 3.13 Beta 6 and 3.13 Beta ???? - -**** API Change **** - -o The member function "casChannel::postEvent()" has been replaced by -"casChannel::postAccessRightsEvent()". An access rights state change -event is now posted to the client each time that -"casChannel::postAccessRightsEvent()" is called. - -o The virtual functions "casChannel::interestRegister()" -and "casChannel::interestDelete()" have been eliminated. - -o The constructor "caServer::caServer()" no-longer has an argument specifying -the maximum PV name length. It also no longer has an argument specifying -the maximum simultaneous IO operations. THIS IS LIKELY TO BREAK YOUR CODE -BECAUSE THE FIRST TWO ARGUMENTS WERE REMOVED AND THERE ARE DEFAULT ARGUMENTS. -This change was made because we would like to remove all limits on -the PV name length (real or perceived). We also felt that if a server -tool wishes to postpone an asynchronious IO operation then it -should return S_casApp_postponeAsyncIO from caServer::pvExistTest() and -caServer::createPV() (instead of relying on the server to keep track of -the number of simultaneous asynchronous IO operations). This provides a -less complex and more flexible API. - -o The member function "casPV::casPV(caServer &cas)" replaces the member -function "casPV::casPV(const casCtx &ctx, const char * const pPVName)". - -o The virtual member function -"caServer::createPV(const casCtx &ctx, const char *pPVName)" -has been replaced by the virtual member function -"pvCreateReturn createPV (const casCtx &ctx, const char *pPVAliasName)" -This change was made in order to allow asynchronous completion of a -PV create operation. - -o The data type (class) pvExistReturn has been changed to an enum - -"enum pvExistReturn {pverExistsHere, pverDoesNotExistHere, - pverAsyncCompletion, pverNoMemoryForAsyncOP}" -This impacts the virtual member function -"pvExistTest (const casCtx &ctx, const char *pPVAliasName)" - -o The server tool is now required to supply the virtual function -"casPV::getName()" so that the server is able to identify the process -variable when diagnostics are printed. - -o The virtual function casPV::maxSimultAsyncOps() has been eliminated -in favor of allowing the server tool to return S_casApp_postponeAsyncIO -from casPV::read() or casPV::write() when there are too many simultaneous -asynchronous IO operations and the server tool would like to postpone -the current (and future) request(s) until one of the outstanding asynchronous -IO operations (read or write) completes. - -o All "show()" virtual member functions in the interface classes -have had the "const" attribute added. - -**** Semantic Change **** - -o IMPORTANT: It is now the responsibility of the server tool to detect attempts -by the server lib to create a 2nd PV with the same canonical name as an -existing PV and avoid this by returning a pointer to the first PV created. -Likewise, if there are several aliases for one canonical PV name then it is -the responsibility of the server tool to return "pvExistsHere" from -"caServerDerived::pvExistTest()" for each of the aliases. Likewise, if there -are several aliases for one canonical PV name then it is the responsibility -of the server tool to return a single PV with the canonical name from -"caServerDerived::createPV()" (even if createPV() is called multiple times -each with a different alias name). This change was made to simplify the API -and to eliminate redundant data structures and labor occurring within the server -tool and the server library. - -o PV creation is now allowed to complete asynchronously - -o It is now the responsibility of the server tool to limit the -number of simultaneous asynchronous IO operations allowed (by returning -S_casApp_postponeAsyncIO). - -Changes between epics 3.13 Beta 11 and 3.13 Beta 12 - -**** API Change **** -o The constructor for class casPV no longer requires a reference to the -server. For backwards compatibility a reference to the server may still be -supplied, but it will not be used. - -Changes after epics 3.13.1 - -**** API Change **** -o The virtual function caServer::createPV() has been deprecated in favor of the new -virtual function caServer::attachPV() which provides exactly the same functionality. -The name was changed so that the purpose of this virtual function is more clear -to server tool designers. To remain backwards compatible the virtual function -caServer::createPV() is called by the base implementation of caServer::attachPV(). -In a future release all calls to the virtual member function caServer::createPV() -will be eliminated. - -o The class pvCreateReturn has been deprecated in favor of the new class -pvAttachReturn which provides exactly the same functionality. The name was -changed so that the purpose of this class is more clear to server tool -designers. To remain backwards compatible the class pvCreateReturn derives from -public base class pvAttachReturn. In a future release the class pvCreateReturn -will be eliminated. - -o The class casAsyncPVCreateIO has been deprecated in favor of the new class -casAsyncPVAttachIO which provides exactly the same functionality. The name was -changed so that the purpose of this class is more clear to server tool -designers. To remain backwards compatible the class casAsyncPVCreateIO derives from -public base class casAsyncPVAttachIO. In a future release the class casAsyncPVCreateIO -will be eliminated. - -o The hash table template class resTable now requires a PV count estimate -argument to its the constructor, and its init(PV count estimate) member function -has been eliminated (server tools frequently implement a string hash table -based on class resTable). - -o The delay argument passed to fileDescriptorManager.process(delay) has been changed -from type osiTime to the C++ primitive type double. - -o The arithmetic operators in class osiTime now return type double, and not type -osiTime. - -o In class osiTimer the use of type osiBool was eliminated in favor of the now universally -implemented ANSI STD C++ "bool" type. - -o In class osiTimer type double, and not type osiTime, is returned from virtual member -function delay(). - -o The public const event mask member data in the caServer class were changed to member -functions in order to avoid problems on some compiler where const event masks cant be -created until the server is fully constructed. The constants have been replaced by the -following member functions. - casEventMask valueEventMask() const; // DBE_VALUE registerEvent("value") - casEventMask logEventMask() const; // DBE_LOG registerEvent("log") - casEventMask alarmEventMask() const; // DBE_ALARM registerEvent("alarm") - - diff --git a/src/ca/legacy/pcas/build/Makefile b/src/ca/legacy/pcas/build/Makefile deleted file mode 100644 index b4783fc17..000000000 --- a/src/ca/legacy/pcas/build/Makefile +++ /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. -#************************************************************************* -TOP := ../../../../.. -CAS := $(TOP)/src/ca/legacy/pcas -SRC := $(CAS)/generic -CA := $(TOP)/src/ca/client -IOSRC := $(CAS)/io/bsdSocket -STSRC := $(SRC)/st - -include $(TOP)/configure/CONFIG - -SRC_DIRS += $(SRC) -SRC_DIRS += $(IOSRC) -SRC_DIRS += $(STSRC) -SRC_DIRS += $(CA) - -#USR_CXXFLAGS = $(USR_CFLAGS) - -INC += casdef.h -INC += casEventMask.h -INC += caNetAddr.h - -LIBSRCS += caServer.cc -LIBSRCS += caServerI.cc -LIBSRCS += casCoreClient.cc -LIBSRCS += casDGClient.cc -LIBSRCS += casStrmClient.cc -LIBSRCS += casPV.cc -LIBSRCS += casPVI.cc -LIBSRCS += casChannel.cc -LIBSRCS += casChannelI.cc -LIBSRCS += casAsyncIOI.cc -LIBSRCS += casAsyncReadIO.cc -LIBSRCS += casAsyncReadIOI.cc -LIBSRCS += casAsyncWriteIO.cc -LIBSRCS += casAsyncWriteIOI.cc -LIBSRCS += casAsyncPVExistIO.cc -LIBSRCS += casAsyncPVExistIOI.cc -LIBSRCS += casAsyncPVAttachIO.cc -LIBSRCS += casAsyncPVAttachIOI.cc -LIBSRCS += casEventSys.cc -LIBSRCS += casMonitor.cc -LIBSRCS += casMonEvent.cc -LIBSRCS += inBuf.cc -LIBSRCS += outBuf.cc -LIBSRCS += casCtx.cc -LIBSRCS += casEventMask.cc -LIBSRCS += ioBlocked.cc -LIBSRCS += pvExistReturn.cc -LIBSRCS += pvAttachReturn.cc -LIBSRCS += caNetAddr.cc -LIBSRCS += beaconTimer.cc -LIBSRCS += beaconAnomalyGovernor.cc -LIBSRCS += clientBufMemoryManager.cpp -LIBSRCS += chanIntfForPV.cc -LIBSRCS += channelDestroyEvent.cpp - -LIBSRCS += casIntfOS.cc -LIBSRCS += casDGIntfOS.cc -LIBSRCS += casStreamOS.cc - -LIBSRCS += caServerIO.cc -LIBSRCS += casIntfIO.cc -LIBSRCS += casDGIntfIO.cc -LIBSRCS += casStreamIO.cc -LIBSRCS += ipIgnoreEntry.cc - -USR_CXXFLAGS_Linux = -fno-strict-aliasing -USR_CXXFLAGS_RTEMS = -fno-strict-aliasing -USR_CXXFLAGS_vxWorks = -fno-strict-aliasing - -# There is a bug in some vxWorks compilers that these work around: -ifeq ($(VX_GNU_VERSION), 4.1.2) - casStreamOS_CXXFLAGS_vxWorks-ppc604_altivec = -O0 - casStreamOS_CXXFLAGS_vxWorks-ppc604_long = -O0 - casStreamOS_CXXFLAGS_vxWorks-ppc604 = -O0 -endif - -LIBRARY = cas -cas_LIBS = ca gdd Com -cas_SYS_LIBS_WIN32 = ws2_32 -cas_RCS = cas.rc - -CLEANS += Templates.DB - -include $(TOP)/configure/RULES diff --git a/src/ca/legacy/pcas/build/cas.rc b/src/ca/legacy/pcas/build/cas.rc deleted file mode 100644 index 6c84bced8..000000000 --- a/src/ca/legacy/pcas/build/cas.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 Server Library for EPICS\0" - VALUE "CompanyName", "The EPICS collaboration\0" - VALUE "FileDescription", "Channel Access Server Library\0" - VALUE "FileVersion", EPICS_VERSION_STRING "\0" - VALUE "InternalName", "cas\0" - VALUE "LegalCopyright", "Copyright (C) Univ. of California, Univ. of Chicago\0" - VALUE "OriginalFilename", "cas.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/legacy/pcas/ex/Makefile b/src/ca/legacy/pcas/ex/Makefile deleted file mode 100644 index 061fb5d7e..000000000 --- a/src/ca/legacy/pcas/ex/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. -#************************************************************************* - -TOP=../../../../.. - -include $(TOP)/configure/CONFIG - -PROD_LIBS += $(EPICS_BASE_HOST_LIBS) - -SRC_DIRS += $(TOP)/src/template/base/top/caServerApp - -# -# Added ws2_32 winmm user32 for the non-dll build -# -PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32 - - -PROD_HOST = excas - -excas_SRCS += main.cc -excas_SRCS += exServer.cc -excas_SRCS += exPV.cc -excas_SRCS += exVectorPV.cc -excas_SRCS += exScalarPV.cc -excas_SRCS += exAsyncPV.cc -excas_SRCS += exChannel.cc - -include $(TOP)/configure/RULES - - diff --git a/src/ca/legacy/pcas/example/Makefile b/src/ca/legacy/pcas/example/Makefile deleted file mode 100644 index 9ec9d6b6a..000000000 --- a/src/ca/legacy/pcas/example/Makefile +++ /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. -#************************************************************************* - -TOP=../../../../.. - -include $(TOP)/configure/CONFIG - -DIRS = directoryService - -include $(TOP)/configure/RULES_DIRS - - diff --git a/src/ca/legacy/pcas/example/README b/src/ca/legacy/pcas/example/README deleted file mode 100644 index affe6533d..000000000 --- a/src/ca/legacy/pcas/example/README +++ /dev/null @@ -1,7 +0,0 @@ -This directory contains a server tool example (which uses the -ca server library): - -directoryService - fully functional pv name resolution server - -The simple example that was provided here has been become the -makeBaseApp template "caServerApp" diff --git a/src/ca/legacy/pcas/example/directoryService/Makefile b/src/ca/legacy/pcas/example/directoryService/Makefile deleted file mode 100644 index d7abb96b2..000000000 --- a/src/ca/legacy/pcas/example/directoryService/Makefile +++ /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. -#************************************************************************* - -TOP=../../../../../.. - -include $(TOP)/configure/CONFIG - -PROD_LIBS := cas ca gdd Com -#cas_DIR = $(INSTALL_LIB) -#ca_DIR = $(INSTALL_LIB) -#gdd_DIR = $(INSTALL_LIB) -#Com_DIR = $(INSTALL_LIB) - -# -# Added winmm user32 for the non-dll build -# -PROD_SYS_LIBS_WIN32 := ws2_32 advapi32 user32 - -caDirServ_SRCS += main.cc -caDirServ_SRCS += directoryServer.cc - -PROD_HOST = caDirServ - -CLEANS += caDirServ pcaDirServ Templates.DB core - -include $(TOP)/configure/RULES - -pcaDirServ: $(PRODUCT_OBJS) $(PROD_RESS) $(PROD_DEPLIBS) - $(PURIFY_$(OS_CLASS)) $(LINK.cpp) - diff --git a/src/ca/legacy/pcas/example/directoryService/README b/src/ca/legacy/pcas/example/directoryService/README deleted file mode 100644 index 73c50df2d..000000000 --- a/src/ca/legacy/pcas/example/directoryService/README +++ /dev/null @@ -1,13 +0,0 @@ - -This directory contains an example ca directory (name resolution) server. - -The directory server reads in a file with records as follows: - [] - -The server responds to search requests with the server address of -the PV (not the address of this directory server). - -This server can be used to cause EPICS to locate any PV listed in -the file anywhere on the internet. You must of course set EPICS_CA_ADDR_LIST -for the client so that it points at a running instance of this directory -(name resolution) server. \ No newline at end of file diff --git a/src/ca/legacy/pcas/example/directoryService/directoryServer.cc b/src/ca/legacy/pcas/example/directoryService/directoryServer.cc deleted file mode 100644 index 4d43b0943..000000000 --- a/src/ca/legacy/pcas/example/directoryService/directoryServer.cc +++ /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. -\*************************************************************************/ - -// -// Example EPICS CA directory server -// - -#include "directoryServer.h" -#include "epicsAlgorithm.h" - -const pvInfo *pvInfo::pFirst; - -// -// directoryServer::directoryServer() -// -directoryServer::directoryServer(const char * const pvPrefix, unsigned aliasCount) -{ - unsigned i; - const pvInfo *pPVI; - char pvAlias[256]; - const char * const pNameFmtStr = "%.100s%.20s"; - const char * const pAliasFmtStr = "%.100s%.20s%u"; - - // - // pre-create all of the simple PVs that this server will export - // - for (pPVI = pvInfo::getFirst(); pPVI; pPVI=pPVI->getNext()) { - - // - // Install canonical (root) name - // - sprintf(pvAlias, pNameFmtStr, pvPrefix, pPVI->getName()); - this->installAliasName(*pPVI, pvAlias); - - // - // Install numbered alias names - // - for (i=0u; igetName(), i); - this->installAliasName(*pPVI, pvAlias); - } - } -} - - -// -// directoryServer::~directoryServer() -// -directoryServer::~directoryServer() -{ -} - -// -// directoryServer::installAliasName() -// -void directoryServer::installAliasName(const pvInfo &info, const char *pAliasName) -{ - pvEntry *pEntry; - - pEntry = new pvEntry(info, *this, pAliasName); - if (pEntry) { - int resLibStatus; - resLibStatus = this->stringResTbl.add(*pEntry); - if (resLibStatus==0) { - return; - } - else { - delete pEntry; - } - } - fprintf(stderr, -"Unable to enter PV=\"%s\" Alias=\"%s\" in PV name alias hash table\n", - info.getName(), pAliasName); -} - -// -// More advanced pvExistTest() isnt needed so we forward to -// original version. This avoids sun pro warnings and speeds -// up execution. -// -pvExistReturn directoryServer::pvExistTest - ( const casCtx & ctx, const caNetAddr &, const char * pPVName ) -{ - return this->pvExistTest ( ctx, pPVName ); -} - -// -// directoryServer::pvExistTest() -// -pvExistReturn directoryServer::pvExistTest - ( const casCtx & /* ctx */, const char * pPVName ) -{ - // - // lifetime of id is shorter than lifetime of pName - // - char pvNameBuf[512]; - stringId id(pPVName, stringId::refString); - stringId idBuf(pvNameBuf, stringId::refString); - pvEntry *pPVE; - const char *pStr, *pLastStr; - - // - // strip trailing occurrence of ".field" - // (for compatibility with EPICS - // function block database). - // - pLastStr = pPVName; - pStr = strstr (pPVName, "."); - while (pStr) { - pLastStr = pStr; - pStr += 1; - pStr = strstr (pStr, "."); - } - - if (pLastStr==pPVName) { - pPVE = this->stringResTbl.lookup(id); - if (!pPVE) { - return pverDoesNotExistHere; - } - } - else { - size_t diff = pLastStr-pPVName; - diff = epicsMin (diff, sizeof(pvNameBuf)-1); - memcpy (pvNameBuf, pPVName, diff); - pvNameBuf[diff] = '\0'; - pLastStr = pvNameBuf; - pPVE = this->stringResTbl.lookup(idBuf); - if (!pPVE) { - // - // look for entire PV name (in case this PV isnt - // associated a function block database) - // - // lifetime of id2 is shorter than lifetime of pName - // - pPVE = this->stringResTbl.lookup(id); - if (!pPVE) { - return pverDoesNotExistHere; - } - } - } - - return pvExistReturn (caNetAddr(pPVE->getInfo().getAddr())); -} - -// -// directoryServer::show() -// -void directoryServer::show (unsigned level) const -{ - // - // server tool specific show code goes here - // - this->stringResTbl.show(level); - - // - // print information about ca server libarary - // internals - // - this->caServer::show(level); -} - diff --git a/src/ca/legacy/pcas/example/directoryService/directoryServer.h b/src/ca/legacy/pcas/example/directoryService/directoryServer.h deleted file mode 100644 index 9315c6af7..000000000 --- a/src/ca/legacy/pcas/example/directoryService/directoryServer.h +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// Example EPICS CA directory server -// -// -// caServer -// | -// directoryServer -// -// - - -// -// ANSI C -// -#include -#include - -// -// EPICS -// -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" -#define caNetAddrSock -#include "casdef.h" -#include "epicsAssert.h" -#include "resourceLib.h" - - -#ifndef NELEMENTS -# define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) -#endif - -class directoryServer; - -// -// pvInfo -// -class pvInfo { -public: - pvInfo (const char *pNameIn, sockaddr_in addrIn) : - addr(addrIn), pNext(pvInfo::pFirst) - { - pvInfo::pFirst = this; - this->pName = new char [strlen(pNameIn)+1u]; - strcpy(this->pName, pNameIn); - } - - const struct sockaddr_in getAddr() const { return this->addr; } - const char *getName () const { return this->pName; } - const pvInfo *getNext () const { return this->pNext; } - static const pvInfo *getFirst () { return pvInfo::pFirst; } -private: - struct sockaddr_in addr; - char * pName; - const pvInfo * pNext; - static const pvInfo * pFirst; -}; - -// -// pvEntry -// -// o entry in the string hash table for the pvInfo -// o Since there may be aliases then we may end up -// with several of this class all referencing -// the same pv info class (justification -// for this breaking out into a seperate class -// from pvInfo) -// -class pvEntry - : public stringId, public tsSLNode { -public: - pvEntry (const pvInfo &infoIn, directoryServer &casIn, - const char *pAliasName) : - stringId(pAliasName), info(infoIn), cas(casIn) - { - assert(this->stringId::resourceName()!=NULL); - } - - inline ~pvEntry(); - - const pvInfo &getInfo() const { return this->info; } - - inline void destroy (); - -private: - const pvInfo &info; - directoryServer &cas; -}; - -// -// directoryServer -// -class directoryServer : public caServer { -public: - directoryServer ( const char * const pvPrefix, unsigned aliasCount ); - ~directoryServer(); - void show ( unsigned level ) const; - - void installAliasName ( const pvInfo &info, const char *pAliasName ); - void removeAliasName ( pvEntry &entry ); - -private: - resTable < pvEntry, stringId > stringResTbl; - - pvExistReturn pvExistTest ( const casCtx&, - const char *pPVName ); - pvExistReturn pvExistTest ( const casCtx&, - const caNetAddr &, const char *pPVName ); -}; - - -// -// directoryServer::removeAliasName() -// -inline void directoryServer::removeAliasName ( pvEntry & entry ) -{ - pvEntry * pE = this->stringResTbl.remove ( entry ); - assert ( pE == & entry ); -} - -// -// pvEntry::~pvEntry() -// -inline pvEntry::~pvEntry() -{ - this->cas.removeAliasName(*this); -} - -// -// pvEntry::destroy() -// -inline void pvEntry::destroy () -{ - // - // always created with new - // - delete this; -} - diff --git a/src/ca/legacy/pcas/example/directoryService/main.cc b/src/ca/legacy/pcas/example/directoryService/main.cc deleted file mode 100644 index 76f27e75d..000000000 --- a/src/ca/legacy/pcas/example/directoryService/main.cc +++ /dev/null @@ -1,209 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "errlog.h" - -#include "directoryServer.h" -#include "fdManager.h" - -static int parseDirectoryFile (const char *pFileName); -static int parseDirectoryFP (FILE *pf, const char *pFileName); - -#ifndef INADDR_NONE -#define INADDR_NONE (~0ul) -#endif - -// -// main() -// (example single threaded ca server tool main loop) -// -extern int main ( int argc, const char **argv ) -{ - epicsTime begin ( epicsTime::getCurrent() ); - directoryServer *pCAS; - unsigned debugLevel = 0u; - double executionTime = 0.0; - char pvPrefix[128] = ""; - char fileName[128] = "pvDirectory.txt"; - unsigned aliasCount = 0u; - bool forever = true; - int nPV; - int i; - - for (i=1; i -t -p -c -f]\n", - argv[0]); - - return (1); - } - - nPV = parseDirectoryFile (fileName); - if (nPV<=0) { - fprintf(stderr, -"No PVs in directory file=%s. Exiting because there is no useful work to do.\n", - fileName); - return (-1); - } - - try { - pCAS = new directoryServer(pvPrefix, aliasCount); - if (!pCAS) { - return (-1); - } - } - catch ( ... ) { - errlogPrintf ( "Unable to create a directory service\n" ); - exit ( -1 ); - } - - pCAS->setDebugLevel(debugLevel); - - if (forever) { - // - // loop here forever - // - while (true) { - fileDescriptorManager.process (1000.0); - } - } - else { - double delay = epicsTime::getCurrent() - begin; - // - // loop here untime the specified execution time - // expires - // - while (delay < executionTime) { - fileDescriptorManager.process (delay); - delay = epicsTime::getCurrent() - begin; - } - } - pCAS->show(2u); - delete pCAS; - return (0); -} - -// -// parseDirectoryFile() -// -// PV directory file is expected to have entries of the form: -// [] -// -// -static int parseDirectoryFile (const char *pFileName) -{ - - FILE *pf; - int nPV; - - // - // open a file that contains the PV directory - // - pf = fopen(pFileName, "r"); - if (!pf) { - fprintf(stderr, "Directory file access probems with file=\"%s\" because \"%s\"\n", - pFileName, strerror(errno)); - return (-1); - } - - nPV = parseDirectoryFP (pf, pFileName); - - fclose (pf); - - return nPV; -} - -// -// parseDirectoryFP() -// -// PV directory file is expected to have entries of the form: -// [] -// -// -static int parseDirectoryFP (FILE *pf, const char *pFileName) -{ - pvInfo *pPVI; - char pvNameStr[128]; - struct sockaddr_in ipa; - char hostNameStr[128]; - int nPV=0; - - ipa.sin_family = AF_INET; - while ( true ) { - - // - // parse the PV name entry from the file - // - if (fscanf(pf, " %127s ", pvNameStr) != 1) { - return nPV; // success - } - - // - // parse out server address - // - if (fscanf(pf, " %s ", hostNameStr) == 1) { - int status; - - status = aToIPAddr (hostNameStr, 0u, &ipa); - if (status) { - fprintf (stderr, "Unknown host name=\"%s\" (or bad dotted ip addr) in \"%s\" with PV=\"%s\"?\n", - hostNameStr, pFileName, pvNameStr); - return -1; - } - } - else { - fprintf (stderr,"No host name (or dotted ip addr) after PV name in \"%s\" with PV=\"%s\"?\n", - pFileName, pvNameStr); - return -1; - } - - // - // parse out optional IP port number - // - unsigned portNumber; - if (fscanf(pf, " %u ", &portNumber) == 1) { - if (portNumber>0xffff) { - fprintf (stderr,"Port number supplied is to large in \"%s\" with PV=\"%s\" host=\"%s\" port=%u?\n", - pFileName, pvNameStr, hostNameStr, portNumber); - return -1; - } - - ipa.sin_port = htons((aitUint16) portNumber); - } - else { - ipa.sin_port = 0u; // use the default CA server port - } - - pPVI = new pvInfo ( pvNameStr, ipa ); - if ( ! pPVI ) { - fprintf (stderr, "Unable to allocate space for a new PV in \"%s\" with PV=\"%s\" host=\"%s\"\n", - pFileName, pvNameStr, hostNameStr); - return -1; - } - nPV++; - } -} diff --git a/src/ca/legacy/pcas/example/directoryService/pvDirectory.txt b/src/ca/legacy/pcas/example/directoryService/pvDirectory.txt deleted file mode 100644 index c76b9d023..000000000 --- a/src/ca/legacy/pcas/example/directoryService/pvDirectory.txt +++ /dev/null @@ -1,5 +0,0 @@ - -ca:ai_2000 myIOC.myLAB.org 22000 -ca:ai_2001 1.1.1.1 22000 -ca:ao_2000 myIOC -ca:ao_2001 1.1.1.1 diff --git a/src/ca/legacy/pcas/example/directoryService/test.adl b/src/ca/legacy/pcas/example/directoryService/test.adl deleted file mode 100644 index 6086a3be5..000000000 --- a/src/ca/legacy/pcas/example/directoryService/test.adl +++ /dev/null @@ -1,844 +0,0 @@ -file { - name="test.dl" -} -display { - magic="305419896" - majv="2" - mnrv="4" - ndyng="0" - npc="5" - nstr="8" - ndynamic="12" - nplot="0" - nrd="0" - nes="0" - nkd="0" - object { - x="0" - y="0" - width="421" - height="306" - } - clr="0" - bclr="1" - nwords_dspy="1106" - nwords_sta="28" - nwords_cmap="36" - nwords_crules="106" - odyng="306" - osta="278" - odynamic="306" - oplot="1106" - ord="1106" - oes="1106" - okd="1106" - opc="58" - ostr="88" - ocmap="136" - ocrules="172" - style="solid" - fill="outline" - width="0" - clrmod="static" - vismod="static" - clrrule="alarm" - pv="" - cmap="" -} -"<>" { - ncolors="8" - dl_color { - r="255" - g="255" - b="255" - inten="255" - blink="off" - RISCpad="128" - } - dl_color { - r="0" - g="0" - b="0" - inten="0" - blink="off" - RISCpad="75" - } - dl_color { - r="255" - g="0" - b="0" - inten="255" - blink="off" - RISCpad="-14684" - } - dl_color { - r="255" - g="0" - b="0" - inten="255" - blink="on" - RISCpad="14744" - } - dl_color { - r="255" - g="255" - b="0" - inten="255" - blink="off" - RISCpad="-16536" - } - dl_color { - r="255" - g="255" - b="0" - inten="255" - blink="on" - RISCpad="-15536" - } - dl_color { - r="0" - g="0" - b="255" - inten="255" - blink="off" - RISCpad="-28408" - } - dl_color { - r="0" - g="0" - b="255" - inten="255" - blink="on" - RISCpad="0" - } -} -"<>" { - nrules="1" - dl_color_rule { - name="alarm" - info[0] { - chan="$(C).SEVR" - value="MAJOR" - connector="use" - comparator="equals" - clr="2" - RISCpad="0" - } - info[1] { - chan="$(C).SEVR" - value="MINOR" - connector="use" - comparator="equals" - clr="4" - RISCpad="127" - } - info[2] { - chan="$(C).SEVR" - value="INFO" - connector="use" - comparator="equals" - clr="6" - RISCpad="44" - } - info[3] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-128" - } - info[4] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-1" - } - info[5] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-104" - } - info[6] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-1" - } - info[7] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="8" - } - info[8] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="120" - } - info[9] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="1" - } - info[10] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="7" - } - info[11] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="19" - } - info[12] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="48" - } - info[13] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="28" - } - info[14] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-88" - } - info[15] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="0" - } - fg_enable="on" - bg_enable="on" - default_fg="0" - default_bg="1" - } -} -"<>" { - attr { - clr="0" - style="solid" - fill="outline" - width="0" - } -} -"text" { - object { - x="44" - y="16" - width="104" - height="14" - groupid="0" - } - textix="Sync" - align="horiz. left" - RISC_pad="0" -} -"text" { - object { - x="260" - y="13" - width="92" - height="17" - groupid="0" - } - textix="Async" - align="horiz. left" - RISC_pad="0" -} -"indicator" { - object { - x="15" - y="88" - width="170" - height="22" - groupid="0" - } - monitor { - chan="fred" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - RISC_pad="0" -} -"text update" { - object { - x="16" - y="133" - width="169" - height="17" - groupid="0" - } - monitor { - chan="fred" - clr="0" - bclr="1" - label="none" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="append" - decorate="none" - convertFunc="" - convertParams="" - } - align="horiz. left" - format="decimal" -} -"valuator" { - object { - x="15" - y="43" - width="168" - height="26" - groupid="0" - } - control { - chan="fred" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - gain="coarse" - sendMode="send on motion" - increment="0" -} -"indicator" { - object { - x="215" - y="81" - width="170" - height="30" - groupid="0" - } - monitor { - chan="freddy" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - RISC_pad="0" -} -"text update" { - object { - x="216" - y="133" - width="171" - height="18" - groupid="0" - } - monitor { - chan="freddy" - clr="0" - bclr="1" - label="none" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="append" - decorate="none" - convertFunc="" - convertParams="" - } - align="horiz. left" - format="decimal" -} -"valuator" { - object { - x="215" - y="43" - width="168" - height="28" - groupid="0" - } - control { - chan="freddy" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - gain="coarse" - sendMode="send on motion" - increment="0" -} -"indicator" { - object { - x="16" - y="225" - width="171" - height="19" - groupid="0" - } - monitor { - chan="jane" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - RISC_pad="0" -} -"text update" { - object { - x="17" - y="259" - width="170" - height="20" - groupid="0" - } - monitor { - chan="jane" - clr="0" - bclr="1" - label="none" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="append" - decorate="none" - convertFunc="" - convertParams="" - } - align="horiz. left" - format="decimal" -} -"valuator" { - object { - x="15" - y="187" - width="170" - height="19" - groupid="0" - } - control { - chan="jane" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - gain="coarse" - sendMode="send on motion" - increment="0" -} -"indicator" { - object { - x="219" - y="218" - width="173" - height="23" - groupid="0" - } - monitor { - chan="janet" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - RISC_pad="0" -} -"text update" { - object { - x="220" - y="257" - width="174" - height="20" - groupid="0" - } - monitor { - chan="janet" - clr="0" - bclr="1" - label="none" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="append" - decorate="none" - convertFunc="" - convertParams="" - } - align="horiz. left" - format="decimal" -} -"valuator" { - object { - x="219" - y="188" - width="171" - height="21" - groupid="0" - } - control { - chan="janet" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - gain="coarse" - sendMode="send on motion" - increment="0" -} diff --git a/src/ca/legacy/pcas/example/directoryService/vxEntry.cc b/src/ca/legacy/pcas/example/directoryService/vxEntry.cc deleted file mode 100644 index 1cb240723..000000000 --- a/src/ca/legacy/pcas/example/directoryService/vxEntry.cc +++ /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 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 (LANL) -// - -#include -#include - -#include "exServer.h" - -// -// so we can call this from the vxWorks shell -// -extern "C" { - -exServer *pExampleCAS; - -// -// excas () -// (vxWorks example server entry point) -// -int excas (unsigned debugLevel, unsigned delaySec) -{ - epicsTime begin(epicsTime::getCurrent()); - exServer *pCAS; - - pCAS = new exServer(32u,5u,500u); - if (!pCAS) { - return (-1); - } - - pCAS->setDebugLevel(debugLevel); - pExampleCAS = pCAS; - - if (delaySec==0u) { - // - // loop here forever - // - while (1) { - taskDelay(10); - } - } - else { - epicsTime total( ((float)delaySec) ); - epicsTime delay(epicsTime::getCurrent() - begin); - // - // loop here untill the specified execution time - // expires - // - while (delay < total) { - taskDelay(10); - delay = epicsTime::getCurrent() - begin; - } - } - pCAS->show(debugLevel); - pExampleCAS = NULL; - delete pCAS; - return 0; -} - -int excasShow(unsigned level) -{ - if (pExampleCAS!=NULL) { - pExampleCAS->show(level); - } - return 0; -} - -} // extern "C" - diff --git a/src/ca/legacy/pcas/generic/README b/src/ca/legacy/pcas/generic/README deleted file mode 100644 index 15366fee5..000000000 --- a/src/ca/legacy/pcas/generic/README +++ /dev/null @@ -1,43 +0,0 @@ - - -This directory contains the generic (os and io independent) source for -the EPICS ca server library - -The sub-diretory "mt" contains multi-threaded specific code and the -sub-directory "st" contains single-threaded specific code. - -Design Notes: -1) When I was preparing a thread-safe version of the server lib I assumed -that all locking required to protect gdd::reference() and gdd::unreference() -will be provided by the gdd library. - -2) The source file "templInst.cc" attempts to provide explicit instantiation -of the template member functions required following the ANSI resolution -r.14.9 in appendix A of Stroustrup's book. The problem is that Sun's -compiler does not recognize this syntax so we must "ifdef" the code until -this matter is resolved. - -Here are some of the inheritance trees used by the server lib: - - casCoreClient - | - | -inBuf outBuf casClient dgInBuf dgOutBuf -| | ________|_______ | | -| | | | | | -|___casStrmClient casDGClient______| - | | - | | - casStreamIO casDGIO - | | - | | - casStreamOS casDGOS - - - casDGIntfIO casIntfIO - | | - | | - casDGIntfOS casIntfOS - - - diff --git a/src/ca/legacy/pcas/generic/beaconAnomalyGovernor.cc b/src/ca/legacy/pcas/generic/beaconAnomalyGovernor.cc deleted file mode 100644 index df22e5301..000000000 --- a/src/ca/legacy/pcas/generic/beaconAnomalyGovernor.cc +++ /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 "fdManager.h" - -#define epicsExportSharedSymbols -#include "caServerI.h" -#include "beaconAnomalyGovernor.h" -#include "beaconTimer.h" - -// -// the minimum period between beacon anomalies -// ------------------------------------------- -// -// o Gateways imply a tradeoff towards less traffic while -// paying a price of a less tightly coupled environment. -// Therefore, clients should not expect instant reconnects -// when a server is rebooted on the other side of a gateway. -// -// o In a quiescent system servers should not need to be -// rebooted and network connectivity should be constant. -// -// o Clients will keep trying to reach channels for around -// 15 min after the last beacon anomaly was seen. -// -// o The exponential backoff mechanism in the beacon timer -// ensures that clients will detect beacon anomalies -// continuously for around 30 seconds after each beacon -// anomaly is requested. -// -static const double CAServerMinBeaconAnomalyPeriod = 60.0 * 5.0; // seconds - -beaconAnomalyGovernor::beaconAnomalyGovernor ( caServerI & casIn ) : - timer ( fileDescriptorManager.createTimer () ), cas ( casIn ), - anomalyPending ( false ) -{ -} - -beaconAnomalyGovernor::~beaconAnomalyGovernor() -{ -} - -void beaconAnomalyGovernor::start () -{ - // order of operations here impacts thread safety - this->anomalyPending = true; - epicsTimer::expireInfo expInfo = this->timer.getExpireInfo (); - if ( ! expInfo.active ) { - this->cas.beaconTmr.generateBeaconAnomaly (); - this->timer.start ( *this, CAServerMinBeaconAnomalyPeriod ); - this->anomalyPending = false; - } -} - -epicsTimerNotify::expireStatus beaconAnomalyGovernor::expire ( const epicsTime & ) -{ - if ( this->anomalyPending ) { - this->anomalyPending = false; - this->cas.beaconTmr.generateBeaconAnomaly (); - } - return noRestart; -} - -void beaconAnomalyGovernor::show ( unsigned level ) const -{ - printf ( "beaconAnomalyGovernor: anomalyPending = %s\n", - this->anomalyPending ? "T": "F" ); - if ( level ) { - this->timer.show ( level - 1 ); - } -} diff --git a/src/ca/legacy/pcas/generic/beaconAnomalyGovernor.h b/src/ca/legacy/pcas/generic/beaconAnomalyGovernor.h deleted file mode 100644 index cb520b6f1..000000000 --- a/src/ca/legacy/pcas/generic/beaconAnomalyGovernor.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 - * 505 665 1831 - */ - -#ifndef beaconAnomalyGovernorh -#define beaconAnomalyGovernorh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_beaconAnomalyGovernorh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "epicsTimer.h" -#include "epicsMutex.h" - -#ifdef epicsExportSharedSymbols_beaconAnomalyGovernorh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class caServerI; - -class beaconAnomalyGovernor : public epicsTimerNotify { -public: - beaconAnomalyGovernor ( caServerI & ); - virtual ~beaconAnomalyGovernor(); - void start (); - void show ( unsigned level ) const; -private: - // has been checked for thread safety - epicsTimer & timer; - class caServerI & cas; - bool anomalyPending; - expireStatus expire( const epicsTime & currentTime ); - beaconAnomalyGovernor ( const beaconAnomalyGovernor & ); - beaconAnomalyGovernor & operator = ( const beaconAnomalyGovernor & ); -}; - -#endif // ifdef beaconAnomalyGovernorh - diff --git a/src/ca/legacy/pcas/generic/beaconTimer.cc b/src/ca/legacy/pcas/generic/beaconTimer.cc deleted file mode 100644 index 71124fac6..000000000 --- a/src/ca/legacy/pcas/generic/beaconTimer.cc +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include "fdManager.h" -#include "envDefs.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "caServerI.h" -#include "beaconTimer.h" - -// the maximum beacon period if EPICS_CA_BEACON_PERIOD isnt available -static const double CAServerMaxBeaconPeriod = 15.0; // seconds - -// the initial beacon period -static const double CAServerMinBeaconPeriod = 1.0e-3; // seconds - -beaconTimer::beaconTimer ( caServerI & casIn ) : - timer ( fileDescriptorManager.createTimer() ), - cas ( casIn ), - beaconPeriod ( CAServerMinBeaconPeriod ), - maxBeaconInterval ( CAServerMaxBeaconPeriod ), - beaconCounter ( 0U ) -{ - caStatus status; - double maxPeriod; - - if ( envGetConfigParamPtr ( & EPICS_CAS_BEACON_PERIOD ) ) { - status = envGetDoubleConfigParam ( & EPICS_CAS_BEACON_PERIOD, & maxPeriod ); - } - else { - status = envGetDoubleConfigParam ( & EPICS_CA_BEACON_PERIOD, & maxPeriod ); - } - if ( status || maxPeriod <= 0.0 ) { - errlogPrintf ( - "EPICS \"%s\" float fetch failed\n", EPICS_CAS_BEACON_PERIOD.name ); - errlogPrintf ( - "Setting \"%s\" = %f\n", EPICS_CAS_BEACON_PERIOD.name, - this->maxBeaconInterval); - } - else { - this->maxBeaconInterval = maxPeriod; - } - - this->timer.start ( *this, CAServerMinBeaconPeriod ); -} - -beaconTimer::~beaconTimer () -{ - this->timer.destroy (); -} - -void beaconTimer::generateBeaconAnomaly () -{ - this->beaconPeriod = CAServerMinBeaconPeriod; - this->timer.start ( *this, CAServerMinBeaconPeriod ); -} - - -epicsTimerNotify::expireStatus beaconTimer::expire( const epicsTime & /* currentTime */ ) -{ - this->cas.sendBeacon ( this->beaconCounter ); - - this->beaconCounter++; - - // double the period between beacons (but dont exceed max) - if ( this->beaconPeriod < this->maxBeaconInterval ) { - this->beaconPeriod += this->beaconPeriod; - - if ( this->beaconPeriod >= this->maxBeaconInterval ) { - this->beaconPeriod = this->maxBeaconInterval; - } - } - - return expireStatus ( restart, this->beaconPeriod ); -} - diff --git a/src/ca/legacy/pcas/generic/beaconTimer.h b/src/ca/legacy/pcas/generic/beaconTimer.h deleted file mode 100644 index 7b6a5654c..000000000 --- a/src/ca/legacy/pcas/generic/beaconTimer.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 Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef beaconTimerh -#define beaconTimerh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_beaconTimerh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "epicsTimer.h" -#include "caProto.h" - -#ifdef epicsExportSharedSymbols_beaconTimerh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class caServerI; - -class beaconTimer : public epicsTimerNotify { -public: - beaconTimer ( caServerI & casIn ); - virtual ~beaconTimer (); - void generateBeaconAnomaly (); -private: - // has been checked for thread safety - epicsTimer & timer; - caServerI & cas; - double beaconPeriod; - double maxBeaconInterval; - ca_uint32_t beaconCounter; - expireStatus expire ( const epicsTime & currentTime ); - beaconTimer ( const beaconTimer & ); - beaconTimer & operator = ( const beaconTimer & ); -}; - -#endif // ifdef beaconTimerh - diff --git a/src/ca/legacy/pcas/generic/caHdrLargeArray.h b/src/ca/legacy/pcas/generic/caHdrLargeArray.h deleted file mode 100644 index 7bda002e9..000000000 --- a/src/ca/legacy/pcas/generic/caHdrLargeArray.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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef caHdrLargeArrayh -#define caHdrLargeArrayh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_caHdrLargeArrayh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "caProto.h" - -#ifdef epicsExportSharedSymbols_caHdrLargeArrayh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -static const unsigned char CA_MINOR_PROTOCOL_REVISION = 13; - -typedef ca_uint32_t caResId; - -/* 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 */ -}; - -#endif // caHdrLargeArrayh diff --git a/src/ca/legacy/pcas/generic/caNetAddr.cc b/src/ca/legacy/pcas/generic/caNetAddr.cc deleted file mode 100644 index 0c831be88..000000000 --- a/src/ca/legacy/pcas/generic/caNetAddr.cc +++ /dev/null @@ -1,197 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 epicsExportSharedSymbols -#define caNetAddrSock -#include "caNetAddr.h" - -static class caNetAddrSelfTest { -public: - caNetAddrSelfTest (); -} caNetAddrSelfTestDuringLoad; - -// -// caNetAddr::stringConvert () -// -void caNetAddr::stringConvert ( char *pString, unsigned stringLength ) const -{ - if ( this->type == casnaInet ) { - ipAddrToA (&this->addr.ip, pString, stringLength); - return; - } - if ( stringLength ) { - strncpy ( pString, "", stringLength ); - pString[stringLength-1] = '\n'; - } -} - -// -// caNetAddr::clear() -// -void caNetAddr::clear () -{ - this->type = casnaUDF; -} - -// -// caNetAddr::caNetAddr() -// -caNetAddr::caNetAddr () -{ - this->clear(); -} - -bool caNetAddr::isInet () const -{ - return this->type == casnaInet; -} - -bool caNetAddr::isValid () const -{ - return this->type != casnaUDF; -} - -bool caNetAddr::operator == (const caNetAddr &rhs) const -{ - if ( this->type != rhs.type ) { - return false; - } - if ( this->type == casnaInet ) { - return ( this->addr.ip.sin_addr.s_addr == rhs.addr.ip.sin_addr.s_addr ) && - ( this->addr.ip.sin_port == rhs.addr.ip.sin_port ); - } - else { - return false; - } -} - -bool caNetAddr::operator != ( const caNetAddr & rhs ) const -{ - return ! this->operator == (rhs); -} - -// -// This is specified so that compilers will not use one of -// the following assignment operators after converting to a -// sockaddr_in or a sockaddr first. -// -// caNetAddr caNetAddr::operator =(const struct sockaddr_in&) -// caNetAddr caNetAddr::operator =(const struct sockaddr&) -// -caNetAddr caNetAddr::operator = ( const caNetAddr &naIn ) -{ - this->addr = naIn.addr; - this->type = naIn.type; - return *this; -} - -void caNetAddr::setSockIP ( unsigned long inaIn, unsigned short portIn ) -{ - this->type = casnaInet; - this->addr.ip.sin_family = AF_INET; - this->addr.ip.sin_addr.s_addr = inaIn; - this->addr.ip.sin_port = portIn; -} - -void caNetAddr::setSockIP ( const struct sockaddr_in & sockIPIn ) -{ - if ( sockIPIn.sin_family != AF_INET ) { - throw std::logic_error ( "caNetAddr::setSockIP (): address wasnt IP" ); - } - this->type = casnaInet; - this->addr.ip = sockIPIn; -} - -void caNetAddr::setSock ( const struct sockaddr & sock ) -{ - if ( sock.sa_family != AF_INET ) { - throw std::logic_error ( "caNetAddr::setSock (): address wasnt IP" ); - } - this->type = casnaInet; - const struct sockaddr_in *psip = - reinterpret_cast ( & sock ); - this->addr.ip = *psip; -} - -caNetAddr::caNetAddr ( const struct sockaddr_in & sockIPIn ) -{ - this->setSockIP ( sockIPIn ); -} - -caNetAddr caNetAddr::operator = ( const struct sockaddr_in & sockIPIn ) -{ - this->setSockIP ( sockIPIn ); - return *this; -} - -caNetAddr caNetAddr::operator = ( const struct sockaddr & sockIn ) -{ - this->setSock (sockIn); - return *this; -} - -struct sockaddr_in caNetAddr::getSockIP() const -{ - if ( this->type != casnaInet ) { - throw std::logic_error ( "caNetAddr::getSockIP (): address wasnt IP" ); - } - return this->addr.ip; -} - -struct sockaddr caNetAddr::getSock() const -{ - if ( this->type != casnaInet ) { - throw std::logic_error ( "caNetAddr::getSock (): address wasnt IP" ); - } - - osiSockAddr addr; - addr.ia = this->addr.ip; - return addr.sa; -} - -caNetAddr::operator sockaddr_in () const -{ - return this->getSockIP (); -} - -caNetAddr::operator sockaddr () const -{ - return this->getSock (); -} - -void caNetAddr::selfTest () -{ - // the dummy field must be greater than or equal to the size of - // each of the other entries in the union - if ( sizeof ( this->addr ) != sizeof ( this->addr.pad ) ) { - fprintf ( stderr, "caNetAddr::selfTest ():self test failed in %s at line %d\n", - __FILE__, __LINE__ ); - throw std::logic_error ( "caNetAddr::selfTest (): failed self test" ); - } -} - -caNetAddrSelfTest::caNetAddrSelfTest () -{ - caNetAddr tmp; - tmp.selfTest (); -} - - diff --git a/src/ca/legacy/pcas/generic/caNetAddr.h b/src/ca/legacy/pcas/generic/caNetAddr.h deleted file mode 100644 index 01dc6c3ba..000000000 --- a/src/ca/legacy/pcas/generic/caNetAddr.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. -\*************************************************************************/ -// -// caNetAddr -// -// special cas specific network address class so: -// 1) we dont drag BSD socket headers into the server tool -// 2) we are not prevented from using other networking services -// besides sockets in the future -// - -#ifndef caNetAddrH -#define caNetAddrH - -#ifdef caNetAddrSock -# ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_caNetAddrH -# undef epicsExportSharedSymbols -# endif -# include "osiSock.h" -# ifdef epicsExportSharedSymbols_caNetAddrH -# define epicsExportSharedSymbols -# include "shareLib.h" -# endif -#else -# include "shareLib.h" -#endif - -class epicsShareClass caNetAddr { -public: - void clear (); - caNetAddr (); - bool isValid () const; - bool operator == ( const caNetAddr & rhs ) const; - bool operator != ( const caNetAddr & rhs) const; - caNetAddr operator = ( const caNetAddr & naIn ); - void stringConvert ( char *pString, unsigned stringLength ) const; - void selfTest (); - - // support for socket addresses - // (other address formats may be supported in the future) - bool isInet () const; - void setSockIP ( unsigned long inaIn, unsigned short portIn ); - void setSockIP ( const struct sockaddr_in & sockIPIn ); - void setSock ( const struct sockaddr & sock ); - caNetAddr ( const struct sockaddr_in & sockIPIn ); - caNetAddr operator = ( const struct sockaddr & sockIn ); - caNetAddr operator = ( const struct sockaddr_in & sockIPIn ); - struct sockaddr getSock() const; - struct sockaddr_in getSockIP() const; - operator struct sockaddr () const; - operator struct sockaddr_in () const; - -private: - enum caNetAddrType { casnaUDF, casnaInet } type; - union { - unsigned char pad[16]; -# ifdef caNetAddrSock - struct sockaddr_in ip; -# endif - } addr; -}; - -#endif // caNetAddrH diff --git a/src/ca/legacy/pcas/generic/caServer.cc b/src/ca/legacy/pcas/generic/caServer.cc deleted file mode 100644 index f992eb56d..000000000 --- a/src/ca/legacy/pcas/generic/caServer.cc +++ /dev/null @@ -1,182 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "dbMapper.h" // ait to dbr types -#include "gddAppTable.h" // EPICS application type table -#include "fdManager.h" - -#define epicsExportSharedSymbols -#include "casMonitor.h" -#include "caServerI.h" - -caServer::caServer () -{ - static bool init = false; - - if ( ! init ) { - gddMakeMapDBR(gddApplicationTypeTable::app_table); - init = true; - } - - this->pCAS = new caServerI ( *this ); -} - -caServer::~caServer() -{ - if (this->pCAS) { - delete this->pCAS; - this->pCAS = NULL; - } -} - -pvExistReturn caServer::pvExistTest ( const casCtx & ctx, - const caNetAddr & /* clientAddress */, const char * pPVAliasName ) -{ - return this->pvExistTest ( ctx, pPVAliasName ); -} - -pvExistReturn caServer::pvExistTest ( const casCtx &, const char * ) -{ - return pverDoesNotExistHere; -} - -pvCreateReturn caServer::createPV ( const casCtx &, const char * ) -{ - return S_casApp_pvNotFound; -} - -pvAttachReturn caServer::pvAttach ( const casCtx &ctx, const char *pAliasName ) -{ - // remain backwards compatible (call deprecated routine) - return this->createPV ( ctx, pAliasName ); -} - -casEventMask caServer::registerEvent (const char *pName) -{ - if (this->pCAS) { - return this->pCAS->registerEvent(pName); - } - else { - casEventMask emptyMask; - printf("caServer:: no server internals attached\n"); - return emptyMask; - } -} - -void caServer::show(unsigned level) const -{ - if (this->pCAS) { - this->pCAS->show(level); - } - else { - printf("caServer:: no server internals attached\n"); - } -} - -void caServer::setDebugLevel (unsigned level) -{ - if (pCAS) { - this->pCAS->setDebugLevel(level); - } - else { - printf("caServer:: no server internals attached\n"); - } -} - -unsigned caServer::getDebugLevel () const -{ - if (pCAS) { - return this->pCAS->getDebugLevel(); - } - else { - printf("caServer:: no server internals attached\n"); - return 0u; - } -} - -casEventMask caServer::valueEventMask () const -{ - if (pCAS) { - return this->pCAS->valueEventMask(); - } - else { - printf("caServer:: no server internals attached\n"); - return casEventMask(); - } -} - -casEventMask caServer::logEventMask () const -{ - if (pCAS) { - return this->pCAS->logEventMask(); - } - else { - printf("caServer:: no server internals attached\n"); - return casEventMask(); - } -} - -casEventMask caServer::alarmEventMask () const -{ - if ( pCAS ) { - return this->pCAS->alarmEventMask (); - } - else { - printf ( "caServer:: no server internals attached\n" ); - return casEventMask (); - } -} - -casEventMask caServer::propertyEventMask () const -{ - if (pCAS) { - return this->pCAS->propertyEventMask(); - } - else { - printf("caServer:: no server internals attached\n"); - return casEventMask(); - } -} - -class epicsTimer & caServer::createTimer () -{ - return fileDescriptorManager.createTimer (); -} - -unsigned caServer::subscriptionEventsProcessed () const -{ - if ( pCAS ) { - return this->pCAS->subscriptionEventsProcessed (); - } - else { - return 0u; - } -} - -unsigned caServer::subscriptionEventsPosted () const -{ - if ( pCAS ) { - return this->pCAS->subscriptionEventsPosted (); - } - else { - return 0u; - } -} - -void caServer::generateBeaconAnomaly () -{ - if ( pCAS ) { - this->pCAS->generateBeaconAnomaly (); - } -} diff --git a/src/ca/legacy/pcas/generic/caServerDefs.h b/src/ca/legacy/pcas/generic/caServerDefs.h deleted file mode 100644 index b1799528f..000000000 --- a/src/ca/legacy/pcas/generic/caServerDefs.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 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 caServerDefsh -#define caServerDefsh - -#ifndef NULL -# define NULL 0 -#endif - -#ifndef NELEMENTS -# define NELEMENTS(array) (sizeof(array)/sizeof((array)[0])) -#endif - -#define invalidResID ( static_cast < ca_uint32_t > ( ~0UL ) ) - -void casVerifyFunc ( const char * pFile, - unsigned line, const char * pExp ); -void serverToolDebugFunc ( const char * pFile, - unsigned line, const char * pComment ); -#define serverToolDebug(COMMENT) \ -{ serverToolDebugFunc(__FILE__, __LINE__, COMMENT); } -#define casVerify(EXP) \ -{ if ((EXP)==0) casVerifyFunc(__FILE__, __LINE__, #EXP); } - -#endif // caServerDefsh diff --git a/src/ca/legacy/pcas/generic/caServerI.cc b/src/ca/legacy/pcas/generic/caServerI.cc deleted file mode 100644 index e8609eb8a..000000000 --- a/src/ca/legacy/pcas/generic/caServerI.cc +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#include "epicsGuard.h" -#include "epicsVersion.h" -#include "errlog.h" - -#include "addrList.h" - -#define epicsExportSharedSymbols -#define caServerGlobal -#include "caServerI.h" -#include "beaconTimer.h" -#include "beaconAnomalyGovernor.h" -#include "casStreamOS.h" -#include "casIntfOS.h" - -// include a version string for POSIX systems -static const char pVersionCAS[] = - "@(#) " EPICS_VERSION_STRING - ", CA Portable Server Library "; - -caServerI::caServerI ( caServer & tool ) : - adapter (tool), - beaconTmr ( * new beaconTimer ( *this ) ), - beaconAnomalyGov ( * new beaconAnomalyGovernor ( *this ) ), - debugLevel ( 0u ), - nEventsProcessed ( 0u ), - nEventsPosted ( 0u ), - ioInProgressCount ( 0u ) -{ - assert ( & adapter != NULL ); - - // create predefined event types - this->valueEvent = registerEvent ( "value" ); - this->logEvent = registerEvent ( "log" ); - this->alarmEvent = registerEvent ( "alarm" ); - this->propertyEvent = registerEvent ( "property" ); - - this->locateInterfaces (); - - if (this->intfList.count()==0u) { - errMessage (S_cas_noInterface, - "- CA server internals init unable to continue"); - throw S_cas_noInterface; - } - - return; -} - -caServerI::~caServerI() -{ - delete & this->beaconAnomalyGov; - delete & this->beaconTmr; - - // delete all clients - while ( casStrmClient * pClient = this->clientList.get() ) { - delete pClient; - } - - casIntfOS *pIF; - while ( ( pIF = this->intfList.get() ) ) { - delete pIF; - } -} - -void caServerI::destroyClient ( casStrmClient & client ) -{ - { - epicsGuard < epicsMutex > locker ( this->mutex ); - this->clientList.remove ( client ); - } - delete & client; -} - -void caServerI::connectCB ( casIntfOS & intf ) -{ - casStreamOS * pClient = intf.newStreamClient ( *this, this->clientBufMemMgr ); - if ( pClient ) { - { - epicsGuard < epicsMutex > locker ( this->mutex ); - this->clientList.add ( *pClient ); - } - pClient->sendVersion (); - pClient->flush (); - } -} - -void casVerifyFunc ( const char * pFile, unsigned line, const char * pExp ) -{ - fprintf(stderr, "the expression \"%s\" didnt evaluate to boolean true \n", - pExp); - fprintf(stderr, - "and therefore internal problems are suspected at line %u in \"%s\"\n", - line, pFile); - fprintf(stderr, - "Please forward above text to johill@lanl.gov - thanks\n"); -} - -void serverToolDebugFunc (const char *pFile, unsigned line, const char *pComment) -{ - fprintf (stderr, -"Bad server tool response detected at line %u in \"%s\" because \"%s\"\n", - line, pFile, pComment); -} - -caStatus caServerI::attachInterface ( const caNetAddr & addrIn, - bool autoBeaconAddr, bool addConfigBeaconAddr) -{ - try { - casIntfOS * pIntf = new casIntfOS ( *this, this->clientBufMemMgr, - addrIn, autoBeaconAddr, addConfigBeaconAddr ); - - { - epicsGuard < epicsMutex > locker ( this->mutex ); - this->intfList.add ( *pIntf ); - } - } - catch ( ... ) { - return S_cas_bindFail; - } - - return S_cas_success; -} - -void caServerI::addMCast(const osiSockAddr& addr) -{ -#ifdef IP_ADD_MEMBERSHIP - epicsGuard < epicsMutex > locker ( this->mutex ); - tsDLIter < casIntfOS > iter = this->intfList.firstIter (); - while ( iter.valid () ) { - struct ip_mreq mreq; - - memset(&mreq, 0, sizeof(mreq)); - mreq.imr_interface = iter->serverAddress().getSockIP().sin_addr; - mreq.imr_multiaddr = addr.ia.sin_addr; - - if ( setsockopt ( iter->casDGIntfIO::getFD (), 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 = addr.ia.sin_port; - epicsSocketConvertErrnoToString ( - sockErrBuf, sizeof ( sockErrBuf ) ); - ipAddrToDottedIP (&temp, name, sizeof(name)); - fprintf(stderr, "CAS: Socket mcast join %s failed with \"%s\"\n", - name, sockErrBuf ); - } - - iter++; - } -#endif -} - -void caServerI::sendBeacon ( ca_uint32_t beaconNo ) -{ - epicsGuard < epicsMutex > locker ( this->mutex ); - tsDLIter < casIntfOS > iter = this->intfList.firstIter (); - while ( iter.valid () ) { - iter->sendBeacon ( beaconNo ); - iter++; - } -} - -void caServerI::generateBeaconAnomaly () -{ - this->beaconAnomalyGov.start (); -} - -void caServerI::destroyMonitor ( casMonitor & mon ) -{ - mon.~casMonitor (); - this->casMonitorFreeList.release ( & mon ); -} - -void caServerI::updateEventsPostedCounter ( unsigned nNewPosts ) -{ - epicsGuard < epicsMutex > guard ( this->diagnosticCountersMutex ); - this->nEventsPosted += nNewPosts; -} - -unsigned caServerI::subscriptionEventsPosted () const -{ - epicsGuard < epicsMutex > guard ( this->diagnosticCountersMutex ); - return this->nEventsPosted; -} - -void caServerI::incrEventsProcessedCounter () -{ - epicsGuard < epicsMutex > guard ( this->diagnosticCountersMutex ); - this->nEventsProcessed ++; -} - -unsigned caServerI::subscriptionEventsProcessed () const -{ - epicsGuard < epicsMutex > guard ( this->diagnosticCountersMutex ); - return this->nEventsProcessed; -} - -void caServerI::show (unsigned level) const -{ - int bytes_reserved; - - printf ( "Channel Access Server V%s\n", - CA_VERSION_STRING ( CA_MINOR_PROTOCOL_REVISION ) ); - printf ( "\trevision %s\n", pVersionCAS ); - - this->mutex.show(level); - - { - epicsGuard < epicsMutex > locker ( this->mutex ); - tsDLIterConst < casStrmClient > iterCl = this->clientList.firstIter (); - while ( iterCl.valid () ) { - iterCl->show ( level ); - ++iterCl; - } - - tsDLIterConst < casIntfOS > iterIF = this->intfList.firstIter (); - while ( iterIF.valid () ) { - iterIF->casIntfOS::show ( level ); - ++iterIF; - } - } - - bytes_reserved = 0u; -#if 0 - bytes_reserved += sizeof(casClient) * - ellCount(&this->freeClientQ); - bytes_reserved += sizeof(casChannel) * - ellCount(&this->freeChanQ); - bytes_reserved += sizeof(casEventBlock) * - ellCount(&this->freeEventQ); - bytes_reserved += sizeof(casAsyncIIO) * - ellCount(&this->freePendingIO); -#endif - if (level>=1) { - printf( - "There are currently %d bytes on the server's free list\n", - bytes_reserved); -#if 0 - printf( - "%d client(s), %d channel(s), %d event(s) (monitors), and %d IO blocks\n", - ellCount(&this->freeClientQ), - ellCount(&this->freeChanQ), - ellCount(&this->freeEventQ), - ellCount(&this->freePendingIO)); -#endif - printf( - "The server's integer resource id conversion table:\n"); - } - - return; -} - -casMonitor & caServerI::casMonitorFactory ( - casChannelI & chan, caResId clientId, - const unsigned long count, const unsigned type, - const casEventMask & mask, - casMonitorCallbackInterface & cb ) -{ - casMonitor * pMon = - new ( this->casMonitorFreeList ) casMonitor - ( clientId, chan, count, type, mask, cb ); - return *pMon; -} - -void caServerI::casMonitorDestroy ( casMonitor & cm ) -{ - cm.~casMonitor (); - this->casMonitorFreeList.release ( & cm ); -} - -// -// caServerI::dumpMsg() -// -// Debug aid - print the header part of a message. -// -// dp arg allowed to be null -// -// -void caServerI::dumpMsg ( const char * pHostName, const char * pUserName, - const caHdrLargeArray * mp, const void * /* dp */, const char * pFormat, ... ) -{ - va_list theArgs; - if ( pFormat ) { - va_start ( theArgs, pFormat ); - errlogPrintf ( "CAS: " ); - errlogVprintf ( pFormat, theArgs ); - va_end ( theArgs ); - } - - fprintf ( stderr, -"CAS Request: %s on %s: cmd=%u cid=%u typ=%u cnt=%u psz=%u avail=%x\n", - pUserName, - pHostName, - mp->m_cmmd, - mp->m_cid, - mp->m_dataType, - mp->m_count, - mp->m_postsize, - mp->m_available); - - //if ( mp->m_cmmd == CA_PROTO_WRITE && mp->m_dataType == DBR_STRING && dp ) { - // errlogPrintf("CAS: The string written: %s \n", (char *)dp); - //} -} - -casEventRegistry::~casEventRegistry() -{ - this->traverse ( &casEventMaskEntry::destroy ); -} - diff --git a/src/ca/legacy/pcas/generic/caServerI.h b/src/ca/legacy/pcas/generic/caServerI.h deleted file mode 100644 index 012233693..000000000 --- a/src/ca/legacy/pcas/generic/caServerI.h +++ /dev/null @@ -1,176 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 caServerIh -#define caServerIh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_caServerIh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "tsFreeList.h" -#include "caProto.h" - -#ifdef epicsExportSharedSymbols_caServerIh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casdef.h" -#include "clientBufMemoryManager.h" -#include "casEventRegistry.h" -#include "caServerIO.h" -#include "ioBlocked.h" -#include "caServerDefs.h" - -class casStrmClient; -class beaconTimer; -class beaconAnomalyGovernor; -class casIntfOS; -class casMonitor; -class casChannelI; - -caStatus convertContainerMemberToAtomic (class gdd & dd, - aitUint32 appType, aitUint32 requestedCount, aitUint32 nativeCount); - -// Keep the old signature for backward compatibility -inline caStatus convertContainerMemberToAtomic (class gdd & dd, - aitUint32 appType, aitUint32 elemCount) -{ return convertContainerMemberToAtomic(dd, appType, elemCount, elemCount); } - -class caServerI : - public caServerIO, - public ioBlockedList, - public casEventRegistry { -public: - caServerI ( caServer &tool ); - ~caServerI (); - bool roomForNewChannel() const; - unsigned getDebugLevel() const { return debugLevel; } - inline void setDebugLevel ( unsigned debugLevelIn ); - void show ( unsigned level ) const; - void destroyMonitor ( casMonitor & ); - caServer * getAdapter (); - caServer * operator -> (); - void connectCB ( casIntfOS & ); - casEventMask valueEventMask () const; // DBE_VALUE registerEvent("value") - casEventMask logEventMask () const; // DBE_LOG registerEvent("log") - casEventMask alarmEventMask () const; // DBE_ALARM registerEvent("alarm") - casEventMask propertyEventMask () const; // DBE_PROPERTY registerEvent("property") - unsigned subscriptionEventsProcessed () const; - void incrEventsProcessedCounter (); - unsigned subscriptionEventsPosted () const; - void updateEventsPostedCounter ( unsigned nNewPosts ); - void generateBeaconAnomaly (); - casMonitor & casMonitorFactory ( casChannelI &, - caResId clientId, const unsigned long count, - const unsigned type, const casEventMask &, - class casMonitorCallbackInterface & ); - void casMonitorDestroy ( casMonitor & ); - void destroyClient ( casStrmClient & ); - static void dumpMsg ( - const char * pHostName, const char * pUserName, - const struct caHdrLargeArray * mp, const void * dp, - const char * pFormat, ... ); - bool ioIsPending () const; - void incrementIOInProgCount (); - void decrementIOInProgCount (); -private: - clientBufMemoryManager clientBufMemMgr; - tsFreeList < casMonitor, 1024 > casMonitorFreeList; - tsDLList < casStrmClient > clientList; - tsDLList < casIntfOS > intfList; - mutable epicsMutex mutex; - mutable epicsMutex diagnosticCountersMutex; - caServer & adapter; - beaconTimer & beaconTmr; - beaconAnomalyGovernor & beaconAnomalyGov; - unsigned debugLevel; - unsigned nEventsProcessed; - unsigned nEventsPosted; - unsigned ioInProgressCount; - - casEventMask valueEvent; // DBE_VALUE registerEvent("value") - casEventMask logEvent; // DBE_LOG registerEvent("log") - casEventMask alarmEvent; // DBE_ALARM registerEvent("alarm") - casEventMask propertyEvent; // DBE_PROPERTY registerEvent("property") - - caStatus attachInterface ( const caNetAddr & addr, bool autoBeaconAddr, - bool addConfigAddr ); - - virtual void addMCast(const osiSockAddr&); - - void sendBeacon ( ca_uint32_t beaconNo ); - - caServerI ( const caServerI & ); - caServerI & operator = ( const caServerI & ); - - friend class beaconAnomalyGovernor; - friend class beaconTimer; -}; - - -inline caServer * caServerI::getAdapter() -{ - return & this->adapter; -} - -inline caServer * caServerI::operator -> () -{ - return this->getAdapter(); -} - -inline void caServerI::setDebugLevel(unsigned debugLevelIn) -{ - this->debugLevel = debugLevelIn; -} - -inline casEventMask caServerI::valueEventMask() const -{ - return this->valueEvent; -} - -inline casEventMask caServerI::logEventMask() const -{ - return this->logEvent; -} - -inline casEventMask caServerI::alarmEventMask() const -{ - return this->alarmEvent; -} - -inline casEventMask caServerI::propertyEventMask() const -{ - return this->propertyEvent; -} - -inline bool caServerI :: ioIsPending () const -{ - return ( ioInProgressCount > 0u ); -} - -inline void caServerI :: incrementIOInProgCount () -{ - assert ( ioInProgressCount < UINT_MAX ); - ioInProgressCount++; -} - -inline void caServerI :: decrementIOInProgCount () -{ - assert ( ioInProgressCount > 0 ); - ioInProgressCount--; - this->ioBlockedList::signal (); -} - -#endif // caServerIh diff --git a/src/ca/legacy/pcas/generic/casAddr.h b/src/ca/legacy/pcas/generic/casAddr.h deleted file mode 100644 index 93ee6f9d9..000000000 --- a/src/ca/legacy/pcas/generic/casAddr.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. -* EPICS BASE 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 includeCASAddrH -#define includeCASAddrH - -#include "osiSock.h" - -#endif // includeCASAddrH - diff --git a/src/ca/legacy/pcas/generic/casAsyncIOI.cc b/src/ca/legacy/pcas/generic/casAsyncIOI.cc deleted file mode 100644 index e90247a6a..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncIOI.cc +++ /dev/null @@ -1,125 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "errlog.h" - -#define epicsExportSharedSymbols -#include "casAsyncIOI.h" - -casAsyncIOI::casAsyncIOI ( const casCtx & ctx ) : - client ( *ctx.getClient() ), inTheEventQueue ( false ), - posted ( false ), ioComplete ( false ) -{ - // - // catch situation where they create more than one - // async IO object per request - // - if ( ! client.okToStartAsynchIO () ) { - throw std::logic_error ( - "server tool attempted to " - "start duplicate asynchronous IO" ); - } -} - -// -// ways this gets destroyed: -// 1) io completes, this is pulled off the queue, and result -// is sent to the client -// 2) client, channel, or PV is deleted -// 3) server tool deletes the casAsyncXxxxIO obj -// -// Case 1) => normal completion -// -// Case 2) -// If the server deletes the channel or the PV then the -// client will get a disconnect msg for the channel -// involved and this will cause the io call back -// to be called with a disconnect error code. -// Therefore we dont need to force an IO canceled -// response here. -// -// Case 3) -// If for any reason the server tool needs to cancel an IO -// operation then it should post io completion with status -// S_casApp_canceledAsyncIO. Deleting the asyncronous io -// object prior to its being allowed to forward an IO termination -// message to the client will result in NO IO CALL BACK TO THE -// CLIENT PROGRAM (in this situation a warning message will be printed by -// the server lib). -// -casAsyncIOI::~casAsyncIOI() -{ - // - // pulls itself out of the event queue - // if it is installed there. - // - this->client.removeFromEventQueue ( *this, this->inTheEventQueue ); -} - -// -// o called when IO completion event reaches top of event queue -// o clients lock is applied when calling this -// -caStatus casAsyncIOI::cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > & clientGuard, - epicsGuard < evSysMutex > & ) -{ - caStatus status = S_cas_success; - { - this->inTheEventQueue = false; - - status = this->cbFuncAsyncIO ( clientGuard ); - if ( status == S_cas_sendBlocked ) { - // - // causes this op to be pushed back on the queue - // - this->inTheEventQueue = true; - return status; - } - else if ( status != S_cas_success ) { - errMessage ( status, "Asynch IO completion failed" ); - } - - this->ioComplete = true; - } - - // dont use "this" after destroying the object here - delete this; - - return S_cas_success; -} - -caStatus casAsyncIOI::insertEventQueue () -{ - // - // place this event in the event queue - // o this also signals the event consumer - // o clients lock protects list and flag - // - return this->client.addToEventQueue ( *this, this->inTheEventQueue, this->posted ); -} - -caServer *casAsyncIOI::getCAS() const -{ - return this->client.getCAS().getAdapter(); -} - -bool casAsyncIOI::oneShotReadOP() const -{ - return false; -} diff --git a/src/ca/legacy/pcas/generic/casAsyncIOI.h b/src/ca/legacy/pcas/generic/casAsyncIOI.h deleted file mode 100644 index 24a48512d..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncIOI.h +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef casAsyncIOIh -#define casAsyncIOIh - -#include "casEvent.h" -#include "caHdrLargeArray.h" -#include "casCoreClient.h" - -class casAsyncIOI : - public tsDLNode < casAsyncIOI >, - public casEvent { -public: - casAsyncIOI ( const casCtx & ctx ); - epicsShareFunc virtual ~casAsyncIOI (); - caServer * getCAS () const; - virtual bool oneShotReadOP () const; - void removeFromEventQueue (); -protected: - caStatus insertEventQueue (); - casCoreClient & client; -private: - bool inTheEventQueue; - bool posted; - bool ioComplete; - - // - // casEvent virtual call back function - // (called when IO completion event reaches top of event queue) - // - epicsShareFunc caStatus cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > &, - epicsGuard < evSysMutex > & ); - - // - // derived class specific call back - // (called when IO completion event reaches top of event queue) - // - epicsShareFunc virtual caStatus cbFuncAsyncIO ( - epicsGuard < casClientMutex > & ) = 0; - - casAsyncIOI ( const casAsyncIOI & ); - casAsyncIOI & operator = ( const casAsyncIOI & ); -}; - -inline void casAsyncIOI::removeFromEventQueue () -{ - this->client.removeFromEventQueue ( *this, this->inTheEventQueue ); -} - -#endif // casAsyncIOIh diff --git a/src/ca/legacy/pcas/generic/casAsyncPVAttachIO.cc b/src/ca/legacy/pcas/generic/casAsyncPVAttachIO.cc deleted file mode 100644 index 0098c13ba..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncPVAttachIO.cc +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "casdef.h" -#include "casAsyncPVAttachIOI.h" - -casAsyncPVAttachIO::casAsyncPVAttachIO ( const casCtx &ctx ) : - pAsyncPVAttachIOI ( new casAsyncPVAttachIOI ( *this, ctx ) ) -{ -} - -void casAsyncPVAttachIO::serverInitiatedDestroy () -{ - this->pAsyncPVAttachIOI = 0; - this->destroy (); -} - -casAsyncPVAttachIO::~casAsyncPVAttachIO () -{ - if ( this->pAsyncPVAttachIOI ) { - throw std::logic_error ( - "the server library *must* initiate asynchronous IO destroy" ); - } -} - -caStatus casAsyncPVAttachIO::postIOCompletion ( const pvAttachReturn & retValIn ) -{ - if ( this->pAsyncPVAttachIOI ) { - return this->pAsyncPVAttachIOI->postIOCompletion ( retValIn ); - } - else { - return S_cas_redundantPost; - } -} - -void casAsyncPVAttachIO::destroy () -{ - delete this; -} - -casAsyncPVCreateIO::casAsyncPVCreateIO ( const casCtx & ctx ) : - casAsyncPVAttachIO ( ctx ) -{ -} - -casAsyncPVCreateIO::~casAsyncPVCreateIO () -{ -} diff --git a/src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.cpp b/src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.cpp deleted file mode 100644 index 1543c74cb..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.cpp +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "casAsyncPVAttachIOI.h" - -casAsyncPVAttachIOI::casAsyncPVAttachIOI ( - casAsyncPVAttachIO & intf, const casCtx & ctx ) : - casAsyncIOI ( ctx ), msg ( *ctx.getMsg() ), - asyncPVAttachIO ( intf ), retVal ( S_cas_badParameter ) -{ - ctx.getServer()->incrementIOInProgCount (); - ctx.getClient()->installAsynchIO ( *this ); -} - -caStatus casAsyncPVAttachIOI::postIOCompletion ( const pvAttachReturn & retValIn ) -{ - this->retVal = retValIn; - return this->insertEventQueue (); -} - -caStatus casAsyncPVAttachIOI::cbFuncAsyncIO ( - epicsGuard < casClientMutex > & guard ) -{ - caStatus status; - - // uninstall here in case the channel is deleted - // further down the call stack - this->client.uninstallAsynchIO ( *this ); - this->client.getCAS().decrementIOInProgCount (); - - if ( this->msg.m_cmmd == CA_PROTO_CREATE_CHAN ) { - casCtx tmpCtx; - tmpCtx.setMsg ( this->msg, 0 ); - tmpCtx.setServer ( & this->client.getCAS() ); - tmpCtx.setClient ( & this->client ); - status = this->client.createChanResponse ( guard, - tmpCtx, this->retVal ); - } - else { - errPrintf ( S_cas_invalidAsynchIO, __FILE__, __LINE__, - " - client request type = %u", this->msg.m_cmmd ); - status = S_cas_invalidAsynchIO; - } - - if ( status == S_cas_sendBlocked ) { - this->client.getCAS().incrementIOInProgCount (); - this->client.installAsynchIO ( *this ); - } - - return status; -} - diff --git a/src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.h b/src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.h deleted file mode 100644 index d8c5d5943..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncPVAttachIOI.h +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef casAsyncPVAttachIOIh -#define casAsyncPVAttachIOIh - -#include "casAsyncIOI.h" - -class casAsyncPVAttachIOI : public casAsyncIOI { -public: - casAsyncPVAttachIOI ( casAsyncPVAttachIO &, const casCtx & ctx ); - ~casAsyncPVAttachIOI (); - caStatus postIOCompletion ( const pvAttachReturn & retValIn ); - caServer *getCAS () const; -private: - caHdrLargeArray const msg; - class casAsyncPVAttachIO & asyncPVAttachIO; - pvAttachReturn retVal; - - caStatus cbFuncAsyncIO ( epicsGuard < casClientMutex > & ); - casAsyncPVAttachIOI ( const casAsyncPVAttachIOI & ); - casAsyncPVAttachIOI & operator = ( const casAsyncPVAttachIOI & ); -}; - -inline casAsyncPVAttachIOI::~casAsyncPVAttachIOI () -{ - this->asyncPVAttachIO.serverInitiatedDestroy (); -} - -#endif // casAsyncPVAttachIOIh diff --git a/src/ca/legacy/pcas/generic/casAsyncPVExistIO.cc b/src/ca/legacy/pcas/generic/casAsyncPVExistIO.cc deleted file mode 100644 index 34f827b34..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncPVExistIO.cc +++ /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 Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "casdef.h" -#include "casAsyncPVExistIOI.h" - -casAsyncPVExistIO::casAsyncPVExistIO ( const casCtx & ctx ) : - pAsyncPVExistIOI ( new casAsyncPVExistIOI ( *this, ctx ) ) {} - -void casAsyncPVExistIO::serverInitiatedDestroy () -{ - this->pAsyncPVExistIOI = 0; - this->destroy (); -} - -casAsyncPVExistIO::~casAsyncPVExistIO () -{ - if ( this->pAsyncPVExistIOI ) { - throw std::logic_error ( - "the server library *must* initiate asynchronous IO destroy" ); - } -} - -caStatus casAsyncPVExistIO::postIOCompletion ( const pvExistReturn & retValIn ) -{ - if ( this->pAsyncPVExistIOI ) { - return this->pAsyncPVExistIOI->postIOCompletion ( retValIn ); - } - else { - return S_cas_redundantPost; - } -} - -void casAsyncPVExistIO::destroy () -{ - delete this; -} - diff --git a/src/ca/legacy/pcas/generic/casAsyncPVExistIOI.cpp b/src/ca/legacy/pcas/generic/casAsyncPVExistIOI.cpp deleted file mode 100644 index f03a9deb6..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncPVExistIOI.cpp +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "casAsyncPVExistIOI.h" - -casAsyncPVExistIOI::casAsyncPVExistIOI ( - casAsyncPVExistIO & intf, const casCtx & ctx ) : - casAsyncIOI ( ctx ), - msg ( *ctx.getMsg() ), - asyncPVExistIO ( intf ), - retVal ( pverDoesNotExistHere ), - dgOutAddr ( ctx.getClient()->fetchLastRecvAddr () ), - protocolRevision ( ctx.getClient()->protocolRevision () ), - sequenceNumber ( ctx.getClient()->datagramSequenceNumber () ) -{ - ctx.getServer()->incrementIOInProgCount (); - ctx.getClient()->installAsynchIO ( *this ); -} - -caStatus casAsyncPVExistIOI::postIOCompletion ( - const pvExistReturn & retValIn ) -{ - this->retVal = retValIn; - return this->insertEventQueue (); -} - -caStatus casAsyncPVExistIOI::cbFuncAsyncIO ( - epicsGuard < casClientMutex > & guard ) -{ - caStatus status; - - if ( this->msg.m_cmmd == CA_PROTO_SEARCH ) { - // - // pass output DG address parameters - // - status = this->client.asyncSearchResponse ( - guard, this->dgOutAddr, this->msg, this->retVal, - this->protocolRevision, this->sequenceNumber ); - } - else { - errPrintf ( S_cas_invalidAsynchIO, __FILE__, __LINE__, - " - client request type = %u", this->msg.m_cmmd ); - status = S_cas_invalidAsynchIO; - } - - if ( status != S_cas_sendBlocked ) { - this->client.uninstallAsynchIO ( *this ); - this->client.getCAS().decrementIOInProgCount (); - } - - return status; -} - diff --git a/src/ca/legacy/pcas/generic/casAsyncPVExistIOI.h b/src/ca/legacy/pcas/generic/casAsyncPVExistIOI.h deleted file mode 100644 index d436c23cb..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncPVExistIOI.h +++ /dev/null @@ -1,46 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 casAsyncPVExistIOIh -#define casAsyncPVExistIOIh - -#include "casAsyncIOI.h" - -class casAsyncPVExistIOI : public casAsyncIOI { -public: - casAsyncPVExistIOI ( casAsyncPVExistIO &, const casCtx & ctx ); - ~casAsyncPVExistIOI (); - caStatus postIOCompletion ( const pvExistReturn & retValIn ); - caServer * getCAS() const; -private: - caHdrLargeArray const msg; - class casAsyncPVExistIO & asyncPVExistIO; - pvExistReturn retVal; - const caNetAddr dgOutAddr; - const ca_uint16_t protocolRevision; - const ca_uint32_t sequenceNumber; - - caStatus cbFuncAsyncIO ( epicsGuard < casClientMutex > & ); - casAsyncPVExistIOI ( const casAsyncPVExistIOI & ); - casAsyncPVExistIOI & operator = ( const casAsyncPVExistIOI & ); -}; - -inline casAsyncPVExistIOI::~casAsyncPVExistIOI () -{ - this->asyncPVExistIO.serverInitiatedDestroy (); -} - -#endif // casAsyncPVExistIOIh diff --git a/src/ca/legacy/pcas/generic/casAsyncReadIO.cc b/src/ca/legacy/pcas/generic/casAsyncReadIO.cc deleted file mode 100644 index e235e3ebe..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncReadIO.cc +++ /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 Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "casdef.h" -#include "casAsyncReadIOI.h" - -casAsyncReadIO::casAsyncReadIO ( const casCtx & ctx ) : - pAsyncReadIOI ( new casAsyncReadIOI ( *this, ctx ) ) {} - -void casAsyncReadIO::serverInitiatedDestroy () -{ - this->pAsyncReadIOI = 0; - this->destroy (); -} - -casAsyncReadIO::~casAsyncReadIO () -{ - if ( this->pAsyncReadIOI ) { - throw std::logic_error ( - "the server library *must* initiate asynchronous IO destroy" ); - } -} - -caStatus casAsyncReadIO::postIOCompletion ( - caStatus completionStatusIn, const gdd & valueRead ) -{ - if ( this->pAsyncReadIOI ) { - return this->pAsyncReadIOI->postIOCompletion ( - completionStatusIn, valueRead ); - } - else { - return S_cas_redundantPost; - } -} - -void casAsyncReadIO::destroy () -{ - delete this; -} - - - diff --git a/src/ca/legacy/pcas/generic/casAsyncReadIOI.cc b/src/ca/legacy/pcas/generic/casAsyncReadIOI.cc deleted file mode 100644 index 4bf01b546..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncReadIOI.cc +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "casAsyncReadIOI.h" -#include "casChannelI.h" - -casAsyncReadIOI::casAsyncReadIOI ( - casAsyncReadIO & intf, const casCtx & ctx ) : - casAsyncIOI ( ctx ), msg ( *ctx.getMsg() ), - asyncReadIO ( intf ), chan ( *ctx.getChannel () ), - pDD ( NULL ), completionStatus ( S_cas_internal ) -{ - this->chan.installIO ( *this ); -} - -casAsyncReadIOI::~casAsyncReadIOI () -{ - this->asyncReadIO.serverInitiatedDestroy (); -} - -caStatus casAsyncReadIOI::postIOCompletion ( - caStatus completionStatusIn, const gdd & valueRead ) -{ - this->pDD = & valueRead; - this->completionStatus = completionStatusIn; - return this->insertEventQueue (); -} - -bool casAsyncReadIOI::oneShotReadOP () const -{ - return true; // it is a read op -} - -caStatus casAsyncReadIOI::cbFuncAsyncIO ( - epicsGuard < casClientMutex > & guard ) -{ - caStatus status; - - // uninstall the io early on to prevent a channel delete from - // destroying this object twice - this->chan.uninstallIO ( *this ); - - switch ( this->msg.m_cmmd ) { - case CA_PROTO_READ: - status = client.readResponse ( - guard, & this->chan, this->msg, - * this->pDD, this->completionStatus ); - break; - - case CA_PROTO_READ_NOTIFY: - status = client.readNotifyResponse ( - guard, & this->chan, this->msg, * this->pDD, - this->completionStatus ); - break; - - case CA_PROTO_EVENT_ADD: - status = client.monitorResponse ( - guard, this->chan, this->msg, * this->pDD, - this->completionStatus ); - break; - - case CA_PROTO_CREATE_CHAN: - // we end up here if the channel claim protocol response is delayed - // by an asynchronous enum string table fetch response - status = client.enumPostponedCreateChanResponse ( - guard, this->chan, this->msg ); - if ( status == S_cas_success ) { - if ( this->completionStatus == S_cas_success && this->pDD.valid() ) { - this->chan.getPVI().updateEnumStringTableAsyncCompletion ( *this->pDD ); - } - else { - errMessage ( this->completionStatus, - "unable to read application type \"enums\" string" - " conversion table for enumerated PV" ); - } - } - break; - - default: - errPrintf ( S_cas_invalidAsynchIO, __FILE__, __LINE__, - " - client request type = %u", this->msg.m_cmmd ); - status = S_cas_invalidAsynchIO; - break; - } - - if ( status == S_cas_sendBlocked ) { - this->chan.installIO ( *this ); - } - - return status; -} - - diff --git a/src/ca/legacy/pcas/generic/casAsyncReadIOI.h b/src/ca/legacy/pcas/generic/casAsyncReadIOI.h deleted file mode 100644 index 6f8b7d6c5..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncReadIOI.h +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef casAsyncReadIOIh -#define casAsyncReadIOIh - -#include "casAsyncIOI.h" -#include "casdef.h" - -class gdd; - -class casAsyncReadIOI : public casAsyncIOI { -public: - casAsyncReadIOI ( casAsyncReadIO &, const casCtx & ctx ); - ~casAsyncReadIOI (); - caStatus postIOCompletion ( - caStatus completionStatusIn, const gdd &valueRead ); - caServer *getCAS () const; -private: - caHdrLargeArray const msg; - class casAsyncReadIO & asyncReadIO; - class casChannelI & chan; - smartConstGDDPointer pDD; - caStatus completionStatus; - epicsShareFunc bool oneShotReadOP () const; - epicsShareFunc caStatus cbFuncAsyncIO ( - epicsGuard < casClientMutex > & ); - casAsyncReadIOI ( const casAsyncReadIOI & ); - casAsyncReadIOI & operator = ( const casAsyncReadIOI & ); -}; - -#endif // casAsyncReadIOIh diff --git a/src/ca/legacy/pcas/generic/casAsyncWriteIO.cc b/src/ca/legacy/pcas/generic/casAsyncWriteIO.cc deleted file mode 100644 index 0366eb59b..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncWriteIO.cc +++ /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 Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#define epicsExportSharedSymbols -#include "casdef.h" -#include "casAsyncWriteIOI.h" - -casAsyncWriteIO::casAsyncWriteIO ( const casCtx & ctx ) : - pAsyncWriteIOI ( new casAsyncWriteIOI ( *this, ctx ) ) -{ -} - -void casAsyncWriteIO::serverInitiatedDestroy () -{ - this->pAsyncWriteIOI = 0; - this->destroy (); -} - -casAsyncWriteIO::~casAsyncWriteIO() -{ - if ( this->pAsyncWriteIOI ) { - throw std::logic_error ( - "the server library *must* initiate asynchronous IO destroy" ); - } -} - -caStatus casAsyncWriteIO::postIOCompletion ( caStatus completionStatusIn ) -{ - if ( this->pAsyncWriteIOI ) { - return this->pAsyncWriteIOI->postIOCompletion ( completionStatusIn ); - } - else { - return S_cas_redundantPost; - } -} - -void casAsyncWriteIO::destroy () -{ - delete this; -} diff --git a/src/ca/legacy/pcas/generic/casAsyncWriteIOI.cpp b/src/ca/legacy/pcas/generic/casAsyncWriteIOI.cpp deleted file mode 100644 index 0b8c0a2cd..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncWriteIOI.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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "casAsyncWriteIOI.h" -#include "casChannelI.h" - -casAsyncWriteIOI::casAsyncWriteIOI ( - casAsyncWriteIO & intf, const casCtx & ctx ) : - casAsyncIOI ( ctx ), - msg ( *ctx.getMsg() ), - asyncWriteIO ( intf ), - chan ( *ctx.getChannel() ), - completionStatus ( S_cas_internal ) -{ - this->chan.installIO ( *this ); -} - -caStatus casAsyncWriteIOI::postIOCompletion ( caStatus completionStatusIn ) -{ - this->completionStatus = completionStatusIn; - return this->insertEventQueue (); -} - -caStatus casAsyncWriteIOI::cbFuncAsyncIO ( - epicsGuard < casClientMutex > & guard ) -{ - caStatus status; - - switch ( this->msg.m_cmmd ) { - case CA_PROTO_WRITE: - status = client.writeResponse ( guard, this->chan, - this->msg, this->completionStatus ); - break; - - case CA_PROTO_WRITE_NOTIFY: - status = client.writeNotifyResponse ( guard, this->chan, - this->msg, this->completionStatus ); - break; - - default: - errPrintf ( S_cas_invalidAsynchIO, __FILE__, __LINE__, - " - client request type = %u", this->msg.m_cmmd ); - status = S_cas_invalidAsynchIO; - break; - } - - if ( status != S_cas_sendBlocked ) { - this->chan.uninstallIO ( *this ); - } - - return status; -} - - diff --git a/src/ca/legacy/pcas/generic/casAsyncWriteIOI.h b/src/ca/legacy/pcas/generic/casAsyncWriteIOI.h deleted file mode 100644 index 86b9c4add..000000000 --- a/src/ca/legacy/pcas/generic/casAsyncWriteIOI.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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef casAsyncWriteIOIh -#define casAsyncWriteIOIh - -#include "casAsyncIOI.h" - -class casAsyncWriteIOI : public casAsyncIOI { -public: - casAsyncWriteIOI ( casAsyncWriteIO &, const casCtx & ctx ); - virtual ~casAsyncWriteIOI (); - caStatus postIOCompletion ( caStatus completionStatusIn ); - caServer * getCAS () const; -private: - caHdrLargeArray const msg; - class casAsyncWriteIO & asyncWriteIO; - class casChannelI & chan; - caStatus completionStatus; - caStatus cbFuncAsyncIO ( - epicsGuard < casClientMutex > & ); - casAsyncWriteIOI ( const casAsyncWriteIOI & ); - casAsyncWriteIOI & operator = ( const casAsyncWriteIOI & ); -}; - -inline casAsyncWriteIOI::~casAsyncWriteIOI () -{ - this->asyncWriteIO.serverInitiatedDestroy (); -} - -#endif // casAsyncWriteIOIh diff --git a/src/ca/legacy/pcas/generic/casChannel.cc b/src/ca/legacy/pcas/generic/casChannel.cc deleted file mode 100644 index 2d9d97796..000000000 --- a/src/ca/legacy/pcas/generic/casChannel.cc +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 - */ - -#define epicsExportSharedSymbols -#include "casdef.h" -#include "casChannelI.h" - -casChannel::casChannel ( const casCtx & /* ctx */ ) : - pChanI ( 0 ) -{ -} - -casChannel::~casChannel () -{ - if ( this->pChanI ) { - this->pChanI->casChannelDestroyFromInterfaceNotify (); - } -} - -void casChannel::destroyRequest () -{ - this->pChanI = 0; - this->destroy (); -} - -casPV * casChannel::getPV () -{ - if ( this->pChanI ) { - casPVI & pvi = this->pChanI->getPVI (); - return pvi.apiPointer (); - } - else { - return 0; - } -} - -void casChannel::setOwner ( const char * const /* pUserName */, - const char * const /* pHostName */ ) -{ - // - // NOOP - // -} - -bool casChannel::readAccess () const -{ - return true; -} - -bool casChannel::writeAccess () const -{ - return true; -} - -bool casChannel::confirmationRequested () const -{ - return false; -} - -caStatus casChannel::beginTransaction () -{ - return S_casApp_success; -} - -void casChannel::endTransaction () -{ -} - -caStatus casChannel::read ( const casCtx & ctx, gdd & prototype ) -{ - return ctx.getPV()->read ( ctx, prototype ); -} - -caStatus casChannel::write ( const casCtx & ctx, const gdd & value ) -{ - return ctx.getPV()->write ( ctx, value ); -} - -caStatus casChannel::writeNotify ( const casCtx & ctx, const gdd & value ) -{ - return ctx.getPV()->writeNotify ( ctx, value ); -} - -void casChannel::show ( unsigned level ) const -{ - if ( level > 2u ) { - printf ( "casChannel: read access = %d\n", - this->readAccess() ); - printf ( "casChannel: write access = %d\n", - this->writeAccess() ); - printf ( "casChannel: confirmation requested = %d\n", - this->confirmationRequested() ); - } -} - -void casChannel::destroy () -{ - delete this; -} - -void casChannel::postAccessRightsEvent () -{ - if ( this->pChanI ) { - this->pChanI->postAccessRightsEvent (); - } -} - diff --git a/src/ca/legacy/pcas/generic/casChannelI.cc b/src/ca/legacy/pcas/generic/casChannelI.cc deleted file mode 100644 index 376f62f8c..000000000 --- a/src/ca/legacy/pcas/generic/casChannelI.cc +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 - */ - -#define epicsExportSharedSymbols -#include "casChannelI.h" -#include "casAsyncIOI.h" - -casChannelI::casChannelI ( casCoreClient & clientIn, - casChannel & chanIn, casPVI & pvIn, ca_uint32_t cidIn ) : - privateForPV ( clientIn, *this ), - pv ( pvIn ), - maxElem( pvIn.nativeCount() ), - chan ( chanIn ), - cid ( cidIn ), - serverDeletePending ( false ), - accessRightsEvPending ( false ) -{ -} - -casChannelI::~casChannelI () -{ - this->privateForPV.client().removeFromEventQueue ( - *this, this->accessRightsEvPending ); - - this->pv.destroyAllIO ( this->ioList ); - - this->serverDeletePending = true; - this->chan.destroyRequest (); - - // force PV delete if this is the last channel attached - this->pv.deleteSignal (); -} - -void casChannelI::uninstallFromPV ( casEventSys & eventSys ) -{ - tsDLList < casMonitor > dest; - this->privateForPV.removeSelfFromPV ( this->pv, dest ); - while ( casMonitor * pMon = dest.get () ) { - eventSys.prepareMonitorForDestroy ( *pMon ); - } -} - -void casChannelI::show ( unsigned level ) const -{ - printf ( "casChannelI: client id %u PV %s\n", - this->cid, this->pv.getName() ); - if ( level > 0 ) { - this->privateForPV.show ( level - 1 ); - this->chan.show ( level - 1 ); - } -} - -caStatus casChannelI::cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > & clientGuard, - epicsGuard < evSysMutex > & ) -{ - caStatus stat = S_cas_success; - { - stat = this->privateForPV.client().accessRightsResponse ( - clientGuard, this ); - } - if ( stat == S_cas_success ) { - this->accessRightsEvPending = false; - } - return stat; -} - -caStatus casChannelI::read ( const casCtx & ctx, gdd & prototype ) -{ - caStatus status = this->chan.beginTransaction (); - if ( status != S_casApp_success ) { - return status; - } - status = this->chan.read ( ctx, prototype ); - this->chan.endTransaction (); - return status; -} - -caStatus casChannelI::write ( const casCtx & ctx, const gdd & value ) -{ - caStatus status = this->chan.beginTransaction (); - if ( status != S_casApp_success ) { - return status; - } - status = this->chan.write ( ctx, value ); - this->chan.endTransaction (); - return status; -} - -caStatus casChannelI::writeNotify ( const casCtx & ctx, const gdd & value ) -{ - caStatus status = this->chan.beginTransaction (); - if ( status != S_casApp_success ) { - return status; - } - status = this->chan.writeNotify ( ctx, value ); - this->chan.endTransaction (); - return status; -} - -void casChannelI::postDestroyEvent () -{ - if ( ! this->serverDeletePending ) { - this->privateForPV.client().casChannelDestroyFromInterfaceNotify ( - *this, false ); - } -} diff --git a/src/ca/legacy/pcas/generic/casChannelI.h b/src/ca/legacy/pcas/generic/casChannelI.h deleted file mode 100644 index a0f74a1df..000000000 --- a/src/ca/legacy/pcas/generic/casChannelI.h +++ /dev/null @@ -1,166 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 casChannelIh -#define casChannelIh - -#include "casPVI.h" -#include "casEvent.h" -#include "chanIntfForPV.h" -#include "casCoreClient.h" - -class casMonitor; -class casAsyncIOI; - -class casChannelI : public tsDLNode < casChannelI >, - public chronIntIdRes < casChannelI >, public casEvent, - private casChannelDestroyFromPV { -public: - casChannelI ( casCoreClient & clientIn, casChannel & chanIn, - casPVI & pvIn, ca_uint32_t cidIn ); - ~casChannelI (); - void casChannelDestroyFromInterfaceNotify (); - const caResId getCID (); - const caResId getSID (); - void uninstallFromPV ( casEventSys & eventSys ); - void installIntoPV (); - void installIO ( casAsyncIOI & ); - void uninstallIO ( casAsyncIOI & ); - void installMonitor ( casMonitor & mon ); - casMonitor * removeMonitor ( ca_uint32_t clientIdIn ); - casPVI & getPVI () const; - void clearOutstandingReads (); - void postAccessRightsEvent (); - const gddEnumStringTable & enumStringTable () const; - ca_uint32_t getMaxElem () const; - void setOwner ( const char * const pUserName, - const char * const pHostName ); - bool readAccess () const; - bool writeAccess () const; - bool confirmationRequested () const; - caStatus read ( const casCtx & ctx, gdd & prototype ); - caStatus write ( const casCtx & ctx, const gdd & value ); - caStatus writeNotify ( const casCtx & ctx, const gdd & value ); - void show ( unsigned level ) const; -private: - chanIntfForPV privateForPV; - tsDLList < casAsyncIOI > ioList; - casPVI & pv; - ca_uint32_t maxElem; - casChannel & chan; - caResId cid; // client id - bool serverDeletePending; - bool accessRightsEvPending; - //epicsShareFunc virtual void destroy (); - caStatus cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > &, - epicsGuard < evSysMutex > & ); - void postDestroyEvent (); - casChannelI ( const casChannelI & ); - casChannelI & operator = ( const casChannelI & ); -}; - -inline casPVI & casChannelI::getPVI () const -{ - return this->pv; -} - -inline ca_uint32_t casChannelI::getMaxElem () const -{ - return this->maxElem; -} - -inline const caResId casChannelI::getCID () -{ - return this->cid; -} - -inline const caResId casChannelI::getSID () -{ - return this->chronIntIdRes < casChannelI >::getId (); -} - -inline void casChannelI::postAccessRightsEvent () -{ - this->privateForPV.client().addToEventQueue ( *this, this->accessRightsEvPending ); -} - -inline const gddEnumStringTable & casChannelI::enumStringTable () const -{ - return this->pv.enumStringTable (); -} - -inline void casChannelI::installIntoPV () -{ - this->pv.installChannel ( this->privateForPV ); -} - -inline void casChannelI::clearOutstandingReads () -{ - this->pv.clearOutstandingReads ( this->ioList ); -} - -inline void casChannelI::setOwner ( const char * const pUserName, - const char * const pHostName ) -{ - this->chan.setOwner ( pUserName, pHostName ); -} - -inline bool casChannelI::readAccess () const -{ - return this->chan.readAccess (); -} - -inline bool casChannelI::writeAccess () const -{ - return this->chan.writeAccess (); -} - -inline bool casChannelI::confirmationRequested () const -{ - return this->chan.confirmationRequested (); -} - -inline void casChannelI::installIO ( casAsyncIOI & io ) -{ - this->pv.installIO ( this->ioList, io ); -} - -inline void casChannelI::uninstallIO ( casAsyncIOI & io ) -{ - this->pv.uninstallIO ( this->ioList, io ); -} - -inline void casChannelI::casChannelDestroyFromInterfaceNotify () -{ - if ( ! this->serverDeletePending ) { - this->privateForPV.client().casChannelDestroyFromInterfaceNotify ( - *this, true ); - } -} - -inline void casChannelI::installMonitor ( casMonitor & mon ) -{ - this->privateForPV.installMonitor ( this->pv, mon ); -} - -inline casMonitor * casChannelI::removeMonitor ( - ca_uint32_t clientIdIn ) -{ - return this->privateForPV.removeMonitor ( this->pv, clientIdIn ); -} - -#endif // casChannelIh diff --git a/src/ca/legacy/pcas/generic/casCoreClient.cc b/src/ca/legacy/pcas/generic/casCoreClient.cc deleted file mode 100644 index 9c384776e..000000000 --- a/src/ca/legacy/pcas/generic/casCoreClient.cc +++ /dev/null @@ -1,209 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 "errlog.h" - -#define epicsExportSharedSymbols -#include "casCoreClient.h" -#include "casAsyncPVExistIOI.h" -#include "casAsyncPVAttachIOI.h" -#include "casChannelI.h" - -casCoreClient::casCoreClient ( caServerI & serverInternal ) : - eventSys ( *this ) -{ - assert ( & serverInternal ); - ctx.setServer ( & serverInternal ); - ctx.setClient ( this ); -} - -casCoreClient::~casCoreClient() -{ - // only used by io that does not have a channel - while ( casAsyncIOI * pIO = this->ioList.get() ) { - pIO->removeFromEventQueue (); - delete pIO; - } - if ( this->ctx.getServer()->getDebugLevel() > 0u ) { - errlogPrintf ( "CAS: Connection Terminated\n" ); - } - - // this will clean up the event queue because all - // channels have been deleted and any events left on - // the queue are there because they are going to - // execute a subscription delete - { - epicsGuard < casClientMutex > guard ( this->mutex ); - this->eventSys.process ( guard ); - } -} - -void casCoreClient::show ( unsigned level ) const -{ - printf ( "Core client\n" ); - epicsGuard < epicsMutex > guard ( this->mutex ); - this->eventSys.show ( level ); - this->ctx.show ( level ); - this->mutex.show ( level ); -} - -// -// one of these for each CA request type that has -// asynchronous completion -// -caStatus casCoreClient::asyncSearchResponse ( - epicsGuard < casClientMutex > &, const caNetAddr &, - const caHdrLargeArray &, const pvExistReturn &, - ca_uint16_t, ca_uint32_t ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::createChanResponse ( - epicsGuard < casClientMutex > &, - casCtx &, const pvAttachReturn & ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::readResponse ( - epicsGuard < casClientMutex > &, casChannelI *, - const caHdrLargeArray &, const gdd &, const caStatus ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::readNotifyResponse ( - epicsGuard < casClientMutex > &, casChannelI *, - const caHdrLargeArray &, const gdd &, const caStatus ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::writeResponse ( - epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray &, const caStatus ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::writeNotifyResponse ( - epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray &, const caStatus ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::monitorResponse ( - epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray &, const gdd &, const caStatus ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::accessRightsResponse ( - epicsGuard < casClientMutex > &, casChannelI * ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::enumPostponedCreateChanResponse ( - epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray & ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::channelCreateFailedResp ( - epicsGuard < casClientMutex > &, const caHdrLargeArray &, - const caStatus ) -{ - return S_casApp_noSupport; -} -caStatus casCoreClient::channelDestroyEventNotify ( - epicsGuard < casClientMutex > &, - casChannelI * const pChan, ca_uint32_t ) -{ - delete pChan; - return S_casApp_success; -} - -void casCoreClient::casChannelDestroyFromInterfaceNotify ( - casChannelI &, bool /* immediateDestroyNeeded */ ) -{ - assert ( 0 ); -} - -caNetAddr casCoreClient::fetchLastRecvAddr () const -{ - return caNetAddr(); // sets addr type to UDF -} - -ca_uint32_t casCoreClient::datagramSequenceNumber () const -{ - return 0; -} - -ca_uint16_t casCoreClient::protocolRevision() const -{ - return 0; -} - -// we need a noop to be called if they post events when a channel -// is being destroyed when we are in the casStrmClient destructor -void casCoreClient::eventSignal() -{ -} - -caStatus casCoreClient::casMonitorCallBack ( - epicsGuard < casClientMutex > &, casMonitor &, const gdd & ) -{ - return S_cas_internal; -} - -casMonitor & casCoreClient::monitorFactory ( - casChannelI & chan, - caResId clientId, - const unsigned long count, - const unsigned type, - const casEventMask & mask ) -{ - casMonitor & mon = this->ctx.getServer()->casMonitorFactory ( - chan, clientId, count, type, mask, *this ); - this->eventSys.installMonitor (); - return mon; -} - -void casCoreClient::destroyMonitor ( casMonitor & mon ) -{ - this->eventSys.removeMonitor (); - assert ( mon.numEventsQueued() == 0 ); - this->ctx.getServer()->casMonitorDestroy ( mon ); -} - -void casCoreClient::installAsynchIO ( casAsyncPVAttachIOI & io ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->ioList.add ( io ); -} - -void casCoreClient::uninstallAsynchIO ( casAsyncPVAttachIOI & io ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->ioList.remove ( io ); -} - -void casCoreClient::installAsynchIO ( casAsyncPVExistIOI & io ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->ioList.add ( io ); -} - -void casCoreClient::uninstallAsynchIO ( casAsyncPVExistIOI & io ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->ioList.remove ( io ); -} diff --git a/src/ca/legacy/pcas/generic/casCoreClient.h b/src/ca/legacy/pcas/generic/casCoreClient.h deleted file mode 100644 index f19f282a9..000000000 --- a/src/ca/legacy/pcas/generic/casCoreClient.h +++ /dev/null @@ -1,249 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 casCoreClienth -#define casCoreClienth - -#include "caServerI.h" -#include "ioBlocked.h" -#include "casMonitor.h" -#include "casEventSys.h" -#include "casCtx.h" - -class casClientMutex : public epicsMutex { -}; - -// -// casCoreClient -// (this will eventually support direct communication -// between the client lib and the server lib) -// -class casCoreClient : public ioBlocked, - private casMonitorCallbackInterface { -public: - casCoreClient ( caServerI & serverInternal ); - virtual ~casCoreClient (); - virtual void show ( unsigned level ) const; - - void installAsynchIO ( class casAsyncPVAttachIOI & io ); - void uninstallAsynchIO ( class casAsyncPVAttachIOI & io ); - void installAsynchIO ( class casAsyncPVExistIOI & io ); - void uninstallAsynchIO ( class casAsyncPVExistIOI & io ); - - caServerI & getCAS () const; - - // - // one virtual function for each CA request type that has - // asynchronous completion - // - virtual caStatus asyncSearchResponse ( - epicsGuard < casClientMutex > &, const caNetAddr & outAddr, - const caHdrLargeArray &, const pvExistReturn &, - ca_uint16_t protocolRevision, ca_uint32_t sequenceNumber ); - virtual caStatus createChanResponse ( - epicsGuard < casClientMutex > &, - casCtx &, const pvAttachReturn &); - virtual caStatus readResponse ( - epicsGuard < casClientMutex > &, - casChannelI *, const caHdrLargeArray &, - const gdd &, const caStatus ); - virtual caStatus readNotifyResponse ( - epicsGuard < casClientMutex > &, - casChannelI *, const caHdrLargeArray &, - const gdd &, const caStatus ); - virtual caStatus writeResponse ( - epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray &, const caStatus ); - virtual caStatus writeNotifyResponse ( - epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray &, const caStatus ); - virtual caStatus monitorResponse ( - epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray &, const gdd &, - const caStatus status ); - virtual caStatus accessRightsResponse ( - epicsGuard < casClientMutex > &, casChannelI * ); - virtual caStatus enumPostponedCreateChanResponse ( - epicsGuard < casClientMutex > &, - casChannelI &, const caHdrLargeArray & ); - virtual caStatus channelCreateFailedResp ( - epicsGuard < casClientMutex > &, - const caHdrLargeArray &, const caStatus createStatus ); - virtual caStatus channelDestroyEventNotify ( - epicsGuard < casClientMutex > & guard, - casChannelI * const pChan, ca_uint32_t sid ); - virtual void casChannelDestroyFromInterfaceNotify ( - casChannelI & chan, bool immediateDestroyNeeded ); - - virtual ca_uint16_t protocolRevision () const = 0; - - // used only with DG clients - virtual caNetAddr fetchLastRecvAddr () const; - virtual ca_uint32_t datagramSequenceNumber () const; - - bool okToStartAsynchIO (); - void setDestroyPending (); - - casProcCond eventSysProcess(); - - caStatus addToEventQueue ( casAsyncIOI &, - bool & onTheQueue, bool & posted ); - void removeFromEventQueue ( casAsyncIOI &, - bool & onTheEventQueue ); - void addToEventQueue ( - casChannelI &, bool & inTheEventQueue ); - void removeFromEventQueue ( class casChannelI &, - bool & inTheEventQueue ); - void addToEventQueue ( class channelDestroyEvent & ev ); - void enableEvents (); - void disableEvents (); - caStatus casMonitorCallBack ( - epicsGuard < casClientMutex > &, - casMonitor &, const gdd & ); - void postEvent ( tsDLList &, - const casEventMask &select, const gdd &event ); - - casMonitor & monitorFactory ( - casChannelI & , - caResId clientId, - const unsigned long count, - const unsigned type, - const casEventMask & ); - void destroyMonitor ( casMonitor & mon ); - - void casMonEventDestroy ( - casMonEvent &, epicsGuard < evSysMutex > & ); - -protected: - casEventSys eventSys; - mutable casClientMutex mutex; - casCtx ctx; - bool userStartedAsyncIO; - -private: - // for io that does not have a channel - tsDLList < casAsyncIOI > ioList; - - // not pure because the base class noop must be called - // when in the destructor - virtual void eventSignal (); - - casCoreClient ( const casCoreClient & ); - casCoreClient & operator = ( const casCoreClient & ); -}; - -inline caServerI & casCoreClient::getCAS() const -{ - return *this->ctx.getServer(); -} - -inline bool casCoreClient::okToStartAsynchIO () -{ - if ( ! this->userStartedAsyncIO ) { - this->userStartedAsyncIO = true; - return true; - } - return false; -} - -inline void casCoreClient::postEvent ( - tsDLList < casMonitor > & monitorList, - const casEventMask & select, const gdd & event ) -{ - bool signalNeeded = - this->eventSys.postEvent ( monitorList, select, event ); - if ( signalNeeded ) { - this->eventSignal (); - } -} - -inline casProcCond casCoreClient :: eventSysProcess () -{ - epicsGuard < casClientMutex > guard ( this->mutex ); - return this->eventSys.process ( guard ); -} - -inline caStatus casCoreClient::addToEventQueue ( casAsyncIOI & io, - bool & onTheQueue, bool & posted ) -{ - bool wakeupNeeded; - caStatus status = this->eventSys.addToEventQueue ( io, - onTheQueue, posted, wakeupNeeded ); - if ( wakeupNeeded ) { - this->eventSignal (); - } - return status; -} - -inline void casCoreClient::removeFromEventQueue ( - casAsyncIOI & io, bool & onTheEventQueue ) -{ - this->eventSys.removeFromEventQueue ( io, onTheEventQueue ); -} - -inline void casCoreClient::addToEventQueue ( - casChannelI & ev, bool & inTheEventQueue ) -{ - bool signalNeeded = - this->eventSys.addToEventQueue ( ev, inTheEventQueue ); - if ( signalNeeded ) { - this->eventSignal (); - } -} - -inline void casCoreClient::removeFromEventQueue ( class casChannelI & io, - bool & inTheEventQueue ) -{ - this->eventSys.removeFromEventQueue ( io, inTheEventQueue ); -} - -inline void casCoreClient::addToEventQueue ( class channelDestroyEvent & ev ) -{ - bool wakeUpNeeded = this->eventSys.addToEventQueue ( ev ); - if ( wakeUpNeeded ) { - this->eventSignal (); - } -} - -inline void casCoreClient::enableEvents () -{ - this->eventSys.eventsOn (); - this->eventSignal (); // wake up the event queue consumer -} - -inline void casCoreClient::disableEvents () -{ - bool signalNeeded = - this->eventSys.eventsOff (); - if ( signalNeeded ) { - this->eventSignal (); - } -} - -inline void casCoreClient::setDestroyPending () -{ - this->eventSys.setDestroyPending (); - this->eventSignal (); -} - -inline void casCoreClient::casMonEventDestroy ( - casMonEvent & ev, epicsGuard < evSysMutex > & guard ) -{ - this->eventSys.casMonEventDestroy ( ev, guard ); -} - -#endif // casCoreClienth - diff --git a/src/ca/legacy/pcas/generic/casCtx.cc b/src/ca/legacy/pcas/generic/casCtx.cc deleted file mode 100644 index c833e9b21..000000000 --- a/src/ca/legacy/pcas/generic/casCtx.cc +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 epicsExportSharedSymbols -#include "casCtx.h" -#include "caServerI.h" -#include "casCoreClient.h" -#include "casChannelI.h" - -casCtx::casCtx() : - pData ( NULL ), pCAS ( NULL ), pClient ( NULL ), - pChannel ( NULL ), pPV ( NULL ), nAsyncIO ( 0u ) -{ - memset(&this->msg, 0, sizeof(this->msg)); -} - -void casCtx::show ( unsigned level ) const -{ - printf ( "casCtx at %p\n", - static_cast ( this ) ); - if (level >= 3u) { - printf ("\tpMsg = %p\n", - static_cast ( &this->msg ) ); - printf ("\tpData = %p\n", - static_cast ( pData ) ); - printf ("\tpCAS = %p\n", - static_cast ( pCAS ) ); - printf ("\tpClient = %p\n", - static_cast ( pClient ) ); - printf ("\tpChannel = %p\n", - static_cast ( pChannel ) ); - printf ("\tpPV = %p\n", - static_cast ( pPV ) ); - } -} - diff --git a/src/ca/legacy/pcas/generic/casCtx.h b/src/ca/legacy/pcas/generic/casCtx.h deleted file mode 100644 index eab644685..000000000 --- a/src/ca/legacy/pcas/generic/casCtx.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. -* EPICS BASE 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 casCtxh -#define casCtxh - -#include "caHdrLargeArray.h" - -class casStrmClient; - -class casCtx { -public: - casCtx(); - const caHdrLargeArray * getMsg () const; - void * getData () const; - class caServerI * getServer () const; - class casCoreClient * getClient () const; - class casPVI * getPV () const; - class casChannelI * getChannel () const; - void setMsg ( const caHdrLargeArray &, void * pBody ); - void setServer ( class caServerI * p ); - void setClient ( class casCoreClient * p ); - void setPV ( class casPVI * p ); - void setChannel ( class casChannelI * p ); - void show ( unsigned level ) const; -private: - caHdrLargeArray msg; // ca message header - void * pData; // pointer to data following header - caServerI * pCAS; - casCoreClient * pClient; - casChannelI * pChannel; - casPVI * pPV; - unsigned nAsyncIO; // checks for improper use of async io - friend class casStrmClient; -}; - -inline const caHdrLargeArray * casCtx::getMsg() const -{ - return & this->msg; -} - -inline void * casCtx::getData() const -{ - return this->pData; -} - -inline caServerI * casCtx::getServer() const -{ - return this->pCAS; -} - -inline casCoreClient * casCtx::getClient() const -{ - return this->pClient; -} - -inline casPVI * casCtx::getPV() const -{ - return this->pPV; -} - -inline casChannelI * casCtx::getChannel() const -{ - return this->pChannel; -} - -inline void casCtx::setMsg ( const caHdrLargeArray & msgIn, void * pBody ) -{ - this->msg = msgIn; - this->pData = pBody; -} - -inline void casCtx::setServer(caServerI *p) -{ - this->pCAS = p; -} - -inline void casCtx::setClient(casCoreClient *p) -{ - this->pClient = p; -} - -inline void casCtx::setPV(casPVI *p) -{ - this->pPV = p; -} - -inline void casCtx::setChannel(casChannelI *p) -{ - this->pChannel = p; -} - -#endif // casCtxh diff --git a/src/ca/legacy/pcas/generic/casCtxIL.h b/src/ca/legacy/pcas/generic/casCtxIL.h deleted file mode 100644 index b0c89fe98..000000000 --- a/src/ca/legacy/pcas/generic/casCtxIL.h +++ /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 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 casCtxILh -#define casCtxILh - -#include "osiWireFormat.h" - -// -// casCtx::casCtx() -// -inline casCtx::casCtx() : - pData(NULL), pCAS(NULL), pClient(NULL), - pChannel(NULL), pPV(NULL), nAsyncIO(0u) -{ - memset(&this->msg, 0, sizeof(this->msg)); -} - -// -// casCtx::getMsg() -// -inline const caHdrLargeArray * casCtx::getMsg() const -{ - return & this->msg; -} - -// -// casCtx::getData() -// -inline void * casCtx::getData() const -{ - return this->pData; -} - -// -// casCtx::getServer() -// -inline caServerI * casCtx::getServer() const -{ - return this->pCAS; -} - -// -// casCtx::getClient() -// -inline casCoreClient * casCtx::getClient() const -{ - return this->pClient; -} - -// -// casCtx::getPV() -// -inline casPVI * casCtx::getPV() const -{ - return this->pPV; -} - -// -// casCtx::getChannel() -// -inline casChannelI * casCtx::getChannel() const -{ - return this->pChannel; -} - -// -// casCtx::setMsg() -// -inline void casCtx::setMsg ( const caHdrLargeArray & msgIn, void * pBody ) -{ - this->msg = msgIn; - this->pData = pBody; -} - -// -// casCtx::setServer() -// -inline void casCtx::setServer(caServerI *p) -{ - this->pCAS = p; -} - -// -// casCtx::setClient() -// -inline void casCtx::setClient(casCoreClient *p) -{ - this->pClient = p; -} - -// -// casCtx::setPV() -// -inline void casCtx::setPV(casPVI *p) -{ - this->pPV = p; -} - -// -// casCtx::setChannel() -// -inline void casCtx::setChannel(casChannelI *p) -{ - this->pChannel = p; -} - -#endif // casCtxILh - diff --git a/src/ca/legacy/pcas/generic/casDGClient.cc b/src/ca/legacy/pcas/generic/casDGClient.cc deleted file mode 100644 index 4cc05be32..000000000 --- a/src/ca/legacy/pcas/generic/casDGClient.cc +++ /dev/null @@ -1,974 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 "gddApps.h" -#include "caerr.h" -#include "osiWireFormat.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "casDGClient.h" -#include "osiPoolStatus.h" // osi pool monitoring functions - -casDGClient::pCASMsgHandler const casDGClient::msgHandlers[] = -{ - & casDGClient::versionAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - - & casDGClient::uknownMessageAction, - & casDGClient::searchAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction, - & casDGClient::uknownMessageAction -}; - -// -// casDGClient::casDGClient() -// -casDGClient::casDGClient ( caServerI & serverIn, clientBufMemoryManager & mgrIn ) : - casCoreClient ( serverIn ), - in ( *this, mgrIn, MAX_UDP_RECV + sizeof ( cadg ) ), - out ( *this, mgrIn ), - seqNoOfReq ( 0 ), - minor_version_number ( 0 ) -{ -} - -// -// casDGClient::~casDGClient() -// (virtual destructor) -// -casDGClient::~casDGClient() -{ -} - -// -// casDGClient::destroy() -// -void casDGClient::destroy() -{ - printf("Attempt to destroy the DG client was ignored\n"); -} - -// -// casDGClient::show() -// -void casDGClient::show (unsigned level) const -{ - printf ( "casDGClient at %p\n", - static_cast ( this ) ); - if (level>=1u) { - char buf[64]; - this->hostName (buf, sizeof(buf)); - printf ("Client Host=%s\n", buf); - this->casCoreClient::show ( level - 1u ); - this->in.show ( level - 1u ); - this->out.show ( level - 1u ); - } -} - -// -// casDGClient::uknownMessageAction() -// -caStatus casDGClient::uknownMessageAction () -{ - const caHdrLargeArray * mp = this->ctx.getMsg(); - - if ( this->getCAS().getDebugLevel() > 3u ) { - char pHostName[64u]; - this->lastRecvAddr.stringConvert ( pHostName, sizeof ( pHostName ) ); - - caServerI::dumpMsg ( pHostName, "?", mp, this->ctx.getData(), - "bad request code=%u in DG\n", mp->m_cmmd ); - } - - return S_cas_badProtocol; -} - -// -// casDGClient::searchAction() -// -caStatus casDGClient::searchAction() -{ - const caHdrLargeArray *mp = this->ctx.getMsg(); - const char *pChanName = static_cast ( this->ctx.getData() ); - caStatus status; - - if (!CA_VSUPPORTED(mp->m_count)) { - if ( this->getCAS().getDebugLevel() > 3u ) { - char pHostName[64u]; - this->hostName ( pHostName, sizeof ( pHostName ) ); - printf ( "\"%s\" is searching for \"%s\" but is too old\n", - pHostName, pChanName ); - } - return S_cas_badProtocol; - } - - // - // check the sanity of the message - // - if ( mp->m_postsize <= 1 ) { - char pHostName[64u]; - this->lastRecvAddr.stringConvert ( pHostName, sizeof ( pHostName ) ); - caServerI::dumpMsg ( pHostName, "?", mp, this->ctx.getData(), - "empty PV name extension in UDP search request?\n" ); - return S_cas_success; - } - - if ( pChanName[0] == '\0' ) { - char pHostName[64u]; - this->lastRecvAddr.stringConvert ( pHostName, sizeof ( pHostName ) ); - caServerI::dumpMsg ( pHostName, "?", mp, this->ctx.getData(), - "zero length PV name in UDP search request?\n" ); - return S_cas_success; - } - - // check for an unterminated string before calling server tool - // by searching backwards through the string (some early versions - // of the client library might not be setting the pad bytes to nill) - for ( unsigned i = mp->m_postsize-1; pChanName[i] != '\0'; i-- ) { - if ( i <= 1 ) { - char pHostName[64u]; - this->lastRecvAddr.stringConvert ( pHostName, sizeof ( pHostName ) ); - caServerI::dumpMsg ( pHostName, "?", mp, this->ctx.getData(), - "unterminated PV name in UDP search request?\n" ); - return S_cas_success; - } - } - - if ( this->getCAS().getDebugLevel() > 6u ) { - char pHostName[64u]; - this->hostName ( pHostName, sizeof ( pHostName ) ); - printf ( "\"%s\" is searching for \"%s\"\n", - pHostName, pChanName ); - } - - // - // verify that we have sufficent memory for a PV and a - // monitor prior to calling PV exist test so that when - // the server runs out of memory we dont reply to - // search requests, and therefore dont thrash through - // caServer::pvExistTest() and casCreatePV::pvAttach() - // - if ( ! osiSufficentSpaceInPool ( 0 ) ) { - return S_cas_success; - } - - // - // ask the server tool if this PV exists - // - this->userStartedAsyncIO = false; - pvExistReturn pver = - this->getCAS()->pvExistTest ( this->ctx, this->lastRecvAddr, pChanName ); - - // - // prevent problems when they initiate - // async IO but dont return status - // indicating so (and vise versa) - // - if ( this->userStartedAsyncIO ) { - if ( pver.getStatus() != pverAsyncCompletion ) { - errMessage (S_cas_badParameter, - "- assuming asynch IO status from caServer::pvExistTest()"); - } - status = S_cas_success; - } - else { - // - // otherwise we assume sync IO operation was initiated - // - switch ( pver.getStatus() ) { - case pverExistsHere: - status = this->searchResponse (*mp, pver); - break; - - case pverDoesNotExistHere: - status = S_cas_success; - break; - - case pverAsyncCompletion: - errMessage (S_cas_badParameter, - "- unexpected asynch IO status from caServer::pvExistTest() ignored"); - status = S_cas_success; - break; - - default: - errMessage (S_cas_badParameter, - "- invalid return from caServer::pvExistTest() ignored"); - status = S_cas_success; - break; - } - } - return status; -} - -// -// caStatus casDGClient::searchResponse() -// -caStatus casDGClient::searchResponse ( const caHdrLargeArray & msg, - const pvExistReturn & retVal ) -{ - caStatus status; - - if ( retVal.getStatus() != pverExistsHere ) { - return S_cas_success; - } - - // - // starting with V4.1 the count field is used (abused) - // by the client to store the minor version number of - // the client. - // - // Old versions expect alloc of channel in response - // to a search request. This is no longer supported. - // - if ( !CA_V44(msg.m_count) ) { - char pName[64u]; - this->hostName (pName, sizeof (pName)); - errlogPrintf ( - "client \"%s\" using EPICS R3.11 CA connect protocol was ignored\n", - pName); - // - // old connect protocol was dropped when the - // new API was added to the server (they must - // now use clients at EPICS 3.12 or higher) - // - status = this->sendErr ( &msg, ECA_DEFUNCT, invalidResID, - "R3.11 connect sequence from old client was ignored" ); - return status; - } - - // - // cid field is abused to carry the IP - // address in CA_V48 or higher - // (this allows a CA servers to serve - // as a directory service) - // - // data type field is abused to carry the IP - // port number here CA_V44 or higher - // (this allows multiple CA servers on one - // host) - // - ca_uint32_t serverAddr; - ca_uint16_t serverPort; - if ( CA_V48( msg.m_count ) ) { - struct sockaddr_in ina; - if ( retVal.addrIsValid() ) { - caNetAddr addr = retVal.getAddr(); - ina = addr.getSockIP(); - // - // If they dont specify a port number then the default - // CA server port is assumed when it it is a server - // address redirect (it is never correct to use this - // server's port when it is a redirect). - // - if (ina.sin_port==0u) { - ina.sin_port = htons ( CA_SERVER_PORT ); - } - } - else { - caNetAddr addr = this->serverAddress (); - ina = addr.getSockIP(); - // - // We dont fill in the servers address here - // because the server was not bound to a particular - // interface, and we would need to waste CPU performing - // the following steps to determine the interface that - // will be used: - // - // o connect UDP socket to the destination IP - // o perform a getsockname() call - // o disconnect UDP socket from the destination IP - // - if ( ina.sin_addr.s_addr == INADDR_ANY ) { - ina.sin_addr.s_addr = htonl ( ~0U ); - } - } - serverAddr = ntohl ( ina.sin_addr.s_addr ); - serverPort = ntohs ( ina.sin_port ); - } - else { - caNetAddr addr = this->serverAddress (); - struct sockaddr_in inetAddr = addr.getSockIP(); - serverAddr = ~0U; - serverPort = ntohs ( inetAddr.sin_port ); - } - - ca_uint16_t * pMinorVersion; - epicsGuard < epicsMutex > guard ( this->mutex ); - status = this->out.copyInHeader ( CA_PROTO_SEARCH, - sizeof ( *pMinorVersion ), serverPort, 0, - serverAddr, msg.m_available, - reinterpret_cast ( &pMinorVersion ) ); - // - // 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. - // - if ( status == S_cas_success ) { - AlignedWireRef < epicsUInt16 > tmp ( *pMinorVersion ); - tmp = CA_MINOR_PROTOCOL_REVISION; - this->out.commitMsg (); - } - - return status; -} - -// -// casDGClient::searchFailResponse() -// (only when requested by the client -// - when it isnt a reply to a broadcast) -// -caStatus casDGClient::searchFailResponse ( const caHdrLargeArray * mp ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->out.copyInHeader ( CA_PROTO_NOT_FOUND, 0, - mp->m_dataType, mp->m_count, mp->m_cid, mp->m_available, 0 ); - - this->out.commitMsg (); - - return S_cas_success; -} - -/* - * casDGClient::versionAction() - */ -caStatus casDGClient::versionAction () -{ - const caHdrLargeArray * mp = this->ctx.getMsg(); - - if (!CA_VSUPPORTED(mp->m_count)) { - if ( this->getCAS().getDebugLevel() > 3u ) { - char pHostName[64u]; - this->hostName ( pHostName, sizeof ( pHostName ) ); - printf ( "\"%s\" is too old\n", - pHostName ); - } - return S_cas_badProtocol; - } - if ( mp->m_count != 0 ) { - this->minor_version_number = static_cast ( mp->m_count ); - if ( CA_V411 ( mp->m_count ) ) { - this->seqNoOfReq = mp->m_cid; - } - else { - this->seqNoOfReq = 0; - } - } - return S_cas_success; -} - -// -// casDGClient::sendBeacon() -// (implemented here because this has knowledge of the protocol) -// -void casDGClient::sendBeacon ( ca_uint32_t beaconNumber ) -{ - union { - caHdr msg; - char buf; - }; - - // - // create the message - // - memset ( & buf, 0, sizeof ( msg ) ); - AlignedWireRef < epicsUInt16 > ( msg.m_cmmd ) = CA_PROTO_RSRV_IS_UP; - AlignedWireRef < epicsUInt16 > ( msg.m_dataType ) = CA_MINOR_PROTOCOL_REVISION; - AlignedWireRef < epicsUInt32 > ( msg.m_cid ) = beaconNumber; - - // - // send it to all addresses on the beacon list, - // but let the IO specific code set the address - // field and the port field - // - this->sendBeaconIO ( buf, sizeof (msg), msg.m_count, msg.m_available ); -} - -// -// casDGClient::xSend() -// -outBufClient::flushCondition casDGClient::xSend ( char *pBufIn, - bufSizeT nBytesToSend, bufSizeT & nBytesSent ) -{ - bufSizeT totalBytes = 0; - while ( totalBytes < nBytesToSend ) { - cadg *pHdr = reinterpret_cast < cadg * > ( & pBufIn[totalBytes] ); - - assert ( totalBytes <= bufSizeT_MAX - pHdr->cadg_nBytes ); - assert ( totalBytes + pHdr->cadg_nBytes <= nBytesToSend ); - - char * pDG = reinterpret_cast < char * > ( pHdr + 1 ); - unsigned sizeDG = pHdr->cadg_nBytes - sizeof ( *pHdr ); - - if ( pHdr->cadg_addr.isValid() ) { - outBufClient::flushCondition stat = - this->osdSend ( pDG, sizeDG, pHdr->cadg_addr ); - if ( stat != outBufClient::flushProgress ) { - break; - } - } - - totalBytes += pHdr->cadg_nBytes; - } - - if ( totalBytes ) { - // - // !! this time fetch may be slowing things down !! - // - //this->lastSendTS = epicsTime::getCurrent(); - nBytesSent = totalBytes; - return outBufClient::flushProgress; - } - else { - return outBufClient::flushNone; - } -} - -// -// casDGClient::xRecv () -// -inBufClient::fillCondition casDGClient::xRecv (char *pBufIn, bufSizeT nBytesToRecv, - fillParameter parm, bufSizeT &nByesRecv) -{ - const char *pAfter = pBufIn + nBytesToRecv; - char *pCurBuf = pBufIn; - bufSizeT nDGBytesRecv; - inBufClient::fillCondition stat; - cadg *pHdr; - - while (pAfter-pCurBuf >= static_cast(MAX_UDP_RECV+sizeof(cadg))) { - pHdr = reinterpret_cast < cadg * > ( pCurBuf ); - stat = this->osdRecv ( reinterpret_cast < char * > ( pHdr + 1 ), - MAX_UDP_RECV, parm, nDGBytesRecv, pHdr->cadg_addr); - if (stat==casFillProgress) { - pHdr->cadg_nBytes = nDGBytesRecv + sizeof(*pHdr); - pCurBuf += pHdr->cadg_nBytes; - // - // !! this time fetch may be slowing things down !! - // - //this->lastRecvTS = epicsTime::getCurrent(); - } - else { - break; - } - } - - nDGBytesRecv = pCurBuf - pBufIn; - if (nDGBytesRecv) { - nByesRecv = nDGBytesRecv; - return casFillProgress; - } - else { - return casFillNone; - } -} - -// -// casDGClient::asyncSearchResp() -// -// -// this results in many small UDP frames which unfortunately -// isnt particularly efficient -// -caStatus casDGClient::asyncSearchResponse ( - epicsGuard < casClientMutex > &, const caNetAddr & outAddr, - const caHdrLargeArray & msg, const pvExistReturn & retVal, - ca_uint16_t protocolRevision, ca_uint32_t sequenceNumber ) -{ - if ( retVal.getStatus() != pverExistsHere ) { - return S_cas_success; - } - - void * pRaw; - const outBufCtx outctx = this->out.pushCtx - ( sizeof(cadg), MAX_UDP_SEND, pRaw ); - if ( outctx.pushResult() != outBufCtx::pushCtxSuccess ) { - return S_cas_sendBlocked; - } - - cadg * pRespHdr = static_cast < cadg * > ( pRaw ); - - // insert version header at the start of the reply message - this->sendVersion (); - - caHdr * pMsg = reinterpret_cast < caHdr * > ( pRespHdr + 1 ); - assert ( ntohs ( pMsg->m_cmmd ) == CA_PROTO_VERSION ); - if ( CA_V411 ( protocolRevision ) ) { - pMsg->m_cid = htonl ( sequenceNumber ); - pMsg->m_dataType = htons ( sequenceNoIsValid ); - } - - caStatus stat = this->searchResponse ( msg, retVal ); - - pRespHdr->cadg_nBytes = this->out.popCtx (outctx) + sizeof ( *pRespHdr ); - if ( pRespHdr->cadg_nBytes > sizeof ( *pRespHdr ) + sizeof (caHdr) ) { - pRespHdr->cadg_addr = outAddr; - this->out.commitRawMsg ( pRespHdr->cadg_nBytes ); - } - - return stat; -} - -// -// casDGClient::processDG () -// -caStatus casDGClient::processDG () -{ - bufSizeT bytesLeft; - caStatus status; - - status = S_cas_success; - while ( ( bytesLeft = this->in.bytesPresent() ) ) { - bufSizeT dgInBytesConsumed; - const cadg * pReqHdr = reinterpret_cast < cadg * > ( this->in.msgPtr () ); - - if (bytesLeftin.removeMsg (bytesLeft); - errlogPrintf ("casDGClient::processMsg: incomplete DG header?"); - status = S_cas_internal; - break; - } - - epicsGuard < epicsMutex > guard ( this->mutex ); - - // - // start a DG context in the output protocol stream - // and grab the send lock - // - void *pRaw; - const outBufCtx outctx = this->out.pushCtx ( sizeof ( cadg ), MAX_UDP_SEND, pRaw ); - if ( outctx.pushResult() != outBufCtx::pushCtxSuccess ) { - status = S_cas_sendBlocked; - break; - } - - // insert version header at the start of the reply message - this->sendVersion (); - - cadg * pRespHdr = static_cast < cadg * > ( pRaw ); - - // - // select the next DG in the input stream and start processing it - // - const bufSizeT reqBodySize = pReqHdr->cadg_nBytes - sizeof (*pReqHdr); - - const inBufCtx inctx = this->in.pushCtx ( sizeof (*pReqHdr), reqBodySize); - if ( inctx.pushResult() != inBufCtx::pushCtxSuccess ) { - this->in.removeMsg ( bytesLeft ); - this->out.popCtx ( outctx ); - errlogPrintf ("casDGClient::processMsg: incomplete DG?\n"); - status = S_cas_internal; - break; - } - - this->lastRecvAddr = pReqHdr->cadg_addr; - this->seqNoOfReq = 0; - this->minor_version_number = 0; - - status = this->processMsg (); - pRespHdr->cadg_nBytes = this->out.popCtx ( outctx ) + sizeof ( *pRespHdr ); - dgInBytesConsumed = this->in.popCtx ( inctx ); - - if ( dgInBytesConsumed > 0 ) { - - // - // at this point processMsg() bailed out because: - // a) it used all of the incoming DG or - // b) it used all of the outgoing DG - // - // In either case commit the DG to the protocol stream and - // release the send lock - // - // if there are not additional messages passed the version header - // then discard the message - if ( pRespHdr->cadg_nBytes > sizeof ( *pRespHdr ) + sizeof (caHdr) ) { - pRespHdr->cadg_addr = pReqHdr->cadg_addr; - - caHdr * pMsg = reinterpret_cast < caHdr * > ( pRespHdr + 1 ); - assert ( ntohs ( pMsg->m_cmmd ) == CA_PROTO_VERSION ); - - if ( CA_V411 ( this->minor_version_number ) ) { - pMsg->m_cid = htonl ( this->seqNoOfReq ); - pMsg->m_dataType = htons ( sequenceNoIsValid ); - } - - this->out.commitRawMsg ( pRespHdr->cadg_nBytes ); - } - - // - // check to see that all of the incoming UDP frame was used - // - if ( dgInBytesConsumed < reqBodySize ) { - // - // remove the bytes in the body that were consumed, - // but _not_ the header bytes - // - this->in.removeMsg (dgInBytesConsumed); - - // - // slide the UDP header forward and correct the byte count - // - { - cadg *pReqHdrMove; - cadg copy = *pReqHdr; - pReqHdrMove = reinterpret_cast < cadg * > ( this->in.msgPtr () ); - pReqHdrMove->cadg_addr = copy.cadg_addr; - pReqHdrMove->cadg_nBytes = copy.cadg_nBytes - dgInBytesConsumed; - } - } - else { - // - // remove the header and all of the body - // - this->in.removeMsg ( pReqHdr->cadg_nBytes ); - } - } - - if ( status != S_cas_success ) { - break; - } - } - return status; -} - -// -// casDGClient::getDebugLevel() -// -unsigned casDGClient::getDebugLevel() const -{ - return this->getCAS().getDebugLevel(); -} - -// -// casDGClient::fetchLastRecvAddr () -// -caNetAddr casDGClient::fetchLastRecvAddr () const -{ - return this->lastRecvAddr; -} - -// -// casDGClient::datagramSequenceNumber () -// -ca_uint32_t casDGClient::datagramSequenceNumber () const -{ - return this->seqNoOfReq; -} - -// -// casDGClient::hostName() -// -void casDGClient::hostName ( char *pBufIn, unsigned bufSizeIn ) const -{ - this->lastRecvAddr.stringConvert ( pBufIn, bufSizeIn ); -} - -// send minor protocol revision to the client -void casDGClient::sendVersion () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - caStatus status = this->out.copyInHeader ( CA_PROTO_VERSION, 0, - 0, CA_MINOR_PROTOCOL_REVISION, 0, 0, 0 ); - if ( ! status ) { - this->out.commitMsg (); - } -} - -bool casDGClient::inBufFull () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->in.full (); -} - -void casDGClient::inBufFill ( inBufClient::fillParameter parm ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->in.fill ( parm ); -} - -bufSizeT casDGClient :: - inBufBytesPending () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->in.bytesPresent (); -} - -bufSizeT casDGClient :: - outBufBytesPending () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->out.bytesPresent (); -} - -outBufClient::flushCondition casDGClient::flush () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->out.flush (); -} - -// -// casDGClient::processMsg () -// process any messages in the in buffer -// -caStatus casDGClient::processMsg () -{ - int status = S_cas_success; - - try { - unsigned bytesLeft; - while ( ( bytesLeft = this->in.bytesPresent() ) ) { - caHdrLargeArray msgTmp; - unsigned msgSize; - ca_uint32_t hdrSize; - char * rawMP; - { - // - // copy as raw bytes in order to avoid - // alignment problems - // - caHdr smallHdr; - if ( bytesLeft < sizeof ( smallHdr ) ) { - break; - } - - rawMP = this->in.msgPtr (); - memcpy ( & smallHdr, rawMP, sizeof ( smallHdr ) ); - - ca_uint32_t payloadSize = AlignedWireRef < epicsUInt16 > ( smallHdr.m_postsize ); - ca_uint32_t nElem = AlignedWireRef < epicsUInt16 > ( smallHdr.m_count ); - if ( payloadSize != 0xffff && nElem != 0xffff ) { - hdrSize = sizeof ( smallHdr ); - } - else { - ca_uint32_t LWA[2]; - hdrSize = sizeof ( smallHdr ) + sizeof ( LWA ); - if ( bytesLeft < hdrSize ) { - break; - } - // - // copy as raw bytes in order to avoid - // alignment problems - // - memcpy ( LWA, rawMP + sizeof ( caHdr ), sizeof( LWA ) ); - payloadSize = AlignedWireRef < epicsUInt32 > ( LWA[0] ); - nElem = AlignedWireRef < epicsUInt32 > ( LWA[1] ); - } - - msgTmp.m_cmmd = AlignedWireRef < epicsUInt16 > ( smallHdr.m_cmmd ); - msgTmp.m_postsize = payloadSize; - msgTmp.m_dataType = AlignedWireRef < epicsUInt16 > ( smallHdr.m_dataType ); - msgTmp.m_count = nElem; - msgTmp.m_cid = AlignedWireRef < epicsUInt32 > ( smallHdr.m_cid ); - msgTmp.m_available = AlignedWireRef < epicsUInt32 > ( smallHdr.m_available ); - - if ( payloadSize & 0x7 ) { - status = this->sendErr ( - & msgTmp, invalidResID, ECA_INTERNAL, - "CAS: Datagram request wasn't 8 byte aligned" ); - this->in.removeMsg ( bytesLeft ); - break; - } - - msgSize = hdrSize + payloadSize; - if ( bytesLeft < msgSize ) { - if ( msgSize > this->in.bufferSize() ) { - status = this->sendErr ( & msgTmp, invalidResID, ECA_TOLARGE, - "client's request didnt fit within the CA server's message buffer" ); - this->in.removeMsg ( bytesLeft ); - } - break; - } - - this->ctx.setMsg ( msgTmp, rawMP + hdrSize ); - - if ( this->getCAS().getDebugLevel() > 5u ) { - char pHostName[64u]; - this->lastRecvAddr.stringConvert ( pHostName, sizeof ( pHostName ) ); - caServerI::dumpMsg ( pHostName, "?", - & msgTmp, rawMP + hdrSize, 0 ); - } - - } - - // - // Reset the context to the default - // (guarantees that previous message does not get mixed - // up with the current message) - // - this->ctx.setChannel ( NULL ); - this->ctx.setPV ( NULL ); - - // - // Call protocol stub - // - casDGClient::pCASMsgHandler pHandler; - if ( msgTmp.m_cmmd < NELEMENTS ( casDGClient::msgHandlers ) ) { - pHandler = this->casDGClient::msgHandlers[msgTmp.m_cmmd]; - } - else { - pHandler = & casDGClient::uknownMessageAction; - } - status = ( this->*pHandler ) (); - if ( status ) { - this->in.removeMsg ( this->in.bytesPresent() ); - break; - } - - this->in.removeMsg ( msgSize ); - } - } - catch ( std::exception & except ) { - this->in.removeMsg ( this->in.bytesPresent() ); - this->sendErr ( - this->ctx.getMsg(), invalidResID, ECA_INTERNAL, - "C++ exception \"%s\" in CA circuit server", - except.what () ); - status = S_cas_internal; - } - catch (...) { - this->in.removeMsg ( this->in.bytesPresent() ); - this->sendErr ( - this->ctx.getMsg(), invalidResID, ECA_INTERNAL, - "unexpected C++ exception in CA datagram server" ); - status = S_cas_internal; - } - - return status; -} - -// -// casDGClient::sendErr() -// -caStatus casDGClient::sendErr ( const caHdrLargeArray *curp, - ca_uint32_t cid, const int reportedStatus, const char *pformat, ... ) -{ - unsigned stringSize; - char msgBuf[1024]; /* allocate plenty of space for the message string */ - if ( pformat ) { - va_list args; - va_start ( args, pformat ); - int status = vsprintf ( msgBuf, pformat, args ); - if ( status < 0 ) { - errPrintf (S_cas_internal, __FILE__, __LINE__, - "bad sendErr(%s)", pformat); - stringSize = 0u; - } - else { - stringSize = 1u + (unsigned) status; - } - va_end ( args ); - } - else { - stringSize = 0u; - } - - unsigned hdrSize = sizeof ( caHdr ); - if ( ( curp->m_postsize >= 0xffff || curp->m_count >= 0xffff ) && - CA_V49( this->minor_version_number ) ) { - hdrSize += 2 * sizeof ( ca_uint32_t ); - } - - caHdr * pReqOut; - epicsGuard < epicsMutex > guard ( this->mutex ); - caStatus status = this->out.copyInHeader ( CA_PROTO_ERROR, - hdrSize + stringSize, 0, 0, cid, reportedStatus, - reinterpret_cast ( & pReqOut ) ); - if ( ! status ) { - char * pMsgString; - - /* - * copy back the request protocol - * (in network byte order) - */ - if ( ( curp->m_postsize >= 0xffff || curp->m_count >= 0xffff ) && - CA_V49( this->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 ); - } - 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 ); - } - - /* - * add their context string into the protocol - */ - memcpy ( pMsgString, msgBuf, stringSize ); - - this->out.commitMsg (); - } - - return S_cas_success; -} - - -// -// echoAction() -// -caStatus casDGClient::echoAction () -{ - const caHdrLargeArray * mp = this->ctx.getMsg(); - const void * dp = this->ctx.getData(); - void * pPayloadOut; - - epicsGuard < epicsMutex > guard ( this->mutex ); - caStatus status = this->out.copyInHeader ( mp->m_cmmd, mp->m_postsize, - mp->m_dataType, mp->m_count, mp->m_cid, mp->m_available, - & pPayloadOut ); - if ( ! status ) { - memcpy ( pPayloadOut, dp, mp->m_postsize ); - this->out.commitMsg (); - } - return S_cas_success; -} diff --git a/src/ca/legacy/pcas/generic/casDGClient.h b/src/ca/legacy/pcas/generic/casDGClient.h deleted file mode 100644 index cac093380..000000000 --- a/src/ca/legacy/pcas/generic/casDGClient.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 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 casDGClienth -#define casDGClienth - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casDGClienth -# undef epicsExportSharedSymbols -#endif - -#include "epicsTime.h" - -#ifdef epicsExportSharedSymbols_casDGClienth -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casCoreClient.h" -#include "inBuf.h" -#include "outBuf.h" - -class casDGClient : public casCoreClient, public outBufClient, - public inBufClient { -public: - casDGClient ( class caServerI & serverIn, - clientBufMemoryManager & ); - virtual ~casDGClient (); - caStatus processMsg (); - void show ( unsigned level ) const; - void sendBeacon ( ca_uint32_t beaconNumber ); - virtual void sendBeaconIO ( char & msg, bufSizeT length, - aitUint16 & portField, aitUint32 & addrField ) = 0; - void destroy (); - unsigned getDebugLevel () const; - void hostName ( char * pBuf, unsigned bufSize ) const; - caNetAddr fetchLastRecvAddr () const; - virtual caNetAddr serverAddress () const = 0; - caStatus sendErr ( const caHdrLargeArray * curp, - ca_uint32_t cid, const int reportedStatus, - const char *pformat, ... ); - caStatus processDG (); -protected: - bool inBufFull () const; - void inBufFill ( inBufClient::fillParameter ); - bufSizeT inBufBytesPending () const; - bufSizeT outBufBytesPending () const; - outBufClient::flushCondition flush (); -private: - inBuf in; - outBuf out; - caNetAddr lastRecvAddr; - epicsTime lastSendTS; - epicsTime lastRecvTS; - ca_uint32_t seqNoOfReq; - ca_uint16_t minor_version_number; - - typedef caStatus ( casDGClient :: * pCASMsgHandler ) (); - static pCASMsgHandler const msgHandlers[CA_PROTO_LAST_CMMD+1u]; - - // one function for each CA request type - caStatus searchAction (); - caStatus uknownMessageAction (); - caStatus echoAction (); - - caStatus searchFailResponse ( const caHdrLargeArray *pMsg ); - caStatus searchResponse ( const caHdrLargeArray &, - const pvExistReturn & retVal ); - caStatus asyncSearchResponse ( - epicsGuard < casClientMutex > &, const caNetAddr & outAddr, - const caHdrLargeArray &, const pvExistReturn &, - ca_uint16_t protocolRevision, ca_uint32_t sequenceNumber ); - void sendVersion (); - outBufClient::flushCondition xSend ( char *pBufIn, bufSizeT nBytesToSend, - bufSizeT &nBytesSent ); - inBufClient::fillCondition xRecv ( char * pBufIn, bufSizeT nBytesToRecv, - fillParameter parm, bufSizeT & nByesRecv ); - virtual outBufClient::flushCondition osdSend ( - const char * pBuf, bufSizeT nBytesReq, const caNetAddr & addr ) = 0; - virtual inBufClient::fillCondition osdRecv ( char *pBuf, bufSizeT nBytesReq, - fillParameter parm, bufSizeT &nBytesActual, caNetAddr & addr ) = 0; - caStatus versionAction (); - ca_uint32_t datagramSequenceNumber () const; - ca_uint16_t protocolRevision () const; - struct cadg { - caNetAddr cadg_addr; // invalid address indicates pad - bufSizeT cadg_nBytes; - }; - casDGClient ( const casDGClient & ); - casDGClient & operator = ( const casDGClient & ); -}; - -inline ca_uint16_t casDGClient::protocolRevision () const -{ - return this->minor_version_number; -} - - -#endif // casDGClienth - diff --git a/src/ca/legacy/pcas/generic/casEvent.h b/src/ca/legacy/pcas/generic/casEvent.h deleted file mode 100644 index efe62b5b7..000000000 --- a/src/ca/legacy/pcas/generic/casEvent.h +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef casEventh -#define casEventh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casEventh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "tsDLList.h" - -#ifdef epicsExportSharedSymbols_casEventh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casdef.h" - -class casCoreClient; - -class evSysMutex; -class casClientMutex; -template < class MUTEX > class epicsGuard; - -class casEvent : public tsDLNode < casEvent > { -public: - virtual caStatus cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > &, - epicsGuard < evSysMutex > & ) = 0; -protected: - epicsShareFunc virtual ~casEvent(); -}; - -#endif // casEventh - diff --git a/src/ca/legacy/pcas/generic/casEventMask.cc b/src/ca/legacy/pcas/generic/casEventMask.cc deleted file mode 100644 index a72ced06d..000000000 --- a/src/ca/legacy/pcas/generic/casEventMask.cc +++ /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 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 "errlog.h" - -#define epicsExportSharedSymbols -#include "casdef.h" -#include "epicsAssert.h" -#include "casEventRegistry.h" - -#ifdef TEST -#define verify(exp) ((exp) ? (void)0 : \ - epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) - -main () -{ - casEventRegistry reg; - casEventMask bill1 (reg, "bill"); - casEventMask bill2 (reg, "bill"); - casEventMask bill3 (reg, "bill"); - casEventMask art1 (reg, "art"); - casEventMask art2 (reg, "art"); - casEventMask jane (reg, "jane"); - casEventMask artBill; - casEventMask tmp; - - bill1.show(10u); - reg.show(10u); - bill2.show(10u); - reg.show(10u); - bill3.show(10u); - reg.show(10u); - jane.show(10u); - reg.show(10u); - art1.show(10u); - reg.show(10u); - art2.show(10u); - reg.show(10u); - - verify (bill1 == bill2); - verify (bill1 == bill3); - verify (jane != bill1); - verify (jane != art1); - verify (bill1 != art1); - verify (art1 == art2); - - artBill = art1 | bill1; - tmp = artBill & art1; - verify (tmp.eventsSelected()); - tmp = artBill & bill1; - verify (tmp.eventsSelected()); - tmp = artBill&jane; - verify (tmp.noEventsSelected()); -} -#endif - -casEventMask casEventRegistry::maskAllocator () -{ - casEventMask evMask; - - if ( this->maskBitAllocator < CHAR_BIT * sizeof ( evMask.mask ) ) { - evMask.mask = 1u << ( this->maskBitAllocator++ ); - } - return evMask; -} - -casEventMask casEventRegistry::registerEvent ( const char *pName ) -{ - // - // NOTE: pName outlives id here - // (so the refString option is ok) - // - stringId id ( pName, stringId::refString ); - casEventMaskEntry * pEntry; - casEventMask mask; - - pEntry = this->lookup ( id ); - if (pEntry) { - mask = *pEntry; - } - else { - mask = this->maskAllocator (); - if ( mask.mask == 0u ) { - errMessage ( S_cas_tooManyEvents, "casEventRegistry::registerEvent" ); - } - else { - pEntry = new casEventMaskEntry ( *this, mask, pName ); - mask = *pEntry; - } - } - return mask; -} - -void casEventMask::show ( unsigned level ) const -{ - if ( level > 0u ) { - printf ( "casEventMask = %x\n", this->mask ); - } -} - -casEventMask::casEventMask ( casEventRegistry & reg, const char * pName ) -{ - *this = reg.registerEvent ( pName ); -} - -void casEventRegistry::show ( unsigned level ) const -{ - if ( level > 1u ) { - printf ("casEventRegistry: bit allocator = %d\n", - this->maskBitAllocator); - } - this->resTable < casEventMaskEntry, stringId >::show ( level ); -} - -casEventMaskEntry::casEventMaskEntry ( - casEventRegistry & regIn, casEventMask maskIn, const char * pName ) : - casEventMask ( maskIn ), stringId ( pName ), reg ( regIn ) -{ - assert ( this->resourceName() != NULL ); - int stat = this->reg.add ( *this ); - assert ( stat == 0 ); -} - -casEventMaskEntry::~casEventMaskEntry() -{ - this->reg.remove ( *this ); -} - -void casEventMaskEntry::destroy () -{ - delete this; -} - -void casEventMaskEntry::show ( unsigned level ) const -{ - this->casEventMask::show ( level ); - this->stringId::show ( level ); -} - diff --git a/src/ca/legacy/pcas/generic/casEventMask.h b/src/ca/legacy/pcas/generic/casEventMask.h deleted file mode 100644 index d166ca918..000000000 --- a/src/ca/legacy/pcas/generic/casEventMask.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 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 casEventMaskH -#define casEventMaskH - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casEventMaskH -# undef epicsExportSharedSymbols -#endif -#include "resourceLib.h" -#ifdef epicsExportSharedSymbols_casEventMaskH -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class casEventRegistry; - -class epicsShareClass casEventMask { - friend inline casEventMask operator| (const casEventMask &lhs, - const casEventMask &rhs); - friend inline casEventMask operator& (const casEventMask &lhs, - const casEventMask &rhs); - friend inline int operator== (const casEventMask &lhs, - const casEventMask &rhs); - friend inline int operator!= (const casEventMask &lhs, - const casEventMask &rhs); - friend class casEventRegistry; -public: - void clear () - { - this->mask = 0u; - } - - casEventMask ( casEventRegistry ®, const char *pName ); - - casEventMask () - { - this->clear(); - } - - void show ( unsigned level ) const; - - bool eventsSelected () const - { - return this->mask != 0u; - } - bool noEventsSelected () const - { - return this->mask == 0u; - } - - inline void operator |= ( const casEventMask & rhs ); - inline void operator &= ( const casEventMask & rhs ); - -private: - unsigned mask; -}; - -inline casEventMask operator| (const casEventMask &lhs, const casEventMask &rhs) -{ - casEventMask result; - - result.mask = lhs.mask | rhs.mask; - return result; -} -inline casEventMask operator& (const casEventMask &lhs, const casEventMask &rhs) -{ - casEventMask result; - - result.mask = lhs.mask & rhs.mask; - return result; -} - -inline int operator== (const casEventMask &lhs, const casEventMask &rhs) -{ - return lhs.mask == rhs.mask; -} - -inline int operator!= (const casEventMask &lhs, const casEventMask &rhs) -{ - return lhs.mask != rhs.mask; -} - -inline void casEventMask::operator|= (const casEventMask &rhs) { - *this = *this | rhs; -} - -inline void casEventMask::operator&= (const casEventMask &rhs) { - *this = *this & rhs; -} - -#endif // casEventMaskH - diff --git a/src/ca/legacy/pcas/generic/casEventRegistry.h b/src/ca/legacy/pcas/generic/casEventRegistry.h deleted file mode 100644 index c10f982e3..000000000 --- a/src/ca/legacy/pcas/generic/casEventRegistry.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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef casEventRegistryh -#define casEventRegistryh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casEventRegistryh -# undef epicsExportSharedSymbols -#endif - -#include "tsSLList.h" - -#ifdef epicsExportSharedSymbols_casEventRegistryh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casEventMask.h" - -class casEventMaskEntry : public tsSLNode < casEventMaskEntry >, - public casEventMask, public stringId { -public: - casEventMaskEntry (casEventRegistry ®In, - casEventMask maskIn, const char *pName); - virtual ~casEventMaskEntry(); - void show (unsigned level) const; - - virtual void destroy(); -private: - casEventRegistry ® - casEventMaskEntry ( const casEventMaskEntry & ); - casEventMaskEntry & operator = ( const casEventMaskEntry & ); -}; - -class casEventRegistry : - private resTable < casEventMaskEntry, stringId > { - friend class casEventMaskEntry; -public: - casEventRegistry () : maskBitAllocator ( 0 ) {} - virtual ~casEventRegistry(); - casEventMask registerEvent ( const char * pName ); - void show ( unsigned level ) const; -private: - unsigned maskBitAllocator; - - casEventMask maskAllocator(); - casEventRegistry ( const casEventRegistry & ); - casEventRegistry & operator = ( const casEventRegistry & ); -}; - -#endif // casEventRegistryh diff --git a/src/ca/legacy/pcas/generic/casEventSys.cc b/src/ca/legacy/pcas/generic/casEventSys.cc deleted file mode 100644 index 8783f36f3..000000000 --- a/src/ca/legacy/pcas/generic/casEventSys.cc +++ /dev/null @@ -1,396 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "errlog.h" - -#define epicsExportSharedSymbols -#include "caHdrLargeArray.h" -#include "casCoreClient.h" -#include "casAsyncIOI.h" -#include "casChannelI.h" -#include "channelDestroyEvent.h" - -void casEventSys::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - printf ( "casEventSys at %p\n", - static_cast ( this ) ); - if (level>=1u) { - printf ( "\numSubscriptions = %u, maxLogEntries = %u\n", - this->numSubscriptions, this->maxLogEntries ); - printf ( "\tthere are %d items in the event queue\n", - this->eventLogQue.count() ); - printf ( "\tthere are %d items in the io queue\n", - this->ioQue.count() ); - printf ( "Replace events flag = %d, dontProcessSubscr flag = %d\n", - static_cast < int > ( this->replaceEvents ), - static_cast < int > ( this->dontProcessSubscr ) ); - } -} - -casEventSys::~casEventSys() -{ - if ( this->pPurgeEvent != NULL ) { - this->eventLogQue.remove ( *this->pPurgeEvent ); - delete this->pPurgeEvent; - } - - // at this point: - // o all channels have been deleted - // o all IO has been deleted - // o any subscription events remaining on the queue - // are pending destroy - - // verify above assertion is true - casVerify ( this->eventLogQue.count() == 0 ); - casVerify ( this->ioQue.count() == 0 ); - - // all active subscriptions should also have been - // uninstalled - casVerify ( this->numSubscriptions == 0 ); - if ( this->numSubscriptions != 0 ) { - printf ( "numSubscriptions=%u\n", this->numSubscriptions ); - } -} - -void casEventSys::installMonitor () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - assert ( this->numSubscriptions < UINT_MAX ); - this->numSubscriptions++; - this->maxLogEntries += averageEventEntries; -} - -void casEventSys::removeMonitor () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - assert ( this->numSubscriptions >= 1u ); - this->numSubscriptions--; - this->maxLogEntries -= averageEventEntries; -} - -casProcCond casEventSys :: process ( - epicsGuard < casClientMutex > & casClientGuard ) -{ - casProcCond cond = casProcOk; - - epicsGuard < evSysMutex > evGuard ( this->mutex ); - - // we need two queues, one for io and one for subscriptions, - // so that we dont hang up the server when in an IO postponed - // state simultaneouly with a flow control active state - while ( true ) { - casEvent * pEvent = this->ioQue.get (); - if ( pEvent == NULL ) { - break; - } - - caStatus status = pEvent->cbFunc ( - this->client, casClientGuard, evGuard ); - if ( status == S_cas_success ) { - cond = casProcOk; - } - else if ( status == S_cas_sendBlocked ) { - // not accepted so return to the head of the list - // (we will try again later) - this->ioQue.push ( *pEvent ); - cond = casProcOk; - break; - } - else if ( status == S_cas_disconnect ) { - cond = casProcDisconnect; - break; - } - else { - errMessage ( status, - "- unexpected error, processing io queue" ); - cond = casProcDisconnect; - break; - } - } - - if ( cond == casProcOk ) { - while ( ! this->dontProcessSubscr ) { - casEvent * pEvent = this->eventLogQue.get (); - if ( pEvent == NULL ) { - break; - } - - caStatus status = pEvent->cbFunc ( - this->client, casClientGuard, evGuard ); - if ( status == S_cas_success ) { - cond = casProcOk; - } - else if ( status == S_cas_sendBlocked ) { - // not accepted so return to the head of the list - // (we will try again later) - this->eventLogQue.push ( *pEvent ); - cond = casProcOk; - break; - } - else if ( status == S_cas_disconnect ) { - cond = casProcDisconnect; - break; - } - else { - errMessage ( status, - "- unexpected error, processing event queue" ); - cond = casProcDisconnect; - break; - } - } - } - - // - // allows the derived class to be informed that it - // needs to delete itself via the event system - // - // this gets the server out of nasty situations - // where the client needs to be deleted but - // the caller may be using the client's "this" - // pointer. - // - if ( this->destroyPending ) { - cond = casProcDisconnect; - } - - return cond; -} - -void casEventSys::eventsOn () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - // - // allow multiple events for each monitor - // - this->replaceEvents = false; - - // - // allow the event queue to be processed - // - this->dontProcessSubscr = false; - - // - // remove purge event if it is still pending - // - if ( this->pPurgeEvent != NULL ) { - this->eventLogQue.remove ( *this->pPurgeEvent ); - delete this->pPurgeEvent; - this->pPurgeEvent = NULL; - } -} - -bool casEventSys::eventsOff () -{ - bool signalNeeded = false; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - - // - // new events will replace the last event on - // the queue for a particular monitor - // - this->replaceEvents = true; - - // - // suppress the processing and sending of events - // only after we have purged the event queue - // for this particular client - // - if ( this->pPurgeEvent == NULL ) { - this->pPurgeEvent = new casEventPurgeEv ( *this ); - if ( this->pPurgeEvent == NULL ) { - // - // if there is no room for the event then immediately - // stop processing and sending events to the client - // until we exit flow control - // - this->dontProcessSubscr = true; - } - else { - if ( this->eventLogQue.count() == 0 ) { - signalNeeded = true; - } - this->eventLogQue.add ( *this->pPurgeEvent ); - } - } - } - return signalNeeded; -} - -casEventPurgeEv::casEventPurgeEv ( casEventSys & evSysIn ) : - evSys ( evSysIn ) -{ -} - -caStatus casEventPurgeEv::cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > &, - epicsGuard < evSysMutex > & ) -{ - this->evSys.dontProcessSubscr = true; - this->evSys.pPurgeEvent = NULL; - delete this; - return S_cas_success; -} - -caStatus casEventSys::addToEventQueue ( casAsyncIOI & event, - bool & onTheQueue, bool & posted, bool & wakeupNeeded ) -{ - { - epicsGuard < epicsMutex > guard ( this->mutex ); - // dont allow them to post completion more than once - if ( posted || onTheQueue ) { - wakeupNeeded = false; - return S_cas_redundantPost; - } - posted = true; - onTheQueue = true; - wakeupNeeded = - ( this->dontProcessSubscr || this->eventLogQue.count() == 0 ) && - this->ioQue.count() == 0; - this->ioQue.add ( event ); - } - return S_cas_success; -} - -void casEventSys::removeFromEventQueue ( casAsyncIOI & io, bool & onTheIOQueue ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( onTheIOQueue ) { - onTheIOQueue = false; - this->ioQue.remove ( io ); - } -} - -bool casEventSys::addToEventQueue ( casChannelI & event, - bool & onTheIOQueue ) -{ - bool wakeupNeeded = false; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( ! onTheIOQueue ) { - onTheIOQueue = true; - wakeupNeeded = - ( this->dontProcessSubscr || this->eventLogQue.count() == 0 ) && - this->ioQue.count() == 0; - this->ioQue.add ( event ); - } - } - return wakeupNeeded; -} - -void casEventSys::removeFromEventQueue ( class casChannelI & io, - bool & onTheIOQueue ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( onTheIOQueue ) { - onTheIOQueue = false; - this->ioQue.remove ( io ); - } -} - -bool casEventSys::addToEventQueue ( channelDestroyEvent & event ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - bool wakeupRequired = - ( this->dontProcessSubscr || this->eventLogQue.count() == 0 ) && - this->ioQue.count() == 0; - this->ioQue.add ( event ); - return wakeupRequired; -} - -void casEventSys::setDestroyPending () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->destroyPending = true; -} - -inline bool casEventSys::full () const -{ - return this->replaceEvents || - this->eventLogQue.count() >= this->maxLogEntries; -} - -bool casEventSys::postEvent ( tsDLList < casMonitor > & monitorList, - const casEventMask & select, const gdd & event ) -{ - bool signalNeeded = false; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - tsDLIter < casMonitor > iter = monitorList.firstIter (); - while ( iter.valid () ) { - if ( iter->selected ( select ) ) { - // get a new block if we havent exceeded quotas - bool full = ( iter->numEventsQueued() >= individualEventEntries ) - || this->full (); - casMonEvent * pLog; - if ( ! full ) { - // should I get rid of this try block by implementing a no - // throw version of the free list alloc? However, crude - // tests on windows with ms visual C++ dont appear to argue - // against the try block. - try { - pLog = new ( this->casMonEventFreeList ) - casMonEvent ( *iter, event ); - } - catch ( ... ) { - pLog = 0; - } - } - else { - pLog = 0; - } - - signalNeeded |= - !this->dontProcessSubscr && - this->eventLogQue.count() == 0 && - this->ioQue.count() == 0; - - iter->installNewEventLog ( - this->eventLogQue, pLog, event ); - } - ++iter; - } - } - return signalNeeded; -} - -void casEventSys::casMonEventDestroy ( - casMonEvent & ev, epicsGuard < evSysMutex > & guard ) -{ - guard.assertIdenticalMutex ( this->mutex ); - ev.~casMonEvent (); - this->casMonEventFreeList.release ( & ev ); -} - -void casEventSys::prepareMonitorForDestroy ( casMonitor & mon ) -{ - bool safeToDestroy = false; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - mon.markDestroyPending (); - // if events reference it on the queue then it gets - // deleted when it reaches the top of the queue - if ( mon.numEventsQueued () == 0 ) { - safeToDestroy = true; - } - } - if ( safeToDestroy ) { - this->client.destroyMonitor ( mon ); - } -} diff --git a/src/ca/legacy/pcas/generic/casEventSys.h b/src/ca/legacy/pcas/generic/casEventSys.h deleted file mode 100644 index d194eedc0..000000000 --- a/src/ca/legacy/pcas/generic/casEventSys.h +++ /dev/null @@ -1,141 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 casEventSysh -#define casEventSysh - -#if defined ( epicsExportSharedSymbols ) -# undef epicsExportSharedSymbols -# define casEventSysh_restore_epicsExportSharedSymbols -#endif - -#include "tsDLList.h" -#include "tsFreeList.h" -#include "epicsMutex.h" - -#if defined ( casEventSysh_restore_epicsExportSharedSymbols ) -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casdef.h" -#include "casEvent.h" - -/* - * maximum peak log entries for each event block (registartion) - * (events cached into the last queue entry if over flow occurs) - * (if this exceeds 256 then the casMonitor::nPend must - * be assigned a new data type) - */ -#define individualEventEntries 16u - -/* - * maximum average log entries for each event block (registartion) - * (events cached into the last queue entry if over flow occurs) - * (if this exceeds 256 then the casMonitor::nPend must - * be assigned a new data type) - */ -#define averageEventEntries 4u - -enum casProcCond { casProcOk, casProcDisconnect }; - -class casMonitor; -class casMonEvent; -class casCoreClient; - -template < class MUTEX > class epicsGuard; - -class evSysMutex : public epicsMutex {}; - -class casEventSys { -public: - casEventSys ( casCoreClient & ); - ~casEventSys (); - void show ( unsigned level ) const; - casProcCond process ( epicsGuard < casClientMutex > & guard ); - void installMonitor (); - void removeMonitor (); - void prepareMonitorForDestroy ( casMonitor & mon ); - bool postEvent ( tsDLList < casMonitor > & monitorList, - const casEventMask & select, const gdd & event ); - caStatus addToEventQueue ( class casAsyncIOI &, - bool & onTheQueue, bool & posted, bool & signalNeeded ); - void removeFromEventQueue ( class casAsyncIOI &, - bool & onTheEventQueue ); - bool addToEventQueue ( - casChannelI &, bool & inTheEventQueue ); - void removeFromEventQueue ( class casChannelI &, - bool & inTheEventQueue ); - bool addToEventQueue ( class channelDestroyEvent & ); - bool getNDuplicateEvents () const; - void setDestroyPending (); - void eventsOn (); - bool eventsOff (); - void casMonEventDestroy ( - casMonEvent &, epicsGuard < evSysMutex > & ); -private: - mutable evSysMutex mutex; - tsDLList < casEvent > eventLogQue; - tsDLList < casEvent > ioQue; - tsFreeList < casMonEvent, 1024, epicsMutexNOOP > casMonEventFreeList; - casCoreClient & client; - class casEventPurgeEv * pPurgeEvent; // flow control purge complete event - unsigned numSubscriptions; // N subscriptions installed - unsigned maxLogEntries; // max log entries - bool destroyPending; - bool replaceEvents; // replace last existing event on queue - bool dontProcessSubscr; // flow ctl is on - dont process subscr event queue - - bool full () const; - casEventSys ( const casEventSys & ); - casEventSys & operator = ( const casEventSys & ); - friend class casEventPurgeEv; -}; - -/* - * when this event reaches the top of the queue we - * know that all duplicate events have been purged - * and that now no events should not be sent to the - * client until it exits flow control mode - */ -class casEventPurgeEv : public casEvent { -public: - casEventPurgeEv ( class casEventSys & ); -private: - casEventSys & evSys; - caStatus cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > &, - epicsGuard < evSysMutex > & ); - casEventPurgeEv & operator = ( const casEventPurgeEv & ); - casEventPurgeEv ( const casEventPurgeEv & ); -}; - -// -// casEventSys::casEventSys () -// -inline casEventSys::casEventSys ( casCoreClient & clientIn ) : - client ( clientIn ), - pPurgeEvent ( NULL ), - numSubscriptions ( 0u ), - maxLogEntries ( individualEventEntries ), - destroyPending ( false ), - replaceEvents ( false ), - dontProcessSubscr ( false ) -{ -} - -#endif // casEventSysh - diff --git a/src/ca/legacy/pcas/generic/casMonEvent.cc b/src/ca/legacy/pcas/generic/casMonEvent.cc deleted file mode 100644 index bcba9f92e..000000000 --- a/src/ca/legacy/pcas/generic/casMonEvent.cc +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include -#include - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "casMonEvent.h" -#include "casMonitor.h" -#include "casCoreClient.h" - -caStatus casMonEvent::cbFunc ( - casCoreClient & client, - epicsGuard < casClientMutex > & clientGuard, - epicsGuard < evSysMutex > & evGuard ) -{ - return this->monitor.executeEvent ( - client, * this, *this->pValue, - clientGuard, evGuard ); -} - -void casMonEvent::assign ( const gdd & valueIn ) -{ - this->pValue = & valueIn; -} - -void casMonEvent::swapValues ( casMonEvent & in ) -{ - assert ( & in.monitor == & this->monitor ); - this->pValue.swap ( in.pValue ); -} - -casMonEvent::~casMonEvent () -{ -} - -#ifdef CXX_PLACEMENT_DELETE -void casMonEvent::operator delete ( void * pCadaver, - tsFreeList < class casMonEvent, 1024, epicsMutexNOOP > & freeList ) -{ - freeList.release ( pCadaver, sizeof ( casMonEvent ) ); -} -#endif - -void casMonEvent::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/legacy/pcas/generic/casMonEvent.h b/src/ca/legacy/pcas/generic/casMonEvent.h deleted file mode 100644 index d31200cc0..000000000 --- a/src/ca/legacy/pcas/generic/casMonEvent.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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef casMonEventh -#define casMonEventh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casMonEventh -# undef epicsExportSharedSymbols -#endif - -#include "tsFreeList.h" -#include "smartGDDPointer.h" - -#ifdef epicsExportSharedSymbols_casMonEventh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casEvent.h" - -class casMonEvent : public casEvent { -public: - casMonEvent ( class casMonitor & monitor ); - casMonEvent ( class casMonitor & monitor, const gdd & value ); - ~casMonEvent (); - void clear (); - void assign ( const gdd & value ); - void swapValues ( casMonEvent & ); - void * operator new ( size_t size, - tsFreeList < casMonEvent, 1024, epicsMutexNOOP > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < casMonEvent, 1024, epicsMutexNOOP > & )) -private: - class casMonitor & monitor; - smartConstGDDPointer pValue; - void operator delete ( void * ); - caStatus cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > &, - epicsGuard < evSysMutex > & ); - casMonEvent ( const casMonEvent & ); - casMonEvent & operator = ( const casMonEvent & ); -}; - -inline casMonEvent::casMonEvent ( class casMonitor & monitorIn ) : - monitor ( monitorIn ) {} - -inline casMonEvent::casMonEvent ( - class casMonitor & monitorIn, const gdd & value ) : - monitor ( monitorIn ), pValue ( value ) {} - -inline void casMonEvent::clear () -{ - this->pValue.set ( 0 ); -} - -inline void * casMonEvent::operator new ( size_t size, - tsFreeList < class casMonEvent, 1024, epicsMutexNOOP > & freeList ) -{ - return freeList.allocate ( size ); -} - -#endif // casMonEventh - diff --git a/src/ca/legacy/pcas/generic/casMonitor.cc b/src/ca/legacy/pcas/generic/casMonitor.cc deleted file mode 100644 index 05deb4a82..000000000 --- a/src/ca/legacy/pcas/generic/casMonitor.cc +++ /dev/null @@ -1,172 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "errlog.h" - -#define epicsExportSharedSymbols -#include "casMonitor.h" -#include "casChannelI.h" - -casEvent::~casEvent () {} - -casMonitor::casMonitor ( - caResId clientIdIn, - casChannelI & chan, - ca_uint32_t nElemIn, - unsigned dbrTypeIn, - const casEventMask & maskIn, - casMonitorCallbackInterface & cb ) : - overFlowEvent ( *this ), - nElem ( nElemIn ), - pChannel ( & chan ), - callBackIntf ( cb ), - mask ( maskIn ), - clientId ( clientIdIn ), - dbrType ( static_cast ( dbrTypeIn ) ), - nPend ( 0u ), - ovf ( false ) -{ - assert ( dbrTypeIn <= 0xff ); -} - -casMonitor::~casMonitor() -{ -} - -caStatus casMonitor::response ( - epicsGuard < casClientMutex > & guard, - casCoreClient & client, const gdd & value ) -{ - if ( this->pChannel ) { - // reconstruct request header - caHdrLargeArray msg; - msg.m_cmmd = CA_PROTO_EVENT_ADD; - msg.m_postsize = 0u; - msg.m_dataType = this->dbrType; - msg.m_count = this->nElem; - msg.m_cid = this->pChannel->getSID(); - msg.m_available = this->clientId; - return client.monitorResponse ( - guard, *this->pChannel, msg, value, S_cas_success ); - } - else { - return S_cas_success; - } -} - -void casMonitor::installNewEventLog ( - tsDLList < casEvent > & eventLogQue, - casMonEvent * pLog, const gdd & event ) -{ - if ( this->ovf ) { - if ( pLog ) { - pLog->assign ( event ); - this->overFlowEvent.swapValues ( *pLog ); - eventLogQue.insertAfter ( *pLog, this->overFlowEvent ); - assert ( this->nPend != UCHAR_MAX ); - this->nPend++; - } - else { - // replace the old OVF value with the current one - this->overFlowEvent.assign ( event ); - } - // remove OVF entry (with its new value) from the queue so - // that it ends up properly ordered at the back of the - // queue - eventLogQue.remove ( this->overFlowEvent ); - pLog = & this->overFlowEvent; - } - else { - if ( pLog == 0 ) { - // use the over flow block in the event structure - this->ovf = true; - pLog = & this->overFlowEvent; - } - pLog->assign ( event ); - assert ( this->nPend != UCHAR_MAX ); - this->nPend++; - } - eventLogQue.add ( *pLog ); -} - -caStatus casMonitor::executeEvent ( casCoreClient & client, - casMonEvent & ev, const gdd & value, - epicsGuard < casClientMutex > & clientGuard, - epicsGuard < evSysMutex > & evGuard ) -{ - if ( this->pChannel ) { - caStatus status = this->callBackIntf.casMonitorCallBack ( - clientGuard, *this, value ); - if ( status != S_cas_success ) { - return status; - } - } - - client.getCAS().incrEventsProcessedCounter (); - assert ( this->nPend != 0u ); - this->nPend--; - - // delete event object if it isnt a cache entry - // saved in the call back object - if ( & ev == & this->overFlowEvent ) { - assert ( this->ovf ); - this->ovf = false; - this->overFlowEvent.clear (); - } - else { - client.casMonEventDestroy ( ev, evGuard ); - } - - if ( ! this->pChannel && this->nPend == 0 ) { - // we carefully avoid inverting the lock hierarchy here - epicsGuardRelease < evSysMutex > unGuardEv ( evGuard ); - { - epicsGuardRelease < casClientMutex > unGuardClient ( clientGuard ); - client.destroyMonitor ( *this ); - } - } - - return S_cas_success; -} - -void casMonitor::show ( unsigned level ) const -{ - if ( level > 1u ) { - printf ( -"\tmonitor type=%u count=%u client id=%u OVF=%u nPend=%u\n", - dbrType, nElem, clientId, ovf, nPend ); - this->mask.show ( level ); - } -} - -void * casMonitor::operator new ( - size_t size, - tsFreeList < casMonitor, 1024 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -void casMonitor::operator delete ( void * pCadaver, - tsFreeList < casMonitor, 1024 > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -void casMonitor::operator delete ( void * ) -{ - errlogPrintf ( "casMonitor: compiler is confused " - "about placement delete?\n" ); -} diff --git a/src/ca/legacy/pcas/generic/casMonitor.h b/src/ca/legacy/pcas/generic/casMonitor.h deleted file mode 100644 index 1c59dfbdf..000000000 --- a/src/ca/legacy/pcas/generic/casMonitor.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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef casMonitorh -#define casMonitorh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casMonitorh -# undef epicsExportSharedSymbols -#endif - -#include "tsDLList.h" - -#ifdef epicsExportSharedSymbols_casMonitorh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - - -#include "caHdrLargeArray.h" -#include "casMonEvent.h" - -class casMonitor; -class casClientMutex; - -class casMonitorCallbackInterface { -public: - virtual caStatus casMonitorCallBack ( - epicsGuard < casClientMutex > &, casMonitor &, - const gdd & ) = 0; -protected: - virtual ~casMonitorCallbackInterface() {} -}; - -class casEvent; - -class casMonitor : public tsDLNode < casMonitor > { -public: - casMonitor ( caResId clientIdIn, casChannelI & chan, - ca_uint32_t nElem, unsigned dbrType, - const casEventMask & maskIn, - casMonitorCallbackInterface & ); - virtual ~casMonitor(); - void markDestroyPending (); - void installNewEventLog ( - tsDLList < casEvent > & eventLogQue, - casMonEvent * pLog, const gdd & event ); - void show ( unsigned level ) const; - bool selected ( const casEventMask & select ) const; - bool matchingClientId ( caResId clientIdIn ) const; - unsigned numEventsQueued () const; - caStatus response ( - epicsGuard < casClientMutex > &, casCoreClient & client, - const gdd & value ); - caStatus executeEvent ( casCoreClient &, - casMonEvent &, const gdd &, - epicsGuard < casClientMutex > &, - epicsGuard < evSysMutex > & ); - void * operator new ( size_t size, - tsFreeList < casMonitor, 1024 > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < casMonitor, 1024 > & )) -private: - casMonEvent overFlowEvent; - ca_uint32_t const nElem; - casChannelI * pChannel; - casMonitorCallbackInterface & callBackIntf; - const casEventMask mask; - caResId const clientId; - unsigned char const dbrType; - unsigned char nPend; - bool destroyPending; - bool ovf; - void operator delete ( void * ); - casMonitor ( const casMonitor & ); - casMonitor & operator = ( const casMonitor & ); -}; - -inline unsigned casMonitor::numEventsQueued () const -{ - return this->nPend; -} - -inline void casMonitor::markDestroyPending () -{ this->pChannel = 0; -} - -inline bool casMonitor::matchingClientId ( caResId clientIdIn ) const -{ - return clientIdIn == this->clientId; -} - -inline bool casMonitor::selected ( const casEventMask & select ) const -{ - casEventMask result ( select & this->mask ); - return result.eventsSelected () && this->pChannel; -} - -#endif // casMonitorh diff --git a/src/ca/legacy/pcas/generic/casOpaqueAddr.cc b/src/ca/legacy/pcas/generic/casOpaqueAddr.cc deleted file mode 100644 index 02f2c870f..000000000 --- a/src/ca/legacy/pcas/generic/casOpaqueAddr.cc +++ /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. -\*************************************************************************/ - -#define epicsExportSharedSymbols -#include "casdef.h" - -// -// this needs to be here (and not in casOpaqueAddrIL.h) if we -// are to avoid undefined symbols under gcc 2.7.x without -O -// -// -// casOpaqueAddr::casOpaqueAddr() -// -casOpaqueAddr::casOpaqueAddr() -{ - this->clear(); -} - -// -// this needs to be here (and not in casOpaqueAddrIL.h) if we -// are to avoid undefined symbols under gcc 2.7.x without -O -// -// -// casOpaqueAddr::clear() -// -void casOpaqueAddr::clear() -{ - this->init = false; -} - - diff --git a/src/ca/legacy/pcas/generic/casOpaqueAddrIL.h b/src/ca/legacy/pcas/generic/casOpaqueAddrIL.h deleted file mode 100644 index 91e0235d6..000000000 --- a/src/ca/legacy/pcas/generic/casOpaqueAddrIL.h +++ /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. -\*************************************************************************/ - -#ifndef casOpaqueAddrILh -#define casOpaqueAddrILh - -// -// casOpaqueAddr::set() -// -inline void casOpaqueAddr::set (const caAddr &addr) -{ - caAddr *p = (caAddr *) this->opaqueAddr; - - // - // see class casOpaqueAddr::checkSize - // for assert fail when - // sizeof(casOpaqueAddr::opaqueAddr) < sizeof(caAddr) - // - *p = addr; - this->init = true; -} - -// -// casOpaqueAddr::set() -// -inline casOpaqueAddr::casOpaqueAddr (const caAddr &addr) -{ - this->set(addr); -} - -// -// casOpaqueAddr::get() -// -inline caAddr casOpaqueAddr::get () const -{ - caAddr *p = (caAddr *) this->opaqueAddr; - - assert ( this->init ); - // - // see class casOpaqueAddr::checkSize - // for assert fail when - // sizeof(casOpaqueAddr::opaqueAddr) < sizeof(caAddr) - // - return *p; -} - -#endif // casOpaqueAddrILh - diff --git a/src/ca/legacy/pcas/generic/casPV.cc b/src/ca/legacy/pcas/generic/casPV.cc deleted file mode 100644 index 317200121..000000000 --- a/src/ca/legacy/pcas/generic/casPV.cc +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#define epicsExportSharedSymbols -#include "casPVI.h" - -casPV::casPV () : - pPVI ( 0 ) -{ -} - -// -// This constructor is preserved for backwards compatibility only. -// Please do _not_ use this constructor. -// -casPV::casPV ( caServer & ) : - pPVI ( 0 ) -{ -} - -casPV::~casPV () -{ - if ( this->pPVI ) { - this->pPVI->casPVDestroyNotify (); - } -} - -void casPV::destroyRequest () -{ - this->pPVI = 0; - this->destroy (); -} - -// -// casPV::destroy() -// -// (this default action will _never_ be called while in the -// casPVI destructor) -// -void casPV::destroy () -{ - delete this; -} - -// -// casPV::createChannel() -// -casChannel *casPV::createChannel ( - const casCtx &ctx, const char * const, const char * const ) -{ - return new casChannel ( ctx ); -} - -// -// casPV::interestRegister() -// -caStatus casPV::interestRegister () -{ - return S_casApp_success; -} - -// -// casPV::interestDelete() -// -void casPV::interestDelete () -{ -} - -// -// casPV::beginTransaction() -// -caStatus casPV::beginTransaction () -{ - return S_casApp_success; -} - -// -// casPV::endTransaction() -// -void casPV::endTransaction () -{ -} - -// -// casPV::read() -// -caStatus casPV::read (const casCtx &, gdd &) -{ - return S_casApp_noSupport; -} - -// -// casPV::write() -// -caStatus casPV::write (const casCtx &, const gdd &) -{ - return S_casApp_noSupport; -} - -// -// casPV::writeNotify() -// -caStatus casPV :: writeNotify ( - const casCtx & ctx, const gdd & val ) -{ - // plumbed this way to preserve backwards - // compatibility with the old interface which - // did not include a writeNotify interface - return this->write ( ctx, val ); -} - -// -// casPV::bestExternalType() -// -aitEnum casPV::bestExternalType () const -{ - return aitEnumString; -} - -// -// casPV::maxDimension() -// (base returns zero - scalar) -// -unsigned casPV::maxDimension () const -{ - return 0u; -} - -// -// casPV::maxBound() -// (base returns scalar bound independent of the dimension arg) -// -aitIndex casPV::maxBound (unsigned /* dimension */) const -{ - return 1u; -} - -// -// casPV::show (unsigned level) -// -void casPV::show ( unsigned /* level */ ) const -{ -} - -// -// Server tool calls this function to post a PV event. -// -void casPV::postEvent ( const casEventMask &select, const gdd &event ) -{ - if ( this->pPVI ) { - this->pPVI->postEvent ( select, event ); - } -} - -// -// Find the server associated with this PV -// ****WARNING**** -// this returns NULL if the PV isnt currently installed -// into a server. -// *************** -// -caServer * casPV::getCAS () const -{ - if ( this->pPVI ) { - return this->pPVI->getExtServer (); - } - else { - return 0; - } -} - - diff --git a/src/ca/legacy/pcas/generic/casPVI.cc b/src/ca/legacy/pcas/generic/casPVI.cc deleted file mode 100644 index 50e5d27a7..000000000 --- a/src/ca/legacy/pcas/generic/casPVI.cc +++ /dev/null @@ -1,545 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "epicsGuard.h" -#include "gddAppTable.h" // EPICS application type table -#include "gddApps.h" -#include "dbMapper.h" // EPICS application type table -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "caServerDefs.h" -#include "caServerI.h" -#include "casPVI.h" -#include "chanIntfForPV.h" -#include "casAsyncIOI.h" -#include "casMonitor.h" - -casPVI::casPVI ( casPV & intf ) : - pCAS ( NULL ), pPV ( & intf ), nMonAttached ( 0u ), - nIOAttached ( 0u ), deletePending ( false ) {} - -casPVI::~casPVI () -{ - // - // all channels should have been destroyed - // (otherwise the server tool is yanking the - // PV out from under the server) - // - casVerify ( this->chanList.count() == 0u ); - - // - // all outstanding IO should have been deleted - // when we destroyed the channels - // - casVerify ( this->nIOAttached == 0u ); - if ( this->nIOAttached ) { - errlogPrintf ( "The number of IO objected attached is %u\n", this->nIOAttached ); - } - - // - // all monitors should have been deleted - // when we destroyed the channels - // - casVerify ( this->nMonAttached == 0u ); - - { - epicsGuard < epicsMutex > guard ( this->mutex ); - this->deletePending = true; - if ( this->pPV ) { - this->pPV->destroyRequest (); - } - } -} - -void casPVI::casPVDestroyNotify () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->pPV = 0; - if ( ! this->deletePending ) { - // last channel to be destroyed destroys the casPVI - tsDLIter < chanIntfForPV > iter = this->chanList.firstIter (); - while ( iter.valid() ) { - iter->postDestroyEvent (); - iter++; - } - } -} - -// -// check for none attached and delete self if so -// -// this call must be protected by the server's lock -// ( which also protects channel creation) -// -void casPVI::deleteSignal () -{ - bool destroyNeeded = false; - { - epicsGuard < epicsMutex > guard ( this->mutex ); - - // - // if we are not attached to a server then the - // following steps are not relevant - // - if ( this->pCAS ) { - if ( this->chanList.count() == 0u ) { - this->pCAS = NULL; - // refresh the table whenever the server reattaches to the PV - this->enumStrTbl.clear (); - destroyNeeded = true; - } - } - } - - if ( destroyNeeded ) { - delete this; - } - - // !! dont access self after potential delete above !! -} - -caStatus casPVI::attachToServer ( caServerI & cas ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pCAS ) { - // - // currently we enforce that the PV can be attached to only - // one server at a time - // - if ( this->pCAS != & cas ) { - return S_cas_pvAlreadyAttached; - } - } - else { - this->pCAS = & cas; - } - return S_cas_success; -} - -// -// casPVI::updateEnumStringTable () -// -// fetch string conversion table so that we can perform proper conversion -// of enumerated PVs to strings during reads -// -// what a API complexity nightmare this GDD is -// -caStatus casPVI::updateEnumStringTable ( casCtx & ctxIn ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - // - // create a gdd with the "enum string table" application type - // - // gddArray(int app, aitEnum prim, int dimen, ...); - gdd * pTmp = new gddScalar ( gddAppType_enums ); - if ( pTmp == NULL ) { - errMessage ( S_cas_noMemory, - "unable to create gdd for read of application type \"enums\" string" - " conversion table for enumerated PV" ); - return S_cas_noMemory; - } - - caStatus status = convertContainerMemberToAtomic ( *pTmp, - gddAppType_enums, MAX_ENUM_STATES ); - if ( status != S_cas_success ) { - pTmp->unreference (); - errMessage ( status, - "unable to to config gdd for read of application type \"enums\" string" - " conversion table for enumerated PV"); - return status; - } - - // - // read the enum string table - // - status = this->read ( ctxIn, *pTmp ); - if ( status == S_cas_success ) { - updateEnumStringTableAsyncCompletion ( *pTmp ); - } - else if ( status != S_casApp_asyncCompletion && - status != S_casApp_postponeAsyncIO ) { - errPrintf ( status, __FILE__, __LINE__, - "- unable to read application type \"enums\" " - " (string conversion table) from enumerated native type PV \"%s\"", - this->getName() ); - } - - pTmp->unreference (); - - return status; -} - -void casPVI::updateEnumStringTableAsyncCompletion ( const gdd & resp ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - if ( resp.isContainer() ) { - errMessage ( S_cas_badType, - "application type \"enums\" string conversion table for" - " enumerated PV was a container (expected vector of strings)" ); - return; - } - - if ( resp.dimension() == 0 ) { - if ( resp.primitiveType() == aitEnumString ) { - aitString *pStr = (aitString *) resp.dataVoid (); - if ( ! this->enumStrTbl.setString ( 0, pStr->string() ) ) { - errMessage ( S_cas_noMemory, - "no memory to set enumerated PV string cache" ); - } - } - else if ( resp.primitiveType() == aitEnumFixedString ) { - aitFixedString *pStr = (aitFixedString *) resp.dataVoid (); - if ( ! this->enumStrTbl.setString ( 0, pStr->fixed_string ) ) { - errMessage ( S_cas_noMemory, - "no memory to set enumerated PV string cache" ); - } - } - else { - errPrintf ( S_cas_badType, __FILE__, __LINE__, - "application type \"enums\" string conversion" - " table for enumerated PV \"%s\" isnt a string type?", - getName() ); - } - } - else if ( resp.dimension() == 1 ) { - gddStatus gdd_status; - aitIndex index, first, count; - - gdd_status = resp.getBound ( 0, first, count ); - assert ( gdd_status == 0 ); - - // - // clear and preallocate the correct amount - // - this->enumStrTbl.clear (); - this->enumStrTbl.reserve ( count ); - - if ( resp.primitiveType() == aitEnumString ) { - aitString *pStr = (aitString *) resp.dataVoid (); - for ( index = 0; indexenumStrTbl.setString ( index, pStr[index].string() ) ) { - errMessage ( S_cas_noMemory, - "no memory to set enumerated PV string cache" ); - } - } - } - else if ( resp.primitiveType() == aitEnumFixedString ) { - aitFixedString *pStr = (aitFixedString *) resp.dataVoid (); - for ( index = 0; index < count; index++ ) { - if ( ! this->enumStrTbl.setString ( index, pStr[index].fixed_string ) ) { - errMessage ( S_cas_noMemory, - "no memory to set enumerated PV string cache" ); - } - } - } - else { - errMessage ( S_cas_badType, - "application type \"enums\" string conversion" - " table for enumerated PV isnt a string type?" ); - } - } - else { - errMessage ( S_cas_badType, - "application type \"enums\" string conversion table" - " for enumerated PV was multi-dimensional" - " (expected vector of strings)" ); - } -} - -void casPVI::postEvent ( const casEventMask & select, const gdd & event ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - // if this is a DBE_PROPERTY event for an enum type - // update the enum string table - if ( (select & this->pCAS->propertyEventMask()).eventsSelected() ) { - const gdd *menu = NULL; - if ( event.applicationType() == gddAppType_dbr_gr_enum ) - menu = event.getDD( gddAppTypeIndex_dbr_gr_enum_enums ); - else if ( event.applicationType() == gddAppType_dbr_ctrl_enum ) - menu = event.getDD( gddAppTypeIndex_dbr_ctrl_enum_enums ); - if ( menu ) - updateEnumStringTableAsyncCompletion( *menu ); - } - - if ( this->nMonAttached ) { - // we are paying some significant locking overhead for - // these diagnostic counters - this->pCAS->updateEventsPostedCounter ( this->nMonAttached ); - tsDLIter < chanIntfForPV > iter = this->chanList.firstIter (); - while ( iter.valid () ) { - iter->postEvent ( select, event ); - ++iter; - } - } -} - -caStatus casPVI::installMonitor ( - casMonitor & mon, tsDLList < casMonitor > & monitorList ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - assert ( this->nMonAttached < UINT_MAX ); - this->nMonAttached++; - // use pv lock to protect channel's monitor list - monitorList.add ( mon ); - if ( this->nMonAttached == 1u && this->pPV ) { - return this->pPV->interestRegister (); - } - else { - return S_cas_success; - } -} - -casMonitor * casPVI::removeMonitor ( - tsDLList < casMonitor > & list, ca_uint32_t clientIdIn ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - casMonitor * pMon = 0; - // - // (it is reasonable to do a linear search here because - // sane clients will require only one or two monitors - // per channel) - // - tsDLIter < casMonitor > iter = list.firstIter (); - while ( iter.valid () ) { - if ( iter->matchingClientId ( clientIdIn ) ) { - list.remove ( *iter.pointer () ); - assert ( this->nMonAttached > 0 ); - this->nMonAttached--; - pMon = iter.pointer (); - break; - } - iter++; - } - if ( this->nMonAttached == 0u && this->pPV ) { - this->pPV->interestDelete (); - } - return pMon; -} - -caServer *casPVI::getExtServer () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pCAS ) { - return this->pCAS->getAdapter (); - } - else { - return NULL; - } -} - -void casPVI::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - printf ( "CA Server PV: nChanAttached=%u nMonAttached=%u nIOAttached=%u\n", - this->chanList.count(), this->nMonAttached, this->nIOAttached ); - if ( level >= 1u ) { - printf ( "\tBest external type = %d\n", this->bestExternalType() ); - } - if ( level >= 2u ) { - this->pPV->show ( level - 2u ); - } -} - -void casPVI::installChannel ( chanIntfForPV & chan ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - this->chanList.add ( chan ); -} - -void casPVI::removeChannel ( - chanIntfForPV & chan, tsDLList < casMonitor > & src, - tsDLList < casMonitor > & dest ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - src.removeAll ( dest ); - if ( dest.count() ) { - assert ( this->nMonAttached >= dest.count() ); - this->nMonAttached -= dest.count (); - } - this->chanList.remove ( chan ); - if ( this->nMonAttached == 0u && this->pPV ) { - this->pPV->interestDelete (); - } -} - -void casPVI::clearOutstandingReads ( tsDLList < casAsyncIOI > & ioList ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - - // cancel any pending asynchronous IO - tsDLIter < casAsyncIOI > iterIO = - ioList.firstIter (); - while ( iterIO.valid () ) { - tsDLIter < casAsyncIOI > tmp = iterIO; - ++tmp; - if ( iterIO->oneShotReadOP () ) { - ioList.remove ( *iterIO ); - delete iterIO.pointer (); - assert ( this->nIOAttached != 0 ); - this->nIOAttached--; - } - iterIO = tmp; - } -} - -void casPVI::destroyAllIO ( tsDLList < casAsyncIOI > & ioList ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - while ( casAsyncIOI * pIO = ioList.get() ) { - pIO->removeFromEventQueue (); - delete pIO; - assert ( this->nIOAttached != 0 ); - this->nIOAttached--; - } -} - -void casPVI::installIO ( - tsDLList < casAsyncIOI > & ioList, casAsyncIOI & io ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - ioList.add ( io ); - assert ( this->nIOAttached != UINT_MAX ); - this->nIOAttached++; -} - -void casPVI::uninstallIO ( - tsDLList < casAsyncIOI > & ioList, casAsyncIOI & io ) -{ - { - epicsGuard < epicsMutex > guard ( this->mutex ); - ioList.remove ( io ); - assert ( this->nIOAttached != 0 ); - this->nIOAttached--; - } - this->ioBlockedList::signal(); -} - -caStatus casPVI::bestDBRType ( unsigned & dbrType ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - aitEnum bestAIT = this->bestExternalType (); - if ( bestAIT == aitEnumInvalid || bestAIT < 0 ) { - return S_cas_badType; - } - unsigned aitIndex = static_cast < unsigned > ( bestAIT ); - if ( aitIndex >= sizeof ( gddAitToDbr ) / sizeof ( gddAitToDbr[0] ) ) { - return S_cas_badType; - } - dbrType = gddAitToDbr[bestAIT]; - return S_cas_success; -} - -caStatus casPVI::read ( const casCtx & ctx, gdd & prototype ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pPV ) { - caStatus status = this->pPV->beginTransaction (); - if ( status != S_casApp_success ) { - return status; - } - status = this->pPV->read ( ctx, prototype ); - this->pPV->endTransaction (); - return status; - } - else { - return S_cas_disconnect; - } -} - -caStatus casPVI::write ( const casCtx & ctx, const gdd & value ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pPV ) { - caStatus status = this->pPV->beginTransaction (); - if ( status != S_casApp_success ) { - return status; - } - status = this->pPV->write ( ctx, value ); - this->pPV->endTransaction (); - return status; - } - else { - return S_cas_disconnect; - } -} - -caStatus casPVI::writeNotify ( const casCtx & ctx, const gdd & value ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pPV ) { - caStatus status = this->pPV->beginTransaction (); - if ( status != S_casApp_success ) { - return status; - } - status = this->pPV->writeNotify ( ctx, value ); - this->pPV->endTransaction (); - return status; - } - else { - return S_cas_disconnect; - } -} - -casChannel * casPVI::createChannel ( const casCtx & ctx, - const char * const pUserName, const char * const pHostName ) -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pPV ) { - return this->pPV->createChannel ( ctx, pUserName, pHostName ); - } - else { - return 0; - } -} - -aitEnum casPVI::bestExternalType () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pPV ) { - return this->pPV->bestExternalType (); - } - else { - return aitEnumInvalid; - } -} - -// CA only does 1D arrays for now -aitIndex casPVI::nativeCount () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pPV ) { - if ( this->pPV->maxDimension() == 0u ) { - return 1u; // scalar - } - return this->pPV->maxBound ( 0u ); - } - else { - return S_cas_disconnect; - } -} - -const char * casPVI::getName () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - if ( this->pPV ) { - return this->pPV->getName (); - } - else { - return ""; - } -} - diff --git a/src/ca/legacy/pcas/generic/casPVI.h b/src/ca/legacy/pcas/generic/casPVI.h deleted file mode 100644 index feea79d23..000000000 --- a/src/ca/legacy/pcas/generic/casPVI.h +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 casPVIh -#define casPVIh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casPVIh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "tsSLList.h" -#include "epicsMutex.h" -#include "caProto.h" - -#ifdef epicsExportSharedSymbols_casPVIh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casdef.h" -#include "ioBlocked.h" - -class chanIntfForPV; -class caServerI; -class casMonitor; - -class casPVI : - public tsSLNode < casPVI >, // server resource table installation - public ioBlockedList // list of clients io blocked on this pv -{ -public: - casPVI ( casPV & ); - epicsShareFunc virtual ~casPVI (); - caServerI * getPCAS () const; - caStatus attachToServer ( caServerI & cas ); - aitIndex nativeCount (); - bool ioIsPending () const; - void clearOutstandingReads ( tsDLList < class casAsyncIOI > &); - void destroyAllIO ( - tsDLList < casAsyncIOI > & ); - void installIO ( - tsDLList < casAsyncIOI > &, casAsyncIOI & ); - void uninstallIO ( - tsDLList < casAsyncIOI > &, casAsyncIOI & ); - void installChannel ( chanIntfForPV & chan ); - void removeChannel ( - chanIntfForPV & chan, tsDLList < casMonitor > & src, - tsDLList < casMonitor > & dest ); - caStatus installMonitor ( - casMonitor & mon, tsDLList < casMonitor > & monitorList ); - casMonitor * removeMonitor ( - tsDLList < casMonitor > & list, ca_uint32_t clientIdIn ); - void deleteSignal (); - void postEvent ( const casEventMask & select, const gdd & event ); - caServer * getExtServer () const; - caStatus bestDBRType ( unsigned & dbrType ); - const gddEnumStringTable & enumStringTable () const; - caStatus updateEnumStringTable ( casCtx & ); - void updateEnumStringTableAsyncCompletion ( const gdd & resp ); - casPV * apiPointer (); // retuns NULL if casPVI isnt a base of casPV - void show ( unsigned level ) const; - caStatus read ( const casCtx & ctx, gdd & prototype ); - caStatus write ( const casCtx & ctx, const gdd & value ); - caStatus writeNotify ( const casCtx & ctx, const gdd & value ); - casChannel * createChannel ( const casCtx & ctx, - const char * const pUserName, const char * const pHostName ); - aitEnum bestExternalType () const; - const char * getName () const; - void casPVDestroyNotify (); - -private: - mutable epicsMutex mutex; - tsDLList < chanIntfForPV > chanList; - gddEnumStringTable enumStrTbl; - caServerI * pCAS; - casPV * pPV; - unsigned nMonAttached; - unsigned nIOAttached; - bool deletePending; - - casPVI ( const casPVI & ); - casPVI & operator = ( const casPVI & ); -}; - -inline caServerI * casPVI::getPCAS() const -{ - return this->pCAS; -} - -inline const gddEnumStringTable & casPVI::enumStringTable () const -{ - return this->enumStrTbl; -} - -inline casPV * casPVI::apiPointer () -{ - return this->pPV; -} - -inline bool casPVI :: ioIsPending () const -{ - return this->nIOAttached > 0u; -} - -#endif // casPVIh - diff --git a/src/ca/legacy/pcas/generic/casStrmClient.cc b/src/ca/legacy/pcas/generic/casStrmClient.cc deleted file mode 100644 index b4c2f5812..000000000 --- a/src/ca/legacy/pcas/generic/casStrmClient.cc +++ /dev/null @@ -1,2965 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 - */ - -// *must* be defined before including net_convert.h -typedef unsigned long arrayElementCount; - -#include "osiWireFormat.h" -#include "net_convert.h" // byte order conversion from libca -#include "dbMapper.h" // ait to dbr types -#include "gddAppTable.h" // EPICS application type table -#include "gddApps.h" // gdd predefined application type codes -#include "errlog.h" -#include "osiPoolStatus.h" // is there sufficent space in pool - -#define epicsExportSharedSymbols -#include "casStrmClient.h" -#include "casChannelI.h" -#include "casAsyncIOI.h" -#include "channelDestroyEvent.h" - -#if defined(__BORLANDC__) && defined(__linux__) -namespace std { -const nothrow_t nothrow ; -} -#endif - -casStrmClient::pCASMsgHandler const casStrmClient::msgHandlers[] = -{ - & casStrmClient::versionAction, - & casStrmClient::eventAddAction, - & casStrmClient::eventCancelAction, - & casStrmClient::readAction, - & casStrmClient::writeAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::searchAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::eventsOffAction, - & casStrmClient::eventsOnAction, - & casStrmClient::readSyncAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::clearChannelAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::readNotifyAction, - & casStrmClient::ignoreMsgAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::claimChannelAction, - & casStrmClient::writeNotifyAction, - & casStrmClient::clientNameAction, - & casStrmClient::hostNameAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::echoAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::uknownMessageAction, - & casStrmClient::uknownMessageAction -}; - -// -// casStrmClient::casStrmClient() -// -casStrmClient::casStrmClient ( - caServerI & cas, clientBufMemoryManager & mgrIn, - const caNetAddr & clientAddr ) : - casCoreClient ( cas ), - in ( *this, mgrIn, 1 ), - out ( *this, mgrIn ), - _clientAddr ( clientAddr ), - pUserName ( 0 ), - pHostName ( 0 ), - incommingBytesToDrain ( 0 ), - pendingResponseStatus ( S_cas_success ), - minor_version_number ( 0 ), - reqPayloadNeedsByteSwap ( true ), - responseIsPending ( false ) -{ - this->pHostName = new char [1u]; - *this->pHostName = '\0'; - - this->pUserName = new ( std::nothrow ) char [1u]; - if ( ! this->pUserName ) { - delete [] this->pHostName; - throw std::bad_alloc(); - } - *this->pUserName= '\0'; -} - -// -// casStrmClient::~casStrmClient () -// -casStrmClient::~casStrmClient () -{ - while ( casChannelI * pChan = this->chanList.get() ) { - pChan->uninstallFromPV ( this->eventSys ); - this->chanTable.remove ( *pChan ); - delete pChan; - } - delete [] this->pUserName; - delete [] this->pHostName; -} - -// -// casStrmClient :: processMsg () -// -caStatus casStrmClient :: processMsg () -{ - epicsGuard < casClientMutex > guard ( this->mutex ); - int status = S_cas_success; - - // protect against service returning s_casApp_success when it - // returned S_casApp_postponeAsyncIO before, but no - // asyn IO completed since the last attempt - if ( this->isBlocked () ) { - return S_casApp_postponeAsyncIO; - } - - try { - - // drain message that does not fit - if ( this->incommingBytesToDrain ) { - unsigned bytesLeft = this->in.bytesPresent(); - if ( bytesLeft < this->incommingBytesToDrain ) { - this->in.removeMsg ( bytesLeft ); - this->incommingBytesToDrain -= bytesLeft; - return S_cas_success; - } - else { - this->in.removeMsg ( this->incommingBytesToDrain ); - this->incommingBytesToDrain = 0u; - } - } - - // - // process any messages in the in buffer - // - unsigned bytesLeft; - while ( ( bytesLeft = this->in.bytesPresent() ) ) { - caHdrLargeArray msgTmp; - unsigned msgSize; - ca_uint32_t hdrSize; - char * rawMP; - { - // - // copy as raw bytes in order to avoid - // alignment problems - // - caHdr smallHdr; - if ( bytesLeft < sizeof ( smallHdr ) ) { - status = S_cas_success; - break; - } - - rawMP = this->in.msgPtr (); - memcpy ( & smallHdr, rawMP, sizeof ( smallHdr ) ); - - ca_uint32_t payloadSize = AlignedWireRef < epicsUInt16 > ( smallHdr.m_postsize ); - ca_uint32_t nElem = AlignedWireRef < epicsUInt16 > ( smallHdr.m_count ); - if ( payloadSize != 0xffff && nElem != 0xffff ) { - hdrSize = sizeof ( smallHdr ); - } - else { - ca_uint32_t LWA[2]; - hdrSize = sizeof ( smallHdr ) + sizeof ( LWA ); - if ( bytesLeft < hdrSize ) { - status = S_cas_success; - break; - } - // - // copy as raw bytes in order to avoid - // alignment problems - // - memcpy ( LWA, rawMP + sizeof ( caHdr ), sizeof( LWA ) ); - payloadSize = AlignedWireRef < epicsUInt32 > ( LWA[0] ); - nElem = AlignedWireRef < epicsUInt32 > ( LWA[1] ); - } - - msgTmp.m_cmmd = AlignedWireRef < epicsUInt16 > ( smallHdr.m_cmmd ); - msgTmp.m_postsize = payloadSize; - msgTmp.m_dataType = AlignedWireRef < epicsUInt16 > ( smallHdr.m_dataType ); - msgTmp.m_count = nElem; - msgTmp.m_cid = AlignedWireRef < epicsUInt32 > ( smallHdr.m_cid ); - msgTmp.m_available = AlignedWireRef < epicsUInt32 > ( smallHdr.m_available ); - - // disconnect clients that dont send 8 byte aligned payloads - if ( payloadSize & 0x7 ) { - caServerI::dumpMsg ( this->pHostName, this->pUserName, & msgTmp, 0, - "CAS: Stream request wasn't 8 byte aligned\n" ); - this->sendErr ( guard, & msgTmp, invalidResID, ECA_INTERNAL, - "Stream request wasn't 8 byte aligned" ); - status = S_cas_internal; - break; - } - - msgSize = hdrSize + payloadSize; - if ( bytesLeft < msgSize ) { - status = S_cas_success; - if ( msgSize > this->in.bufferSize() ) { - this->in.expandBuffer (msgSize); - // msg to large - set up message drain - if ( msgSize > this->in.bufferSize() ) { - caServerI::dumpMsg ( this->pHostName, this->pUserName, & msgTmp, 0, - "The client requested transfer is greater than available " - "memory in server or EPICS_CA_MAX_ARRAY_BYTES\n" ); - status = this->sendErr ( guard, & msgTmp, invalidResID, ECA_TOLARGE, - "client's request didnt fit within the CA server's message buffer" ); - if ( status == S_cas_success ) { - this->in.removeMsg ( bytesLeft ); - this->incommingBytesToDrain = msgSize - bytesLeft; - } - } - } - break; - } - - this->ctx.setMsg ( msgTmp, rawMP + hdrSize ); - - if ( this->getCAS().getDebugLevel() > 2u ) { - caServerI::dumpMsg ( this->pHostName, this->pUserName, - & msgTmp, rawMP + hdrSize, 0 ); - } - } - - // - // Reset the context to the default - // (guarantees that previous message does not get mixed - // up with the current message) - // - this->ctx.setChannel ( NULL ); - this->ctx.setPV ( NULL ); - - // - // Call protocol stub - // - casStrmClient::pCASMsgHandler pHandler; - if ( msgTmp.m_cmmd < NELEMENTS ( casStrmClient::msgHandlers ) ) { - pHandler = this->casStrmClient::msgHandlers[msgTmp.m_cmmd]; - } - else { - pHandler = & casStrmClient::uknownMessageAction; - } - status = ( this->*pHandler ) ( guard ); - if ( status ) { - break; - } - this->in.removeMsg ( msgSize ); - this->pendingResponseStatus = S_cas_success; - this->reqPayloadNeedsByteSwap = true; - this->responseIsPending = false; - this->pValueRead.set ( 0 ); - } - } - catch ( std::bad_alloc & ) { - this->sendErr ( guard, - this->ctx.getMsg(), invalidResID, ECA_ALLOCMEM, - "inablility to allocate memory in " - "the CA server - disconnected client" ); - status = S_cas_noMemory; - } - catch ( std::exception & except ) { - this->sendErr ( guard, - this->ctx.getMsg(), invalidResID, ECA_INTERNAL, - "C++ exception \"%s\" in server - " - "disconnected client", - except.what () ); - status = S_cas_internal; - } - catch ( ... ) { - this->sendErr ( guard, - this->ctx.getMsg(), invalidResID, ECA_INTERNAL, - "unexpected C++ exception in server " - "disconnected client" ); - status = S_cas_internal; - } - - return status; -} - -// -// casStrmClient::uknownMessageAction() -// -caStatus casStrmClient::uknownMessageAction ( epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray *mp = this->ctx.getMsg(); - caStatus status; - - caServerI::dumpMsg ( this->pHostName, - this->pUserName, mp, this->ctx.getData(), - "bad request code from virtual circuit=%u\n", mp->m_cmmd ); - - /* - * most clients dont recover from this - */ - status = this->sendErr ( guard, mp, invalidResID, - ECA_INTERNAL, "Invalid Request Code" ); - if (status) { - return status; - } - - /* - * returning S_cas_badProtocol here disconnects - * the client with the bad message - */ - return S_cas_badProtocol; -} - -/* - * casStrmClient::ignoreMsgAction() - */ -caStatus casStrmClient::ignoreMsgAction ( epicsGuard < casClientMutex > & ) -{ - return S_cas_success; -} - -// -// versionAction() -// -caStatus casStrmClient::versionAction ( epicsGuard < casClientMutex > & ) -{ -#if 1 - return S_cas_success; -#else - // - // eventually need to set the priority here - // - const caHdrLargeArray * mp = this->ctx.getMsg(); - - if ( mp->m_dataType > CA_PROTO_PRIORITY_MAX ) { - return S_cas_badProtocol; - } - - if (!CA_VSUPPORTED(mp->m_count)) { - if ( this->getCAS().getDebugLevel() > 3u ) { - char pHostName[64u]; - this->hostName ( pHostName, sizeof ( pHostName ) ); - printf ( "\"%s\" is too old\n", - pHostName ); - } - return S_cas_badProtocol; - } - - double tmp = mp->m_dataType - CA_PROTO_PRIORITY_MIN; - tmp *= epicsThreadPriorityCAServerHigh - epicsThreadPriorityCAServerLow; - tmp /= CA_PROTO_PRIORITY_MAX - CA_PROTO_PRIORITY_MIN; - tmp += epicsThreadPriorityCAServerLow; - unsigned epicsPriorityNew = (unsigned) tmp; - unsigned 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 S_cas_success; -#endif -} - -// -// echoAction() -// -caStatus casStrmClient::echoAction ( epicsGuard < casClientMutex > & ) -{ - const caHdrLargeArray * mp = this->ctx.getMsg(); - const void * dp = this->ctx.getData(); - void * pPayloadOut; - - caStatus status = this->out.copyInHeader ( mp->m_cmmd, mp->m_postsize, - mp->m_dataType, mp->m_count, mp->m_cid, mp->m_available, - & pPayloadOut ); - if ( ! status ) { - memcpy ( pPayloadOut, dp, mp->m_postsize ); - this->out.commitMsg (); - } - return S_cas_success; -} - -// -// casStrmClient::verifyRequest() -// -caStatus casStrmClient::verifyRequest (casChannelI * & pChan , bool allowdyn) -{ - // - // channel exists for this resource id ? - // - chronIntId tmpId ( ctx.msg.m_cid ); - pChan = this->chanTable.lookup ( tmpId ); - if ( ! pChan ) { - return ECA_BADCHID; - } - - // - // data type out of range ? - // - if ( ctx.msg.m_dataType > ((unsigned)LAST_BUFFER_TYPE) ) { - return ECA_BADTYPE; - } - - // - // element count out of range ? - // - if ( ctx.msg.m_count > pChan->getMaxElem() || - ( !allowdyn && ctx.msg.m_count == 0u ) ) { - return ECA_BADCOUNT; - } - - this->ctx.setChannel ( pChan ); - this->ctx.setPV ( &pChan->getPVI() ); - - return ECA_NORMAL; -} - -void casStrmClient::show ( unsigned level ) const -{ - epicsGuard < epicsMutex > locker ( this->mutex ); - printf ( "casStrmClient at %p\n", - static_cast ( this ) ); - if ( level > 1u ) { - printf ("\tuser %s at %s\n", this->pUserName, this->pHostName); - this->casCoreClient::show ( level - 1 ); - this->in.show ( level - 1 ); - this->out.show ( level - 1 ); - this->chanTable.show ( level - 1 ); - } -} - -/* - * casStrmClient::readAction() - */ -caStatus casStrmClient::readAction ( epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray * mp = this->ctx.getMsg(); - casChannelI * pChan; - - { - caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) ); - if ( status != ECA_NORMAL ) { - if ( pChan ) { - return this->sendErr ( guard, mp, pChan->getCID(), - status, "get request" ); - } - else { - return this->sendErr ( guard, mp, invalidResID, - status, "get request" ); - } - } - } - - // dont allow a request that completed with the service in the - // past, but was incomplete because no response was sent to be - // executed twice with the service - if ( this->responseIsPending ) { - // dont read twice if we didnt finish in the past - // because we were send blocked - if ( this->pendingResponseStatus == S_cas_success ) { - assert ( pValueRead.valid () ); - return this->readResponse ( guard, pChan, *mp, - *pValueRead, S_cas_success ); - } - else { - return this->sendErrWithEpicsStatus ( - guard, mp, pChan->getCID(), - this->pendingResponseStatus, - ECA_GETFAIL ); - } - } - - /* - * verify read access - */ - if ( ! pChan->readAccess() ) { - int v41 = CA_V41 ( this->minor_version_number ); - int cacStatus; - if ( v41 ) { - cacStatus = ECA_NORDACCESS; - } - else{ - cacStatus = ECA_GETFAIL; - } - return this->sendErr ( guard, mp, pChan->getCID(), - cacStatus, "read access denied" ); - } - - { - caStatus servStat = this->read (); - if ( servStat == S_casApp_success ) { - assert ( pValueRead.valid () ); - caStatus status = this->readResponse ( guard, pChan, *mp, - *pValueRead, S_cas_success ); - this->responseIsPending = ( status != S_cas_success ); - return status; - } - else if ( servStat == S_casApp_asyncCompletion ) { - return S_cas_success; - } - else if ( servStat == S_casApp_postponeAsyncIO ) { - return S_casApp_postponeAsyncIO; - } - else { - caStatus status = this->sendErrWithEpicsStatus ( guard, mp, - pChan->getCID(), servStat, ECA_GETFAIL ); - if ( status != S_cas_success ) { - this->pendingResponseStatus = servStat; - this->responseIsPending = true; - } - return status; - } - } -} - -// -// casStrmClient::readResponse() -// -caStatus casStrmClient::readResponse ( epicsGuard < casClientMutex > & guard, - casChannelI * pChan, const caHdrLargeArray & msg, - const gdd & desc, const caStatus status ) -{ - if ( status != S_casApp_success ) { - return this->sendErrWithEpicsStatus ( guard, & msg, - pChan->getCID(), status, ECA_GETFAIL ); - } - - aitUint32 elementCount = 0; - if (desc.isContainer()) { - aitUint32 index; - int gdds = gddApplicationTypeTable::app_table.mapAppToIndex - ( desc.applicationType(), gddAppType_value, index ); - if ( gdds ) { - return S_cas_badType; - } - elementCount = desc.getDD(index)->getDataSizeElements(); - } else { - elementCount = desc.getDataSizeElements(); - } - ca_uint32_t count = (msg.m_count == 0) ? - (ca_uint32_t)elementCount : - msg.m_count; - - void * pPayload; - { - unsigned payloadSize = dbr_size_n ( msg.m_dataType, count ); - caStatus localStatus = this->out.copyInHeader ( msg.m_cmmd, payloadSize, - msg.m_dataType, count, pChan->getCID (), - msg.m_available, & pPayload ); - if ( localStatus ) { - if ( localStatus==S_cas_hugeRequest ) { - localStatus = sendErr ( guard, & msg, pChan->getCID(), ECA_TOLARGE, - "unable to fit read response into server's buffer" ); - } - return localStatus; - } - } - - // - // convert gdd to db_access type - // (places the data in network format) - // - int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr( - pPayload, count, desc, pChan->enumStringTable() ); - if ( mapDBRStatus < 0 ) { - desc.dump (); - errPrintf ( S_cas_badBounds, __FILE__, __LINE__, "- get with PV=%s type=%u count=%u", - pChan->getPVI().getName(), msg.m_dataType, count ); - return this->sendErrWithEpicsStatus ( - guard, & msg, pChan->getCID(), S_cas_badBounds, ECA_GETFAIL ); - } - int cacStatus = caNetConvert ( - msg.m_dataType, pPayload, pPayload, true, count ); - if ( cacStatus != ECA_NORMAL ) { - return this->sendErrWithEpicsStatus ( - guard, & msg, pChan->getCID(), S_cas_internal, cacStatus ); - } - if ( msg.m_dataType == DBR_STRING && count == 1u ) { - unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u; - this->out.commitMsg ( reducedPayloadSize ); - } - else { - this->out.commitMsg (); - } - - return S_cas_success; -} - -// -// casStrmClient::readNotifyAction() -// -caStatus casStrmClient::readNotifyAction ( epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray * mp = this->ctx.getMsg(); - casChannelI * pChan; - - { - caStatus status = this->verifyRequest ( pChan, CA_V413 ( this->minor_version_number ) ); - if ( status != ECA_NORMAL ) { - return this->readNotifyFailureResponse ( guard, * mp, status ); - } - } - - // dont allow a request that completed with the service in the - // past, but was incomplete because no response was sent to be - // executed twice with the service - if ( this->responseIsPending ) { - // dont read twice if we didnt finish in the past - // because we were send blocked - if ( this->pendingResponseStatus == S_cas_success ) { - assert ( pValueRead.valid () ); - return this->readNotifyResponse ( guard, pChan, *mp, - *pValueRead, S_cas_success ); - } - else { - return this->readNotifyFailureResponse ( - guard, *mp, ECA_GETFAIL ); - } - } - - // - // verify read access - // - if ( ! pChan->readAccess() ) { - return this->readNotifyFailureResponse ( guard, *mp, ECA_NORDACCESS ); - } - - { - caStatus servStat = this->read (); - if ( servStat == S_casApp_success ) { - assert ( pValueRead.valid () ); - caStatus status = this->readNotifyResponse ( - guard, pChan, *mp, - *pValueRead, servStat ); - this->responseIsPending = ( status != S_cas_success ); - return status; - } - else if ( servStat == S_casApp_asyncCompletion ) { - return S_cas_success; - } - else if ( servStat == S_casApp_postponeAsyncIO ) { - return S_casApp_postponeAsyncIO; - } - else { - caStatus status = this->readNotifyFailureResponse ( - guard, *mp, ECA_GETFAIL ); - if ( status != S_cas_success ) { - this->pendingResponseStatus = servStat; - this->responseIsPending = true; - } - return status; - } - } -} - -// -// casStrmClient::readNotifyResponse() -// -caStatus casStrmClient::readNotifyResponse ( epicsGuard < casClientMutex > & guard, - casChannelI * pChan, const caHdrLargeArray & msg, const gdd & desc, - const caStatus completionStatus ) -{ - if ( completionStatus != S_cas_success ) { - caStatus ecaStatus = this->readNotifyFailureResponse ( - guard, msg, ECA_GETFAIL ); - return ecaStatus; - } - - aitUint32 elementCount = 0; - if (desc.isContainer()) { - aitUint32 index; - int gdds = gddApplicationTypeTable::app_table.mapAppToIndex - ( desc.applicationType(), gddAppType_value, index ); - if ( gdds ) { - return S_cas_badType; - } - elementCount = desc.getDD(index)->getDataSizeElements(); - } else { - elementCount = desc.getDataSizeElements(); - } - ca_uint32_t count = (msg.m_count == 0) ? - (ca_uint32_t)elementCount : - msg.m_count; - - void *pPayload; - { - unsigned size = dbr_size_n ( msg.m_dataType, count ); - caStatus status = this->out.copyInHeader ( msg.m_cmmd, size, - msg.m_dataType, count, ECA_NORMAL, - msg.m_available, & pPayload ); - if ( status ) { - if ( status == S_cas_hugeRequest ) { - status = sendErr ( guard, & msg, pChan->getCID(), ECA_TOLARGE, - "unable to fit read notify response into server's buffer" ); - } - return status; - } - } - - // - // convert gdd to db_access type - // - int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr ( pPayload, - count, desc, pChan->enumStringTable() ); - if ( mapDBRStatus < 0 ) { - desc.dump(); - errPrintf ( S_cas_badBounds, __FILE__, __LINE__, - "- get notify with PV=%s type=%u count=%u", - pChan->getPVI().getName(), msg.m_dataType, count ); - return this->readNotifyFailureResponse ( guard, msg, ECA_NOCONVERT ); - } - - int cacStatus = caNetConvert ( - msg.m_dataType, pPayload, pPayload, true, count ); - if ( cacStatus != ECA_NORMAL ) { - return this->sendErrWithEpicsStatus ( - guard, & msg, pChan->getCID(), S_cas_internal, cacStatus ); - } - - if ( msg.m_dataType == DBR_STRING && count == 1u ) { - unsigned reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u; - this->out.commitMsg ( reducedPayloadSize ); - } - else { - this->out.commitMsg (); - } - - return S_cas_success; -} - -// -// casStrmClient::readNotifyFailureResponse () -// -caStatus casStrmClient::readNotifyFailureResponse ( - epicsGuard < casClientMutex > &, const caHdrLargeArray & msg, const caStatus ECA_XXXX ) -{ - assert ( ECA_XXXX != ECA_NORMAL ); - void *pPayload; - unsigned size = dbr_size_n ( msg.m_dataType, msg.m_count ); - caStatus status = this->out.copyInHeader ( msg.m_cmmd, size, - msg.m_dataType, msg.m_count, ECA_XXXX, - msg.m_available, & pPayload ); - if ( ! status ) { - memset ( pPayload, '\0', size ); - this->out.commitMsg (); - } - return status; -} - -// -// set bounds on an application type within a container, but dont -// preallocate space (not preallocating buffer space allows gdd::put -// to be more efficent if it discovers that the source has less data -// than the destination) -// -caStatus convertContainerMemberToAtomic ( gdd & dd, - aitUint32 appType, aitUint32 requestedCount, aitUint32 nativeCount ) -{ - gdd * pVal; - if ( dd.isContainer() ) { - // All DBR types have a value member - aitUint32 index; - int gdds = gddApplicationTypeTable::app_table.mapAppToIndex - ( dd.applicationType(), appType, index ); - if ( gdds ) { - return S_cas_badType; - } - - pVal = dd.getDD ( index ); - if ( ! pVal ) { - return S_cas_badType; - } - } - else { - pVal = & dd; - } - - // we cant changed a managed type that is - // already atomic (array) - if ( ! pVal->isScalar () ) { - return S_cas_badType; - } - - if ( nativeCount <= 1 ) { - return S_cas_success; - } - - // convert to atomic - gddBounds bds; - bds.setSize ( requestedCount ); - bds.setFirst ( 0u ); - pVal->setDimension ( 1u, & bds ); - return S_cas_success; -} - -// -// createDBRDD () -// -static caStatus createDBRDD ( unsigned dbrType, - unsigned requestedCount, unsigned nativeCount, gdd * & pDD ) -{ - /* - * DBR type has already been checked, but it is possible - * that "gddDbrToAit" will not track with changes in - * the DBR_XXXX type system - */ - if ( dbrType >= NELEMENTS ( gddDbrToAit ) ) { - return S_cas_badType; - } - - if ( gddDbrToAit[dbrType].type == aitEnumInvalid ) { - return S_cas_badType; - } - - aitUint16 appType = gddDbrToAit[dbrType].app; - - // - // create the descriptor - // - gdd * pDescRet = - gddApplicationTypeTable::app_table.getDD ( appType ); - if ( ! pDescRet ) { - return S_cas_noMemory; - } - - // fix the value element count - caStatus status = convertContainerMemberToAtomic ( - *pDescRet, gddAppType_value, requestedCount, nativeCount ); - if ( status != S_cas_success ) { - pDescRet->unreference (); - return status; - } - - // fix the enum string table element count - // (this is done here because the application type table in gdd - // does not appear to handle this correctly) - if ( dbrType == DBR_CTRL_ENUM || dbrType == DBR_GR_ENUM ) { - status = convertContainerMemberToAtomic ( - *pDescRet, gddAppType_enums, MAX_ENUM_STATES ); - if ( status != S_cas_success ) { - pDescRet->unreference (); - return status; - } - } - - pDD = pDescRet; - return S_cas_success; -} - -// -// casStrmClient::monitorFailureResponse () -// -caStatus casStrmClient::monitorFailureResponse ( - epicsGuard < casClientMutex > &, const caHdrLargeArray & msg, - const caStatus ECA_XXXX ) -{ - assert ( ECA_XXXX != ECA_NORMAL ); - void *pPayload; - unsigned size = dbr_size_n ( msg.m_dataType, msg.m_count ); - caStatus status = this->out.copyInHeader ( msg.m_cmmd, size, - msg.m_dataType, msg.m_count, ECA_XXXX, - msg.m_available, & pPayload ); - if ( ! status ) { - memset ( pPayload, '\0', size ); - this->out.commitMsg (); - } - return status; -} - -// -// casStrmClient::monitorResponse () -// -caStatus casStrmClient::monitorResponse ( - epicsGuard < casClientMutex > & guard, - casChannelI & chan, const caHdrLargeArray & msg, - const gdd & desc, const caStatus completionStatus ) -{ - aitUint32 elementCount = 0; - if (desc.isContainer()) { - aitUint32 index; - int gdds = gddApplicationTypeTable::app_table.mapAppToIndex - ( desc.applicationType(), gddAppType_value, index ); - if ( gdds ) { - return S_cas_badType; - } - elementCount = desc.getDD(index)->getDataSizeElements(); - } else { - elementCount = desc.getDataSizeElements(); - } - ca_uint32_t count = (msg.m_count == 0) ? - (ca_uint32_t)elementCount : - msg.m_count; - - void * pPayload = 0; - { - ca_uint32_t size = dbr_size_n ( msg.m_dataType, count ); - caStatus status = out.copyInHeader ( msg.m_cmmd, size, - msg.m_dataType, count, ECA_NORMAL, - msg.m_available, & pPayload ); - if ( status ) { - if ( status == S_cas_hugeRequest ) { - status = sendErr ( guard, & msg, chan.getCID(), ECA_TOLARGE, - "unable to fit read subscription update response " - "into server's buffer" ); - } - return status; - } - } - - if ( ! chan.readAccess () ) { - return monitorFailureResponse ( guard, msg, ECA_NORDACCESS ); - } - - gdd * pDBRDD = 0; - if ( completionStatus == S_cas_success ) { - caStatus status = createDBRDD ( msg.m_dataType, count, - chan.getMaxElem(), pDBRDD ); - if ( status != S_cas_success ) { - caStatus ecaStatus; - if ( status == S_cas_badType ) { - ecaStatus = ECA_BADTYPE; - } - else if ( status == S_cas_noMemory ) { - ecaStatus = ECA_ALLOCMEM; - } - else { - ecaStatus = ECA_GETFAIL; - } - return monitorFailureResponse ( guard, msg, ecaStatus ); - } - else { - gddStatus gdds = gddApplicationTypeTable:: - app_table.smartCopy ( pDBRDD, & desc ); - if ( gdds < 0 ) { - pDBRDD->unreference (); - errPrintf ( S_cas_noConvert, __FILE__, __LINE__, - "no conversion between event app type=%d and DBR type=%d Element count=%d", - desc.applicationType (), msg.m_dataType, count); - return monitorFailureResponse ( guard, msg, ECA_NOCONVERT ); - } - } - } - else { - if ( completionStatus == S_cas_noRead ) { - return monitorFailureResponse ( guard, msg, ECA_NORDACCESS ); - } - else if ( completionStatus == S_cas_noMemory || - completionStatus == S_casApp_noMemory ) { - return monitorFailureResponse ( guard, msg, ECA_ALLOCMEM ); - } - else if ( completionStatus == S_cas_badType ) { - return monitorFailureResponse ( guard, msg, ECA_BADTYPE ); - } - else { - errMessage ( completionStatus, "- in monitor response" ); - return monitorFailureResponse ( guard, msg, ECA_GETFAIL ); - } - } - - int mapDBRStatus = gddMapDbr[msg.m_dataType].conv_dbr ( - pPayload, count, *pDBRDD, chan.enumStringTable() ); - if ( mapDBRStatus < 0 ) { - pDBRDD->unreference (); - return monitorFailureResponse ( guard, msg, ECA_NOCONVERT ); - } - - int cacStatus = caNetConvert ( - msg.m_dataType, pPayload, pPayload, true, count ); - if ( cacStatus != ECA_NORMAL ) { - pDBRDD->unreference (); - return this->sendErrWithEpicsStatus ( - guard, & msg, chan.getCID(), S_cas_internal, cacStatus ); - } - - // - // force string message size to be the true size - // - if ( msg.m_dataType == DBR_STRING && count == 1u ) { - ca_uint32_t reducedPayloadSize = strlen ( static_cast < char * > ( pPayload ) ) + 1u; - this->out.commitMsg ( reducedPayloadSize ); - } - else { - this->out.commitMsg (); - } - - pDBRDD->unreference (); - - return S_cas_success; -} - -/* - * casStrmClient::writeActionSendFailureStatus() - */ -caStatus casStrmClient :: - writeActionSendFailureStatus ( epicsGuard < casClientMutex > & guard, - const caHdrLargeArray & msg, ca_uint32_t cid, caStatus status ) -{ - caStatus ecaStatus; - if ( status == S_cas_noMemory ) { - ecaStatus = ECA_ALLOCMEM; - } - else if ( status == S_cas_noConvert ) { - ecaStatus = ECA_NOCONVERT; - } - else if ( status == S_cas_badType ) { - ecaStatus = ECA_BADTYPE; - } - else { - ecaStatus = ECA_PUTFAIL; - } - status = this->sendErrWithEpicsStatus ( guard, & msg, cid, - status, ecaStatus ); - return status; -} - - -/* - * casStrmClient::writeAction() - */ -caStatus casStrmClient::writeAction ( epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray *mp = this->ctx.getMsg(); - casChannelI *pChan; - - { - caStatus status = this->verifyRequest ( pChan ); - if (status != ECA_NORMAL) { - if ( pChan ) { - return this->sendErr ( guard, mp, pChan->getCID(), - status, "get request" ); - } - else { - return this->sendErr ( guard, mp, invalidResID, - status, "get request" ); - } - } - } - - // dont allow a request that completed with the service in the - // past, but was incomplete because no response was sent be - // executed twice with the service - if ( this->responseIsPending ) { - caStatus status = this->writeActionSendFailureStatus ( - guard, *mp, pChan->getCID(), - this->pendingResponseStatus ); - return status; - } - - // - // verify write access - // - if ( ! pChan->writeAccess() ) { - caStatus status; - int v41 = CA_V41 ( this->minor_version_number ); - if (v41) { - status = ECA_NOWTACCESS; - } - else{ - status = ECA_PUTFAIL; - } - return this->sendErr ( guard, mp, pChan->getCID(), - status, "write access denied"); - } - - // - // initiate the write operation - // - { - caStatus servStat = this->write ( & casChannelI :: write ); - if ( servStat == S_casApp_success || - servStat == S_casApp_asyncCompletion ) { - return S_cas_success; - } - else if ( servStat == S_casApp_postponeAsyncIO ) { - return S_casApp_postponeAsyncIO; - } - else { - caStatus status = - this->writeActionSendFailureStatus ( guard, *mp, - pChan->getCID(), servStat ); - if ( status != S_cas_success ) { - this->pendingResponseStatus = servStat; - this->responseIsPending = true; - } - return status; - } - } - - // - // The gdd created above is deleted by the server tool - // -} - -// -// casStrmClient::writeResponse() -// -caStatus casStrmClient::writeResponse ( - epicsGuard < casClientMutex > & guard, casChannelI & chan, - const caHdrLargeArray & msg, const caStatus completionStatus ) -{ - caStatus status; - - if ( completionStatus ) { - errMessage ( completionStatus, "write failed" ); - status = this->sendErrWithEpicsStatus ( guard, & msg, - chan.getCID(), completionStatus, ECA_PUTFAIL ); - } - else { - status = S_cas_success; - } - - return status; -} - -/* - * casStrmClient::writeNotifyAction() - */ -caStatus casStrmClient::writeNotifyAction ( - epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray *mp = this->ctx.getMsg (); - - casChannelI *pChan; - { - caStatus status = this->verifyRequest ( pChan ); - if ( status != ECA_NORMAL ) { - return casStrmClient::writeNotifyResponseECA_XXX ( guard, *mp, status ); - } - } - - // dont allow a request that completed with the service in the - // past, but was incomplete because no response was sent be - // executed twice with the service - if ( this->responseIsPending ) { - caStatus status = this->writeNotifyResponse ( guard, *pChan, - *mp, this->pendingResponseStatus ); - return status; - } - - // - // verify write access - // - if ( ! pChan->writeAccess() ) { - if ( CA_V41(this->minor_version_number) ) { - return this->casStrmClient::writeNotifyResponseECA_XXX ( - guard, *mp, ECA_NOWTACCESS); - } - else { - return this->casStrmClient::writeNotifyResponse ( - guard, *pChan, *mp, S_cas_noWrite ); - } - } - - // - // initiate the write operation - // - { - caStatus servStat = this->write ( & casChannelI :: writeNotify ); - if ( servStat == S_casApp_asyncCompletion ) { - return S_cas_success; - } - else if ( servStat == S_casApp_postponeAsyncIO ) { - return S_casApp_postponeAsyncIO; - } - else { - caStatus status = this->writeNotifyResponse ( guard, *pChan, - *mp, servStat ); - if ( status != S_cas_success ) { - this->pendingResponseStatus = servStat; - this->responseIsPending = true; - } - return status; - } - } -} - -/* - * casStrmClient::writeNotifyResponse() - */ -caStatus casStrmClient::writeNotifyResponse ( epicsGuard < casClientMutex > & guard, - casChannelI & chan, const caHdrLargeArray & msg, const caStatus completionStatus ) -{ - caStatus ecaStatus; - - if ( completionStatus == S_cas_success ) { - ecaStatus = ECA_NORMAL; - } - else { - ecaStatus = ECA_PUTFAIL; - } - - ecaStatus = this->casStrmClient::writeNotifyResponseECA_XXX ( - guard, msg, ecaStatus ); - if (ecaStatus) { - return ecaStatus; - } - - // - // send independent warning exception to the client so that they - // will see the error string associated with this error code - // since the error string cant be sent with the put call back - // response (hopefully this is useful information) - // - // order is very important here because it determines that the put - // call back response is always sent, and that this warning exception - // message will be sent at most one time. In rare instances it will - // not be sent, but at least it will not be sent multiple times. - // The message is logged to the console in the rare situations when - // we are unable to send. - // - if ( completionStatus != S_cas_success ) { - ecaStatus = this->sendErrWithEpicsStatus ( guard, & msg, chan.getCID(), - completionStatus, ECA_NOCONVERT ); - if ( ecaStatus ) { - errMessage ( completionStatus, - "<= put callback failure detail not passed to client" ); - } - } - return S_cas_success; -} - -/* - * casStrmClient::writeNotifyResponseECA_XXX() - */ -caStatus casStrmClient::writeNotifyResponseECA_XXX ( - epicsGuard < casClientMutex > &, - const caHdrLargeArray & msg, const caStatus ecaStatus ) -{ - caStatus status = out.copyInHeader ( msg.m_cmmd, 0, - msg.m_dataType, msg.m_count, ecaStatus, - msg.m_available, 0 ); - if ( ! status ) { - this->out.commitMsg (); - } - - return status; -} - -// -// casStrmClient :: asyncSearchResp() -// -caStatus casStrmClient :: asyncSearchResponse ( - epicsGuard < casClientMutex > & guard, const caNetAddr & /* outAddr */, - const caHdrLargeArray & msg, const pvExistReturn & retVal, - ca_uint16_t /* protocolRevision */, ca_uint32_t /* sequenceNumber */ ) -{ - return this->searchResponse ( guard, msg, retVal ); -} - -// casStrmClient :: hostName() -void casStrmClient :: hostName ( char * pInBuf, unsigned bufSizeIn ) const -{ - _clientAddr.stringConvert ( pInBuf, bufSizeIn ); -} - -// -// caStatus casStrmClient :: searchResponse() -// -caStatus casStrmClient :: searchResponse ( - epicsGuard < casClientMutex > & guard, - const caHdrLargeArray & msg, - const pvExistReturn & retVal ) -{ - if ( retVal.getStatus() != pverExistsHere ) { - if (msg.m_dataType == DOREPLY ) { - long status = this->out.copyInHeader ( CA_PROTO_NOT_FOUND, 0, - msg.m_dataType, msg.m_count, msg.m_cid, msg.m_available, 0 ); - - if ( status == S_cas_success ) { - this->out.commitMsg (); - } - } - return S_cas_success; - } - - // - // starting with V4.1 the count field is used (abused) - // by the client to store the minor version number of - // the client. - // - // Old versions expect alloc of channel in response - // to a search request. This is no longer supported. - // - if ( !CA_V44( msg.m_count ) ) { - errlogPrintf ( - "client \"%s\" using EPICS R3.11 CA " - "connect protocol was ignored\n", - pHostName ); - // - // old connect protocol was dropped when the - // new API was added to the server (they must - // now use clients at EPICS 3.12 or higher) - // - caStatus status = this->sendErr ( - guard, & msg, invalidResID, ECA_DEFUNCT, - "R3.11 connect sequence from old client was ignored" ); - return status; - } - - // - // cid field is abused to carry the IP - // address in CA_V48 or higher - // (this allows a CA servers to serve - // as a directory service) - // - // data type field is abused to carry the IP - // port number here CA_V44 or higher - // (this allows multiple CA servers on one - // host) - // - ca_uint32_t serverAddr; - ca_uint16_t serverPort; - if ( CA_V48( msg.m_count ) ) { - struct sockaddr_in ina; - if ( retVal.addrIsValid() ) { - caNetAddr addr = retVal.getAddr(); - ina = addr.getSockIP(); - // - // If they dont specify a port number then the default - // CA server port is assumed when it it is a server - // address redirect (it is never correct to use this - // server's port when it is a redirect). - // - if ( ina.sin_port == 0u ) { - ina.sin_port = htons ( CA_SERVER_PORT ); - } - } - else { - // - // We dont fill in the servers address here because - // the client has a tcp circuit to us and he knows - // our address - // - ina.sin_addr.s_addr = htonl ( ~0U ); - ina.sin_port = htons ( 0 ); - } - serverAddr = ntohl ( ina.sin_addr.s_addr ); - serverPort = ntohs ( ina.sin_port ); - } - else { - serverAddr = ntohl ( ~0U ); - serverPort = ntohs ( 0 ); - } - - caStatus status = this->out.copyInHeader ( CA_PROTO_SEARCH, - 0, serverPort, 0, serverAddr, msg.m_available, 0 ); - // - // 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. - // - if ( status == S_cas_success ) { - this->out.commitMsg (); - } - - return status; -} - -// -// casStrmClient :: searchAction() -// -caStatus casStrmClient :: searchAction ( epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray *mp = this->ctx.getMsg(); - const char *pChanName = static_cast ( this->ctx.getData() ); - caStatus status; - - if (!CA_VSUPPORTED(mp->m_count)) { - if ( this->getCAS().getDebugLevel() > 3u ) { - char pHostName[64u]; - this->hostName ( pHostName, sizeof ( pHostName ) ); - printf ( "\"%s\" is searching for \"%s\" but is too old\n", - pHostName, pChanName ); - } - return S_cas_badProtocol; - } - - // - // check the sanity of the message - // - if ( mp->m_postsize <= 1 ) { - caServerI::dumpMsg ( this->pHostName, "?", mp, this->ctx.getData(), - "empty PV name extension in TCP search request?\n" ); - return S_cas_success; - } - - if ( pChanName[0] == '\0' ) { - caServerI::dumpMsg ( this->pHostName, "?", mp, this->ctx.getData(), - "zero length PV name in UDP search request?\n" ); - return S_cas_success; - } - - // check for an unterminated string before calling server tool - // by searching backwards through the string (some early versions - // of the client library might not be setting the pad bytes to nill) - for ( unsigned i = mp->m_postsize-1; pChanName[i] != '\0'; i-- ) { - if ( i <= 1 ) { - caServerI::dumpMsg ( pHostName, "?", mp, this->ctx.getData(), - "unterminated PV name in UDP search request?\n" ); - return S_cas_success; - } - } - - if ( this->getCAS().getDebugLevel() > 6u ) { - this->hostName ( this->pHostName, sizeof ( pHostName ) ); - printf ( "\"%s\" is searching for \"%s\"\n", - pHostName, pChanName ); - } - - // - // verify that we have sufficent memory for a PV and a - // monitor prior to calling PV exist test so that when - // the server runs out of memory we dont reply to - // search requests, and therefore dont thrash through - // caServer::pvExistTest() and casCreatePV::pvAttach() - // - if ( ! osiSufficentSpaceInPool ( 0 ) ) { - return S_cas_success; - } - - // - // ask the server tool if this PV exists - // - this->userStartedAsyncIO = false; - pvExistReturn pver = - this->getCAS()->pvExistTest ( - this->ctx, _clientAddr, pChanName ); - - // - // prevent problems when they initiate - // async IO but dont return status - // indicating so (and vise versa) - // - if ( this->userStartedAsyncIO ) { - if ( pver.getStatus() != pverAsyncCompletion ) { - errMessage ( S_cas_badParameter, - "- assuming asynch IO status from caServer::pvExistTest()"); - } - status = S_cas_success; - } - else { - // - // otherwise we assume sync IO operation was initiated - // - switch ( pver.getStatus() ) { - case pverExistsHere: - case pverDoesNotExistHere: - status = this->searchResponse ( guard, *mp, pver ); - break; - - case pverAsyncCompletion: - errMessage ( S_cas_badParameter, - "- unexpected asynch IO status from " - "caServer::pvExistTest() ignored"); - status = S_cas_success; - break; - - default: - errMessage ( S_cas_badParameter, - "- invalid return from " - "caServer::pvExistTest() ignored"); - status = S_cas_success; - break; - } - } - return status; -} - -/* - * casStrmClient::hostNameAction() - */ -caStatus casStrmClient::hostNameAction ( epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray *mp = this->ctx.getMsg(); - char *pName = (char *) this->ctx.getData(); - unsigned size; - char *pMalloc; - caStatus status; - - // currently this has to occur prior to - // creating channels or its not allowed - if ( this->chanList.count () ) { - return this->sendErr ( guard, mp, invalidResID, - ECA_UNAVAILINSERV, pName ); - } - - size = strlen(pName)+1u; - /* - * user name will not change if there isnt enough memory - */ - pMalloc = new char [size]; - if ( ! pMalloc ){ - status = this->sendErr ( guard, mp, invalidResID, - ECA_ALLOCMEM, pName ); - if (status) { - return status; - } - return S_cas_internal; - } - strncpy ( pMalloc, pName, size - 1 ); - pMalloc[ size - 1 ]='\0'; - - if ( this->pHostName ) { - delete [] this->pHostName; - } - this->pHostName = pMalloc; - - return S_cas_success; -} - -/* - * casStrmClient::clientNameAction() - */ -caStatus casStrmClient::clientNameAction ( - epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray *mp = this->ctx.getMsg(); - char *pName = (char *) this->ctx.getData(); - unsigned size; - char *pMalloc; - caStatus status; - - // currently this has to occur prior to - // creating channels or its not allowed - if ( this->chanList.count () ) { - return this->sendErr ( guard, mp, invalidResID, - ECA_UNAVAILINSERV, pName ); - } - - size = strlen(pName)+1; - - /* - * user name will not change if there isnt enough memory - */ - pMalloc = new char [size]; - if(!pMalloc){ - status = this->sendErr ( guard, mp, invalidResID, - ECA_ALLOCMEM, pName ); - if (status) { - return status; - } - return S_cas_internal; - } - strncpy ( pMalloc, pName, size - 1 ); - pMalloc[size-1]='\0'; - - if ( this->pUserName ) { - delete [] this->pUserName; - } - this->pUserName = pMalloc; - - return S_cas_success; -} - -/* - * casStrmClientMon::claimChannelAction() - */ -caStatus casStrmClient::claimChannelAction ( - epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray * mp = this->ctx.getMsg(); - char *pName = (char *) this->ctx.getData(); - caServerI & cas = *this->ctx.getServer(); - - /* - * 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 - */ - if ( mp->m_available < 0xffff ) { - this->minor_version_number = - static_cast < ca_uint16_t > ( mp->m_available ); - } - else { - this->minor_version_number = 0; - } - - // - // We shouldnt be receiving a connect message from - // an R3.11 client because we will not respond to their - // search requests (if so we disconnect) - // - if ( ! CA_V44 ( this->minor_version_number ) ) { - // - // old connect protocol was dropped when the - // new API was added to the server (they must - // now use clients at EPICS 3.12 or higher) - // - caStatus status = this->sendErr ( guard, mp, mp->m_cid, ECA_DEFUNCT, - "R3.11 connect sequence from old client was ignored"); - if ( status ) { - return status; - } - return S_cas_badProtocol; // disconnect client - } - - if ( mp->m_postsize <= 1u ) { - return S_cas_badProtocol; // disconnect client - } - - pName[mp->m_postsize-1u] = '\0'; - - if ( ( mp->m_postsize - 1u ) > unreasonablePVNameSize ) { - return S_cas_badProtocol; // disconnect client - } - - this->userStartedAsyncIO = false; - - // - // attach to the PV - // - pvAttachReturn pvar = cas->pvAttach ( this->ctx, pName ); - - // - // prevent problems when they initiate - // async IO but dont return status - // indicating so (and vise versa) - // - if ( this->userStartedAsyncIO ) { - if ( pvar.getStatus() != S_casApp_asyncCompletion ) { - fprintf ( stderr, - "Application returned %d from cas::pvAttach()" - " - expected S_casApp_asyncCompletion\n", - pvar.getStatus() ); - } - return S_cas_success; - } - else if ( pvar.getStatus() == S_casApp_asyncCompletion ) { - errMessage ( S_cas_badParameter, - "- expected asynch IO creation " - "from caServer::pvAttach()" ); - return this->createChanResponse ( guard, - this->ctx, S_cas_badParameter ); - } - else if ( pvar.getStatus() == S_casApp_postponeAsyncIO ) { - caServerI & casi ( * this->ctx.getServer() ); - if ( casi.ioIsPending () ) { - casi.addItemToIOBLockedList ( *this ); - return S_casApp_postponeAsyncIO; - } - else { - // Its not ok to postpone IO when there isnt at - // least one request pending. In that situation - // there is no event from the service telling us - // when its ok to start issuing requests again! - // So in that situation we tell the client that - // the service refused the request, and this - // caused the request to fail. - this->issuePosponeWhenNonePendingWarning ( "PV attach channel" ); - return this->createChanResponse ( guard, this->ctx, - S_cas_posponeWhenNonePending ); - } - } - else { - return this->createChanResponse ( guard, this->ctx, pvar ); - } -} - -// -// casStrmClient::issuePosponeWhenNonePendingWarning() -// -void casStrmClient :: - issuePosponeWhenNonePendingWarning ( const char * pReqTypeStr ) -{ - errlogPrintf ( "service attempted to postpone %s IO when " - "no IO was pending against the target\n", pReqTypeStr ); - errlogPrintf ( "server library will not receive a restart event, " - "and so failure response was sent to client\n" ); -} - -// -// casStrmClient::createChanResponse() -// -caStatus casStrmClient::createChanResponse ( - epicsGuard < casClientMutex > & guard, - casCtx & ctxIn, const pvAttachReturn & pvar ) -{ - const caHdrLargeArray & hdr = *ctxIn.getMsg(); - - if ( pvar.getStatus() != S_cas_success ) { - return this->channelCreateFailedResp ( guard, - hdr, pvar.getStatus() ); - } - - if ( ! pvar.getPV()->pPVI ) { - // @#$!* Tornado 2 Cygnus GNU compiler bugs -# if ! defined (__GNUC__) || __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 92 ) - pvar.getPV()->pPVI = new ( std::nothrow ) - casPVI ( *pvar.getPV() ); -# else - try { - pvar.getPV()->pPVI = new - casPVI ( *pvar.getPV() ); - } - catch ( ... ) { - pvar.getPV()->pPVI = 0; - } -# endif - - if ( ! pvar.getPV()->pPVI ) { - pvar.getPV()->destroyRequest (); - return this->channelCreateFailedResp ( guard, hdr, S_casApp_pvNotFound ); - } - } - - unsigned nativeTypeDBR; - caStatus status = pvar.getPV()->pPVI->bestDBRType ( nativeTypeDBR ); - if ( status ) { - pvar.getPV()->pPVI->deleteSignal(); - errMessage ( status, "best external dbr type fetch failed" ); - return this->channelCreateFailedResp ( guard, hdr, status ); - } - - // - // attach the PV to this server - // - status = pvar.getPV()->pPVI->attachToServer ( this->getCAS() ); - if ( status ) { - pvar.getPV()->pPVI->deleteSignal(); - return this->channelCreateFailedResp ( guard, hdr, status ); - } - - // - // create server tool XXX derived from casChannel - // - casChannel * pChan = pvar.getPV()->pPVI->createChannel ( - ctxIn, this->pUserName, this->pHostName ); - if ( ! pChan ) { - pvar.getPV()->pPVI->deleteSignal(); - return this->channelCreateFailedResp ( - guard, hdr, S_cas_noMemory ); - } - - if ( ! pChan->pChanI ) { - // @#$!* Tornado 2 Cygnus GNU compiler bugs -# if ! defined (__GNUC__) || __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 92 ) - pChan->pChanI = new ( std::nothrow ) - casChannelI ( * this, *pChan, - * pvar.getPV()->pPVI, hdr.m_cid ); -# else - try { - pChan->pChanI = new - casChannelI ( * this, *pChan, - * pvar.getPV()->pPVI, hdr.m_cid ); - } - catch ( ... ) { - pChan->pChanI = 0; - } -# endif - - if ( ! pChan->pChanI ) { - pChan->destroyRequest (); - pChan->getPV()->pPVI->deleteSignal (); - return this->channelCreateFailedResp ( - guard, hdr, S_cas_noMemory ); - } - } - - // - // Install the channel now so that the server will - // clean up properly if the client disconnects - // while an asynchronous IO fetching the enum - // string table is outstanding - // - this->chanTable.idAssignAdd ( *pChan->pChanI ); - this->chanList.add ( *pChan->pChanI ); - pChan->pChanI->installIntoPV (); - - assert ( hdr.m_cid == pChan->pChanI->getCID() ); - - // - // check to see if the enum table is empty and therefore - // an update is needed every time that a PV attaches - // to the server in case the client disconnected before - // an asynchronous IO to get the table completed - // - if ( nativeTypeDBR == DBR_ENUM ) { - ctxIn.setChannel ( pChan->pChanI ); - ctxIn.setPV ( pvar.getPV()->pPVI ); - this->userStartedAsyncIO = false; - status = pvar.getPV()->pPVI->updateEnumStringTable ( ctxIn ); - if ( this->userStartedAsyncIO ) { - if ( status != S_casApp_asyncCompletion ) { - fprintf ( stderr, - "Application returned %d from casChannel::read()" - " - expected S_casApp_asyncCompletion\n", status); - } - status = S_cas_success; - } - else if ( status == S_cas_success ) { - status = privateCreateChanResponse ( - guard, * pChan->pChanI, hdr, nativeTypeDBR ); - } - else { - if ( status == S_casApp_asyncCompletion ) { - errMessage ( status, - "- enum string tbl cache read returned asynch IO creation, but async IO not started?"); - } - else if ( status == S_casApp_postponeAsyncIO ) { - errMessage ( status, "- enum string tbl cache read ASYNC IO postponed ?"); - errlogPrintf ( "The server library does not currently support postponment of\n" ); - errlogPrintf ( "string table cache update of casChannel::read().\n" ); - errlogPrintf ( "To postpone this request please postpone the PC attach IO request.\n" ); - errlogPrintf ( "String table cache update did not occur.\n" ); - } - else { - errMessage ( status, "- enum string tbl cache read failed ?"); - } - status = privateCreateChanResponse ( - guard, * pChan->pChanI, hdr, nativeTypeDBR ); - } - } - else { - status = privateCreateChanResponse ( - guard, * pChan->pChanI, hdr, nativeTypeDBR ); - } - - if ( status != S_cas_success ) { - this->chanTable.remove ( *pChan->pChanI ); - this->chanList.remove ( *pChan->pChanI ); - pChan->pChanI->uninstallFromPV ( this->eventSys ); - delete pChan->pChanI; - } - - return status; -} - -// -// casStrmClient::enumPostponedCreateChanResponse() -// -// LOCK must be applied -// -caStatus casStrmClient::enumPostponedCreateChanResponse ( - epicsGuard < casClientMutex > & guard, casChannelI & chan, - const caHdrLargeArray & hdr ) -{ - caStatus status = this->privateCreateChanResponse ( - guard, chan, hdr, DBR_ENUM ); - if ( status != S_cas_success ) { - if ( status != S_cas_sendBlocked ) { - this->chanTable.remove ( chan ); - this->chanList.remove ( chan ); - chan.uninstallFromPV ( this->eventSys ); - delete & chan; - } - } - return status; -} - -// -// privateCreateChanResponse -// -caStatus casStrmClient::privateCreateChanResponse ( - epicsGuard < casClientMutex > & guard, - casChannelI & chan, const caHdrLargeArray & hdr, - unsigned nativeTypeDBR ) -{ - // - // We are allocating enough space for both the claim - // response and the access rights response so that we know for - // certain that they will both be sent together. - // - // Considering the possibility of large arrays we must allocate - // an additional 2 * sizeof(ca_uint32_t) - // - void *pRaw; - const outBufCtx outctx = this->out.pushCtx - ( 0, 2 * sizeof ( caHdr ) + 2 * sizeof(ca_uint32_t), pRaw ); - if ( outctx.pushResult() != outBufCtx::pushCtxSuccess ) { - return S_cas_sendBlocked; - } - - // - // We are certain that the request will complete - // here because we allocated enough space for this - // and the claim response above. - // - caStatus status = this->accessRightsResponse ( guard, & chan ); - if ( status ) { - this->out.popCtx ( outctx ); - errMessage ( status, "incomplete channel create?" ); - status = this->channelCreateFailedResp ( guard, hdr, status ); - if ( status != S_cas_sendBlocked ) { - this->chanTable.remove ( chan ); - this->chanList.remove ( chan ); - chan.uninstallFromPV ( this->eventSys ); - delete & chan; - } - return status; - } - - // - // We are allocated enough space for both the claim - // response and the access response so that we know for - // certain that they will both be sent together. - // Nevertheles, some (old) clients do not receive - // an access rights response so we allocate again - // here to be certain that we are at the correct place in - // the protocol buffer. - // - assert ( nativeTypeDBR <= 0xffff ); - aitIndex nativeCount = chan.getMaxElem(); - assert ( nativeCount <= 0xffffffff ); - assert ( hdr.m_cid == chan.getCID() ); - status = this->out.copyInHeader ( CA_PROTO_CREATE_CHAN, 0, - static_cast ( nativeTypeDBR ), - static_cast ( nativeCount ), - chan.getCID(), chan.getSID(), 0 ); - if ( status != S_cas_success ) { - this->out.popCtx ( outctx ); - errMessage ( status, "incomplete channel create?" ); - status = this->channelCreateFailedResp ( guard, hdr, status ); - if ( status != S_cas_sendBlocked ) { - this->chanTable.remove ( chan ); - this->chanList.remove ( chan ); - chan.uninstallFromPV ( this->eventSys ); - delete & chan; - } - return status; - } - - this->out.commitMsg (); - - // - // commit the message - // - bufSizeT nBytes = this->out.popCtx ( outctx ); - assert ( - nBytes == 2 * sizeof ( caHdr ) || - nBytes == 2 * sizeof ( caHdr ) + 2 * sizeof ( ca_uint32_t ) ); - this->out.commitRawMsg ( nBytes ); - - return status; -} - -/* - * casStrmClient::channelCreateFailed() - */ -caStatus casStrmClient::channelCreateFailedResp ( - epicsGuard < casClientMutex > & guard, const caHdrLargeArray & hdr, - const caStatus createStatus ) -{ - if ( createStatus == S_casApp_asyncCompletion ) { - errMessage( S_cas_badParameter, - "- no asynchronous IO create in pvAttach() ?"); - errMessage( S_cas_badParameter, - "- or S_casApp_asyncCompletion was " - "async IO competion code ?"); - } - else if ( createStatus != S_casApp_pvNotFound ) { - errMessage ( createStatus, - "- Server unable to create a new PV" ); - } - caStatus status; - if ( CA_V46 ( this->minor_version_number ) ) { - status = this->out.copyInHeader ( - CA_PROTO_CREATE_CH_FAIL, 0, - 0, 0, hdr.m_cid, 0, 0 ); - if ( status == S_cas_success ) { - this->out.commitMsg (); - } - } - else { - status = this->sendErrWithEpicsStatus ( - guard, & hdr, hdr.m_cid, createStatus, ECA_ALLOCMEM ); - } - return status; -} - -// -// casStrmClient::eventsOnAction() -// -caStatus casStrmClient::eventsOnAction ( epicsGuard < casClientMutex > & ) -{ - this->enableEvents (); - return S_cas_success; -} - -// -// casStrmClient::eventsOffAction() -// -caStatus casStrmClient::eventsOffAction ( epicsGuard < casClientMutex > & ) -{ - this->disableEvents (); - return S_cas_success; -} - -// -// eventAddAction() -// -caStatus casStrmClient::eventAddAction ( - epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray *mp = this->ctx.getMsg(); - struct mon_info *pMonInfo = (struct mon_info *) - this->ctx.getData(); - - casChannelI *pciu; - { - caStatus status = casStrmClient::verifyRequest ( pciu, CA_V413 ( this->minor_version_number ) ); - if ( status != ECA_NORMAL ) { - if ( pciu ) { - return this->sendErr ( guard, mp, - pciu->getCID(), status, NULL); - } - else { - return this->sendErr ( guard, mp, - invalidResID, status, NULL ); - } - } - } - - // dont allow a request that completed with the service in the - // past, but was incomplete because no response was sent to be - // executed twice with the service - if ( this->responseIsPending ) { - // dont read twice if we didnt finish in the past - // because we were send blocked - if ( this->pendingResponseStatus == S_cas_success ) { - assert ( pValueRead.valid () ); - return this->monitorResponse ( guard, *pciu, - *mp, *pValueRead, S_cas_success ); - } - else { - return this->monitorFailureResponse ( - guard, *mp, ECA_GETFAIL ); - } - } - - // - // place monitor mask in correct byte order - // - casEventMask mask; - ca_uint16_t caProtoMask = AlignedWireRef < epicsUInt16 > ( pMonInfo->m_mask ); - if (caProtoMask&DBE_VALUE) { - mask |= this->getCAS().valueEventMask(); - } - - if (caProtoMask&DBE_LOG) { - mask |= this->getCAS().logEventMask(); - } - - if (caProtoMask&DBE_ALARM) { - mask |= this->getCAS().alarmEventMask(); - } - if (caProtoMask&DBE_PROPERTY) { - mask |= this->getCAS().propertyEventMask(); - } - - if (mask.noEventsSelected()) { - char errStr[40]; - sprintf ( errStr, "event add req with mask=0X%X\n", caProtoMask ); - return this->sendErr ( guard, mp, pciu->getCID(), - ECA_BADMASK, errStr ); - } - - casMonitor & mon = this->monitorFactory ( - *pciu, mp->m_available, mp->m_count, - mp->m_dataType, mask ); - pciu->installMonitor ( mon ); - - - // - // Attempt to read the first monitored value prior to creating - // the monitor object so that if the server tool chooses - // to postpone asynchronous IO we can safely restart this - // request later. - // - { - caStatus servStat = this->read (); - // - // always send immediate monitor response at event add - // - if ( servStat == S_cas_success ) { - assert ( pValueRead.valid () ); - caStatus status = this->monitorResponse ( guard, *pciu, - *mp, *pValueRead, servStat ); - this->responseIsPending = ( status != S_cas_success ); - return status; - } - else if ( servStat == S_casApp_asyncCompletion ) { - return S_cas_success; - } - else if ( servStat == S_casApp_postponeAsyncIO ) { - return S_casApp_postponeAsyncIO; - } - else { - caStatus status = this->monitorFailureResponse ( - guard, *mp, ECA_GETFAIL ); - if ( status != S_cas_success ) { - pendingResponseStatus = servStat; - this->responseIsPending = true; - } - return status; - } - } -} - - -// -// casStrmClient::clearChannelAction() -// -caStatus casStrmClient::clearChannelAction ( - epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray * mp = this->ctx.getMsg (); - const void * dp = this->ctx.getData (); - int status; - - // send delete confirmed message - status = this->out.copyInHeader ( mp->m_cmmd, 0, - mp->m_dataType, mp->m_count, - mp->m_cid, mp->m_available, 0 ); - if ( status ) { - return status; - } - this->out.commitMsg (); - - // Verify the channel - chronIntId tmpId ( mp->m_cid ); - casChannelI * pciu = this->chanTable.remove ( tmpId ); - if ( pciu ) { - this->chanList.remove ( *pciu ); - pciu->uninstallFromPV ( this->eventSys ); - delete pciu; - } - else { - /* - * it is possible that the channel delete arrives just - * after the server tool has deleted the PV so we will - * not disconnect the client in this case. Nevertheless, - * we send a warning message in case either the client - * or server has become corrupted - */ - logBadId ( guard, mp, dp, ECA_BADCHID, mp->m_cid ); - } - - return status; -} - -// -// If the channel pointer is nill this indicates that -// the existence of the channel isnt certain because -// it is still installed and the client or the server -// tool might have destroyed it. Therefore, we must -// locate it using the supplied server id. -// -// If the channel pointer isnt nill this indicates -// that the channel has already been uninstalled. -// -// In both situations we need to send a channel -// disconnect message to the client and destroy the -// channel. -// -caStatus casStrmClient::channelDestroyEventNotify ( - epicsGuard < casClientMutex > &, - casChannelI * const pChan, ca_uint32_t sid ) -{ - casChannelI * pChanFound; - if ( pChan ) { - pChanFound = pChan; - } - else { - chronIntId tmpId ( sid ); - pChanFound = - this->chanTable.lookup ( tmpId ); - if ( ! pChanFound ) { - return S_cas_success; - } - } - - if ( CA_V47 ( this->minor_version_number ) ) { - caStatus status = this->out.copyInHeader ( - CA_PROTO_SERVER_DISCONN, 0, - 0, 0, pChanFound->getCID(), 0, 0 ); - if ( status == S_cas_sendBlocked ) { - return status; - } - this->out.commitMsg (); - } - else { - this->forceDisconnect (); - } - - if ( ! pChan ) { - this->chanTable.remove ( * pChanFound ); - this->chanList.remove ( * pChanFound ); - pChanFound->uninstallFromPV ( this->eventSys ); - } - - delete pChanFound; - - return S_cas_success; -} - -// casStrmClient::casChannelDestroyFromInterfaceNotify() -// immediateUninstallNeeded is false when we must avoid -// taking the lock in situations where we would compromise -// the lock hierarchy -void casStrmClient::casChannelDestroyFromInterfaceNotify ( - casChannelI & chan, bool immediateUninstallNeeded ) -{ - if ( immediateUninstallNeeded ) { - epicsGuard < casClientMutex > guard ( this->mutex ); - - this->chanTable.remove ( chan ); - this->chanList.remove ( chan ); - chan.uninstallFromPV ( this->eventSys ); - } - - class channelDestroyEvent * pEvent = - new ( std::nothrow ) class channelDestroyEvent ( - immediateUninstallNeeded ? & chan : 0, - chan.getSID() ); - if ( pEvent ) { - this->addToEventQueue ( *pEvent ); - } - else { - this->forceDisconnect (); - if ( immediateUninstallNeeded ) { - delete & chan; - } - } -} - -// casStrmClient::eventCancelAction() -caStatus casStrmClient::eventCancelAction ( - epicsGuard < casClientMutex > & guard ) -{ - const caHdrLargeArray * mp = this->ctx.getMsg (); - const void * dp = this->ctx.getData (); - - { - chronIntId tmpId ( mp->m_cid ); - casChannelI * pChan = this->chanTable.lookup ( tmpId ); - if ( ! pChan ) { - // It is possible that the event delete arrives just - // after the server tool has deleted the PV. Its probably - // best to just diconnect for now since some old clients - // may still exist. - logBadId ( guard, mp, dp, ECA_BADCHID, mp->m_cid ); - return S_cas_badResourceId; - } - - caStatus status = this->out.copyInHeader ( - CA_PROTO_EVENT_ADD, 0, - mp->m_dataType, mp->m_count, - mp->m_cid, mp->m_available, 0 ); - if ( status != S_cas_success ) { - return status; - } - this->out.commitMsg (); - - casMonitor * pMon = pChan->removeMonitor ( mp->m_available ); - if ( pMon ) { - this->eventSys.prepareMonitorForDestroy ( *pMon ); - } - else { - // this indicates client or server library - // corruption so a disconnect is probably - // the best option - logBadId ( guard, mp, dp, ECA_BADMONID, mp->m_available ); - return S_cas_badResourceId; - } - } - - return S_cas_success; -} - -#if 0 -/* - * casStrmClient::noReadAccessEvent() - * - * substantial complication introduced here by the need for backwards - * compatibility - */ -caStatus casStrmClient::noReadAccessEvent ( - epicsGuard < casClientMutex > & guard, casClientMon * pMon ) -{ - caHdr falseReply; - unsigned size; - caHdr * reply; - int status; - - size = dbr_size_n ( pMon->getType(), pMon->getCount() ); - - falseReply.m_cmmd = CA_PROTO_EVENT_ADD; - falseReply.m_postsize = size; - falseReply.m_dataType = pMon->getType(); - falseReply.m_count = pMon->getCount(); - falseReply.m_cid = pMon->getChannel().getCID(); - falseReply.m_available = pMon->getClientId(); - - status = this->allocMsg ( size, &reply ); - if ( status ) { - if( status == S_cas_hugeRequest ) { - return this->sendErr ( &falseReply, ECA_TOLARGE, NULL ); - } - return status; - } - else{ - /* - * 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 - */ - *reply = falseReply; - reply->m_postsize = size; - reply->m_cid = ECA_NORDACCESS; - memset((char *)(reply+1), 0, size); - this->commitMsg (); - } - - return S_cas_success; -} -#endif - -// -// casStrmClient::readSyncAction() -// -// This message indicates that the R3.13 or before client -// timed out on a read so we must clear out any pending -// asynchronous IO associated with a read. -// -caStatus casStrmClient::readSyncAction ( epicsGuard < casClientMutex > & ) -{ - tsDLIter < casChannelI > iter = - this->chanList.firstIter (); - while ( iter.valid() ) { - iter->clearOutstandingReads (); - iter++; - } - - const caHdrLargeArray * mp = this->ctx.getMsg (); - - int status = this->out.copyInHeader ( mp->m_cmmd, 0, - mp->m_dataType, mp->m_count, - mp->m_cid, mp->m_available, 0 ); - if ( ! status ) { - this->out.commitMsg (); - } - - return status; -} - - // - // casStrmClient::accessRightsResponse() - // - // NOTE: - // Do not change the size of this response without making - // parallel changes in createChanResp - // -caStatus casStrmClient::accessRightsResponse ( casChannelI * pciu ) -{ - epicsGuard < casClientMutex > guard ( this->mutex ); - return this->accessRightsResponse ( guard, pciu ); -} - -caStatus casStrmClient::accessRightsResponse ( - epicsGuard < casClientMutex > &, casChannelI * pciu ) -{ - unsigned ar; - int v41; - int status; - - // noop if this is an old client - v41 = CA_V41 ( this->minor_version_number ); - if ( ! v41 ) { - return S_cas_success; - } - - ar = 0; // none - if ( pciu->readAccess() ) { - ar |= CA_PROTO_ACCESS_RIGHT_READ; - } - if ( pciu->writeAccess() ) { - ar |= CA_PROTO_ACCESS_RIGHT_WRITE; - } - - status = this->out.copyInHeader ( CA_PROTO_ACCESS_RIGHTS, 0, - 0, 0, pciu->getCID(), ar, 0 ); - if ( ! status ) { - this->out.commitMsg (); - } - - return status; -} - -// -// casStrmClient::write() -// -caStatus casStrmClient :: write ( PWriteMethod pWriteMethod ) -{ - const caHdrLargeArray *pHdr = this->ctx.getMsg(); - - // no puts via compound types (for now) - if (dbr_value_offset[pHdr->m_dataType]) { - return S_cas_badType; - } - - // dont byte swap twice - if ( this->reqPayloadNeedsByteSwap ) { - int cacStatus = caNetConvert ( - pHdr->m_dataType, this->ctx.getData(), this->ctx.getData(), - false, pHdr->m_count ); - if ( cacStatus != ECA_NORMAL ) { - return S_cas_badType; - } - this->reqPayloadNeedsByteSwap = false; - } - - // - // clear async IO flag - // - this->userStartedAsyncIO = false; - - // - // DBR_STRING is stored outside the DD so it - // lumped in with arrays - // - { - caStatus servStatus; - if ( pHdr->m_count > 1u ) { - servStatus = this->writeArrayData ( pWriteMethod ); - } - else { - servStatus = this->writeScalarData ( pWriteMethod ); - } - - // - // prevent problems when they initiate - // async IO but dont return status - // indicating so (and vise versa) - // - if ( this->userStartedAsyncIO ) { - if ( servStatus != S_casApp_asyncCompletion ) { - errlogPrintf ( - "Application returned %d from casChannel::write() - " - "expected S_casApp_asyncCompletion\n", - servStatus ); - servStatus = S_casApp_asyncCompletion; - } - } - else if ( servStatus == S_casApp_postponeAsyncIO ) { - casPVI & pvi ( this->ctx.getChannel()->getPVI() ); - if ( pvi.ioIsPending () ) { - pvi.addItemToIOBLockedList ( *this ); - } - else { - // Its not ok to postpone IO when there isnt at - // least one request pending. In that situation - // there is no event from the service telling us - // when its ok to start issuing requests again! - // So in that situation we tell the client that - // the service refused the request, and this - // caused the request to fail. - this->issuePosponeWhenNonePendingWarning ( "write" ); - servStatus = S_cas_posponeWhenNonePending; - } - } - else { - if ( servStatus == S_casApp_asyncCompletion ) { - servStatus = S_cas_badParameter; - errMessage ( servStatus, - "- expected asynch IO creation from casChannel::write()" ); - } - } - - return servStatus; - } -} - -// -// casStrmClient::writeScalarData() -// -caStatus casStrmClient :: writeScalarData ( PWriteMethod pWriteMethod ) -{ - const caHdrLargeArray * pHdr = this->ctx.getMsg (); - - /* - * DBR type has already been checked, but it is possible - * that "gddDbrToAit" will not track with changes in - * the DBR_XXXX type system - */ - if ( pHdr->m_dataType >= NELEMENTS(gddDbrToAit) ) { - return S_cas_badType; - } - - // a primitive type matching the atomic DBR_XXX type - aitEnum type = gddDbrToAit[pHdr->m_dataType].type; - if ( type == aitEnumInvalid ) { - return S_cas_badType; - } - - // the application type best maching this DBR_XXX type - aitUint16 app = gddDbrToAit[pHdr->m_dataType].app; - - // When possible, preconvert to best external type in order - // to reduce problems in the services - aitEnum bestWritePrimType = - app == gddAppType_value ? - this->ctx.getPV()->bestExternalType () : - type; - - gdd * pDD = new gddScalar ( app, bestWritePrimType ); - if ( ! pDD ) { - return S_cas_noMemory; - } - - // - // copy in, and convert to native type, the incoming data - // - gddStatus gddStat = aitConvert ( - pDD->primitiveType(), pDD->dataVoid(), type, - this->ctx.getData(), 1, &this->ctx.getPV()->enumStringTable() ); - caStatus status = S_cas_noConvert; - if ( gddStat >= 0 ) { - // - // set the status and severity to normal - // - pDD->setStat ( epicsAlarmNone ); - pDD->setSevr ( epicsSevNone ); - - // - // set the time stamp to the last time that - // we added bytes to the in buf - // - aitTimeStamp gddts = this->lastRecvTS; - pDD->setTimeStamp ( & gddts ); - - // - // call the server tool's virtual function - // - status = ( this->ctx.getChannel()->*pWriteMethod ) ( this->ctx, *pDD ); - } - - // - // reference count is managed by smart pointer class - // from here down - // - gddStat = pDD->unreference(); - assert ( ! gddStat ); - - return status; -} - -// -// casStrmClient::writeArrayData() -// -caStatus casStrmClient :: writeArrayData ( PWriteMethod pWriteMethod ) -{ - const caHdrLargeArray *pHdr = this->ctx.getMsg (); - - /* - * DBR type has already been checked, but it is possible - * that "gddDbrToAit" will not track with changes in - * the DBR_XXXX type system - */ - if ( pHdr->m_dataType >= NELEMENTS(gddDbrToAit) ) { - return S_cas_badType; - } - aitEnum type = gddDbrToAit[pHdr->m_dataType].type; - if ( type == aitEnumInvalid ) { - return S_cas_badType; - } - - aitEnum bestExternalType = this->ctx.getPV()->bestExternalType (); - - // the application type best maching this DBR_XXX type - aitUint16 app = gddDbrToAit[pHdr->m_dataType].app; - - // When possible, preconvert to best external type in order - // to reduce problems in the services - aitEnum bestWritePrimType = - app == gddAppType_value ? - this->ctx.getPV()->bestExternalType () : - type; - - gdd * pDD = new gddAtomic( app, bestWritePrimType, 1, pHdr->m_count); - if ( ! pDD ) { - return S_cas_noMemory; - } - - size_t size = aitSize[bestExternalType] * pHdr->m_count; - char * pData = new char [size]; - if ( ! pData ) { - pDD->unreference(); - return S_cas_noMemory; - } - - // - // ok to use the default gddDestructor here because - // an array of characters was allocated above - // - gddDestructor * pDestructor = new gddDestructor; - if ( ! pDestructor ) { - pDD->unreference(); - delete [] pData; - return S_cas_noMemory; - } - - // - // install allocated area into the DD - // - pDD->putRef ( pData, bestWritePrimType, pDestructor ); - - // - // convert the data from the protocol buffer - // to the allocated area so that they - // will be allowed to ref the DD - // - caStatus status = S_cas_noConvert; - gddStatus gddStat = aitConvert ( bestWritePrimType, - pData, type, this->ctx.getData(), - pHdr->m_count, &this->ctx.getPV()->enumStringTable() ); - if ( gddStat >= 0 ) { - // - // set the status and severity to normal - // - pDD->setStat ( epicsAlarmNone ); - pDD->setSevr ( epicsSevNone ); - - // - // set the time stamp to the last time that - // we added bytes to the in buf - // - aitTimeStamp gddts = this->lastRecvTS; - pDD->setTimeStamp ( & gddts ); - - // - // call the server tool's virtual function - // - status = ( this->ctx.getChannel()->*pWriteMethod ) ( this->ctx, *pDD ); - } - else { - status = S_cas_noConvert; - } - - gddStat = pDD->unreference (); - assert ( ! gddStat ); - - return status; -} - -// -// casStrmClient::read() -// -caStatus casStrmClient::read () -{ - const caHdrLargeArray * pHdr = this->ctx.getMsg(); - - { - gdd * pDD = 0; - caStatus status = createDBRDD ( pHdr->m_dataType, pHdr->m_count, - this->ctx.getChannel()->getMaxElem(), pDD ); - if ( status != S_cas_success ) { - return status; - } - pValueRead.set ( pDD ); - pDD->unreference (); - } - - // - // clear the async IO flag - // - this->userStartedAsyncIO = false; - - { - // - // call the server tool's virtual function - // - caStatus servStat = this->ctx.getChannel()-> - read ( this->ctx, *pValueRead ); - - // - // prevent problems when they initiate - // async IO but dont return status - // indicating so (and vise versa) - // - if ( this->userStartedAsyncIO ) { - if ( servStat != S_casApp_asyncCompletion ) { - errlogPrintf ( - "Application returned %d from casChannel::read() - " - "expected S_casApp_asyncCompletion\n", - servStat ); - servStat = S_casApp_asyncCompletion; - } - pValueRead.set ( 0 ); - } - else if ( servStat == S_casApp_asyncCompletion ) { - servStat = S_cas_badParameter; - errMessage ( servStat, - "- expected asynch IO creation from casChannel::read()"); - } - else if ( servStat != S_casApp_success ) { - pValueRead.set ( 0 ); - if ( servStat == S_casApp_postponeAsyncIO ) { - casPVI & pvi ( this->ctx.getChannel()->getPVI() ); - if ( pvi.ioIsPending () ) { - pvi.addItemToIOBLockedList ( *this ); - } - else { - // Its not ok to postpone IO when there isnt at - // least one request pending. In that situation - // there is no event from the service telling us - // when its ok to start issuing requests again! - // So in that situation we tell the client that - // the service refused the request, and this - // caused the request to fail. - this->issuePosponeWhenNonePendingWarning ( "read" ); - servStat = S_cas_posponeWhenNonePending; - } - } - } - return servStat; - } -} - -// -// casStrmClient::userName() -// -void casStrmClient::userName ( char * pBuf, unsigned bufSize ) const -{ - if ( bufSize ) { - const char *pName = this->pUserName ? this->pUserName : "?"; - strncpy ( pBuf, pName, bufSize ); - pBuf [bufSize-1] = '\0'; - } -} - -// -// caServerI::roomForNewChannel() -// -inline bool caServerI::roomForNewChannel() const -{ - return true; -} - -// -// casStrmClient::xSend() -// -outBufClient::flushCondition casStrmClient :: - xSend ( char * pBufIn, bufSizeT nBytesToSend, bufSizeT & nBytesSent ) -{ - return this->osdSend ( pBufIn, nBytesToSend, nBytesSent ); -} - -// -// casStrmClient::xRecv() -// -inBufClient::fillCondition casStrmClient::xRecv ( char * pBufIn, bufSizeT nBytesToRecv, - inBufClient::fillParameter, bufSizeT & nActualBytes ) -{ - inBufClient::fillCondition stat = - this->osdRecv ( pBufIn, nBytesToRecv, nActualBytes ); - // - // this is used to set the time stamp for write GDD's - // - this->lastRecvTS = epicsTime::getCurrent (); - return stat; -} - -// -// casStrmClient::getDebugLevel() -// -unsigned casStrmClient::getDebugLevel () const -{ - return this->getCAS().getDebugLevel (); -} - -// -// casStrmClient::casMonitorCallBack() -// -caStatus casStrmClient::casMonitorCallBack ( - epicsGuard < casClientMutex > & guard, - casMonitor & mon, const gdd & value ) -{ - return mon.response ( guard, *this, value ); -} - -// -// casStrmClient::sendErr() -// -caStatus casStrmClient::sendErr ( epicsGuard &, - const caHdrLargeArray * curp, ca_uint32_t cid, - const int reportedStatus, const char *pformat, ... ) -{ - unsigned stringSize; - char msgBuf[1024]; /* allocate plenty of space for the message string */ - if ( pformat ) { - va_list args; - va_start ( args, pformat ); - int status = vsprintf (msgBuf, pformat, args); - if ( status < 0 ) { - errPrintf (S_cas_internal, __FILE__, __LINE__, - "bad sendErr(%s)", pformat); - stringSize = 0u; - } - else { - stringSize = 1u + (unsigned) status; - } - va_end ( args ); - } - else { - stringSize = 0u; - } - - unsigned hdrSize = sizeof ( caHdr ); - if ( ( curp->m_postsize >= 0xffff || curp->m_count >= 0xffff ) && - CA_V49( this->minor_version_number ) ) { - hdrSize += 2 * sizeof ( ca_uint32_t ); - } - - caHdr * pReqOut; - caStatus status = this->out.copyInHeader ( CA_PROTO_ERROR, - hdrSize + stringSize, 0, 0, cid, reportedStatus, - reinterpret_cast ( & pReqOut ) ); - if ( ! status ) { - char * pMsgString; - - /* - * copy back the request protocol - * (in network byte order) - */ - if ( ( curp->m_postsize >= 0xffff || curp->m_count >= 0xffff ) && - CA_V49( this->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 ); - } - 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 ); - } - - /* - * add their context string into the protocol - */ - memcpy ( pMsgString, msgBuf, stringSize ); - - this->out.commitMsg (); - } - - return S_cas_success; -} - -// send minor protocol revision to the client -void casStrmClient::sendVersion () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - caStatus status = this->out.copyInHeader ( CA_PROTO_VERSION, 0, - 0, CA_MINOR_PROTOCOL_REVISION, 0, 0, 0 ); - if ( ! status ) { - this->out.commitMsg (); - } -} - -bool casStrmClient::inBufFull () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->in.full (); -} - -inBufClient::fillCondition casStrmClient::inBufFill () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->in.fill (); -} - -bufSizeT casStrmClient :: inBufBytesPending () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->in.bytesPresent (); -} - -bufSizeT casStrmClient :: - outBufBytesPending () const -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->out.bytesPresent (); -} - -outBufClient::flushCondition casStrmClient::flush () -{ - epicsGuard < epicsMutex > guard ( this->mutex ); - return this->out.flush (); -} - -// -// casStrmClient::logBadIdWithFileAndLineno() -// -caStatus casStrmClient::logBadIdWithFileAndLineno ( - epicsGuard < casClientMutex > & guard, - const caHdrLargeArray * mp, const void * dp, - const int cacStatus, const char * pFileName, - const unsigned lineno, const unsigned idIn ) -{ - if ( pFileName ) { - caServerI::dumpMsg ( this->pHostName, this->pUserName, mp, dp, - "bad resource id in \"%s\" at line %d\n", - pFileName, lineno ); - } - else { - caServerI::dumpMsg ( this->pHostName, this->pUserName, mp, dp, - "bad resource id\n" ); - } - - int status = this->sendErr ( guard, - mp, invalidResID, cacStatus, - "Bad Resource ID=%u detected at %s.%d", - idIn, pFileName, lineno ); - - return status; -} - -/* - * casStrmClient::sendErrWithEpicsStatus() - * - * same as sendErr() except that we convert epicsStatus - * to a string and send that additional detail - */ -caStatus casStrmClient::sendErrWithEpicsStatus ( - epicsGuard < casClientMutex > & guard, const caHdrLargeArray * pMsg, - ca_uint32_t cid, caStatus epicsStatus, caStatus clientStatus ) -{ - char buf[0x1ff]; - errSymLookup ( epicsStatus, buf, sizeof(buf) ); - return this->sendErr ( guard, pMsg, cid, clientStatus, buf ); -} - diff --git a/src/ca/legacy/pcas/generic/casStrmClient.h b/src/ca/legacy/pcas/generic/casStrmClient.h deleted file mode 100644 index 0fdd36bb4..000000000 --- a/src/ca/legacy/pcas/generic/casStrmClient.h +++ /dev/null @@ -1,196 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 casStrmClienth -#define casStrmClienth - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casStrmClienth -# undef epicsExportSharedSymbols -#endif - -#include "epicsTime.h" - -#ifdef epicsExportSharedSymbols_casStrmClienth -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casCoreClient.h" -#include "inBuf.h" -#include "outBuf.h" - -enum xBlockingStatus { xIsBlocking, xIsntBlocking }; - -// -// casStrmClient -// -class casStrmClient : - public casCoreClient, public outBufClient, - public inBufClient, public tsDLNode < casStrmClient > { -public: - casStrmClient ( caServerI &, clientBufMemoryManager &, const caNetAddr & clientAddr ); - virtual ~casStrmClient(); - void show ( unsigned level ) const; - outBufClient::flushCondition flush (); - unsigned getDebugLevel () const; - void hostName ( char * pBuf, unsigned bufSize ) const; - void userName ( char * pBuf, unsigned bufSize ) const; - ca_uint16_t protocolRevision () const; - void sendVersion (); -protected: - caStatus processMsg (); - bool inBufFull () const; - inBufClient::fillCondition inBufFill (); - bufSizeT inBufBytesPending () const; - bufSizeT outBufBytesPending () const; -private: - //char hostNameStr [32]; - inBuf in; - outBuf out; - chronIntIdResTable < casChannelI > chanTable; - tsDLList < casChannelI > chanList; - epicsTime lastSendTS; - epicsTime lastRecvTS; - caNetAddr _clientAddr; - char * pUserName; - char * pHostName; - smartGDDPointer pValueRead; - unsigned incommingBytesToDrain; - caStatus pendingResponseStatus; - ca_uint16_t minor_version_number; - bool reqPayloadNeedsByteSwap; - bool responseIsPending; - - caStatus createChannel ( const char * pName ); - caStatus verifyRequest ( casChannelI * & pChan, bool allowdyn = false ); - typedef caStatus ( casStrmClient :: * pCASMsgHandler ) - ( epicsGuard < casClientMutex > & ); - static pCASMsgHandler const msgHandlers[CA_PROTO_LAST_CMMD+1u]; - - // - // one function for each CA request type - // - caStatus uknownMessageAction ( epicsGuard < casClientMutex > & ); - caStatus ignoreMsgAction ( epicsGuard < casClientMutex > & ); - caStatus versionAction ( epicsGuard < casClientMutex > & ); - caStatus echoAction ( epicsGuard < casClientMutex > & ); - caStatus eventAddAction ( epicsGuard < casClientMutex > & ); - caStatus eventCancelAction ( epicsGuard < casClientMutex > & ); - caStatus readAction ( epicsGuard < casClientMutex > & ); - caStatus readNotifyAction ( epicsGuard < casClientMutex > & ); - caStatus writeAction ( epicsGuard < casClientMutex > & ); - caStatus eventsOffAction ( epicsGuard < casClientMutex > & ); - caStatus eventsOnAction ( epicsGuard < casClientMutex > & ); - caStatus readSyncAction ( epicsGuard < casClientMutex > & ); - caStatus clearChannelAction ( epicsGuard < casClientMutex > & ); - caStatus claimChannelAction ( epicsGuard < casClientMutex > & ); - caStatus writeNotifyAction ( epicsGuard < casClientMutex > & ); - caStatus clientNameAction ( epicsGuard < casClientMutex > & ); - caStatus hostNameAction ( epicsGuard < casClientMutex > & ); - caStatus searchAction ( epicsGuard < casClientMutex > & ); - caStatus sendErr ( epicsGuard < casClientMutex > &, - const caHdrLargeArray *curp, ca_uint32_t cid, - const int reportedStatus, const char * pformat, ... ); - caStatus readNotifyFailureResponse ( epicsGuard < casClientMutex > &, - const caHdrLargeArray & msg, const caStatus ECA_XXXX ); - caStatus monitorFailureResponse ( epicsGuard < casClientMutex > &, - const caHdrLargeArray & msg, const caStatus ECA_XXXX ); - caStatus writeNotifyResponseECA_XXX ( epicsGuard < casClientMutex > &, - const caHdrLargeArray & msg, const caStatus status ); - caStatus sendErrWithEpicsStatus ( epicsGuard < casClientMutex > &, - const caHdrLargeArray * pMsg, ca_uint32_t cid, caStatus epicsStatus, - caStatus clientStatus ); - caStatus writeActionSendFailureStatus ( epicsGuard < casClientMutex > &, - const caHdrLargeArray &, ca_uint32_t cid, caStatus ); - - // - // one function for each CA request type that has - // asynchronous completion - // - caStatus createChanResponse ( epicsGuard < casClientMutex > &, - casCtx &, const pvAttachReturn & ); - caStatus readResponse ( epicsGuard < casClientMutex > &, - casChannelI * pChan, const caHdrLargeArray & msg, - const gdd & desc, const caStatus status ); - caStatus readNotifyResponse ( epicsGuard < casClientMutex > &, - casChannelI *pChan, const caHdrLargeArray & msg, - const gdd & desc, const caStatus status ); - caStatus writeResponse ( epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray & msg, const caStatus status ); - caStatus writeNotifyResponse ( epicsGuard < casClientMutex > &, casChannelI &, - const caHdrLargeArray &, const caStatus status ); - caStatus monitorResponse ( epicsGuard < casClientMutex > &, - casChannelI & chan, const caHdrLargeArray & msg, - const gdd & desc, const caStatus status ); - caStatus enumPostponedCreateChanResponse ( epicsGuard < casClientMutex > &, - casChannelI & chan, const caHdrLargeArray & hdr ); - caStatus privateCreateChanResponse ( epicsGuard < casClientMutex > &, - casChannelI & chan, const caHdrLargeArray & hdr, unsigned dbrType ); - caStatus channelCreateFailedResp ( epicsGuard < casClientMutex > &, - const caHdrLargeArray &, const caStatus createStatus ); - caStatus channelDestroyEventNotify ( - epicsGuard < casClientMutex > & guard, - casChannelI * const pChan, ca_uint32_t sid ); - caStatus accessRightsResponse ( - casChannelI * pciu ); - caStatus accessRightsResponse ( - epicsGuard < casClientMutex > &, casChannelI * pciu ); - caStatus searchResponse ( - epicsGuard < casClientMutex > &, const caHdrLargeArray &, const pvExistReturn & ); - caStatus asyncSearchResponse ( - epicsGuard < casClientMutex > &, const caNetAddr & outAddr, - const caHdrLargeArray & msg, const pvExistReturn & retVal, - ca_uint16_t protocolRevision, ca_uint32_t sequenceNumber ); - - - typedef caStatus ( casChannelI :: * PWriteMethod ) ( - const casCtx &, const gdd & ); - caStatus read (); - caStatus write ( PWriteMethod ); - caStatus writeArrayData( PWriteMethod ); - caStatus writeScalarData( PWriteMethod ); - - outBufClient::flushCondition xSend ( char * pBuf, bufSizeT nBytesToSend, - bufSizeT & nBytesSent ); - inBufClient::fillCondition xRecv ( char * pBuf, bufSizeT nBytesToRecv, - inBufClient::fillParameter parm, bufSizeT & nByesRecv ); - - virtual xBlockingStatus blockingState () const = 0; - - virtual outBufClient::flushCondition osdSend ( const char *pBuf, bufSizeT nBytesReq, - bufSizeT & nBytesActual ) = 0; - virtual inBufClient::fillCondition osdRecv ( char *pBuf, bufSizeT nBytesReq, - bufSizeT &nBytesActual ) = 0; - virtual void forceDisconnect () = 0; - caStatus casMonitorCallBack ( - epicsGuard < casClientMutex > &, casMonitor &, const gdd & ); - caStatus logBadIdWithFileAndLineno ( - epicsGuard < casClientMutex > & guard, const caHdrLargeArray * mp, - const void * dp, const int cacStatus, const char * pFileName, - const unsigned lineno, const unsigned idIn ); - void casChannelDestroyFromInterfaceNotify ( casChannelI & chan, - bool immediatedSestroyNeeded ); - static void issuePosponeWhenNonePendingWarning ( const char * pReqTypeStr ); - - casStrmClient ( const casStrmClient & ); - casStrmClient & operator = ( const casStrmClient & ); -}; - -#define logBadId(GUARD, MP, DP, CACSTAT, RESID) \ - this->logBadIdWithFileAndLineno ( GUARD, MP, DP, \ - CACSTAT, __FILE__, __LINE__, RESID ) - - -inline ca_uint16_t casStrmClient::protocolRevision () const -{ - return this->minor_version_number; -} - -#endif // casStrmClienth diff --git a/src/ca/legacy/pcas/generic/casdef.h b/src/ca/legacy/pcas/generic/casdef.h deleted file mode 100644 index e223dee3c..000000000 --- a/src/ca/legacy/pcas/generic/casdef.h +++ /dev/null @@ -1,981 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 -// Date: 1-95 -// - -#ifndef includecasdefh -#define includecasdefh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casdefh -# undef epicsExportSharedSymbols -#endif - -// -// EPICS -// -#include "errMdef.h" // EPICS error codes -#include "gdd.h" // EPICS data descriptors -#include "alarm.h" // EPICS alarm severity/condition - -#ifdef epicsExportSharedSymbols_casdefh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "caNetAddr.h" -#include "casEventMask.h" // EPICS event select class - -typedef aitUint32 caStatus; - -/* - * =========================================================== - * for internal use by the server library - * (and potentially returned to the server tool) - * =========================================================== - */ -#define S_cas_success 0 -#define S_cas_internal (M_cas| 1) /*Internal failure*/ -#define S_cas_noMemory (M_cas| 2) /*Memory allocation failed*/ -#define S_cas_bindFail (M_cas| 3) /*Attempt to set server's IP address/port failed*/ -#define S_cas_hugeRequest (M_cas | 4) /*Requested op does not fit*/ -#define S_cas_sendBlocked (M_cas | 5) /*Blocked for send q space*/ -#define S_cas_badElementCount (M_cas | 6) /*Bad element count*/ -#define S_cas_noConvert (M_cas | 7) /*No conversion between src & dest types*/ -#define S_cas_badWriteType (M_cas | 8) /*Src type inappropriate for write*/ -#define S_cas_noContext (M_cas | 11) /*Context parameter is required*/ -#define S_cas_disconnect (M_cas | 12) /*Lost connection to server*/ -#define S_cas_recvBlocked (M_cas | 13) /*Recv blocked*/ -#define S_cas_badType (M_cas | 14) /*Bad data type*/ -#define S_cas_timerDoesNotExist (M_cas | 15) /*Timer does not exist*/ -#define S_cas_badEventType (M_cas | 16) /*Bad event type*/ -#define S_cas_badResourceId (M_cas | 17) /*Bad resource identifier*/ -#define S_cas_chanCreateFailed (M_cas | 18) /*Unable to create channel*/ -#define S_cas_noRead (M_cas | 19) /*read access denied*/ -#define S_cas_noWrite (M_cas | 20) /*write access denied*/ -#define S_cas_noEventsSelected (M_cas | 21) /*no events selected*/ -#define S_cas_noFD (M_cas | 22) /*no file descriptors available*/ -#define S_cas_badProtocol (M_cas | 23) /*protocol from client was invalid*/ -#define S_cas_redundantPost (M_cas | 24) /*redundundant io completion post*/ -#define S_cas_badPVName (M_cas | 25) /*bad PV name from server tool*/ -#define S_cas_badParameter (M_cas | 26) /*bad parameter from server tool*/ -#define S_cas_validRequest (M_cas | 27) /*valid request*/ -#define S_cas_tooManyEvents (M_cas | 28) /*maximum simult event types exceeded*/ -#define S_cas_noInterface (M_cas | 29) /*server isnt attached to a network*/ -#define S_cas_badBounds (M_cas | 30) /*server tool changed bounds on request*/ -#define S_cas_pvAlreadyAttached (M_cas | 31) /*PV attached to another server*/ -#define S_cas_badRequest (M_cas | 32) /*client's request was invalid*/ -#define S_cas_invalidAsynchIO (M_cas | 33) /*inappropriate asynchronous IO type*/ -#define S_cas_posponeWhenNonePending (M_cas | 34) /*request postponement, none pending*/ - -/* - * =========================================================== - * returned by the application (to the server library) - * =========================================================== - */ -#define S_casApp_success 0 -#define S_casApp_noMemory (M_casApp | 1) /*Memory allocation failed*/ -#define S_casApp_pvNotFound (M_casApp | 2) /*PV not found*/ -#define S_casApp_badPVId (M_casApp | 3) /*Unknown PV identifier*/ -#define S_casApp_noSupport (M_casApp | 4) /*No application support for op*/ -#define S_casApp_asyncCompletion (M_casApp | 5) /*will complete asynchronously*/ -#define S_casApp_badDimension (M_casApp | 6) /*bad matrix size in request*/ -#define S_casApp_canceledAsyncIO (M_casApp | 7) /*asynchronous io canceled*/ -#define S_casApp_outOfBounds (M_casApp | 8) /*operation was out of bounds*/ -#define S_casApp_undefined (M_casApp | 9) /*undefined value*/ -#define S_casApp_postponeAsyncIO (M_casApp | 10) /*postpone asynchronous IO*/ - -// -// pv exist test return -// -// If the server tool does not wish to start another simultaneous -// asynchronous IO operation or if there is not enough memory -// to do so return pverDoesNotExistHere (and the client will -// retry the request later). -// -enum pvExistReturnEnum { pverExistsHere, pverDoesNotExistHere, - pverAsyncCompletion }; - -class casPV; -class casPVI; -class casCtx; -class casChannel; - -class epicsShareClass pvExistReturn { -public: - // most server tools will use this - pvExistReturn ( pvExistReturnEnum s = pverDoesNotExistHere ); - // directory service server tools will use this (see caNetAddr.h) - pvExistReturn ( const caNetAddr & ); - ~pvExistReturn (); - const pvExistReturn & operator = ( pvExistReturnEnum rhs ); - const pvExistReturn & operator = ( const caNetAddr & rhs ); - pvExistReturnEnum getStatus () const; - caNetAddr getAddr () const; - bool addrIsValid () const; -private: - caNetAddr address; - pvExistReturnEnum status; -}; - -// -// pvAttachReturn -// -class epicsShareClass pvAttachReturn { -public: - pvAttachReturn (); - pvAttachReturn ( caStatus statIn ); - pvAttachReturn ( casPV & pv ); - const pvAttachReturn & operator = ( caStatus rhs ); - const pvAttachReturn & operator = ( casPV * pPVIn ); - caStatus getStatus() const ; - casPV * getPV() const; -private: - casPV * pPV; - caStatus stat; -}; - -// -// caServer - Channel Access Server API Class -// -class epicsShareClass caServer { - friend class casPVI; -public: - caServer (); - virtual ~caServer() = 0; - - // - // pvExistTest() - // - // This function is called by the server library when it needs to - // determine if a named PV exists (or could be created) in the - // server tool. - // - // The request is allowed to complete asynchronously - // (see Asynchronous IO Classes below). - // - // The server tool is encouraged to accept multiple PV name - // aliases for the same PV here. - // - // example return from this procedure: - // return pverExistsHere; // server has PV - // return pverDoesNotExistHere; // server does know of this PV - // return pverAsynchCompletion; // deferred result - // - // Return pverDoesNotExistHere if too many simultaneous - // asynchronous IO operations are pending against the server. - // The client library will retry the request at some time - // in the future. - // - virtual pvExistReturn pvExistTest ( const casCtx & ctx, - const caNetAddr & clientAddress, const char * pPVAliasName ); - - // - // pvAttach() - // - // This function is called _every_ time that a client attaches to the PV. - // The name supplied here will be either a canonical PV name or an alias - // PV name. - // - // The request is allowed to complete asynchronously - // (see Asynchronous IO Classes below). - // - // IMPORTANT: - // It is a responsibility of the server tool to detect attempts by - // the server library to attach to an existing PV. If the PV does not - // exist then the server tool should create it. Otherwise, the server - // tool typically will return a pointer to the preexisting PV. - // - // The server tool is encouraged to accept multiple PV name aliases - // for the same PV here. - // - // In most situations the server tool should avoid PV duplication - // by returning a pointer to an existing PV if the PV alias name - // matches a preexisting PV's name or any of its aliases. - // - // example return from this procedure: - // return pPV; // success (pass by pointer) - // return PV; // success (pass by ref) - // return S_casApp_pvNotFound; // no PV by that name here - // return S_casApp_noMemory; // no resource to create pv - // return S_casApp_asyncCompletion; // deferred completion - // - // Return S_casApp_postponeAsyncIO if too many simultaneous - // asynchronous IO operations are pending against the server. - // The server library will retry the request whenever an - // asynchronous IO operation (create or exist) completes - // against the server. - // - // In certain specialized rare situations the server tool may choose - // to create client private process variables that are not shared between - // clients. In this situation there might be several process variables - // with the same name. One for each client. For example, a server tool - // might be written that provides access to archival storage of the - // historic values of a set of process variables. Each client would - // specify its date of interest by writing into a client private process - // variable. Next the client would determine the current value of its - // subset of named process variables at its privately specified date by - // attaching to additional client private process variables. - // - virtual pvAttachReturn pvAttach ( const casCtx &ctx, - const char *pPVAliasName ); - - // - // obtain an event mask for a named event type - // to be used with casPV::postEvent() - // - casEventMask registerEvent ( const char *pName ); - - // - // common event masks - // (what is currently used by the CA clients) - // - casEventMask valueEventMask () const; // DBE_VALUE - casEventMask logEventMask () const; // DBE_LOG - casEventMask alarmEventMask () const; // DBE_ALARM - casEventMask propertyEventMask () const; // DBE_PROPERTY - - void setDebugLevel ( unsigned level ); - unsigned getDebugLevel () const; - - // - // dump internal state of server to standard out - // - virtual void show ( unsigned level ) const; - - // - // server diagnostic counters (allowed to roll over) - // - // subscriptionEventsPosted() - // - number of events posted by server tool to the event queue - // subscriptionEventsProcessed() - // - number of events removed by server library from the event queue - // - unsigned subscriptionEventsPosted () const; - unsigned subscriptionEventsProcessed () const; - - class epicsTimer & createTimer (); - - void generateBeaconAnomaly (); - - // caStatus enableClients (); - // caStatus disableClients (); - -private: - class caServerI * pCAS; - - // deprecated interfaces (will be deleted in a future release) - virtual class pvCreateReturn createPV ( const casCtx & ctx, - const char * pPVAliasName ); - virtual pvExistReturn pvExistTest ( const casCtx & ctx, - const char * pPVAliasName ); -}; - -// -// casPV() - Channel Access Server Process Variable API Class -// -// Objects of this type are created by the caServer::pvAttach() -// object factory virtual function. -// -// Deletion Responsibility -// -------- -------------- -// o the server lib will not call "delete" directly for any -// casPV because we dont know that "new" was called to create -// the object -// o The server tool is responsible for reclaiming storage for any -// casPV it creates. The destroy() virtual function will -// assist the server tool with this responsibility. The -// virtual function casPV::destroy() does a "delete this". -// o The virtual function "destroy()" is called by the server lib -// each time that the last client attachment to the PV object is removed. -// o The destructor for this object will cancel any -// client attachment to this PV (and reclaim any resources -// allocated by the server library on its behalf) -// o If the server tool needs to asynchronously delete an object -// derived from casPV from another thread then it *must* also -// define a specialized destroy() method that prevent race conditions -// occurring when both the server library and the server tool attempt -// to destroy the same casPV derived object at the same instant. -// -// NOTE: if the server tool precreates the PV during initialization -// then it may decide to provide a "destroy()" implementation in the -// derived class which is a noop. -// -class epicsShareClass casPV { -public: - casPV (); - - virtual ~casPV (); - - // - // This is called for each PV in the server if - // caServer::show() is called and the level is high - // enough - // - virtual void show ( unsigned level ) const; - - // - // called by the server libary each time that it wishes to - // subscribe for PV change notification from the server - // tool via postEvent() below - // - virtual caStatus interestRegister (); - - // - // called by the server library each time that it wishes to - // remove its subscription for PV value change events - // from the server tool via postEvent() below - // - virtual void interestDelete (); - - // - // called by the server library immediately before initiating - // a transaction (PV state must not be modified during a - // transaction) - // - // NOTE: there may be many read/write operations performed within - // a single transaction if a large array is being transferred - // - virtual caStatus beginTransaction (); - - // - // called by the server library immediately after completing - // a tranaction (PV state modification may resume after the - // transaction completes) - // - virtual void endTransaction (); - - // - // read - // - // The request is allowed to complete asynchronously - // (see Asynchronous IO Classes below). - // - // RULE: if this completes asynchronously and the server tool references - // its data into the prototype descriptor passed in the args to read() - // then this data must _not_ be modified while the reference count - // on the prototype is greater than zero. - // - // Return S_casApp_postponeAsyncIO if too many simultaneous - // asynchronous IO operations are pending aginst the PV. - // The server library will retry the request whenever an - // asynchronous IO operation (read or write) completes - // against the PV. - // - // NOTE: - // o the server tool is encouraged to change the prototype GDD's - // primitive type to whatever primitive data type is most convient - // for the server side tool. Conversion libraries in the CA server - // will convert as necessary to the client's primitive data type. - // - virtual caStatus read (const casCtx &ctx, gdd &prototype); - - // - // write - // - // The request is allowed to complete asynchronously - // (see Asynchronous IO Classes below). - // - // Return S_casApp_postponeAsyncIO if too many simultaneous - // asynchronous IO operations are pending aginst the PV. - // The server library will retry the request whenever an - // asynchronous IO operation (read or write) completes - // against the PV. - // - // NOTES: - // o The incoming GDD with application type "value" is always - // converted to the PV.bestExternalType() primitive type. - // o The time stamp in the incoming GDD is set to the time that - // the last message was received from the client. - // o Currently, no container type GDD's are passed here and - // the application type is always "value". This may change. - // o The write interface is called when the server receives - // ca_put request and the writeNotify interface is called - // when the server receives ca_put_callback request. - // o A writeNotify request is considered complete and therefore - // ready for asynchronous completion notification when any - // action that it initiates, and any cascaded actions, complete. - // o In an IOC context intermediate write requets can be discarded - // as long as the final writeRequest is always executed. In an - // IOC context intermediate writeNotify requests are never discarded. - // o If the service does not implement writeNotify then - // the base implementation of casPV :: writeNotify calls - // casPV :: write thereby preserving backwards compatibility - // with the original interface which included a virtual write - // method but not a virtual writeNotify method. - // - virtual caStatus write (const casCtx &ctx, const gdd &value); - virtual caStatus writeNotify (const casCtx &ctx, const gdd &value); - - // - // chCreate() is called each time that a PV is attached to - // by a client. The server tool may choose not to - // implement this routine (in which case the channel - // will be created by the server). If the server tool - // implements this function then it must create a casChannel object - // (or a derived class) each time that this routine is called - // - virtual casChannel * createChannel ( const casCtx &ctx, - const char * const pUserName, const char * const pHostName ); - - // - // tbe best type for clients to use when accessing the - // value of the PV - // - virtual aitEnum bestExternalType () const; - - // - // Returns the maximum bounding box for all present and - // future data stored within the PV. - // - // The virtual function "dimension()" returns the maximum - // number of dimensions in the hypercube (0=scalar, - // 1=array, 2=plane, 3=cube ...}. - // - // The virtual function "maxBound(dimension)" returns the - // maximum number of elements in a particular dimension - // of the hypercube as follows: - // - // scalar - maxDimension() returns 0 - // - // array - maxDimension() returns 1 - // maxBounds(0) supplies number of elements in array - // - // plane - maxDimension() returns 2 - // maxBounds(0) supplies number of elements in X dimension - // maxBounds(1) supplies number of elements in Y dimension - // - // cube - maxDimension() returns 3 - // maxBounds(0) supplies number of elements in X dimension - // maxBounds(1) supplies number of elements in Y dimension - // maxBounds(2) supplies number of elements in Z dimension - // . - // . - // . - // - // The default (base) "dimension()" returns zero (scalar). - // The default (base) "maxBound()" returns one (scalar bounds) - // for all dimensions. - // - // Clients will see that the PV's data is scalar if - // these routines are not supplied in the derived class. - // - // If the "dimension" argument to maxBounds() is set to - // zero then the bound on the first dimension is being - // fetched. If the "dimension" argument to maxBound() is - // set to one then the bound on the second dimension - // are being fetched... - // - virtual unsigned maxDimension () const; // return zero if scalar - virtual aitIndex maxBound ( unsigned dimension ) const; - - // - // destroy() is called - // 1) each time that a PV transitions from - // a situation where clients are attached to a situation - // where no clients are attached. - // 2) once for all PVs that exist when the server is deleted - // - // the default (base) "destroy()" executes "delete this" - // - virtual void destroy (); - - // - // Server tool calls this function to post a PV event. - // - void postEvent ( const casEventMask & select, const gdd & event ); - - // - // peek at the pv name - // - // NOTE if there are several aliases for the same PV - // this routine should return the canonical (base) - // name for the PV - // - // pointer returned must remain valid for the life time - // o fthe process variable - // -// -// !! not thread safe !! -// - virtual const char * getName () const = 0; - - // - // Find the server associated with this PV - // ****WARNING**** - // this returns NULL if the PV isnt currently installed - // into a server (this situation will exist if - // the pv isnt deleted in a derived classes replacement - // for virtual casPV::destroy() or if the PV is created - // before the server - // *************** - // - caServer * getCAS () const; - - // not to be called by the user - void destroyRequest (); - -private: - class casPVI * pPVI; - casPV & operator = ( const casPV & ); - - friend class casStrmClient; -public: - // - // This constructor has been deprecated, and is preserved for - // backwards compatibility only. Please do not use it. - // - casPV ( caServer & ); -}; - -// -// casChannel - Channel Access Server - Channel API Class -// -// Objects of this type are created by the casPV::createChannel() -// object factory virtual function. -// -// A casChannel object is created each time that a CA client -// attaches to a process variable. -// -// Deletion Responsibility -// -------- -------------- -// o the server lib will not call "delete" directly for any -// casChannel created by the server tool because we dont know -// that "new" was called to create the object -// o The server tool is responsible for reclaiming storage for any -// casChannel it creates. The destroy() virtual function will -// assist the server tool with this responsibility. The -// virtual function casChannel::destroy() does a "delete this". -// o The destructor for this object will cancel any -// client attachment to this channel (and reclaim any resources -// allocated by the server library on its behalf) -// o If the server tool needs to asynchronously delete an object -// derived from casChannel from another thread then it *must* also -// define a specialized destroy() method that prevent race conditions -// occurring when both the server library and the server tool attempt -// to destroy the same casChannel derived object at the same instant. -// -class epicsShareClass casChannel { -public: - casChannel ( const casCtx & ctx ); - virtual ~casChannel (); - - // - // Called when the user name and the host name are changed - // for a live connection. - // - virtual void setOwner ( const char * const pUserName, - const char * const pHostName ); - - // - // the following are encouraged to change during an channel's - // lifetime - // - virtual bool readAccess () const; - virtual bool writeAccess () const; - // return true to hint that the opi should ask the operator - // for confirmation prior writing to this PV - virtual bool confirmationRequested () const; - - // - // If this function is not provided in the derived class then casPV::beginTransaction() - // is called - see casPV::beginTransaction() for additional comments. - // - virtual caStatus beginTransaction (); - - // - // If this function is not provided in the derived class then casPV::endTransaction() - // is called - see casPV::endTransaction() for additional comments. - // - virtual void endTransaction (); - - // - // read - // - // If this function is not provided in the derived class then casPV::read() - // is called - see casPV::read() for additional comments. - // - virtual caStatus read (const casCtx &ctx, gdd &prototype); - - // - // write - // - // If this function is not provided in the derived class then casPV::write() - // is called - see casPV::write() for additional comments. - // - virtual caStatus write (const casCtx &ctx, const gdd &value); - - // - // writeNotify - // - // If this function is not provided in the derived class then casPV::writeNotify() - // is called - see casPV::writeNotify() for additional comments. - // - virtual caStatus writeNotify (const casCtx &ctx, const gdd &value); - - // - // This is called for each channel in the server if - // caServer::show() is called and the level is high - // enough - // - virtual void show ( unsigned level ) const; - - // - // destroy() is called when - // 1) there is a client initiated channel delete - // 2) there is a server tool initiated PV delete - // - // the casChannel::destroy() executes a "delete this" - // - virtual void destroy (); - - // - // server tool calls this to indicate change in access - // rights has occurred - // - void postAccessRightsEvent (); - - // - // Find the PV associated with this channel - // ****WARNING**** - // this returns NULL if the channel isnt currently installed - // into a PV (this situation will exist only if - // the channel isnt deleted in a derived classes replacement - // for virtual casChannel::destroy() - // *************** - // - casPV * getPV (); - - // not to be called by the user - void destroyRequest (); - -private: - class casChannelI * pChanI; - - casChannel ( const casChannel & ); - casChannel & operator = ( const casChannel & ); - friend class casStrmClient; -}; - -// -// Asynchronous IO Classes -// -// The following virtual functions allow for asynchronous completion: -// -// Virtual Function Asynchronous IO Class -// ----------------- --------------------- -// caServer::pvExistTest() casAsyncPVExistIO -// caServer::pvAttach() casAsyncPVAttachIO -// casPV::read() casAsyncReadIO -// casPV::write() casAsyncWriteIO -// -// To initiate asynchronous completion create a corresponding -// asynchronous IO object from within one of the virtual -// functions shown in the table above and return the status code -// S_casApp_asyncCompletion. Use the member function -// "postIOCompletion()" to inform the server library that the -// requested operation has completed. -// -// -// Deletion Responsibility -// -------- -------------- -// o the server lib will not call "delete" directly for any -// casAsyncXxxIO created by the server tool because we dont know -// that "new" was called to create the object. -// o The server tool is responsible for reclaiming storage for any -// casAsyncXxxxIO it creates. The destroy virtual function will -// assist the server tool with this responsibility. The -// virtual function casAsyncXxxxIO::destroy() does a "delete this". -// o Avoid deleting the async IO object immediately after calling -// postIOCompletion(). Instead, proper operation requires that -// the server tool wait for the server lib to call destroy after -// the response is successfully queued to the client -// o If for any reason the server tool needs to cancel an IO -// operation then it should post io completion with status -// S_casApp_canceledAsyncIO. Deleting the asynchronous io -// object prior to its being allowed to forward an IO termination -// message to the client will result in NO IO CALL BACK TO THE -// CLIENT PROGRAM (in this situation a warning message will be -// printed by the server lib). -// - -// -// casAsyncReadIO -// - for use with casPV::read() -// -// **Warning** -// The server tool must reference the gdd object -// passed in the arguments to casPV::read() if it is -// necessary for this gdd object to continue to exist -// after the return from casPV::read(). If this -// is done then it is suggested that this gdd object -// be referenced in the constructor, and unreferenced -// in the destructor, for the class deriving from -// casAsyncReadIO. -// ** -class epicsShareClass casAsyncReadIO { -public: - - // - // casAsyncReadIO() - // - casAsyncReadIO ( const casCtx & ctx ); - virtual ~casAsyncReadIO (); - - // - // place notification of IO completion on the event queue - // (this function does not delete the casAsyncReadIO object) - // - // only the first call to this function has any effect - // - caStatus postIOCompletion ( - caStatus completionStatusIn, const gdd & valueRead ); - - // - // Find the server associated with this async IO - // ****WARNING**** - // this returns NULL if the async io isnt currently installed - // into a server - // *************** - // - caServer * getCAS () const; - -private: - class casAsyncReadIOI * pAsyncReadIOI; - // - // called by the server lib after the response message - // is succesfully queued to the client or when the - // IO operation is canceled (client disconnects etc) - // - // default destroy executes a "delete this" - // - virtual void destroy (); - - casAsyncReadIO ( const casAsyncReadIO & ); - casAsyncReadIO & operator = ( const casAsyncReadIO & ); - - void serverInitiatedDestroy (); - friend class casAsyncReadIOI; -}; - -// -// casAsyncWriteIO -// - for use with casPV::write() -// -// **Warning** -// The server tool must reference the gdd object -// passed in the arguments to casPV::write() if it is -// necessary for this gdd object to continue to exist -// after the return from casPV::write(). If this -// is done then it is suggested that this gdd object -// be referenced in the constructor, and unreferenced -// in the destructor, for the class deriving from -// casAsyncWriteIO. -// ** -// -class epicsShareClass casAsyncWriteIO { -public: - // - // casAsyncWriteIO() - // - casAsyncWriteIO ( const casCtx & ctx ); - virtual ~casAsyncWriteIO (); - - // - // place notification of IO completion on the event queue - // (this function does not delete the casAsyncWriteIO object). - // Only the first call to this function has any effect. - // - caStatus postIOCompletion ( caStatus completionStatusIn ); - - // - // Find the server associated with this async IO - // ****WARNING**** - // this returns NULL if the async io isnt currently installed - // into a server - // *************** - // - caServer * getCAS () const; - -private: - class casAsyncWriteIOI * pAsyncWriteIOI; - // - // called by the server lib after the response message - // is succesfully queued to the client or when the - // IO operation is canceled (client disconnects etc) - // - // default destroy executes a "delete this" - // - virtual void destroy (); - - casAsyncWriteIO ( const casAsyncWriteIO & ); - casAsyncWriteIO & operator = ( const casAsyncWriteIO & ); - - void serverInitiatedDestroy (); - friend class casAsyncWriteIOI; -}; - -// -// casAsyncPVExistIO -// - for use with caServer::pvExistTest() -// -class epicsShareClass casAsyncPVExistIO { -public: - - // - // casAsyncPVExistIO() - // - casAsyncPVExistIO ( const casCtx & ctx ); - virtual ~casAsyncPVExistIO (); - - // - // place notification of IO completion on the event queue - // (this function does not delete the casAsyncPVExistIO object) - // - // only the first call to this function has any effect. - // - caStatus postIOCompletion ( const pvExistReturn & retValIn ); - - // - // Find the server associated with this async IO - // ****WARNING**** - // this returns NULL if the async io isnt currently installed - // into a server - // *************** - // - caServer * getCAS () const; - -private: - class casAsyncPVExistIOI * pAsyncPVExistIOI; - - // - // called by the server lib after the response message - // is succesfully queued to the client or when the - // IO operation is canceled (client disconnects etc) - // - // default destroy executes a "delete this" - // - virtual void destroy (); - - casAsyncPVExistIO ( const casAsyncPVExistIO & ); - casAsyncPVExistIO & operator = ( const casAsyncPVExistIO & ); - - friend class casAsyncPVExistIOI; - void serverInitiatedDestroy (); -}; - -// -// casAsyncPVAttachIO -// - for use with caServer::pvAttach() -// -class epicsShareClass casAsyncPVAttachIO { -public: - // - // casAsyncPVAttachIO() - // - casAsyncPVAttachIO ( const casCtx & ctx ); - virtual ~casAsyncPVAttachIO (); - - // - // place notification of IO completion on the event queue - // (this function does not delete the casAsyncPVAttachIO object). - // Only the first call to this function has any effect. - // - caStatus postIOCompletion ( const pvAttachReturn & retValIn ); - - // - // Find the server associated with this async IO - // ****WARNING**** - // this returns NULL if the async io isnt currently installed - // into a server - // *************** - // - caServer * getCAS () const; - -private: - class casAsyncPVAttachIOI * pAsyncPVAttachIOI; - - // - // called by the server lib after the response message - // is succesfully queued to the client or when the - // IO operation is canceled (client disconnects etc) - // - // default destroy executes a "delete this" - // - virtual void destroy (); - - casAsyncPVAttachIO ( const casAsyncPVAttachIO & ); - casAsyncPVAttachIO & operator = ( const casAsyncPVAttachIO & ); - - friend class casAsyncPVAttachIOI; - void serverInitiatedDestroy (); -}; - -// -// casAsyncPVCreateIO (deprecated) -// (this class will be deleted in a future release) -// -class epicsShareClass casAsyncPVCreateIO : private casAsyncPVAttachIO { -public: - casAsyncPVCreateIO ( const casCtx & ctx ); - virtual ~casAsyncPVCreateIO (); -private: - casAsyncPVCreateIO ( const casAsyncPVCreateIO & ); - casAsyncPVCreateIO & operator = ( const casAsyncPVCreateIO & ); -}; - -// -// pvCreateReturn (deprecated) -// (the class "pvCreateReturn" will be deleted in a future release) -// -class epicsShareClass pvCreateReturn : public pvAttachReturn { -public: - pvCreateReturn ( caStatus statIn ) : pvAttachReturn ( statIn ) {}; - pvCreateReturn ( casPV & pvIn ) : pvAttachReturn ( pvIn ) {}; -}; - -// TODO: -// .03 document new event types for limits change etc -// .04 certain things like native type cant be changed during -// pv id's life time or we will be required to have locking -// (doc this) -// .08 Need a mechanism by which an error detail string can be returned -// to the server from a server app (in addition to the normal -// error constant) -// .12 Should the server have an interface so that all PV names -// can be obtained (even ones created after init)? This -// would be used to implement update of directory services and -// wild cards? Problems here with knowing PV name structure and -// maximum permutations of name components. -// .16 go through this file and make sure that we are consistent about -// the use of const - use a pointer only in spots where NULL is -// allowed? -// NOTES: -// .01 When this code is used in a multi threaded situation we -// must be certain that the derived class's virtual function -// are not called between derived class destruction and base -// class destruction (or prevent problems if they are). -// Possible solutions -// 1) in the derived classes destructor set a variable which -// inhibits use of the derived classes virtual function. -// Each virtual function must check this inhibit bit and return -// an error if it is set -// 2) call a method on the base which prevents further use -// of it by the server from the derived class destructor. -// 3) some form of locking (similar to (1) above) -// - -#endif // ifdef includecasdefh (this must be the last line in this file) - diff --git a/src/ca/legacy/pcas/generic/chanIntfForPV.cc b/src/ca/legacy/pcas/generic/chanIntfForPV.cc deleted file mode 100644 index 4c983df60..000000000 --- a/src/ca/legacy/pcas/generic/chanIntfForPV.cc +++ /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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "chanIntfForPV.h" -#include "casCoreClient.h" -#include "casPVI.h" - -chanIntfForPV::chanIntfForPV ( class casCoreClient & clientIn, - casChannelDestroyFromPV & destroyRefIn ) : - clientRef ( clientIn ), destroyRef ( destroyRefIn ) -{ -} - -chanIntfForPV::~chanIntfForPV () -{ - while ( casMonitor * pMon = this->monitorList.get () ) { - this->clientRef.destroyMonitor ( *pMon ); - } -} - -class casCoreClient & chanIntfForPV::client () const -{ - return this->clientRef; -} - -void chanIntfForPV::installMonitor ( casPVI & pv, casMonitor & mon ) -{ - caStatus status = pv.installMonitor ( - mon, this->monitorList ); - if ( status ) { - errMessage ( status, - "Server tool failed to register event\n" ); - } -} - -void chanIntfForPV::show ( unsigned level ) const -{ - printf ( "chanIntfForPV\n" ); - if ( level > 0 && this->monitorList.count() ) { - printf ( "List of subscriptions attached\n" ); - tsDLIterConst < casMonitor > iter = - this->monitorList.firstIter (); - while ( iter.valid () ) { - iter->show ( level - 1 ); - ++iter; - } - } -} - - diff --git a/src/ca/legacy/pcas/generic/chanIntfForPV.h b/src/ca/legacy/pcas/generic/chanIntfForPV.h deleted file mode 100644 index c61a97bab..000000000 --- a/src/ca/legacy/pcas/generic/chanIntfForPV.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 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 chanIntfForPVh -#define chanIntfForPVh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_chanIntfForPVh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "tsDLList.h" -#include "caProto.h" - -#ifdef epicsExportSharedSymbols_chanIntfForPVh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casStrmClient.h" -#include "casPVI.h" - -class casMonitor; -class casPVI; -class casEventMask; -class gdd; - -class casChannelDestroyFromPV { -public: - virtual void postDestroyEvent () = 0; -protected: - virtual ~casChannelDestroyFromPV() {} -}; - -class chanIntfForPV : public tsDLNode < chanIntfForPV > { -public: - chanIntfForPV ( class casCoreClient &, casChannelDestroyFromPV & ); - ~chanIntfForPV (); - class casCoreClient & client () const; - void installMonitor ( casPVI & pv, casMonitor & mon ); - casMonitor * removeMonitor ( casPVI &, ca_uint32_t monId ); - void removeSelfFromPV ( casPVI &, - tsDLList < casMonitor > & dest ); - void postEvent ( const casEventMask &, const gdd & ); - void show ( unsigned level ) const; - void postDestroyEvent (); -private: - tsDLList < casMonitor > monitorList; - class casCoreClient & clientRef; - casChannelDestroyFromPV & destroyRef; - chanIntfForPV ( const chanIntfForPV & ); - chanIntfForPV & operator = ( const chanIntfForPV & ); -}; - -inline void chanIntfForPV::postEvent ( - const casEventMask & select, const gdd & event ) -{ - this->clientRef.postEvent ( this->monitorList, select, event ); -} - -inline casMonitor * chanIntfForPV::removeMonitor ( - casPVI & pv, ca_uint32_t clientIdIn ) -{ - return pv.removeMonitor ( this->monitorList, clientIdIn ); -} - -inline void chanIntfForPV::removeSelfFromPV ( - casPVI & pv, tsDLList < casMonitor > & dest ) -{ - pv.removeChannel ( *this, this->monitorList, dest ); -} - -inline void chanIntfForPV::postDestroyEvent () -{ - this->destroyRef.postDestroyEvent (); -} - -#endif // chanIntfForPVh diff --git a/src/ca/legacy/pcas/generic/channelDestroyEvent.cpp b/src/ca/legacy/pcas/generic/channelDestroyEvent.cpp deleted file mode 100644 index 33c64938a..000000000 --- a/src/ca/legacy/pcas/generic/channelDestroyEvent.cpp +++ /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 Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - - -#define epicsExportSharedSymbols -#include "channelDestroyEvent.h" -#include "casCoreClient.h" - -caStatus channelDestroyEvent::cbFunc ( - casCoreClient & client, - epicsGuard < casClientMutex > & clientGuard, - epicsGuard < evSysMutex > & ) -{ - caStatus status = client.channelDestroyEventNotify ( - clientGuard, this->pChan, this->sid ); - if ( status != S_cas_sendBlocked ) { - delete this; - } - return status; -} - diff --git a/src/ca/legacy/pcas/generic/channelDestroyEvent.h b/src/ca/legacy/pcas/generic/channelDestroyEvent.h deleted file mode 100644 index 17b32f72a..000000000 --- a/src/ca/legacy/pcas/generic/channelDestroyEvent.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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef channelDestroyEventh -#define channelDestroyEventh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_channelDestroyEventh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "caProto.h" - -#ifdef epicsExportSharedSymbols_channelDestroyEventh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casEvent.h" - -class casChannelI; - -class channelDestroyEvent : public casEvent { -public: - channelDestroyEvent ( - casChannelI * pChan, ca_uint32_t sid ); -private: - casChannelI * pChan; - ca_uint32_t sid; - caStatus cbFunc ( - casCoreClient &, - epicsGuard < casClientMutex > &, - epicsGuard < evSysMutex > & ); -}; - -inline channelDestroyEvent::channelDestroyEvent ( - casChannelI * pChanIn, ca_uint32_t sidIn ) : - pChan ( pChanIn ), sid ( sidIn ) -{ -} - -#endif // channelDestroyEventh - diff --git a/src/ca/legacy/pcas/generic/clientBufMemoryManager.cpp b/src/ca/legacy/pcas/generic/clientBufMemoryManager.cpp deleted file mode 100644 index 167995f91..000000000 --- a/src/ca/legacy/pcas/generic/clientBufMemoryManager.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. -\*************************************************************************/ -/* - * Author Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#include - -#include - -#include "epicsAssert.h" -#include "freeList.h" - -#define epicsExportSharedSymbols -#include "clientBufMemoryManager.h" -#include "caProto.h" - -clientBufMemoryManager::clientBufMemoryManager() - :smallBufFreeList ( 0 ) -{ - freeListInitPvt ( & this->smallBufFreeList, MAX_MSG_SIZE, 8 ); -} - -clientBufMemoryManager::~clientBufMemoryManager() -{ - freeListCleanup ( this->smallBufFreeList ); -} - -casBufferParm clientBufMemoryManager::allocate ( bufSizeT newMinSize ) -{ - casBufferParm parm; - if ( newMinSize <= MAX_MSG_SIZE ) { - parm.pBuf = (char*)freeListMalloc(this->smallBufFreeList); - parm.bufSize = MAX_MSG_SIZE; - } - else { - // round size up to multiple of 4K - newMinSize = ((newMinSize-1)|0xfff)+1; - parm.pBuf = (char*)malloc(newMinSize); - parm.bufSize = newMinSize; - } - if(!parm.pBuf) - throw std::bad_alloc(); - return parm; -} - -void clientBufMemoryManager::release ( char * pBuf, bufSizeT bufSize ) -{ - assert(pBuf); - if (bufSize <= MAX_MSG_SIZE) { - freeListFree(this->smallBufFreeList, pBuf); - } - else { - free(pBuf); - } -} - diff --git a/src/ca/legacy/pcas/generic/clientBufMemoryManager.h b/src/ca/legacy/pcas/generic/clientBufMemoryManager.h deleted file mode 100644 index 9a823484d..000000000 --- a/src/ca/legacy/pcas/generic/clientBufMemoryManager.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 clientBufMemoryManagerh -#define clientBufMemoryManagerh - -#include - -typedef unsigned bufSizeT; -static const unsigned bufSizeT_MAX = UINT_MAX; - -struct casBufferParm { - char * pBuf; - bufSizeT bufSize; -}; - -class clientBufMemoryManager { -public: - clientBufMemoryManager(); - ~clientBufMemoryManager(); - - //! @throws std::bad_alloc on failure - casBufferParm allocate ( bufSizeT newMinSize ); - void release ( char * pBuf, bufSizeT bufSize ); -private: - - void * smallBufFreeList; -}; - -#endif // clientBufMemoryManagerh - diff --git a/src/ca/legacy/pcas/generic/inBuf.cc b/src/ca/legacy/pcas/generic/inBuf.cc deleted file mode 100644 index 046c9f18a..000000000 --- a/src/ca/legacy/pcas/generic/inBuf.cc +++ /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 - */ - -#include -#include - -#include -#include - -#define epicsExportSharedSymbols -#include "inBuf.h" - -// -// inBuf::inBuf() -// -inBuf::inBuf ( inBufClient & clientIn, clientBufMemoryManager & memMgrIn, - bufSizeT ioMinSizeIn ) : - client ( clientIn ), memMgr ( memMgrIn ), pBuf ( 0 ), - bufSize ( 0u ), bytesInBuffer ( 0u ), nextReadIndex ( 0u ), - ioMinSize ( ioMinSizeIn ), ctxRecursCount ( 0u ) -{ - if ( this->ioMinSize == 0 ) { - this->ioMinSize = 1; - } - casBufferParm bufParm = this->memMgr.allocate ( this->ioMinSize ); - this->pBuf = bufParm.pBuf; - this->bufSize = bufParm.bufSize; -} - -// -// inBuf::~inBuf() -// (virtual destructor) -// -inBuf::~inBuf () -{ - assert ( this->ctxRecursCount == 0 ); - this->memMgr.release ( this->pBuf, this->bufSize ); -} - -// -// inBuf::show() -// -void inBuf :: show (unsigned level) const -{ - if ( level > 1u ) { - printf ( - "\tUnprocessed request bytes = %d\n", - this->bytesPresent () ); - } -} - -// -// inBuf::fill() -// -inBufClient::fillCondition inBuf::fill ( inBufClient::fillParameter parm ) -{ - bufSizeT bytesOpen; - bufSizeT bytesRecv; - inBufClient::fillCondition stat; - - // - // move back any prexisting data to the start of the buffer - // - if ( this->nextReadIndex > 0 ) { - assert ( this->bytesInBuffer >= this->nextReadIndex ); - bufSizeT unprocessedBytes = - this->bytesInBuffer - this->nextReadIndex; - // - // memmove() handles overlapping buffers - // - if (unprocessedBytes>0u) { - memmove (this->pBuf, this->pBuf+this->nextReadIndex, - unprocessedBytes); - } - this->bytesInBuffer = unprocessedBytes; - this->nextReadIndex = 0u; - } - - // - // noop if the buffer is full - // - bytesOpen = this->bufSize - this->bytesInBuffer; - if ( bytesOpen < this->ioMinSize ) { - return inBufClient::casFillNone; - } - - stat = this->client.xRecv ( &this->pBuf[this->bytesInBuffer], - bytesOpen, parm, bytesRecv ); - if ( stat == inBufClient::casFillProgress ) { - assert (bytesRecv<=bytesOpen); - this->bytesInBuffer += bytesRecv; - - if ( this->client.getDebugLevel() > 2u ) { - char buf[64]; - - this->client.hostName ( buf, sizeof ( buf ) ); - - fprintf ( stderr, "CAS Incoming: %u byte msg from %s\n", - bytesRecv, buf); - } - } - - return stat; -} - -// -// inBuf::pushCtx () -// -const inBufCtx inBuf::pushCtx ( bufSizeT headerSize, - bufSizeT bodySize ) -{ - if ( headerSize + bodySize > ( this->bytesInBuffer - this->nextReadIndex ) || - this->ctxRecursCount == UINT_MAX ) { - return inBufCtx (); - } - else { - inBufCtx result (*this); - bufSizeT effectiveNextReadIndex = this->nextReadIndex + headerSize; - this->pBuf = this->pBuf + effectiveNextReadIndex; - this->bytesInBuffer -= effectiveNextReadIndex; - this->nextReadIndex = 0; - this->bytesInBuffer = bodySize; - this->bufSize = this->bytesInBuffer; - this->ctxRecursCount++; - return result; - } -} - -// -// inBuf::popCtx () -// -bufSizeT inBuf::popCtx ( const inBufCtx &ctx ) -{ - if ( ctx.stat==inBufCtx::pushCtxSuccess ) { - bufSizeT bytesRemoved = this->nextReadIndex; - this->pBuf = ctx.pBuf; - this->bufSize = ctx.bufSize; - this->bytesInBuffer = ctx.bytesInBuffer; - this->nextReadIndex = ctx.nextReadIndex; - assert ( this->ctxRecursCount > 0 ); - this->ctxRecursCount--; - return bytesRemoved; - } - else { - return 0; - } -} - -void inBuf::expandBuffer (bufSizeT needed) -{ - if (needed > bufSize) { - casBufferParm bufParm; - try { - bufParm = this->memMgr.allocate ( needed ); - } catch (std::bad_alloc& e) { - // caller must check that buffer size has expended - return; - } - - bufSizeT unprocessedBytes = this->bytesPresent (); - memcpy ( bufParm.pBuf, &this->pBuf[this->nextReadIndex], unprocessedBytes ); - this->bytesInBuffer = unprocessedBytes; - this->nextReadIndex = 0u; - this->memMgr.release ( this->pBuf, this->bufSize ); - this->pBuf = bufParm.pBuf; - this->bufSize = bufParm.bufSize; - } -} - -bufSizeT inBuf::bufferSize() const -{ - return this->bufSize; -} - - diff --git a/src/ca/legacy/pcas/generic/inBuf.h b/src/ca/legacy/pcas/generic/inBuf.h deleted file mode 100644 index 8098ad26e..000000000 --- a/src/ca/legacy/pcas/generic/inBuf.h +++ /dev/null @@ -1,159 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 inBufh -#define inBufh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_inBufh -# undef epicsExportSharedSymbols -#endif - -#undef epicsAssertAuthor -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" -#include "epicsAssert.h" - -#ifdef epicsExportSharedSymbols_inBufh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "clientBufMemoryManager.h" - -class inBufCtx { - friend class inBuf; -public: - enum pushCtxResult { pushCtxNoSpace, pushCtxSuccess }; - inBufCtx ( const class inBuf & ); // success - inBufCtx (); // failure - - pushCtxResult pushResult () const; - -private: - pushCtxResult stat; - char * pBuf; - bufSizeT bufSize; - bufSizeT bytesInBuffer; - bufSizeT nextReadIndex; -}; - -class inBufClient { -public: - enum fillCondition { casFillNone, casFillProgress, - casFillDisconnect }; - // this is a hack for a Solaris IP kernel feature - enum fillParameter { fpNone, fpUseBroadcastInterface }; - virtual unsigned getDebugLevel () const = 0; - virtual fillCondition xRecv ( char *pBuf, bufSizeT nBytesToRecv, - enum fillParameter parm, bufSizeT &nByesRecv ) = 0; - virtual void hostName ( char *pBuf, unsigned bufSize ) const = 0; -protected: - virtual ~inBufClient() {} -}; - -class inBuf { - friend class inBufCtx; -public: - inBuf ( class inBufClient &, class clientBufMemoryManager &, - bufSizeT ioMinSizeIn ); - virtual ~inBuf (); - bufSizeT bytesPresent () const; - bool full () const; - inBufClient::fillCondition fill ( - inBufClient::fillParameter parm = inBufClient::fpNone ); - void show ( unsigned level ) const; - void removeMsg ( bufSizeT nBytes ); - char * msgPtr () const; - // - // This is used to create recursive protocol stacks. A subsegment - // of the buffer of max size "maxSize" is assigned to the next - // layer down in the protocol stack by pushCtx () until popCtx () - // is called. The roiutine popCtx () returns the actual number - // of bytes used by the next layer down. - // - // pushCtx() returns an outBufCtx to be restored by popCtx() - // - const inBufCtx pushCtx ( bufSizeT headerSize, bufSizeT bodySize ); - bufSizeT popCtx ( const inBufCtx & ); // returns actual size - bufSizeT bufferSize () const; - void expandBuffer (bufSizeT needed); -private: - class inBufClient & client; - class clientBufMemoryManager & memMgr; - char * pBuf; - bufSizeT bufSize; - bufSizeT bytesInBuffer; - bufSizeT nextReadIndex; - bufSizeT ioMinSize; - unsigned ctxRecursCount; - inBuf ( const inBuf & ); - inBuf & operator = ( const inBuf & ); -}; - -// -// inBuf::bytesPresent() -// -inline bufSizeT inBuf::bytesPresent () const -{ - return this->bytesInBuffer - this->nextReadIndex; -} - -// -// inBuf::full() -// -inline bool inBuf::full () const -{ - if (this->bufSize-this->bytesPresent()ioMinSize) { - return true; - } - return false; -} - -// -// inBuf::msgPtr() -// -inline char *inBuf::msgPtr () const -{ - return &this->pBuf[this->nextReadIndex]; -} - -// -// inBuf::removeMsg() -// -inline void inBuf::removeMsg ( bufSizeT nBytes ) -{ - this->nextReadIndex += nBytes; - assert ( this->nextReadIndex <= this->bytesInBuffer ); -} - -// -// inBufCtx::inBufCtx () -// -inline inBufCtx::inBufCtx () : - stat (pushCtxNoSpace) {} - -// -// inBufCtx::inBufCtx () -// -inline inBufCtx::inBufCtx (const inBuf &inBufIn) : - stat (pushCtxSuccess), pBuf (inBufIn.pBuf), - bufSize (inBufIn.bufSize), bytesInBuffer (inBufIn.bytesInBuffer), - nextReadIndex (inBufIn.nextReadIndex) {} - -// -// inBufCtx::pushResult -// -inline inBufCtx::pushCtxResult inBufCtx::pushResult () const -{ - return this->stat; -} - -#endif // inBufh - diff --git a/src/ca/legacy/pcas/generic/ioBlocked.h b/src/ca/legacy/pcas/generic/ioBlocked.h deleted file mode 100644 index 000292eaf..000000000 --- a/src/ca/legacy/pcas/generic/ioBlocked.h +++ /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 Jeffrey O. Hill - * johill@lanl.gov - * 505 665 1831 - */ - -#ifndef ioBlockedh -#define ioBlockedh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_ioBlockedh -# undef epicsExportSharedSymbols -#endif - -#include "tsDLList.h" - -#ifdef epicsExportSharedSymbols_ioBlockedh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class ioBlocked : public tsDLNode < ioBlocked > { -friend class ioBlockedList; -public: - ioBlocked (); - virtual ~ioBlocked (); - bool isBlocked (); -private: - class ioBlockedList * pList; - virtual void ioBlockedSignal (); -}; - -class ioBlockedList : private tsDLList { -friend class ioBlocked; -public: - ioBlockedList (); - virtual ~ioBlockedList (); - void signal (); - void addItemToIOBLockedList ( ioBlocked & item ); - ioBlockedList ( const ioBlockedList & ); - ioBlockedList & operator = ( const ioBlockedList & ); -}; - -inline bool ioBlocked :: isBlocked () -{ - return this->pList != NULL; -} - -#endif // ioBlockedh - diff --git a/src/ca/legacy/pcas/generic/mt/README b/src/ca/legacy/pcas/generic/mt/README deleted file mode 100644 index 73d5be3dd..000000000 --- a/src/ca/legacy/pcas/generic/mt/README +++ /dev/null @@ -1,5 +0,0 @@ - -This directory contains files specific to the multi-threaded -version of the CA server - -- diff --git a/src/ca/legacy/pcas/generic/mt/ioBlocked.cc b/src/ca/legacy/pcas/generic/mt/ioBlocked.cc deleted file mode 100644 index 974d113e2..000000000 --- a/src/ca/legacy/pcas/generic/mt/ioBlocked.cc +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 -// This file implements a IO blocked list NOOP for multi-threaded systems -// - -#include - -#define epicsExportSharedSymbols -#include "casdef.h" - -// -// ioBlocked::~ioBlocked() -// -ioBlocked::ioBlocked() : - pList(NULL) -{ -} - -// -// ioBlocked::~ioBlocked() -// -ioBlocked::~ioBlocked() -{ -} - -// -// ioBlocked::ioBlockedSignal () -// -void ioBlocked::ioBlockedSignal () -{ - // - // this must _not_ be pure virtual because - // there are situations where this is called - // inbetween the derived class's and this base - // class's destructors, and therefore a - // NOOP is required - // -} - -// -// ioBlockedList::ioBlockedList () -// -ioBlockedList::ioBlockedList () -{ -} - -// -// ioBlockedList::~ioBlockedList () -// (NOOP on MT system) -// -ioBlockedList::~ioBlockedList () -{ -} - -// -// ioBlockedList::signal() -// (NOOP on MT system) -// -void ioBlockedList::signal() -{ -} - -// -// ioBlockedList::addItemToIOBLockedList() -// (NOOP on MT system) -// -void ioBlockedList::addItemToIOBLockedList(ioBlocked &) -{ -} - - diff --git a/src/ca/legacy/pcas/generic/outBuf.cc b/src/ca/legacy/pcas/generic/outBuf.cc deleted file mode 100644 index ed9cd8505..000000000 --- a/src/ca/legacy/pcas/generic/outBuf.cc +++ /dev/null @@ -1,337 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "errlog.h" -#include "epicsTime.h" - -#define epicsExportSharedSymbols -#include "outBuf.h" -#include "osiWireFormat.h" - -const char * outBufClient :: ppFlushCondText[3] = -{ - "flushNone", - "flushProgress", - "flushDisconnect" -}; - -// -// outBuf::outBuf() -// -outBuf::outBuf ( outBufClient & clientIn, - clientBufMemoryManager & memMgrIn ) : - client ( clientIn ), memMgr ( memMgrIn ), bufSize ( 0 ), - stack ( 0u ), ctxRecursCount ( 0u ) -{ - casBufferParm bufParm = memMgr.allocate ( 1 ); - this->pBuf = bufParm.pBuf; - this->bufSize = bufParm.bufSize; - memset ( this->pBuf, '\0', this->bufSize ); -} - -// -// outBuf::~outBuf() -// -outBuf::~outBuf() -{ - assert ( this->ctxRecursCount == 0 ); - memMgr.release ( this->pBuf, this->bufSize ); -} - -// -// outBuf::allocRawMsg () -// -caStatus outBuf::allocRawMsg ( bufSizeT msgsize, void **ppMsg ) -{ - bufSizeT stackNeeded; - - msgsize = CA_MESSAGE_ALIGN ( msgsize ); - - if ( msgsize > this->bufSize ) { - this->expandBuffer (msgsize); - if ( msgsize > this->bufSize ) { - return S_cas_hugeRequest; - } - } - - stackNeeded = this->bufSize - msgsize; - - if ( this->stack > stackNeeded ) { - // - // Try to flush the output queue - // - this->flush (); - - // - // If this failed then the fd is nonblocking - // and we will let select() take care of it - // - if ( this->stack > stackNeeded ) { - this->client.sendBlockSignal(); - return S_cas_sendBlocked; - } - } - - // - // it fits so commitMsg() will move the stack pointer forward - // - *ppMsg = (void *) &this->pBuf[this->stack]; - - return S_cas_success; -} - -// code size is allowed to increase here somewhat in the -// interest of efficency since this is a very frequently -// called function -caStatus outBuf::copyInHeader ( 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 ) -{ - ca_uint32_t alignedPayloadSize = CA_MESSAGE_ALIGN ( payloadSize ); - char * pPayload; - - if ( alignedPayloadSize < 0xffff && nElem < 0xffff ) { - ca_uint32_t msgSize = sizeof ( caHdr ) + alignedPayloadSize; - caHdr * pHdr; - caStatus status = this->allocRawMsg ( - msgSize, reinterpret_cast < void ** > ( & pHdr ) ); - if ( status != S_cas_success ) { - return status; - } - - AlignedWireRef < epicsUInt16 > ( pHdr->m_cmmd ) = response; - AlignedWireRef < epicsUInt16 > ( pHdr->m_dataType ) = dataType; - AlignedWireRef < epicsUInt32 > ( pHdr->m_cid ) = cid; - AlignedWireRef < epicsUInt32 > ( pHdr->m_available ) = responseSpecific; - AlignedWireRef < epicsUInt16 > ( pHdr->m_postsize ) = - static_cast < epicsUInt16 > ( alignedPayloadSize ); - AlignedWireRef < epicsUInt16 > ( pHdr->m_count ) = - static_cast < epicsUInt16 > ( nElem ); - pPayload = reinterpret_cast < char * > ( pHdr + 1 ); - } - else { - ca_uint32_t msgSize = sizeof ( caHdr ) + - 2 * sizeof (ca_uint32_t) + alignedPayloadSize; - caHdr * pHdr; - caStatus status = this->allocRawMsg ( - msgSize, reinterpret_cast < void ** > ( & pHdr ) ); - if ( status != S_cas_success ) { - return status; - } - - AlignedWireRef < epicsUInt16 > ( pHdr->m_cmmd ) = response; - AlignedWireRef < epicsUInt16 > ( pHdr->m_dataType ) = dataType; - AlignedWireRef < epicsUInt32 > ( pHdr->m_cid ) = cid; - AlignedWireRef < epicsUInt32 > ( pHdr->m_available ) = responseSpecific; - AlignedWireRef < epicsUInt16 > ( pHdr->m_postsize ) = 0xffff; - AlignedWireRef < epicsUInt16 > ( pHdr->m_count ) = 0; - ca_uint32_t * pLW = reinterpret_cast < ca_uint32_t * > ( pHdr + 1 ); - AlignedWireRef < epicsUInt32 > sizeWireRef ( pLW[0] ); - sizeWireRef = alignedPayloadSize; - AlignedWireRef < epicsUInt32 > nElemWireRef ( pLW[1] ); - nElemWireRef= nElem; - pPayload = reinterpret_cast < char * > ( pLW + 2 ); - } - - /* zero out pad bytes */ - if ( alignedPayloadSize > payloadSize ) { - memset ( pPayload + payloadSize, '\0', - alignedPayloadSize - payloadSize ); - } - - if ( ppPayload ) { - *ppPayload = pPayload; - } - - return S_cas_success; -} - -// -// outBuf::commitMsg () -// -void outBuf::commitMsg () -{ - ca_uint32_t payloadSize; - ca_uint32_t elementCount; - ca_uint32_t hdrSize; - - const caHdr * mp = ( caHdr * ) & this->pBuf[ this->stack ]; - if ( mp->m_postsize == 0xffff || mp->m_count == 0xffff ) { - const ca_uint32_t *pLW = reinterpret_cast ( mp + 1 ); - payloadSize = AlignedWireRef < const epicsUInt32 > ( pLW[0] ); - elementCount = AlignedWireRef < const epicsUInt32 > ( pLW[1] ); - hdrSize = sizeof ( caHdr ) + 2 * sizeof ( ca_uint32_t ); - } - else { - payloadSize = AlignedWireRef < const epicsUInt16 > ( mp->m_postsize ); - elementCount = AlignedWireRef < const epicsUInt16 > ( mp->m_count ); - hdrSize = sizeof ( caHdr ); - } - - this->commitRawMsg ( hdrSize + payloadSize ); - - unsigned debugLevel = this->client.getDebugLevel(); - if ( debugLevel ) { - epicsUInt16 cmmd = AlignedWireRef < const epicsUInt16 > ( mp->m_cmmd ); - if ( cmmd != CA_PROTO_VERSION || debugLevel > 2 ) { - epicsUInt16 type = AlignedWireRef < const epicsUInt16 > ( mp->m_dataType ); - epicsUInt32 cid = AlignedWireRef < const epicsUInt32 > ( mp->m_cid ); - epicsUInt32 avail = AlignedWireRef < const epicsUInt32 > ( mp->m_available ); - fprintf ( stderr, - "CAS Response: cmd=%d id=%x typ=%d cnt=%d psz=%d avail=%x outBuf ptr=%p \n", - cmmd, cid, type, elementCount, payloadSize, avail, - static_cast < const void * > ( mp ) ); - } - } -} - -// -// outBuf::commitMsg () -// -void outBuf::commitMsg ( ca_uint32_t reducedPayloadSize ) -{ - caHdr * mp = ( caHdr * ) & this->pBuf[ this->stack ]; - reducedPayloadSize = CA_MESSAGE_ALIGN ( reducedPayloadSize ); - if ( mp->m_postsize == 0xffff || mp->m_count == 0xffff ) { - ca_uint32_t *pLW = reinterpret_cast ( mp + 1 ); - AlignedWireRef < epicsUInt32 > payloadSizeExtended ( pLW[0] ); - assert ( reducedPayloadSize <= payloadSizeExtended ); - payloadSizeExtended = reducedPayloadSize; - } - else { - AlignedWireRef < epicsUInt16 > payloadSizeOnWire ( mp->m_postsize ); - ca_uint32_t payloadSize = payloadSizeOnWire; - assert ( reducedPayloadSize <= payloadSize ); - payloadSizeOnWire = static_cast < ca_uint16_t > ( reducedPayloadSize ); - } - this->commitMsg (); -} - -// -// outBuf::flush () -// -outBufClient::flushCondition outBuf :: flush () -{ - if ( this->ctxRecursCount > 0 ) { - return outBufClient::flushNone; - } - - bufSizeT nBytesSent; - //epicsTime beg = epicsTime::getCurrent (); - outBufClient :: flushCondition cond = - this->client.xSend ( this->pBuf, this->stack, nBytesSent ); - //epicsTime end = epicsTime::getCurrent (); - //printf ( "send of %u bytes, stat =%s, cost us %f u sec\n", - // this->stack, this->client.ppFlushCondText[cond], ( end - beg ) * 1e6 ); - if ( cond == outBufClient::flushProgress ) { - if ( nBytesSent >= this->stack ) { - this->stack = 0u; - } - else { - bufSizeT len = this->stack - nBytesSent; - // - // memmove() is ok with overlapping buffers - // - //epicsTime beg = epicsTime::getCurrent (); - memmove ( this->pBuf, &this->pBuf[nBytesSent], len ); - //epicsTime end = epicsTime::getCurrent (); - //printf ( "mem move cost us %f nano sec\n", ( end - beg ) * 1e9 ); - this->stack = len; - } - - if ( this->client.getDebugLevel () > 2u ) { - char buf[64]; - this->client.hostName ( buf, sizeof ( buf ) ); - fprintf ( stderr, "CAS outgoing: %u byte reply to %s\n", - nBytesSent, buf ); - } - } - return cond; -} - -// -// outBuf::pushCtx () -// -const outBufCtx outBuf::pushCtx ( bufSizeT headerSize, - bufSizeT maxBodySize, - void *&pHeader ) -{ - bufSizeT totalSize = headerSize + maxBodySize; - caStatus status; - - status = this->allocRawMsg ( totalSize, & pHeader ); - if ( status != S_cas_success ) { - return outBufCtx (); - } - else if ( this->ctxRecursCount >= UINT_MAX ) { - return outBufCtx (); - } - else { - outBufCtx result ( *this ); - this->pBuf = this->pBuf + this->stack + headerSize; - this->stack = 0; - this->bufSize = maxBodySize; - this->ctxRecursCount++; - return result; - } -} - -// -// outBuf::popCtx () -// -bufSizeT outBuf::popCtx (const outBufCtx &ctx) -{ - if (ctx.stat==outBufCtx::pushCtxSuccess) { - bufSizeT bytesAdded = this->stack; - this->pBuf = ctx.pBuf; - this->bufSize = ctx.bufSize; - this->stack = ctx.stack; - assert (this->ctxRecursCount>0u); - this->ctxRecursCount--; - return bytesAdded; - } - else { - return 0; - } -} - -// -// outBuf::show (unsigned level) -// -void outBuf::show (unsigned level) const -{ - if ( level > 1u ) { - printf("\tUndelivered response bytes = %d\n", this->bytesPresent()); - } -} - -void outBuf::expandBuffer (bufSizeT needed) -{ - if (needed > bufSize) { - casBufferParm bufParm; - try { - bufParm = this->memMgr.allocate ( needed ); - } catch (std::bad_alloc& e) { - // caller must check that buffer size has expended - return; - } - - memcpy ( bufParm.pBuf, this->pBuf, this->stack ); - this->memMgr.release ( this->pBuf, this->bufSize ); - this->pBuf = bufParm.pBuf; - this->bufSize = bufParm.bufSize; - } -} - - diff --git a/src/ca/legacy/pcas/generic/outBuf.h b/src/ca/legacy/pcas/generic/outBuf.h deleted file mode 100644 index 87a428bbe..000000000 --- a/src/ca/legacy/pcas/generic/outBuf.h +++ /dev/null @@ -1,171 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 outBufh -#define outBufh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_outBufh -# undef epicsExportSharedSymbols -#endif - -#include "caProto.h" - -#ifdef epicsExportSharedSymbols_outBufh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casdef.h" -#include "clientBufMemoryManager.h" - -// -// outBufCtx -// -class outBufCtx { - friend class outBuf; -public: - enum pushCtxResult { pushCtxNoSpace, pushCtxSuccess }; - outBufCtx ( const class outBuf & ); // success - outBufCtx (); // failure - - pushCtxResult pushResult () const; - -private: - pushCtxResult stat; - char * pBuf; - bufSizeT bufSize; - bufSizeT stack; -}; - -class outBufClient { -public: - enum flushCondition { - flushNone = 0, - flushProgress = 1, - flushDisconnect = 2 - }; - static const char * ppFlushCondText[3]; - virtual unsigned getDebugLevel () const = 0; - virtual void sendBlockSignal () = 0; - virtual flushCondition xSend ( char *pBuf, bufSizeT nBytesToSend, - bufSizeT & nBytesSent ) = 0; - virtual void hostName ( char *pBuf, unsigned bufSize ) const = 0; - virtual bufSizeT osSendBufferSize () const = 0; -protected: - virtual ~outBufClient() {} -}; - -// -// outBuf -// -class outBuf { - friend class outBufCtx; -public: - outBuf ( outBufClient &, clientBufMemoryManager & ); - virtual ~outBuf (); - - bufSizeT bytesPresent () const; - - // - // flush output queue - // (returns the number of bytes sent) - // - outBufClient::flushCondition flush (); - - void show (unsigned level) const; - - unsigned bufferSize () const; - - // - // allocate message buffer space - // (leaves message buffer locked) - // - caStatus copyInHeader ( 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 ); - - // - // commit message created with copyInHeader - // - void commitMsg (); - void commitMsg ( ca_uint32_t reducedPayloadSize ); - - caStatus allocRawMsg ( bufSizeT msgsize, void **ppMsg ); - void commitRawMsg ( bufSizeT size ); - - // - // This is used to create recursive protocol stacks. A subsegment - // of the buffer of max size "maxSize" is assigned to the next - // layer down in the protocol stack by pushCtx () until popCtx () - // is called. The routine popCtx () returns the actual number - // of bytes used by the next layer down. - // - // pushCtx() returns an outBufCtx to be restored by popCtx() - // - const outBufCtx pushCtx ( bufSizeT headerSize, - bufSizeT maxBodySize, void *&pHeader ); - bufSizeT popCtx ( const outBufCtx & ); // returns actual size - -private: - outBufClient & client; - clientBufMemoryManager & memMgr; - char * pBuf; - bufSizeT bufSize; - bufSizeT stack; - unsigned ctxRecursCount; - - void expandBuffer (bufSizeT needed); - - outBuf ( const outBuf & ); - outBuf & operator = ( const outBuf & ); -}; - -// -// outBuf::bytesPresent () -// number of bytes in the output queue -// -inline bufSizeT outBuf::bytesPresent () const -{ - return this->stack; -} - -// -// outBuf::commitRawMsg() -// -inline void outBuf::commitRawMsg (bufSizeT size) -{ - this->stack += size; - assert ( this->stack <= this->bufSize ); -} - -// -// outBufCtx::outBufCtx () -// -inline outBufCtx::outBufCtx () : - stat (pushCtxNoSpace) {} - -// -// outBufCtx::outBufCtx () -// -inline outBufCtx::outBufCtx (const outBuf &outBufIn) : - stat (pushCtxSuccess), pBuf (outBufIn.pBuf), - bufSize (outBufIn.bufSize), stack (outBufIn.stack) {} - -// -// outBufCtx::pushResult -// -inline outBufCtx::pushCtxResult outBufCtx::pushResult () const -{ - return this->stat; -} - -#endif // outBufh - diff --git a/src/ca/legacy/pcas/generic/pvAttachReturn.cc b/src/ca/legacy/pcas/generic/pvAttachReturn.cc deleted file mode 100644 index 0b70fef8c..000000000 --- a/src/ca/legacy/pcas/generic/pvAttachReturn.cc +++ /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. -\*************************************************************************/ - -// -// Author: Jeffrey O. Hill -// johill@lanl.gov -// - -#define epicsExportSharedSymbols -#include "casdef.h" - -pvAttachReturn::pvAttachReturn () -{ - this->pPV = 0; - // - // A pv name is required for success - // - this->stat = S_cas_badParameter; -} - -pvAttachReturn::pvAttachReturn ( caStatus statIn ) -{ - this->pPV = NULL; - if ( statIn == S_casApp_success ) { - // - // A pv name is required for success - // - this->stat = S_cas_badParameter; - } - else { - this->stat = statIn; - } -} - -pvAttachReturn::pvAttachReturn ( casPV & pv ) -{ - this->pPV = & pv; - this->stat = S_casApp_success; -} - -const pvAttachReturn & pvAttachReturn::operator = ( caStatus rhs ) -{ - this->pPV = NULL; - if ( rhs == S_casApp_success ) { - this->stat = S_cas_badParameter; - } - else { - this->stat = rhs; - } - return *this; -} - -// -// const pvAttachReturn &operator = (casPV &pvIn) -// -// The above assignment operator is not included -// because it does not match the strict definition of an -// assignment operator unless "const casPV &" -// is passed in, and we cant use a const PV -// pointer here because the server library _will_ make -// controlled modification of the PV in the future. -// -const pvAttachReturn & pvAttachReturn::operator = ( casPV *pPVIn ) -{ - if ( pPVIn != NULL ) { - this->stat = S_casApp_success; - } - else { - this->stat = S_casApp_pvNotFound; - } - this->pPV = pPVIn; - return *this; -} - -caStatus pvAttachReturn::getStatus () const -{ - return this->stat; -} - -casPV * pvAttachReturn::getPV () const -{ - return this->pPV; -} - diff --git a/src/ca/legacy/pcas/generic/pvExistReturn.cc b/src/ca/legacy/pcas/generic/pvExistReturn.cc deleted file mode 100644 index 46fd7eb65..000000000 --- a/src/ca/legacy/pcas/generic/pvExistReturn.cc +++ /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. -\*************************************************************************/ - -// -// Author: Jeffrey O. Hill -// johill@lanl.gov -// - -#define epicsExportSharedSymbols -#include "casdef.h" - -pvExistReturn::pvExistReturn ( pvExistReturnEnum s ) : - status ( s ) {} - -pvExistReturn::pvExistReturn ( const caNetAddr & addrIn ) : - address ( addrIn ), status ( pverExistsHere ) {} - -pvExistReturn::~pvExistReturn () -{ -} - -const pvExistReturn & pvExistReturn::operator = ( pvExistReturnEnum rhs ) -{ - this->status = rhs; - this->address.clear (); - return * this; -} - -const pvExistReturn & pvExistReturn::operator = ( const caNetAddr & rhs ) -{ - this->status = pverExistsHere; - this->address = rhs; - return * this; -} - -pvExistReturnEnum pvExistReturn::getStatus () const -{ - return this->status; -} - -caNetAddr pvExistReturn::getAddr () const -{ - return this->address; -} - -bool pvExistReturn::addrIsValid () const -{ - return this->address.isValid (); -} diff --git a/src/ca/legacy/pcas/generic/st/README b/src/ca/legacy/pcas/generic/st/README deleted file mode 100644 index f5851b1f6..000000000 --- a/src/ca/legacy/pcas/generic/st/README +++ /dev/null @@ -1,5 +0,0 @@ - -This directory contains files specific to the single-threaded -version of the CA server - -- diff --git a/src/ca/legacy/pcas/generic/st/caServerOS.cc b/src/ca/legacy/pcas/generic/st/caServerOS.cc deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/ca/legacy/pcas/generic/st/casDGEvWakeup.h b/src/ca/legacy/pcas/generic/st/casDGEvWakeup.h deleted file mode 100644 index 9676bad1c..000000000 --- a/src/ca/legacy/pcas/generic/st/casDGEvWakeup.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. -\*************************************************************************/ - -#ifndef casDGEvWakeuph -#define casDGEvWakeuph - -class casDGEvWakeup : public epicsTimerNotify { -public: - casDGEvWakeup (); - virtual ~casDGEvWakeup(); - void show ( unsigned level ) const; - void start ( class casDGIntfOS &osIn ); -private: - epicsTimer &timer; - class casDGIntfOS *pOS; - expireStatus expire( const epicsTime & currentTime ); - casDGEvWakeup ( const casDGEvWakeup & ); - casDGEvWakeup & operator = ( const casDGEvWakeup & ); -}; - -#endif // casDGEvWakeuph diff --git a/src/ca/legacy/pcas/generic/st/casDGIOWakeup.h b/src/ca/legacy/pcas/generic/st/casDGIOWakeup.h deleted file mode 100644 index 0f71ce607..000000000 --- a/src/ca/legacy/pcas/generic/st/casDGIOWakeup.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. -\*************************************************************************/ - -#ifndef casDGIOWakeuph -#define casDGIOWakeuph - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casDGIOWakeuph -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "epicsTimer.h" - -#ifdef epicsExportSharedSymbols_casDGIOWakeuph -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class casDGIOWakeup : public epicsTimerNotify { -public: - casDGIOWakeup (); - virtual ~casDGIOWakeup (); - void show ( unsigned level ) const; - void start ( class casDGIntfOS &osIn ); -private: - epicsTimer &timer; - class casDGIntfOS *pOS; - expireStatus expire( const epicsTime & currentTime ); - casDGIOWakeup ( const casDGIOWakeup & ); - casDGIOWakeup & operator = ( const casDGIOWakeup & ); -}; - -#endif // casDGIOWakeuph diff --git a/src/ca/legacy/pcas/generic/st/casDGIntfOS.cc b/src/ca/legacy/pcas/generic/st/casDGIntfOS.cc deleted file mode 100644 index 0ce4258d1..000000000 --- a/src/ca/legacy/pcas/generic/st/casDGIntfOS.cc +++ /dev/null @@ -1,484 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// casDGIntfOS.cc -// - -#include "fdManager.h" -#include "errlog.h" - -#define epicsExportSharedFunc -#include "casDGIntfOS.h" - -// -// casDGReadReg -// -class casDGReadReg : public fdReg { -public: - casDGReadReg ( casDGIntfOS & osIn ) : - fdReg (osIn.getFD(), fdrRead), os (osIn) {} - ~casDGReadReg (); - void show (unsigned level) const; -private: - casDGIntfOS &os; - void callBack (); - casDGReadReg ( const casDGReadReg & ); - casDGReadReg & operator = ( const casDGReadReg & ); -}; - -// -// casDGBCastReadReg -// -class casDGBCastReadReg : public fdReg { -public: - casDGBCastReadReg (casDGIntfOS &osIn) : - fdReg (osIn.getBCastFD(), fdrRead), os (osIn) {} - ~casDGBCastReadReg (); - - void show (unsigned level) const; -private: - casDGIntfOS &os; - void callBack (); - casDGBCastReadReg ( const casDGBCastReadReg & ); - casDGBCastReadReg & operator = ( const casDGBCastReadReg & ); -}; - -// -// casDGWriteReg -// -class casDGWriteReg : public fdReg { -public: - casDGWriteReg (casDGIntfOS &osIn) : - fdReg (osIn.getFD(), fdrWrite), os (osIn) {} - ~casDGWriteReg (); - - void show (unsigned level) const; -private: - casDGIntfOS &os; - void callBack (); - casDGWriteReg ( const casDGWriteReg & ); - casDGWriteReg & operator = ( const casDGWriteReg & ); -}; - -// -// casDGIntfOS::casDGIntfOS() -// -casDGIntfOS::casDGIntfOS ( - caServerI & serverIn, clientBufMemoryManager & memMgrIn, - const caNetAddr & addr, bool autoBeaconAddr, - bool addConfigBeaconAddr ) : - casDGIntfIO ( serverIn, memMgrIn, addr, - autoBeaconAddr, addConfigBeaconAddr ), - pRdReg ( 0 ), - pBCastRdReg ( 0 ), - pWtReg ( 0 ) -{ - this->xSetNonBlocking(); - this->armRecv(); -} - -// -// casDGIntfOS::~casDGIntfOS() -// -casDGIntfOS::~casDGIntfOS() -{ - this->disarmSend(); - this->disarmRecv(); -} - -// -// casDGEvWakeup::casDGEvWakeup() -// -casDGEvWakeup::casDGEvWakeup () : - timer ( fileDescriptorManager.createTimer() ), pOS ( 0 ) -{ -} - -// -// casDGEvWakeup::~casDGEvWakeup() -// -casDGEvWakeup::~casDGEvWakeup() -{ - this->timer.destroy (); -} - -void casDGEvWakeup::start ( casDGIntfOS &os ) -{ - if ( this->pOS ) { - assert ( this->pOS == &os ); - } - else { - this->pOS = &os; - this->timer.start ( *this, 0.0 ); - } -} - -// -// casDGEvWakeup::show() -// -void casDGEvWakeup::show ( unsigned level ) const -{ - printf ( "casDGEvWakeup at %p {\n", - static_cast ( this ) ); - this->timer.show ( level ); - printf ("}\n"); -} - -// -// casDGEvWakeup::expire() -// -epicsTimerNotify::expireStatus casDGEvWakeup::expire ( const epicsTime & /* currentTime */ ) -{ - this->pOS->eventSysProcess (); - // We do not wait for any impartial, or complete, - // messages in the input queue to be processed - // because. - // A) IO postponement might be preventing the - // input queue processing from proceeding. - // B) Since both reads and events get processed - // before going back to select to find out if we - // can do a write then we naturally tend to - // combine get responses and subscription responses - // into one write. - this->pOS->armSend (); - this->pOS = 0; - return noRestart; -} - -// -// casDGIOWakeup::casDGIOWakeup() -// -casDGIOWakeup::casDGIOWakeup () : - timer ( fileDescriptorManager.createTimer() ), pOS ( 0 ) -{ -} - -// -// casDGIOWakeup::~casDGIOWakeup() -// -casDGIOWakeup::~casDGIOWakeup() -{ - this->timer.destroy (); -} - -// -// casDGIOWakeup::expire() -// -// Running this indirectly off of the timer queue -// guarantees that we will not call processDG() -// recursively -// -epicsTimerNotify :: expireStatus - casDGIOWakeup :: expire( const epicsTime & /* currentTime */ ) -{ - caStatus status = this->pOS->processDG (); - if ( status != S_cas_success && - status != S_cas_sendBlocked ) { - char pName[64u]; - this->pOS->hostName (pName, sizeof (pName)); - errPrintf (status, __FILE__, __LINE__, - "unexpected problem with UDP input from \"%s\"", pName); - } - this->pOS->armRecv (); - this->pOS->armSend (); - this->pOS = 0; - return noRestart; -} - -// -// casDGIOWakeup::show() -// -void casDGIOWakeup::start ( casDGIntfOS &os ) -{ - if ( this->pOS ) { - assert ( this->pOS == &os ); - } - else { - this->pOS = &os; - this->timer.start ( *this, 0.0 ); - } -} - -// -// casDGIOWakeup::show() -// -void casDGIOWakeup::show(unsigned level) const -{ - printf ( "casDGIOWakeup at %p {\n", - static_cast ( this ) ); - this->timer.show ( level ); - printf ( "}\n" ); -} - -// -// casDGIntfOS::armRecv () -// -void casDGIntfOS::armRecv() -{ - if ( ! this->inBufFull () ) { - if ( ! this->pRdReg ) { - this->pRdReg = new casDGReadReg ( *this ); - } - if ( this->validBCastFD() && this->pBCastRdReg == NULL ) { - this->pBCastRdReg = new casDGBCastReadReg ( *this ); - } - } -} - -// -// casDGIntfOS::disarmRecv() -// -void casDGIntfOS::disarmRecv() -{ - delete this->pRdReg; - this->pRdReg = 0; - delete this->pBCastRdReg; - this->pBCastRdReg = 0; -} - -// -// casDGIntfOS::armSend() -// -void casDGIntfOS::armSend() -{ - if ( this->outBufBytesPending () == 0u ) { - return; - } - - if ( ! this->pWtReg ) { - this->pWtReg = new casDGWriteReg ( *this ); - } -} - -// -// casDGIntfOS::disarmSend() -// -void casDGIntfOS::disarmSend () -{ - delete this->pWtReg; - this->pWtReg = 0; -} - -// -// casDGIntfOS::ioBlockedSignal() -// -void casDGIntfOS::ioBlockedSignal() -{ - this->ioWk.start ( *this ); -} - -// -// casDGIntfOS::eventSignal() -// -void casDGIntfOS::eventSignal() -{ - this->evWk.start ( *this ); -} - -// -// casDGIntfOS::show() -// -void casDGIntfOS::show(unsigned level) const -{ - printf ( "casDGIntfOS at %p\n", - static_cast ( this ) ); - if ( this->pRdReg ) { - this->pRdReg->show ( level ); - } - if ( this->pWtReg ) { - this->pWtReg->show ( level ); - } - if ( this->pBCastRdReg ) { - this->pBCastRdReg->show ( level ); - } - this->evWk.show (level); - this->ioWk.show (level); - this->casDGIntfIO::show (level); -} - -// -// casDGReadReg::callBack() -// -void casDGReadReg::callBack() -{ - this->os.recvCB ( inBufClient::fpNone ); -} - -// -// casDGReadReg::~casDGReadReg() -// -casDGReadReg::~casDGReadReg() -{ -} - -// -// casDGReadReg::show() -// -void casDGReadReg::show(unsigned level) const -{ - this->fdReg::show(level); - printf("casDGReadReg at %p\n", - static_cast ( this) ); -} - -// -// casDGBCastReadReg::callBack() -// -void casDGBCastReadReg::callBack() -{ - this->os.recvCB ( inBufClient::fpUseBroadcastInterface ); -} - -// -// casDGBCastReadReg::~casDGBCastReadReg() -// -casDGBCastReadReg::~casDGBCastReadReg() -{ -} - -// -// casDGReadReg::show() -// -void casDGBCastReadReg::show(unsigned level) const -{ - this->fdReg::show(level); - printf ( "casDGBCastReadReg at %p\n", - static_cast ( this ) ); -} - -// -// casDGWriteReg::~casDGWriteReg() -// -casDGWriteReg::~casDGWriteReg() -{ -} - -// -// casDGWriteReg::callBack() -// -void casDGWriteReg::callBack() -{ - casDGIntfOS * pDGIOS = & this->os; - pDGIOS->sendCB(); - // - // NO CODE HERE - sendCB deletes this object - // -} - -// -// casDGWriteReg::show() -// -void casDGWriteReg::show(unsigned level) const -{ - this->fdReg::show (level); - printf ( "casDGWriteReg: at %p\n", - static_cast ( this ) ); -} - -// -// casDGIntfOS::sendBlockSignal() -// -void casDGIntfOS::sendBlockSignal() -{ - this->armSend(); -} - -// -// casDGIntfOS::sendCB() -// -void casDGIntfOS::sendCB() -{ - // allows rearm to occur if required - this->disarmSend (); - - // - // attempt to flush the output buffer - // - outBufClient::flushCondition flushCond = this->flush (); - if ( flushCond == flushProgress ) { - // - // If we are unable to flush out all of the events - // in casDgEvWakeup::expire() because the - // client is slow then we must check again here when - // we _are_ able to write to see if additional events - // can be sent to the slow client. - // - this->eventSysProcess (); - - // - // If we were able to send something then we need - // to process the input queue in case we were send - // blocked. - // - caStatus status = this->processDG (); - if ( status != S_cas_success && - status != S_cas_sendBlocked ) { - char pName[64u]; - this->hostName (pName, sizeof (pName)); - errPrintf ( status, __FILE__, __LINE__, - "unexpected problem with UDP input from \"%s\"", pName); - } - } - -# if defined(DEBUG) - printf ("write attempted on %d result was %d\n", this->getFD(), flushCond ); - printf ("Recv backlog %u\n", this->inBuf::bytesPresent()); - printf ("Send backlog %u\n", this->outBuf::bytesPresent()); -# endif - - // - // this reenables receipt of incoming frames once - // the output has been flushed in case the receive - // side is blocked due to lack of buffer space - // - this->armRecv (); - - - // once we start sending we continue until done - this->armSend (); -} - -// -// casDGIntfOS::recvCB() -// -void casDGIntfOS :: recvCB ( inBufClient::fillParameter parm ) -{ - assert ( this->pRdReg ); - - // - // copy in new messages - // - this->inBufFill ( parm ); - caStatus status = this->processDG (); - if ( status != S_cas_success && - status != S_cas_sendBlocked ) { - char pName[64u]; - this->hostName (pName, sizeof (pName)); - errPrintf (status, __FILE__, __LINE__, - "unexpected problem with UDP input from \"%s\"", pName); - } - - this->armSend (); - - // - // If there isnt any space then temporarily - // stop calling this routine until problem is resolved - // either by: - // (1) sending or - // (2) a blocked IO op unblocks - // - // (casDGReadReg is _not_ a onceOnly fdReg - - // therefore an explicit delete is required here) - // - if ( this->inBufFull() ) { - this->disarmRecv(); // this deletes the casDGReadReg object - } -} - diff --git a/src/ca/legacy/pcas/generic/st/casDGIntfOS.h b/src/ca/legacy/pcas/generic/st/casDGIntfOS.h deleted file mode 100644 index 38d4b46ac..000000000 --- a/src/ca/legacy/pcas/generic/st/casDGIntfOS.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. -\*************************************************************************/ - -#ifndef casDGIntfOSh -#define casDGIntfOSh - -#include "casDGIntfIO.h" -#include "casDGIOWakeup.h" -#include "casDGEvWakeup.h" - -class casDGIntfOS : public casDGIntfIO { - friend class casDGReadReg; - friend class casDGBCastReadReg; - friend class casDGWriteReg; - friend class casDGEvWakeup; - friend class casDGIOWakeup; - friend class casStreamEvWakeup; -public: - casDGIntfOS ( caServerI &, clientBufMemoryManager &, - const caNetAddr & addr, bool autoBeaconAddr = true, - bool addConfigBeaconAddr = false); - virtual ~casDGIntfOS (); - virtual void show (unsigned level) const; -private: - casDGIOWakeup ioWk; - casDGEvWakeup evWk; - class casDGReadReg * pRdReg; - class casDGBCastReadReg * pBCastRdReg; // fix for solaris bug - class casDGWriteReg * pWtReg; - - void armRecv (); - void armSend (); - - void disarmRecv (); - void disarmSend (); - - void recvCB ( inBufClient::fillParameter parm ); - void sendCB (); - - void sendBlockSignal (); - - void ioBlockedSignal (); - - void eventSignal (); - - casDGIntfOS ( const casDGIntfOS & ); - casDGIntfOS & operator = ( const casDGIntfOS & ); -}; - -#endif // casDGIntfOSh diff --git a/src/ca/legacy/pcas/generic/st/casIntfOS.cc b/src/ca/legacy/pcas/generic/st/casIntfOS.cc deleted file mode 100644 index 87d24a0a4..000000000 --- a/src/ca/legacy/pcas/generic/st/casIntfOS.cc +++ /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. -\*************************************************************************/ - -/* - * casIntfOS.cc - */ - -#include "fdManager.h" - -#define epicsExportSharedSymbols -#include "casIntfOS.h" - -class casServerReg : public fdReg { -public: - casServerReg (casIntfOS &osIn) : - fdReg (osIn.casIntfIO::getFD(), fdrRead), os (osIn) {} - ~casServerReg (); -private: - casIntfOS &os; - void callBack (); - casServerReg ( const casServerReg & ); - casServerReg & operator = ( const casServerReg & ); -}; - -casIntfOS::casIntfOS ( caServerI & casIn, clientBufMemoryManager & memMgrIn, - const caNetAddr & addrIn, bool autoBeaconAddr, bool addConfigBeaconAddr ) : - casIntfIO ( addrIn ), - casDGIntfOS ( casIn, memMgrIn, addrIn, autoBeaconAddr, - addConfigBeaconAddr ), - cas ( casIn ) -{ - this->setNonBlocking(); - - this->pRdReg = new casServerReg ( *this ); -} - -casIntfOS::~casIntfOS() -{ - delete this->pRdReg; -} - -void casServerReg::callBack() -{ - assert ( this->os.pRdReg ); - this->os.cas.connectCB ( this->os ); -} - -casServerReg::~casServerReg() -{ -} - -void casIntfOS::show ( unsigned level ) const -{ - printf ( "casIntfOS at %p\n", - static_cast < const void * > ( this ) ); - this->casDGIntfOS::show ( level ); -} - -caNetAddr casIntfOS::serverAddress () const -{ - return this->casIntfIO::serverAddress(); -} - - - diff --git a/src/ca/legacy/pcas/generic/st/casIntfOS.h b/src/ca/legacy/pcas/generic/st/casIntfOS.h deleted file mode 100644 index 40d077bb0..000000000 --- a/src/ca/legacy/pcas/generic/st/casIntfOS.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. -\*************************************************************************/ -// -// casOSD.h - Channel Access Server OS dependent wrapper -// - -#ifndef casIntfOSh -#define casIntfOSh - -#include "casIntfIO.h" -#include "casDGIntfOS.h" - -// -// casIntfOS -// -class casIntfOS : public casIntfIO, public tsDLNode < casIntfOS >, - public casDGIntfOS -{ - friend class casServerReg; -public: - casIntfOS ( caServerI &, clientBufMemoryManager &, const caNetAddr &, - bool autoBeaconAddr = true, bool addConfigBeaconAddr = false ); - virtual ~casIntfOS(); - void show ( unsigned level ) const; - caNetAddr serverAddress () const; -private: - caServerI & cas; - class casServerReg * pRdReg; - - casIntfOS ( const casIntfOS & ); - casIntfOS & operator = ( const casIntfOS & ); -}; - -#endif // casIntfOSh diff --git a/src/ca/legacy/pcas/generic/st/casOSD.h b/src/ca/legacy/pcas/generic/st/casOSD.h deleted file mode 100644 index 0fb8baf46..000000000 --- a/src/ca/legacy/pcas/generic/st/casOSD.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 Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// casOSD.h - Channel Access Server OS dependent wrapper -// - -#ifndef includeCASOSDH -#define includeCASOSDH - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_includeCASOSDH -# undef epicsExportSharedSymbols -#endif -#include "fdManager.h" -#ifdef epicsExportSharedSymbols_includeCASOSDH -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class caServerI; - -class casServerReg; - -class casDGReadReg; -class casDGBCastReadReg; -class casDGWriteReg; - - - - - - -class casStreamWriteReg; -class casStreamReadReg; - - - - -// no additions below this line -#endif // includeCASOSDH - diff --git a/src/ca/legacy/pcas/generic/st/casStreamOS.cc b/src/ca/legacy/pcas/generic/st/casStreamOS.cc deleted file mode 100644 index 1b6c4e2c2..000000000 --- a/src/ca/legacy/pcas/generic/st/casStreamOS.cc +++ /dev/null @@ -1,632 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// casStreamOS.cc -// -// TO DO: -// o armRecv() and armSend() should return bad status when -// there isnt enough memory -// - -#include "fdManager.h" -#include "errlog.h" - -#define epicsExportSharedFunc -#include "casStreamOS.h" - -#if 0 -#define DEBUG -#endif - -// -// printStatus () -// -#if defined(DEBUG) -void casStreamOS :: printStatus ( const char * pCtx ) const -{ - static epicsTime beginTime = epicsTime :: getCurrent (); - epicsTime current = epicsTime :: getCurrent (); - printf ( - "%03.3f, " - "Sock %d, %s, " - "RecvBuf %u, " - "SendBuf %u\n", - current - beginTime, - this->getFD(), - pCtx, - this->inBufBytesPending (), - this->outBufBytesPending () ); - fflush ( stdout ); -} -#else -inline void casStreamOS :: printStatus ( const char * ) const {} -#endif - -// -// casStreamReadReg -// -class casStreamReadReg : public fdReg { -public: - inline casStreamReadReg (casStreamOS &osIn); - inline ~casStreamReadReg (); - void show (unsigned level) const; -private: - casStreamOS &os; - void callBack (); - casStreamReadReg ( const casStreamReadReg & ); - casStreamReadReg & operator = ( const casStreamReadReg & ); -}; - -// -// casStreamReadReg::casStreamReadReg() -// -inline casStreamReadReg::casStreamReadReg (casStreamOS &osIn) : - fdReg (osIn.getFD(), fdrRead), os (osIn) -{ - this->os.printStatus ( "read schedualed" ); -} - -// -// casStreamReadReg::~casStreamReadReg -// -inline casStreamReadReg::~casStreamReadReg () -{ - this->os.printStatus ( "read unschedualed" ); -} - -// -// casStreamWriteReg -// -class casStreamWriteReg : public fdReg { -public: - inline casStreamWriteReg (casStreamOS &osIn); - inline ~casStreamWriteReg (); - - void show (unsigned level) const; -private: - casStreamOS &os; - void callBack (); - casStreamWriteReg ( const casStreamWriteReg & ); - casStreamWriteReg & operator = ( const casStreamWriteReg & ); -}; - -// -// casStreamWriteReg::casStreamWriteReg() -// -inline casStreamWriteReg::casStreamWriteReg (casStreamOS &osIn) : - fdReg (osIn.getFD(), fdrWrite, true), os (osIn) -{ - this->os.printStatus ( "write schedualed" ); -} - -// -// casStreamWriteReg::~casStreamWriteReg () -// -inline casStreamWriteReg::~casStreamWriteReg () -{ - this->os.printStatus ( "write unschedualed" ); -} - -// -// casStreamEvWakeup() -// -casStreamEvWakeup::casStreamEvWakeup ( casStreamOS & osIn ) : - timer ( fileDescriptorManager.createTimer() ), os ( osIn ) -{ -} - -// -// casStreamEvWakeup::~casStreamEvWakeup() -// -casStreamEvWakeup::~casStreamEvWakeup() -{ - this->timer.destroy (); -} - -// -// casStreamEvWakeup::show() -// -void casStreamEvWakeup::show(unsigned level) const -{ - printf ( "casStreamEvWakeup at %p {\n", - static_cast ( this ) ); - this->timer.show ( level ); - printf ( "}\n" ); -} - -// -// casStreamEvWakeup::expire() -// -epicsTimerNotify::expireStatus casStreamEvWakeup:: - expire ( const epicsTime & /* currentTime */ ) -{ - this->os.printStatus ( "casStreamEvWakeup tmr expire" ); - casProcCond pc = os.eventSysProcess (); - if ( pc == casProcOk ) { - // We do not wait for any impartial, or complete, - // messages in the input queue to be processed - // because. - // A) IO postponement might be preventing the - // input queue processing from proceeding. - // B) We dont want to interrupt subscription - // updates while waiting for very large arrays - // to be read in a packet at a time. - // C) Since both reads and events get processed - // before going back to select to find out if we - // can do a write then we naturally tend to - // combine get responses and subscription responses - // into one write. - // D) Its probably questionable to hold up event - // traffic (introduce latency) because a partial - // message is pending in the input queue. - this->os.armSend (); - } - else { - // - // ok to delete the client here - // because casStreamEvWakeup::expire() - // is called by the timer queue system - // and therefore we are not being - // called from a client member function - // higher up on the stack - // - delete & this->os; - - // - // must not touch the "this" pointer - // from this point on however - // - } - return noRestart; -} - -// -// casStreamEvWakeup::start() -// -// care is needed here because this is called -// asynchronously by postEvent -// -// there is some overhead here but care is taken -// in the caller of this routine to call this -// only when its the 2nd event on the queue -// -void casStreamEvWakeup::start( casStreamOS & ) -{ - this->os.printStatus ( "casStreamEvWakeup tmr start" ); - this->timer.start ( *this, 0.0 ); -} - -// -// casStreamIOWakeup::casStreamIOWakeup() -// -casStreamIOWakeup::casStreamIOWakeup () : - timer ( fileDescriptorManager.createTimer() ), pOS ( 0 ) -{ -} - -// -// casStreamIOWakeup::~casStreamIOWakeup() -// -casStreamIOWakeup::~casStreamIOWakeup() -{ - this->timer.destroy (); -} - -// -// casStreamIOWakeup::show() -// -void casStreamIOWakeup::show ( unsigned level ) const -{ - printf ( "casStreamIOWakeup at %p {\n", - static_cast ( this ) ); - this->timer.show ( level ); - printf ( "}\n" ); -} - -// -// casStreamOS::armRecv () -// -inline void casStreamOS::armRecv() -{ - if ( ! this->pRdReg ) { - if ( ! this->inBufFull() ) { - this->pRdReg = new casStreamReadReg ( *this ); - } - } -} - -// -// casStreamIOWakeup::expire() -// -// This is called whenever asynchronous IO completes -// -// Running this indirectly off of the timer queue -// guarantees that we will not call processMsg() -// recursively -// -epicsTimerNotify::expireStatus casStreamIOWakeup :: - expire ( const epicsTime & /* currentTime */ ) -{ - assert ( this->pOS ); - this->pOS->printStatus ( "casStreamIOWakeup tmr expire" ); - casStreamOS & tmpOS = *this->pOS; - this->pOS = 0; - caStatus status = tmpOS.processMsg (); - if ( status == S_cas_success ) { - tmpOS.armRecv (); - if ( tmpOS._sendNeeded () ) { - tmpOS.armSend (); - } - } - else if ( status == S_cas_sendBlocked ) { - tmpOS.armSend (); - // always activate receives if space is available - // in the in buf - tmpOS.armRecv (); - } - else if ( status == S_casApp_postponeAsyncIO ) { - // we should be back on the IO blocked list - // if S_casApp_postponeAsyncIO was returned - // so this function will be called again when - // another asynchronous request completes - tmpOS.armSend (); - // always activate receives if space is available - // in the in buf - tmpOS.armRecv (); - } - else { - errMessage ( status, - "- unexpected problem with client's input - forcing disconnect"); - tmpOS.getCAS().destroyClient ( tmpOS ); - // - // must _not_ touch "tmpOS" ref - // after the destroy - // - return noRestart; - } - return noRestart; -} - -// -// casStreamIOWakeup::start() -// -void casStreamIOWakeup::start ( casStreamOS &os ) -{ - if ( this->pOS ) { - assert ( this->pOS == &os ); - } - else { - this->pOS = &os; - this->timer.start ( *this, 0.0 ); - } - this->pOS->printStatus ( "casStreamIOWakeup tmr start" ); -} - -// -// casStreamOS::disarmRecv () -// -inline void casStreamOS::disarmRecv () -{ - delete this->pRdReg; - this->pRdReg = 0; -} - -// -// casStreamOS::armSend() -// -void casStreamOS::armSend() -{ - if ( this->outBufBytesPending() == 0u ) { - return; - } - - if ( ! this->pWtReg ) { - this->pWtReg = new casStreamWriteReg(*this); - } -} - -// -// casStreamOS::disarmSend() -// -inline void casStreamOS::disarmSend () -{ - delete this->pWtReg; - this->pWtReg = 0; -} - -// -// casStreamOS::ioBlockedSignal() -// (called by main thread when lock is applied) -// -void casStreamOS::ioBlockedSignal() -{ - this->ioWk.start ( *this ); -} - -// -// casStreamOS::eventSignal() -// (called by any thread asynchronously -// when an event is posted) -// -void casStreamOS::eventSignal() -{ - this->evWk.start ( *this ); -} - -// -// casStreamOS::casStreamOS() -// -casStreamOS::casStreamOS ( - caServerI & cas, clientBufMemoryManager & bufMgrIn, - const ioArgsToNewStreamIO & ioArgs ) : - casStreamIO ( cas, bufMgrIn, ioArgs ), - evWk ( *this ), - pWtReg ( 0 ), - pRdReg ( 0 ), - _sendBacklogThresh ( osSendBufferSize () / 2u ) -{ - if ( _sendBacklogThresh < MAX_TCP / 2 ) { - _sendBacklogThresh = MAX_TCP / 2; - } - this->xSetNonBlocking (); - this->armRecv (); -} - -// -// casStreamOS::~casStreamOS() -// -casStreamOS::~casStreamOS() -{ - // - // attempt to flush out any remaining messages - // - this->flush (); - - this->disarmSend (); - this->disarmRecv (); -} - -// -// casStreamOS::show() -// -void casStreamOS::show ( unsigned level ) const -{ - this->casStrmClient::show ( level ); - printf ( "casStreamOS at %p\n", - static_cast ( this ) ); - if ( this->pWtReg ) { - this->pWtReg->show ( level ); - } - if ( this->pRdReg ) { - this->pRdReg->show ( level ); - } - this->evWk.show ( level ); - this->ioWk.show ( level ); -} - -// -// casStreamReadReg::show() -// -void casStreamReadReg::show ( unsigned level ) const -{ - this->fdReg::show ( level ); - printf ( "casStreamReadReg at %p\n", - static_cast ( this ) ); -} - -// -// casStreamReadReg::callBack () -// -void casStreamReadReg::callBack () -{ - this->os.recvCB (); - // - // NO CODE HERE - // (casStreamOS::recvCB() may up indirectly deleting this object) - // -} - -// -// casStreamOS::recvCB() -// -void casStreamOS :: recvCB () -{ - assert ( this->pRdReg ); - - printStatus ( "receiving" ); - - // - // copy in new messages - // - inBufClient::fillCondition fillCond = this->inBufFill (); - if ( fillCond == casFillDisconnect ) { - this->getCAS().destroyClient ( *this ); - // - // must _not_ touch "this" pointer - // after the destroy - // - return; - } - else if ( fillCond == casFillNone ) { - if ( this->inBufFull() ) { - this->disarmRecv (); - } - } - else { - printStatus ( "recv CB req proc" ); - caStatus status = this->processMsg (); - if ( status == S_cas_success ) { - this->armRecv (); - if ( _sendNeeded () ) { - this->armSend (); - } - } - else if ( status == S_cas_sendBlocked ) { - this->armSend (); - } - else if ( status == S_casApp_postponeAsyncIO ) { - this->armSend (); - } - else { - errMessage ( status, - "- unexpected problem with client's input - forcing disconnect"); - this->getCAS().destroyClient ( *this ); - // - // must _not_ touch "this" pointer - // after the destroy - // - return; - } - } -} - -// -// casStreamOS :: sendBlockSignal() -// -void casStreamOS :: sendBlockSignal () -{ - this->armSend (); -} - -// -// casStreamWriteReg::show() -// -void casStreamWriteReg::show ( unsigned level ) const -{ - this->fdReg::show ( level ); - printf ( "casStreamWriteReg at %p\n", - static_cast ( this ) ); -} - -// -// casStreamWriteReg::callBack () -// -void casStreamWriteReg::callBack() -{ - casStreamOS * pSOS = & this->os; - pSOS->sendCB (); - // - // NO CODE HERE - sendCB deletes this object - // -} - -// -// casStreamOS::sendCB () -// -void casStreamOS::sendCB () -{ - // we know that the fdManager will destroy the write - // registration after this function returns, and that - // it is robust in situations where the callback - // deletes its fdReg derived object so delete it now, - // because we can now reschedule a send as needed - // - this->disarmSend (); - - printStatus ( "writing" ); - - // - // attempt to flush the output buffer - // - outBufClient::flushCondition flushCond = this->flush (); - if ( flushCond == outBufClient::flushDisconnect ) { - // - // ok to delete the client here - // because casStreamWriteReg::callBack() - // is called by the fdManager system - // and therefore we are not being - // called from a client member function - // higher up on the stack - // - this->getCAS().destroyClient ( *this ); - // - // must _not_ touch "this" pointer - // after the destroy - // - return; - } - - // - // If we are unable to flush out all of the events - // in casStreamEvWakeup::expire() because the - // client is slow then we must check again here when - // we _are_ able to write to see if additional events - // can be sent to the slow client. - // - casProcCond pc = this->eventSysProcess (); - if ( pc != casProcOk ) { - // - // ok to delete the client here - // because casStreamWriteReg::callBack() - // is called by the fdManager system - // and therefore we are not being - // called from a client member function - // higher up on the stack - // - this->getCAS().destroyClient ( *this ); - // - // must _not_ touch "this" pointer - // after the destroy - // - return; - } - - printStatus ( ppFlushCondText [ flushCond ] ); - - // - // If we were able to send something then we need - // to process the input queue in case we were send - // blocked. - // - - bufSizeT inBufBytesPend = this->inBufBytesPending (); - if ( flushCond == flushProgress && inBufBytesPend ) { - printStatus ( "send CB req proc" ); - caStatus status = this->processMsg (); - if ( status == S_cas_success ) { - this->armRecv (); - } - else if ( status == S_cas_sendBlocked - || status == S_casApp_postponeAsyncIO ) { - bufSizeT inBufBytesPendNew = this->inBufBytesPending (); - if ( inBufBytesPendNew < inBufBytesPend ) { - this->armRecv (); - } - } - else { - errMessage ( status, - "- unexpected problem with client's input - forcing disconnect"); - this->getCAS().destroyClient ( *this ); - // - // must _not_ touch "this" pointer - // after the destroy - // - return; - } - } - - // Once a send starts we will keep going with it until - // it flushes all of the way out. Its important to - // perform this step only after processMsg so that we - // flush out any send blocks detected by processMsg. - this->armSend (); -} - -// -// casStreamOS :: sendNeeded () -// -bool casStreamOS :: - _sendNeeded () const -{ - bool sn = this->outBufBytesPending() >= this->_sendBacklogThresh; - bufSizeT inBytesPending = this->inBufBytesPending (); - return sn || ( inBytesPending == 0u ); -} - - diff --git a/src/ca/legacy/pcas/generic/st/casStreamOS.h b/src/ca/legacy/pcas/generic/st/casStreamOS.h deleted file mode 100644 index 7d0612c18..000000000 --- a/src/ca/legacy/pcas/generic/st/casStreamOS.h +++ /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 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 casStreamOSh -#define casStreamOSh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casStreamOSh -# undef epicsExportSharedSymbols -#endif - -#undef epicsAssertAuthor -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" -#include "epicsAssert.h" -#include "epicsTimer.h" - -#ifdef epicsExportSharedSymbols_casStreamOSh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -#include "casStreamIO.h" - -class casStreamIOWakeup : public epicsTimerNotify { -public: - casStreamIOWakeup (); - virtual ~casStreamIOWakeup (); - void show ( unsigned level ) const; - void start ( class casStreamOS & osIn ); -private: - epicsTimer & timer; - casStreamOS * pOS; - expireStatus expire ( const epicsTime & currentTime ); - casStreamIOWakeup ( const casStreamIOWakeup & ); - casStreamIOWakeup & operator = ( const casStreamIOWakeup & ); -}; - -class casStreamEvWakeup : public epicsTimerNotify { -public: - casStreamEvWakeup ( casStreamOS & ); - virtual ~casStreamEvWakeup (); - void show ( unsigned level ) const; - void start ( class casStreamOS & osIn ); -private: - epicsTimer & timer; - casStreamOS & os; - expireStatus expire ( const epicsTime & currentTime ); - casStreamEvWakeup ( const casStreamEvWakeup & ); - casStreamEvWakeup & operator = ( const casStreamEvWakeup & ); -}; - -class casStreamOS : public casStreamIO { -public: - casStreamOS ( caServerI &, clientBufMemoryManager &, - const ioArgsToNewStreamIO & ); - ~casStreamOS (); - void show ( unsigned level ) const; - void printStatus ( const char * pCtx ) const; -private: - casStreamEvWakeup evWk; - casStreamIOWakeup ioWk; - class casStreamWriteReg * pWtReg; - class casStreamReadReg * pRdReg; - bufSizeT _sendBacklogThresh; - void armSend (); - void armRecv (); - void disarmSend(); - void disarmRecv(); - void recvCB (); - void sendCB (); - void sendBlockSignal (); - void ioBlockedSignal (); - void eventSignal (); - bool _sendNeeded () const; - casStreamOS ( const casStreamOS & ); - casStreamOS & operator = ( const casStreamOS & ); - friend class casStreamWriteReg; - friend class casStreamReadReg; - friend class casStreamIOWakeup; - friend class casStreamEvWakeup; -}; - -#endif // casStreamOSh diff --git a/src/ca/legacy/pcas/generic/st/ioBlocked.cc b/src/ca/legacy/pcas/generic/st/ioBlocked.cc deleted file mode 100644 index 4d5856f6a..000000000 --- a/src/ca/legacy/pcas/generic/st/ioBlocked.cc +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 -// -// IO Blocked list class -// (for single threaded version of the server) -// - -#include - -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" -#include "epicsAssert.h" - -#define epicsExportSharedSymbols -#include "ioBlocked.h" - -// -// ioBlocked::ioBlocked () -// -ioBlocked::ioBlocked () : - pList(NULL) -{ -} - -// -// ioBlocked::~ioBlocked () -// -ioBlocked::~ioBlocked () -{ - if (this->pList) { - this->pList->remove (*this); - this->pList = NULL; - } -} - -// -// ioBlocked::ioBlockedSignal () -// -void ioBlocked::ioBlockedSignal () -{ - // - // this must _not_ be pure virtual because - // there are situations where this is called - // inbetween the derived class's and this base - // class's destructors, and therefore a - // NOOP is required - // -} - -// -// ioBlockedList::ioBlockedList () -// -ioBlockedList::ioBlockedList () -{ -} - -// -// ioBlockedList::~ioBlockedList () -// -ioBlockedList::~ioBlockedList () -{ - for ( ioBlocked * pB = this->get (); pB; pB = this->get () ) { - pB->pList = NULL; - } -} - -// -// ioBlockedList::signal () -// -// works from a temporary list to avoid problems -// where the virtual function adds items to the -// list -// -void ioBlockedList::signal () -{ - tsDLList tmp; - - // - // move all of the items onto tmp - // - tmp.add(*this); - - for ( ioBlocked * pB = tmp.get (); pB; pB = tmp.get () ) { - pB->pList = NULL; - pB->ioBlockedSignal (); - } -} - -// -// ioBlockedList::addItemToIOBLockedList () -// -void ioBlockedList::addItemToIOBLockedList (ioBlocked &item) -{ - if (item.pList==NULL) { - this->add (item); - item.pList = this; - } - else { - assert (item.pList == this); - } -} - - diff --git a/src/ca/legacy/pcas/generic/st/osiMutexCAS.h b/src/ca/legacy/pcas/generic/st/osiMutexCAS.h deleted file mode 100644 index 5bcd2f335..000000000 --- a/src/ca/legacy/pcas/generic/st/osiMutexCAS.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. -\*************************************************************************/ - -// -// single threaded code NOOPs the mutex class -// -#include "osiMutexNOOP.h" - diff --git a/src/ca/legacy/pcas/io/bsdSocket/README b/src/ca/legacy/pcas/io/bsdSocket/README deleted file mode 100644 index 2c2147c18..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/README +++ /dev/null @@ -1,6 +0,0 @@ - - -this directory contains the bsd socket dependent source for -the EPICS ca server - - diff --git a/src/ca/legacy/pcas/io/bsdSocket/caServerIO.cc b/src/ca/legacy/pcas/io/bsdSocket/caServerIO.cc deleted file mode 100644 index 04c729654..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/caServerIO.cc +++ /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. -\*************************************************************************/ -// -// verify connection state prior to doing anything in this file -// - -#include -#include - -#include "epicsSignal.h" -#include "envDefs.h" -#include "caProto.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "caServerIO.h" - -static char * getToken ( const char **ppString, char *pBuf, unsigned bufSIze ); - -int caServerIO::staticInitialized; - -// -// caServerIO::caServerIO() -// -caServerIO::caServerIO () -{ - if ( ! osiSockAttach () ) { - throw S_cas_internal; - } - - caServerIO::staticInit (); -} - -// -// caServerIO::locateInterfaces() -// -void caServerIO::locateInterfaces () -{ - char buf[64u]; - const char *pStr; - char *pToken; - caStatus stat; - unsigned short port; - struct sockaddr_in saddr; - bool autoBeaconAddr; - - // - // first try for the server's private port number env var. - // If this available use the CA server port number (used by - // clients to find the server). If this also isnt available - // then use a hard coded default - CA_SERVER_PORT. - // - if ( envGetConfigParamPtr ( & EPICS_CAS_SERVER_PORT ) ) { - port = envGetInetPortConfigParam ( - &EPICS_CAS_SERVER_PORT, - static_cast ( CA_SERVER_PORT ) ); - } - else { - port = envGetInetPortConfigParam ( - & EPICS_CA_SERVER_PORT, - static_cast ( CA_SERVER_PORT ) ); - } - - memset ((char *)&saddr,0,sizeof(saddr)); - - pStr = envGetConfigParam ( &EPICS_CAS_AUTO_BEACON_ADDR_LIST, sizeof(buf), buf ); - if ( ! pStr ) { - pStr = envGetConfigParam ( &EPICS_CA_AUTO_ADDR_LIST, sizeof(buf), buf ); - } - if (pStr) { - if (strstr(pStr,"no")||strstr(pStr,"NO")) { - autoBeaconAddr = false; - } - else if (strstr(pStr,"yes")||strstr(pStr,"YES")) { - autoBeaconAddr = true; - } - else { - fprintf(stderr, - "CAS: EPICS_CA(S)_AUTO_ADDR_LIST = \"%s\"? Assuming \"YES\"\n", pStr); - autoBeaconAddr = true; - } - } - else { - autoBeaconAddr = true; - } - - typedef std::list mcastAddrs_t; - mcastAddrs_t mcastAddrs; - - // - // bind to the the interfaces specified - otherwise wildcard - // with INADDR_ANY and allow clients to attach from any interface - // - pStr = envGetConfigParamPtr ( & EPICS_CAS_INTF_ADDR_LIST ); - if (pStr) { - bool configAddrOnceFlag = true; - stat = S_cas_noInterface; - while ( (pToken = getToken ( & pStr, buf, sizeof ( buf ) ) ) ) { - int status; - - status = aToIPAddr (pToken, port, &saddr); - if (status) { - errlogPrintf( - "%s: Parsing '%s'\n", - __FILE__, - EPICS_CAS_INTF_ADDR_LIST.name); - errlogPrintf( - "\tBad internet address or host name: '%s'\n", - pToken); - continue; - } - - epicsUInt32 top = ntohl(saddr.sin_addr.s_addr)>>24; - if (saddr.sin_family==AF_INET && top>=224 && top<=239) { - osiSockAddr oaddr; - oaddr.ia = saddr; - mcastAddrs.push_back(oaddr); - continue; - } - - stat = this->attachInterface (caNetAddr(saddr), autoBeaconAddr, configAddrOnceFlag); - if (stat) { - errMessage(stat, "unable to attach explicit interface"); - break; - } - configAddrOnceFlag = false; - } - } - else { - saddr.sin_family = AF_INET; - saddr.sin_port = ntohs (port); - saddr.sin_addr.s_addr = htonl(INADDR_ANY); - stat = this->attachInterface (caNetAddr(saddr), autoBeaconAddr, true); - if (stat) { - errMessage(stat, "unable to attach any interface"); - } - } - - for (mcastAddrs_t::const_iterator it = mcastAddrs.begin(); it!=mcastAddrs.end(); ++it) { - this->addMCast(*it); - } -} - -// -// caServerIO::~caServerIO() -// -caServerIO::~caServerIO() -{ - osiSockRelease(); -} - -// -// caServerIO::staticInit() -// -inline void caServerIO::staticInit() -{ - if ( caServerIO::staticInitialized ) { - return; - } - - epicsSignalInstallSigPipeIgnore (); - - caServerIO::staticInitialized = true; -} - -// -// caServerIO::show() -// -void caServerIO::show (unsigned /* level */) const -{ - printf ( "caServerIO at %p\n", - static_cast ( this ) ); -} - -// -// getToken() -// -static char *getToken(const char **ppString, - char *pBuf, unsigned bufSIze) -{ - const char *pToken; - unsigned i; - - pToken = *ppString; - while(isspace(*pToken)&&*pToken){ - pToken++; - } - - for (i=0u; i - typedef SSIZE_T ssize_t; -#endif - -#define epicsExportSharedSymbols -#include "casDGIntfIO.h" -#include "ipIgnoreEntry.h" - -static void forcePort (ELLLIST *pList, unsigned short port) -{ - osiSockAddrNode *pNode; - - pNode = reinterpret_cast < osiSockAddrNode * > ( ellFirst ( pList ) ); - while ( pNode ) { - if ( pNode->addr.sa.sa_family == AF_INET ) { - pNode->addr.ia.sin_port = htons (port); - } - pNode = reinterpret_cast < osiSockAddrNode * > ( ellNext ( &pNode->node ) ); - } -} - - -casDGIntfIO::casDGIntfIO ( caServerI & serverIn, clientBufMemoryManager & memMgr, - const caNetAddr & addr, bool autoBeaconAddr, bool addConfigBeaconAddr ) : - casDGClient ( serverIn, memMgr ) -{ - ELLLIST BCastAddrList; - osiSockAddr serverAddr; - osiSockAddr serverBCastAddr; - unsigned short beaconPort; - int status; - - ellInit ( &BCastAddrList ); - ellInit ( &this->beaconAddrList ); - - if ( ! osiSockAttach () ) { - throw S_cas_internal; - } - - this->sock = casDGIntfIO::makeSockDG(); - if (this->sock==INVALID_SOCKET) { - throw S_cas_internal; - } - - this->beaconSock = casDGIntfIO::makeSockDG(); - if (this->beaconSock==INVALID_SOCKET) { - epicsSocketDestroy (this->sock); - throw S_cas_internal; - } - - { - // this connect is to supress a warning message on Linux - // when we shutdown the read side of the socket. If it - // fails (and it will on old ip kernels) we just ignore - // the failure. - osiSockAddr sockAddr; - sockAddr.ia.sin_family = AF_UNSPEC; - sockAddr.ia.sin_port = htons ( 0 ); - sockAddr.ia.sin_addr.s_addr = htonl ( 0 ); - connect ( this->beaconSock, - & sockAddr.sa, sizeof ( sockAddr.sa ) ); - shutdown ( this->beaconSock, SHUT_RD ); - } - - // - // Fetch port configuration from EPICS environment variables - // - if (envGetConfigParamPtr(&EPICS_CAS_SERVER_PORT)) { - this->dgPort = envGetInetPortConfigParam (&EPICS_CAS_SERVER_PORT, - static_cast (CA_SERVER_PORT)); - } - else { - this->dgPort = envGetInetPortConfigParam (&EPICS_CA_SERVER_PORT, - static_cast (CA_SERVER_PORT)); - } - if (envGetConfigParamPtr(&EPICS_CAS_BEACON_PORT)) { - beaconPort = envGetInetPortConfigParam (&EPICS_CAS_BEACON_PORT, - static_cast (CA_REPEATER_PORT)); - } - else { - beaconPort = envGetInetPortConfigParam (&EPICS_CA_REPEATER_PORT, - static_cast (CA_REPEATER_PORT)); - } - - // - // set up the primary address of the server - // - serverAddr.ia = addr; - serverAddr.ia.sin_port = htons (this->dgPort); - - // - // discover beacon addresses associated with this interface - // - { - osiSockAddrNode *pAddr; - ELLLIST tmpList; - - ellInit ( &tmpList ); - osiSockDiscoverBroadcastAddresses (&tmpList, - this->sock, &serverAddr); // match addr - forcePort ( &tmpList, beaconPort ); - removeDuplicateAddresses ( &BCastAddrList, &tmpList, 1 ); - if (ellCount(&BCastAddrList)<1) { - errMessage (S_cas_noInterface, "- unable to continue"); - epicsSocketDestroy (this->sock); - throw S_cas_noInterface; - } - pAddr = reinterpret_cast < osiSockAddrNode * > ( ellFirst ( &BCastAddrList ) ); - serverBCastAddr.ia = pAddr->addr.ia; - serverBCastAddr.ia.sin_port = htons (this->dgPort); - - if ( ! autoBeaconAddr ) { - // avoid use of ellFree because problems on windows occur if the - // free is in a different DLL than the malloc - while ( ELLNODE * pnode = ellGet ( & BCastAddrList ) ) { - free ( pnode ); - } - } - } - - status = bind ( this->sock, &serverAddr.sa, sizeof (serverAddr) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - char buf[64]; - ipAddrToA ( &serverAddr.ia, buf, sizeof ( buf ) ); - errPrintf ( S_cas_bindFail, __FILE__, __LINE__, - "- bind UDP IP addr=%s failed because %s", buf, sockErrBuf ); - epicsSocketDestroy (this->sock); - throw S_cas_bindFail; - } - - if ( addConfigBeaconAddr ) { - addAddrToChannelAccessAddressList ( - & BCastAddrList, &EPICS_CAS_BEACON_ADDR_LIST, beaconPort, 0 ); - } - - removeDuplicateAddresses ( & this->beaconAddrList, & BCastAddrList, 0 ); - - { - ELLLIST parsed, filtered; - ellInit ( & parsed ); - ellInit ( & filtered ); - // we dont care what port they are coming from - addAddrToChannelAccessAddressList ( & parsed, & EPICS_CAS_IGNORE_ADDR_LIST, 0, false ); - removeDuplicateAddresses ( & filtered, & parsed, true ); - - while ( ELLNODE * pRawNode = ellGet ( & filtered ) ) { - STATIC_ASSERT ( offsetof (osiSockAddrNode, node) == 0 ); - osiSockAddrNode * pNode = reinterpret_cast < osiSockAddrNode * > ( pRawNode ); - if ( pNode->addr.sa.sa_family == AF_INET ) { - ipIgnoreEntry * pIPI = new ( this->ipIgnoreEntryFreeList ) - ipIgnoreEntry ( pNode->addr.ia.sin_addr.s_addr ); - this->ignoreTable.add ( * pIPI ); - } - else { - errlogPrintf ( - "Expected IP V4 address - EPICS_CAS_IGNORE_ADDR_LIST entry ignored\n" ); - } - free ( pNode ); - } - } - - // - // Solaris specific: - // If they are binding to a particular interface then - // we will also need to bind to the broadcast address - // for that interface (if it has one). This allows - // broadcast packets to be received, but we must reply - // through the "normal" UDP binding or the client will - // appear to receive replies from the broadcast address. - // Since it should never be valid to fill in the UDP - // source address as the broadcast address, then we must - // conclude that the Solaris implementation is at least - // partially broken. - // - // WIN32 specific: - // On windows this appears to only create problems because - // they allow broadcast to be received when - // binding to a particular interface's IP address, and - // always fill in this interface's address as the reply - // address. - // -#if !defined(_WIN32) - if (serverAddr.ia.sin_addr.s_addr != htonl(INADDR_ANY)) { - - this->bcastRecvSock = casDGIntfIO::makeSockDG (); - if (this->bcastRecvSock==INVALID_SOCKET) { - epicsSocketDestroy (this->sock); - throw S_cas_internal; - } - - status = bind ( this->bcastRecvSock, &serverBCastAddr.sa, - sizeof (serverBCastAddr.sa) ); - if (status<0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - char buf[64]; - ipAddrToA ( & serverBCastAddr.ia, buf, sizeof ( buf ) ); - errPrintf ( S_cas_bindFail, __FILE__, __LINE__, - "- bind UDP IP addr=%s failed because %s", - buf, sockErrBuf ); - epicsSocketDestroy ( this->sock ); - epicsSocketDestroy ( this->bcastRecvSock ); - throw S_cas_bindFail; - } - } - else { - this->bcastRecvSock=INVALID_SOCKET; - } -#else - this->bcastRecvSock=INVALID_SOCKET; -#endif -} - -// -// use an initialize routine ? -// -casDGIntfIO::~casDGIntfIO() -{ - if ( this->sock != INVALID_SOCKET ) { - epicsSocketDestroy ( this->sock ); - } - - if ( this->bcastRecvSock != INVALID_SOCKET ) { - epicsSocketDestroy ( this->bcastRecvSock ); - } - - if ( this->beaconSock != INVALID_SOCKET ) { - epicsSocketDestroy ( this->beaconSock ); - } - - // avoid use of ellFree because problems on windows occur if the - // free is in a different DLL than the malloc - ELLNODE * nnode = ellFirst(&this->beaconAddrList); - while ( nnode ) - { - ELLNODE * pnode = nnode; - nnode = nnode->next; - free ( pnode ); - } - - tsSLList < ipIgnoreEntry > tmp; - this->ignoreTable.removeAll ( tmp ); - while ( ipIgnoreEntry * pEntry = tmp.get() ) { - pEntry->~ipIgnoreEntry (); - this->ipIgnoreEntryFreeList.release ( pEntry ); - } - - osiSockRelease (); -} - -void casDGIntfIO::show (unsigned level) const -{ - printf ( "casDGIntfIO at %p\n", - static_cast ( this ) ); - printChannelAccessAddressList (&this->beaconAddrList); - this->casDGClient::show (level); -} - -void casDGIntfIO::xSetNonBlocking() -{ - osiSockIoctl_t yes = true; - - int status = socket_ioctl ( this->sock, FIONBIO, &yes ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "%s:CAS: UDP non blocking IO set fail because \"%s\"\n", - __FILE__, sockErrBuf ); - } - - if ( this->bcastRecvSock != INVALID_SOCKET ) { - yes = true; - int status = socket_ioctl ( this->bcastRecvSock, - FIONBIO, &yes ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "%s:CAS: Broadcast receive UDP non blocking IO set failed because \"%s\"\n", - __FILE__, sockErrBuf ); - } - } -} - -inBufClient::fillCondition -casDGIntfIO::osdRecv ( char * pBufIn, bufSizeT size, - fillParameter parm, bufSizeT & actualSize, caNetAddr & fromOut ) -{ - int status; - osiSocklen_t addrSize; - sockaddr addr; - SOCKET sockThisTime; - - if ( parm == fpUseBroadcastInterface ) { - sockThisTime = this->bcastRecvSock; - } - else { - sockThisTime = this->sock; - } - - addrSize = ( osiSocklen_t ) sizeof ( addr ); - status = recvfrom ( sockThisTime, pBufIn, size, 0, - &addr, &addrSize ); - if ( status <= 0 ) { - if ( status < 0 ) { - if ( SOCKERRNO != SOCK_EWOULDBLOCK ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: UDP recv error was \"%s\"\n", sockErrBuf ); - } - } - return casFillNone; - } - else { - // filter out and discard frames received from the ignore list - if ( this->ignoreTable.numEntriesInstalled () > 0 ) { - if ( addr.sa_family == AF_INET ) { - sockaddr_in * pIP = - reinterpret_cast < sockaddr_in * > ( & addr ); - ipIgnoreEntry comapre ( pIP->sin_addr.s_addr ); - if ( this->ignoreTable.lookup ( comapre ) ) { - return casFillNone; - } - } - } - fromOut = addr; - actualSize = static_cast < bufSizeT > ( status ); - return casFillProgress; - } -} - -outBufClient::flushCondition -casDGIntfIO::osdSend ( const char * pBufIn, bufSizeT size, - const caNetAddr & to ) -{ - int status; - - // - // (char *) cast below is for brain dead wrs prototype - // - struct sockaddr dest = to; - status = sendto ( this->sock, (char *) pBufIn, size, 0, - & dest, sizeof ( dest ) ); - if ( status >= 0 ) { - assert ( size == (unsigned) status ); - return outBufClient::flushProgress; - } - else { - if ( SOCKERRNO != SOCK_EWOULDBLOCK ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - char buf[64]; - sockAddrToA ( & dest, buf, sizeof ( buf ) ); - errlogPrintf ( - "CAS: UDP socket send to \"%s\" failed because \"%s\"\n", - buf, sockErrBuf ); - } - return outBufClient::flushNone; - } -} - -bufSizeT casDGIntfIO :: - dgInBytesPending () const -{ - int status; - osiSockIoctl_t nchars = 0; - - status = socket_ioctl ( this->sock, FIONREAD, & nchars ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: FIONREAD failed because \"%s\"\n", - sockErrBuf ); - return 0u; - } - else if ( nchars < 0 ) { - return 0u; - } - else { - return ( bufSizeT ) nchars; - } -} - -void casDGIntfIO::sendBeaconIO ( char & msg, unsigned length, - aitUint16 & portField, aitUint32 & ) -{ - caNetAddr addr = this->serverAddress (); - struct sockaddr_in inetAddr = addr.getSockIP(); - - portField = inetAddr.sin_port; // the TCP port - - for (ELLNODE *pNode = ellFirst(&this->beaconAddrList); pNode; pNode = ellNext(pNode)) - { - osiSockAddrNode *pAddr = reinterpret_cast(pNode); - - ssize_t status = sendto(this->beaconSock, &msg, length, 0, &pAddr->addr.sa, sizeof(pAddr->addr.ia)); - if ( status != length ) { - char sockErrBuf[64], buf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - ipAddrToA ( &pAddr->addr.ia, buf, sizeof(buf) ); - errlogPrintf ( "%s: CA beacon (send to \"%s\") error was \"%s\" (%u)\n", - __FILE__, buf, sockErrBuf, (unsigned)status ); - } - } -} - -bufSizeT casDGIntfIO::optimumInBufferSize () -{ - -#if 1 - // - // must update client before the message size can be - // increased here - // - return ETHERNET_MAX_UDP; -#else - int n; - int size; - int status; - - /* fetch the TCP send buffer size */ - n = sizeof(size); - status = getsockopt( - this->sock, - SOL_SOCKET, - SO_RCVBUF, - (char *)&size, - &n); - if(status < 0 || n != sizeof(size)){ - size = ETEHRNET_MAX_UDP; - } - - if (size<=0) { - size = ETHERNET_MAX_UDP; - } - return (bufSizeT) size; -#endif -} - -bufSizeT casDGIntfIO :: - osSendBufferSize () const -{ - /* fetch the TCP send buffer size */ - unsigned int size = MAX_UDP_SEND; - osiSocklen_t n = sizeof ( size ); - int status = getsockopt( this->sock, SOL_SOCKET, SO_SNDBUF, - reinterpret_cast < char * > ( & size ), & n ); - if ( status < 0 || n != sizeof(size) ) { - size = MAX_UDP_SEND; - } - if ( size <= MAX_UDP_SEND ) { - size = MAX_UDP_SEND; - } - return static_cast < bufSizeT > ( size ); -} - -SOCKET casDGIntfIO::makeSockDG () -{ - int yes = true; - int status; - SOCKET newSock; - - newSock = epicsSocketCreate (AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (newSock == INVALID_SOCKET) { - errMessage(S_cas_noMemory, "CAS: unable to create cast socket\n"); - return INVALID_SOCKET; - } - - status = setsockopt( - newSock, - SOL_SOCKET, - SO_BROADCAST, - (char *)&yes, - sizeof(yes)); - if (status<0) { - epicsSocketDestroy (newSock); - errMessage(S_cas_internal, - "CAS: unable to set up cast socket\n"); - return INVALID_SOCKET; - } - - // - // some concern that vxWorks will run out of mBuf's - // if this change is made - // - // joh 11-10-98 - // -#if 0 - { - // - // - // this allows for faster connects by queuing - // additional incoming UDP search frames - // - // this allocates a 32k buffer - // (uses a power of two) - // - int size = 1u<<15u; - status = setsockopt( - newSock, - SOL_SOCKET, - SO_RCVBUF, - (char *)&size, - sizeof(size)); - if (status<0) { - epicsSocketDestroy (newSock); - errMessage(S_cas_internal, - "CAS: unable to set cast socket size\n"); - return INVALID_SOCKET; - } - } -#endif - - // - // release the port in case we exit early. Also if - // on a kernel with MULTICAST mods then we can have - // two UDP servers on the same port number (requires - // setting SO_REUSEADDR prior to the bind step below). - // - epicsSocketEnableAddressUseForDatagramFanout ( newSock ); - - return newSock; -} - -int casDGIntfIO::getFD() const -{ - return this->sock; -} - diff --git a/src/ca/legacy/pcas/io/bsdSocket/casDGIntfIO.h b/src/ca/legacy/pcas/io/bsdSocket/casDGIntfIO.h deleted file mode 100644 index f84190cab..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/casDGIntfIO.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. -\*************************************************************************/ - -#ifndef casDGIntfIOh -#define casDGIntfIOh - -#include "casDGClient.h" -#include "ipIgnoreEntry.h" - -class casDGIntfIO : public casDGClient { -public: - casDGIntfIO ( caServerI & serverIn, clientBufMemoryManager &, - const caNetAddr & addr, bool autoBeaconAddr = true, - bool addConfigBeaconAddr = false ); - virtual ~casDGIntfIO(); - - int getFD () const; - int getBCastFD () const; - bool validBCastFD () const; - - void xSetNonBlocking (); - void sendBeaconIO ( char & msg, bufSizeT length, - aitUint16 &portField, aitUint32 & addrField ); - - outBufClient::flushCondition osdSend ( const char * pBuf, bufSizeT nBytesReq, - const caNetAddr & addr); - inBufClient::fillCondition osdRecv ( char * pBuf, bufSizeT nBytesReq, - inBufClient::fillParameter parm, bufSizeT & nBytesActual, caNetAddr & addr ); - virtual void show ( unsigned level ) const; - - static bufSizeT optimumInBufferSize (); - - bufSizeT dgInBytesPending () const; - bufSizeT osSendBufferSize () const ; - -private: - tsFreeList < ipIgnoreEntry, 128 > ipIgnoreEntryFreeList; - resTable < ipIgnoreEntry, ipIgnoreEntry > ignoreTable; - ELLLIST beaconAddrList; - SOCKET sock; - SOCKET bcastRecvSock; // fix for solaris bug - SOCKET beaconSock; // allow connect - unsigned short dgPort; - - static SOCKET makeSockDG (); - casDGIntfIO ( const casDGIntfIO & ); - casDGIntfIO & operator = ( const casDGIntfIO & ); -}; - -inline int casDGIntfIO::getBCastFD() const -{ - return this->bcastRecvSock; -} - -inline bool casDGIntfIO::validBCastFD() const -{ - return this->bcastRecvSock != INVALID_SOCKET; -} - -#endif // casDGIntfIOh - diff --git a/src/ca/legacy/pcas/io/bsdSocket/casIOD.h b/src/ca/legacy/pcas/io/bsdSocket/casIOD.h deleted file mode 100644 index 318efb81b..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/casIOD.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. -\*************************************************************************/ - -#ifndef includeCASIODH -#define includeCASIODH - -#ifdef epicsExportSharedSymbols -# define ipIgnoreEntryEpicsExportSharedSymbols -# undef epicsExportSharedSymbols -#endif - -#include "envDefs.h" -#include "resourceLib.h" -#include "tsFreeList.h" -#include "osiSock.h" -#include "inetAddrID.h" -#include "compilerDependencies.h" - -#ifdef ipIgnoreEntryEpicsExportSharedSymbols -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class caServerIO; -class casStreamOS; - - -// no additions below this line -#endif // includeCASIODH - diff --git a/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc b/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc deleted file mode 100644 index 2c2cb5bef..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.cc +++ /dev/null @@ -1,235 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "errlog.h" -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" -#include "epicsAssert.h" - -#define epicsExportSharedSymbols -#include "casdef.h" -#include "caNetAddr.h" -#include "casIntfIO.h" -#include "casStreamIO.h" -#include "casStreamOS.h" - -// -// 5 appears to be a TCP/IP built in maximum -// -const unsigned caServerConnectPendQueueSize = 5u; - -// -// casIntfIO::casIntfIO() -// -casIntfIO::casIntfIO ( const caNetAddr & addrIn ) : - sock ( INVALID_SOCKET ), - addr ( addrIn.getSockIP() ) -{ - int status; - osiSocklen_t addrSize; - bool portChange; - - if ( ! osiSockAttach () ) { - throw S_cas_internal; - } - - /* - * Setup the server socket - */ - this->sock = epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); - if (this->sock == INVALID_SOCKET) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - printf ( "No socket error was %s\n", sockErrBuf ); - throw S_cas_noFD; - } - - epicsSocketEnableAddressReuseDuringTimeWaitState ( this->sock ); - - status = bind ( this->sock, - reinterpret_cast (&this->addr), - sizeof(this->addr) ); - if (status < 0) { - if (SOCKERRNO == SOCK_EADDRINUSE || - SOCKERRNO == SOCK_EACCES) { - // - // enable assignment of a default port - // (so the getsockname() call below will - // work correctly) - // - this->addr.sin_port = ntohs (0); - status = bind( - this->sock, - reinterpret_cast (&this->addr), - sizeof(this->addr) ); - } - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - char buf[64]; - ipAddrToA (&this->addr, buf, sizeof(buf)); - errlogPrintf ( "CAS: Socket bind TCP to %s failed with %s", - buf, sockErrBuf ); - epicsSocketDestroy (this->sock); - throw S_cas_bindFail; - } - portChange = true; - } - else { - portChange = false; - } - - addrSize = ( osiSocklen_t ) sizeof (this->addr); - status = getsockname ( - this->sock, - reinterpret_cast ( &this->addr ), - &addrSize ); - if (status) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: getsockname() error %s\n", - sockErrBuf ); - epicsSocketDestroy (this->sock); - throw S_cas_internal; - } - - // - // be sure of this now so that we can fetch the IP - // address and port number later - // - assert (this->addr.sin_family == AF_INET); - - if ( portChange ) { - errlogPrintf ( "cas warning: Configured TCP port was unavailable.\n"); - errlogPrintf ( "cas warning: Using dynamically assigned TCP port %hu,\n", - ntohs (this->addr.sin_port) ); - errlogPrintf ( "cas warning: but now two or more servers share the same UDP port.\n"); - errlogPrintf ( "cas warning: Depending on your IP kernel this server may not be\n" ); - errlogPrintf ( "cas warning: reachable with UDP unicast (a host's IP in EPICS_CA_ADDR_LIST)\n" ); - } - - status = listen(this->sock, caServerConnectPendQueueSize); - if (status < 0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: listen() error %s\n", sockErrBuf ); - epicsSocketDestroy (this->sock); - throw S_cas_internal; - } -} - -// -// casIntfIO::~casIntfIO() -// -casIntfIO::~casIntfIO() -{ - if (this->sock != INVALID_SOCKET) { - epicsSocketDestroy (this->sock); - } - - osiSockRelease (); -} - -// -// newStreamIO::newStreamClient() -// -casStreamOS *casIntfIO::newStreamClient ( caServerI & cas, - clientBufMemoryManager & bufMgr ) const -{ - static bool oneMsgFlag = false; - - struct sockaddr newClientAddr; - osiSocklen_t length = ( osiSocklen_t ) sizeof ( newClientAddr ); - SOCKET newSock = epicsSocketAccept ( this->sock, & newClientAddr, & length ); - if ( newSock == INVALID_SOCKET ) { - int errnoCpy = SOCKERRNO; - if ( errnoCpy != SOCK_EWOULDBLOCK && ! oneMsgFlag ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "CAS: %s accept error \"%s\"\n", - __FILE__, sockErrBuf ); - oneMsgFlag = true; - } - return NULL; - } - else if ( sizeof ( newClientAddr ) > (size_t) length ) { - epicsSocketDestroy ( newSock ); - errlogPrintf ( "CAS: accept returned bad address len?\n" ); - return NULL; - } - oneMsgFlag = false; - ioArgsToNewStreamIO args; - args.clientAddr = newClientAddr; - args.sock = newSock; - casStreamOS * pOS = new casStreamOS ( cas, bufMgr, args ); - if ( ! pOS ) { - errMessage ( S_cas_noMemory, - "unable to create data structures for a new client" ); - epicsSocketDestroy ( newSock ); - } - else { - if ( cas.getDebugLevel() > 0u ) { - char pName[64u]; - - pOS->hostName ( pName, sizeof ( pName ) ); - errlogPrintf ( "CAS: allocated client object for \"%s\"\n", pName ); - } - } - return pOS; -} - -// -// casIntfIO::setNonBlocking() -// -void casIntfIO::setNonBlocking() -{ - int status; - osiSockIoctl_t yes = true; - - status = socket_ioctl(this->sock, FIONBIO, &yes); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( - "%s:CAS: server non blocking IO set fail because \"%s\"\n", - __FILE__, sockErrBuf ); - } -} - -// -// casIntfIO::getFD() -// -int casIntfIO::getFD() const -{ - return this->sock; -} - -// -// casIntfIO::show() -// -void casIntfIO::show(unsigned level) const -{ - if (level>2u) { - printf(" casIntfIO::sock = %d\n", this->sock); - } -} - -// -// casIntfIO::serverAddress () -// (avoid problems with GNU inliner) -// -caNetAddr casIntfIO::serverAddress () const -{ - return caNetAddr (this->addr); -} diff --git a/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.h b/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.h deleted file mode 100644 index dd9f333b3..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/casIntfIO.h +++ /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. -\*************************************************************************/ - -#ifndef casIntfIOh -#define casIntfIOh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_casIntfIOh -# undef epicsExportSharedSymbols -#endif - -// external headers included here -#include "osiSock.h" - -#ifdef epicsExportSharedSymbols_casIntfIOh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class caNetAddr; -class caServerI; -class clientBufMemoryManager; - -// -// casIntfIO -// -class casIntfIO { -public: - casIntfIO ( const caNetAddr & addr ); - virtual ~casIntfIO (); - void show ( unsigned level ) const; - - int getFD () const; - - void setNonBlocking (); - - // - // called when we expect that a virtual circuit for a - // client can be created - // - class casStreamOS * newStreamClient ( caServerI & cas, - clientBufMemoryManager & ) const; - - caNetAddr serverAddress () const; - -private: - SOCKET sock; - struct sockaddr_in addr; -}; - -#endif // casIntfIOh diff --git a/src/ca/legacy/pcas/io/bsdSocket/casStreamIO.cc b/src/ca/legacy/pcas/io/bsdSocket/casStreamIO.cc deleted file mode 100644 index e8b67698e..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/casStreamIO.cc +++ /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. -\*************************************************************************/ - -// -// Author: Jeff Hill -// - -#include "errlog.h" - -#define epicsExportSharedSymbols -#include "casStreamIO.h" - -// casStreamIO::casStreamIO() -casStreamIO::casStreamIO ( caServerI & cas, clientBufMemoryManager & bufMgr, - const ioArgsToNewStreamIO & args ) : - casStrmClient ( cas, bufMgr, args.clientAddr ), - sock ( args.sock ), - _osSendBufferSize ( MAX_TCP ), - blockingFlag ( xIsBlocking ), - sockHasBeenShutdown ( false ) -{ - assert ( sock >= 0 ); - int yes = true; - int status; - - /* - * see TCP(4P) this seems to make unsollicited single events much - * faster. I take care of queue up as load increases. - */ - status = setsockopt ( this->sock, IPPROTO_TCP, TCP_NODELAY, - ( char * ) & yes, sizeof ( yes ) ); - if ( status < 0 ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( - "CAS: %s TCP_NODELAY option set failed %s\n", - __FILE__, sockErrBuf ); - throw S_cas_internal; - } - - /* - * turn on KEEPALIVE so if the client crashes - * this task will find out and exit - */ - status = setsockopt ( sock, SOL_SOCKET, SO_KEEPALIVE, - (char *) & yes, sizeof ( yes ) ); - if (status<0) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( - "CAS: %s SO_KEEPALIVE option set failed %s\n", - __FILE__, sockErrBuf ); - throw S_cas_internal; - } - - /* - * some concern that vxWorks will run out of mBuf's - * if this change is made - * - * joh 11-10-98 - */ -#if 0 - int i; - - /* - * 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"); - throw S_cas_internal; - } - 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"); - throw S_cas_internal; - } -#endif - - /* cache the TCP send buffer size */ - unsigned int size = MAX_TCP; - osiSocklen_t n = sizeof ( size ) ; - status = getsockopt ( this->sock, SOL_SOCKET, - SO_SNDBUF, reinterpret_cast < char * > ( & size ), & n ); - if ( status < 0 || n != sizeof ( size ) ) { - size = MAX_TCP; - } - if ( size <= MAX_TCP ) { - size = MAX_TCP; - } - _osSendBufferSize = static_cast < bufSizeT > ( size ); -} - -// casStreamIO::~casStreamIO() -casStreamIO::~casStreamIO() -{ - epicsSocketDestroy ( this->sock ); -} - -// casStreamIO::osdSend() -outBufClient::flushCondition casStreamIO::osdSend ( const char *pInBuf, bufSizeT nBytesReq, - bufSizeT &nBytesActual ) -{ - int status; - - if ( nBytesReq == 0 ) { - nBytesActual = 0; - return outBufClient::flushNone; - } - - status = send (this->sock, (char *) pInBuf, nBytesReq, 0); - if (status == 0) { - return outBufClient::flushDisconnect; - } - else if (status<0) { - int anerrno = SOCKERRNO; - - if ( anerrno == SOCK_EINTR || - anerrno == SOCK_EWOULDBLOCK ) { - return outBufClient::flushNone; - } - - if ( anerrno == SOCK_ENOBUFS ) { - errlogPrintf ( - "cas: system low on network buffers - hybernating for 1 second\n" ); - epicsThreadSleep ( 1.0 ); - return outBufClient::flushNone; - } - - if ( - anerrno != SOCK_ECONNABORTED && - anerrno != SOCK_ECONNRESET && - anerrno != SOCK_EPIPE && - anerrno != SOCK_ETIMEDOUT ) { - - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - char buf[64]; - this->hostName ( buf, sizeof ( buf ) ); - errlogPrintf ( -"CAS: TCP socket send to \"%s\" failed because \"%s\"\n", - buf, sockErrBuf ); - } - return outBufClient::flushDisconnect; - } - nBytesActual = (bufSizeT) status; - return outBufClient::flushProgress; -} - -// casStreamIO::osdRecv() -inBufClient::fillCondition -casStreamIO::osdRecv ( char * pInBuf, bufSizeT nBytes, - bufSizeT & nBytesActual ) -{ - int nchars; - - nchars = recv (this->sock, pInBuf, nBytes, 0); - if ( nchars == 0 ) { - return casFillDisconnect; - } - else if ( nchars < 0 ) { - int myerrno = SOCKERRNO; - char buf[64]; - - if ( myerrno == SOCK_EWOULDBLOCK || - myerrno == SOCK_EINTR ) { - return casFillNone; - } - - if ( myerrno == SOCK_ENOBUFS ) { - errlogPrintf ( - "CAS: system low on network buffers - hybernating for 1 second\n" ); - epicsThreadSleep ( 1.0 ); - return casFillNone; - } - - if ( - myerrno != SOCK_ECONNABORTED && - myerrno != SOCK_ECONNRESET && - myerrno != SOCK_EPIPE && - myerrno != SOCK_ETIMEDOUT ) { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - this->hostName ( buf, sizeof ( buf ) ); - errlogPrintf( - "CAS: client %s disconnected because \"%s\"\n", - buf, sockErrBuf ); - } - return casFillDisconnect; - } - else { - nBytesActual = (bufSizeT) nchars; - return casFillProgress; - } -} - -// casStreamIO::forceDisconnect() -void casStreamIO::forceDisconnect () -{ - // !!!! other OS specific wakeup will be required here when we - // !!!! switch to a threaded implementation - if ( ! this->sockHasBeenShutdown ) { - int status = ::shutdown ( this->sock, SHUT_RDWR ); - if ( status == 0 ) { - this->sockHasBeenShutdown = true; - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ("CAC TCP socket shutdown error was %s\n", - sockErrBuf ); - } - } -} - -// casStreamIO::show() -void casStreamIO::osdShow (unsigned level) const -{ - printf ( "casStreamIO at %p\n", - static_cast ( this ) ); - if (level>1u) { - char buf[64]; - this->hostName ( buf, sizeof ( buf ) ); - printf ( "client = \"%s\"\n", buf ); - } -} - -// casStreamIO::xSsetNonBlocking() -void casStreamIO::xSetNonBlocking() -{ - int status; - osiSockIoctl_t yes = true; - - status = socket_ioctl(this->sock, FIONBIO, &yes); - if (status>=0) { - this->blockingFlag = xIsntBlocking; - } - else { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - errlogPrintf ( "%s:CAS: TCP non blocking IO set fail because \"%s\"\n", - __FILE__, sockErrBuf ); - throw S_cas_internal; - } -} - -// casStreamIO::blockingState() -xBlockingStatus casStreamIO::blockingState() const -{ - return this->blockingFlag; -} - -// casStreamIO :: inCircuitBytesPending() -bufSizeT casStreamIO :: inCircuitBytesPending () const -{ - int status; - osiSockIoctl_t nchars = 0; - - status = socket_ioctl ( this->sock, FIONREAD, &nchars ); - if ( status < 0 ) { - int localError = SOCKERRNO; - if ( - localError != SOCK_ECONNABORTED && - localError != SOCK_ECONNRESET && - localError != SOCK_EPIPE && - localError != SOCK_ETIMEDOUT ) - { - char sockErrBuf[64]; - epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) ); - char buf[64]; - this->hostName ( buf, sizeof ( buf ) ); - errlogPrintf ("CAS: FIONREAD for %s failed because \"%s\"\n", - buf, sockErrBuf ); - } - return 0u; - } - else if ( nchars < 0 ) { - return 0u; - } - else { - return ( bufSizeT ) nchars; - } -} - -// casStreamIO :: osSendBufferSize () -bufSizeT casStreamIO :: osSendBufferSize () const -{ - return _osSendBufferSize; -} - -// casStreamIO::getFD() -int casStreamIO::getFD() const -{ - return this->sock; -} diff --git a/src/ca/legacy/pcas/io/bsdSocket/casStreamIO.h b/src/ca/legacy/pcas/io/bsdSocket/casStreamIO.h deleted file mode 100644 index 6d25ea3bf..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/casStreamIO.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 casStreamIOh -#define casStreamIOh - -#include "casStrmClient.h" - -struct ioArgsToNewStreamIO { - caNetAddr clientAddr; - SOCKET sock; -}; - -class casStreamIO : public casStrmClient { -public: - casStreamIO ( caServerI &, clientBufMemoryManager &, - const ioArgsToNewStreamIO & ); - ~casStreamIO (); - int getFD () const; - void xSetNonBlocking (); - bufSizeT inCircuitBytesPending () const; - bufSizeT osSendBufferSize () const; -private: - SOCKET sock; - bufSizeT _osSendBufferSize; - xBlockingStatus blockingFlag; - - bool sockHasBeenShutdown; - xBlockingStatus blockingState() const; - void osdShow ( unsigned level ) const; - outBufClient::flushCondition osdSend ( const char *pBuf, bufSizeT nBytesReq, - bufSizeT & nBytesActual ); - inBufClient::fillCondition osdRecv ( char *pBuf, bufSizeT nBytesReq, - bufSizeT & nBytesActual ); - void forceDisconnect (); - casStreamIO ( const casStreamIO & ); - casStreamIO & operator = ( const casStreamIO & ); -}; - -#endif // casStreamIOh diff --git a/src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.cpp b/src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.cpp deleted file mode 100644 index 79fba2c79..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.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: Jeffrey O. Hill -// johill@lanl.gov -// - -#include -#include - -#include "osiSock.h" -#include "errlog.h" - -#define epicsExportSharedSymbols -#define caNetAddrSock -#include "ipIgnoreEntry.h" - -void ipIgnoreEntry::show ( unsigned /* level */ ) const -{ - char buf[256]; - struct sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = this->ipAddr; - addr.sin_port = 0; - ipAddrToDottedIP ( & addr, buf, sizeof ( buf ) ); - printf ( "ipIgnoreEntry: %s\n", buf ); -} - -bool ipIgnoreEntry::operator == ( const ipIgnoreEntry & rhs ) const -{ - return this->ipAddr == rhs.ipAddr; -} - -resTableIndex ipIgnoreEntry::hash () const -{ - const unsigned inetAddrMinIndexBitWidth = 8u; - const unsigned inetAddrMaxIndexBitWidth = 32u; - return integerHash ( inetAddrMinIndexBitWidth, - inetAddrMaxIndexBitWidth, this->ipAddr ); -} - -ipIgnoreEntry::ipIgnoreEntry ( unsigned ipAddrIn ) : - ipAddr ( ipAddrIn ) -{ -} - -void * ipIgnoreEntry::operator new ( size_t size, - tsFreeList < class ipIgnoreEntry, 128 > & freeList ) -{ - return freeList.allocate ( size ); -} - -#ifdef CXX_PLACEMENT_DELETE -void ipIgnoreEntry::operator delete ( void * pCadaver, - tsFreeList < class ipIgnoreEntry, 128 > & freeList ) -{ - freeList.release ( pCadaver ); -} -#endif - -void ipIgnoreEntry::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/legacy/pcas/io/bsdSocket/ipIgnoreEntry.h b/src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.h deleted file mode 100644 index d27a77f18..000000000 --- a/src/ca/legacy/pcas/io/bsdSocket/ipIgnoreEntry.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 ipIgnoreEntryh -#define ipIgnoreEntryh - -#ifdef epicsExportSharedSymbols -# define epicsExportSharedSymbols_ipIgnoreEntryh -# undef epicsExportSharedSymbols -#endif - -#include "tsSLList.h" -#include "tsFreeList.h" -#include "resourceLib.h" - -#ifdef epicsExportSharedSymbols_ipIgnoreEntryh -# define epicsExportSharedSymbols -# include "shareLib.h" -#endif - -class ipIgnoreEntry : public tsSLNode < ipIgnoreEntry > { -public: - ipIgnoreEntry ( unsigned ipAddr ); - void show ( unsigned level ) const; - bool operator == ( const ipIgnoreEntry & ) const; - resTableIndex hash () const; - void * operator new ( size_t size, - tsFreeList < class ipIgnoreEntry, 128 > & ); - epicsPlacementDeleteOperator (( void *, - tsFreeList < class ipIgnoreEntry, 128 > & )) -private: - unsigned ipAddr; - ipIgnoreEntry ( const ipIgnoreEntry & ); - ipIgnoreEntry & operator = ( const ipIgnoreEntry & ); - void operator delete ( void * ); -}; - -#endif // ipIgnoreEntryh - diff --git a/src/ca/legacy/pcas/os/vms/BUILD_VMS.COM b/src/ca/legacy/pcas/os/vms/BUILD_VMS.COM deleted file mode 100644 index 5a56baedc..000000000 --- a/src/ca/legacy/pcas/os/vms/BUILD_VMS.COM +++ /dev/null @@ -1,203 +0,0 @@ -$!======================================================================== -$! -$! Name : BUILD_VMS -$! -$! Purpose : To build the CA server library and test programs for -$! VAX/VMS. This procedure assumes the following: -$! - You have copied *.c and *.h from the Epics channel access -$! server source directory (base/src/cas) into this VMS directory -$! - You have copied *.c from the Epics -$! base/src/libCom directory into this VMS directory -$! - You have copied *.h from the base/include directory into this -$! VMS directory -$! - You are using Multinet for TCP/IP access. If not, the logical -$! name definitions below will need to be changed -$! -$! -$! Arguments : None -$! -$! Created 16-NOV-1993 Mark L. Rivers -$! 05-MAY-1994 Jeff O. Hill Updated for EPICS 3.12 -$! -$!======================================================================== -$! -$! Example FTP script moves sources from UNIX to VMS -$! (remove "$!" comment delimeters) -$! -$! open -$! user -$! mkdir [.cas] -$! cd [.cas] -$! prompt -$! lcd ~/epics/base/src/cas -$! mput *.c -$! mput *.h -$! put BUILD_VMS.COM -$! lcd vms -$! mput *.c -$! mput *.h -$! lcd ../../libCom -$! mput *.c -$! mput *.h -$! lcd ../ca -$! mput *.h -$! mput *.c -$! lcd ../../include -$! mput *.h -$!======================================================================== -$! -$ cwd = f$logical("sys$disk") + f$directory() -$ define /nolog sys multinet_root:[multinet.include.sys] -$ define /nolog vms multinet_root:[multinet.include.vms] -$ define /nolog net multinet_root:[multinet.include.net] -$ define /nolog netinet multinet_root:[multinet.include.netinet] -$ define /nolog arpa multinet_root:[multinet.include.arpa] -$ define /nolog tcp multinet_root:[multinet.include] -$! -$! Compile the functions and test programs -$! Define symbol for the CC command -$ call set_cc_command -$ if (p1 .nes. "") -$ then -$ cc_command 'p1' -$ else -$ cc_command casCreateCvrt -$ call linktmp casCreateCvrt -$ casCreateCvrt == "$" + cwd + "casCreateCvrt.exe" -$ casCreateCvrt casCvrt.c -$ cc_command - -exampleCaServer, - -singleThread, - -camessage, - -camsgtask, - -caserverio, - -caservertask, - -cast_server, - -online_notify, - -caEventQueue, - -caMemory, - -casAccess, - -casCvrt, - -mitfp, - -pvRead, - -pvWrite, - -cvtfast, - -errPrintfUNIX, - -fdmgr -$ cc_command - -ACCESS, - -CONN, - -CONVERT, - -FLOW_CONTROL, - -IOCINF, - -REPEATER, - -CAREPEATER, - -SERVICE, - -SYNCGRP,- -TEST_EVENT, - -BSD_DEPEN, - -IF_DEPEN, - -VMS_DEPEN, - -ELLLIB, - -BUCKETLIB, - -ENVSUBR, - -TSSUBR, - -NEXTFIELDSUBR, - -ASSERTUNIX, - -CATIME, - -ACCTST -$ endif -$ -$! -$! Build an object library -$ library /create ca_server_library - -casAccess, - -singleThread, - -camessage, - -camsgtask, - -caserverio, - -caservertask, - -cast_server, - -online_notify, - -caEventQueue, - -casCvrt, - -mitfp, - -caMemory, - -pvRead, - -pvWrite, - -cvtfast, - -errPrintfUNIX, - -fdmgr -$ library /create ca_client_library - -IOCINF, - -ACCESS, - -CONN, - -CONVERT, - -FLOW_CONTROL, - -REPEATER, - -TEST_EVENT, - -SYNCGRP, - -SERVICE, - -IF_DEPEN, - -VMS_DEPEN, - -BSD_DEPEN, - -BUCKETLIB, - -TSSUBR, - -ENVSUBR, - -NEXTFIELDSUBR, - -ASSERTUNIX, - -ELLLIB -$! Link the example server -$ call link exampleCaServer -$ -$! Setup DCL Foreign Command for UNIX cmd line params -$ excas == "$" + cwd + "exampleCaServer.exe" -$ -$! -$ link: subroutine -$! Link differently for VAX and AXP -$ if f$getsyi("HW_MODEL") .ge. 1024 -$ then -$ link 'p1', sys$input/options - ca_server_library/lib - ca_client_library/lib - multinet_socket_library/share -$ else -$ link 'p1', sys$input/options - ca_server_library/lib - ca_client_library/lib - multinet_socket_library/share - sys$share:vaxcrtl/share -$ endif -$ endsubroutine -$ -$ -$ linktmp: subroutine -$! Link differently for VAX and AXP -$ if f$getsyi("HW_MODEL") .ge. 1024 -$ then -$ link 'p1' -$ else -$ link 'p1', sys$input/options - sys$share:vaxcrtl/share -$ endif -$ endsubroutine -$ -$ -$! This subroutine sets up "cc_command" to use different switches for -$! VAX (assumes VAX C compiler) and AXP (DEC C compiler). -$ set_cc_command : subroutine -$ if f$getsyi("HW_MODEL") .ge. 1024 -$ then -$! turn of no prototype messages because MULTINET does not -$! supply prototypes. -$ cc_command:== cc /warn/float=d_float - - /include=([], [-.include], [-.libcom]) - - /define=(MULTINET=1) -$ else -$ cc_command:== cc /include=([], [-.include], [-.libcom]) - - /define=(MULTINET=1) -$ endif -$ endsubroutine -$! ************************************************************ - diff --git a/src/ca/legacy/pcas/os/vms/README b/src/ca/legacy/pcas/os/vms/README deleted file mode 100644 index 6602707af..000000000 --- a/src/ca/legacy/pcas/os/vms/README +++ /dev/null @@ -1,7 +0,0 @@ - -WORK IN PROGRESS - -this directory contains the vms os dependent source for -the EPICS ca server - - diff --git a/src/ca/legacy/pcas/os/vms/casSpecificOS.h b/src/ca/legacy/pcas/os/vms/casSpecificOS.h deleted file mode 100644 index 7aad5d828..000000000 --- a/src/ca/legacy/pcas/os/vms/casSpecificOS.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. -\*************************************************************************/ - -#include - -#include - -#if defined (MULTINET) -# include "multinet_root:[multinet.include]errno.h" -#elif defined (WINTCP) -# include -#else -# include -#endif - -#include -#include -#include -#include - -#if defined(UCX) && 0 -# include -# include -#else -# include -#endif - -#include - -typedef int SOCKET; - -#if defined(WINTCP) - extern int uerrno; -# define SOCKERRNO uerrno -#elif defined(MULTINET) -# define SOCKERRNO socket_errno -#else -# define SOCKERRNO errno -#endif - -#if defined (UCX) -# define socket_close(S) close (S) -# define socket_ioctl(A,B,C) ioctl (A,B,C) -#elif defined (WINTCP) -# define socket_close(S) netclose (S) -# define socket_ioctl(A,B,C) ioctl (A,B,C) -#endif /* UCX */ - -#include - diff --git a/src/ca/legacy/pcas/os/vms/login.com b/src/ca/legacy/pcas/os/vms/login.com deleted file mode 100644 index 8c0e2c6d6..000000000 --- a/src/ca/legacy/pcas/os/vms/login.com +++ /dev/null @@ -1,3 +0,0 @@ - -set display/create/node=xxxx.atdiv.lanl.gov/trans=tcpip - diff --git a/src/ca/legacy/pcas/os/vms/mitfp.c b/src/ca/legacy/pcas/os/vms/mitfp.c deleted file mode 100644 index 0cbce11f4..000000000 --- a/src/ca/legacy/pcas/os/vms/mitfp.c +++ /dev/null @@ -1,271 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * mitfp.c - routines to convert between VAX float and big endian - * IEEE float - * - * Author: Jeffrey O. Hill - * - * - */ - -/************************************************************************/ -/* float convert */ -/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */ -/************************************************************************/ -struct ieeeflt{ - unsigned mant :23; - unsigned exp :8; - unsigned sign :1; -}; - -/* Exponent sign bias */ -#define IEEE_SB 127 - -/* Conversion Range */ -/* -126sign; - if( ((short) pMIT->exp) < (EXPMINIEEE + MIT_SB) ){ - exp = 0; - mant = 0; - sign = 0; - } - else{ - exp = ((short) pMIT->exp) - (MIT_SB + IEEE_SB); - mant = (pMIT->mant1<<16) | pMIT->mant2; - } - pIEEE->mant = mant; - pIEEE->exp = exp; - pIEEE->sign = sign; - - ptmp = (short *)pIEEE; - *ptmp = htons(*ptmp); - - return ieee; -} - - -/* - * ntohf() - * - * sign must be forced to zero if the exponent is zero to prevent a reserved - * operand fault- joh 9-13-90 - */ -float ntohf(float ieee) -{ - float mit; - struct ieeeflt *pIEEE; - struct mitflt *pMIT; - short *ptmp; - long exp; - long mant2; - long mant1; - long sign; - - pMIT = (struct mitflt *) &mit; - pIEEE = (struct ieeeflt *) &ieee; - - ptmp = (short *)pIEEE; - *ptmp = htonl(*ptmp); - - if( ((short) pIEEE->exp) > EXPMAXMIT + IEEE_SB){ - sign = pIEEE->sign; - exp = EXPMAXMIT + MIT_SB; - mant2 = ~0; - mant1 = ~0; - } - else if( pIEEE->exp == 0){ - sign = 0; - exp = 0; - mant2 = 0; - mant1 = 0; - } - else{ - sign = pIEEE->sign; - exp = pIEEE->exp+MIT_SB-IEEE_SB; - mant2 = pIEEE->mant; - mant1 = pIEEE->mant>>(unsigned)16; - } - pMIT->exp = exp; - pMIT->mant2 = mant2; - pMIT->mant1 = mant1; - pMIT->sign = sign; - - return mit; -} - - -/************************************************************************/ -/* double convert */ -/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */ -/************************************************************************/ - -/* (this includes mapping of fringe reals to zero or infinity) */ -/* (byte swaps included in conversion */ - -struct ieeedbl{ - unsigned int mant2 : 32; - unsigned int mant1 : 20; - unsigned int exp : 11; - unsigned int sign : 1; -}; - -#define IEEE_DBL_SB 1023 - -/* Conversion Range */ -/* -1022exp) < (DBLEXPMINMIT+MIT_DBL_SB) ){ - pIEEE->mant1 = 0; - pIEEE->mant2 = 0; - pIEEE->exp = 0; - pIEEE->sign = 0; - } - else{ - pIEEE->exp = ((int)pMIT->exp)+(IEEE_DBL_SB-MIT_DBL_SB); - pIEEE->mant1 = (pMIT->mant1<<13) | (pMIT->mant2>>3); - pIEEE->mant2 = (pMIT->mant2<<29) | (pMIT->mant3<<13) | - (pMIT->mant4>>3); - pIEEE->sign = pMIT->sign; - } - - /* - * byte swap to net order - */ - ptmp = (long *) pIEEE; - tmp = htonl(ptmp[0]); - ptmp[0] = htonl(ptmp[1]); - ptmp[1] = tmp; - - return ieee; -} - - -/* - * sign must be forced to zero if the exponent is zero to prevent a reserved - * operand fault- joh 9-13-90 - */ -double ntohd(double ieee) -{ - double mit; - struct mitdbl *pMIT; - struct ieeedbl *pIEEE; - long *ptmp; - long tmp; - - pMIT = (struct mitdbl *)&mit; - pIEEE = (struct ieeedbl *)&ieee; - - /* - * Byte swap from net order to host order - */ - ptmp = (long *) pIEEE; - tmp = htonl(ptmp[0]); - ptmp[0] = htonl(ptmp[1]); - ptmp[1] = tmp; - - if( ((int)pIEEE->exp) > (DBLEXPMAXMIT + IEEE_DBL_SB) ){ - pMIT->sign = pIEEE->sign; - pMIT->exp = DBLEXPMAXMIT + MIT_DBL_SB; - pMIT->mant1 = ~0; - pMIT->mant2 = ~0; - pMIT->mant3 = ~0; - pMIT->mant4 = ~0; - } - else if( ((int)pIEEE->exp) < (DBLEXPMINMIT + IEEE_DBL_SB) ){ - pMIT->sign = 0; - pMIT->exp = 0; - pMIT->mant1 = 0; - pMIT->mant2 = 0; - pMIT->mant3 = 0; - pMIT->mant4 = 0; - } - else{ - pMIT->sign = pIEEE->sign; - pMIT->exp = ((int)pIEEE->exp)+(MIT_DBL_SB-IEEE_DBL_SB); - pMIT->mant1 = pIEEE->mant1>>13; - pMIT->mant2 = (pIEEE->mant1<<3) | (pIEEE->mant2>>29); - pMIT->mant3 = pIEEE->mant2>>13; - pMIT->mant4 = pIEEE->mant2<<3; - } - return mit; -} - diff --git a/src/ca/legacy/pcas/os/vms/mitfp.cc b/src/ca/legacy/pcas/os/vms/mitfp.cc deleted file mode 100644 index 5dd1903ff..000000000 --- a/src/ca/legacy/pcas/os/vms/mitfp.cc +++ /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 Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * mitfp.c - routines to convert between VAX float and big endian - * IEEE float - * - * Author: Jeffrey O. Hill - * - * - */ - -/* - * include htons() etc. - */ -#include -#include - -double htond(double mit); -double ntohd(double ieee); -float htonf(float mit); -float ntohf(float ieee); - - - -/************************************************************************/ -/* float convert */ -/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */ -/************************************************************************/ -struct ieeeflt{ - unsigned mant :23; - unsigned exp :8; - unsigned sign :1; -}; - -/* Exponent sign bias */ -#define IEEE_SB 127 - -/* Conversion Range */ -/* -126sign; - if( ((short) pMIT->exp) < (EXPMINIEEE + MIT_SB) ){ - exp = 0; - mant = 0; - sign = 0; - } - else{ - exp = ((short) pMIT->exp) - (MIT_SB + IEEE_SB); - mant = (pMIT->mant1<<16) | pMIT->mant2; - } - pIEEE->mant = mant; - pIEEE->exp = exp; - pIEEE->sign = sign; - - ptmp = (short *)pIEEE; - *ptmp = htons(*ptmp); - - return ieee; -} - - -/* - * ntohf() - * - * sign must be forced to zero if the exponent is zero to prevent a reserved - * operand fault- joh 9-13-90 - */ -float ntohf(float ieee) -{ - float mit; - struct ieeeflt *pIEEE; - struct mitflt *pMIT; - short *ptmp; - long exp; - long mant2; - long mant1; - long sign; - - pMIT = (struct mitflt *) &mit; - pIEEE = (struct ieeeflt *) &ieee; - - ptmp = (short *)pIEEE; - *ptmp = htonl(*ptmp); - - if( ((short) pIEEE->exp) > EXPMAXMIT + IEEE_SB){ - sign = pIEEE->sign; - exp = EXPMAXMIT + MIT_SB; - mant2 = ~0; - mant1 = ~0; - } - else if( pIEEE->exp == 0){ - sign = 0; - exp = 0; - mant2 = 0; - mant1 = 0; - } - else{ - sign = pIEEE->sign; - exp = pIEEE->exp+MIT_SB-IEEE_SB; - mant2 = pIEEE->mant; - mant1 = pIEEE->mant>>(unsigned)16; - } - pMIT->exp = exp; - pMIT->mant2 = mant2; - pMIT->mant1 = mant1; - pMIT->sign = sign; - - return mit; -} - - -/************************************************************************/ -/* double convert */ -/* (THIS ASSUMES IEEE IS THE NETWORK FLOATING POINT FORMAT) */ -/************************************************************************/ - -/* (this includes mapping of fringe reals to zero or infinity) */ -/* (byte swaps included in conversion */ - -struct ieeedbl{ - unsigned int mant2 : 32; - unsigned int mant1 : 20; - unsigned int exp : 11; - unsigned int sign : 1; -}; - -#define IEEE_DBL_SB 1023 - -/* Conversion Range */ -/* -1022exp) < (DBLEXPMINMIT+MIT_DBL_SB) ){ - pIEEE->mant1 = 0; - pIEEE->mant2 = 0; - pIEEE->exp = 0; - pIEEE->sign = 0; - } - else{ - pIEEE->exp = ((int)pMIT->exp)+(IEEE_DBL_SB-MIT_DBL_SB); - pIEEE->mant1 = (pMIT->mant1<<13) | (pMIT->mant2>>3); - pIEEE->mant2 = (pMIT->mant2<<29) | (pMIT->mant3<<13) | - (pMIT->mant4>>3); - pIEEE->sign = pMIT->sign; - } - - /* - * byte swap to net order - */ - ptmp = (long *) pIEEE; - tmp = htonl(ptmp[0]); - ptmp[0] = htonl(ptmp[1]); - ptmp[1] = tmp; - - return ieee; -} - - -/* - * sign must be forced to zero if the exponent is zero to prevent a reserved - * operand fault- joh 9-13-90 - */ -double ntohd(double ieee) -{ - double mit; - struct mitdbl *pMIT; - struct ieeedbl *pIEEE; - long *ptmp; - long tmp; - - pMIT = (struct mitdbl *)&mit; - pIEEE = (struct ieeedbl *)&ieee; - - /* - * Byte swap from net order to host order - */ - ptmp = (long *) pIEEE; - tmp = htonl(ptmp[0]); - ptmp[0] = htonl(ptmp[1]); - ptmp[1] = tmp; - - if( ((int)pIEEE->exp) > (DBLEXPMAXMIT + IEEE_DBL_SB) ){ - pMIT->sign = pIEEE->sign; - pMIT->exp = DBLEXPMAXMIT + MIT_DBL_SB; - pMIT->mant1 = ~0; - pMIT->mant2 = ~0; - pMIT->mant3 = ~0; - pMIT->mant4 = ~0; - } - else if( ((int)pIEEE->exp) < (DBLEXPMINMIT + IEEE_DBL_SB) ){ - pMIT->sign = 0; - pMIT->exp = 0; - pMIT->mant1 = 0; - pMIT->mant2 = 0; - pMIT->mant3 = 0; - pMIT->mant4 = 0; - } - else{ - pMIT->sign = pIEEE->sign; - pMIT->exp = ((int)pIEEE->exp)+(MIT_DBL_SB-IEEE_DBL_SB); - pMIT->mant1 = pIEEE->mant1>>13; - pMIT->mant2 = (pIEEE->mant1<<3) | (pIEEE->mant2>>29); - pMIT->mant3 = pIEEE->mant2>>13; - pMIT->mant4 = pIEEE->mant2<<3; - } - return mit; -} - diff --git a/src/ca/legacy/pcas/os/vms/mitfp.h b/src/ca/legacy/pcas/os/vms/mitfp.h deleted file mode 100644 index dce0ad99d..000000000 --- a/src/ca/legacy/pcas/os/vms/mitfp.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. -* EPICS BASE Versions 3.13.7 -* and higher are distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - - -double htond(double mit); -double ntohd(double ieee); -float htonf(float mit); -float ntohf(float ieee); - - diff --git a/src/ca/legacy/pcas/os/vms/vms_depen.h b/src/ca/legacy/pcas/os/vms/vms_depen.h deleted file mode 100644 index 630de4441..000000000 --- a/src/ca/legacy/pcas/os/vms/vms_depen.h +++ /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 -#include - - -#if defined(WINTCP) /* Wallangong */ -# define socket_close(S) netclose(S) -# define socket_ioctl(A,B,C) ioctl(A,B,C) -# include -# include -# include -# include -# define SOCKERRNO uerrno -#elif defined(UCX) /* GeG 09-DEC-1992 */ -# include -# include -# define socket_close(S) close(S) -# define socket_ioctl(A,B,C) ioctl(A,B,C) -# include -# define SOCKERRNO errno -#else /* MULTINET */ -# include -# include -# include -# include -# define SOCKERRNO socket_errno -#endif - -/* - * NOOP out task watch dog for now - */ -#define taskwdInsert(A,B,C) -#define taskwdRemove(A) diff --git a/src/ca/legacy/pcas/test/gddAppFuncTableTest.cc b/src/ca/legacy/pcas/test/gddAppFuncTableTest.cc deleted file mode 100644 index 2c95ebeda..000000000 --- a/src/ca/legacy/pcas/test/gddAppFuncTableTest.cc +++ /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. -\*************************************************************************/ -// -// gddAppFuncTable.h -// -// Author: Jeff Hill -// -// -// -// - -#include -#include "gddAppFuncTable.h" - -class casPV { -public: - casPV(const char * const pNameIn) : pName(pNameIn) {}; - gddAppFuncTableStatus cb(gdd &val); -protected: - const char * const pName; -}; - -class casPVII : public casPV { -public: - casPVII(const char * const pNameIn) : casPV(pNameIn) {}; - gddAppFuncTableStatus cb0(gdd &val); - gddAppFuncTableStatus cb1(gdd &val); -}; - -main () -{ - gddAppFuncTableTable pvAttrDB; - unsigned appPrecision= pvAttrDB.RegisterApplicationType ("precision"); - unsigned appValue = pvAttrDB.RegisterApplicationType ("value"); - gddScalar *pPrec = new gddScalar (appPrecision, aitEnumFloat32); - gddScalar *pVal = new gddScalar (appValue, aitEnumFloat32); - casPV pv ("jane"); - casPVII pvII ("fred"); - casPVII pvIIa ("albert"); - - pvAttrDB.installReadFunc (appPrecision, casPVII::cb0); - pvAttrDB.installReadFunc (appValue, casPVII::cb1); - - pvAttrDB.read (pvII, *pPrec); - pvAttrDB.read (pvII, *pVal); - pvAttrDB.read (pvIIa, *pPrec); -} - -unsigned casPV::cb(gdd &value) -{ - printf("Here for %s\n", pName); - return 0; -} - -unsigned casPVII::cb0(gdd &value) -{ - printf("Here in cb0 for %s\n", pName); - return 0; -} - -unsigned casPVII::cb1(gdd &value) -{ - printf("Here in cb1 for %s\n", pName); - return 0; -} - - diff --git a/src/libCom/calc/Makefile b/src/calc/Makefile similarity index 100% rename from src/libCom/calc/Makefile rename to src/calc/Makefile diff --git a/src/libCom/calc/calcPerform.c b/src/calc/calcPerform.c similarity index 100% rename from src/libCom/calc/calcPerform.c rename to src/calc/calcPerform.c diff --git a/src/libCom/calc/postfix.c b/src/calc/postfix.c similarity index 100% rename from src/libCom/calc/postfix.c rename to src/calc/postfix.c diff --git a/src/libCom/calc/postfix.h b/src/calc/postfix.h similarity index 100% rename from src/libCom/calc/postfix.h rename to src/calc/postfix.h diff --git a/src/libCom/calc/postfixPvt.h b/src/calc/postfixPvt.h similarity index 100% rename from src/libCom/calc/postfixPvt.h rename to src/calc/postfixPvt.h diff --git a/src/libCom/cppStd/Makefile b/src/cppStd/Makefile similarity index 100% rename from src/libCom/cppStd/Makefile rename to src/cppStd/Makefile diff --git a/src/libCom/cppStd/epicsAlgorithm.h b/src/cppStd/epicsAlgorithm.h similarity index 100% rename from src/libCom/cppStd/epicsAlgorithm.h rename to src/cppStd/epicsAlgorithm.h diff --git a/src/libCom/cppStd/epicsExcept.h b/src/cppStd/epicsExcept.h similarity index 100% rename from src/libCom/cppStd/epicsExcept.h rename to src/cppStd/epicsExcept.h diff --git a/src/libCom/cvtFast/Makefile b/src/cvtFast/Makefile similarity index 100% rename from src/libCom/cvtFast/Makefile rename to src/cvtFast/Makefile diff --git a/src/libCom/cvtFast/cvtFast.c b/src/cvtFast/cvtFast.c similarity index 100% rename from src/libCom/cvtFast/cvtFast.c rename to src/cvtFast/cvtFast.c diff --git a/src/libCom/cvtFast/cvtFast.h b/src/cvtFast/cvtFast.h similarity index 100% rename from src/libCom/cvtFast/cvtFast.h rename to src/cvtFast/cvtFast.h diff --git a/src/libCom/cxxTemplates/Makefile b/src/cxxTemplates/Makefile similarity index 100% rename from src/libCom/cxxTemplates/Makefile rename to src/cxxTemplates/Makefile diff --git a/src/libCom/cxxTemplates/README b/src/cxxTemplates/README similarity index 100% rename from src/libCom/cxxTemplates/README rename to src/cxxTemplates/README diff --git a/src/libCom/cxxTemplates/epicsGuard.h b/src/cxxTemplates/epicsGuard.h similarity index 100% rename from src/libCom/cxxTemplates/epicsGuard.h rename to src/cxxTemplates/epicsGuard.h diff --git a/src/libCom/cxxTemplates/epicsSingleton.h b/src/cxxTemplates/epicsSingleton.h similarity index 100% rename from src/libCom/cxxTemplates/epicsSingleton.h rename to src/cxxTemplates/epicsSingleton.h diff --git a/src/libCom/cxxTemplates/epicsSingletonBase.cpp b/src/cxxTemplates/epicsSingletonBase.cpp similarity index 100% rename from src/libCom/cxxTemplates/epicsSingletonBase.cpp rename to src/cxxTemplates/epicsSingletonBase.cpp diff --git a/src/libCom/cxxTemplates/epicsSingletonMutex.cpp b/src/cxxTemplates/epicsSingletonMutex.cpp similarity index 100% rename from src/libCom/cxxTemplates/epicsSingletonMutex.cpp rename to src/cxxTemplates/epicsSingletonMutex.cpp diff --git a/src/libCom/cxxTemplates/resourceLib.cpp b/src/cxxTemplates/resourceLib.cpp similarity index 100% rename from src/libCom/cxxTemplates/resourceLib.cpp rename to src/cxxTemplates/resourceLib.cpp diff --git a/src/libCom/cxxTemplates/resourceLib.h b/src/cxxTemplates/resourceLib.h similarity index 100% rename from src/libCom/cxxTemplates/resourceLib.h rename to src/cxxTemplates/resourceLib.h diff --git a/src/libCom/cxxTemplates/test/Makefile b/src/cxxTemplates/test/Makefile similarity index 100% rename from src/libCom/cxxTemplates/test/Makefile rename to src/cxxTemplates/test/Makefile diff --git a/src/libCom/cxxTemplates/test/minmaxTest.cc b/src/cxxTemplates/test/minmaxTest.cc similarity index 100% rename from src/libCom/cxxTemplates/test/minmaxTest.cc rename to src/cxxTemplates/test/minmaxTest.cc diff --git a/src/libCom/cxxTemplates/test/resourceLibTest.cc b/src/cxxTemplates/test/resourceLibTest.cc similarity index 100% rename from src/libCom/cxxTemplates/test/resourceLibTest.cc rename to src/cxxTemplates/test/resourceLibTest.cc diff --git a/src/libCom/cxxTemplates/test/tsDLListBench.cc b/src/cxxTemplates/test/tsDLListBench.cc similarity index 100% rename from src/libCom/cxxTemplates/test/tsDLListBench.cc rename to src/cxxTemplates/test/tsDLListBench.cc diff --git a/src/libCom/cxxTemplates/test/tsDLListTest.cc b/src/cxxTemplates/test/tsDLListTest.cc similarity index 100% rename from src/libCom/cxxTemplates/test/tsDLListTest.cc rename to src/cxxTemplates/test/tsDLListTest.cc diff --git a/src/libCom/cxxTemplates/test/tsSLListBench.cc b/src/cxxTemplates/test/tsSLListBench.cc similarity index 100% rename from src/libCom/cxxTemplates/test/tsSLListBench.cc rename to src/cxxTemplates/test/tsSLListBench.cc diff --git a/src/libCom/cxxTemplates/test/tsSLListTest.cc b/src/cxxTemplates/test/tsSLListTest.cc similarity index 100% rename from src/libCom/cxxTemplates/test/tsSLListTest.cc rename to src/cxxTemplates/test/tsSLListTest.cc diff --git a/src/libCom/cxxTemplates/tsDLList.h b/src/cxxTemplates/tsDLList.h similarity index 100% rename from src/libCom/cxxTemplates/tsDLList.h rename to src/cxxTemplates/tsDLList.h diff --git a/src/libCom/cxxTemplates/tsFreeList.h b/src/cxxTemplates/tsFreeList.h similarity index 100% rename from src/libCom/cxxTemplates/tsFreeList.h rename to src/cxxTemplates/tsFreeList.h diff --git a/src/libCom/cxxTemplates/tsMinMax.h b/src/cxxTemplates/tsMinMax.h similarity index 100% rename from src/libCom/cxxTemplates/tsMinMax.h rename to src/cxxTemplates/tsMinMax.h diff --git a/src/libCom/cxxTemplates/tsSLList.h b/src/cxxTemplates/tsSLList.h similarity index 100% rename from src/libCom/cxxTemplates/tsSLList.h rename to src/cxxTemplates/tsSLList.h diff --git a/src/libCom/dbmf/Makefile b/src/dbmf/Makefile similarity index 100% rename from src/libCom/dbmf/Makefile rename to src/dbmf/Makefile diff --git a/src/libCom/dbmf/dbmf.c b/src/dbmf/dbmf.c similarity index 100% rename from src/libCom/dbmf/dbmf.c rename to src/dbmf/dbmf.c diff --git a/src/libCom/dbmf/dbmf.h b/src/dbmf/dbmf.h similarity index 100% rename from src/libCom/dbmf/dbmf.h rename to src/dbmf/dbmf.h diff --git a/src/libCom/ellLib/Makefile b/src/ellLib/Makefile similarity index 100% rename from src/libCom/ellLib/Makefile rename to src/ellLib/Makefile diff --git a/src/libCom/ellLib/ellLib.c b/src/ellLib/ellLib.c similarity index 100% rename from src/libCom/ellLib/ellLib.c rename to src/ellLib/ellLib.c diff --git a/src/libCom/ellLib/ellLib.h b/src/ellLib/ellLib.h similarity index 100% rename from src/libCom/ellLib/ellLib.h rename to src/ellLib/ellLib.h diff --git a/src/libCom/ellLib/ellSort.c b/src/ellLib/ellSort.c similarity index 100% rename from src/libCom/ellLib/ellSort.c rename to src/ellLib/ellSort.c diff --git a/src/libCom/env/Makefile b/src/env/Makefile similarity index 100% rename from src/libCom/env/Makefile rename to src/env/Makefile diff --git a/src/libCom/env/RULES b/src/env/RULES similarity index 100% rename from src/libCom/env/RULES rename to src/env/RULES diff --git a/src/libCom/env/bldEnvData.pl b/src/env/bldEnvData.pl similarity index 100% rename from src/libCom/env/bldEnvData.pl rename to src/env/bldEnvData.pl diff --git a/src/libCom/env/envDefs.h b/src/env/envDefs.h similarity index 100% rename from src/libCom/env/envDefs.h rename to src/env/envDefs.h diff --git a/src/libCom/env/envSubr.c b/src/env/envSubr.c similarity index 100% rename from src/libCom/env/envSubr.c rename to src/env/envSubr.c diff --git a/src/libCom/error/Makefile b/src/error/Makefile similarity index 100% rename from src/libCom/error/Makefile rename to src/error/Makefile diff --git a/src/libCom/error/RULES b/src/error/RULES similarity index 100% rename from src/libCom/error/RULES rename to src/error/RULES diff --git a/src/libCom/error/epicsPrint.h b/src/error/epicsPrint.h similarity index 100% rename from src/libCom/error/epicsPrint.h rename to src/error/epicsPrint.h diff --git a/src/libCom/error/errMdef.h b/src/error/errMdef.h similarity index 100% rename from src/libCom/error/errMdef.h rename to src/error/errMdef.h diff --git a/src/libCom/error/errSymLib.c b/src/error/errSymLib.c similarity index 100% rename from src/libCom/error/errSymLib.c rename to src/error/errSymLib.c diff --git a/src/libCom/error/errSymTbl.h b/src/error/errSymTbl.h similarity index 100% rename from src/libCom/error/errSymTbl.h rename to src/error/errSymTbl.h diff --git a/src/libCom/error/errlog.c b/src/error/errlog.c similarity index 100% rename from src/libCom/error/errlog.c rename to src/error/errlog.c diff --git a/src/libCom/error/errlog.h b/src/error/errlog.h similarity index 100% rename from src/libCom/error/errlog.h rename to src/error/errlog.h diff --git a/src/libCom/error/error.h b/src/error/error.h similarity index 100% rename from src/libCom/error/error.h rename to src/error/error.h diff --git a/src/libCom/error/makeStatTbl.pl b/src/error/makeStatTbl.pl similarity index 100% rename from src/libCom/error/makeStatTbl.pl rename to src/error/makeStatTbl.pl diff --git a/src/libCom/fdmgr/Makefile b/src/fdmgr/Makefile similarity index 100% rename from src/libCom/fdmgr/Makefile rename to src/fdmgr/Makefile diff --git a/src/libCom/fdmgr/fdManager.cpp b/src/fdmgr/fdManager.cpp similarity index 100% rename from src/libCom/fdmgr/fdManager.cpp rename to src/fdmgr/fdManager.cpp diff --git a/src/libCom/fdmgr/fdManager.h b/src/fdmgr/fdManager.h similarity index 100% rename from src/libCom/fdmgr/fdManager.h rename to src/fdmgr/fdManager.h diff --git a/src/libCom/fdmgr/fdmgr.cpp b/src/fdmgr/fdmgr.cpp similarity index 100% rename from src/libCom/fdmgr/fdmgr.cpp rename to src/fdmgr/fdmgr.cpp diff --git a/src/libCom/fdmgr/fdmgr.h b/src/fdmgr/fdmgr.h similarity index 100% rename from src/libCom/fdmgr/fdmgr.h rename to src/fdmgr/fdmgr.h diff --git a/src/libCom/flex/COPYING b/src/flex/COPYING similarity index 100% rename from src/libCom/flex/COPYING rename to src/flex/COPYING diff --git a/src/libCom/flex/Changes b/src/flex/Changes similarity index 100% rename from src/libCom/flex/Changes rename to src/flex/Changes diff --git a/src/libCom/flex/EPICS_READ_THIS b/src/flex/EPICS_READ_THIS similarity index 100% rename from src/libCom/flex/EPICS_READ_THIS rename to src/flex/EPICS_READ_THIS diff --git a/src/libCom/flex/Flex.doc b/src/flex/Flex.doc similarity index 100% rename from src/libCom/flex/Flex.doc rename to src/flex/Flex.doc diff --git a/src/libCom/flex/Makefile b/src/flex/Makefile similarity index 100% rename from src/libCom/flex/Makefile rename to src/flex/Makefile diff --git a/src/libCom/flex/README b/src/flex/README similarity index 100% rename from src/libCom/flex/README rename to src/flex/README diff --git a/src/libCom/flex/RULES b/src/flex/RULES similarity index 83% rename from src/libCom/flex/RULES rename to src/flex/RULES index 65406f4c5..22fe5283f 100644 --- a/src/libCom/flex/RULES +++ b/src/flex/RULES @@ -4,10 +4,10 @@ # Copyright (c) 2002 The Regents of the University of California, as # Operator of Los Alamos National Laboratory. # EPICS BASE is distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. +# 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) +parse.c: $(INSTALL_HOST_BIN)/antelope$(HOSTEXE) diff --git a/src/libCom/flex/ccl.c b/src/flex/ccl.c similarity index 100% rename from src/libCom/flex/ccl.c rename to src/flex/ccl.c diff --git a/src/libCom/flex/dfa.c b/src/flex/dfa.c similarity index 100% rename from src/libCom/flex/dfa.c rename to src/flex/dfa.c diff --git a/src/libCom/flex/ecs.c b/src/flex/ecs.c similarity index 100% rename from src/libCom/flex/ecs.c rename to src/flex/ecs.c diff --git a/src/libCom/flex/flex.c b/src/flex/flex.c similarity index 100% rename from src/libCom/flex/flex.c rename to src/flex/flex.c diff --git a/src/libCom/flex/flex.html b/src/flex/flex.html similarity index 100% rename from src/libCom/flex/flex.html rename to src/flex/flex.html diff --git a/src/libCom/flex/flex.skel b/src/flex/flex.skel similarity index 100% rename from src/libCom/flex/flex.skel rename to src/flex/flex.skel diff --git a/src/libCom/flex/flex.skel.static b/src/flex/flex.skel.static similarity index 100% rename from src/libCom/flex/flex.skel.static rename to src/flex/flex.skel.static diff --git a/src/libCom/flex/flexdef.h b/src/flex/flexdef.h similarity index 100% rename from src/libCom/flex/flexdef.h rename to src/flex/flexdef.h diff --git a/src/libCom/flex/flexdoc.html b/src/flex/flexdoc.html similarity index 100% rename from src/libCom/flex/flexdoc.html rename to src/flex/flexdoc.html diff --git a/src/libCom/flex/gen.c b/src/flex/gen.c similarity index 100% rename from src/libCom/flex/gen.c rename to src/flex/gen.c diff --git a/src/libCom/flex/libmain.c b/src/flex/libmain.c similarity index 100% rename from src/libCom/flex/libmain.c rename to src/flex/libmain.c diff --git a/src/libCom/flex/misc.c b/src/flex/misc.c similarity index 100% rename from src/libCom/flex/misc.c rename to src/flex/misc.c diff --git a/src/libCom/flex/nfa.c b/src/flex/nfa.c similarity index 100% rename from src/libCom/flex/nfa.c rename to src/flex/nfa.c diff --git a/src/libCom/flex/parse.y b/src/flex/parse.y similarity index 100% rename from src/libCom/flex/parse.y rename to src/flex/parse.y diff --git a/src/libCom/flex/scan.c b/src/flex/scan.c similarity index 100% rename from src/libCom/flex/scan.c rename to src/flex/scan.c diff --git a/src/libCom/flex/scan.l.DISTRIB b/src/flex/scan.l.DISTRIB similarity index 100% rename from src/libCom/flex/scan.l.DISTRIB rename to src/flex/scan.l.DISTRIB diff --git a/src/libCom/flex/sym.c b/src/flex/sym.c similarity index 100% rename from src/libCom/flex/sym.c rename to src/flex/sym.c diff --git a/src/libCom/flex/tblcmp.c b/src/flex/tblcmp.c similarity index 100% rename from src/libCom/flex/tblcmp.c rename to src/flex/tblcmp.c diff --git a/src/libCom/flex/yylex.c b/src/flex/yylex.c similarity index 100% rename from src/libCom/flex/yylex.c rename to src/flex/yylex.c diff --git a/src/libCom/freeList/Makefile b/src/freeList/Makefile similarity index 100% rename from src/libCom/freeList/Makefile rename to src/freeList/Makefile diff --git a/src/libCom/freeList/freeList.h b/src/freeList/freeList.h similarity index 100% rename from src/libCom/freeList/freeList.h rename to src/freeList/freeList.h diff --git a/src/libCom/freeList/freeListLib.c b/src/freeList/freeListLib.c similarity index 100% rename from src/libCom/freeList/freeListLib.c rename to src/freeList/freeListLib.c diff --git a/src/libCom/gpHash/Makefile b/src/gpHash/Makefile similarity index 100% rename from src/libCom/gpHash/Makefile rename to src/gpHash/Makefile diff --git a/src/libCom/gpHash/gpHash.h b/src/gpHash/gpHash.h similarity index 100% rename from src/libCom/gpHash/gpHash.h rename to src/gpHash/gpHash.h diff --git a/src/libCom/gpHash/gpHashLib.c b/src/gpHash/gpHashLib.c similarity index 100% rename from src/libCom/gpHash/gpHashLib.c rename to src/gpHash/gpHashLib.c 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 bef8637e5..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 Com 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 058dc8d8c..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" -}; -#define FULL_MSG(name) "callbackRequest: " name " ring buffer full\n" -static char *fullMessage[NUM_CALLBACK_PRIORITIES] = { - FULL_MSG("cbLow"), FULL_MSG("cbMedium"), FULL_MSG("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) { - epicsInterruptContextMessage(fullMessage[priority]); - 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 928dae983..000000000 --- a/src/ioc/db/dbConstLink.c +++ /dev/null @@ -1,234 +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" -#include "epicsStdlib.h" - -#define epicsExportSharedSymbols -#include "dbAccessDefs.h" -#include "dbAddr.h" -#include "dbCommon.h" -#include "dbConstLink.h" -#include "dbConvertJSON.h" -#include "dbFldTypes.h" -#include "dbLink.h" -#include "link.h" - -/**************************** Convert functions ****************************/ - -/* The difference between these and dbFastConvert is that constants - * may contain hex numbers, whereas database conversions can't. - */ - -/* Copy to STRING */ -static long cvt_st_st(const char *from, void *pfield, const dbAddr *paddr) -{ - char *to = pfield; - 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; -} - -/* Most integer conversions are identical */ -#define cvt_st_int(TYPE) static long \ -cvt_st_ ## TYPE(const char *from, void *pfield, const dbAddr *paddr) { \ - epics##TYPE *to = pfield; \ - char *end; \ -\ - if (*from == 0) { \ - *to = 0; \ - return 0; \ - } \ - return epicsParse##TYPE(from, to, 0, &end); \ -} - -/* Instanciate for CHAR, UCHAR, SHORT, USHORT and LONG */ -cvt_st_int(Int8) -cvt_st_int(UInt8) -cvt_st_int(Int16) -cvt_st_int(UInt16) -cvt_st_int(Int32) - -/* Conversion for ULONG is different... */ -static long cvt_st_UInt32(const char *from, void *pfield, const dbAddr *paddr) -{ - epicsUInt32 *to = pfield; - char *end; - long status; - - if (*from == 0) { - *to = 0; - return 0; - } - status = epicsParseUInt32(from, to, 0, &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 ULONG fields are DOUBLE. - */ - double dval; - - status = epicsParseFloat64(from, &dval, &end); - if (!status && - dval >=0 && - dval <= ULONG_MAX) - *to = dval; - } - return status; -} - -/* Instanciate for INT64 and UINT64 */ -cvt_st_int(Int64) -cvt_st_int(UInt64) - - -/* Float conversions are identical */ -#define cvt_st_float(TYPE) static long \ -cvt_st_ ## TYPE(const char *from, void *pfield, const dbAddr *paddr) { \ - epics##TYPE *to = pfield; \ - char *end; \ -\ - if (*from == 0) { \ - *to = 0; \ - return 0; \ - } \ - return epicsParse##TYPE(from, to, &end); \ -} - -/* Instanciate for FLOAT32 and FLOAT64 */ -cvt_st_float(Float32) -cvt_st_float(Float64) - - -static long (*convert[DBF_DOUBLE+1])(const char *, void *, const dbAddr *) = { - cvt_st_st, - cvt_st_Int8, cvt_st_UInt8, - cvt_st_Int16, cvt_st_UInt16, - cvt_st_Int32, cvt_st_UInt32, - cvt_st_Int64, cvt_st_UInt64, - cvt_st_Float32, cvt_st_Float64 -}; - -/***************************** 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 convert[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 long dbConstPutValue(struct link *plink, short dbrType, - const void *pbuffer, long nRequest) -{ - 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, - dbConstPutValue, 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 105799876..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 && precord != paddr->precord) - 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 e6de60606..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) -{ - if(dbevEventUserFreeList) freeListCleanup(dbevEventUserFreeList); - dbevEventUserFreeList = NULL; - - if(dbevEventQueueFreeList) freeListCleanup(dbevEventQueueFreeList); - dbevEventQueueFreeList = NULL; - - if(dbevEventSubscriptionFreeList) freeListCleanup(dbevEventSubscriptionFreeList); - dbevEventSubscriptionFreeList = NULL; - - if(dbevFieldLogFreeList) 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 fb03b54cf..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 ca 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 bd663070f..000000000 --- a/src/ioc/dbtemplate/test/msi.plt +++ /dev/null @@ -1,83 +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'; -my $count = 5; # Try up to 5 times... -my $result; -do { - unlink $out; - msi("-I.. -o $out ../t1-template.txt"); - $result = slurp($out); - print "# msi output file empty, retrying\n" - if $result eq ''; -} while ($result eq '') && (--$count > 0); -ok($result, 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 921b3818e..000000000 --- a/src/ioc/misc/dbCore.dbd +++ /dev/null @@ -1,28 +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) - -# CA server debug flag (very verbose) range[0,5] -variable(CASDEBUG,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 72a4b17a1..000000000 --- a/src/ioc/rsrv/camessage.c +++ /dev/null @@ -1,2569 +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 - size, pformat, args ); - if ( localStatus >= 1 ) { - unsigned diagLen = ( unsigned ) localStatus; - if ( diagLen < maxDiagLen - size ) { - 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_LOCK(client); - send_err ( &msg, ECA_DEFUNCT, client, - "CAS: Client version %u too old", client->minor_version_number ); - SEND_UNLOCK(client); - 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_LOCK(client); - send_err ( &msg, ECA_INTERNAL, client, - "CAS: Missaligned protocol rejected" ); - SEND_UNLOCK(client); - 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_LOCK(client); - send_err ( &msg, ECA_TOLARGE, client, - "CAS: Server unable to load large request message. Max bytes=%lu", - rsrvSizeofLargeBufTCP ); - SEND_UNLOCK(client); - 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 e2a0d3e18..000000000 --- a/src/ioc/rsrv/camsgtask.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. -\*************************************************************************/ -/* - * 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; - - casAttachThreadToClient ( client ); - - while (castcp_ctl == ctlRun && !client->disconnect) { - osiSockIoctl_t check_nchars; - long nchars; - int status; - - /* - * allow message to batch up if more are comming - */ - status = socket_ioctl (client->sock, FIONREAD, &check_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 (check_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]; - - /* flush any queued messages before shutdown */ - cas_send_bs_msg(client, 1); - - 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 7250ae6db..000000000 --- a/src/ioc/rsrv/caserverio.c +++ /dev/null @@ -1,405 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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) - * - * - * Set lock_needed=1 unless SEND_LOCK() is held by caller - */ -void cas_send_bs_msg ( struct client *pclient, int lock_needed ) -{ - int status; - - if ( lock_needed ) { - SEND_LOCK ( pclient ); - } - - 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; - if(lock_needed) - SEND_UNLOCK(pclient); - return; - } - - 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 9a032d25e..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, (int)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", (int)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(rsrvLargeBufFreeListTCP && 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 ccbd792dc..000000000 --- a/src/ioc/rsrv/rsrvIocRegister.c +++ /dev/null @@ -1,34 +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 "osiSock.h" -#include "iocsh.h" - -#define epicsExportSharedSymbols -#include "rsrv.h" -#include "server.h" -#include "rsrvIocRegister.h" - -#include "epicsExport.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); -} - -epicsExportAddress(int, CASDEBUG); 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 ef9730ba8..000000000 --- a/src/ioc/rsrv/server.h +++ /dev/null @@ -1,262 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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; - /*! points to first filled byte in buffer */ - unsigned stk; - unsigned maxstk; - /*! points to first unused byte in buffer (after filled bytes) */ - unsigned cnt; - enum messageBufferType type; -}; - -extern epicsThreadPrivateId rsrvCurrentClient; - -typedef struct client { - ELLNODE node; - /*! guarded by SEND_LOCK() aka. client::lock */ - struct message_buffer send; - /*! accessed by receive thread w/o locks cf. camsgtask() */ - 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/iocsh/Makefile b/src/iocsh/Makefile similarity index 100% rename from src/libCom/iocsh/Makefile rename to src/iocsh/Makefile diff --git a/src/libCom/iocsh/iocsh.cpp b/src/iocsh/iocsh.cpp similarity index 100% rename from src/libCom/iocsh/iocsh.cpp rename to src/iocsh/iocsh.cpp diff --git a/src/libCom/iocsh/iocsh.h b/src/iocsh/iocsh.h similarity index 100% rename from src/libCom/iocsh/iocsh.h rename to src/iocsh/iocsh.h diff --git a/src/libCom/iocsh/libComRegister.c b/src/iocsh/libComRegister.c similarity index 100% rename from src/libCom/iocsh/libComRegister.c rename to src/iocsh/libComRegister.c diff --git a/src/libCom/iocsh/libComRegister.h b/src/iocsh/libComRegister.h similarity index 100% rename from src/libCom/iocsh/libComRegister.h rename to src/iocsh/libComRegister.h diff --git a/src/libCom/iocsh/registry.c b/src/iocsh/registry.c similarity index 100% rename from src/libCom/iocsh/registry.c rename to src/iocsh/registry.c diff --git a/src/libCom/iocsh/registry.h b/src/iocsh/registry.h similarity index 100% rename from src/libCom/iocsh/registry.h rename to src/iocsh/registry.h 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/log/Makefile b/src/log/Makefile similarity index 100% rename from src/libCom/log/Makefile rename to src/log/Makefile diff --git a/src/libCom/log/S99logServer@ b/src/log/S99logServer@ similarity index 100% rename from src/libCom/log/S99logServer@ rename to src/log/S99logServer@ diff --git a/src/libCom/log/iocLog.c b/src/log/iocLog.c similarity index 100% rename from src/libCom/log/iocLog.c rename to src/log/iocLog.c diff --git a/src/libCom/log/iocLog.h b/src/log/iocLog.h similarity index 100% rename from src/libCom/log/iocLog.h rename to src/log/iocLog.h diff --git a/src/libCom/log/iocLogServer.c b/src/log/iocLogServer.c similarity index 100% rename from src/libCom/log/iocLogServer.c rename to src/log/iocLogServer.c diff --git a/src/libCom/log/logClient.c b/src/log/logClient.c similarity index 100% rename from src/libCom/log/logClient.c rename to src/log/logClient.c diff --git a/src/libCom/log/logClient.h b/src/log/logClient.h similarity index 100% rename from src/libCom/log/logClient.h rename to src/log/logClient.h diff --git a/src/libCom/macLib/Makefile b/src/macLib/Makefile similarity index 100% rename from src/libCom/macLib/Makefile rename to src/macLib/Makefile diff --git a/src/libCom/macLib/macCore.c b/src/macLib/macCore.c similarity index 100% rename from src/libCom/macLib/macCore.c rename to src/macLib/macCore.c diff --git a/src/libCom/macLib/macEnv.c b/src/macLib/macEnv.c similarity index 100% rename from src/libCom/macLib/macEnv.c rename to src/macLib/macEnv.c diff --git a/src/libCom/macLib/macLib.h b/src/macLib/macLib.h similarity index 100% rename from src/libCom/macLib/macLib.h rename to src/macLib/macLib.h diff --git a/src/libCom/macLib/macLibNOTES b/src/macLib/macLibNOTES similarity index 100% rename from src/libCom/macLib/macLibNOTES rename to src/macLib/macLibNOTES diff --git a/src/libCom/macLib/macLibREADME b/src/macLib/macLibREADME similarity index 100% rename from src/libCom/macLib/macLibREADME rename to src/macLib/macLibREADME diff --git a/src/libCom/macLib/macUtil.c b/src/macLib/macUtil.c similarity index 100% rename from src/libCom/macLib/macUtil.c rename to src/macLib/macUtil.c diff --git a/src/libCom/misc/Makefile b/src/misc/Makefile similarity index 100% rename from src/libCom/misc/Makefile rename to src/misc/Makefile diff --git a/src/libCom/misc/RULES b/src/misc/RULES similarity index 100% rename from src/libCom/misc/RULES rename to src/misc/RULES diff --git a/src/libCom/misc/aToIPAddr.c b/src/misc/aToIPAddr.c similarity index 100% rename from src/libCom/misc/aToIPAddr.c rename to src/misc/aToIPAddr.c diff --git a/src/libCom/misc/adjustment.c b/src/misc/adjustment.c similarity index 100% rename from src/libCom/misc/adjustment.c rename to src/misc/adjustment.c diff --git a/src/libCom/misc/adjustment.h b/src/misc/adjustment.h similarity index 100% rename from src/libCom/misc/adjustment.h rename to src/misc/adjustment.h diff --git a/src/libCom/misc/alarm.h b/src/misc/alarm.h similarity index 100% rename from src/libCom/misc/alarm.h rename to src/misc/alarm.h diff --git a/src/libCom/misc/alarmString.c b/src/misc/alarmString.c similarity index 100% rename from src/libCom/misc/alarmString.c rename to src/misc/alarmString.c diff --git a/src/libCom/misc/alarmString.h b/src/misc/alarmString.h similarity index 100% rename from src/libCom/misc/alarmString.h rename to src/misc/alarmString.h diff --git a/src/libCom/misc/cantProceed.c b/src/misc/cantProceed.c similarity index 100% rename from src/libCom/misc/cantProceed.c rename to src/misc/cantProceed.c diff --git a/src/libCom/misc/cantProceed.h b/src/misc/cantProceed.h similarity index 100% rename from src/libCom/misc/cantProceed.h rename to src/misc/cantProceed.h diff --git a/src/libCom/misc/dbDefs.h b/src/misc/dbDefs.h similarity index 100% rename from src/libCom/misc/dbDefs.h rename to src/misc/dbDefs.h diff --git a/src/libCom/misc/epicsConvert.c b/src/misc/epicsConvert.c similarity index 100% rename from src/libCom/misc/epicsConvert.c rename to src/misc/epicsConvert.c diff --git a/src/libCom/misc/epicsConvert.h b/src/misc/epicsConvert.h similarity index 100% rename from src/libCom/misc/epicsConvert.h rename to src/misc/epicsConvert.h diff --git a/src/libCom/misc/epicsExit.c b/src/misc/epicsExit.c similarity index 100% rename from src/libCom/misc/epicsExit.c rename to src/misc/epicsExit.c diff --git a/src/libCom/misc/epicsExit.h b/src/misc/epicsExit.h similarity index 100% rename from src/libCom/misc/epicsExit.h rename to src/misc/epicsExit.h diff --git a/src/libCom/misc/epicsExport.h b/src/misc/epicsExport.h similarity index 100% rename from src/libCom/misc/epicsExport.h rename to src/misc/epicsExport.h diff --git a/src/libCom/misc/epicsStdlib.c b/src/misc/epicsStdlib.c similarity index 100% rename from src/libCom/misc/epicsStdlib.c rename to src/misc/epicsStdlib.c diff --git a/src/libCom/misc/epicsStdlib.h b/src/misc/epicsStdlib.h similarity index 100% rename from src/libCom/misc/epicsStdlib.h rename to src/misc/epicsStdlib.h diff --git a/src/libCom/misc/epicsString.c b/src/misc/epicsString.c similarity index 100% rename from src/libCom/misc/epicsString.c rename to src/misc/epicsString.c diff --git a/src/libCom/misc/epicsString.h b/src/misc/epicsString.h similarity index 100% rename from src/libCom/misc/epicsString.h rename to src/misc/epicsString.h diff --git a/src/libCom/misc/epicsTypes.h b/src/misc/epicsTypes.h similarity index 100% rename from src/libCom/misc/epicsTypes.h rename to src/misc/epicsTypes.h diff --git a/src/libCom/misc/epicsUnitTest.c b/src/misc/epicsUnitTest.c similarity index 100% rename from src/libCom/misc/epicsUnitTest.c rename to src/misc/epicsUnitTest.c diff --git a/src/libCom/misc/epicsUnitTest.h b/src/misc/epicsUnitTest.h similarity index 100% rename from src/libCom/misc/epicsUnitTest.h rename to src/misc/epicsUnitTest.h diff --git a/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp b/src/misc/ipAddrToAsciiAsynchronous.cpp similarity index 100% rename from src/libCom/misc/ipAddrToAsciiAsynchronous.cpp rename to src/misc/ipAddrToAsciiAsynchronous.cpp diff --git a/src/libCom/misc/ipAddrToAsciiAsynchronous.h b/src/misc/ipAddrToAsciiAsynchronous.h similarity index 100% rename from src/libCom/misc/ipAddrToAsciiAsynchronous.h rename to src/misc/ipAddrToAsciiAsynchronous.h diff --git a/src/libCom/misc/locationException.h b/src/misc/locationException.h similarity index 100% rename from src/libCom/misc/locationException.h rename to src/misc/locationException.h diff --git a/src/libCom/misc/makeEpicsVersion.pl b/src/misc/makeEpicsVersion.pl similarity index 100% rename from src/libCom/misc/makeEpicsVersion.pl rename to src/misc/makeEpicsVersion.pl diff --git a/src/libCom/misc/shareLib.h b/src/misc/shareLib.h similarity index 100% rename from src/libCom/misc/shareLib.h rename to src/misc/shareLib.h diff --git a/src/libCom/misc/testMain.h b/src/misc/testMain.h similarity index 100% rename from src/libCom/misc/testMain.h rename to src/misc/testMain.h diff --git a/src/libCom/misc/truncateFile.c b/src/misc/truncateFile.c similarity index 100% rename from src/libCom/misc/truncateFile.c rename to src/misc/truncateFile.c diff --git a/src/libCom/misc/unixFileName.h b/src/misc/unixFileName.h similarity index 100% rename from src/libCom/misc/unixFileName.h rename to src/misc/unixFileName.h diff --git a/src/libCom/osi/Makefile b/src/osi/Makefile similarity index 100% rename from src/libCom/osi/Makefile rename to src/osi/Makefile diff --git a/src/libCom/osi/RULES b/src/osi/RULES similarity index 100% rename from src/libCom/osi/RULES rename to src/osi/RULES diff --git a/src/libCom/osi/TODOfuture b/src/osi/TODOfuture similarity index 100% rename from src/libCom/osi/TODOfuture rename to src/osi/TODOfuture diff --git a/src/libCom/osi/compiler/clang/compilerSpecific.h b/src/osi/compiler/clang/compilerSpecific.h similarity index 100% rename from src/libCom/osi/compiler/clang/compilerSpecific.h rename to src/osi/compiler/clang/compilerSpecific.h diff --git a/src/libCom/osi/compiler/clang/epicsAtomicCD.h b/src/osi/compiler/clang/epicsAtomicCD.h similarity index 100% rename from src/libCom/osi/compiler/clang/epicsAtomicCD.h rename to src/osi/compiler/clang/epicsAtomicCD.h diff --git a/src/libCom/osi/compiler/default/compilerSpecific.h b/src/osi/compiler/default/compilerSpecific.h similarity index 100% rename from src/libCom/osi/compiler/default/compilerSpecific.h rename to src/osi/compiler/default/compilerSpecific.h diff --git a/src/libCom/osi/compiler/default/epicsAtomicCD.h b/src/osi/compiler/default/epicsAtomicCD.h similarity index 100% rename from src/libCom/osi/compiler/default/epicsAtomicCD.h rename to src/osi/compiler/default/epicsAtomicCD.h diff --git a/src/libCom/osi/compiler/gcc/compilerSpecific.h b/src/osi/compiler/gcc/compilerSpecific.h similarity index 100% rename from src/libCom/osi/compiler/gcc/compilerSpecific.h rename to src/osi/compiler/gcc/compilerSpecific.h diff --git a/src/libCom/osi/compiler/gcc/epicsAtomicCD.h b/src/osi/compiler/gcc/epicsAtomicCD.h similarity index 100% rename from src/libCom/osi/compiler/gcc/epicsAtomicCD.h rename to src/osi/compiler/gcc/epicsAtomicCD.h diff --git a/src/libCom/osi/compiler/msvc/compilerSpecific.h b/src/osi/compiler/msvc/compilerSpecific.h similarity index 100% rename from src/libCom/osi/compiler/msvc/compilerSpecific.h rename to src/osi/compiler/msvc/compilerSpecific.h diff --git a/src/libCom/osi/compiler/msvc/epicsAtomicCD.h b/src/osi/compiler/msvc/epicsAtomicCD.h similarity index 100% rename from src/libCom/osi/compiler/msvc/epicsAtomicCD.h rename to src/osi/compiler/msvc/epicsAtomicCD.h diff --git a/src/libCom/osi/compiler/solStudio/compilerSpecific.h b/src/osi/compiler/solStudio/compilerSpecific.h similarity index 100% rename from src/libCom/osi/compiler/solStudio/compilerSpecific.h rename to src/osi/compiler/solStudio/compilerSpecific.h diff --git a/src/libCom/osi/compiler/solStudio/epicsAtomicCD.h b/src/osi/compiler/solStudio/epicsAtomicCD.h similarity index 100% rename from src/libCom/osi/compiler/solStudio/epicsAtomicCD.h rename to src/osi/compiler/solStudio/epicsAtomicCD.h diff --git a/src/libCom/osi/compilerDependencies.h b/src/osi/compilerDependencies.h similarity index 100% rename from src/libCom/osi/compilerDependencies.h rename to src/osi/compilerDependencies.h diff --git a/src/libCom/osi/devLib.h b/src/osi/devLib.h similarity index 100% rename from src/libCom/osi/devLib.h rename to src/osi/devLib.h diff --git a/src/libCom/osi/devLibVME.c b/src/osi/devLibVME.c similarity index 100% rename from src/libCom/osi/devLibVME.c rename to src/osi/devLibVME.c diff --git a/src/libCom/osi/devLibVME.h b/src/osi/devLibVME.h similarity index 100% rename from src/libCom/osi/devLibVME.h rename to src/osi/devLibVME.h diff --git a/src/libCom/osi/devLibVMEImpl.h b/src/osi/devLibVMEImpl.h similarity index 100% rename from src/libCom/osi/devLibVMEImpl.h rename to src/osi/devLibVMEImpl.h diff --git a/src/libCom/osi/epicsAssert.h b/src/osi/epicsAssert.h similarity index 100% rename from src/libCom/osi/epicsAssert.h rename to src/osi/epicsAssert.h diff --git a/src/libCom/osi/epicsAtomic.h b/src/osi/epicsAtomic.h similarity index 100% rename from src/libCom/osi/epicsAtomic.h rename to src/osi/epicsAtomic.h diff --git a/src/libCom/osi/epicsAtomicDefault.h b/src/osi/epicsAtomicDefault.h similarity index 100% rename from src/libCom/osi/epicsAtomicDefault.h rename to src/osi/epicsAtomicDefault.h diff --git a/src/libCom/osi/epicsEndian.h b/src/osi/epicsEndian.h similarity index 100% rename from src/libCom/osi/epicsEndian.h rename to src/osi/epicsEndian.h diff --git a/src/libCom/osi/epicsEvent.cpp b/src/osi/epicsEvent.cpp similarity index 100% rename from src/libCom/osi/epicsEvent.cpp rename to src/osi/epicsEvent.cpp diff --git a/src/libCom/osi/epicsEvent.h b/src/osi/epicsEvent.h similarity index 100% rename from src/libCom/osi/epicsEvent.h rename to src/osi/epicsEvent.h diff --git a/src/libCom/osi/epicsFindSymbol.h b/src/osi/epicsFindSymbol.h similarity index 100% rename from src/libCom/osi/epicsFindSymbol.h rename to src/osi/epicsFindSymbol.h diff --git a/src/libCom/osi/epicsGeneralTime.c b/src/osi/epicsGeneralTime.c similarity index 100% rename from src/libCom/osi/epicsGeneralTime.c rename to src/osi/epicsGeneralTime.c diff --git a/src/libCom/osi/epicsGeneralTime.h b/src/osi/epicsGeneralTime.h similarity index 100% rename from src/libCom/osi/epicsGeneralTime.h rename to src/osi/epicsGeneralTime.h diff --git a/src/libCom/osi/epicsInterrupt.h b/src/osi/epicsInterrupt.h similarity index 100% rename from src/libCom/osi/epicsInterrupt.h rename to src/osi/epicsInterrupt.h diff --git a/src/libCom/osi/epicsMath.cpp b/src/osi/epicsMath.cpp similarity index 100% rename from src/libCom/osi/epicsMath.cpp rename to src/osi/epicsMath.cpp diff --git a/src/libCom/osi/epicsMessageQueue.cpp b/src/osi/epicsMessageQueue.cpp similarity index 100% rename from src/libCom/osi/epicsMessageQueue.cpp rename to src/osi/epicsMessageQueue.cpp diff --git a/src/libCom/osi/epicsMessageQueue.h b/src/osi/epicsMessageQueue.h similarity index 100% rename from src/libCom/osi/epicsMessageQueue.h rename to src/osi/epicsMessageQueue.h diff --git a/src/libCom/osi/epicsMutex.cpp b/src/osi/epicsMutex.cpp similarity index 100% rename from src/libCom/osi/epicsMutex.cpp rename to src/osi/epicsMutex.cpp diff --git a/src/libCom/osi/epicsMutex.h b/src/osi/epicsMutex.h similarity index 100% rename from src/libCom/osi/epicsMutex.h rename to src/osi/epicsMutex.h diff --git a/src/libCom/osi/epicsReadline.c b/src/osi/epicsReadline.c similarity index 100% rename from src/libCom/osi/epicsReadline.c rename to src/osi/epicsReadline.c diff --git a/src/libCom/osi/epicsReadline.h b/src/osi/epicsReadline.h similarity index 100% rename from src/libCom/osi/epicsReadline.h rename to src/osi/epicsReadline.h diff --git a/src/libCom/osi/epicsSignal.h b/src/osi/epicsSignal.h similarity index 100% rename from src/libCom/osi/epicsSignal.h rename to src/osi/epicsSignal.h diff --git a/src/libCom/osi/epicsSpin.h b/src/osi/epicsSpin.h similarity index 100% rename from src/libCom/osi/epicsSpin.h rename to src/osi/epicsSpin.h diff --git a/src/libCom/osi/epicsStackTrace.c b/src/osi/epicsStackTrace.c similarity index 100% rename from src/libCom/osi/epicsStackTrace.c rename to src/osi/epicsStackTrace.c diff --git a/src/libCom/osi/epicsStackTrace.h b/src/osi/epicsStackTrace.h similarity index 100% rename from src/libCom/osi/epicsStackTrace.h rename to src/osi/epicsStackTrace.h diff --git a/src/libCom/osi/epicsStackTracePvt.h b/src/osi/epicsStackTracePvt.h similarity index 100% rename from src/libCom/osi/epicsStackTracePvt.h rename to src/osi/epicsStackTracePvt.h diff --git a/src/libCom/osi/epicsStdio.c b/src/osi/epicsStdio.c similarity index 100% rename from src/libCom/osi/epicsStdio.c rename to src/osi/epicsStdio.c diff --git a/src/libCom/osi/epicsStdio.h b/src/osi/epicsStdio.h similarity index 100% rename from src/libCom/osi/epicsStdio.h rename to src/osi/epicsStdio.h diff --git a/src/libCom/osi/epicsStdioRedirect.h b/src/osi/epicsStdioRedirect.h similarity index 100% rename from src/libCom/osi/epicsStdioRedirect.h rename to src/osi/epicsStdioRedirect.h diff --git a/src/libCom/osi/epicsTempFile.h b/src/osi/epicsTempFile.h similarity index 100% rename from src/libCom/osi/epicsTempFile.h rename to src/osi/epicsTempFile.h diff --git a/src/libCom/osi/epicsThread.cpp b/src/osi/epicsThread.cpp similarity index 100% rename from src/libCom/osi/epicsThread.cpp rename to src/osi/epicsThread.cpp diff --git a/src/libCom/osi/epicsThread.h b/src/osi/epicsThread.h similarity index 100% rename from src/libCom/osi/epicsThread.h rename to src/osi/epicsThread.h diff --git a/src/libCom/osi/epicsTime.cpp b/src/osi/epicsTime.cpp similarity index 100% rename from src/libCom/osi/epicsTime.cpp rename to src/osi/epicsTime.cpp diff --git a/src/libCom/osi/epicsTime.h b/src/osi/epicsTime.h similarity index 100% rename from src/libCom/osi/epicsTime.h rename to src/osi/epicsTime.h diff --git a/src/libCom/osi/generalTimeSup.h b/src/osi/generalTimeSup.h similarity index 100% rename from src/libCom/osi/generalTimeSup.h rename to src/osi/generalTimeSup.h diff --git a/src/libCom/osi/os/Darwin/epicsMath.h b/src/osi/os/Darwin/epicsMath.h similarity index 100% rename from src/libCom/osi/os/Darwin/epicsMath.h rename to src/osi/os/Darwin/epicsMath.h diff --git a/src/libCom/osi/os/Darwin/osdBackTrace.cpp b/src/osi/os/Darwin/osdBackTrace.cpp similarity index 100% rename from src/libCom/osi/os/Darwin/osdBackTrace.cpp rename to src/osi/os/Darwin/osdBackTrace.cpp diff --git a/src/libCom/osi/os/Darwin/osdEnv.c b/src/osi/os/Darwin/osdEnv.c similarity index 100% rename from src/libCom/osi/os/Darwin/osdEnv.c rename to src/osi/os/Darwin/osdEnv.c diff --git a/src/libCom/osi/os/Darwin/osdFindAddr.c b/src/osi/os/Darwin/osdFindAddr.c similarity index 100% rename from src/libCom/osi/os/Darwin/osdFindAddr.c rename to src/osi/os/Darwin/osdFindAddr.c diff --git a/src/libCom/osi/os/Darwin/osdSock.h b/src/osi/os/Darwin/osdSock.h similarity index 100% rename from src/libCom/osi/os/Darwin/osdSock.h rename to src/osi/os/Darwin/osdSock.h diff --git a/src/libCom/osi/os/Darwin/osdSockAddrReuse.cpp b/src/osi/os/Darwin/osdSockAddrReuse.cpp similarity index 100% rename from src/libCom/osi/os/Darwin/osdSockAddrReuse.cpp rename to src/osi/os/Darwin/osdSockAddrReuse.cpp diff --git a/src/libCom/osi/os/Darwin/osdTime.cpp b/src/osi/os/Darwin/osdTime.cpp similarity index 100% rename from src/libCom/osi/os/Darwin/osdTime.cpp rename to src/osi/os/Darwin/osdTime.cpp diff --git a/src/libCom/osi/os/Darwin/osdTime.h b/src/osi/os/Darwin/osdTime.h similarity index 100% rename from src/libCom/osi/os/Darwin/osdTime.h rename to src/osi/os/Darwin/osdTime.h diff --git a/src/libCom/osi/os/Darwin/osiFileName.h b/src/osi/os/Darwin/osiFileName.h similarity index 100% rename from src/libCom/osi/os/Darwin/osiFileName.h rename to src/osi/os/Darwin/osiFileName.h diff --git a/src/libCom/osi/os/Linux/osdBackTrace.cpp b/src/osi/os/Linux/osdBackTrace.cpp similarity index 100% rename from src/libCom/osi/os/Linux/osdBackTrace.cpp rename to src/osi/os/Linux/osdBackTrace.cpp diff --git a/src/libCom/osi/os/Linux/osdFindAddr.c b/src/osi/os/Linux/osdFindAddr.c similarity index 100% rename from src/libCom/osi/os/Linux/osdFindAddr.c rename to src/osi/os/Linux/osdFindAddr.c diff --git a/src/libCom/osi/os/Linux/osdSock.h b/src/osi/os/Linux/osdSock.h similarity index 100% rename from src/libCom/osi/os/Linux/osdSock.h rename to src/osi/os/Linux/osdSock.h diff --git a/src/libCom/osi/os/Linux/osdThread.h b/src/osi/os/Linux/osdThread.h similarity index 100% rename from src/libCom/osi/os/Linux/osdThread.h rename to src/osi/os/Linux/osdThread.h diff --git a/src/libCom/osi/os/Linux/osdThreadExtra.c b/src/osi/os/Linux/osdThreadExtra.c similarity index 100% rename from src/libCom/osi/os/Linux/osdThreadExtra.c rename to src/osi/os/Linux/osdThreadExtra.c diff --git a/src/libCom/osi/os/Linux/osdTime.h b/src/osi/os/Linux/osdTime.h similarity index 100% rename from src/libCom/osi/os/Linux/osdTime.h rename to src/osi/os/Linux/osdTime.h diff --git a/src/libCom/osi/os/Linux/osiFileName.h b/src/osi/os/Linux/osiFileName.h similarity index 100% rename from src/libCom/osi/os/Linux/osiFileName.h rename to src/osi/os/Linux/osiFileName.h diff --git a/src/libCom/osi/os/Linux/osiUnistd.h b/src/osi/os/Linux/osiUnistd.h similarity index 100% rename from src/libCom/osi/os/Linux/osiUnistd.h rename to src/osi/os/Linux/osiUnistd.h diff --git a/src/libCom/osi/os/RTEMS/devLibVMEOSD.c b/src/osi/os/RTEMS/devLibVMEOSD.c similarity index 100% rename from src/libCom/osi/os/RTEMS/devLibVMEOSD.c rename to src/osi/os/RTEMS/devLibVMEOSD.c diff --git a/src/libCom/osi/os/RTEMS/epicsAtomicOSD.cpp b/src/osi/os/RTEMS/epicsAtomicOSD.cpp similarity index 100% rename from src/libCom/osi/os/RTEMS/epicsAtomicOSD.cpp rename to src/osi/os/RTEMS/epicsAtomicOSD.cpp diff --git a/src/libCom/osi/os/RTEMS/epicsAtomicOSD.h b/src/osi/os/RTEMS/epicsAtomicOSD.h similarity index 100% rename from src/libCom/osi/os/RTEMS/epicsAtomicOSD.h rename to src/osi/os/RTEMS/epicsAtomicOSD.h diff --git a/src/libCom/osi/os/RTEMS/epicsMMIO.h b/src/osi/os/RTEMS/epicsMMIO.h similarity index 100% rename from src/libCom/osi/os/RTEMS/epicsMMIO.h rename to src/osi/os/RTEMS/epicsMMIO.h diff --git a/src/libCom/osi/os/RTEMS/epicsMath.h b/src/osi/os/RTEMS/epicsMath.h similarity index 100% rename from src/libCom/osi/os/RTEMS/epicsMath.h rename to src/osi/os/RTEMS/epicsMath.h diff --git a/src/libCom/osi/os/RTEMS/osdEvent.c b/src/osi/os/RTEMS/osdEvent.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdEvent.c rename to src/osi/os/RTEMS/osdEvent.c diff --git a/src/libCom/osi/os/RTEMS/osdEvent.h b/src/osi/os/RTEMS/osdEvent.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdEvent.h rename to src/osi/os/RTEMS/osdEvent.h diff --git a/src/libCom/osi/os/RTEMS/osdFindSymbol.c b/src/osi/os/RTEMS/osdFindSymbol.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdFindSymbol.c rename to src/osi/os/RTEMS/osdFindSymbol.c diff --git a/src/libCom/osi/os/RTEMS/osdInterrupt.c b/src/osi/os/RTEMS/osdInterrupt.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdInterrupt.c rename to src/osi/os/RTEMS/osdInterrupt.c diff --git a/src/libCom/osi/os/RTEMS/osdInterrupt.h b/src/osi/os/RTEMS/osdInterrupt.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdInterrupt.h rename to src/osi/os/RTEMS/osdInterrupt.h diff --git a/src/libCom/osi/os/RTEMS/osdMessageQueue.c b/src/osi/os/RTEMS/osdMessageQueue.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdMessageQueue.c rename to src/osi/os/RTEMS/osdMessageQueue.c diff --git a/src/libCom/osi/os/RTEMS/osdMessageQueue.h b/src/osi/os/RTEMS/osdMessageQueue.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdMessageQueue.h rename to src/osi/os/RTEMS/osdMessageQueue.h diff --git a/src/libCom/osi/os/RTEMS/osdMutex.c b/src/osi/os/RTEMS/osdMutex.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdMutex.c rename to src/osi/os/RTEMS/osdMutex.c diff --git a/src/libCom/osi/os/RTEMS/osdMutex.h b/src/osi/os/RTEMS/osdMutex.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdMutex.h rename to src/osi/os/RTEMS/osdMutex.h diff --git a/src/libCom/osi/os/RTEMS/osdPoolStatus.c b/src/osi/os/RTEMS/osdPoolStatus.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdPoolStatus.c rename to src/osi/os/RTEMS/osdPoolStatus.c diff --git a/src/libCom/osi/os/RTEMS/osdProcess.c b/src/osi/os/RTEMS/osdProcess.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdProcess.c rename to src/osi/os/RTEMS/osdProcess.c diff --git a/src/libCom/osi/os/RTEMS/osdReadline.c b/src/osi/os/RTEMS/osdReadline.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdReadline.c rename to src/osi/os/RTEMS/osdReadline.c diff --git a/src/libCom/osi/os/RTEMS/osdSignal.cpp b/src/osi/os/RTEMS/osdSignal.cpp similarity index 100% rename from src/libCom/osi/os/RTEMS/osdSignal.cpp rename to src/osi/os/RTEMS/osdSignal.cpp diff --git a/src/libCom/osi/os/RTEMS/osdSock.h b/src/osi/os/RTEMS/osdSock.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdSock.h rename to src/osi/os/RTEMS/osdSock.h diff --git a/src/libCom/osi/os/RTEMS/osdSpin.c b/src/osi/os/RTEMS/osdSpin.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdSpin.c rename to src/osi/os/RTEMS/osdSpin.c diff --git a/src/libCom/osi/os/RTEMS/osdStrtod.h b/src/osi/os/RTEMS/osdStrtod.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdStrtod.h rename to src/osi/os/RTEMS/osdStrtod.h diff --git a/src/libCom/osi/os/RTEMS/osdThread.c b/src/osi/os/RTEMS/osdThread.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdThread.c rename to src/osi/os/RTEMS/osdThread.c diff --git a/src/libCom/osi/os/RTEMS/osdThread.h b/src/osi/os/RTEMS/osdThread.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdThread.h rename to src/osi/os/RTEMS/osdThread.h diff --git a/src/libCom/osi/os/RTEMS/osdThreadExtra.c b/src/osi/os/RTEMS/osdThreadExtra.c similarity index 100% rename from src/libCom/osi/os/RTEMS/osdThreadExtra.c rename to src/osi/os/RTEMS/osdThreadExtra.c diff --git a/src/libCom/osi/os/RTEMS/osdTime.cpp b/src/osi/os/RTEMS/osdTime.cpp similarity index 100% rename from src/libCom/osi/os/RTEMS/osdTime.cpp rename to src/osi/os/RTEMS/osdTime.cpp diff --git a/src/libCom/osi/os/RTEMS/osdTime.h b/src/osi/os/RTEMS/osdTime.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdTime.h rename to src/osi/os/RTEMS/osdTime.h diff --git a/src/libCom/osi/os/RTEMS/osdVME.h b/src/osi/os/RTEMS/osdVME.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osdVME.h rename to src/osi/os/RTEMS/osdVME.h diff --git a/src/libCom/osi/os/RTEMS/osiFileName.h b/src/osi/os/RTEMS/osiFileName.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osiFileName.h rename to src/osi/os/RTEMS/osiFileName.h diff --git a/src/libCom/osi/os/RTEMS/osiUnistd.h b/src/osi/os/RTEMS/osiUnistd.h similarity index 100% rename from src/libCom/osi/os/RTEMS/osiUnistd.h rename to src/osi/os/RTEMS/osiUnistd.h diff --git a/src/libCom/osi/os/WIN32/epicsAtomicMS.h b/src/osi/os/WIN32/epicsAtomicMS.h similarity index 100% rename from src/libCom/osi/os/WIN32/epicsAtomicMS.h rename to src/osi/os/WIN32/epicsAtomicMS.h diff --git a/src/libCom/osi/os/WIN32/epicsAtomicOSD.h b/src/osi/os/WIN32/epicsAtomicOSD.h similarity index 100% rename from src/libCom/osi/os/WIN32/epicsAtomicOSD.h rename to src/osi/os/WIN32/epicsAtomicOSD.h diff --git a/src/libCom/osi/os/WIN32/epicsGetopt.c b/src/osi/os/WIN32/epicsGetopt.c similarity index 100% rename from src/libCom/osi/os/WIN32/epicsGetopt.c rename to src/osi/os/WIN32/epicsGetopt.c diff --git a/src/libCom/osi/os/WIN32/epicsGetopt.h b/src/osi/os/WIN32/epicsGetopt.h similarity index 100% rename from src/libCom/osi/os/WIN32/epicsGetopt.h rename to src/osi/os/WIN32/epicsGetopt.h diff --git a/src/libCom/osi/os/WIN32/epicsMath.h b/src/osi/os/WIN32/epicsMath.h similarity index 100% rename from src/libCom/osi/os/WIN32/epicsMath.h rename to src/osi/os/WIN32/epicsMath.h diff --git a/src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp b/src/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp rename to src/osi/os/WIN32/epicsSocketConvertErrnoToString.cpp diff --git a/src/libCom/osi/os/WIN32/epicsTempFile.cpp b/src/osi/os/WIN32/epicsTempFile.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/epicsTempFile.cpp rename to src/osi/os/WIN32/epicsTempFile.cpp diff --git a/src/libCom/osi/os/WIN32/forceBadAllocException.cpp b/src/osi/os/WIN32/forceBadAllocException.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/forceBadAllocException.cpp rename to src/osi/os/WIN32/forceBadAllocException.cpp diff --git a/src/libCom/osi/os/WIN32/osdBackTrace.cpp b/src/osi/os/WIN32/osdBackTrace.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/osdBackTrace.cpp rename to src/osi/os/WIN32/osdBackTrace.cpp diff --git a/src/libCom/osi/os/WIN32/osdEvent.c b/src/osi/os/WIN32/osdEvent.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdEvent.c rename to src/osi/os/WIN32/osdEvent.c diff --git a/src/libCom/osi/os/WIN32/osdEvent.h b/src/osi/os/WIN32/osdEvent.h similarity index 100% rename from src/libCom/osi/os/WIN32/osdEvent.h rename to src/osi/os/WIN32/osdEvent.h diff --git a/src/libCom/osi/os/WIN32/osdFindSymbol.c b/src/osi/os/WIN32/osdFindSymbol.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdFindSymbol.c rename to src/osi/os/WIN32/osdFindSymbol.c diff --git a/src/libCom/osi/os/WIN32/osdMutex.c b/src/osi/os/WIN32/osdMutex.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdMutex.c rename to src/osi/os/WIN32/osdMutex.c diff --git a/src/libCom/osi/os/WIN32/osdMutex.h b/src/osi/os/WIN32/osdMutex.h similarity index 100% rename from src/libCom/osi/os/WIN32/osdMutex.h rename to src/osi/os/WIN32/osdMutex.h diff --git a/src/libCom/osi/os/WIN32/osdNetIntf.c b/src/osi/os/WIN32/osdNetIntf.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdNetIntf.c rename to src/osi/os/WIN32/osdNetIntf.c diff --git a/src/libCom/osi/os/WIN32/osdPoolStatus.c b/src/osi/os/WIN32/osdPoolStatus.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdPoolStatus.c rename to src/osi/os/WIN32/osdPoolStatus.c diff --git a/src/libCom/osi/os/WIN32/osdPoolStatus.h b/src/osi/os/WIN32/osdPoolStatus.h similarity index 100% rename from src/libCom/osi/os/WIN32/osdPoolStatus.h rename to src/osi/os/WIN32/osdPoolStatus.h diff --git a/src/libCom/osi/os/WIN32/osdProcess.c b/src/osi/os/WIN32/osdProcess.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdProcess.c rename to src/osi/os/WIN32/osdProcess.c diff --git a/src/libCom/osi/os/WIN32/osdSignal.cpp b/src/osi/os/WIN32/osdSignal.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/osdSignal.cpp rename to src/osi/os/WIN32/osdSignal.cpp diff --git a/src/libCom/osi/os/WIN32/osdSock.c b/src/osi/os/WIN32/osdSock.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdSock.c rename to src/osi/os/WIN32/osdSock.c diff --git a/src/libCom/osi/os/WIN32/osdSock.h b/src/osi/os/WIN32/osdSock.h similarity index 100% rename from src/libCom/osi/os/WIN32/osdSock.h rename to src/osi/os/WIN32/osdSock.h diff --git a/src/libCom/osi/os/WIN32/osdSockAddrReuse.cpp b/src/osi/os/WIN32/osdSockAddrReuse.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/osdSockAddrReuse.cpp rename to src/osi/os/WIN32/osdSockAddrReuse.cpp diff --git a/src/libCom/osi/os/WIN32/osdStdio.c b/src/osi/os/WIN32/osdStdio.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdStdio.c rename to src/osi/os/WIN32/osdStdio.c diff --git a/src/libCom/osi/os/WIN32/osdStrtod.h b/src/osi/os/WIN32/osdStrtod.h similarity index 100% rename from src/libCom/osi/os/WIN32/osdStrtod.h rename to src/osi/os/WIN32/osdStrtod.h diff --git a/src/libCom/osi/os/WIN32/osdThread.c b/src/osi/os/WIN32/osdThread.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdThread.c rename to src/osi/os/WIN32/osdThread.c diff --git a/src/libCom/osi/os/WIN32/osdThread.h b/src/osi/os/WIN32/osdThread.h similarity index 100% rename from src/libCom/osi/os/WIN32/osdThread.h rename to src/osi/os/WIN32/osdThread.h diff --git a/src/libCom/osi/os/WIN32/osdThreadExtra.c b/src/osi/os/WIN32/osdThreadExtra.c similarity index 100% rename from src/libCom/osi/os/WIN32/osdThreadExtra.c rename to src/osi/os/WIN32/osdThreadExtra.c diff --git a/src/libCom/osi/os/WIN32/osdTime.cpp b/src/osi/os/WIN32/osdTime.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/osdTime.cpp rename to src/osi/os/WIN32/osdTime.cpp diff --git a/src/libCom/osi/os/WIN32/osdTime.h b/src/osi/os/WIN32/osdTime.h similarity index 100% rename from src/libCom/osi/os/WIN32/osdTime.h rename to src/osi/os/WIN32/osdTime.h diff --git a/src/libCom/osi/os/WIN32/osdWireConfig.h b/src/osi/os/WIN32/osdWireConfig.h similarity index 100% rename from src/libCom/osi/os/WIN32/osdWireConfig.h rename to src/osi/os/WIN32/osdWireConfig.h diff --git a/src/libCom/osi/os/WIN32/osiFileName.h b/src/osi/os/WIN32/osiFileName.h similarity index 100% rename from src/libCom/osi/os/WIN32/osiFileName.h rename to src/osi/os/WIN32/osiFileName.h diff --git a/src/libCom/osi/os/WIN32/osiUnistd.h b/src/osi/os/WIN32/osiUnistd.h similarity index 100% rename from src/libCom/osi/os/WIN32/osiUnistd.h rename to src/osi/os/WIN32/osiUnistd.h diff --git a/src/libCom/osi/os/WIN32/setThreadName.cpp b/src/osi/os/WIN32/setThreadName.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/setThreadName.cpp rename to src/osi/os/WIN32/setThreadName.cpp diff --git a/src/libCom/osi/os/WIN32/systemCallIntMech.cpp b/src/osi/os/WIN32/systemCallIntMech.cpp similarity index 100% rename from src/libCom/osi/os/WIN32/systemCallIntMech.cpp rename to src/osi/os/WIN32/systemCallIntMech.cpp diff --git a/src/libCom/osi/os/cygwin32/devLibVMEOSD.c b/src/osi/os/cygwin32/devLibVMEOSD.c similarity index 100% rename from src/libCom/osi/os/cygwin32/devLibVMEOSD.c rename to src/osi/os/cygwin32/devLibVMEOSD.c diff --git a/src/libCom/osi/os/cygwin32/osdSock.h b/src/osi/os/cygwin32/osdSock.h similarity index 100% rename from src/libCom/osi/os/cygwin32/osdSock.h rename to src/osi/os/cygwin32/osdSock.h diff --git a/src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp b/src/osi/os/cygwin32/osdSockAddrReuse.cpp similarity index 100% rename from src/libCom/osi/os/cygwin32/osdSockAddrReuse.cpp rename to src/osi/os/cygwin32/osdSockAddrReuse.cpp diff --git a/src/libCom/osi/os/cygwin32/osdStrtod.h b/src/osi/os/cygwin32/osdStrtod.h similarity index 100% rename from src/libCom/osi/os/cygwin32/osdStrtod.h rename to src/osi/os/cygwin32/osdStrtod.h diff --git a/src/libCom/osi/os/cygwin32/osiFileName.h b/src/osi/os/cygwin32/osiFileName.h similarity index 100% rename from src/libCom/osi/os/cygwin32/osiFileName.h rename to src/osi/os/cygwin32/osiFileName.h diff --git a/src/libCom/osi/os/cygwin32/systemCallIntMech.cpp b/src/osi/os/cygwin32/systemCallIntMech.cpp similarity index 100% rename from src/libCom/osi/os/cygwin32/systemCallIntMech.cpp rename to src/osi/os/cygwin32/systemCallIntMech.cpp diff --git a/src/libCom/osi/os/default/devLibVMEOSD.c b/src/osi/os/default/devLibVMEOSD.c similarity index 100% rename from src/libCom/osi/os/default/devLibVMEOSD.c rename to src/osi/os/default/devLibVMEOSD.c diff --git a/src/libCom/osi/os/default/epicsAtomicOSD.cpp b/src/osi/os/default/epicsAtomicOSD.cpp similarity index 100% rename from src/libCom/osi/os/default/epicsAtomicOSD.cpp rename to src/osi/os/default/epicsAtomicOSD.cpp diff --git a/src/libCom/osi/os/default/epicsGetopt.h b/src/osi/os/default/epicsGetopt.h similarity index 100% rename from src/libCom/osi/os/default/epicsGetopt.h rename to src/osi/os/default/epicsGetopt.h diff --git a/src/libCom/osi/os/default/epicsMMIO.h b/src/osi/os/default/epicsMMIO.h similarity index 100% rename from src/libCom/osi/os/default/epicsMMIO.h rename to src/osi/os/default/epicsMMIO.h diff --git a/src/libCom/osi/os/default/epicsMMIODef.h b/src/osi/os/default/epicsMMIODef.h similarity index 100% rename from src/libCom/osi/os/default/epicsMMIODef.h rename to src/osi/os/default/epicsMMIODef.h diff --git a/src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp b/src/osi/os/default/epicsSocketConvertErrnoToString.cpp similarity index 100% rename from src/libCom/osi/os/default/epicsSocketConvertErrnoToString.cpp rename to src/osi/os/default/epicsSocketConvertErrnoToString.cpp diff --git a/src/libCom/osi/os/default/gnuReadline.c b/src/osi/os/default/gnuReadline.c similarity index 100% rename from src/libCom/osi/os/default/gnuReadline.c rename to src/osi/os/default/gnuReadline.c diff --git a/src/libCom/osi/os/default/osdAssert.c b/src/osi/os/default/osdAssert.c similarity index 100% rename from src/libCom/osi/os/default/osdAssert.c rename to src/osi/os/default/osdAssert.c diff --git a/src/libCom/osi/os/default/osdBackTrace.cpp b/src/osi/os/default/osdBackTrace.cpp similarity index 100% rename from src/libCom/osi/os/default/osdBackTrace.cpp rename to src/osi/os/default/osdBackTrace.cpp diff --git a/src/libCom/osi/os/default/osdEnv.c b/src/osi/os/default/osdEnv.c similarity index 100% rename from src/libCom/osi/os/default/osdEnv.c rename to src/osi/os/default/osdEnv.c diff --git a/src/libCom/osi/os/default/osdFindAddr.c b/src/osi/os/default/osdFindAddr.c similarity index 100% rename from src/libCom/osi/os/default/osdFindAddr.c rename to src/osi/os/default/osdFindAddr.c diff --git a/src/libCom/osi/os/default/osdFindSymbol.c b/src/osi/os/default/osdFindSymbol.c similarity index 100% rename from src/libCom/osi/os/default/osdFindSymbol.c rename to src/osi/os/default/osdFindSymbol.c diff --git a/src/libCom/osi/os/default/osdInterrupt.c b/src/osi/os/default/osdInterrupt.c similarity index 100% rename from src/libCom/osi/os/default/osdInterrupt.c rename to src/osi/os/default/osdInterrupt.c diff --git a/src/libCom/osi/os/default/osdInterrupt.h b/src/osi/os/default/osdInterrupt.h similarity index 100% rename from src/libCom/osi/os/default/osdInterrupt.h rename to src/osi/os/default/osdInterrupt.h diff --git a/src/libCom/osi/os/default/osdMessageQueue.cpp b/src/osi/os/default/osdMessageQueue.cpp similarity index 100% rename from src/libCom/osi/os/default/osdMessageQueue.cpp rename to src/osi/os/default/osdMessageQueue.cpp diff --git a/src/libCom/osi/os/default/osdMessageQueue.h b/src/osi/os/default/osdMessageQueue.h similarity index 100% rename from src/libCom/osi/os/default/osdMessageQueue.h rename to src/osi/os/default/osdMessageQueue.h diff --git a/src/libCom/osi/os/default/osdNetIntf.c b/src/osi/os/default/osdNetIntf.c similarity index 100% rename from src/libCom/osi/os/default/osdNetIntf.c rename to src/osi/os/default/osdNetIntf.c diff --git a/src/libCom/osi/os/default/osdPoolStatus.c b/src/osi/os/default/osdPoolStatus.c similarity index 100% rename from src/libCom/osi/os/default/osdPoolStatus.c rename to src/osi/os/default/osdPoolStatus.c diff --git a/src/libCom/osi/os/default/osdPoolStatus.h b/src/osi/os/default/osdPoolStatus.h similarity index 100% rename from src/libCom/osi/os/default/osdPoolStatus.h rename to src/osi/os/default/osdPoolStatus.h diff --git a/src/libCom/osi/os/default/osdSignal.cpp b/src/osi/os/default/osdSignal.cpp similarity index 100% rename from src/libCom/osi/os/default/osdSignal.cpp rename to src/osi/os/default/osdSignal.cpp diff --git a/src/libCom/osi/os/default/osdSpin.c b/src/osi/os/default/osdSpin.c similarity index 100% rename from src/libCom/osi/os/default/osdSpin.c rename to src/osi/os/default/osdSpin.c diff --git a/src/libCom/osi/os/default/osdThreadExtra.c b/src/osi/os/default/osdThreadExtra.c similarity index 100% rename from src/libCom/osi/os/default/osdThreadExtra.c rename to src/osi/os/default/osdThreadExtra.c diff --git a/src/libCom/osi/os/default/osdThreadHooks.c b/src/osi/os/default/osdThreadHooks.c similarity index 100% rename from src/libCom/osi/os/default/osdThreadHooks.c rename to src/osi/os/default/osdThreadHooks.c diff --git a/src/libCom/osi/os/default/osdVME.h b/src/osi/os/default/osdVME.h similarity index 100% rename from src/libCom/osi/os/default/osdVME.h rename to src/osi/os/default/osdVME.h diff --git a/src/libCom/osi/os/default/osdWireConfig.h b/src/osi/os/default/osdWireConfig.h similarity index 100% rename from src/libCom/osi/os/default/osdWireConfig.h rename to src/osi/os/default/osdWireConfig.h diff --git a/src/libCom/osi/os/default/osdWireFormat.h b/src/osi/os/default/osdWireFormat.h similarity index 100% rename from src/libCom/osi/os/default/osdWireFormat.h rename to src/osi/os/default/osdWireFormat.h diff --git a/src/libCom/osi/os/freebsd/osdSock.h b/src/osi/os/freebsd/osdSock.h similarity index 100% rename from src/libCom/osi/os/freebsd/osdSock.h rename to src/osi/os/freebsd/osdSock.h diff --git a/src/libCom/osi/os/freebsd/osdTime.h b/src/osi/os/freebsd/osdTime.h similarity index 100% rename from src/libCom/osi/os/freebsd/osdTime.h rename to src/osi/os/freebsd/osdTime.h diff --git a/src/libCom/osi/os/freebsd/osiFileName.h b/src/osi/os/freebsd/osiFileName.h similarity index 100% rename from src/libCom/osi/os/freebsd/osiFileName.h rename to src/osi/os/freebsd/osiFileName.h diff --git a/src/libCom/osi/os/freebsd/osiUnistd.h b/src/osi/os/freebsd/osiUnistd.h similarity index 100% rename from src/libCom/osi/os/freebsd/osiUnistd.h rename to src/osi/os/freebsd/osiUnistd.h diff --git a/src/libCom/osi/os/iOS/epicsMath.h b/src/osi/os/iOS/epicsMath.h similarity index 100% rename from src/libCom/osi/os/iOS/epicsMath.h rename to src/osi/os/iOS/epicsMath.h diff --git a/src/libCom/osi/os/iOS/osdEnv.c b/src/osi/os/iOS/osdEnv.c similarity index 100% rename from src/libCom/osi/os/iOS/osdEnv.c rename to src/osi/os/iOS/osdEnv.c diff --git a/src/libCom/osi/os/iOS/osdSock.h b/src/osi/os/iOS/osdSock.h similarity index 100% rename from src/libCom/osi/os/iOS/osdSock.h rename to src/osi/os/iOS/osdSock.h diff --git a/src/libCom/osi/os/iOS/osdSockAddrReuse.cpp b/src/osi/os/iOS/osdSockAddrReuse.cpp similarity index 100% rename from src/libCom/osi/os/iOS/osdSockAddrReuse.cpp rename to src/osi/os/iOS/osdSockAddrReuse.cpp diff --git a/src/libCom/osi/os/iOS/osdTime.h b/src/osi/os/iOS/osdTime.h similarity index 100% rename from src/libCom/osi/os/iOS/osdTime.h rename to src/osi/os/iOS/osdTime.h diff --git a/src/libCom/osi/os/iOS/osiFileName.h b/src/osi/os/iOS/osiFileName.h similarity index 100% rename from src/libCom/osi/os/iOS/osiFileName.h rename to src/osi/os/iOS/osiFileName.h diff --git a/src/libCom/osi/os/posix/README b/src/osi/os/posix/README similarity index 100% rename from src/libCom/osi/os/posix/README rename to src/osi/os/posix/README diff --git a/src/libCom/osi/os/posix/epicsAtomicOSD.cpp b/src/osi/os/posix/epicsAtomicOSD.cpp similarity index 100% rename from src/libCom/osi/os/posix/epicsAtomicOSD.cpp rename to src/osi/os/posix/epicsAtomicOSD.cpp diff --git a/src/libCom/osi/os/posix/epicsAtomicOSD.h b/src/osi/os/posix/epicsAtomicOSD.h similarity index 100% rename from src/libCom/osi/os/posix/epicsAtomicOSD.h rename to src/osi/os/posix/epicsAtomicOSD.h diff --git a/src/libCom/osi/os/posix/epicsMath.h b/src/osi/os/posix/epicsMath.h similarity index 100% rename from src/libCom/osi/os/posix/epicsMath.h rename to src/osi/os/posix/epicsMath.h diff --git a/src/libCom/osi/os/posix/epicsTempFile.cpp b/src/osi/os/posix/epicsTempFile.cpp similarity index 100% rename from src/libCom/osi/os/posix/epicsTempFile.cpp rename to src/osi/os/posix/epicsTempFile.cpp diff --git a/src/libCom/osi/os/posix/osdElfFindAddr.c b/src/osi/os/posix/osdElfFindAddr.c similarity index 100% rename from src/libCom/osi/os/posix/osdElfFindAddr.c rename to src/osi/os/posix/osdElfFindAddr.c diff --git a/src/libCom/osi/os/posix/osdEvent.c b/src/osi/os/posix/osdEvent.c similarity index 100% rename from src/libCom/osi/os/posix/osdEvent.c rename to src/osi/os/posix/osdEvent.c diff --git a/src/libCom/osi/os/posix/osdEvent.h b/src/osi/os/posix/osdEvent.h similarity index 100% rename from src/libCom/osi/os/posix/osdEvent.h rename to src/osi/os/posix/osdEvent.h diff --git a/src/libCom/osi/os/posix/osdExecinfoBackTrace.cpp b/src/osi/os/posix/osdExecinfoBackTrace.cpp similarity index 100% rename from src/libCom/osi/os/posix/osdExecinfoBackTrace.cpp rename to src/osi/os/posix/osdExecinfoBackTrace.cpp diff --git a/src/libCom/osi/os/posix/osdFindSymbol.c b/src/osi/os/posix/osdFindSymbol.c similarity index 100% rename from src/libCom/osi/os/posix/osdFindSymbol.c rename to src/osi/os/posix/osdFindSymbol.c diff --git a/src/libCom/osi/os/posix/osdMutex.c b/src/osi/os/posix/osdMutex.c similarity index 100% rename from src/libCom/osi/os/posix/osdMutex.c rename to src/osi/os/posix/osdMutex.c diff --git a/src/libCom/osi/os/posix/osdMutex.h b/src/osi/os/posix/osdMutex.h similarity index 100% rename from src/libCom/osi/os/posix/osdMutex.h rename to src/osi/os/posix/osdMutex.h diff --git a/src/libCom/osi/os/posix/osdProcess.c b/src/osi/os/posix/osdProcess.c similarity index 100% rename from src/libCom/osi/os/posix/osdProcess.c rename to src/osi/os/posix/osdProcess.c diff --git a/src/libCom/osi/os/posix/osdSignal.cpp b/src/osi/os/posix/osdSignal.cpp similarity index 100% rename from src/libCom/osi/os/posix/osdSignal.cpp rename to src/osi/os/posix/osdSignal.cpp diff --git a/src/libCom/osi/os/posix/osdSock.c b/src/osi/os/posix/osdSock.c similarity index 100% rename from src/libCom/osi/os/posix/osdSock.c rename to src/osi/os/posix/osdSock.c diff --git a/src/libCom/osi/os/posix/osdSockAddrReuse.cpp b/src/osi/os/posix/osdSockAddrReuse.cpp similarity index 100% rename from src/libCom/osi/os/posix/osdSockAddrReuse.cpp rename to src/osi/os/posix/osdSockAddrReuse.cpp diff --git a/src/libCom/osi/os/posix/osdSpin.c b/src/osi/os/posix/osdSpin.c similarity index 100% rename from src/libCom/osi/os/posix/osdSpin.c rename to src/osi/os/posix/osdSpin.c diff --git a/src/libCom/osi/os/posix/osdStdio.c b/src/osi/os/posix/osdStdio.c similarity index 100% rename from src/libCom/osi/os/posix/osdStdio.c rename to src/osi/os/posix/osdStdio.c diff --git a/src/libCom/osi/os/posix/osdStrtod.h b/src/osi/os/posix/osdStrtod.h similarity index 100% rename from src/libCom/osi/os/posix/osdStrtod.h rename to src/osi/os/posix/osdStrtod.h diff --git a/src/libCom/osi/os/posix/osdThread.c b/src/osi/os/posix/osdThread.c similarity index 100% rename from src/libCom/osi/os/posix/osdThread.c rename to src/osi/os/posix/osdThread.c diff --git a/src/libCom/osi/os/posix/osdThread.h b/src/osi/os/posix/osdThread.h similarity index 100% rename from src/libCom/osi/os/posix/osdThread.h rename to src/osi/os/posix/osdThread.h diff --git a/src/libCom/osi/os/posix/osdThreadExtra.c b/src/osi/os/posix/osdThreadExtra.c similarity index 100% rename from src/libCom/osi/os/posix/osdThreadExtra.c rename to src/osi/os/posix/osdThreadExtra.c diff --git a/src/libCom/osi/os/posix/osdTime.cpp b/src/osi/os/posix/osdTime.cpp similarity index 100% rename from src/libCom/osi/os/posix/osdTime.cpp rename to src/osi/os/posix/osdTime.cpp diff --git a/src/libCom/osi/os/posix/osdTime.h b/src/osi/os/posix/osdTime.h similarity index 100% rename from src/libCom/osi/os/posix/osdTime.h rename to src/osi/os/posix/osdTime.h diff --git a/src/libCom/osi/os/posix/osiUnistd.h b/src/osi/os/posix/osiUnistd.h similarity index 100% rename from src/libCom/osi/os/posix/osiUnistd.h rename to src/osi/os/posix/osiUnistd.h diff --git a/src/libCom/osi/os/posix/systemCallIntMech.cpp b/src/osi/os/posix/systemCallIntMech.cpp similarity index 100% rename from src/libCom/osi/os/posix/systemCallIntMech.cpp rename to src/osi/os/posix/systemCallIntMech.cpp diff --git a/src/libCom/osi/os/solaris/epicsAtomicOSD.h b/src/osi/os/solaris/epicsAtomicOSD.h similarity index 100% rename from src/libCom/osi/os/solaris/epicsAtomicOSD.h rename to src/osi/os/solaris/epicsAtomicOSD.h diff --git a/src/libCom/osi/os/solaris/epicsMath.h b/src/osi/os/solaris/epicsMath.h similarity index 100% rename from src/libCom/osi/os/solaris/epicsMath.h rename to src/osi/os/solaris/epicsMath.h diff --git a/src/libCom/osi/os/solaris/osdBackTrace.cpp b/src/osi/os/solaris/osdBackTrace.cpp similarity index 100% rename from src/libCom/osi/os/solaris/osdBackTrace.cpp rename to src/osi/os/solaris/osdBackTrace.cpp diff --git a/src/libCom/osi/os/solaris/osdFindAddr.c b/src/osi/os/solaris/osdFindAddr.c similarity index 100% rename from src/libCom/osi/os/solaris/osdFindAddr.c rename to src/osi/os/solaris/osdFindAddr.c diff --git a/src/libCom/osi/os/solaris/osdSock.h b/src/osi/os/solaris/osdSock.h similarity index 100% rename from src/libCom/osi/os/solaris/osdSock.h rename to src/osi/os/solaris/osdSock.h diff --git a/src/libCom/osi/os/solaris/osdStrtod.h b/src/osi/os/solaris/osdStrtod.h similarity index 100% rename from src/libCom/osi/os/solaris/osdStrtod.h rename to src/osi/os/solaris/osdStrtod.h diff --git a/src/libCom/osi/os/solaris/osdWireConfig.h b/src/osi/os/solaris/osdWireConfig.h similarity index 100% rename from src/libCom/osi/os/solaris/osdWireConfig.h rename to src/osi/os/solaris/osdWireConfig.h diff --git a/src/libCom/osi/os/solaris/osiFileName.h b/src/osi/os/solaris/osiFileName.h similarity index 100% rename from src/libCom/osi/os/solaris/osiFileName.h rename to src/osi/os/solaris/osiFileName.h diff --git a/src/libCom/osi/os/vxWorks/atReboot.cpp b/src/osi/os/vxWorks/atReboot.cpp similarity index 100% rename from src/libCom/osi/os/vxWorks/atReboot.cpp rename to src/osi/os/vxWorks/atReboot.cpp diff --git a/src/libCom/osi/os/vxWorks/camacLib.h b/src/osi/os/vxWorks/camacLib.h similarity index 100% rename from src/libCom/osi/os/vxWorks/camacLib.h rename to src/osi/os/vxWorks/camacLib.h diff --git a/src/libCom/osi/os/vxWorks/devLibVMEOSD.c b/src/osi/os/vxWorks/devLibVMEOSD.c similarity index 100% rename from src/libCom/osi/os/vxWorks/devLibVMEOSD.c rename to src/osi/os/vxWorks/devLibVMEOSD.c diff --git a/src/libCom/osi/os/vxWorks/epicsAtomicOSD.cpp b/src/osi/os/vxWorks/epicsAtomicOSD.cpp similarity index 100% rename from src/libCom/osi/os/vxWorks/epicsAtomicOSD.cpp rename to src/osi/os/vxWorks/epicsAtomicOSD.cpp diff --git a/src/libCom/osi/os/vxWorks/epicsAtomicOSD.h b/src/osi/os/vxWorks/epicsAtomicOSD.h similarity index 100% rename from src/libCom/osi/os/vxWorks/epicsAtomicOSD.h rename to src/osi/os/vxWorks/epicsAtomicOSD.h diff --git a/src/libCom/osi/os/vxWorks/epicsDynLink.c b/src/osi/os/vxWorks/epicsDynLink.c similarity index 100% rename from src/libCom/osi/os/vxWorks/epicsDynLink.c rename to src/osi/os/vxWorks/epicsDynLink.c diff --git a/src/libCom/osi/os/vxWorks/epicsDynLink.h b/src/osi/os/vxWorks/epicsDynLink.h similarity index 100% rename from src/libCom/osi/os/vxWorks/epicsDynLink.h rename to src/osi/os/vxWorks/epicsDynLink.h diff --git a/src/libCom/osi/os/vxWorks/epicsMMIO.h b/src/osi/os/vxWorks/epicsMMIO.h similarity index 100% rename from src/libCom/osi/os/vxWorks/epicsMMIO.h rename to src/osi/os/vxWorks/epicsMMIO.h diff --git a/src/libCom/osi/os/vxWorks/epicsMath.h b/src/osi/os/vxWorks/epicsMath.h similarity index 100% rename from src/libCom/osi/os/vxWorks/epicsMath.h rename to src/osi/os/vxWorks/epicsMath.h diff --git a/src/libCom/osi/os/vxWorks/logMsgToErrlog.cpp b/src/osi/os/vxWorks/logMsgToErrlog.cpp similarity index 100% rename from src/libCom/osi/os/vxWorks/logMsgToErrlog.cpp rename to src/osi/os/vxWorks/logMsgToErrlog.cpp diff --git a/src/libCom/osi/os/vxWorks/module_types.h b/src/osi/os/vxWorks/module_types.h similarity index 100% rename from src/libCom/osi/os/vxWorks/module_types.h rename to src/osi/os/vxWorks/module_types.h diff --git a/src/libCom/osi/os/vxWorks/osdEnv.c b/src/osi/os/vxWorks/osdEnv.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdEnv.c rename to src/osi/os/vxWorks/osdEnv.c diff --git a/src/libCom/osi/os/vxWorks/osdEvent.c b/src/osi/os/vxWorks/osdEvent.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdEvent.c rename to src/osi/os/vxWorks/osdEvent.c diff --git a/src/libCom/osi/os/vxWorks/osdEvent.h b/src/osi/os/vxWorks/osdEvent.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdEvent.h rename to src/osi/os/vxWorks/osdEvent.h diff --git a/src/libCom/osi/os/vxWorks/osdFindSymbol.c b/src/osi/os/vxWorks/osdFindSymbol.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdFindSymbol.c rename to src/osi/os/vxWorks/osdFindSymbol.c diff --git a/src/libCom/osi/os/vxWorks/osdInterrupt.c b/src/osi/os/vxWorks/osdInterrupt.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdInterrupt.c rename to src/osi/os/vxWorks/osdInterrupt.c diff --git a/src/libCom/osi/os/vxWorks/osdInterrupt.h b/src/osi/os/vxWorks/osdInterrupt.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdInterrupt.h rename to src/osi/os/vxWorks/osdInterrupt.h diff --git a/src/libCom/osi/os/vxWorks/osdMessageQueue.cpp b/src/osi/os/vxWorks/osdMessageQueue.cpp similarity index 100% rename from src/libCom/osi/os/vxWorks/osdMessageQueue.cpp rename to src/osi/os/vxWorks/osdMessageQueue.cpp diff --git a/src/libCom/osi/os/vxWorks/osdMessageQueue.h b/src/osi/os/vxWorks/osdMessageQueue.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdMessageQueue.h rename to src/osi/os/vxWorks/osdMessageQueue.h diff --git a/src/libCom/osi/os/vxWorks/osdMutex.c b/src/osi/os/vxWorks/osdMutex.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdMutex.c rename to src/osi/os/vxWorks/osdMutex.c diff --git a/src/libCom/osi/os/vxWorks/osdMutex.h b/src/osi/os/vxWorks/osdMutex.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdMutex.h rename to src/osi/os/vxWorks/osdMutex.h diff --git a/src/libCom/osi/os/vxWorks/osdPoolStatus.c b/src/osi/os/vxWorks/osdPoolStatus.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdPoolStatus.c rename to src/osi/os/vxWorks/osdPoolStatus.c diff --git a/src/libCom/osi/os/vxWorks/osdProcess.c b/src/osi/os/vxWorks/osdProcess.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdProcess.c rename to src/osi/os/vxWorks/osdProcess.c diff --git a/src/libCom/osi/os/vxWorks/osdReadline.c b/src/osi/os/vxWorks/osdReadline.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdReadline.c rename to src/osi/os/vxWorks/osdReadline.c diff --git a/src/libCom/osi/os/vxWorks/osdSignal.cpp b/src/osi/os/vxWorks/osdSignal.cpp similarity index 100% rename from src/libCom/osi/os/vxWorks/osdSignal.cpp rename to src/osi/os/vxWorks/osdSignal.cpp diff --git a/src/libCom/osi/os/vxWorks/osdSock.c b/src/osi/os/vxWorks/osdSock.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdSock.c rename to src/osi/os/vxWorks/osdSock.c diff --git a/src/libCom/osi/os/vxWorks/osdSock.h b/src/osi/os/vxWorks/osdSock.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdSock.h rename to src/osi/os/vxWorks/osdSock.h diff --git a/src/libCom/osi/os/vxWorks/osdSpin.c b/src/osi/os/vxWorks/osdSpin.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdSpin.c rename to src/osi/os/vxWorks/osdSpin.c diff --git a/src/libCom/osi/os/vxWorks/osdStdio.c b/src/osi/os/vxWorks/osdStdio.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdStdio.c rename to src/osi/os/vxWorks/osdStdio.c diff --git a/src/libCom/osi/os/vxWorks/osdStrtod.h b/src/osi/os/vxWorks/osdStrtod.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdStrtod.h rename to src/osi/os/vxWorks/osdStrtod.h diff --git a/src/libCom/osi/os/vxWorks/osdThread.c b/src/osi/os/vxWorks/osdThread.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdThread.c rename to src/osi/os/vxWorks/osdThread.c diff --git a/src/libCom/osi/os/vxWorks/osdThread.h b/src/osi/os/vxWorks/osdThread.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdThread.h rename to src/osi/os/vxWorks/osdThread.h diff --git a/src/libCom/osi/os/vxWorks/osdThreadExtra.c b/src/osi/os/vxWorks/osdThreadExtra.c similarity index 100% rename from src/libCom/osi/os/vxWorks/osdThreadExtra.c rename to src/osi/os/vxWorks/osdThreadExtra.c diff --git a/src/libCom/osi/os/vxWorks/osdTime.cpp b/src/osi/os/vxWorks/osdTime.cpp similarity index 100% rename from src/libCom/osi/os/vxWorks/osdTime.cpp rename to src/osi/os/vxWorks/osdTime.cpp diff --git a/src/libCom/osi/os/vxWorks/osdTime.h b/src/osi/os/vxWorks/osdTime.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdTime.h rename to src/osi/os/vxWorks/osdTime.h diff --git a/src/libCom/osi/os/vxWorks/osdVME.h b/src/osi/os/vxWorks/osdVME.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdVME.h rename to src/osi/os/vxWorks/osdVME.h diff --git a/src/libCom/osi/os/vxWorks/osdWireConfig.h b/src/osi/os/vxWorks/osdWireConfig.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osdWireConfig.h rename to src/osi/os/vxWorks/osdWireConfig.h diff --git a/src/libCom/osi/os/vxWorks/osiFileName.h b/src/osi/os/vxWorks/osiFileName.h similarity index 100% rename from src/libCom/osi/os/vxWorks/osiFileName.h rename to src/osi/os/vxWorks/osiFileName.h diff --git a/src/libCom/osi/os/vxWorks/strtoll.c b/src/osi/os/vxWorks/strtoll.c similarity index 100% rename from src/libCom/osi/os/vxWorks/strtoll.c rename to src/osi/os/vxWorks/strtoll.c diff --git a/src/libCom/osi/os/vxWorks/strtoull.c b/src/osi/os/vxWorks/strtoull.c similarity index 100% rename from src/libCom/osi/os/vxWorks/strtoull.c rename to src/osi/os/vxWorks/strtoull.c diff --git a/src/libCom/osi/os/vxWorks/task_params.h b/src/osi/os/vxWorks/task_params.h similarity index 100% rename from src/libCom/osi/os/vxWorks/task_params.h rename to src/osi/os/vxWorks/task_params.h diff --git a/src/libCom/osi/os/vxWorks/veclist.c b/src/osi/os/vxWorks/veclist.c similarity index 100% rename from src/libCom/osi/os/vxWorks/veclist.c rename to src/osi/os/vxWorks/veclist.c diff --git a/src/libCom/osi/os/vxWorks/vxComLibrary.c b/src/osi/os/vxWorks/vxComLibrary.c similarity index 100% rename from src/libCom/osi/os/vxWorks/vxComLibrary.c rename to src/osi/os/vxWorks/vxComLibrary.c diff --git a/src/libCom/osi/osiClockTime.c b/src/osi/osiClockTime.c similarity index 100% rename from src/libCom/osi/osiClockTime.c rename to src/osi/osiClockTime.c diff --git a/src/libCom/osi/osiClockTime.h b/src/osi/osiClockTime.h similarity index 100% rename from src/libCom/osi/osiClockTime.h rename to src/osi/osiClockTime.h diff --git a/src/libCom/osi/osiNTPTime.c b/src/osi/osiNTPTime.c similarity index 100% rename from src/libCom/osi/osiNTPTime.c rename to src/osi/osiNTPTime.c diff --git a/src/libCom/osi/osiNTPTime.h b/src/osi/osiNTPTime.h similarity index 100% rename from src/libCom/osi/osiNTPTime.h rename to src/osi/osiNTPTime.h diff --git a/src/libCom/osi/osiPoolStatus.h b/src/osi/osiPoolStatus.h similarity index 100% rename from src/libCom/osi/osiPoolStatus.h rename to src/osi/osiPoolStatus.h diff --git a/src/libCom/osi/osiProcess.h b/src/osi/osiProcess.h similarity index 100% rename from src/libCom/osi/osiProcess.h rename to src/osi/osiProcess.h diff --git a/src/libCom/osi/osiSock.c b/src/osi/osiSock.c similarity index 100% rename from src/libCom/osi/osiSock.c rename to src/osi/osiSock.c diff --git a/src/libCom/osi/osiSock.h b/src/osi/osiSock.h similarity index 100% rename from src/libCom/osi/osiSock.h rename to src/osi/osiSock.h diff --git a/src/libCom/osi/osiWireFormat.h b/src/osi/osiWireFormat.h similarity index 100% rename from src/libCom/osi/osiWireFormat.h rename to src/osi/osiWireFormat.h diff --git a/src/libCom/pool/Makefile b/src/pool/Makefile similarity index 100% rename from src/libCom/pool/Makefile rename to src/pool/Makefile diff --git a/src/libCom/pool/epicsThreadPool.h b/src/pool/epicsThreadPool.h similarity index 100% rename from src/libCom/pool/epicsThreadPool.h rename to src/pool/epicsThreadPool.h diff --git a/src/libCom/pool/poolJob.c b/src/pool/poolJob.c similarity index 100% rename from src/libCom/pool/poolJob.c rename to src/pool/poolJob.c diff --git a/src/libCom/pool/poolPriv.h b/src/pool/poolPriv.h similarity index 100% rename from src/libCom/pool/poolPriv.h rename to src/pool/poolPriv.h diff --git a/src/libCom/pool/threadPool.c b/src/pool/threadPool.c similarity index 100% rename from src/libCom/pool/threadPool.c rename to src/pool/threadPool.c diff --git a/src/libCom/ring/Makefile b/src/ring/Makefile similarity index 100% rename from src/libCom/ring/Makefile rename to src/ring/Makefile diff --git a/src/libCom/ring/epicsRingBytes.c b/src/ring/epicsRingBytes.c similarity index 100% rename from src/libCom/ring/epicsRingBytes.c rename to src/ring/epicsRingBytes.c diff --git a/src/libCom/ring/epicsRingBytes.h b/src/ring/epicsRingBytes.h similarity index 100% rename from src/libCom/ring/epicsRingBytes.h rename to src/ring/epicsRingBytes.h diff --git a/src/libCom/ring/epicsRingPointer.cpp b/src/ring/epicsRingPointer.cpp similarity index 100% rename from src/libCom/ring/epicsRingPointer.cpp rename to src/ring/epicsRingPointer.cpp diff --git a/src/libCom/ring/epicsRingPointer.h b/src/ring/epicsRingPointer.h similarity index 100% rename from src/libCom/ring/epicsRingPointer.h rename to src/ring/epicsRingPointer.h 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 6e6ad79c6..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 ca 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 6a3dc5d6c..000000000 --- a/src/std/link/lnkConst.c +++ /dev/null @@ -1,591 +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; -} - -static long lnkConst_putValue(struct link *plink, short dbrType, - const void *pbuffer, long nRequest) -{ - 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, - lnkConst_putValue, 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 5a591b230..000000000 --- a/src/std/rec/test/Makefile +++ /dev/null @@ -1,121 +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 - -TESTPROD_HOST += softTest -softTest_SRCS += softTest.c -softTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp -testHarness_SRCS += softTest.c -TESTFILES += ../softTest.db -TESTS += softTest - -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 ../regressHex.db ../regressLinkMS.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/regressHex.db b/src/std/rec/test/regressHex.db deleted file mode 100644 index 83f6916e9..000000000 --- a/src/std/rec/test/regressHex.db +++ /dev/null @@ -1,28 +0,0 @@ -record(ai, "ai1") { - field(INP, 0x10) -} -record(longin, "li1") { - field(INP, 0x10) -} -record(mbbiDirect, "mi1") { - field(INP, 0x10) - field(NOBT, 8) -} -record(aSub, "as1") { - field(INPA, 0x10) - field(FTA, "CHAR") - field(INPB, 0x10) - field(FTB, "UCHAR") - field(INPC, 0x10) - field(FTC, "SHORT") - field(INPD, 0x10) - field(FTD, "USHORT") - field(INPE, 0x10) - field(FTE, "LONG") - field(INPF, 0x10) - field(FTF, "ULONG") - field(INPG, 0x10) - field(FTG, "FLOAT") - field(INPH, 0x10) - field(FTH, "DOUBLE") -} diff --git a/src/std/rec/test/regressTest.c b/src/std/rec/test/regressTest.c deleted file mode 100644 index 15010cebf..000000000 --- a/src/std/rec/test/regressTest.c +++ /dev/null @@ -1,134 +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 - -/* - * Tests for specific regressions - */ - -void regressTest_registerRecordDeviceDriver(struct dbBase *); - -static -void startRegressTestIoc(const char *dbfile) -{ - testdbPrepare(); - testdbReadDatabase("regressTest.dbd", NULL, NULL); - regressTest_registerRecordDeviceDriver(pdbbase); - testdbReadDatabase(dbfile, NULL, NULL); - - eltc(0); - testIocInitOk(); - eltc(1); -} - -/* - * https://bugs.launchpad.net/epics-base/+bug/1577108 - */ -static -void testArrayLength1(void) -{ - waveformRecord *precwf; - calcoutRecord *precco; - double *pbuf; - - startRegressTestIoc("regressArray1.db"); - - precwf = (waveformRecord*)testdbRecordPtr("wf"); - precco = (calcoutRecord*)testdbRecordPtr("co"); - - 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(); -} - -/* - * https://bugs.launchpad.net/epics-base/+bug/1699445 - */ -static -void testHexConstantLinks(void) -{ - startRegressTestIoc("regressHex.db"); - - testdbGetFieldEqual("ai1", DBR_LONG, 0x10); - testdbGetFieldEqual("li1", DBR_LONG, 0x10); - testdbGetFieldEqual("mi1", DBR_LONG, 0x10); - testTodoBegin("Needs JSON5 for hex arrays"); - testdbGetFieldEqual("as1.A", DBR_LONG, 0x10); - testdbGetFieldEqual("as1.B", DBR_LONG, 0x10); - testdbGetFieldEqual("as1.C", DBR_LONG, 0x10); - testdbGetFieldEqual("as1.D", DBR_LONG, 0x10); - testdbGetFieldEqual("as1.E", DBR_LONG, 0x10); - testdbGetFieldEqual("as1.F", DBR_LONG, 0x10); - testdbGetFieldEqual("as1.G", DBR_LONG, 0x10); - testdbGetFieldEqual("as1.H", DBR_LONG, 0x10); - testTodoEnd(); - - testIocShutdownOk(); - testdbCleanup(); -} - -static -void testLinkMS(void) -{ - startRegressTestIoc("regressLinkMS.db"); - - testdbPutFieldOk("alarm", DBF_DOUBLE, 0.5); - testdbGetFieldEqual("latch", DBR_DOUBLE, 0.5); - testdbGetFieldEqual("latch.SEVR", DBR_LONG, 0); - - testdbPutFieldOk("alarm", DBF_DOUBLE, 1.5); - testdbGetFieldEqual("latch", DBR_DOUBLE, 1.5); - testdbGetFieldEqual("latch.SEVR", DBR_LONG, 1); - - testdbPutFieldOk("alarm", DBF_DOUBLE, 0.5); - testdbGetFieldEqual("latch", DBR_DOUBLE, 0.5); - testdbGetFieldEqual("latch.SEVR", DBR_LONG, 0); - - testdbPutFieldOk("alarm", DBF_DOUBLE, 2.5); - testdbGetFieldEqual("latch", DBR_DOUBLE, 2.5); - testdbGetFieldEqual("latch.SEVR", DBR_LONG, 2); - - testdbPutFieldOk("alarm", DBF_DOUBLE, 0.5); - testdbGetFieldEqual("latch", DBR_DOUBLE, 0.5); - testdbGetFieldEqual("latch.SEVR", DBR_LONG, 0); - - testIocShutdownOk(); - testdbCleanup(); -} - - -MAIN(regressTest) -{ - testPlan(31); - testArrayLength1(); - testHexConstantLinks(); - testLinkMS(); - 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/libCom/taskwd/Makefile b/src/taskwd/Makefile similarity index 100% rename from src/libCom/taskwd/Makefile rename to src/taskwd/Makefile diff --git a/src/libCom/taskwd/taskwd.c b/src/taskwd/taskwd.c similarity index 100% rename from src/libCom/taskwd/taskwd.c rename to src/taskwd/taskwd.c diff --git a/src/libCom/taskwd/taskwd.h b/src/taskwd/taskwd.h similarity index 100% rename from src/libCom/taskwd/taskwd.h rename to src/taskwd/taskwd.h 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/caServerApp/Makefile b/src/template/base/top/caServerApp/Makefile deleted file mode 100644 index 0195112ac..000000000 --- a/src/template/base/top/caServerApp/Makefile +++ /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. -#************************************************************************* - -TOP=.. - -include $(TOP)/configure/CONFIG - -PROD_LIBS += $(EPICS_BASE_HOST_LIBS) - -# -# Added ws2_32 winmm user32 for the non-dll build -# -PROD_SYS_LIBS_WIN32 += ws2_32 advapi32 user32 - -casexample_SRCS += main.cc -casexample_SRCS += exServer.cc -casexample_SRCS += exPV.cc -casexample_SRCS += exVectorPV.cc -casexample_SRCS += exScalarPV.cc -casexample_SRCS += exAsyncPV.cc -casexample_SRCS += exChannel.cc - -PROD_HOST = casexample - -include $(TOP)/configure/RULES - - diff --git a/src/template/base/top/caServerApp/README b/src/template/base/top/caServerApp/README deleted file mode 100644 index 202c0dbc5..000000000 --- a/src/template/base/top/caServerApp/README +++ /dev/null @@ -1,63 +0,0 @@ - -The files in this directory build an example CA server. This code -is meant to provide some examples of how the CA server library can -be used but is not intended to be an example of exemplary code organization -and therefore care should be taken when emulating what is found here. - -The example server exports the process variables (PVs) in the table below. - -ScanPeriod Name HOPR LOPR Type Asynchronous Elements - -.1 "jane" 10.0 0.0 DBR_DOUBLE No 1 -2.0 "fred" 10.0 -10.0 DBR_DOUBLE No 1 -.1 "janet" 10.0 0.0 DBR_DOUBLE Yes 1 -2.0 "freddy"10.0 -10.0 DBR_DOUBLE Yes 1 -2.0 "alan" 10.0 -10.0 DBR_DOUBLE No 100 -20.0 "albert"10.0 -10.0 DBR_DOUBLE No 1000 --1.0 "boot" 10.0 -10.0 DBR_ENUM No 1 --1.0 "booty" 10.0 -10.0 DBR_ENUM Yes 1 --1.0 "bill" 10.0 -10.0 DBR_DOUBLE No 1 --1.0 "billy" 10.0 -10.0 DBR_DOUBLE Yes 1 --1.0 "bloaty"10.0 -10.0 DBR_DOUBLE No 100000 - -Many ca servers will find that synchronous variables will meet -their needs and will not require the increased complexity -associated with asynchronous PVs. Asynchronous PVs are needed -when read and write IO requests cant be completed immediately. - -The PVs in the example server are updated periodically if the -"ScanPeriod" column above contains a positive number. Some random -"noise" is added to a PV's current value each time that it is -updated. - -usage: - -excas [-d -t -p --c -s<1=scan on (default), 0=scan off> --ss<1=synchronous scan (default), 0=asynchronous scan>] - --d -Increased diagnostics messages with increasing debug level. Defaults to no -messages. - --t -Specifies the duration that the server will run. Defaults to forever. - --p -Specifies the prefix applied to all PV names. If you specify "-pxxx:" -then clients must specify PV names like "xxx:fred" or "xxx:jane". -This is useful when several example servers are running on the same -IP subnet for testing purposes. Defaults to no prefix. - --c -Useful when you need lots of aliased PV names. The alias names are -of the form "fred1", "fred2", etc. Defaults to no aliases. - --s<1=scan on (default), 0=scan off> -Used to turn off updating of the PVs with random noise. Default is -to update all PVs with a positive scan period. - --ss<1=synchronous scan (default), 0=asynchronous scan> -Controls updating of PVs from an asynchronous thread (tests thread -safety of the server library). Defaults to synchronous. - diff --git a/src/template/base/top/caServerApp/exAsyncPV.cc b/src/template/base/top/caServerApp/exAsyncPV.cc deleted file mode 100644 index b5bff9181..000000000 --- a/src/template/base/top/caServerApp/exAsyncPV.cc +++ /dev/null @@ -1,228 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// Example EPICS CA server -// (asynchrronous process variable) -// - -#include "exServer.h" - -exAsyncPV::exAsyncPV ( exServer & cas, pvInfo & setup, - bool preCreateFlag, bool scanOnIn, - double asyncDelayIn ) : - exScalarPV ( cas, setup, preCreateFlag, scanOnIn ), - asyncDelay ( asyncDelayIn ), - simultAsychReadIOCount ( 0u ), - simultAsychWriteIOCount ( 0u ) -{ -} - -// -// exAsyncPV::read() -// -caStatus exAsyncPV::read (const casCtx &ctx, gdd &valueIn) -{ - exAsyncReadIO *pIO; - - if ( this->simultAsychReadIOCount >= this->cas.maxSimultAsyncIO () ) { - return S_casApp_postponeAsyncIO; - } - - pIO = new exAsyncReadIO ( this->cas, ctx, - *this, valueIn, this->asyncDelay ); - if ( ! pIO ) { - if ( this->simultAsychReadIOCount > 0 ) { - return S_casApp_postponeAsyncIO; - } - else { - return S_casApp_noMemory; - } - } - this->simultAsychReadIOCount++; - return S_casApp_asyncCompletion; -} - -// -// exAsyncPV::writeNotify() -// -caStatus exAsyncPV::writeNotify ( const casCtx &ctx, const gdd &valueIn ) -{ - if ( this->simultAsychWriteIOCount >= this->cas.maxSimultAsyncIO() ) { - return S_casApp_postponeAsyncIO; - } - - exAsyncWriteIO * pIO = new - exAsyncWriteIO ( this->cas, ctx, *this, - valueIn, this->asyncDelay ); - if ( ! pIO ) { - if ( this->simultAsychReadIOCount > 0 ) { - return S_casApp_postponeAsyncIO; - } - else { - return S_casApp_noMemory; - } - } - this->simultAsychWriteIOCount++; - return S_casApp_asyncCompletion; -} - -// -// exAsyncPV::write() -// -caStatus exAsyncPV::write ( const casCtx &ctx, const gdd &valueIn ) -{ - // implement the discard intermediate values, but last value - // sent always applied behavior that IOCs provide excepting - // that we will alow N requests to pend instead of a limit - // of only one imposed in the IOC - if ( this->simultAsychWriteIOCount >= this->cas.maxSimultAsyncIO() ) { - pStandbyValue.set ( & valueIn ); - return S_casApp_success; - } - - exAsyncWriteIO * pIO = new - exAsyncWriteIO ( this->cas, ctx, *this, - valueIn, this->asyncDelay ); - if ( ! pIO ) { - pStandbyValue.set ( & valueIn ); - return S_casApp_success; - } - this->simultAsychWriteIOCount++; - return S_casApp_asyncCompletion; -} - -// Implementing a specialized update for exAsyncPV -// allows standby value to update when we update -// the PV from an asynchronous write timer expiration -// which is a better time compared to removeIO below -// which, if used, gets the reads and writes out of -// order. This type of reordering can cause the -// regression tests to fail. -caStatus exAsyncPV :: updateFromAsyncWrite ( const gdd & src ) -{ - caStatus stat = this->update ( src ); - if ( this->simultAsychWriteIOCount <=1 && - pStandbyValue.valid () ) { -//printf("updateFromAsyncWrite: write standby\n"); - stat = this->update ( *this->pStandbyValue ); - this->pStandbyValue.set ( 0 ); - } - return stat; -} - -void exAsyncPV::removeReadIO () -{ - if ( this->simultAsychReadIOCount > 0u ) { - this->simultAsychReadIOCount--; - } - else { - fprintf ( stderr, "inconsistent simultAsychReadIOCount?\n" ); - } -} - -void exAsyncPV::removeWriteIO () -{ - if ( this->simultAsychWriteIOCount > 0u ) { - this->simultAsychWriteIOCount--; - if ( this->simultAsychWriteIOCount == 0 && - pStandbyValue.valid () ) { -//printf("removeIO: write standby\n"); - this->update ( *this->pStandbyValue ); - this->pStandbyValue.set ( 0 ); - } - } - else { - fprintf ( stderr, "inconsistent simultAsychWriteIOCount?\n" ); - } -} - -// -// exAsyncWriteIO::exAsyncWriteIO() -// -exAsyncWriteIO::exAsyncWriteIO ( exServer & cas, - const casCtx & ctxIn, exAsyncPV & pvIn, - const gdd & valueIn, double asyncDelay ) : - casAsyncWriteIO ( ctxIn ), pv ( pvIn ), - timer ( cas.createTimer () ), pValue(valueIn) -{ - this->timer.start ( *this, asyncDelay ); -} - -// -// exAsyncWriteIO::~exAsyncWriteIO() -// -exAsyncWriteIO::~exAsyncWriteIO() -{ - this->timer.destroy (); - // if the timer hasnt expired, and the value - // hasnt been written then force it to happen - // now so that regression testing works - if ( this->pValue.valid () ) { - this->pv.updateFromAsyncWrite ( *this->pValue ); - } - this->pv.removeWriteIO(); -} - -// -// exAsyncWriteIO::expire() -// (a virtual function that runs when the base timer expires) -// -epicsTimerNotify::expireStatus exAsyncWriteIO:: - expire ( const epicsTime & /* currentTime */ ) -{ - assert ( this->pValue.valid () ); - caStatus status = this->pv.updateFromAsyncWrite ( *this->pValue ); - this->pValue.set ( 0 ); - this->postIOCompletion ( status ); - return noRestart; -} - -// -// exAsyncReadIO::exAsyncReadIO() -// -exAsyncReadIO::exAsyncReadIO ( exServer & cas, const casCtx & ctxIn, - exAsyncPV & pvIn, gdd & protoIn, - double asyncDelay ) : - casAsyncReadIO ( ctxIn ), pv ( pvIn ), - timer ( cas.createTimer() ), pProto ( protoIn ) -{ - this->timer.start ( *this, asyncDelay ); -} - -// -// exAsyncReadIO::~exAsyncReadIO() -// -exAsyncReadIO::~exAsyncReadIO() -{ - this->pv.removeReadIO (); - this->timer.destroy (); -} - -// -// exAsyncReadIO::expire() -// (a virtual function that runs when the base timer expires) -// -epicsTimerNotify::expireStatus - exAsyncReadIO::expire ( const epicsTime & /* currentTime */ ) -{ - // - // map between the prototype in and the - // current value - // - caStatus status = this->pv.exPV::readNoCtx ( this->pProto ); - - // - // post IO completion - // - this->postIOCompletion ( status, *this->pProto ); - - return noRestart; -} - diff --git a/src/template/base/top/caServerApp/exChannel.cc b/src/template/base/top/caServerApp/exChannel.cc deleted file mode 100644 index 5f4e5b109..000000000 --- a/src/template/base/top/caServerApp/exChannel.cc +++ /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. -\*************************************************************************/ - -// -// Example EPICS CA server -// - -#include "exServer.h" - -// -// exChannel::setOwner () -// -void exChannel::setOwner(const char * const /* pUserName */, - const char * const /* pHostName */) -{ -} - -// -// exChannel::readAccess () -// -bool exChannel::readAccess () const -{ - return true; -} - -// -// exChannel::writeAccess () -// -bool exChannel::writeAccess () const -{ - return true; -} - - diff --git a/src/template/base/top/caServerApp/exPV.cc b/src/template/base/top/caServerApp/exPV.cc deleted file mode 100644 index 97430c000..000000000 --- a/src/template/base/top/caServerApp/exPV.cc +++ /dev/null @@ -1,344 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// Example EPICS CA server -// -#include "exServer.h" -#include "gddApps.h" - -// -// static data for exPV -// -char exPV::hasBeenInitialized = 0; -gddAppFuncTable exPV::ft; -epicsTime exPV::currentTime; - -// -// special gddDestructor guarantees same form of new and delete -// -class exFixedStringDestructor: public gddDestructor { - virtual void run (void *); -}; - -// -// exPV::exPV() -// -exPV::exPV ( exServer & casIn, pvInfo & setup, - bool preCreateFlag, bool scanOnIn ) : - cas ( casIn ), - timer ( cas.createTimer() ), - info ( setup ), - interest ( false ), - preCreate ( preCreateFlag ), - scanOn ( scanOnIn ) -{ - // - // no dataless PV allowed - // - assert (this->info.getCapacity()>=1u); - - // - // start a very slow background scan - // (we will speed this up to the normal rate when - // someone is watching the PV) - // - if ( this->scanOn && this->info.getScanPeriod () > 0.0 ) { - this->timer.start ( *this, this->getScanPeriod() ); - } -} - -// -// exPV::~exPV() -// -exPV::~exPV() -{ - this->timer.destroy (); - this->info.unlinkPV(); -} - -// -// exPV::destroy() -// -// this is replaced by a noop since we are -// pre-creating most of the PVs during init in this simple server -// -void exPV::destroy() -{ - if ( ! this->preCreate ) { - delete this; - } -} - -// -// exPV::update() -// -caStatus exPV::update ( const gdd & valueIn ) -{ -# if DEBUG - printf("Setting %s too:\n", this->info.getName().string()); - valueIn.dump(); -# endif - - caStatus status = this->updateValue ( valueIn ); - if ( status || ( ! this->pValue.valid() ) ) { - return status; - } - - // - // post a value change event - // - caServer * pCAS = this->getCAS(); - if ( this->interest == true && pCAS != NULL ) { - casEventMask select ( pCAS->valueEventMask() | pCAS->logEventMask() ); - this->postEvent ( select, *this->pValue ); - } - - return S_casApp_success; -} - -// -// exScanTimer::expire () -// -epicsTimerNotify::expireStatus -exPV::expire ( const epicsTime & /*currentTime*/ ) -{ - this->scan(); - if ( this->scanOn && this->getScanPeriod() > 0.0 ) { - return expireStatus ( restart, this->getScanPeriod() ); - } - else { - return noRestart; - } -} - -// -// exPV::bestExternalType() -// -aitEnum exPV::bestExternalType () const -{ - return this->info.getType (); -} - -// -// exPV::interestRegister() -// -caStatus exPV::interestRegister () -{ - if ( ! this->getCAS() ) { - return S_casApp_success; - } - - this->interest = true; - if ( this->scanOn && this->getScanPeriod() > 0.0 && - this->getScanPeriod() < this->timer.getExpireDelay() ) { - this->timer.start ( *this, this->getScanPeriod() ); - } - - return S_casApp_success; -} - -// -// exPV::interestDelete() -// -void exPV::interestDelete() -{ - this->interest = false; -} - -// -// exPV::show() -// -void exPV::show ( unsigned level ) const -{ - if (level>1u) { - if ( this->pValue.valid () ) { - printf ( "exPV: cond=%d\n", this->pValue->getStat () ); - printf ( "exPV: sevr=%d\n", this->pValue->getSevr () ); - printf ( "exPV: value=%f\n", static_cast < double > ( * this->pValue ) ); - } - printf ( "exPV: interest=%d\n", this->interest ); - this->timer.show ( level - 1u ); - } -} - -// -// exPV::initFT() -// -void exPV::initFT () -{ - if ( exPV::hasBeenInitialized ) { - return; - } - - // - // time stamp, status, and severity are extracted from the - // GDD associated with the "value" application type. - // - exPV::ft.installReadFunc ("value", &exPV::getValue); - exPV::ft.installReadFunc ("precision", &exPV::getPrecision); - exPV::ft.installReadFunc ("graphicHigh", &exPV::getHighLimit); - exPV::ft.installReadFunc ("graphicLow", &exPV::getLowLimit); - exPV::ft.installReadFunc ("controlHigh", &exPV::getHighLimit); - exPV::ft.installReadFunc ("controlLow", &exPV::getLowLimit); - exPV::ft.installReadFunc ("alarmHigh", &exPV::getHighLimit); - exPV::ft.installReadFunc ("alarmLow", &exPV::getLowLimit); - exPV::ft.installReadFunc ("alarmHighWarning", &exPV::getHighLimit); - exPV::ft.installReadFunc ("alarmLowWarning", &exPV::getLowLimit); - exPV::ft.installReadFunc ("units", &exPV::getUnits); - exPV::ft.installReadFunc ("enums", &exPV::getEnums); - - exPV::hasBeenInitialized = 1; -} - -// -// exPV::getPrecision() -// -caStatus exPV::getPrecision ( gdd & prec ) -{ - prec.put(4u); - return S_cas_success; -} - -// -// exPV::getHighLimit() -// -caStatus exPV::getHighLimit ( gdd & value ) -{ - value.put(info.getHopr()); - return S_cas_success; -} - -// -// exPV::getLowLimit() -// -caStatus exPV::getLowLimit ( gdd & value ) -{ - value.put(info.getLopr()); - return S_cas_success; -} - -// -// exPV::getUnits() -// -caStatus exPV::getUnits( gdd & units ) -{ - aitString str("furlongs", aitStrRefConstImortal); - units.put(str); - return S_cas_success; -} - -// -// exPV::getEnums() -// -// returns the eneumerated state strings -// for a discrete channel -// -// The PVs in this example are purely analog, -// and therefore this isnt appropriate in an -// analog context ... -// -caStatus exPV::getEnums ( gdd & enumsIn ) -{ - if ( this->info.getType () == aitEnumEnum16 ) { - static const unsigned nStr = 2; - aitFixedString *str; - exFixedStringDestructor *pDes; - - str = new aitFixedString[nStr]; - if (!str) { - return S_casApp_noMemory; - } - - pDes = new exFixedStringDestructor; - if (!pDes) { - delete [] str; - return S_casApp_noMemory; - } - - strncpy (str[0].fixed_string, "off", - sizeof(str[0].fixed_string)); - strncpy (str[1].fixed_string, "on", - sizeof(str[1].fixed_string)); - - enumsIn.setDimension(1); - enumsIn.setBound (0,0,nStr); - enumsIn.putRef (str, pDes); - - return S_cas_success; - } - - return S_cas_success; -} - -// -// exPV::getValue() -// -caStatus exPV::getValue ( gdd & value ) -{ - caStatus status; - - if ( this->pValue.valid () ) { - gddStatus gdds; - - gdds = gddApplicationTypeTable:: - app_table.smartCopy ( &value, & (*this->pValue) ); - if (gdds) { - status = S_cas_noConvert; - } - else { - status = S_cas_success; - } - } - else { - status = S_casApp_undefined; - } - return status; -} - -// -// exPV::write() -// (synchronous default) -// -caStatus exPV::write ( const casCtx &, const gdd & valueIn ) -{ - return this->update ( valueIn ); -} - -// -// exPV::read() -// (synchronous default) -// -caStatus exPV::read ( const casCtx &, gdd & protoIn ) -{ - return this->ft.read ( *this, protoIn ); -} - -// -// exPV::createChannel() -// -// for access control - optional -// -casChannel *exPV::createChannel ( const casCtx &ctx, - const char * const /* pUserName */, - const char * const /* pHostName */ ) -{ - return new exChannel ( ctx ); -} - -// -// exFixedStringDestructor::run() -// -// special gddDestructor guarantees same form of new and delete -// -void exFixedStringDestructor::run ( void * pUntyped ) -{ - aitFixedString *ps = (aitFixedString *) pUntyped; - delete [] ps; -} - diff --git a/src/template/base/top/caServerApp/exScalarPV.cc b/src/template/base/top/caServerApp/exScalarPV.cc deleted file mode 100644 index 1b326fa51..000000000 --- a/src/template/base/top/caServerApp/exScalarPV.cc +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 "exServer.h" -#include "gddApps.h" - -#define myPI 3.14159265358979323846 - -// -// SUN C++ does not have RAND_MAX yet -// -#if !defined(RAND_MAX) -// -// Apparently SUN C++ is using the SYSV version of rand -// -#if 0 -#define RAND_MAX INT_MAX -#else -#define RAND_MAX SHRT_MAX -#endif -#endif - -// -// exScalarPV::scan -// -void exScalarPV::scan() -{ - caStatus status; - double radians; - smartGDDPointer pDD; - float newValue; - float limit; - int gddStatus; - - // - // update current time (so we are not required to do - // this every time that we write the PV which impacts - // throughput under sunos4 because gettimeofday() is - // slow) - // - this->currentTime = epicsTime::getCurrent (); - - pDD = new gddScalar ( gddAppType_value, aitEnumFloat64 ); - if ( ! pDD.valid () ) { - return; - } - - // - // smart pointer class manages reference count after this point - // - gddStatus = pDD->unreference (); - assert ( ! gddStatus ); - - radians = ( rand () * 2.0 * myPI ) / RAND_MAX; - if ( this->pValue.valid () ) { - this->pValue->getConvert(newValue); - } - else { - newValue = 0.0f; - } - newValue += (float) ( sin (radians) / 10.0 ); - limit = (float) this->info.getHopr (); - newValue = epicsMin ( newValue, limit ); - limit = (float) this->info.getLopr (); - newValue = epicsMax ( newValue, limit ); - *pDD = newValue; - aitTimeStamp gddts ( this->currentTime ); - pDD->setTimeStamp ( & gddts ); - status = this->update ( *pDD ); - if (status!=S_casApp_success) { - errMessage ( status, "scalar scan update failed\n" ); - } -} - -// -// exScalarPV::updateValue () -// -// NOTES: -// 1) This should have a test which verifies that the -// incoming value in all of its various data types can -// be translated into a real number? -// 2) We prefer to unreference the old PV value here and -// reference the incomming value because this will -// result in each value change events retaining an -// independent value on the event queue. -// -caStatus exScalarPV::updateValue ( const gdd & valueIn ) -{ - // - // Really no need to perform this check since the - // server lib verifies that all requests are in range - // - if ( ! valueIn.isScalar() ) { - return S_casApp_outOfBounds; - } - - if ( ! pValue.valid () ) { - this->pValue = new gddScalar ( - gddAppType_value, this->info.getType () ); - if ( ! pValue.valid () ) { - return S_casApp_noMemory; - } - } - - this->pValue->put ( & valueIn ); - - return S_casApp_success; -} - diff --git a/src/template/base/top/caServerApp/exServer.cc b/src/template/base/top/caServerApp/exServer.cc deleted file mode 100644 index f934f3608..000000000 --- a/src/template/base/top/caServerApp/exServer.cc +++ /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. -\*************************************************************************/ -// -// fileDescriptorManager.process(delay); -// (the name of the global symbol has leaked in here) -// - -// -// Example EPICS CA server -// -#include "exServer.h" - -// -// static list of pre-created PVs -// -pvInfo exServer::pvList[] = { - pvInfo (1.0e-1, "jane", 10.0f, 0.0f, aitEnumFloat64, excasIoSync, 1u), - pvInfo (2.0, "fred", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 1u), - pvInfo (1.0e-1, "janet", 10.0f, 0.0f, aitEnumFloat64, excasIoAsync, 1u), - pvInfo (2.0, "freddy", 10.0f, -10.0f, aitEnumFloat64, excasIoAsync, 1u), - pvInfo (2.0, "alan", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 100u), - pvInfo (20.0, "albert", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 1000u), - pvInfo (-1.0, "boot", 10.0f, -10.0f, aitEnumEnum16, excasIoSync, 1u), - pvInfo (1.0, "booty", 10.0f, -10.0f, aitEnumEnum16, excasIoAsync, 1u), - pvInfo (-1.0, "bill", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 1u), - pvInfo (-1.0, "billy", 10.0f, -10.0f, aitEnumFloat64, excasIoAsync, 1u) -}; - -const unsigned exServer::pvListNElem = NELEMENTS (exServer::pvList); - -// -// static on-the-fly PVs -// -pvInfo exServer::billy (-1.0, "billybob", 10.0f, -10.0f, aitEnumFloat64, excasIoAsync, 1u); -pvInfo exServer::bloater (.010, "bloater", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 10000u); -pvInfo exServer::bloaty (.010, "bloaty", 10.0f, -10.0f, aitEnumFloat64, excasIoSync, 100000u); - - -// -// exServer::exServer() -// -exServer::exServer ( const char * const pvPrefix, - unsigned aliasCount, bool scanOnIn, - bool asyncScan, double asyncDelayIn, - unsigned maxSimultAsyncIOIn ) : - pTimerQueue ( 0 ), simultAsychIOCount ( 0u ), - _maxSimultAsyncIO ( maxSimultAsyncIOIn ), - asyncDelay ( asyncDelayIn ), scanOn ( scanOnIn ) -{ - unsigned i; - exPV *pPV; - pvInfo *pPVI; - pvInfo *pPVAfter = &exServer::pvList[pvListNElem]; - char pvAlias[256]; - const char * const pNameFmtStr = "%.100s%.20s"; - const char * const pAliasFmtStr = "%.100s%.20s%.6u"; - - exPV::initFT(); - - if ( asyncScan ) { - unsigned timerPriotity; - epicsThreadBooleanStatus etbs = epicsThreadLowestPriorityLevelAbove ( - epicsThreadGetPrioritySelf (), & timerPriotity ); - if ( etbs != epicsThreadBooleanStatusSuccess ) { - timerPriotity = epicsThreadGetPrioritySelf (); - } - this->pTimerQueue = & epicsTimerQueueActive::allocate ( false, timerPriotity ); - } - - // - // pre-create all of the simple PVs that this server will export - // - for (pPVI = exServer::pvList; pPVI < pPVAfter; pPVI++) { - pPV = pPVI->createPV (*this, true, scanOnIn, this->asyncDelay ); - if (!pPV) { - fprintf(stderr, "Unable to create new PV \"%s\"\n", - pPVI->getName()); - } - - - // - // Install canonical (root) name - // - sprintf(pvAlias, pNameFmtStr, pvPrefix, pPVI->getName()); - this->installAliasName(*pPVI, pvAlias); - - // - // Install numbered alias names - // - for (i=0u; igetName(), i); - this->installAliasName(*pPVI, pvAlias); - } - } - - // - // Install create on-the-fly PVs - // into the PV name hash table - // - sprintf ( pvAlias, pNameFmtStr, pvPrefix, billy.getName() ); - this->installAliasName ( billy, pvAlias ); - sprintf ( pvAlias, pNameFmtStr, pvPrefix, bloater.getName() ); - this->installAliasName ( bloater, pvAlias ); - sprintf ( pvAlias, pNameFmtStr, pvPrefix, bloaty.getName() ); - this->installAliasName ( bloaty, pvAlias ); -} - -// -// exServer::~exServer() -// -exServer::~exServer() -{ - this->destroyAllPV (); - this->stringResTbl.traverse ( &pvEntry::destroy ); -} - -void exServer::destroyAllPV () -{ - for ( unsigned i = 0; - i < NELEMENTS(exServer::pvList); i++ ) { - exServer::pvList[i].deletePV (); - } -} - -// -// exServer::installAliasName() -// -void exServer::installAliasName(pvInfo &info, const char *pAliasName) -{ - pvEntry *pEntry; - - pEntry = new pvEntry(info, *this, pAliasName); - if (pEntry) { - int resLibStatus; - resLibStatus = this->stringResTbl.add(*pEntry); - if (resLibStatus==0) { - return; - } - else { - delete pEntry; - } - } - fprintf ( stderr, -"Unable to enter PV=\"%s\" Alias=\"%s\" in PV name alias hash table\n", - info.getName(), pAliasName ); -} - -// -// More advanced pvExistTest() isnt needed so we forward to -// original version. This avoids sun pro warnings and speeds -// up execution. -// -pvExistReturn exServer::pvExistTest - ( const casCtx & ctx, const caNetAddr &, const char * pPVName ) -{ - return this->pvExistTest ( ctx, pPVName ); -} - -// -// exServer::pvExistTest() -// -pvExistReturn exServer::pvExistTest - ( const casCtx& ctxIn, const char * pPVName ) -{ - // - // lifetime of id is shorter than lifetime of pName - // - stringId id ( pPVName, stringId::refString ); - pvEntry *pPVE; - - // - // Look in hash table for PV name (or PV alias name) - // - pPVE = this->stringResTbl.lookup ( id ); - if ( ! pPVE ) { - return pverDoesNotExistHere; - } - - pvInfo & pvi = pPVE->getInfo(); - - // - // Initiate async IO if this is an async PV - // - if ( pvi.getIOType() == excasIoSync ) { - return pverExistsHere; - } - else { - if ( this->simultAsychIOCount >= this->_maxSimultAsyncIO ) { - return pverDoesNotExistHere; - } - - this->simultAsychIOCount++; - - exAsyncExistIO * pIO = - new exAsyncExistIO ( pvi, ctxIn, *this ); - if ( pIO ) { - return pverAsyncCompletion; - } - else { - this->simultAsychIOCount--; - return pverDoesNotExistHere; - } - } -} - -// -// exServer::pvAttach() -// -pvAttachReturn exServer::pvAttach - (const casCtx &ctx, const char *pName) -{ - // - // lifetime of id is shorter than lifetime of pName - // - stringId id(pName, stringId::refString); - exPV *pPV; - pvEntry *pPVE; - - pPVE = this->stringResTbl.lookup(id); - if (!pPVE) { - return S_casApp_pvNotFound; - } - - pvInfo &pvi = pPVE->getInfo(); - - // - // If this is a synchronous PV create the PV now - // - if (pvi.getIOType() == excasIoSync) { - pPV = pvi.createPV(*this, false, this->scanOn, this->asyncDelay ); - if (pPV) { - return *pPV; - } - else { - return S_casApp_noMemory; - } - } - // - // Initiate async IO if this is an async PV - // - else { - if (this->simultAsychIOCount>=this->_maxSimultAsyncIO) { - return S_casApp_postponeAsyncIO; - } - - this->simultAsychIOCount++; - - exAsyncCreateIO *pIO = - new exAsyncCreateIO ( pvi, *this, ctx, - this->scanOn, this->asyncDelay ); - if (pIO) { - return S_casApp_asyncCompletion; - } - else { - this->simultAsychIOCount--; - return S_casApp_noMemory; - } - } -} - -// -// exServer::setDebugLevel () -// -void exServer::setDebugLevel ( unsigned level ) -{ - this->caServer::setDebugLevel ( level ); -} - -// -// exServer::createTimer () -// -class epicsTimer & exServer::createTimer () -{ - if ( this->pTimerQueue ) { - return this->pTimerQueue->createTimer (); - } - else { - return this->caServer::createTimer (); - } -} - -// -// pvInfo::createPV() -// -exPV *pvInfo::createPV ( exServer & cas, bool preCreateFlag, - bool scanOn, double asyncDelay ) -{ - if (this->pPV) { - return this->pPV; - } - - exPV *pNewPV; - - // - // create an instance of the appropriate class - // depending on the io type and the number - // of elements - // - if (this->capacity==1u) { - switch (this->ioType){ - case excasIoSync: - pNewPV = new exScalarPV ( cas, *this, preCreateFlag, scanOn ); - break; - case excasIoAsync: - pNewPV = new exAsyncPV ( cas, *this, - preCreateFlag, scanOn, asyncDelay ); - break; - default: - pNewPV = NULL; - break; - } - } - else { - if ( this->ioType == excasIoSync ) { - pNewPV = new exVectorPV ( cas, *this, preCreateFlag, scanOn ); - } - else { - pNewPV = NULL; - } - } - - // - // load initial value (this is not done in - // the constructor because the base class's - // pure virtual function would be called) - // - // We always perform this step even if - // scanning is disable so that there will - // always be an initial value - // - if (pNewPV) { - this->pPV = pNewPV; - pNewPV->scan(); - } - - return pNewPV; -} - -// -// exServer::show() -// -void exServer::show (unsigned level) const -{ - // - // server tool specific show code goes here - // - this->stringResTbl.show(level); - - // - // print information about ca server libarary - // internals - // - this->caServer::show(level); -} - -// -// exAsyncExistIO::exAsyncExistIO() -// -exAsyncExistIO::exAsyncExistIO ( const pvInfo &pviIn, const casCtx &ctxIn, - exServer &casIn ) : - casAsyncPVExistIO ( ctxIn ), pvi ( pviIn ), - timer ( casIn.createTimer () ), cas ( casIn ) -{ - this->timer.start ( *this, 0.00001 ); -} - -// -// exAsyncExistIO::~exAsyncExistIO() -// -exAsyncExistIO::~exAsyncExistIO() -{ - this->cas.removeIO (); - this->timer.destroy (); -} - -// -// exAsyncExistIO::expire() -// (a virtual function that runs when the base timer expires) -// -epicsTimerNotify::expireStatus exAsyncExistIO::expire ( const epicsTime & /*currentTime*/ ) -{ - // - // post IO completion - // - this->postIOCompletion ( pvExistReturn(pverExistsHere) ); - return noRestart; -} - - -// -// exAsyncCreateIO::exAsyncCreateIO() -// -exAsyncCreateIO :: - exAsyncCreateIO ( pvInfo &pviIn, exServer &casIn, - const casCtx &ctxIn, bool scanOnIn, double asyncDelayIn ) : - casAsyncPVAttachIO ( ctxIn ), pvi ( pviIn ), - timer ( casIn.createTimer () ), - cas ( casIn ), asyncDelay ( asyncDelayIn ), scanOn ( scanOnIn ) -{ - this->timer.start ( *this, 0.00001 ); -} - -// -// exAsyncCreateIO::~exAsyncCreateIO() -// -exAsyncCreateIO::~exAsyncCreateIO() -{ - this->cas.removeIO (); - this->timer.destroy (); -} - -// -// exAsyncCreateIO::expire() -// (a virtual function that runs when the base timer expires) -// -epicsTimerNotify::expireStatus exAsyncCreateIO::expire ( const epicsTime & /*currentTime*/ ) -{ - exPV * pPV = this->pvi.createPV ( this->cas, false, - this->scanOn, this->asyncDelay ); - if ( pPV ) { - this->postIOCompletion ( pvAttachReturn ( *pPV ) ); - } - else { - this->postIOCompletion ( pvAttachReturn ( S_casApp_noMemory ) ); - } - return noRestart; -} - diff --git a/src/template/base/top/caServerApp/exServer.h b/src/template/base/top/caServerApp/exServer.h deleted file mode 100644 index cd9a897d3..000000000 --- a/src/template/base/top/caServerApp/exServer.h +++ /dev/null @@ -1,602 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -// -// Example EPICS CA server -// -// -// caServer -// | -// exServer -// -// casPV -// | -// exPV----------- -// | | -// exScalarPV exVectorPV -// | -// exAsyncPV -// -// casChannel -// | -// exChannel -// - - -// -// ANSI C -// -#include -#include - -// -// EPICS -// -#define epicsAssertAuthor "Jeff Hill johill@lanl.gov" -#include "gddAppFuncTable.h" -#include "smartGDDPointer.h" -#include "epicsTimer.h" -#include "casdef.h" -#include "epicsAssert.h" -#include "resourceLib.h" -#include "epicsAlgorithm.h" - -#ifndef NELEMENTS -# define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) -#endif - -// -// info about all pv in this server -// -enum excasIoType { excasIoSync, excasIoAsync }; - -class exPV; -class exServer; - -// -// pvInfo -// -class pvInfo { -public: - - pvInfo ( double scanPeriodIn, const char * pNameIn, - aitFloat32 hoprIn, aitFloat32 loprIn, aitEnum typeIn, - excasIoType ioTypeIn, unsigned countIn ); - pvInfo ( const pvInfo & copyIn ); - ~pvInfo (); - double getScanPeriod () const; - const char * getName () - const; double getHopr () const; - double getLopr () const; - aitEnum getType () const; - excasIoType getIOType () const; - unsigned getCapacity () const; - unsigned getElementCount () const; - void setElementCount (unsigned); - void unlinkPV (); - exPV *createPV ( exServer & exCAS, bool preCreateFlag, - bool scanOn, double asyncDelay ); - void deletePV (); -private: - const double scanPeriod; - const char * pName; - const double hopr; - const double lopr; - aitEnum type; - const excasIoType ioType; - const unsigned capacity; - unsigned elementCount; - exPV * pPV; - pvInfo & operator = ( const pvInfo & ); -}; - -// -// pvEntry -// -// o entry in the string hash table for the pvInfo -// o Since there may be aliases then we may end up -// with several of this class all referencing -// the same pv info class (justification -// for this breaking out into a seperate class -// from pvInfo) -// -class pvEntry - : public stringId, public tsSLNode < pvEntry > { -public: - pvEntry ( pvInfo &infoIn, exServer & casIn, - const char * pAliasName ); - ~pvEntry(); - pvInfo & getInfo() const { return this->info; } - void destroy (); - -private: - pvInfo & info; - exServer & cas; - pvEntry & operator = ( const pvEntry & ); - pvEntry ( const pvEntry & ); -}; - - -// -// exPV -// -class exPV : public casPV, public epicsTimerNotify, - public tsSLNode < exPV > { -public: - exPV ( exServer & cas, pvInfo & setup, - bool preCreateFlag, bool scanOn ); - virtual ~exPV(); - - void show ( unsigned level ) const; - - // - // Called by the server libary each time that it wishes to - // subscribe for PV the server tool via postEvent() below. - // - caStatus interestRegister (); - - // - // called by the server library each time that it wishes to - // remove its subscription for PV value change events - // from the server tool via caServerPostEvents() - // - void interestDelete (); - - aitEnum bestExternalType () const; - - // - // chCreate() is called each time that a PV is attached to - // by a client. The server tool must create a casChannel object - // (or a derived class) each time that this routine is called - // - // If the operation must complete asynchronously then return - // the status code S_casApp_asyncCompletion and then - // create the casChannel object at some time in the future - // - //casChannel *createChannel (); - - // - // This gets called when the pv gets a new value - // - caStatus update ( const gdd & ); - - // - // Gets called when we add noise to the current value - // - virtual void scan () = 0; - - // - // If no one is watching scan the PV with 10.0 - // times the specified period - // - double getScanPeriod (); - - caStatus read ( const casCtx &, gdd & protoIn ); - - caStatus readNoCtx ( smartGDDPointer pProtoIn ); - - caStatus write ( const casCtx &, const gdd & value ); - - void destroy (); - - const pvInfo & getPVInfo (); - - const char * getName() const; - - static void initFT(); - - casChannel * createChannel ( const casCtx &ctx, - const char * const pUserName, - const char * const pHostName ); - -protected: - smartGDDPointer pValue; - exServer & cas; - epicsTimer & timer; - pvInfo & info; - bool interest; - bool preCreate; - bool scanOn; - static epicsTime currentTime; - - virtual caStatus updateValue ( const gdd & ) = 0; - -private: - - // - // scan timer expire - // - expireStatus expire ( const epicsTime & currentTime ); - - // - // Std PV Attribute fetch support - // - gddAppFuncTableStatus getPrecision(gdd &value); - gddAppFuncTableStatus getHighLimit(gdd &value); - gddAppFuncTableStatus getLowLimit(gdd &value); - gddAppFuncTableStatus getUnits(gdd &value); - gddAppFuncTableStatus getValue(gdd &value); - gddAppFuncTableStatus getEnums(gdd &value); - - exPV & operator = ( const exPV & ); - exPV ( const exPV & ); - - // - // static - // - static gddAppFuncTable ft; - static char hasBeenInitialized; -}; - -// -// exScalarPV -// -class exScalarPV : public exPV { -public: - exScalarPV ( exServer & cas, pvInfo &setup, - bool preCreateFlag, bool scanOnIn ) : - exPV ( cas, setup, - preCreateFlag, scanOnIn) {} - void scan(); -private: - caStatus updateValue ( const gdd & ); - exScalarPV & operator = ( const exScalarPV & ); - exScalarPV ( const exScalarPV & ); -}; - -// -// exVectorPV -// -class exVectorPV : public exPV { -public: - exVectorPV ( exServer & cas, pvInfo &setup, - bool preCreateFlag, bool scanOnIn ) : - exPV ( cas, setup, - preCreateFlag, scanOnIn) {} - void scan(); - - unsigned maxDimension() const; - aitIndex maxBound (unsigned dimension) const; - -private: - caStatus updateValue ( const gdd & ); - exVectorPV & operator = ( const exVectorPV & ); - exVectorPV ( const exVectorPV & ); -}; - -// -// exServer -// -class exServer : private caServer { -public: - exServer ( const char * const pvPrefix, - unsigned aliasCount, bool scanOn, - bool asyncScan, double asyncDelay, - unsigned maxSimultAsyncIO ); - ~exServer (); - void show ( unsigned level ) const; - void removeIO (); - void removeAliasName ( pvEntry & entry ); - - class epicsTimer & createTimer (); - void setDebugLevel ( unsigned level ); - - void destroyAllPV (); - - unsigned maxSimultAsyncIO () const; - -private: - resTable < pvEntry, stringId > stringResTbl; - epicsTimerQueueActive * pTimerQueue; - unsigned simultAsychIOCount; - const unsigned _maxSimultAsyncIO; - double asyncDelay; - bool scanOn; - - void installAliasName ( pvInfo & info, const char * pAliasName ); - pvExistReturn pvExistTest ( const casCtx &, - const caNetAddr &, const char * pPVName ); - pvExistReturn pvExistTest ( const casCtx &, - const char * pPVName ); - pvAttachReturn pvAttach ( const casCtx &, - const char * pPVName ); - - exServer & operator = ( const exServer & ); - exServer ( const exServer & ); - - // - // list of pre-created PVs - // - static pvInfo pvList[]; - static const unsigned pvListNElem; - - // - // on-the-fly PVs - // - static pvInfo bill; - static pvInfo billy; - static pvInfo bloater; - static pvInfo bloaty; - static pvInfo boot; - static pvInfo booty; -}; - -// -// exAsyncPV -// -class exAsyncPV : public exScalarPV { -public: - exAsyncPV ( exServer & cas, pvInfo &setup, - bool preCreateFlag, bool scanOnIn, double asyncDelay ); - caStatus read ( const casCtx & ctxIn, gdd & protoIn ); - caStatus write ( const casCtx & ctxIn, const gdd & value ); - caStatus writeNotify ( const casCtx & ctxIn, const gdd & value ); - void removeReadIO(); - void removeWriteIO(); - caStatus updateFromAsyncWrite ( const gdd & ); -private: - double asyncDelay; - smartConstGDDPointer pStandbyValue; - unsigned simultAsychReadIOCount; - unsigned simultAsychWriteIOCount; - exAsyncPV & operator = ( const exAsyncPV & ); - exAsyncPV ( const exAsyncPV & ); -}; - -// -// exChannel -// -class exChannel : public casChannel{ -public: - exChannel ( const casCtx & ctxIn ); - void setOwner ( const char * const pUserName, - const char * const pHostName ); - bool readAccess () const; - bool writeAccess () const; -private: - exChannel & operator = ( const exChannel & ); - exChannel ( const exChannel & ); -}; - -// -// exAsyncWriteIO -// -class exAsyncWriteIO : public casAsyncWriteIO, public epicsTimerNotify { -public: - exAsyncWriteIO ( exServer &, const casCtx & ctxIn, - exAsyncPV &, const gdd &, double asyncDelay ); - ~exAsyncWriteIO (); -private: - exAsyncPV & pv; - epicsTimer & timer; - smartConstGDDPointer pValue; - expireStatus expire ( const epicsTime & currentTime ); - exAsyncWriteIO & operator = ( const exAsyncWriteIO & ); - exAsyncWriteIO ( const exAsyncWriteIO & ); -}; - -// -// exAsyncReadIO -// -class exAsyncReadIO : public casAsyncReadIO, public epicsTimerNotify { -public: - exAsyncReadIO ( exServer &, const casCtx &, - exAsyncPV &, gdd &, double asyncDelay ); - virtual ~exAsyncReadIO (); -private: - exAsyncPV & pv; - epicsTimer & timer; - smartGDDPointer pProto; - expireStatus expire ( const epicsTime & currentTime ); - exAsyncReadIO & operator = ( const exAsyncReadIO & ); - exAsyncReadIO ( const exAsyncReadIO & ); -}; - -// -// exAsyncExistIO -// (PV exist async IO) -// -class exAsyncExistIO : public casAsyncPVExistIO, public epicsTimerNotify { -public: - exAsyncExistIO ( const pvInfo & pviIn, const casCtx & ctxIn, - exServer & casIn ); - virtual ~exAsyncExistIO (); -private: - const pvInfo & pvi; - epicsTimer & timer; - exServer & cas; - expireStatus expire ( const epicsTime & currentTime ); - exAsyncExistIO & operator = ( const exAsyncExistIO & ); - exAsyncExistIO ( const exAsyncExistIO & ); -}; - - -// -// exAsyncCreateIO -// (PV create async IO) -// -class exAsyncCreateIO : public casAsyncPVAttachIO, public epicsTimerNotify { -public: - exAsyncCreateIO ( pvInfo & pviIn, exServer & casIn, - const casCtx & ctxIn, bool scanOnIn, double asyncDelay ); - virtual ~exAsyncCreateIO (); -private: - pvInfo & pvi; - epicsTimer & timer; - exServer & cas; - double asyncDelay; - bool scanOn; - expireStatus expire ( const epicsTime & currentTime ); - exAsyncCreateIO & operator = ( const exAsyncCreateIO & ); - exAsyncCreateIO ( const exAsyncCreateIO & ); -}; - -inline pvInfo::pvInfo ( double scanPeriodIn, const char *pNameIn, - aitFloat32 hoprIn, aitFloat32 loprIn, - aitEnum typeIn, excasIoType ioTypeIn, - unsigned countIn ) : - - scanPeriod ( scanPeriodIn ), pName ( pNameIn ), - hopr ( hoprIn ), lopr ( loprIn ), type ( typeIn ), - ioType ( ioTypeIn ), capacity ( countIn ), - elementCount ( 0 ), pPV ( 0 ) -{ -} - -// -// for use when MSVC++ will not build a default copy constructor -// for this class -// -inline pvInfo::pvInfo ( const pvInfo & copyIn ) : - - scanPeriod ( copyIn.scanPeriod ), pName ( copyIn.pName ), - hopr ( copyIn.hopr ), lopr ( copyIn.lopr ), type ( copyIn.type ), - ioType ( copyIn.ioType ), capacity ( copyIn.capacity ), - elementCount ( copyIn.elementCount ), pPV ( copyIn.pPV ) -{ -} - -inline pvInfo::~pvInfo () -{ - // - // GDD cleanup gets rid of GDD's that are in use - // by the PV before the file scope destructer for - // this class runs here so this does not seem to - // be a good idea - // - //if ( this->pPV != NULL ) { - // delete this->pPV; - //} -} - -inline void pvInfo::deletePV () -{ - if ( this->pPV != NULL ) { - delete this->pPV; - } -} - -inline double pvInfo::getScanPeriod () const -{ - return this->scanPeriod; -} - -inline const char *pvInfo::getName () const -{ - return this->pName; -} - -inline double pvInfo::getHopr () const -{ - return this->hopr; -} - -inline double pvInfo::getLopr () const -{ - return this->lopr; -} - -inline aitEnum pvInfo::getType () const -{ - return this->type; -} - -inline excasIoType pvInfo::getIOType () const -{ - return this->ioType; -} - -inline unsigned pvInfo::getCapacity () const -{ - return this->capacity; -} - -inline unsigned pvInfo::getElementCount () const -{ - return this->elementCount; -} - -inline void pvInfo::setElementCount (unsigned newCount) -{ - this->elementCount = newCount; -} - -inline void pvInfo::unlinkPV () -{ - this->pPV = NULL; -} - -inline pvEntry::pvEntry ( pvInfo & infoIn, exServer & casIn, - const char * pAliasName ) : - stringId ( pAliasName ), info ( infoIn ), cas ( casIn ) -{ - assert ( this->stringId::resourceName() != NULL ); -} - -inline pvEntry::~pvEntry () -{ - this->cas.removeAliasName ( *this ); -} - -inline void pvEntry::destroy () -{ - delete this; -} - -inline void exServer::removeAliasName ( pvEntry & entry ) -{ - pvEntry * pE; - pE = this->stringResTbl.remove ( entry ); - assert ( pE == &entry ); -} - -inline double exPV::getScanPeriod () -{ - double curPeriod = this->info.getScanPeriod (); - if ( ! this->interest ) { - curPeriod *= 10.0L; - } - return curPeriod; -} - -inline caStatus exPV::readNoCtx ( smartGDDPointer pProtoIn ) -{ - return this->ft.read ( *this, *pProtoIn ); -} - -inline const pvInfo & exPV::getPVInfo () -{ - return this->info; -} - -inline const char * exPV::getName () const -{ - return this->info.getName(); -} - -inline void exServer::removeIO() -{ - if ( this->simultAsychIOCount > 0u ) { - this->simultAsychIOCount--; - } - else { - fprintf ( stderr, - "simultAsychIOCount underflow?\n" ); - } -} - -inline unsigned exServer :: maxSimultAsyncIO () const -{ - return this->_maxSimultAsyncIO; -} - -inline exChannel::exChannel ( const casCtx & ctxIn ) : - casChannel(ctxIn) -{ -} - diff --git a/src/template/base/top/caServerApp/exVectorPV.cc b/src/template/base/top/caServerApp/exVectorPV.cc deleted file mode 100644 index 932188806..000000000 --- a/src/template/base/top/caServerApp/exVectorPV.cc +++ /dev/null @@ -1,264 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of 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 "exServer.h" -#include "gddApps.h" - -#define myPI 3.14159265358979323846 - -// -// SUN C++ does not have RAND_MAX yet -// -#if ! defined(RAND_MAX) -// -// Apparently SUN C++ is using the SYSV version of rand -// -# if 0 -# define RAND_MAX INT_MAX -# else -# define RAND_MAX SHRT_MAX -# endif -#endif - -// -// special gddDestructor guarantees same form of new and delete -// -class exVecDestructor: public gddDestructor { - virtual void run (void *); -}; - -// -// exVectorPV::maxDimension() -// -unsigned exVectorPV::maxDimension() const -{ - return 1u; -} - -// -// exVectorPV::maxBound() -// -aitIndex exVectorPV::maxBound (unsigned dimension) const -{ - if (dimension==0u) { - return this->info.getCapacity(); - } - else { - return 0u; - } -} - -// -// exVectorPV::scan -// -void exVectorPV::scan() -{ - static epicsTime startTime = epicsTime::getCurrent(); - - // update current time - // - this->currentTime = epicsTime::getCurrent(); - - // demonstrate a changing array size - unsigned ramp = 15 & (unsigned) (this->currentTime - startTime); - unsigned newSize = this->info.getCapacity(); - if (newSize > ramp) { - newSize -= ramp; - } - - smartGDDPointer pDD = new gddAtomic (gddAppType_value, aitEnumFloat64, - 1u, newSize); - if ( ! pDD.valid () ) { - return; - } - - // - // smart pointer class manages reference count after this point - // - gddStatus gdds = pDD->unreference(); - assert(!gdds); - - // - // allocate array buffer - // - aitFloat64 * pF = new aitFloat64 [newSize]; - if (!pF) { - return; - } - - exVecDestructor * pDest = new exVecDestructor; - if (!pDest) { - delete [] pF; - return; - } - - // - // install the buffer into the DD - // (do this before we increment pF) - // - pDD->putRef(pF, pDest); - - // - // double check for reasonable bounds on the - // current value - // - const aitFloat64 *pCF = NULL, *pCFE = NULL; - if (this->pValue.valid () && - this->pValue->dimension() == 1u) { - const gddBounds *pB = this->pValue->getBounds(); - - pCF = *this->pValue; - pCFE = &pCF[pB->size()]; - } - - aitFloat64 * pFE = &pF[newSize]; - while (pF < pFE) { - double radians = (rand () * 2.0 * myPI)/RAND_MAX; - double newValue; - if (pCF && pCF < pCFE) { - newValue = *pCF++; - } - else { - newValue = 0.0f; - } - newValue += (sin (radians) / 10.0); - double limit = this->info.getHopr(); - newValue = epicsMin (newValue, limit); - limit = this->info.getLopr(); - newValue = epicsMax (newValue, limit); - *pF++ = newValue; - } - - aitTimeStamp gddts = this->currentTime; - pDD->setTimeStamp ( & gddts ); - - caStatus status = this->update ( *pDD ); - this->info.setElementCount(newSize); - - if ( status != S_casApp_success ) { - errMessage (status, "vector scan update failed\n"); - } -} - -// -// exVectorPV::updateValue () -// -// NOTES: -// 1) This should have a test which verifies that the -// incoming value in all of its various data types can -// be translated into a real number? -// 2) We prefer to unreference the old PV value here and -// reference the incomming value because this will -// result in value change events each retaining an -// independent value on the event queue. With large arrays -// this may result in too much memory consumtion on -// the event queue. -// -caStatus exVectorPV::updateValue ( const gdd & value ) -{ - aitUint32 newSize = 0; - // - // Check bounds of incoming request - // (and see if we are replacing all elements - - // replaceOk==true) - // - // Perhaps much of this is unnecessary since the - // server lib checks the bounds of all requests - // - if ( value.isAtomic()) { - if ( value.dimension() != 1u ) { - return S_casApp_badDimension; - } - const gddBounds* pb = value.getBounds (); - if ( pb[0u].first() != 0u ) { - return S_casApp_outOfBounds; - } - - newSize = pb[0u].size(); - if ( newSize > this->info.getCapacity() ) { - return S_casApp_outOfBounds; - } - } - else if ( ! value.isScalar() ) { - // - // no containers - // - return S_casApp_outOfBounds; - } - - // - // Create a new array data descriptor - // (so that old values that may be referenced on the - // event queue are not replaced) - // - smartGDDPointer pNewValue ( new gddAtomic ( gddAppType_value, aitEnumFloat64, - 1u, newSize ) ); - if ( ! pNewValue.valid() ) { - return S_casApp_noMemory; - } - - // - // smart pointer class takes care of the reference count - // from here down - // - gddStatus gdds = pNewValue->unreference( ); - assert ( ! gdds ); - - // - // allocate array buffer - // - aitFloat64 * pF = new aitFloat64 [newSize]; - if (!pF) { - return S_casApp_noMemory; - } - - // - // Install (and initialize) array buffer - // if no old values exist - // - for ( unsigned i = 0u; i < newSize; i++ ) { - pF[i] = 0.0f; - } - - exVecDestructor * pDest = new exVecDestructor; - if (!pDest) { - delete [] pF; - return S_casApp_noMemory; - } - - // - // install the buffer into the DD - // (do this before we increment pF) - // - pNewValue->putRef ( pF, pDest ); - - // - // copy in the values that they are writing - // - gdds = pNewValue->put( & value ); - if ( gdds ) { - return S_cas_noConvert; - } - - this->pValue = pNewValue; - this->info.setElementCount(newSize); - - return S_casApp_success; -} - -// -// exVecDestructor::run() -// -// special gddDestructor guarantees same form of new and delete -// -void exVecDestructor::run ( void *pUntyped ) -{ - aitFloat64 * pf = reinterpret_cast < aitFloat64 * > ( pUntyped ); - delete [] pf; -} diff --git a/src/template/base/top/caServerApp/main.cc b/src/template/base/top/caServerApp/main.cc deleted file mode 100644 index 34d794841..000000000 --- a/src/template/base/top/caServerApp/main.cc +++ /dev/null @@ -1,151 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* EPICS BASE 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 "envDefs.h" -#include "errlog.h" - -#include "exServer.h" -#include "fdManager.h" - -// -// main() -// (example single threaded ca server tool main loop) -// -extern int main ( int argc, const char **argv ) -{ - epicsTime begin (epicsTime::getCurrent()); - exServer *pCAS; - unsigned debugLevel = 0u; - double executionTime = 0.0; - double asyncDelay = 0.1; - char pvPrefix[128] = ""; - unsigned aliasCount = 1u; - unsigned scanOn = true; - unsigned syncScan = true; - char arraySize[64] = ""; - bool forever = true; - unsigned maxSimultAsyncIO = 1000u; - int i; - - i = 1; - while ( i < argc ) { - if ( strcmp ( argv[i], "-d" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%u", & debugLevel ) == 1 ) { - i += 2; - continue; - } - } - if ( strcmp ( argv[i],"-t" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%lf", & executionTime ) == 1 ) { - forever = false; - i += 2; - continue; - } - } - if ( strcmp ( argv[i], "-p" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%127s", pvPrefix ) == 1 ) { - i += 2; - continue; - } - } - if ( strcmp ( argv[i], "-c" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%u", & aliasCount ) == 1 ) { - i += 2; - continue; - } - } - if ( strcmp ( argv[i], "-s" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%u", & scanOn ) == 1 ) { - i += 2; - continue; - } - } - if ( strcmp ( argv[i], "-a" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%63s", arraySize ) == 1 ) { - i += 2; - continue; - } - } - if ( strcmp ( argv[i],"-ss" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%u", & syncScan ) == 1 ) { - i += 2; - continue; - } - } - if ( strcmp ( argv[i],"-ad" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%lf", & asyncDelay ) == 1 ) { - i += 2; - continue; - } - } - if ( strcmp ( argv[i],"-an" ) == 0 ) { - if ( i+1 < argc && sscanf ( argv[i+1], "%u", & maxSimultAsyncIO ) == 1 ) { - i += 2; - continue; - } - } - printf ( "\"%s\"?\n", argv[i] ); - if ( i + 1 < argc ) { - printf ( "\"%s\"?\n", argv[i+1] ); - } - printf ( - "usage: %s [-d -t -p " - "-c -s <1=scan on (default), 0=scan off> " - "-ss <1=synchronous scan (default), 0=asynchronous scan> " - "-a -ad " - "-an \n", - argv[0]); - - return (1); - } - - if ( arraySize[0] != '\0' ) { - epicsEnvSet ( "EPICS_CA_MAX_ARRAY_BYTES", arraySize ); - } - - try { - pCAS = new exServer ( pvPrefix, aliasCount, - scanOn != 0, syncScan == 0, asyncDelay, - maxSimultAsyncIO ); - } - catch ( ... ) { - errlogPrintf ( "Server initialization error\n" ); - errlogFlush (); - return (-1); - } - - pCAS->setDebugLevel(debugLevel); - - if ( forever ) { - // - // loop here forever - // - while (true) { - fileDescriptorManager.process(1000.0); - } - } - else { - double delay = epicsTime::getCurrent() - begin; - - // - // loop here untill the specified execution time - // expires - // - while ( delay < executionTime ) { - fileDescriptorManager.process ( executionTime - delay ); - delay = epicsTime::getCurrent() - begin; - } - } - //pCAS->show(2u); - delete pCAS; - errlogFlush (); - return (0); -} - diff --git a/src/template/base/top/caServerApp/test.adl b/src/template/base/top/caServerApp/test.adl deleted file mode 100644 index 6086a3be5..000000000 --- a/src/template/base/top/caServerApp/test.adl +++ /dev/null @@ -1,844 +0,0 @@ -file { - name="test.dl" -} -display { - magic="305419896" - majv="2" - mnrv="4" - ndyng="0" - npc="5" - nstr="8" - ndynamic="12" - nplot="0" - nrd="0" - nes="0" - nkd="0" - object { - x="0" - y="0" - width="421" - height="306" - } - clr="0" - bclr="1" - nwords_dspy="1106" - nwords_sta="28" - nwords_cmap="36" - nwords_crules="106" - odyng="306" - osta="278" - odynamic="306" - oplot="1106" - ord="1106" - oes="1106" - okd="1106" - opc="58" - ostr="88" - ocmap="136" - ocrules="172" - style="solid" - fill="outline" - width="0" - clrmod="static" - vismod="static" - clrrule="alarm" - pv="" - cmap="" -} -"<>" { - ncolors="8" - dl_color { - r="255" - g="255" - b="255" - inten="255" - blink="off" - RISCpad="128" - } - dl_color { - r="0" - g="0" - b="0" - inten="0" - blink="off" - RISCpad="75" - } - dl_color { - r="255" - g="0" - b="0" - inten="255" - blink="off" - RISCpad="-14684" - } - dl_color { - r="255" - g="0" - b="0" - inten="255" - blink="on" - RISCpad="14744" - } - dl_color { - r="255" - g="255" - b="0" - inten="255" - blink="off" - RISCpad="-16536" - } - dl_color { - r="255" - g="255" - b="0" - inten="255" - blink="on" - RISCpad="-15536" - } - dl_color { - r="0" - g="0" - b="255" - inten="255" - blink="off" - RISCpad="-28408" - } - dl_color { - r="0" - g="0" - b="255" - inten="255" - blink="on" - RISCpad="0" - } -} -"<>" { - nrules="1" - dl_color_rule { - name="alarm" - info[0] { - chan="$(C).SEVR" - value="MAJOR" - connector="use" - comparator="equals" - clr="2" - RISCpad="0" - } - info[1] { - chan="$(C).SEVR" - value="MINOR" - connector="use" - comparator="equals" - clr="4" - RISCpad="127" - } - info[2] { - chan="$(C).SEVR" - value="INFO" - connector="use" - comparator="equals" - clr="6" - RISCpad="44" - } - info[3] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-128" - } - info[4] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-1" - } - info[5] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-104" - } - info[6] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-1" - } - info[7] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="8" - } - info[8] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="120" - } - info[9] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="1" - } - info[10] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="7" - } - info[11] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="19" - } - info[12] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="48" - } - info[13] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="28" - } - info[14] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="-88" - } - info[15] { - chan="" - value="" - connector="use" - comparator="equals" - clr="1" - RISCpad="0" - } - fg_enable="on" - bg_enable="on" - default_fg="0" - default_bg="1" - } -} -"<>" { - attr { - clr="0" - style="solid" - fill="outline" - width="0" - } -} -"text" { - object { - x="44" - y="16" - width="104" - height="14" - groupid="0" - } - textix="Sync" - align="horiz. left" - RISC_pad="0" -} -"text" { - object { - x="260" - y="13" - width="92" - height="17" - groupid="0" - } - textix="Async" - align="horiz. left" - RISC_pad="0" -} -"indicator" { - object { - x="15" - y="88" - width="170" - height="22" - groupid="0" - } - monitor { - chan="fred" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - RISC_pad="0" -} -"text update" { - object { - x="16" - y="133" - width="169" - height="17" - groupid="0" - } - monitor { - chan="fred" - clr="0" - bclr="1" - label="none" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="append" - decorate="none" - convertFunc="" - convertParams="" - } - align="horiz. left" - format="decimal" -} -"valuator" { - object { - x="15" - y="43" - width="168" - height="26" - groupid="0" - } - control { - chan="fred" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - gain="coarse" - sendMode="send on motion" - increment="0" -} -"indicator" { - object { - x="215" - y="81" - width="170" - height="30" - groupid="0" - } - monitor { - chan="freddy" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - RISC_pad="0" -} -"text update" { - object { - x="216" - y="133" - width="171" - height="18" - groupid="0" - } - monitor { - chan="freddy" - clr="0" - bclr="1" - label="none" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="append" - decorate="none" - convertFunc="" - convertParams="" - } - align="horiz. left" - format="decimal" -} -"valuator" { - object { - x="215" - y="43" - width="168" - height="28" - groupid="0" - } - control { - chan="freddy" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - gain="coarse" - sendMode="send on motion" - increment="0" -} -"indicator" { - object { - x="16" - y="225" - width="171" - height="19" - groupid="0" - } - monitor { - chan="jane" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - RISC_pad="0" -} -"text update" { - object { - x="17" - y="259" - width="170" - height="20" - groupid="0" - } - monitor { - chan="jane" - clr="0" - bclr="1" - label="none" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="append" - decorate="none" - convertFunc="" - convertParams="" - } - align="horiz. left" - format="decimal" -} -"valuator" { - object { - x="15" - y="187" - width="170" - height="19" - groupid="0" - } - control { - chan="jane" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - gain="coarse" - sendMode="send on motion" - increment="0" -} -"indicator" { - object { - x="219" - y="218" - width="173" - height="23" - groupid="0" - } - monitor { - chan="janet" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - RISC_pad="0" -} -"text update" { - object { - x="220" - y="257" - width="174" - height="20" - groupid="0" - } - monitor { - chan="janet" - clr="0" - bclr="1" - label="none" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="append" - decorate="none" - convertFunc="" - convertParams="" - } - align="horiz. left" - format="decimal" -} -"valuator" { - object { - x="219" - y="188" - width="171" - height="21" - groupid="0" - } - control { - chan="janet" - clr="0" - bclr="1" - label="limits" - clrmod="static" - rulechan[0] = "" - rulechan[1] = "" - rulechan[2] = "" - rulechan[3] = "" - rulechan[4] = "" - rulechan[5] = "" - rulechan[6] = "" - rulechan[7] = "" - rulechan[8] = "" - rulechan[9] = "" - rulechan[10] = "" - rulechan[11] = "" - rulechan[12] = "" - rulechan[13] = "" - rulechan[14] = "" - rulechan[15] = "" - clrrule="alarm" - clrargs="" - rulecolorbg="0" - rulecolorfg="0" - hdl="0" - ldl="0" - prec="-1" - newunits="" - units="none" - decorate="none" - convertFunc="" - convertParams="" - } - direction="down" - gain="coarse" - sendMode="send on motion" - increment="0" -} diff --git a/src/template/base/top/caServerApp/vxEntry.cc b/src/template/base/top/caServerApp/vxEntry.cc deleted file mode 100644 index 1cb240723..000000000 --- a/src/template/base/top/caServerApp/vxEntry.cc +++ /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 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 (LANL) -// - -#include -#include - -#include "exServer.h" - -// -// so we can call this from the vxWorks shell -// -extern "C" { - -exServer *pExampleCAS; - -// -// excas () -// (vxWorks example server entry point) -// -int excas (unsigned debugLevel, unsigned delaySec) -{ - epicsTime begin(epicsTime::getCurrent()); - exServer *pCAS; - - pCAS = new exServer(32u,5u,500u); - if (!pCAS) { - return (-1); - } - - pCAS->setDebugLevel(debugLevel); - pExampleCAS = pCAS; - - if (delaySec==0u) { - // - // loop here forever - // - while (1) { - taskDelay(10); - } - } - else { - epicsTime total( ((float)delaySec) ); - epicsTime delay(epicsTime::getCurrent() - begin); - // - // loop here untill the specified execution time - // expires - // - while (delay < total) { - taskDelay(10); - delay = epicsTime::getCurrent() - begin; - } - } - pCAS->show(debugLevel); - pExampleCAS = NULL; - delete pCAS; - return 0; -} - -int excasShow(unsigned level) -{ - if (pExampleCAS!=NULL) { - pExampleCAS->show(level); - } - return 0; -} - -} // extern "C" - 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/libCom/timer/Makefile b/src/timer/Makefile similarity index 100% rename from src/libCom/timer/Makefile rename to src/timer/Makefile diff --git a/src/libCom/timer/epicsTimer.cpp b/src/timer/epicsTimer.cpp similarity index 100% rename from src/libCom/timer/epicsTimer.cpp rename to src/timer/epicsTimer.cpp diff --git a/src/libCom/timer/epicsTimer.h b/src/timer/epicsTimer.h similarity index 100% rename from src/libCom/timer/epicsTimer.h rename to src/timer/epicsTimer.h diff --git a/src/libCom/timer/timer.cpp b/src/timer/timer.cpp similarity index 100% rename from src/libCom/timer/timer.cpp rename to src/timer/timer.cpp diff --git a/src/libCom/timer/timerPrivate.h b/src/timer/timerPrivate.h similarity index 100% rename from src/libCom/timer/timerPrivate.h rename to src/timer/timerPrivate.h diff --git a/src/libCom/timer/timerQueue.cpp b/src/timer/timerQueue.cpp similarity index 100% rename from src/libCom/timer/timerQueue.cpp rename to src/timer/timerQueue.cpp diff --git a/src/libCom/timer/timerQueueActive.cpp b/src/timer/timerQueueActive.cpp similarity index 100% rename from src/libCom/timer/timerQueueActive.cpp rename to src/timer/timerQueueActive.cpp diff --git a/src/libCom/timer/timerQueueActiveMgr.cpp b/src/timer/timerQueueActiveMgr.cpp similarity index 100% rename from src/libCom/timer/timerQueueActiveMgr.cpp rename to src/timer/timerQueueActiveMgr.cpp diff --git a/src/libCom/timer/timerQueuePassive.cpp b/src/timer/timerQueuePassive.cpp similarity index 100% rename from src/libCom/timer/timerQueuePassive.cpp rename to src/timer/timerQueuePassive.cpp 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 bceed2ed7..000000000 --- a/src/tools/EPICS/Release.pm +++ /dev/null @@ -1,121 +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); - - my %done; - &readRelease($relfile, $Rmacros, $Rapps, \%done); - - if ($hostarch) { - my $hrelfile = "$relfile.$hostarch"; - &readRelease($hrelfile, $Rmacros, $Rapps, \%done) if (-e $hrelfile); - $hrelfile .= '.Common'; - &readRelease($hrelfile, $Rmacros, $Rapps, \%done) if (-e $hrelfile); - } - - if ($arch) { - my $crelfile = "$relfile.Common.$arch"; - &readRelease($crelfile, $Rmacros, $Rapps, \%done) if (-e $crelfile); - - if ($hostarch) { - my $arelfile = "$relfile.$hostarch.$arch"; - &readRelease($arelfile, $Rmacros, $Rapps, \%done) if (-e $arelfile); - } - } -} - -# -# Parse a configure/RELEASE* file and anything it includes -# -sub readRelease { - my ($file, $Rmacros, $Rapps, $Rdone) = @_; - # $Rmacros and $Rdone are hash-refs, $Rapps an array-ref - - if (exists $Rdone->{$file}) { - die "Release.pm: Recursive loop found in RELEASE files,\n" . - "discovered in $file\n"; - } - - open(my $IN, '<', $file) or croak "Can't open $file: $!\n"; - $Rdone->{$file}++; - 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, $Rdone); - } 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 be4648258..000000000 --- a/src/tools/makeTestfile.pl +++ /dev/null @@ -1,47 +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; - -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/src/libCom/valgrind/valgrind.h b/src/valgrind/valgrind.h similarity index 100% rename from src/libCom/valgrind/valgrind.h rename to src/valgrind/valgrind.h diff --git a/src/libCom/yacc/ACKNOWLEDGEMENTS b/src/yacc/ACKNOWLEDGEMENTS similarity index 100% rename from src/libCom/yacc/ACKNOWLEDGEMENTS rename to src/yacc/ACKNOWLEDGEMENTS diff --git a/src/libCom/yacc/EPICS_READ_THIS b/src/yacc/EPICS_READ_THIS similarity index 100% rename from src/libCom/yacc/EPICS_READ_THIS rename to src/yacc/EPICS_READ_THIS diff --git a/src/libCom/yacc/Makefile b/src/yacc/Makefile similarity index 100% rename from src/libCom/yacc/Makefile rename to src/yacc/Makefile diff --git a/src/libCom/yacc/NEW_FEATURES b/src/yacc/NEW_FEATURES similarity index 100% rename from src/libCom/yacc/NEW_FEATURES rename to src/yacc/NEW_FEATURES diff --git a/src/libCom/yacc/NOTES b/src/yacc/NOTES similarity index 100% rename from src/libCom/yacc/NOTES rename to src/yacc/NOTES diff --git a/src/libCom/yacc/NO_WARRANTY b/src/yacc/NO_WARRANTY similarity index 100% rename from src/libCom/yacc/NO_WARRANTY rename to src/yacc/NO_WARRANTY diff --git a/src/libCom/yacc/README b/src/yacc/README similarity index 100% rename from src/libCom/yacc/README rename to src/yacc/README diff --git a/src/libCom/yacc/antelope.c b/src/yacc/antelope.c similarity index 100% rename from src/libCom/yacc/antelope.c rename to src/yacc/antelope.c diff --git a/src/libCom/yacc/closure.c b/src/yacc/closure.c similarity index 100% rename from src/libCom/yacc/closure.c rename to src/yacc/closure.c diff --git a/src/libCom/yacc/defs.h b/src/yacc/defs.h similarity index 100% rename from src/libCom/yacc/defs.h rename to src/yacc/defs.h diff --git a/src/libCom/yacc/error.c b/src/yacc/error.c similarity index 100% rename from src/libCom/yacc/error.c rename to src/yacc/error.c diff --git a/src/libCom/yacc/lalr.c b/src/yacc/lalr.c similarity index 100% rename from src/libCom/yacc/lalr.c rename to src/yacc/lalr.c diff --git a/src/libCom/yacc/lr0.c b/src/yacc/lr0.c similarity index 100% rename from src/libCom/yacc/lr0.c rename to src/yacc/lr0.c diff --git a/src/libCom/yacc/mkpar.c b/src/yacc/mkpar.c similarity index 100% rename from src/libCom/yacc/mkpar.c rename to src/yacc/mkpar.c diff --git a/src/libCom/yacc/output.c b/src/yacc/output.c similarity index 100% rename from src/libCom/yacc/output.c rename to src/yacc/output.c diff --git a/src/libCom/yacc/reader.c b/src/yacc/reader.c similarity index 100% rename from src/libCom/yacc/reader.c rename to src/yacc/reader.c diff --git a/src/libCom/yacc/skeleton.c b/src/yacc/skeleton.c similarity index 100% rename from src/libCom/yacc/skeleton.c rename to src/yacc/skeleton.c diff --git a/src/libCom/yacc/symtab.c b/src/yacc/symtab.c similarity index 100% rename from src/libCom/yacc/symtab.c rename to src/yacc/symtab.c diff --git a/src/libCom/yacc/verbose.c b/src/yacc/verbose.c similarity index 100% rename from src/libCom/yacc/verbose.c rename to src/yacc/verbose.c diff --git a/src/libCom/yacc/warshall.c b/src/yacc/warshall.c similarity index 100% rename from src/libCom/yacc/warshall.c rename to src/yacc/warshall.c diff --git a/src/libCom/yacc/yacc.html b/src/yacc/yacc.html similarity index 100% rename from src/libCom/yacc/yacc.html rename to src/yacc/yacc.html diff --git a/src/libCom/yajl/Makefile b/src/yajl/Makefile similarity index 100% rename from src/libCom/yajl/Makefile rename to src/yajl/Makefile diff --git a/src/libCom/yajl/yajl.c b/src/yajl/yajl.c similarity index 100% rename from src/libCom/yajl/yajl.c rename to src/yajl/yajl.c diff --git a/src/libCom/yajl/yajl_alloc.c b/src/yajl/yajl_alloc.c similarity index 100% rename from src/libCom/yajl/yajl_alloc.c rename to src/yajl/yajl_alloc.c diff --git a/src/libCom/yajl/yajl_alloc.h b/src/yajl/yajl_alloc.h similarity index 100% rename from src/libCom/yajl/yajl_alloc.h rename to src/yajl/yajl_alloc.h diff --git a/src/libCom/yajl/yajl_buf.c b/src/yajl/yajl_buf.c similarity index 100% rename from src/libCom/yajl/yajl_buf.c rename to src/yajl/yajl_buf.c diff --git a/src/libCom/yajl/yajl_buf.h b/src/yajl/yajl_buf.h similarity index 100% rename from src/libCom/yajl/yajl_buf.h rename to src/yajl/yajl_buf.h diff --git a/src/libCom/yajl/yajl_bytestack.h b/src/yajl/yajl_bytestack.h similarity index 100% rename from src/libCom/yajl/yajl_bytestack.h rename to src/yajl/yajl_bytestack.h diff --git a/src/libCom/yajl/yajl_common.h b/src/yajl/yajl_common.h similarity index 100% rename from src/libCom/yajl/yajl_common.h rename to src/yajl/yajl_common.h diff --git a/src/libCom/yajl/yajl_encode.c b/src/yajl/yajl_encode.c similarity index 100% rename from src/libCom/yajl/yajl_encode.c rename to src/yajl/yajl_encode.c diff --git a/src/libCom/yajl/yajl_encode.h b/src/yajl/yajl_encode.h similarity index 100% rename from src/libCom/yajl/yajl_encode.h rename to src/yajl/yajl_encode.h diff --git a/src/libCom/yajl/yajl_gen.c b/src/yajl/yajl_gen.c similarity index 100% rename from src/libCom/yajl/yajl_gen.c rename to src/yajl/yajl_gen.c diff --git a/src/libCom/yajl/yajl_gen.h b/src/yajl/yajl_gen.h similarity index 100% rename from src/libCom/yajl/yajl_gen.h rename to src/yajl/yajl_gen.h diff --git a/src/libCom/yajl/yajl_lex.c b/src/yajl/yajl_lex.c similarity index 100% rename from src/libCom/yajl/yajl_lex.c rename to src/yajl/yajl_lex.c diff --git a/src/libCom/yajl/yajl_lex.h b/src/yajl/yajl_lex.h similarity index 100% rename from src/libCom/yajl/yajl_lex.h rename to src/yajl/yajl_lex.h diff --git a/src/libCom/yajl/yajl_parse.h b/src/yajl/yajl_parse.h similarity index 100% rename from src/libCom/yajl/yajl_parse.h rename to src/yajl/yajl_parse.h diff --git a/src/libCom/yajl/yajl_parser.c b/src/yajl/yajl_parser.c similarity index 100% rename from src/libCom/yajl/yajl_parser.c rename to src/yajl/yajl_parser.c diff --git a/src/libCom/yajl/yajl_parser.h b/src/yajl/yajl_parser.h similarity index 100% rename from src/libCom/yajl/yajl_parser.h rename to src/yajl/yajl_parser.h 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\ - diff --git a/src/libCom/test/Makefile b/test/Makefile similarity index 99% rename from src/libCom/test/Makefile rename to test/Makefile index 04438854c..fcdcce39a 100755 --- a/src/libCom/test/Makefile +++ b/test/Makefile @@ -6,8 +6,8 @@ # EPICS BASE is distributed subject to a Software License Agreement found # in file LICENSE that is included with this distribution. #************************************************************************* -TOP=../../.. +TOP = .. include $(TOP)/configure/CONFIG PROD_LIBS += Com diff --git a/src/libCom/test/blockingSockTest.cpp b/test/blockingSockTest.cpp similarity index 100% rename from src/libCom/test/blockingSockTest.cpp rename to test/blockingSockTest.cpp diff --git a/src/libCom/test/buckTest.c b/test/buckTest.c similarity index 100% rename from src/libCom/test/buckTest.c rename to test/buckTest.c diff --git a/src/libCom/test/cvtFastPerform.cpp b/test/cvtFastPerform.cpp similarity index 100% rename from src/libCom/test/cvtFastPerform.cpp rename to test/cvtFastPerform.cpp diff --git a/src/libCom/test/cvtFastTest.c b/test/cvtFastTest.c similarity index 100% rename from src/libCom/test/cvtFastTest.c rename to test/cvtFastTest.c diff --git a/src/libCom/test/epicsAlgorithmTest.cpp b/test/epicsAlgorithmTest.cpp similarity index 100% rename from src/libCom/test/epicsAlgorithmTest.cpp rename to test/epicsAlgorithmTest.cpp diff --git a/src/libCom/test/epicsAtomicPerform.cpp b/test/epicsAtomicPerform.cpp similarity index 100% rename from src/libCom/test/epicsAtomicPerform.cpp rename to test/epicsAtomicPerform.cpp diff --git a/src/libCom/test/epicsAtomicTest.cpp b/test/epicsAtomicTest.cpp similarity index 100% rename from src/libCom/test/epicsAtomicTest.cpp rename to test/epicsAtomicTest.cpp diff --git a/src/libCom/test/epicsCalcTest.cpp b/test/epicsCalcTest.cpp similarity index 100% rename from src/libCom/test/epicsCalcTest.cpp rename to test/epicsCalcTest.cpp diff --git a/src/libCom/test/epicsEllTest.c b/test/epicsEllTest.c similarity index 100% rename from src/libCom/test/epicsEllTest.c rename to test/epicsEllTest.c diff --git a/src/libCom/test/epicsEnvTest.c b/test/epicsEnvTest.c similarity index 100% rename from src/libCom/test/epicsEnvTest.c rename to test/epicsEnvTest.c diff --git a/src/libCom/test/epicsErrlogTest.c b/test/epicsErrlogTest.c similarity index 100% rename from src/libCom/test/epicsErrlogTest.c rename to test/epicsErrlogTest.c diff --git a/src/libCom/test/epicsEventTest.cpp b/test/epicsEventTest.cpp similarity index 100% rename from src/libCom/test/epicsEventTest.cpp rename to test/epicsEventTest.cpp diff --git a/src/libCom/test/epicsExitTest.c b/test/epicsExitTest.c similarity index 100% rename from src/libCom/test/epicsExitTest.c rename to test/epicsExitTest.c diff --git a/src/libCom/test/epicsInlineTest1.c b/test/epicsInlineTest1.c similarity index 100% rename from src/libCom/test/epicsInlineTest1.c rename to test/epicsInlineTest1.c diff --git a/src/libCom/test/epicsInlineTest2.c b/test/epicsInlineTest2.c similarity index 100% rename from src/libCom/test/epicsInlineTest2.c rename to test/epicsInlineTest2.c diff --git a/src/libCom/test/epicsInlineTest3.cpp b/test/epicsInlineTest3.cpp similarity index 100% rename from src/libCom/test/epicsInlineTest3.cpp rename to test/epicsInlineTest3.cpp diff --git a/src/libCom/test/epicsInlineTest4.cpp b/test/epicsInlineTest4.cpp similarity index 100% rename from src/libCom/test/epicsInlineTest4.cpp rename to test/epicsInlineTest4.cpp diff --git a/src/libCom/test/epicsMMIOTest.c b/test/epicsMMIOTest.c similarity index 100% rename from src/libCom/test/epicsMMIOTest.c rename to test/epicsMMIOTest.c diff --git a/src/libCom/test/epicsMathTest.c b/test/epicsMathTest.c similarity index 100% rename from src/libCom/test/epicsMathTest.c rename to test/epicsMathTest.c diff --git a/src/libCom/test/epicsMaxThreads.c b/test/epicsMaxThreads.c similarity index 100% rename from src/libCom/test/epicsMaxThreads.c rename to test/epicsMaxThreads.c diff --git a/src/libCom/test/epicsMessageQueueTest.cpp b/test/epicsMessageQueueTest.cpp similarity index 100% rename from src/libCom/test/epicsMessageQueueTest.cpp rename to test/epicsMessageQueueTest.cpp diff --git a/src/libCom/test/epicsMutexTest.cpp b/test/epicsMutexTest.cpp similarity index 100% rename from src/libCom/test/epicsMutexTest.cpp rename to test/epicsMutexTest.cpp diff --git a/src/libCom/test/epicsRunLibComTests.c b/test/epicsRunLibComTests.c similarity index 100% rename from src/libCom/test/epicsRunLibComTests.c rename to test/epicsRunLibComTests.c diff --git a/src/libCom/test/epicsSockResolveTest.c b/test/epicsSockResolveTest.c similarity index 100% rename from src/libCom/test/epicsSockResolveTest.c rename to test/epicsSockResolveTest.c diff --git a/src/libCom/test/epicsSpinTest.c b/test/epicsSpinTest.c similarity index 100% rename from src/libCom/test/epicsSpinTest.c rename to test/epicsSpinTest.c diff --git a/src/libCom/test/epicsStackTraceTest.c b/test/epicsStackTraceTest.c similarity index 100% rename from src/libCom/test/epicsStackTraceTest.c rename to test/epicsStackTraceTest.c diff --git a/src/libCom/test/epicsStdioTest.c b/test/epicsStdioTest.c similarity index 100% rename from src/libCom/test/epicsStdioTest.c rename to test/epicsStdioTest.c diff --git a/src/libCom/test/epicsStdlibTest.c b/test/epicsStdlibTest.c similarity index 100% rename from src/libCom/test/epicsStdlibTest.c rename to test/epicsStdlibTest.c diff --git a/src/libCom/test/epicsStringTest.c b/test/epicsStringTest.c similarity index 100% rename from src/libCom/test/epicsStringTest.c rename to test/epicsStringTest.c diff --git a/src/libCom/test/epicsThreadHooksTest.c b/test/epicsThreadHooksTest.c similarity index 100% rename from src/libCom/test/epicsThreadHooksTest.c rename to test/epicsThreadHooksTest.c diff --git a/src/libCom/test/epicsThreadOnceTest.c b/test/epicsThreadOnceTest.c similarity index 100% rename from src/libCom/test/epicsThreadOnceTest.c rename to test/epicsThreadOnceTest.c diff --git a/src/libCom/test/epicsThreadPerform.cpp b/test/epicsThreadPerform.cpp similarity index 100% rename from src/libCom/test/epicsThreadPerform.cpp rename to test/epicsThreadPerform.cpp diff --git a/src/libCom/test/epicsThreadPoolTest.c b/test/epicsThreadPoolTest.c similarity index 100% rename from src/libCom/test/epicsThreadPoolTest.c rename to test/epicsThreadPoolTest.c diff --git a/src/libCom/test/epicsThreadPriorityTest.cpp b/test/epicsThreadPriorityTest.cpp similarity index 100% rename from src/libCom/test/epicsThreadPriorityTest.cpp rename to test/epicsThreadPriorityTest.cpp diff --git a/src/libCom/test/epicsThreadPrivateTest.cpp b/test/epicsThreadPrivateTest.cpp similarity index 100% rename from src/libCom/test/epicsThreadPrivateTest.cpp rename to test/epicsThreadPrivateTest.cpp diff --git a/src/libCom/test/epicsThreadTest.cpp b/test/epicsThreadTest.cpp similarity index 100% rename from src/libCom/test/epicsThreadTest.cpp rename to test/epicsThreadTest.cpp diff --git a/src/libCom/test/epicsTimeTest.cpp b/test/epicsTimeTest.cpp similarity index 100% rename from src/libCom/test/epicsTimeTest.cpp rename to test/epicsTimeTest.cpp diff --git a/src/libCom/test/epicsTimeZoneTest.c b/test/epicsTimeZoneTest.c similarity index 100% rename from src/libCom/test/epicsTimeZoneTest.c rename to test/epicsTimeZoneTest.c diff --git a/src/libCom/test/epicsTimerTest.cpp b/test/epicsTimerTest.cpp similarity index 100% rename from src/libCom/test/epicsTimerTest.cpp rename to test/epicsTimerTest.cpp diff --git a/src/libCom/test/epicsTypesTest.c b/test/epicsTypesTest.c similarity index 100% rename from src/libCom/test/epicsTypesTest.c rename to test/epicsTypesTest.c diff --git a/src/libCom/test/epicsUnitTestTest.c b/test/epicsUnitTestTest.c similarity index 100% rename from src/libCom/test/epicsUnitTestTest.c rename to test/epicsUnitTestTest.c diff --git a/src/libCom/test/epicsUnitTestTest.plt b/test/epicsUnitTestTest.plt similarity index 100% rename from src/libCom/test/epicsUnitTestTest.plt rename to test/epicsUnitTestTest.plt diff --git a/src/libCom/test/fdmgrTest.c b/test/fdmgrTest.c similarity index 100% rename from src/libCom/test/fdmgrTest.c rename to test/fdmgrTest.c diff --git a/src/libCom/test/ipAddrToAsciiTest.cpp b/test/ipAddrToAsciiTest.cpp similarity index 100% rename from src/libCom/test/ipAddrToAsciiTest.cpp rename to test/ipAddrToAsciiTest.cpp diff --git a/src/libCom/test/macDefExpandTest.c b/test/macDefExpandTest.c similarity index 100% rename from src/libCom/test/macDefExpandTest.c rename to test/macDefExpandTest.c diff --git a/src/libCom/test/macLibTest.c b/test/macLibTest.c similarity index 100% rename from src/libCom/test/macLibTest.c rename to test/macLibTest.c diff --git a/src/libCom/test/ringBytesTest.c b/test/ringBytesTest.c similarity index 100% rename from src/libCom/test/ringBytesTest.c rename to test/ringBytesTest.c diff --git a/src/libCom/test/ringPointerTest.c b/test/ringPointerTest.c similarity index 100% rename from src/libCom/test/ringPointerTest.c rename to test/ringPointerTest.c diff --git a/src/libCom/test/rtemsTestHarness.c b/test/rtemsTestHarness.c similarity index 100% rename from src/libCom/test/rtemsTestHarness.c rename to test/rtemsTestHarness.c diff --git a/src/libCom/test/taskwdTest.c b/test/taskwdTest.c similarity index 100% rename from src/libCom/test/taskwdTest.c rename to test/taskwdTest.c